+++ /dev/null
-/* 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, 8.0.200, 4 Mar 2004";
-#else
-#ifdef Plan9
-char *ckzv = "Plan 9 File support, 8.0.200, 4 Mar 2004";
-#else
-char *ckzv = "UNIX File support, 8.0.200, 4 Mar 2004";
-#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.
-
- Copyright (C) 1985, 2004,
- 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 */
-
-#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 */
-
-#include <errno.h>
-#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 */
-#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) );
-
-/*
- 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... */
-#include <security/pam_appl.h>
-#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 BIGBUFOK
-#define SSPACE 500000
-#else
-#define SSPACE 10000
-#endif /* BIGBUFOK */
-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 */
-
-#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 */ {
-#ifdef HAVEUTMPX
- struct utmpx ut; /* Needed for ut_host[] */
-#else
- struct utmp ut;
-#endif /* HAVEUTMPX */
- 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));
- ckstrncpy(ut.ut_name, name, sizeof(ut.ut_name));
-#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
- time(&ut.ut_time);
-#endif /* LINUX */
-#endif /* HAVEUTMPX */
- if (write(wtmpfd, (char *)&ut, sizeof(struct utmp)) !=
- sizeof(struct utmp)) {
-#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;
-
-static long iflen = -1L; /* 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;
-
-/* 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 DEBUG
- if (n != ZDFILE)
- debug(F101,"zopeno fp[n]=stdout","",fp[n]);
-#endif /* DEBUG */
- 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);
- }
- debug(F110,"zopeno fopen arg",p,0);
- 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);
-#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 long 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 %ld %s %c %s %c %c %s %s %d %s\n",
- ctime(&timenow), /* date/time */
- gtimer(), /* elapsed secs */
- s, /* peer name */
- 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. */
-
-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)
- return(write(fileno(fp[n]),s,(int)strlen(s)));
- 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 */
-
-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));
- 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. */
-
-int
-zsoutx(n,s,x) int n, x; char *s; {
-#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 */
-
-#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 */
-
-long
-zgetfs(name) char *name; {
- struct stat buf;
- char fnam[CKMAXPATH+4];
- long size = -1L;
- 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.
-*/
-long
-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;
- 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 */
- 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);
-
- 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);
-
-#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);
- 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.
-*/
-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",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.
-*/
- if (!diractive && haveonedir) {
-#ifdef COMMENT
- fcount = (mtchs == NULL &&
- (mtchs = (char **)malloc(maxnames * sizeof(*mtchs))) == NULL)
- ? 0 : 1;
-#else
- fcount = 0;
- if (!mtchs) {
- mtchs = (char **)malloc(maxnames * sizeof(*mtchs));
- if (mtchs)
- fcount = 1;
- if (!fcount)
- return(nxpand = fcount);
- }
-#endif /* COMMENT */
- 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(F110,"zxpand haveonedir A2",*mtchptr,0);
- 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, long n)
-#else
-zchkspa(f,n) char *f; long 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; {
- long k; int x;
- struct stat buf;
-
- k = iflen % 1024L; /* File length in K */
- if (k != 0L) k = 1L;
- xx->lengthk = (iflen / 1024L) + 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
- tmx += timezone;
-#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);
-
- debug(F110,"zstime",f,0);
- debug(F111,"zstime date",yy->date.val,yy->date.len);
-
-#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 = iswild(pl -> npart);
-
- 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))
-#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) );
-
- if (ruid != -1)
- return(realname);
-
- ruid = real_uid(); /* get our uid */
-
- /* how about $USER or $LOGNAME? */
- if ((c = getenv(NAMEENV)) != NULL) { /* check the env variable */
- ckstrncpy(envname, c, 255);
- if ((p = getpwnam(envname)) != NULL) {
- if (p->pw_uid == ruid) { /* get passwd entry for envname */
- ckstrncpy(realname, envname, UIDBUFLEN); /* uid's are same */
- return(realname);
- }
- }
- }
-
- /* can we use loginname() ? */
-
- if ((c = getlogin()) != NULL) { /* name from utmp file */
- ckstrncpy (loginname, c, UIDBUFLEN);
- 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 */
- realname[0] = '\0'; /* no user name */
- ruid = -1;
- return(NULL);
- }
- ckstrncpy(realname, p->pw_name, UIDBUFLEN);
- 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 */
- return(dirname);
- if (!strcmp(olddir,dirname)) { /* Same as last time */
- return(oldrealdir); /* so return old answer. */
- } else {
- 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 */
- if (i == 1) { /* if just a "~" */
-#ifdef IKSD
- if (inserver)
- user = getpwnam(uidbuf); /* Get info on current user */
- else
-#endif /* IKSD */
- {
- char * p = whoami();
- if (p)
- user = getpwnam(p);
- else
- user = NULL;
- }
- } else {
- user = getpwnam(&temp[1]); /* otherwise on the specified user */
- }
- }
- 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);
- 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);
- if (shpath == NULL) {
- 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",shpath,0);
- }
-#endif /* COMMENT */
-#endif /* aegis */
- shptr = shname = shpath;
- while (*shptr != '\0')
- if (*shptr++ == DIRSEP)
- shname = shptr;
- restorsigs(); /* Restore ignored signals */
- debug(F110,"zshcmd shname",shname,0);
- if (s == NULL || *s == '\0') { /* Interactive shell requested? */
- execl(shpath,shname,"-i",NULL); /* Yes, do that */
- } else { /* Otherwise, */
- execl(shpath,shname,"-c",s,NULL); /* exec the given command */
- } /* If execl() failed, */
- 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... */
-
-#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 if 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)
- 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
-isdir(s) char *s; {
- int x, needrlink = 0, islink = 0;
- struct stat statbuf;
- char fnam[CKMAXPATH+4];
-
- if (!s) return(0);
- 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:
- Long int, 0-based, indicating desired position.
- Returns:
- 0 on success.
- -1 on failure.
-*/
-#ifndef NORESEND
-int
-#ifdef CK_ANSIC
-zfseek(long pos)
-#else
-zfseek(pos) long pos;
-#endif /* CK_ANSIC */
-/* zfseek */ {
- zincnt = -1; /* Must empty the input buffer */
- debug(F101,"zfseek","",pos);
- return(fseek(fp[ZIFILE], pos, 0)?-1:0);
-}
-#endif /* NORESEND */
-
-/* Z F N Q F P -- Convert filename to fully qualified absolute pathname */
-
-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);
- debug(F111,"sgetpwnam","getspnam()",sp);
- if (sp == NULL)
- 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
- char *getusershell();
-#endif /* GETUSERSHELL */
-
-#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 (strcmp(cp, shell) == 0)
- break;
- }
- debug(F100,"zvuser endusershell 1","",0);
- endusershell();
- 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 */
-
-int
-zvpass(p) char *p; {
- 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);
- if (*p)
- pam_pw = p;
- 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 */
+++ /dev/null
-#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, 2004,
- 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;
-#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;
-
-#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-telnet", NP_SSL_TELNET, 0 },
-#endif /* CK_SSL */
- { "/telnet", NP_TELNET, 0 },
-#ifdef CK_SSL
- { "/tls", NP_TLS, 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, 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 }
-};
-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 */
-#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 */
-
-#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_VT320; /* Terminal type, initially VT320 */
-int tt_type_mode = TT_VT320; /* 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 */
- { "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;
- long 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");
- 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
- 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);
- }
-}
-
-#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));
- default: /* Shouldn't get here. */
- return(-2);
- }
-}
-#endif /* OS2 */
-
-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,"","vt320",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 */
- 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");
-#endif /* OS2 */
- return(success = 0);
-}
-
-#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 (nothing)");
- while ((c = *p++) && n < 131) {
- c &= 0xff;
- if (c == '\\') {
- if (n > 130) break;
- *q++ = '\\';
- *q++ = '\\';
- *q = NUL;
- n += 2;
- } else if ((c > 31 && 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);
-
-#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"
- , "\\v(newline)",&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);
-
- 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);
- }
- 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 = "";
- 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);
- }
- 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. */
- 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);
- }
- 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;
-
-#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(), ftpbye();
- 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
- case NP_SSL:
- ttnproto = protocol;
- ssl_only_flag = 1;
- tls_only_flag = 0;
- break;
-
- case NP_TLS:
- ttnproto = protocol;
- ssl_only_flag = 0;
- tls_only_flag = 1;
- break;
-
- case NP_SSL_TELNET:
- ttnproto = NP_TELNET;
- ssl_only_flag = 1;
- tls_only_flag = 0;
- break;
-
- case NP_TLS_TELNET:
- ttnproto = NP_TELNET;
- ssl_only_flag = 0;
- tls_only_flag = 1;
- break;
-#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
- ssl_only_flag = 0;
- tls_only_flag = 0;
-#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;
- }
-#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;
- 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);
- 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) {
- strncat(line," ",LINBUFSIZ);
- strncat(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.
-*/
-
-/* Define NOSTAT if the <#>include causes trouble. */
-
-#ifndef NOSTAT
-#ifdef VMS
-#ifdef VAXC /* As it does in VAX C */
-#define NOSTAT
-#endif /* VAXC */
-#endif /* VMS */
-#endif /* NOSTAT */
-
-#ifndef NOSTAT
-#include <sys/stat.h>
-#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, */
- long 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 */
- 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';
- }
- z_inited = 1; /* Remember we did */
- }
- for (n = -1, i = 0; i < z_maxchan; i++) {
- if (!z_file[i].z_fp) {
- n = i;
- break;
- }
- }
- 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... */
-
- 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 */
- 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_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 (!(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 */
- 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 (!(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 (!(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 */
- i = fread(s,1,length,t);
-#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 */
- z_file[channel].z_nline = -1; /* Current line no longer known */
- } 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","",ftell(t));
- for (i = 0; i < length; i++) {
- if ((x = getc(t)) == EOF) {
- debug(F101,"z_in getc error","",ftell(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;
- long 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 = ftell(t);
- if (pos > -1) {
- pos -= (x - j - 1);
- x = fseek(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 (!(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, long pos) /* Move file pointer to byte */
-#else
-z_seek(channel,pos) int channel; long 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 (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- if (pos < 0L) {
- x = 2;
- pos = (pos == -2) ? -1L : 0L;
- }
- errno = 0;
- rc = fseek(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, long pos) /* Move file pointer to line */
-#else
-z_line(channel,pos) int channel; long pos; /* (seek to given position) */
-#endif /* CK_ANSIC */
-{
- int i, len, x = 0;
- long current = 0L, prev = -1L, old = -1L;
- FILE * t;
- char tmpbuf[256];
- if (!z_inited) /* Check... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- debug(F101,"z_line pos","",pos);
- if (pos < 0L) { /* EOF wanted */
- long 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 = ftell(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 (!(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 (!(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 (ftell(t) == statbuf.st_size)
- x |= FM_EOF;
-#endif /* NOSTAT */
- }
- return(x);
-}
-
-long
-z_getpos(channel) int channel; { /* Get file pointer position */
- FILE * t; /* on this channel */
- long x;
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- x = ftell(t);
- return((x < 0L) ? (z_error = FX_SYS) : x);
-}
-
-long
-z_getline(channel) int channel; { /* Get current line number */
- FILE * t; /* in file on this channel */
- long rc;
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- 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 (!(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.
-*/
-long
-z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
- FILE * t;
- int i, x;
- long pos, count = 0L;
- if (!z_inited) /* Check stuff... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- pos = ftell(t); /* Save current file pointer */
- errno = 0;
- z_error = 0;
- if (what == RD_CHAR) { /* Size in bytes requested */
- if (!fseek(t,0L,2)) { /* Seek to end */
- count = ftell(t); /* Get file pointer */
- fseek(t,pos,0); /* Restore file file pointer */
- return(count);
- } else /* Fallback in case seek fails */
- 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 = fseek(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
-
-static struct keytab fskswtab[] = {
- { "/absolute", SEE_ABS, 0 },
- { "/byte", SEE_CHAR, 0 },
- { "/character", SEE_CHAR, CM_INV },
- { "/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 */
-
-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;
- struct FDB fl, sw, nu;
- long 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;
-
- 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 ere 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);
- }
- }
- 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(F101,"fopen /append x","",x);
- }
- if (x == -9) {
- if (zchko(s) < 0) {
- printf("Can't create \"%s\"\n",s);
- return(x);
- }
- } else 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 ((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 */
- cmfdbi(&sw, /* Second FDB - switches */
- _CMKEY, /* fcode */
- "Channel number; or keyword",
- "",
- "", /* addtl string data */
- 1, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- fclkwtab, /* Keyword table */
- &nu /* Pointer to next FDB */
- );
- cmfdbi(&nu, /* First FDB - command switches */
- _CMNUM, /* 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 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);
- 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);
- }
- 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);
- 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);
-
- line[0] = NUL; /* Clear destination buffer */
- if (rsize >= LINBUFSIZ) /* Don't overrun it */
- rsize = LINBUFSIZ - 1;
-
- 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;
- 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);
- 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);
- }
- cmfdbi(&sw, /* SEEK symbolic targets (EOF) */
- _CMKEY, /* fcode */
- "Channel number;\n or keyword",
- "",
- "", /* 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, /* Channel number */
- _CMNUM, /* 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 == _CMNUM) {
- y = cmresult.nresult;
- 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);
- z = y; /* Convert to long */
- 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) {
- long pos;
- pos = z_getpos(n);
- if (pos < 0L) {
- 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) {
- long pos;
- pos = z_getline(n);
- debug(F101,"FILE SEEK /LINE pos","",pos);
- if (pos < 0L) {
- 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);
- }
- }
- return(success = y);
-
- 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: %4d\n", z_openmax);
- printf("Maximum for FILE OPEN: %4d\n", z_maxchan);
- printf("Files currently open: %4d\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 > -1) {
- 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
- printf(" %ld",z_getpos(i)); /* And file position too */
- }
- 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 ((rc = z_flush(n)) < 0) {
- printf("?FLUSH failed - Channel %d: %s\n",n,ckferror(rc));
- return(-9);
- }
- return(success = 1);
-
- case FIL_STA: /* STATUS */
- 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);
- 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 {
- long 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: %ld\n",z_count(n,RD_CHAR));
- printf(" At byte: %ld\n",z_getpos(n));
- xx = z_getline(n);
- if (xx > -1)
- printf(" At line: %ld\n",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));
- break;
-#endif /* NORECALL */
-
-#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;
- 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;
- }
-
-#ifdef CK_SSL
- 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 { /* Temporary array for switch values */
- char * sval; /* String value */
- int ival; /* Integer value */
- } pv[KRB_I_MAX+1]; /* This many */
- 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 */
- }
-
- 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 CK_PAM
- extern int guest;
-#endif /* CK_PAM */
- 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 CK_PAM
- && guest
-#endif /* CK_PAM */
- ) {
- 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 */
- 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);
- }
- 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);
- }
-
- 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 */