From c298fb9a5c2430cfc8fd22800ee25eabf900cf6b Mon Sep 17 00:00:00 2001 From: Ian Beckwith Date: Sat, 28 Jan 2012 22:55:13 +0000 Subject: [PATCH] 040_pam-password-prompting: pop patch --- .pc/040_pam-password-prompting.patch/.timestamp | 0 .pc/040_pam-password-prompting.patch/ckufio.c | 8310 ------------ .pc/040_pam-password-prompting.patch/ckuus7.c | 14933 ---------------------- .pc/applied-patches | 1 - ckufio.c | 11 +- ckuus7.c | 27 +- 6 files changed, 6 insertions(+), 23276 deletions(-) delete mode 100644 .pc/040_pam-password-prompting.patch/.timestamp delete mode 100644 .pc/040_pam-password-prompting.patch/ckufio.c delete mode 100644 .pc/040_pam-password-prompting.patch/ckuus7.c diff --git a/.pc/040_pam-password-prompting.patch/.timestamp b/.pc/040_pam-password-prompting.patch/.timestamp deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/040_pam-password-prompting.patch/ckufio.c b/.pc/040_pam-password-prompting.patch/ckufio.c deleted file mode 100644 index 298c48e..0000000 --- a/.pc/040_pam-password-prompting.patch/ckufio.c +++ /dev/null @@ -1,8310 +0,0 @@ -/* C K U F I O -- Kermit file system support for UNIX, Aegis, and Plan 9 */ - -#define CK_NONBLOCK /* See zoutdump() */ - -#ifdef aegis -char *ckzv = "Aegis File support, 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 , - 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 -#include - -#ifdef MINIX2 -#undef MINIX -#undef CKSYSLOG -#include -#include -#define NOFILEH -#endif /* MINIX2 */ - -#ifdef MINIX -#include -#include -#include -#else -#ifdef POSIX -#include -#else -#ifdef SVR3 -#include -#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 -#else /* !XNDIR */ -#ifdef NDIR -#include -#else /* !NDIR, !XNDIR */ -#ifdef RTU -#include "/usr/lib/ndir.h" -#else /* !RTU, !NDIR, !XNDIR */ -#ifdef DIRENT -#ifdef SDIRENT -#include -#else -#include -#endif /* SDIRENT */ -#else -#include -#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 /* Password file for shell name */ -#ifdef CK_SRP -#include /* SRP Password file */ -#endif /* CK_SRP */ - -#ifdef HPUX10_TRUSTED -#include -#include -#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 /* if requested, */ -#include /* for extra fields required by */ -#else /* 88Open spec. */ -#ifdef UTIMEH /* or if requested */ -#include /* (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, . 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 -#include - -#else /* Not BSD44 */ - -#ifdef BSD4 /* BSD 4.3 and below */ -#define TIMESTAMP /* Can do file dates */ -#include /* Need this */ -#include /* 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 - -/* 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 -#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 /* File status */ -#else -#include -#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 /* */ -#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 -#endif /* NOFILEH */ - -#ifndef is68k /* Whether to include */ -#ifndef BSD41 /* All but a couple UNIXes have it. */ -#ifndef FT18 -#ifndef COHERENT -#include -#endif /* COHERENT */ -#endif /* FT18 */ -#endif /* BSD41 */ -#endif /* is68k */ - -#ifdef COHERENT -#ifdef _I386 -#include -#else -#include -#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 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 -#endif /* CK_SHADOW */ -#ifdef CK_PAM /* PAM... */ -#include -#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... , , , , ... - 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 /* For MAXPATHLEN */ -#endif /* BSD44 */ -#ifdef COHERENT -#include /* 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 */ -_PROTOTYP( FILE * fdopen, (int, char *) ); -#endif /* DCLFDOPEN */ - -#ifdef DCLPOPEN -/* popen() needs declaring because it's not declared in */ -_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 -#else /* RTAIX */ -#include -#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 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 -#include -#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 */ -#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 -#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 -#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 - . See the section for including 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 ".~~", where is argument name - (fn), and 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 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.~~" */ - 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, */ -#define OPENDIR - DIR *fd, *opendir(); - struct dirent *dirbuf; - struct dirent *readdir(); -#else /* !DIRENT */ -#ifdef LONGFN /* Old way, with opendir() */ -#define OPENDIR - DIR *fd, *opendir(); - struct direct *dirbuf; -#else /* !LONGFN */ - int fd; /* Old way, 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" */ - 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 /.txt lists every file in * and does not even open up the - subdirectories. However, "dir /rec /.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 */ diff --git a/.pc/040_pam-password-prompting.patch/ckuus7.c b/.pc/040_pam-password-prompting.patch/ckuus7.c deleted file mode 100644 index 4268ef1..0000000 --- a/.pc/040_pam-password-prompting.patch/ckuus7.c +++ /dev/null @@ -1,14933 +0,0 @@ -#include "ckcsym.h" - -/* C K U U S 7 -- "User Interface" for C-Kermit, part 7 */ - -/* - Authors: - Frank da Cruz , - The Kermit Project, Columbia University, New York City - Jeffrey E Altman - 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 -#endif /* TCPSOCKET */ -#endif /* VMS */ - -#ifdef OS2 -#ifndef NT -#define INCL_NOPM -#define INCL_VIO /* Needed for ckocon.h */ -#define INCL_DOSMODULEMGR -#include -#undef COMMENT -#else /* NT */ -#define APIRET ULONG -#include -#include -#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 */ - 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 */ - 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 */ - 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 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 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 */ -#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 -#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 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:""); -#endif /* OS2 */ - printf(" Anonymous Initfile: %s\r\n",anonfile?anonfile:""); - printf(" Anonymous Login: %d\r\n",ckxanon); - printf(" Anonymous Root: %s\r\n",anonroot?anonroot:""); -#endif /* CK_LOGIN */ - printf(" Bannerfile: %s\r\n",bannerfile?bannerfile:""); - printf(" CDfile: %s\r\n",cdmsgfile[0]?cdmsgfile[0]:""); - 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:""); - 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:""); - printf(" Initfile: %s\r\n",kermrc?kermrc:""); - 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:""); -#ifdef CK_LOGIN -#ifdef CKWTMP - printf(" Wtmplog: %d\r\n",ckxwtmp); - printf(" Wtmpfile: %s\r\n",wtmpfile?wtmpfile:""); -#endif /* CKWTMP */ -#endif /* CK_LOGIN */ - printf(" Xferfile: %s\r\n",xferfile?xferfile:""); - 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: */ - 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: */ - 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: */ - 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: */ - 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: */ - 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: */ - 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: */ - 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: */ - 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:{} */ - 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 */ diff --git a/.pc/applied-patches b/.pc/applied-patches index 6b6c6e7..d705a33 100644 --- a/.pc/applied-patches +++ b/.pc/applied-patches @@ -1,4 +1,3 @@ 010_makefile-destdir-support.patch 020_man-hyphen-quoting.patch 030_fix-if-else.patch -040_pam-password-prompting.patch diff --git a/ckufio.c b/ckufio.c index 4648104..298c48e 100644 --- a/ckufio.c +++ b/ckufio.c @@ -490,9 +490,6 @@ extern char * anonroot; static char guestpass[GUESTPASS] = { NUL, NUL }; /* Anonymous "password" */ static int logged_in = 0; /* Set when user is logged in */ static int askpasswd = 0; /* Have OK user, must ask for passwd */ -#ifdef CK_PAM -extern int gotemptypasswd; -#endif /* CK_PAM */ #endif /* CK_LOGIN */ #ifdef CKROOT @@ -8046,12 +8043,8 @@ zvpass(p) char *p; { } } debug(F110,"zvpass","calling pam_authenticate",0); - if (*p -#ifdef CK_LOGIN - || gotemptypasswd -#endif /* CK_LOGIN */ - ) - pam_pw = p; + 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); diff --git a/ckuus7.c b/ckuus7.c index 8801478..4268ef1 100644 --- a/ckuus7.c +++ b/ckuus7.c @@ -98,12 +98,6 @@ extern int g_matchdot, hints, xcmdsrc, rcdactive; extern char * k_info_dir; -#ifdef CK_LOGIN -#ifdef CK_PAM -int gotemptypasswd = 0; /* distinguish empty passwd from none given */ -#endif /* CK_PAM */ -#endif /* CK_LOGIN */ - #ifndef NOSPL extern int nmac; extern struct mtab *mactab; @@ -14662,9 +14656,9 @@ ckxlogin(userid, passwd, acct, promptok) #ifdef CK_RECALL extern int on_recall; /* around Password prompting */ #endif /* CK_RECALL */ -#ifdef COMMENT +#ifdef CK_PAM extern int guest; -#endif /* COMMENT */ +#endif /* CK_PAM */ int rprompt = 0; /* Restore prompt */ #ifdef CKSYSLOG int savlog; @@ -14780,9 +14774,9 @@ ckxlogin(userid, passwd, acct, promptok) debug(F111,"ckxlogin zvuser",userid,ok); if (!*passwd && promptok -#ifdef COMMENT +#ifdef CK_PAM && guest -#endif /* COMMENT */ +#endif /* CK_PAM */ ) { char prmpt[80]; @@ -14858,9 +14852,6 @@ ckxlogin(userid, passwd, acct, promptok) if (pflag) prompt(xxstring); /* Issue prompt if at top level */ cmres(); /* Reset the parser */ for (x = -1; x < 0;) { /* Prompt till they answer */ -#ifdef CK_PAM - gotemptypasswd=0; -#endif /* CK_PAM */ x = cmtxt("","",&s,NULL); /* Get a literal line of text */ if (x == -4 || x == -10) { printf("\r\n%sLogin cancelled\n", @@ -14870,10 +14861,6 @@ ckxlogin(userid, passwd, acct, promptok) #endif /* CKSYSLOG */ doexit(GOOD_EXIT,0); } -#ifdef CK_PAM - if(!*s) - gotemptypasswd=1; -#endif /* CK_PAM */ if (sstate) /* In case of a Kermit packet */ goto XCKXLOG; cmres(); /* Reset the parser again */ @@ -14908,12 +14895,6 @@ ckxlogin(userid, passwd, acct, promptok) if (ok) { ok = zvpass((char *)passwd); /* Check password */ debug(F101,"ckxlogin zvpass","",ok); -#ifdef CK_PAM - } else { - /* Fake pam password failure for nonexistent users */ - sleep(1); - printf("Authentication failure\n"); -#endif } if (ok > 0 && isguest) { -- 2.11.0