| #include "ckcsym.h" |
| |
| /* C K U U S X -- "User Interface" common functions. */ |
| |
| /* |
| Authors: |
| Frank da Cruz <fdc@columbia.edu>, |
| The Kermit Project, Columbia University, New York City |
| Jeffrey E Altman <jaltman@secure-endpoints.com> |
| Secure Endpoints Inc., New York City |
| |
| Copyright (C) 1985, 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 module contains user interface functions needed by both the interactive |
| user interface and the command-line-only user interface. |
| */ |
| |
| /* Includes */ |
| |
| #include "ckcdeb.h" |
| #include "ckcasc.h" |
| #include "ckcker.h" |
| #include "ckuusr.h" |
| #include "ckcxla.h" |
| |
| #ifndef NOHTERMCAP |
| #ifdef NOTERMCAP |
| #define NOHTERMCAP |
| #else |
| #ifndef BSD44 |
| #define NOHTERMCAP |
| #else |
| #ifdef __bsdi__ |
| #define NOHTERMCAP |
| #else |
| #ifdef OPENBSD |
| #define NOHTERMCAP |
| #else |
| #ifdef MACOSX |
| #define NOHTERMCAP |
| #endif /* MACOSX */ |
| #endif /* OPENBSD */ |
| #endif /* __bsdi__ */ |
| #endif /* BSD44 */ |
| #endif /* NOTERMCAP */ |
| #endif /* NOHTERMCAP */ |
| |
| #ifndef NOTERMCAP |
| #ifdef BSD44 |
| #ifndef NOHTERMCAP |
| #include <termcap.h> |
| #endif /* NOHTERMCAP */ |
| #endif /* BSD44 */ |
| #else /* !BSD44 */ |
| #ifdef linux |
| #include <term.h> |
| #endif /* linux */ |
| #endif /* NOTERMCAP */ |
| |
| #ifdef OS2 |
| #include <string.h> |
| _PROTOTYP(char * os2_gethostname, (void)); |
| #define getpid _getpid |
| #endif /* OS2 */ |
| #ifdef BSD44 |
| #include <errno.h> |
| #endif /* BSD44 */ |
| |
| extern xx_strp xxstring; |
| |
| #ifdef OS2 |
| #include "ckcnet.h" |
| #else /* OS2 */ |
| _PROTOTYP(int getlocalipaddr, (void)); |
| _PROTOTYP(int istncomport, (void)); |
| #ifndef NOCKGETFQHOST |
| _PROTOTYP( char * ckgetfqhostname,(char *)); |
| #endif /* NOCKGETFQHOST */ |
| #ifndef NETCONN |
| /* |
| We should just pull in ckcnet.h here, but it causes a conflict with curses.h. |
| */ |
| #ifdef TCPSOCKET |
| #define NETCONN |
| #else |
| #ifdef SUNX25 |
| #define NETCONN |
| #else |
| #ifdef STRATUSX25 |
| #define NETCONN |
| #else |
| #ifdef IBMX25 |
| #define NETCONN |
| #else |
| #ifdef HPX25 |
| #define NETCONN |
| #else |
| #ifdef DECNET |
| #define NETCONN |
| #else |
| #ifdef NPIPE |
| #define NETCONN |
| #else |
| #ifdef CK_NETBIOS |
| #define NETCONN |
| #ifdef SUPERLAT |
| #define NETCONN |
| #else |
| #endif /* SUPERLAT */ |
| #endif /* TCPSOCKET */ |
| #endif /* SUNX25 */ |
| #endif /* STRATUSX25 */ |
| #endif /* IBMX25 */ |
| #endif /* HPX25 */ |
| #endif /* DECNET */ |
| #endif /* NPIPE */ |
| #endif /* CK_NETBIOS */ |
| #endif /* NETCONN */ |
| #endif /* OS2 */ |
| |
| #ifndef TCPSOCKET |
| #ifdef MULTINET |
| #define TCPSOCKET |
| #endif /* MULTINET */ |
| #ifdef DEC_TCPIP |
| #define TCPSOCKET |
| #endif /* DEC_TCPIP */ |
| #ifdef WINTCP |
| #define TCPSOCKET |
| #endif /* WINTCP */ |
| #ifdef TCPWARE |
| #define TCPSOCKET |
| #endif /* TCPWARE */ |
| #endif /* TCPSOCKET */ |
| |
| #ifdef OS2 |
| #ifdef NT |
| #include <windows.h> |
| #include <tapi.h> |
| #include "ckntap.h" |
| #else /* NT */ |
| #define INCL_VIO |
| #include <os2.h> |
| #endif /* NT */ |
| #ifdef COMMENT /* Would you believe */ |
| #undef COMMENT /* <os2.h> defines this ? */ |
| #endif /* COMMENT */ |
| #ifdef CK_NETBIOS |
| #include "ckonbi.h" |
| #endif /* CK_NETBIOS */ |
| |
| #include "ckocon.h" |
| extern ascreen commandscreen; |
| #ifdef KUI |
| #include "ikui.h" |
| #endif /* KUI */ |
| #endif /* OS2 */ |
| |
| #ifdef NT |
| #include "cknwin.h" |
| #endif /* NT */ |
| #ifdef OS2 |
| #include "ckowin.h" |
| #include "ckosyn.h" |
| #endif /* OS2 */ |
| |
| #ifdef CK_TAPI |
| extern int tttapi; |
| extern int tapipass; |
| #endif /* CK_TAPI */ |
| |
| #ifdef CK_KERBEROS |
| #include "ckuath.h" |
| #endif /* CK_KERBEROS */ |
| |
| #ifndef WINTCP |
| #include <signal.h> |
| #endif /* WINTCP */ |
| |
| #ifdef VMS |
| #include <descrip.h> |
| #include <ssdef.h> |
| #include <stsdef.h> |
| #ifndef OLD_VMS |
| #include <lib$routines.h> /* Not for VAX C 2.3 */ |
| #else |
| #include <libdef.h> |
| #endif /* OLD_VMS */ |
| #ifdef WINTCP |
| #include <signal.h> |
| #endif /* WINTCP */ |
| #endif /* VMS */ |
| |
| #ifdef DCLFDOPEN |
| /* fdopen() needs declaring because it's not declared in <stdio.h> */ |
| _PROTOTYP( FILE * fdopen, (int, char *) ); |
| #endif /* DCLFDOPEN */ |
| |
| #ifdef DCLPOPEN |
| /* popen() needs declaring because it's not declared in <stdio.h> */ |
| _PROTOTYP( FILE * popen, (char *, char *) ); |
| #endif /* DCLPOPEN */ |
| |
| int tt_crd = 0; /* Carriage return display */ |
| int interrupted = 0; /* Interrupted from keyboard flag */ |
| static int fxd_inited = 0; /* Fullscreen stuff initialized */ |
| |
| #ifdef DEBUG |
| char debfil[CKMAXPATH+1]; /* Debugging log file name */ |
| #endif /* DEBUG */ |
| |
| #ifdef TLOG |
| char trafil[CKMAXPATH+1]; /* Transaction log file name */ |
| #endif /* TLOG */ |
| |
| char sesfil[CKMAXPATH+1]; /* Session log file name */ |
| |
| #ifdef CKLOGDIAL |
| char diafil[CKMAXPATH+1]; /* Connection log file name */ |
| char cxlogbuf[CXLOGBUFL+1]; /* Connection log record buffer */ |
| int cx_active = 0; /* Connection is active */ |
| extern int dialog; |
| #endif /* CKLOGDIAL */ |
| |
| #ifdef DYNAMIC |
| static char *cmdstr = NULL; /* Place to build generic command */ |
| #else |
| #ifdef pdp11 |
| static char cmdstr[256]; |
| #else |
| static char cmdstr[4096]; |
| #endif /* pdp11 */ |
| #endif /* DYNAMIC */ |
| |
| #ifndef NOMSEND |
| char fspec[CMDBL+4]; /* Filename string for \v(filespec) */ |
| int fspeclen = CMDBL; |
| #else |
| char fspec[CKMAXPATH+4]; |
| int fspeclen = CKMAXPATH; |
| #endif /* NOMSEND */ |
| |
| char * rfspec = NULL; /* Received filespec: local */ |
| char * prfspec = NULL; /* Preliminary rfspec */ |
| char * sfspec = NULL; /* Sent filespec: local */ |
| char * psfspec = NULL; /* Preliminary sfspec */ |
| char * srfspec = NULL; /* Received filespec: remote */ |
| char * psrfspec = NULL; /* Preliminary srfspec */ |
| char * rrfspec = NULL; /* Sent filespec: remote */ |
| char * prrfspec = NULL; /* Preliminary rrfspec */ |
| |
| int success = 1, /* Command success/failure flag */ |
| cmdlvl = 0, /* Command level */ |
| action = 0, /* Action selected on command line */ |
| slogts = 0, /* Session-log timestamps on/off */ |
| #ifdef UNIX |
| sessft = XYFT_T, /* Session log file type */ |
| #else |
| sessft = XYFT_B, /* (text for UNIX binary for others) */ |
| #endif /* UNIX */ |
| pflag = 1, /* Print prompt */ |
| msgflg = 1; /* Print informational messages */ |
| |
| extern int xaskmore, saveask; /* More-prompting */ |
| |
| #ifdef CK_APC |
| extern int apcactive; |
| #endif /* CK_APC */ |
| /* External variables */ |
| |
| extern int local, quiet, binary, network, what, parity, xitsta, escape, |
| tlevel, bgset, backgrd, xsuspend, cmdint, nettype, seslog, dfloc; |
| |
| extern int cmd_rows, cmd_cols, xcmdsrc; |
| |
| extern char cmdfil[]; |
| |
| #ifdef VMS |
| extern int batch; |
| #endif /* VMS */ |
| |
| #ifdef datageneral /* 2/12/92 ENH */ |
| #include <sysid.h> |
| extern int con_reads_mt, conint_ch, conint_avl; |
| #endif /* datageneral */ |
| |
| extern long speed; |
| |
| extern char ttname[], *dftty, *cmarg, **cmlist, *versio, myhost[]; |
| |
| #ifndef NOCSETS |
| extern int fcharset, tcharset, xfrxla; |
| extern struct csinfo fcsinfo[], tcsinfo[]; |
| #endif /* NOCSETS */ |
| |
| #ifdef OS2 |
| extern unsigned char colorcmd; |
| #endif /* OS2 */ |
| |
| #ifdef NOXFER |
| |
| int fdispla = XYFD_N; |
| |
| #else /* NOXFER is not defined */ |
| |
| #ifdef OS2 /* File transfer display type */ |
| int fdispla = XYFD_C; /* Curses (fullscreen) if we have it */ |
| #else |
| #ifdef CK_CURSES |
| int fdispla = XYFD_C; |
| #else |
| int fdispla = XYFD_S; /* Otherwise CRT */ |
| #endif /* CK_CURSES */ |
| #endif /* OS2 */ |
| |
| extern struct ck_p ptab[]; |
| extern int protocol, xfrbel, xfrint; |
| |
| #ifdef STREAMING |
| extern int streaming, streamok; |
| #endif /* STREAMING */ |
| |
| /* Used internally */ |
| |
| _PROTOTYP( VOID screenc, (int, char, long, char *) ); |
| _PROTOTYP( VOID screeng, (int, char, long, char *) ); |
| |
| #ifdef CK_CURSES |
| #ifndef DYNAMIC |
| static char xtrmbuf[TRMBUFL]; /* tgetent() buffer */ |
| char * trmbuf = xtrmbuf; |
| #else |
| char * trmbuf = NULL; |
| #endif /* DYNAMIC */ |
| _PROTOTYP( static VOID dpyinit, (void) ); |
| _PROTOTYP( static long shocps, (int, long, long) ); |
| _PROTOTYP( static long shoetl, (long, long, long, long) ); |
| #endif /* CK_CURSES */ |
| |
| static int ft_win = 0; /* Fullscreen file transfer display window is active */ |
| |
| /* Variables declared here */ |
| |
| static char * skreason[] = { |
| "", /* 0 */ |
| "Remote file not older", /* SKP_DAT */ |
| "Identical modification times", /* SKP_EQU */ |
| "Type", /* SKP_TYP */ |
| "Size", /* SKP_SIZ */ |
| "Name collision", /* SKP_NAM */ |
| "Exception List", /* SKP_EXL */ |
| "Dot file", /* SKP_DOT */ |
| "Backup file", /* SKP_BKU */ |
| "Recovery not needed", /* SKP_RES */ |
| "Access denied", /* SKP_ACC */ |
| "Not a regular file", /* SKP_NRF */ |
| "Simulated", /* SKP_SIM */ |
| "Simulated - Remote file older", /* SKP_XUP */ |
| "Simulated - No remote file", /* SKP_XNX */ |
| }; |
| static int nskreason = (sizeof(skreason) / sizeof(char *)); |
| |
| char * |
| gskreason(n) int n; { |
| return((n > 0 && n < nskreason) ? skreason[n] : ""); |
| } |
| |
| char pktfil[CKMAXPATH+1]; /* Packet log file name */ |
| |
| #ifndef NOMSEND /* Multiple SEND */ |
| char *msfiles[MSENDMAX]; |
| #endif /* NOMSEND */ |
| |
| #ifdef CK_TIMERS |
| extern long rttdelay; |
| extern int rttflg; |
| #endif /* CK_TIMERS */ |
| extern int rcvtimo; |
| |
| #ifdef CK_RESEND |
| extern int sendmode; |
| extern long sendstart, rs_len; |
| #endif /* CK_RESEND */ |
| |
| #ifdef CK_PCT_BAR /* File transfer thermometer */ |
| int thermometer = 1; /* ON by default */ |
| #endif /* CK_PCT_BAR */ |
| |
| #ifdef GFTIMER |
| CKFLOAT gtv = -1.0, oldgtv = -1.0; |
| #else |
| #ifndef OS2 |
| static |
| #endif /* OS2 */ |
| long gtv = -1L, oldgtv = -1L; |
| #endif /* GFTIMER */ |
| |
| extern int server, bctu, rptflg, ebqflg, spsiz, urpsiz, wmax, czseen, cxseen, |
| winlo, displa, timint, npad, ebq, bctr, rptq, atcapu, lpcapu, |
| swcapu, wslotn, wslotr, rtimo, mypadn, sq, capas, rpsiz, tsecs, |
| pktlog, lscapu, dest, srvdis, wslots, spackets, spktl, rpktl, |
| retrans, wcur, numerrs, fsecs, whatru, crunched, timeouts, |
| rpackets, fncnv, bye_active, discard, inserver, diractive, cdactive; |
| |
| extern long filcnt, filrej, ffc, tfc, rptn, fsize, filcps, tfcps, cps, peakcps; |
| |
| long oldcps = 0L; |
| |
| extern CHAR *rdatap, padch, seol, ctlq, mypadc, eol, *epktmsg; |
| extern char *xfrmsg; |
| |
| #ifdef IKSDB |
| FILE * dbfp = NULL; /* File pointer to database file */ |
| |
| int dbenabled = 1; /* Flag for database is enabled */ |
| extern int ikdbopen; /* Flag for database is open */ |
| |
| unsigned long mydbseek = 0L; /* Seek pointer to my record */ |
| int mydbslot = 0; /* My slot number */ |
| unsigned long myflags = 0L; /* My flags */ |
| unsigned long myatype = 0L; /* My authorization type */ |
| unsigned long myamode = 0L; /* My authorization mode */ |
| unsigned long mystate = 0L; /* My state (SEND, RECEIVE, etc) */ |
| unsigned long mypid = 0L; /* My PID */ |
| unsigned long myip = 0L; /* My IP address */ |
| unsigned long peerip = 0L; /* My peer's IP address */ |
| |
| unsigned long dbip = 0L; /* IP address in db record */ |
| unsigned long dbpid = 0L; /* PID in db record */ |
| unsigned long dbflags = 0L; /* Flags field in db record */ |
| unsigned long dblastused = 0L; /* Last in-use record in db */ |
| char dbrec[DB_RECL]; /* Database record buffer */ |
| |
| char * dbdir = NULL; /* Database directory */ |
| char * dbfile = NULL; /* Database file full pathname */ |
| char myhexip[33] = { NUL, NUL }; /* My IP address in hex */ |
| char peerhexip[33] = { NUL, NUL }; /* Client's IP address in hex */ |
| #endif /* IKSDB */ |
| |
| #ifdef GFTIMER |
| extern CKFLOAT fpfsecs, fptsecs, fpxfsecs; |
| #else |
| extern long xfsecs; |
| #endif /* GFTIMER */ |
| #endif /* NOXFER */ |
| |
| #ifdef TCPSOCKET |
| #ifdef NEWFTP |
| extern char * ftp_host, ftp_srvtyp[]; |
| extern int ftp_csx, ftp_csl, ftp_deb; |
| #endif /* NEWFTP */ |
| extern char myipaddr[]; |
| #endif /* TCPSOCKET */ |
| |
| #ifndef NOICP |
| #ifndef NOSPL |
| extern struct mtab *mactab; /* For ON_EXIT macro. */ |
| extern int nmac; |
| #endif /* NOSPL */ |
| #ifdef DCMDBUF |
| extern char *cmdbuf; /* Command buffer */ |
| #else |
| extern char cmdbuf[]; /* Command buffer */ |
| #endif /* DCMDBUF */ |
| extern int cmd_quoting; |
| #endif /* NOICP */ |
| |
| #ifndef NOCCTRAP |
| #ifdef NT |
| #include <setjmpex.h> |
| #else /* NT */ |
| #include <setjmp.h> |
| #endif /* NT */ |
| #include "ckcsig.h" |
| extern ckjmpbuf cmjbuf; |
| #endif /* NOCCTRAP */ |
| |
| extern int xfiletype, nscanfile; |
| |
| int |
| shoesc(escape) int escape; { |
| extern char * ccntab[]; /* C0 control character name table */ |
| extern int tt_escape; |
| if ((escape > 0 && escape < 32) || (escape == 127)) { |
| printf(" Escape character: Ctrl-%c (ASCII %d, %s): %s\r\n", |
| ctl(escape), |
| escape, |
| (escape == 127 ? "DEL" : ccntab[escape]), |
| tt_escape ? "enabled" : "disabled" |
| ); |
| } else { |
| printf(" Escape character: Code %d",escape); |
| if (escape > 160 && escape < 256) |
| printf(" (%c)",escape); |
| printf(": %s\r\n", tt_escape ? "enabled" : "disabled"); |
| } |
| return(0); |
| } |
| |
| #ifndef NOXFER |
| /* P R E S E T -- Reset global protocol variables */ |
| |
| extern int recursive; |
| |
| #ifdef PATTERNS |
| int patterns = SET_AUTO; /* Whether to use filename patterns */ |
| extern int g_patterns; /* For saving and restoring */ |
| #else |
| int patterns = SET_OFF; |
| #endif /* PATTERNS */ |
| |
| #ifndef NOICP |
| #ifdef CK_LABELED |
| extern int g_lf_opts, lf_opts; |
| #endif /* CK_LABELED */ |
| extern int g_matchdot, g_usepipes, usepipes; |
| extern int g_binary, g_proto, g_displa, g_spath, g_rpath, g_fncnv; |
| extern int g_recursive; |
| extern int g_xfermode, xfermode; |
| extern int g_urpsiz, g_spsizf, g_spsiz; |
| extern int g_spsizr, g_spmax, g_wslotr, g_prefixing, g_fncact; |
| extern int g_fnspath, g_fnrpath, g_skipbup; |
| extern int nolinks; |
| #ifdef CKSYMLINK |
| extern int zgfs_link; |
| #endif /* CKSYMLINK */ |
| #ifndef NOSPL |
| extern int g_pflg, pwflg, g_pcpt, pwcrypt; |
| extern char * g_pswd, pwbuf[]; |
| #endif /* NOSPL */ |
| #endif /* NOICP */ |
| |
| extern int spsizf, spsizr, spmax, prefixing, fncact, fnspath, fnrpath; |
| extern int moving; /* SEND criteria */ |
| extern char sndafter[], sndbefore[], *sndexcept[], *rcvexcept[]; |
| extern long sndlarger, sndsmaller, calibrate, skipbup; |
| extern int rmailf, rprintf; |
| extern char optbuf[]; |
| |
| #ifdef PIPESEND |
| extern char * g_sfilter, * g_rfilter; |
| extern char * sndfilter, * rcvfilter; |
| #endif /* PIPESEND */ |
| extern char ** sndarray; |
| |
| VOID |
| ftreset() { |
| #ifndef NOICP |
| int i; |
| extern char * filefile; |
| extern int reliable, xreliable, c_save, ss_save, slostart, urclear; |
| extern int oopts, omode, oname, opath, kactive, autopath; |
| extern char * snd_move; /* Directory to move sent files to */ |
| extern char * snd_rename; /* What to rename sent files to */ |
| extern char * rcv_move; |
| extern char * rcv_rename; |
| extern char * g_snd_move; |
| extern char * g_snd_rename; |
| extern char * g_rcv_move; |
| extern char * g_rcv_rename; |
| |
| #ifdef CK_TMPDIR |
| extern int f_tmpdir; |
| extern char savdir[]; |
| #endif /* CK_TMPDIR */ |
| |
| #ifdef CK_SPEED |
| #ifdef COMMENT |
| extern int f_ctlp; |
| extern short s_ctlp[], ctlp[]; |
| #endif /* COMMENT */ |
| #endif /* CK_SPEED */ |
| |
| #ifndef NOCSETS |
| extern int fcs_save, tcs_save; |
| extern int g_xfrxla, xfrxla; |
| #endif /* NOCSETS */ |
| |
| /* Restore / reset per-command file-transfer switches */ |
| |
| makestr(&snd_move,g_snd_move); |
| makestr(&rcv_move,g_rcv_move); |
| makestr(&snd_rename,g_snd_rename); |
| makestr(&rcv_rename,g_rcv_rename); |
| |
| kactive = 0; /* Kermit protocol no longer active */ |
| oopts = -1; /* O-Packet Options */ |
| omode = -1; /* O-Packet Transfer Mode */ |
| oname = -1; /* O-Packet Filename Options */ |
| opath = -1; /* O-Packet Pathname Options */ |
| |
| #ifdef CK_RESEND |
| rs_len = 0L; /* REGET position */ |
| #endif /* CK_RESEND */ |
| |
| #ifdef COMMENT |
| #ifdef CK_SPEED |
| if (f_ctlp) { |
| for (i = 0; i < 256; i++) |
| ctlp[i] = s_ctlp[i]; |
| f_ctlp = 0; |
| } |
| #endif /* CK_SPEED */ |
| #endif /* COMMENT */ |
| |
| #ifdef CK_TMPDIR |
| if (f_tmpdir) { /* If we changed to download dir */ |
| zchdir((char *) savdir); /* Go back where we came from */ |
| f_tmpdir = 0; |
| } |
| #endif /* CK_TMPDIR */ |
| |
| calibrate = 0L; /* Calibration run */ |
| if (xreliable > -1) { |
| reliable = xreliable; |
| debug(F101,"ftreset reliable","",reliable); |
| } |
| urclear = 0; |
| |
| if (autopath) { /* SET RECEIVE PATHNAMES AUTO */ |
| fnrpath = PATH_AUTO; |
| autopath = 0; |
| } |
| if (filefile) { /* File list */ |
| zclose(ZMFILE); |
| makestr(&filefile,NULL); |
| } |
| if (c_save > -1) { /* Block Check Type */ |
| bctr = c_save; |
| c_save = -1; |
| } |
| if (ss_save > -1) { /* Slow Start */ |
| slostart = ss_save; |
| ss_save = -1; |
| } |
| #ifdef CK_LABELED |
| if (g_lf_opts > -1) { |
| lf_opts = g_lf_opts; /* Restore labeled transfer options */ |
| g_lf_opts = -1; |
| } |
| #endif /* CK_LABELED */ |
| |
| #ifndef NOCSETS |
| if (tcs_save > -1) { /* Character sets */ |
| tcharset = tcs_save; |
| tcs_save = -1; |
| } |
| if (fcs_save > -1) { |
| fcharset = fcs_save; |
| fcs_save = -1; |
| } |
| if (g_xfrxla > -1) { |
| xfrxla = g_xfrxla; |
| g_xfrxla = -1; |
| } |
| setxlatype(tcharset,fcharset); /* Translation type */ |
| #endif /* NOCSETS */ |
| |
| #ifdef NETCONN |
| #ifndef NOSPL |
| if (g_pswd) { |
| ckstrncpy(pwbuf,g_pswd,PWBUFL); |
| makestr(&g_pswd,NULL); |
| } |
| if (g_pflg > -1) { |
| pwflg = g_pflg; |
| g_pflg = -1; |
| } |
| if (g_pcpt > -1) { |
| pwcrypt = g_pcpt; |
| g_pcpt = -1; |
| } |
| #endif /* NOSPL */ |
| #endif /* NETCONN */ |
| |
| if (g_binary > -1) { /* File type */ |
| binary = g_binary; |
| g_binary = -1; |
| } |
| if (g_xfermode > -1) { /* Transfer mode */ |
| xfermode = g_xfermode; |
| g_xfermode = -1; |
| } |
| #ifdef PATTERNS |
| if (g_patterns > -1) { /* Filename patterns */ |
| patterns = g_patterns; |
| g_patterns = -1; |
| } |
| #endif /* PATTERNS */ |
| |
| if (g_usepipes > -1) { |
| usepipes = g_usepipes; |
| g_usepipes = -1; |
| } |
| if (g_matchdot > -1) { |
| matchdot = g_matchdot; |
| g_matchdot = -1; |
| } |
| if (g_proto > -1) { /* Protocol */ |
| protocol = g_proto; |
| g_proto = -1; |
| } |
| if (g_urpsiz > -1) { |
| urpsiz = g_urpsiz; |
| debug(F101,"ftreset restoring urpsiz","",urpsiz); |
| g_urpsiz = -1; |
| } |
| if (g_spsizf > -1) { |
| spsizf = g_spsizf; |
| debug(F101,"ftreset restoring spsizf","",spsizf); |
| g_spsizf = -1; |
| } |
| if (g_spsiz > -1) { |
| spsiz = g_spsiz; |
| debug(F101,"ftreset restoring spsiz","",spsiz); |
| g_spsiz = -1; |
| } |
| if (g_spsizr > -1) { |
| spsizr = g_spsizr; |
| debug(F101,"ftreset restoring spsizr","",spsizr); |
| g_spsizr = -1; |
| } |
| if (g_spmax > -1) { |
| spmax = g_spmax; |
| g_spmax = -1; |
| } |
| if (g_wslotr > -1) { |
| wslotr = g_wslotr; |
| g_wslotr = -1; |
| } |
| if (g_prefixing > -1) { |
| prefixing = g_prefixing; |
| g_prefixing = -1; |
| } |
| if (g_fncact > -1) { |
| fncact = g_fncact; |
| g_fncact = -1; |
| } |
| if (g_fncnv > -1) { |
| fncnv = g_fncnv; |
| g_fncnv = -1; |
| } |
| if (g_fnspath > -1) { |
| fnspath = g_fnspath; |
| g_fnspath = -1; |
| } |
| if (g_fnrpath > -1) { |
| fnrpath = g_fnrpath; |
| g_fnrpath = -1; |
| } |
| if (g_skipbup > -1) { |
| skipbup = g_skipbup; |
| g_skipbup = -1; |
| } |
| nolinks = 2; /* /FOLLOWLINKS is never global */ |
| recursive = 0; /* /RECURSIVE can never be global */ |
| xfiletype = -1; |
| |
| if (g_displa > -1) { /* File transfer display */ |
| fdispla = g_displa; |
| g_displa = -1; |
| } |
| if (g_spath > -1) { /* Send pathnames */ |
| fnspath = g_spath; |
| g_spath = -1; |
| } |
| if (g_rpath > -1) { /* Receive pathnames */ |
| fnrpath = g_rpath; |
| g_rpath = -1; |
| } |
| if (g_fncnv > -1) { /* Filename conversion */ |
| fncnv = g_fncnv; |
| g_fncnv = -1; |
| } |
| #ifdef PIPESEND |
| makestr(&sndfilter,g_sfilter); /* Send filter */ |
| makestr(&rcvfilter,g_rfilter); /* Receive filter */ |
| #endif /* PIPESEND */ |
| |
| #ifndef NOFRILLS |
| rmailf = rprintf = 0; /* MAIL and PRINT modifiers for SEND */ |
| optbuf[0] = NUL; /* MAIL and PRINT options */ |
| #endif /* NOFRILLS */ |
| |
| moving = 0; /* Reset delete-after-send indicator */ |
| sndafter[0] = NUL; /* Reset SEND selection switches */ |
| sndbefore[0] = NUL; |
| |
| for (i = 0; i < NSNDEXCEPT; i++) { |
| if (sndexcept[i]) |
| free(sndexcept[i]); |
| sndexcept[i] = NULL; |
| if (rcvexcept[i]) |
| free(rcvexcept[i]); |
| rcvexcept[i] = NULL; |
| } |
| sndlarger = -1L; |
| sndsmaller = -1L; |
| #ifdef GFTIMER |
| gtv = -1.0; |
| oldgtv = -1.0; |
| #else |
| gtv = -1L; |
| oldgtv = -1L; |
| #endif /* GFTIMER */ |
| #endif /* NOICP */ |
| } |
| #endif /* NOXFER */ |
| |
| char * |
| ttgtpn() { /* Get typical port name */ |
| /* |
| Ideally this routine would be implemented in each of the cku?io.* modules, |
| but that requires changing the API definition. |
| */ |
| return( |
| #ifdef OS2 |
| #ifdef OS2ONLY |
| "COM1" |
| #else /* OS2ONLY */ |
| "TAPI [ name ] or COM1" |
| #endif /* OS2ONLY */ |
| #else /* OS2 */ |
| #ifdef VMS |
| "TXA0:, TTA0:, or LTA0:" |
| #else /* VMS */ |
| #ifdef SOLARIS |
| "/dev/cua/a" |
| #else /* SOLARIS */ |
| #ifdef HPUX10 |
| "/dev/cua0p0" |
| #else /* HPUX10 */ |
| #ifdef HPUX |
| "/dev/cua00" |
| #else /* HPUX */ |
| #ifdef __FreeBSD__ |
| "/dev/cuaa0" |
| #else /* __FreeBSD__ */ |
| #ifdef __linux__ |
| "/dev/ttyS0" |
| #else /* __linux__ */ |
| #ifdef BSD44 |
| "/dev/tty00" |
| #else /* BSD44 */ |
| #ifdef OSK |
| "/t1" |
| #else /* OSK */ |
| #ifdef QNX |
| "/dev/ser1" |
| #else /* QNX */ |
| #ifdef QNX6 |
| "/dev/ser1" |
| #else /* QNX6 */ |
| #ifdef UNIXWARE |
| "/dev/term/00 or /dev/tty00" |
| #else /* UNIXWARE */ |
| #ifdef CK_SCOV5 |
| "/dev/tty1A" |
| #else /* CK_SCOV5 */ |
| #ifdef CK_SCO32V4 |
| "/dev/tty1A" |
| #else /* CK_SCO32V4 */ |
| #ifdef M_XENIX |
| "/dev/tty1A" |
| #else /* M_XENIX */ |
| #ifdef AIXRS |
| "/dev/tty0" |
| #else /* AIXRS */ |
| #ifdef DGUX |
| "/dev/tty00" |
| #else /* DGUX */ |
| #ifdef datageneral |
| "@con1" |
| #else /* datageneral */ |
| #ifdef IRIX |
| "/dev/ttym0" |
| #else /* IRIX */ |
| #ifdef SUNOS4 |
| "/dev/ttyh0" |
| #else /* SUNOS4 */ |
| #ifdef SV68R3V6 |
| "/dev/scc0" |
| #else /* SV68R3V6 */ |
| #ifdef MOTSV88R4 |
| "/dev/contty00" |
| #else /* MOTSV88R4 */ |
| #ifdef NEXT |
| "/dev/cufa" |
| #else |
| #ifdef OSF |
| "/dev/ttyd1" |
| #else |
| #ifdef SINIX |
| "/dev/ttyc1" |
| #else |
| #ifdef UNIX |
| "/dev/cua, /dev/acu, /dev/tty0, etc" |
| #else /* UNIX */ |
| "(sorry no example available)" |
| #endif /* UNIX */ |
| #endif /* SINIX */ |
| #endif /* OSF */ |
| #endif /* NEXT */ |
| #endif /* MOTSV88R4 */ |
| #endif /* SV68R3V6 */ |
| #endif /* SUNOS4 */ |
| #endif /* IRIX */ |
| #endif /* datageneral */ |
| #endif /* DGUX */ |
| #endif /* AIX */ |
| #endif /* M_XENIX */ |
| #endif /* CK_SCO32V4 */ |
| #endif /* CK_SCOV5 */ |
| #endif /* UNIXWARE */ |
| #endif /* QNX6 */ |
| #endif /* QNX */ |
| #endif /* OSK */ |
| #endif /* BSD44 */ |
| #endif /* __linux__ */ |
| #endif /* __FreeBSD__ */ |
| #endif /* HPUX */ |
| #endif /* HPUX10 */ |
| #endif /* SOLARIS */ |
| #endif /* VMS */ |
| #endif /* OS2 */ |
| ); |
| } |
| |
| /* C K _ E R R S T R -- Return message from most recent system error */ |
| |
| #ifdef CKROOT |
| extern int ckrooterr; |
| #endif /* CKROOT */ |
| |
| char * |
| ck_errstr() { |
| #ifdef USE_STRERROR |
| #ifndef CK_ANSILIBS |
| /* Should have been declared in <string.h> */ |
| _PROTOTYP( char * strerror, (int) ); |
| #endif /* CK_ANSILIBS */ |
| #ifdef CKROOT |
| if (ckrooterr) |
| return("Off limits"); |
| #endif /* CKROOT */ |
| return(strerror(errno)); |
| #else /* !USE_STRERROR */ |
| #ifdef VMS |
| extern char * ckvmserrstr(unsigned long); |
| #ifdef CKROOT |
| if (ckrooterr) |
| return("Off limits"); |
| #endif /* CKROOT */ |
| return(ckvmserrstr(0L)); |
| #else /* !VMS */ |
| #ifdef BSD44 |
| #ifdef __386BSD__ |
| #ifndef NDSYSERRLIST |
| extern int sys_nerr; |
| extern char *sys_errlist[]; |
| #endif /* NDSYSERRLIST */ |
| #else /* !__386BSD__ */ |
| #ifndef __bsdi__ |
| #ifndef NDSYSERRLIST |
| extern int sys_nerr; |
| extern const char *const sys_errlist[]; |
| #endif /* NDSYSERRLIST */ |
| #endif /* __bsdi__ */ |
| #endif /* __386BSD__ */ |
| #ifdef CKROOT |
| if (ckrooterr) |
| return("Off limits"); |
| else |
| #endif /* CKROOT */ |
| if (errno >= sys_nerr) |
| return("Error number out of range"); |
| else |
| return((char *) sys_errlist[errno]); |
| #else /* !BSD44 */ |
| #ifdef ATTSV |
| #ifndef NDSYSERRLIST |
| extern int sys_nerr; |
| extern char *sys_errlist[]; |
| #endif /* NDSYSERRLIST */ |
| #ifdef CKROOT |
| if (ckrooterr) |
| return("Off limits"); |
| else |
| #endif /* CKROOT */ |
| if (errno >= sys_nerr) |
| return("Error number out of range"); |
| else |
| return((char *) sys_errlist[errno]); |
| #else /* !ATTSV */ |
| #ifdef BSD4 |
| #ifndef NDSYSERRLIST |
| extern int sys_nerr; |
| extern char *sys_errlist[]; |
| #endif /* NDSYSERRLIST */ |
| #ifdef CKROOT |
| if (ckrooterr) |
| return("Off limits"); |
| else |
| #endif /* CKROOT */ |
| if (errno >= sys_nerr) |
| return("Error number out of range"); |
| else |
| return((char *) sys_errlist[errno]); |
| #else |
| #ifdef OS2 |
| #ifndef NDSYSERRLIST |
| extern char *sys_errlist[]; |
| #endif /* NDSYSERRLIST */ |
| #ifdef NT |
| extern int_sys_nerr; |
| #endif /* NT */ |
| char *e; |
| #ifdef CKROOT |
| if (ckrooterr) |
| return("Off limits"); |
| #endif /* CKROOT */ |
| e = (errno > -1 |
| #ifdef NT |
| && errno <= _sys_nerr |
| #endif /* NT */ |
| ) ? |
| #ifdef NT |
| (char *) sys_errlist[errno] |
| #else /* NT */ |
| /* I don't know how to get a CLIB error string in OS/2 */ |
| strerror(errno) |
| #endif /* NT */ |
| : ""; |
| return(e ? e : ""); |
| #else /* OS2 */ |
| return(""); |
| #endif /* OS2 */ |
| #endif /* BSD4 */ |
| #endif /* ATTSV */ |
| #endif /* BSD44 */ |
| #endif /* VMS */ |
| #endif /* USE_STRERROR */ |
| } |
| |
| #ifdef PATTERNS |
| /* |
| Filename pattern recognition lists for automatic text/binary switching. |
| These are somewhat passe after the addition of scanfile() (7.0). |
| But with the addition of FTP [M]GET, they're back in style (8.0). |
| |
| Although, with FTP the lists need to be used in the reverse. With |
| Kermit the list is used to imply the types of the local system. Whereas |
| with FTP, the list must be used to imply the type of the remote system. |
| Therefore, all platforms must now support all of the lists. |
| */ |
| char *txtpatterns[FTPATTERNS+1] = { NULL, NULL }; |
| char *binpatterns[FTPATTERNS+1] = { NULL, NULL }; |
| /* |
| Default pattern lists for each platform... |
| |
| NOTE: In most cases we leave ".hlp", ".ini", and ".scr" alone; although they |
| are traditionally text types, they are binary in Windows. So they are |
| handled by the prevailing SET FILE TYPE, rather than automatically. |
| Similarly for ".dat", ".inf", and so on. Also ".ps" since PostScript files |
| are not always text. ".log" is omitted since logs can be text or binary, |
| except in VMS they are usually text, etc etc. |
| |
| Later (Sep 2003): Add PostScript to binary patterns. |
| */ |
| static char *txtp[SYS_MAX][FTPATTERNS] = { |
| /* UNKNOWN */ { |
| NULL, NULL |
| }, |
| { /* UNIX */ |
| "*.txt","*.c","*.h","*.r","*.w","*.cpp","*.cc","*.ksc","*.bwr","*.upd", |
| "*.html","*.htm","*.mss","*.tex","*.nr","[Mm]akefile", "*.hex", "*.hqx", |
| "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp","*.sh", |
| "*.m4","*.perl","*.pl","*.pod","*.pm","*.awk","*.sno","*.spt","*.sed", |
| "*.ksc","*.TXT", "*read.me", "*READ.ME", ".*", "*/.*", "*.mem","*.mac", |
| NULL |
| }, |
| { /* WIN32 */ |
| "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex", |
| "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w", |
| "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile", |
| "*.mem","*.mac","*.cc","*.pl","*.pod","*.pm","*.m4",NULL |
| }, |
| { /* VMS */ |
| "*.com","*.txt","*.c", "*.for","*.pas","*.rno","*.rnh","*.mar","*.bli", |
| "*.hlp","*.mss","*.doc","*.bwr","*.cld","*.hex","*.bas","*.ini","*.log", |
| "*.mms","*.opt","*.ksc","*.perl","*.pl","*.pod","*.pm","*.sno","*.spt", |
| "*.mem",NULL |
| }, |
| { /* OS2 */ |
| "*.txt","*.ksc","*.htm","*.html","*.bat","*.cmd","*.jav","*.asm", "*.hex", |
| "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w", |
| "*.java", "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile", |
| NULL |
| }, |
| { /* DOS */ |
| "*.txt","*.ksc","*.htm","*.bat","*.cmd","*.jav","*.asm", "*.hex", |
| "*.hqx", "*.c", "*.h", "*.cpp", "*.hpp", "*.cxx", "*.cxx", "*.w", |
| "*.bwr", "*.upd", "*.mak", "read.me", "*.map", "makefile", NULL |
| }, |
| { /* TOPS-10 */ |
| "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli", |
| "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub", |
| "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL |
| }, |
| { /* TOPS-20 */ |
| "*.cmd","*.hlp","*.doc","*.ini","*.txt","*.mac","*.for","*.sai","*.bli", |
| "*.pas","*.sno","*.spt","*.pcl","*.mss","*.rno","*.b36","*.tex","*.pub", |
| "*.req","*.r36","*.mem","*.bwr","*.ccl","*.ctl","*.rnh","*.ksc",NULL |
| }, |
| { /* STRATUS VOS */ |
| "*.txt","*.ksc","*.htm","*.html","*.bat", "*.cmd","*.jav","*.asm","*.hex", |
| "*.hqx","*.c", "*.h", "*.w", "*.java","*.bwr","*.upd","*.ttp","*.cm", |
| "*.pl1","*.emacs", "read.me", "*.pl", "makefile", NULL |
| }, |
| { /* DG AOS/VS */ |
| "*.txt", "*.c", "*.h", "*.w", "*.er", "*.bwr", "*.upd", "read.me", |
| "*.cli", "*.ksc", NULL |
| }, |
| { /* OSK */ |
| "*.c","*.cpp","*.h","*.a","*akefile", /* program sources */ |
| "*.for","*.f77","*.f","*.F","*.s","*.pas","*.java","*.el","*.lisp", |
| "*.sh","*.perl","*.awk","*.sno","*.spt","*.sed", |
| "*.txt","*.w", /* general text */ |
| "*.ksc","*.bwr","*.upd", |
| "*.html","*.htm","*.mss","*.tex","*.nr","*.hex", "*.hqx", |
| "*.TXT", "*read.me", "*READ.ME", ".*", "*/.*", |
| NULL |
| } |
| }; |
| |
| /* Note: .DOC added to (some) binary patterns June 1998... Microsoft wins. */ |
| |
| static char *binp[SYS_MAX][FTPATTERNS] = { |
| { /* UNKNOWN */ |
| NULL, NULL |
| }, |
| { /* UNIX */ |
| "*.gz","*.Z","*.tgz","*.gif", "*.tar","*.zip","*.o","*.so","*.a","*.out", |
| "*.exe", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.so.*", "*.class", |
| "*.rpm", "*.bmp", "*.bz2", "*.BMP", "*.dll", "*.doc", "*.vxd", "*.dcx", |
| "*.xl*", "*.lzh", "*.lhz", "*.au", "*.voc", "*.mpg", "*.mpeg","[wk]ermit", |
| "*.ps", NULL |
| }, |
| { /* WIN32 */ |
| "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram", |
| "*.class","*.cla","*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico", |
| "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd", |
| "*.pdf", "*.lzh", "*.vxd", "*.snd", "*.au", "* .voc", "*.mpg", "*.mpeg", |
| "*.ps", NULL |
| }, |
| { /* VMS */ |
| "*.exe","*.obj","*.bak","*.bin","*.adf","*.stb","*.mai","*.sys","*.dmp", |
| "*.ps", "*.dat","*.par", NULL |
| }, |
| { /* OS2 */ |
| "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram", |
| "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico", |
| "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd", |
| "*.pdf", "*.ps", "*.lzh", NULL |
| }, |
| { /* DOS */ |
| "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram", |
| "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico", |
| "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd", |
| "*.pdf", "*.ps", "*.lzh", NULL |
| }, |
| { /* TOPS10 */ |
| "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi", |
| "*.ps", NULL |
| }, |
| { /* TOPS20 */ |
| "*.exe","*.sav","*.bin","*.rim","*.rel","*.unv","*.lib","*.tap","*.dvi", |
| "*.ps", NULL |
| }, |
| { /* STRATUS VOS */ |
| "*.exe", "*.zip", "*.obj", "*.com", "*.gif", "*.jpg", "*.wav", "*.ram", |
| "*.class", "*.cla", "*.dll", "*.drv", "*.ocx", "*.vbx", "*.lib", "*.ico", |
| "*.bmp", "*.tif", "*.tar", "*.gz", "*.tgz", "*.xl*", "*.doc", "*.vxd", |
| "*.pdf", "*.ps", "*.lzh", "*.pm", NULL |
| }, |
| { /* DG */ |
| "*.ob", "*.pr", "*.dmp", "*.ps", NULL |
| }, |
| { /* OSK */ |
| "*.gz","*.Z","*.z","*.tgz","*.lhz","*.tar", /* archivers */ |
| "*.zip","*.ar","*.zoo","*.rpm","*.lzh", |
| /* object files, libraries, executables */ |
| "*.r","*.l","*.exe", "*.dll", "*.so.*", "*.class", |
| /* images */ |
| "*.gif", "*.jpg", "*.jpeg", "*.tif","*.tiff", "*.pdf", "*.ps", |
| "*.bmp", "*.bz2", "*.BMP","*.pcx", |
| NULL |
| } |
| }; |
| |
| /* |
| Set up default pattern lists so they can be freed and re-malloc'd. |
| Each pattern list must terminated by a null element. |
| */ |
| VOID |
| initpat() { |
| int i; |
| for (i = 0; i < FTPATTERNS; i++) { |
| txtpatterns[i] = NULL; |
| binpatterns[i] = NULL; |
| } |
| for (i = 0; i < FTPATTERNS; i++) { |
| #ifdef UNIX |
| makestr(&(txtpatterns[i]),txtp[SYS_UNIX][i]); |
| #else /* UNIX */ |
| #ifdef OS2 |
| #ifdef NT |
| makestr(&(txtpatterns[i]),txtp[SYS_WIN32][i]); |
| #else /* NT */ |
| makestr(&(txtpatterns[i]),txtp[SYS_OS2][i]); |
| #endif /* NT */ |
| #else /* OS2 */ |
| #ifdef VMS |
| makestr(&(txtpatterns[i]),txtp[SYS_VMS][i]); |
| #else /* VMS */ |
| #ifdef STRATUS |
| makestr(&(txtpatterns[i]),txtp[SYS_VOS][i]); |
| #else /* STRATUS */ |
| #ifdef datageneral |
| makestr(&(txtpatterns[i]),txtp[SYS_DG][i]); |
| #else /* datageneral */ |
| #ifdef OSK |
| makestr(&(txtpatterns[i]),txtp[SYS_OSK][i]); |
| #else /* OSK */ |
| makestr(&(txtpatterns[i]),txtp[SYS_UNK][i]); |
| #endif /* OSK */ |
| #endif /* datageneral */ |
| #endif /* STRATUS */ |
| #endif /* VMS */ |
| #endif /* OS2 */ |
| #endif /* UNIX */ |
| if (!txtp[i]) |
| break; |
| } |
| for (i = 0; i < FTPATTERNS; i++) { |
| #ifdef UNIX |
| makestr(&(binpatterns[i]),binp[SYS_UNIX][i]); |
| #else /* UNIX */ |
| #ifdef OS2 |
| #ifdef NT |
| makestr(&(binpatterns[i]),binp[SYS_WIN32][i]); |
| #else /* NT */ |
| makestr(&(binpatterns[i]),binp[SYS_OS2][i]); |
| #endif /* NT */ |
| #else /* OS2 */ |
| #ifdef VMS |
| makestr(&(binpatterns[i]),binp[SYS_VMS][i]); |
| #else /* VMS */ |
| #ifdef STRATUS |
| makestr(&(binpatterns[i]),binp[SYS_VOS][i]); |
| #else /* STRATUS */ |
| #ifdef datageneral |
| makestr(&(binpatterns[i]),binp[SYS_DG][i]); |
| #else /* datageneral */ |
| #ifdef OSK |
| makestr(&(binpatterns[i]),binp[SYS_OSK][i]); |
| #else /* OSK */ |
| makestr(&(binpatterns[i]),binp[SYS_UNK][i]); |
| #endif /* OSK */ |
| #endif /* datageneral */ |
| #endif /* STRATUS */ |
| #endif /* VMS */ |
| #endif /* OS2 */ |
| #endif /* UNIX */ |
| if (!binp[i]) |
| break; |
| } |
| } |
| |
| /* |
| m a t c h n a m e -- Compare filename with text & binary name patterns. |
| |
| Returns: |
| 0 if name matches a text pattern but not a binary pattern. |
| 1 if name matches a binary pattern but not a text pattern. |
| -1 if name matches no patterns. |
| -2 if name matches a binary pattern and a text pattern. |
| */ |
| int |
| matchname(filename, local, os) char * filename; int local; int os; { |
| int rc = -1; /* Return code */ |
| char * name, * p; |
| #ifdef OS2ORUNIX |
| char tmpbuf[CKMAXPATH+1]; |
| #endif /* OS2ORUNIX */ |
| |
| name = filename ? filename : ""; /* Copy of original arg */ |
| if (patterns && *name) { /* If PATTERNS ON... */ |
| int i; |
| |
| #ifdef OS2ORUNIX |
| if (ckmatch("*.~[1-9]*~",name,1,1)) { /* Name has backup suffix? */ |
| int k; |
| k = ckstrncpy(tmpbuf,name,CKMAXPATH+1); /* Yes, copy and strip */ |
| for (i = k - 3; i > 4; i--) { |
| if (tmpbuf[i] == '~' && tmpbuf[i-1] == '.') { |
| tmpbuf[i-1] = NUL; |
| break; |
| } |
| } |
| name = tmpbuf; /* And point to stripped copy */ |
| } |
| #endif /* OS2ORUNIX */ |
| zstrip(name,&p); /* Strip pathname too */ |
| name = p; |
| |
| if (local) { |
| if (txtpatterns[0]) { /* Search text patterns */ |
| for (i = 0; i < FTPATTERNS && txtpatterns[i]; i++) { |
| if (ckmatch(txtpatterns[i],name,filecase,1)) { |
| rc = 0; |
| break; |
| } |
| } |
| } |
| if (binpatterns[0]) { /* And search binary patterns */ |
| for (i = 0; i < FTPATTERNS && binpatterns[i]; i++) { |
| if (ckmatch(binpatterns[i],name,filecase,1)) { |
| rc = (rc > -1) ? -2 : 1; |
| break; |
| } |
| } |
| } |
| } else { |
| if (os >= 0 && os < SYS_MAX) { |
| if (txtp[os][0]) { |
| for (i = 0; i < FTPATTERNS && txtp[os][i]; i++) { |
| if (ckmatch(txtp[os][i],name,filecase,1)) { |
| rc = 0; |
| break; |
| } |
| } |
| } |
| if (binp[os][0]) { |
| for (i = 0; i < FTPATTERNS && binp[os][i]; i++) { |
| if (ckmatch(binp[os][i],name,filecase,1)) { |
| rc = (rc > -1) ? -2 : 1; |
| break; |
| } |
| } |
| } |
| } |
| } |
| } |
| debug(F111,"matchname",name,rc); |
| return(rc); |
| } |
| #endif /* PATTERNS */ |
| |
| #ifdef UNICODE |
| #ifndef NOEVENMAX |
| #define EVENMAX |
| #endif /* NOEVENMAX */ |
| #endif /* UNICODE */ |
| |
| /* S C A N F I L E -- Analyze a file's contents */ |
| |
| /* |
| Call with: |
| name: Pointer to name of existing file. |
| flag: Pointer to int in which to return additional numeric data. |
| |
| Returns: |
| -1 on failure (to open file or to read from it). |
| Integer, 0..4, on success indicating file type: |
| 0 = 7-bit text (flag = -1) |
| 1 = UTF-8 text (flag = -1) |
| 2 = UCS-2 text (flag = 0: big-endian; flag = 1: little-endian) |
| 3 = 8-bit text (flag = 0: no C1 bytes; flag = 1: includes C1 bytes) |
| 4 = binary (flag = -1) |
| |
| If UNICODE is defined: |
| |
| 1. If file begins with a valid BOM, it is believed. Otherwise we |
| read the first 4K of the file (since it might be email with verbose |
| headers) and analyze it: |
| |
| 2. If file contains only valid UTF-8 sequences, we call it UTF-8; |
| otherwise: |
| |
| 3. If the file contains lots of alternate 0 bytes, we call it UCS-2, and |
| set the polarity according to whether the preponderance of them are in |
| even or odd positions; otherwise: |
| |
| 4. If EVENMAX is defined and the file contains lots of alternate bytes that |
| are identical, even if they aren't zero, and the number of such bytes |
| is at least four times the length of the maximum run of alternating |
| identical bytes of the opposite polarity, we call it UCS-2; otherwise: |
| |
| 5. If the file contained no bytes with their 8th bits on and no controls |
| other than CR, LF, HT, and FF, we call it ASCII; otherwise: |
| |
| 6. If it contains C0 control characters other than CR, LF, HT, and FF, we |
| call it binary; otherwise: |
| |
| 7. We call it 8-bit text, character set unknown (could be Latin-1 or |
| anything else). |
| |
| Note that malformed UTF-8 is not diagnosed as UTF-8. |
| |
| If UNICODE is not defined: |
| |
| 1. If the file contains C0 control characters other than CR, LF, HT, and |
| FF, we call it binary; otherwise: |
| |
| 2. If the file contains any 8-bit bytes, we call it 8-bit text; otherwise: |
| |
| 3. We call it 7-bit text. |
| |
| In the non-Unicode case, UCS-2 is diagnosed as binary, but UTF-8 as |
| 8-bit text. |
| |
| There is no significant speed difference between the Unicode and |
| non-Unicode cases. |
| */ |
| int |
| scanfile(name,flag,nscanfile) char * name; int * flag, nscanfile; { |
| FILE * fp; /* File pointer */ |
| unsigned char buf[SCANFILEBUF]; /* File data buffer for analysis */ |
| int x, val = -1, count = 0; /* Workers */ |
| int rc = -1; /* Return code */ |
| int pv = -1; /* Pattern-match value */ |
| int eof = 0; /* Flag for file EOF encountered */ |
| int bytes = 0; /* Total byte count */ |
| #ifdef UNICODE |
| unsigned int c0, c1; /* First 2 file bytes (for BOM) */ |
| #endif /* UNICODE */ |
| extern int pipesend, filepeek; |
| |
| register int i; /* Loop control */ |
| int readsize = 0; /* How much to read */ |
| int eightbit = 0; /* Number of bytes with 8th bit on */ |
| int c0controls = 0; /* C0 non-text control-char counter */ |
| int c0noniso = 0; /* C0 non-ISO control-char counter */ |
| int c1controls = 0; /* C1 control-character counter */ |
| unsigned int c; /* Current character */ |
| int runmax = 0; /* Longest run of 0 bytes */ |
| int runzero = 0; /* Run of 0 bytes */ |
| int pctzero = 0; /* Percentage of 0 bytes */ |
| int txtcz = 0; |
| #ifdef CK_CTRLZ |
| extern int eofmethod; |
| #endif /* CK_CTRLZ */ |
| |
| #ifdef UNICODE |
| int notutf8 = 0; /* Nonzero if definitely not UTF-8 */ |
| int utf8state = 0; /* UTF-8 recognizer state */ |
| int oddzero = 0; /* Number of 0 bytes in odd postions */ |
| int evenzero = 0; /* and in even positions */ |
| int lfnul = 0; /* Number of <LF><NUL> sequences */ |
| int crlf = 0; /* Number of <CRLF> sequences */ |
| #else |
| int notutf8 = 1; |
| #endif /* UNICODE */ |
| |
| #ifdef COMMENT |
| #ifdef EVENMAX |
| int oddrun = 0, oddmax = 0, oddbyte = 0, oddmaxbyte = 0; |
| int evenrun = 0, evenmax = 0, evenbyte = 0, evenmaxbyte = 0; |
| #endif /* EVENMAX */ |
| #endif /* COMMENT */ |
| |
| #ifndef NOXFER |
| if (pipesend || calibrate || sndarray) /* Only for real files */ |
| return(-1); |
| #endif /* NOXFER */ |
| debug(F111,"scanfile",name,nscanfile); |
| #ifdef PATTERNS |
| if (!filepeek) { |
| pv = matchname(name,1,-1); |
| if (pv < 0) |
| rc = -1; |
| else |
| rc = (pv == 1) ? FT_BIN : FT_TEXT; |
| debug(F111,"scanfile !filepeek result",name,rc); |
| return(rc); |
| } |
| #endif /* PATTERNS */ |
| |
| #ifdef VMS |
| /* We don't scan in VMS where text files have various record formats in */ |
| /* which record headers contain seemingly non-text bytes. So the best */ |
| /* we can do in VMS is tell whether the file is text or binary, period. */ |
| { |
| int b, x; |
| b = binary; /* Save current binary setting */ |
| if (zopeni(ZIFILE,name) > 0) { /* In VMS this sets binary */ |
| x = binary; /* Get result */ |
| zclose(ZIFILE); /* Close the file */ |
| binary = b; /* Restore previous binary setting */ |
| rc = x ? FT_BIN : FT_TEXT; |
| val = 0; |
| goto xscanfile; |
| } |
| } |
| #endif /* VMS */ |
| |
| eof = 0; /* End-of-file reached indicator */ |
| #ifdef OS2 |
| fp = fopen(name, "rb"); /* Open the file in binary mode */ |
| #else |
| fp = fopen(name, "r"); |
| #endif /* OS2 */ |
| |
| if (!fp) /* Failed? */ |
| return(-1); |
| |
| while (1) { /* One or more gulps from file */ |
| if (eof) { /* EOF from last time? */ |
| debug(F111,"scanfile at EOF",name,bytes); |
| if (runzero > runmax) |
| runmax = runzero; |
| break; |
| } |
| if (nscanfile < 0) { /* Reading whole file */ |
| readsize = SCANFILEBUF; |
| } else { /* Reading first nscanfilee bytes */ |
| readsize = nscanfile - bytes; |
| if (readsize < 1) |
| break; |
| if (readsize > SCANFILEBUF) |
| readsize = SCANFILEBUF; |
| } |
| debug(F101,"scanfile readsize","",readsize); |
| count = fread(buf,1,readsize,fp); /* Read a buffer */ |
| if (count == EOF || count == 0) { |
| debug(F111,"scanfile EOF",name,count); |
| break; |
| } |
| debug(F111,"scanfile buffer ok",name,count); |
| |
| if (bytes == 0 && count > 8) { |
| /* PDF files can look like text in the beginning. */ |
| if (!ckstrcmp((char *)buf,"%PDF-1.",7,1)) { |
| if (isdigit(buf[7])) { |
| if (buf[8] == '\015' || |
| count > 9 && buf[8] == SP && buf[9] == '\015') { |
| #ifdef DEBUG |
| buf[8] = NUL; |
| debug(F110,"scanfile PDF",buf,0); |
| #endif /* DEBUG */ |
| binary = 1; /* But they are binary. */ |
| break; |
| } |
| } |
| } else if (!ckstrcmp((char *)buf,"%!PS-Ado",8,1)) { |
| /* Ditto for PostScript */ |
| #ifdef DEBUG |
| int i; |
| for (i = 8; i < count; i++) { |
| if (buf[i] < '!') { |
| buf[i] = NUL; |
| break; |
| } |
| } |
| debug(F110,"scanfile PostScript",buf,0); |
| #endif /* DEBUG */ |
| binary = 1; |
| break; |
| #ifndef NOPCLSCAN |
| } else if (!ckstrcmp((char *)buf,") HP-PCL",8,1)) { |
| /* HP PCL printer language */ |
| #ifdef DEBUG |
| int i; |
| for (i = 8; i < count; i++) { |
| if (buf[i] < '!') { |
| buf[i] = NUL; |
| break; |
| } |
| } |
| debug(F110,"scanfile PCL",buf,0); |
| #endif /* DEBUG */ |
| binary = 1; |
| break; |
| } |
| #endif /* NOPCLSCAN */ |
| #ifndef NOPJLSCAN |
| else if (buf[0] == '\033' && (buf[1] == 'E' || buf[1] == '%')) { |
| /* Ditto for PJL Job printer header */ |
| #ifdef DEBUG |
| int i; |
| for (i = 2; i < count; i++) { |
| if (buf[i] < '!') { |
| buf[i] = NUL; |
| break; |
| } |
| } |
| debug(F110,"scanfile PJL Job printer header",buf,0); |
| #endif /* DEBUG */ |
| binary = 1; |
| break; |
| #endif /* NOPJLSCAN */ |
| } |
| } |
| |
| #ifdef UNICODE |
| if (bytes == 0 && count > 1) { |
| int incl_cnt = 0; |
| |
| /* First look for BOM */ |
| |
| c0 = (unsigned)((unsigned)buf[0]&0xFF); /* First file byte */ |
| c1 = (unsigned)((unsigned)buf[1]&0xFF); /* Second byte */ |
| |
| if (c0 == 0xFE && c1 == 0xFF) { /* UCS-2 BE */ |
| rc = FT_UCS2; |
| val = 0; |
| debug(F111,"scanfile UCS2 BOM BE",ckitoa(val),rc); |
| incl_cnt++; |
| } else if (c0 == 0xFF && c1 == 0xFE) { /* UCS-2 LE */ |
| rc = FT_UCS2; |
| val = 1; |
| debug(F111,"scanfile UCS2 BOM LE",ckitoa(val),rc); |
| incl_cnt++; |
| } else if (count > 2) if (c0 == 0xEF && c1 == 0xBB && |
| (unsigned)((unsigned)buf[2]&0xFF) == 0xBF) { |
| rc = FT_UTF8; |
| debug(F111,"scanfile UTF8 BOM",ckitoa(val),rc); |
| incl_cnt++; |
| } |
| if (incl_cnt) { /* Have BOM */ |
| bytes += count; |
| goto xscanfile; |
| } |
| } |
| #endif /* UNICODE */ |
| |
| bytes += count; /* Count bytes read */ |
| eof = feof(fp); /* Flag for at EOF */ |
| |
| for (i = 0; i < count; i++) { /* For each byte... */ |
| c = (unsigned)buf[i]; /* For ease of reference */ |
| if (!c) { /* Zero byte? */ |
| #ifdef EVENMAX |
| if (i&1) /* In odd position */ |
| oddzero++; |
| else |
| evenzero++; /* In even position */ |
| #endif /* EVENMAX */ |
| runzero++; |
| } else { /* Not a zero byte */ |
| if (runzero > runmax) |
| runmax = runzero; |
| if (runmax > 2) /* That's all we need to be certain */ |
| break; /* it's a binary file. */ |
| runzero = 0; |
| } |
| |
| #ifdef COMMENT |
| #ifdef EVENMAX |
| |
| /* This is to catch UCS-2 with a non-ASCII, non-Latin-1 repertoire */ |
| |
| if (i > 1) { /* Look for runs of alternating chars */ |
| if (i&1) { |
| if (c == buf[i-2]) { /* In odd positions */ |
| oddrun++; |
| oddbyte = c; |
| } else { |
| oddmax = oddrun; |
| oddmaxbyte = oddbyte; |
| } |
| } else { /* and even positions */ |
| if (c == buf[i-2]) { |
| evenrun++; |
| evenbyte = c; |
| } else { |
| evenmax = evenrun; |
| evenmaxbyte = evenbyte; |
| } |
| } |
| } |
| #endif /* EVENMAX */ |
| #endif /* COMMENT */ |
| |
| if ((c & 0x80) == 0) { /* We have a 7-bit byte */ |
| #ifdef UNICODE |
| if (i > 0 && c == 10) { /* Linefeed */ |
| if (buf[i-1] == 0) lfnul++; /* Preceded by NUL */ |
| else if (buf[i-1] == 13) crlf++; /* or by CR... */ |
| } |
| #endif /* UNICODE */ |
| if (c < ' ') { /* Check for CO controls */ |
| if (c != LF && c != CR && c != HT && c != FF) { |
| c0controls++; |
| if (c != ESC && c != SO && c != SI) |
| c0noniso++; |
| } |
| if ((c == '\032') /* Ctrl-Z */ |
| #ifdef COMMENT |
| && eof && (i >= count - 2) |
| #endif /* COMMENT */ |
| ) { |
| c0controls--; |
| c0noniso--; |
| #ifdef CK_CTRLZ |
| if (eofmethod == XYEOF_Z && txtcz == 0) { |
| if (c0controls == 0) /* All text prior to Ctrl-Z */ |
| txtcz = 1; |
| } |
| #endif /* CK_CTRLZ */ |
| } |
| } |
| #ifdef UNICODE |
| if (!notutf8 && utf8state) { /* In UTF-8 sequence? */ |
| utf8state = 0; |
| debug(F000,"scanfile","7-bit byte in UTF8 sequence",c); |
| notutf8++; /* Then it's not UTF-8 */ |
| continue; |
| } |
| #endif /* UNICODE */ |
| } else { /* We have an 8-bit byte */ |
| eightbit++; /* Count it */ |
| if (c >= 0x80 && c < 0xA0) /* Check for C1 controls */ |
| c1controls++; |
| #ifdef UNICODE |
| if (!notutf8) { /* If it might still be UTF8... */ |
| switch (utf8state) { /* Enter the UTF-8 state machine */ |
| case 0: /* First byte... */ |
| if ((c & 0xE0) == 0xC0) { /* Tells number of */ |
| utf8state = 1; /* subsequent bytes */ |
| } else if ((c & 0xF0) == 0xE0) { |
| utf8state = 2; |
| } else if ((c & 0xF8) == 0xF0) { |
| utf8state = 3; |
| } else { |
| notutf8++; |
| } |
| break; |
| case 1: /* Subsequent byte */ |
| case 2: |
| case 3: |
| if ((c & 0xC0) != 0x80) { /* Must start with 10 */ |
| debug(F000,"scanfile", |
| "bad byte in UTF8 sequence",c); |
| notutf8++; |
| break; |
| } |
| utf8state--; /* Good, one less in this sequence */ |
| break; |
| default: /* Shouldn't happen */ |
| debug(F111,"scanfile","bad UTF8 state",utf8state); |
| notutf8++; |
| } |
| } |
| #endif /* UNICODE */ |
| } |
| } |
| } |
| fclose(fp); /* Close the file */ |
| debug(F101,"scanfile bytes","",bytes); |
| |
| if (bytes == 0) /* If nothing was read */ |
| return(-1); /* we're done. */ |
| |
| #ifdef EVENMAX |
| /* In case we had a run that never broke... */ |
| #ifdef COMMENT |
| if (oddmax == 0) { |
| oddmax = oddrun; |
| oddmaxbyte = oddbyte; |
| } |
| if (evenmax == 0) { |
| evenmax = evenrun; |
| evenmaxbyte = evenbyte; |
| } |
| #endif /* COMMENT */ |
| if (runmax == 0) { |
| runmax = runzero; |
| } |
| #endif /* EVENMAX */ |
| |
| #ifdef UNICODE |
| if (bytes > 100) /* Bytes is not 0 */ |
| pctzero = (evenzero + oddzero) / (bytes / 100); |
| else |
| pctzero = ((evenzero + oddzero) * 100) / bytes; |
| #endif /* UNICODE */ |
| |
| #ifdef DEBUG |
| if (deblog) { /* If debugging, dump statistics */ |
| debug(F101,"scanfile c0controls ","",c0controls); |
| debug(F101,"scanfile c0noniso ","",c0noniso); |
| debug(F101,"scanfile c1controls ","",c1controls); |
| debug(F101,"scanfile eightbit ","",eightbit); |
| #ifdef UNICODE |
| debug(F101,"scanfile crlf ","",crlf); |
| debug(F101,"scanfile lfnul ","",lfnul); |
| debug(F101,"scanfile notutf8 ","",notutf8); |
| debug(F101,"scanfile evenzero ","",evenzero); |
| debug(F101,"scanfile oddzero ","",oddzero); |
| debug(F101,"scanfile even/odd ","",(evenzero / (oddzero + 1))); |
| debug(F101,"scanfile odd/even ","",(oddzero / (evenzero + 1))); |
| debug(F101,"scanfile pctzero ","",pctzero); |
| #endif /* UNICODE */ |
| #ifdef COMMENT |
| #ifdef EVENMAX |
| debug(F101,"scanfile oddmax ","",oddmax); |
| debug(F101,"scanfile oddmaxbyte ","",oddmaxbyte); |
| debug(F101,"scanfile evenmax ","",evenmax); |
| debug(F101,"scanfile evenmaxbyte","",evenmaxbyte); |
| #endif /* EVENMAX */ |
| #endif /* COMMENT */ |
| debug(F101,"scanfile runmax ","",runmax); |
| } |
| #endif /* DEBUG */ |
| |
| #ifdef UNICODE |
| x = eightbit ? bytes / 20 : bytes / 4; /* For UCS-2... */ |
| |
| if (runmax > 2) { /* File has run of more than 2 NULs */ |
| debug(F100,"scanfile BIN runmax","",0); |
| rc = FT_BIN; /* so it can't be any kind of text. */ |
| goto xscanfile; |
| |
| } else if (rc == FT_UCS2 || (rc == FT_UTF8 && runmax == 0)) { |
| goto xscanfile; /* File starts with a BOM */ |
| |
| } else if (eightbit > 0 && !notutf8) { /* File has 8-bit data */ |
| if (runmax > 0) { /* and runs of NULs */ |
| debug(F100,"scanfile BIN (nnUTF8) runmax","",0); |
| rc = FT_BIN; /* UTF-8 doesn't have NULs */ |
| } else { /* No NULs */ |
| debug(F100,"scanfile UTF8 (nnUTF8 + runmax == 0)","",0); |
| rc = FT_UTF8; /* and not not UTF-8, so is UTF-8 */ |
| } |
| goto xscanfile; |
| } |
| /* |
| For UCS-2 detection, see if the text contains lines delimited by |
| ASCII controls and containing spaces, ASCII digits, or other ASCII |
| characters, thus forcing the presence of a certain percentage of zero bytes. |
| For this purpose require 20% zero bytes, with at least six times as many |
| in even (odd) positions as in odd (even) positions. |
| */ |
| if ((evenzero >= x && oddzero == 0) || |
| ((((evenzero / (oddzero + 1)) > 6) && (pctzero > 20)) && |
| (crlf == 0) && |
| (lfnul > 1)) |
| ) { |
| debug(F100,"scanfile UCS2 noBOM BE (even/oddzero)","",0); |
| rc = FT_UCS2; |
| val = 0; |
| } else if ((evenzero == 0 && oddzero >= x) || |
| ((((oddzero / (evenzero + 1)) > 6) && (pctzero > 20)) && |
| (crlf == 0) && |
| (lfnul > 1)) |
| ) { |
| debug(F100,"scanfile UCS2 noBOM LE (even/oddzero)","",0); |
| rc = FT_UCS2; |
| val = 1; |
| |
| #ifdef COMMENT |
| #ifdef EVENMAX |
| /* |
| If the tests above fail, we still might have UCS-2 if there are significant |
| runs of identical bytes in alternating positions, but only if it also has |
| unusual C0 controls (otherwise we'd pick up hex files here). NOTE: We |
| don't actually do this -- EVENMAX is not defined (see comments above at |
| first occurrence of EVENMAX). |
| */ |
| } else if (c0noniso && evenmax > bytes / 4) { |
| debug(F100,"scanfile UCS2 BE (evenmax)","",0); |
| rc = FT_UCS2; |
| val = 0; |
| } else if (c0noniso && oddmax > bytes / 4) { |
| debug(F100,"scanfile UCS2 LE (evenmax)","",0); |
| rc = FT_UCS2; |
| val = 1; |
| #endif /* EVENMAX */ |
| #endif /* COMMENT */ |
| |
| } |
| /* |
| It seems to be UCS-2 but let's be more certain since there is no BOM... |
| If the number of 7- and 8-bit characters is approximately equal, it might |
| be a compressed file. In this case we decide based on the name. |
| */ |
| if (rc == FT_UCS2) { |
| if (eightbit > 0) { |
| int j, k; |
| j = (c1controls * 100) / (c0controls + 1); |
| debug(F101,"scanfile c1/c0 ","",j); |
| k = (bytes * 100) / eightbit; |
| debug(F101,"scanfile pct 8bit ","",k); |
| if (k > 40 && k < 60 && j > 60) { |
| if (ckmatch("{*.Z,*.gz,*.zip,*.ZIP}",name,1,1)) { |
| debug(F110,"scanfile 8-bit BIN compressed",name,0); |
| rc = FT_BIN; |
| goto xscanfile; |
| } |
| } |
| } |
| /* Small file - not enough evidence unless ... */ |
| |
| if (bytes < 100) { |
| if (oddzero != 0 && evenzero != 0) { |
| debug(F100,"scanfile small UCS2 doubtful","",0); |
| rc = FT_BIN; |
| goto xscanfile; |
| } else if (oddzero == 0 && evenzero == 0) { |
| rc = eightbit ? FT_8BIT : FT_7BIT; |
| } |
| } |
| goto xscanfile; /* Seems to be UCS-2 */ |
| } |
| |
| /* If none of the above, it's probably not Unicode. */ |
| |
| if (!eightbit) { /* It's 7-bit */ |
| if (c0controls) { /* This would be strange */ |
| if ((c0noniso > 0) && (txtcz == 0)) { |
| debug(F100,"scanfile 7-bit BIN (c0coniso)","",0); |
| rc = FT_BIN; |
| } else { |
| debug(F100,"scanfile 7-bit ISO2022 TEXT (no c0noniso)","",0); |
| rc = FT_7BIT; |
| } |
| } else { /* 7-bit text */ |
| debug(F100,"scanfile 7-bit TEXT (no c0controls)","",0); |
| rc = FT_7BIT; |
| } |
| } else if (!c0noniso || txtcz) { /* 8-bit text */ |
| debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0); |
| rc = FT_8BIT; |
| val = c1controls ? 1 : 0; |
| } else { /* 8-bit binary */ |
| debug(F100,"scanfile 8-bit BIN (c0noniso)","",0); |
| rc = FT_BIN; |
| } |
| |
| #else /* !UNICODE */ |
| |
| if (c0noniso) { |
| debug(F100,"scanfile 8-bit BIN (c0noniso)","",0); |
| rc = FT_BIN; |
| } else if (eightbit) { |
| debug(F100,"scanfile 8-bit TEXT (no c0noniso)","",0); |
| rc = FT_8BIT; |
| val = c1controls ? 1 : 0; |
| } else { |
| debug(F100,"scanfile 7-bit TEXT (no c0noniso)","",0); |
| rc = FT_7BIT; |
| } |
| |
| #endif /* UNICODE */ |
| |
| xscanfile: |
| if (flag) *flag = val; |
| debug(F101,"scanfile result ","",rc); |
| return(rc); |
| } |
| |
| /* F I L E S E L E C T -- Select this file for sending */ |
| |
| int |
| #ifdef CK_ANSIC |
| fileselect( |
| char *f, char *sa, char *sb, char *sna, char *snb, |
| long minsiz, long maxsiz, |
| int nbu, int nxlist, |
| char ** xlist |
| ) |
| #else |
| fileselect(f,sa,sb,sna,snb,minsiz,maxsiz,nbu,nxlist,xlist) |
| char *f,*sa,*sb,*sna,*snb; long minsiz,maxsiz; int nbu,nxlist; char ** xlist; |
| #endif /* CK_ANSIC */ |
| /* fileselect */ { |
| char *fdate; |
| int n; |
| long z; |
| |
| if (!sa) sa = ""; |
| if (!sb) sb = ""; |
| if (!sna) sna = ""; |
| if (!snb) snb = ""; |
| |
| #ifdef CKSYMLINK |
| #ifndef NOICP |
| #ifndef NOXFER |
| if (nolinks) { |
| long zz; |
| zz = zgetfs(f); |
| debug(F111,"fileselect NOLINKS zgetfs",f,zz); |
| if (zz < 0L) |
| return(0); |
| debug(F111,"fileselect NOLINKS zgfs_link",f,zgfs_link); |
| if (zgfs_link) |
| return(0); |
| } |
| #endif /* NOXFER */ |
| #endif /* NOICP */ |
| #endif /* CKSYMLINK */ |
| |
| debug(F110,"fileselect",f,0); |
| if (*sa || *sb || *sna || *snb) { |
| fdate = zfcdat(f); /* Date/time of this file */ |
| if (!fdate) fdate = ""; |
| n = strlen(fdate); |
| debug(F111,"fileselect fdate",fdate,n); |
| if (n != 17) /* Failed to get it */ |
| return(1); |
| /* /AFTER: */ |
| if (sa[0] && (strcmp(fdate,(char *)sa) <= 0)) { |
| debug(F110,"fileselect sa",sa,0); |
| /* tlog(F110,"Skipping (too old)",f,0); */ |
| return(0); |
| } |
| /* /BEFORE: */ |
| if (sb[0] && (strcmp(fdate,(char *)sb) >= 0)) { |
| debug(F110,"fileselect sb",sb,0); |
| /* tlog(F110,"Skipping (too new)",f,0); */ |
| return(0); |
| } |
| /* /NOT-AFTER: */ |
| if (sna[0] && (strcmp(fdate,(char *)sna) > 0)) { |
| debug(F110,"fileselect sna",sna,0); |
| /* tlog(F110,"Skipping (too new)",f,0); */ |
| return(0); |
| } |
| /* /NOT-BEFORE: */ |
| if (snb[0] && (strcmp(fdate,(char *)snb) < 0)) { |
| debug(F110,"fileselect snb",snb,0); |
| /* tlog(F110,"Skipping (too old)",f,0); */ |
| return(0); |
| } |
| } |
| if (minsiz > -1L || maxsiz > -1L) { /* Smaller or larger */ |
| z = zchki(f); /* Get size */ |
| debug(F101,"fileselect filesize","",z); |
| if (z < 0) |
| return(1); |
| if ((minsiz > -1L) && (z >= minsiz)) { |
| debug(F111,"fileselect minsiz skipping",f,minsiz); |
| /* tlog(F111,"Skipping (too big)",f,z); */ |
| return(0); |
| } |
| if ((maxsiz > -1L) && (z <= maxsiz)) { |
| debug(F111,"fileselect maxsiz skipping",f,maxsiz); |
| /* tlog(F110,"Skipping (too small)",f,0); */ |
| return(0); |
| } |
| } |
| if (nbu) { /* Skipping backup files? */ |
| if (ckmatch( |
| #ifdef CKREGEX |
| "*.~[0-9]*~" /* Not perfect but close enough. */ |
| #else |
| "*.~*~" /* Less close. */ |
| #endif /* CKREGEX */ |
| ,f,filecase,1)) { |
| debug(F110,"fileselect skipping backup",f,0); |
| return(0); |
| } |
| } |
| for (n = 0; xlist && n < nxlist; n++) { |
| if (!xlist[n]) { |
| debug(F101,"fileselect xlist empty",0,n); |
| break; |
| } |
| if (ckmatch(xlist[n],f,filecase,1)) { |
| debug(F111,"fileselect xlist",xlist[n],n); |
| debug(F110,"fileselect skipping",f,0); |
| return(0); |
| } |
| } |
| if (xfiletype > -1) { |
| n = scanfile(f,NULL,nscanfile); |
| if (n < 0) { |
| n = binary ? 1 : 0; |
| } else { |
| n = (n == FT_BIN) ? 1 : 0; |
| } |
| if (n != xfiletype) |
| return(0); |
| } |
| debug(F110,"fileselect selecting",f,0); |
| return(1); |
| } |
| |
| |
| #ifdef TCPSOCKET |
| #ifdef NT |
| extern int WSASafeToCancel; |
| #endif /* NT */ |
| #endif /* TCPSOCKET */ |
| |
| VOID |
| setflow() { |
| extern int flow, autoflow, mdmtyp, cxtype, cxflow[]; |
| #ifndef NODIAL |
| extern int dialcapas, dialfc; |
| extern MDMINF * modemp[]; |
| MDMINF * p = NULL; |
| long bits = 0; |
| #endif /* NODIAL */ |
| |
| debug(F101,"setflow autoflow","",autoflow); |
| |
| /* #ifdef COMMENT */ |
| /* WHY WAS THIS COMMENTED OUT? */ |
| if (!autoflow) /* Only if FLOW is AUTO */ |
| return; |
| /* #endif */ /* COMMENT */ |
| |
| debug(F101,"setflow local","",local); |
| debug(F101,"setflow network","",network); |
| debug(F101,"setflow cxtype","",cxtype); |
| |
| #ifdef TN_COMPORT |
| if (network && istncomport()) { |
| flow = cxflow[CXT_MODEM]; |
| debug(F101,"setflow TN_COMPORT flow","",flow); |
| return; |
| } |
| #endif /* TN_COMPORT */ |
| |
| if (network || !local || cxtype == CXT_DIRECT) { |
| flow = cxflow[cxtype]; /* Set appropriate flow control */ |
| debug(F101,"setflow flow","",flow); |
| return; |
| } |
| if (cxtype != CXT_MODEM) /* Connection type should be modem */ |
| return; |
| |
| #ifndef NODIAL |
| bits = dialcapas; /* Capability bits */ |
| if (!bits) { /* No bits? */ |
| p = modemp[mdmtyp]; /* Look in modem info structure */ |
| if (p) |
| bits = p->capas; |
| } |
| if (dialfc == FLO_AUTO) { /* If DIAL flow is AUTO */ |
| #ifdef CK_RTSCTS /* If we can do RTS/CTS flow control */ |
| if (bits & CKD_HW) /* and modem can do it too */ |
| flow = FLO_RTSC; /* then switch to RTS/CTS */ |
| else /* otherwise */ |
| flow = FLO_XONX; /* use Xon/Xoff. */ |
| #else |
| #ifndef NEXT |
| #ifndef IRIX |
| flow = FLO_XONX; /* Use Xon/Xoff. */ |
| #endif /* IRIX */ |
| #endif /* NEXT */ |
| #endif /* CK_RTSCTS */ |
| } |
| #endif /* NODIAL */ |
| debug(F101,"setflow modem flow","",flow); |
| return; |
| } |
| |
| #ifndef NOLOCAL |
| #ifdef CK_TRIGGER |
| |
| /* A U T O E X I T C H K -- Check for CONNECT-mode trigger string */ |
| /* |
| Returns -1 if trigger not found, or else the trigger index, 0 or greater. |
| (Replace with fancier and more efficient matcher later...) |
| NOTE: to prevent unnecessary function call overhead, call this way: |
| |
| x = tt_trigger[0] ? autoexitchk(c) : -1; |
| |
| */ |
| int |
| #ifdef CK_ANSIC |
| autoexitchk(CHAR c) |
| #else |
| autoexitchk(c) CHAR c; |
| #endif /* CK_ANSIC */ |
| /* autoexitchk */ { |
| extern CHAR * tt_trmatch[]; |
| extern char * tt_trigger[]; |
| int i; |
| for (i = 0; i < TRIGGERS; i++) { |
| if (!tt_trigger[i]) { /* No more triggers in list */ |
| break; |
| } else if (*tt_trigger[i]) { |
| if (!tt_trmatch[i]) /* Just starting? */ |
| tt_trmatch[i] = (CHAR *)tt_trigger[i]; /* Set match pointer */ |
| if (c == *tt_trmatch[i]) { /* Compare this character */ |
| tt_trmatch[i]++; /* It matches */ |
| if (!*tt_trmatch[i]) { /* End of match string? */ |
| tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Yes, rewind, */ |
| debug(F101,"autoexitchk",tt_trigger[i],i); /* log, */ |
| return(i); /* and return success */ |
| } |
| } else /* No match */ |
| tt_trmatch[i] = (CHAR *) tt_trigger[i]; /* Rewind match string */ |
| } /* and go on the next match string */ |
| } |
| return(-1); /* No match found */ |
| } |
| #endif /* CK_TRIGGER */ |
| |
| #ifndef NOSHOW |
| /* S H O M D M -- Show modem signals */ |
| |
| VOID |
| shomdm() { |
| /* |
| Note use of "\r\n" to make sure this report prints right, even when |
| called during CONNECT mode. |
| */ |
| int y; |
| y = ttgmdm(); |
| switch (y) { |
| case -3: printf( |
| "Modem signals unavailable in this version of Kermit\r\n"); |
| break; |
| case -2: printf("No modem control for this device\r\n"); break; |
| case -1: printf("Modem signals unavailable\r\n"); break; |
| default: |
| #ifndef MAC |
| printf( |
| " Carrier Detect (CD): %s\r\n",(y & BM_DCD) ? "On": "Off"); |
| printf( |
| " Dataset Ready (DSR): %s\r\n",(y & BM_DSR) ? "On": "Off"); |
| #endif /* MAC */ |
| printf( |
| " Clear To Send (CTS): %s\r\n",(y & BM_CTS) ? "On": "Off"); |
| #ifndef STRATUS |
| #ifndef MAC |
| printf( |
| " Ring Indicator (RI): %s\r\n",(y & BM_RNG) ? "On": "Off"); |
| #endif /* MAC */ |
| printf( |
| " Data Terminal Ready (DTR): %s\r\n", |
| #ifdef NT |
| "(unknown)" |
| #else /* NT */ |
| (y & BM_DTR) ? "On": "Off" |
| #endif /* NT */ |
| ); |
| #ifndef MAC |
| printf( |
| " Request To Send (RTS): %s\r\n", |
| #ifdef NT |
| "(unknown)" |
| #else /* NT */ |
| (y & BM_RTS) ? "On": "Off" |
| #endif /* NT */ |
| ); |
| #endif /* MAC */ |
| #endif /* STRATUS */ |
| } |
| #ifdef BETADEBUG |
| #ifdef CK_TAPI |
| if (tttapi && !tapipass) { |
| LPDEVCFG lpDevCfg = NULL; |
| LPCOMMCONFIG lpCommConfig = NULL; |
| LPMODEMSETTINGS lpModemSettings = NULL; |
| DCB * lpDCB = NULL; |
| |
| if (cktapiGetModemSettings(&lpDevCfg,&lpModemSettings, |
| &lpCommConfig,&lpDCB)) { |
| printf("\n"); |
| cktapiDisplayModemSettings(lpDevCfg,lpModemSettings, |
| lpCommConfig,lpDCB); |
| } |
| } |
| #endif /* CK_TAPI */ |
| #endif /* BETADEBUG */ |
| } |
| #endif /* NOSHOW */ |
| #endif /* NOLOCAL */ |
| |
| #ifndef NOXFER |
| /* S D E B U -- Record spar results in debugging log */ |
| |
| VOID |
| sdebu(len) int len; { |
| debug(F111,"spar: data",(char *) rdatap,len); |
| debug(F101," spsiz ","", spsiz); |
| debug(F101," timint","",timint); |
| debug(F101," npad ","", npad); |
| debug(F101," padch ","", padch); |
| debug(F101," seol ","", seol); |
| debug(F101," ctlq ","", ctlq); |
| debug(F101," ebq ","", ebq); |
| debug(F101," ebqflg","",ebqflg); |
| debug(F101," bctr ","", bctr); |
| debug(F101," rptq ","", rptq); |
| debug(F101," rptflg","",rptflg); |
| debug(F101," lscapu","",lscapu); |
| debug(F101," atcapu","",atcapu); |
| debug(F101," lpcapu","",lpcapu); |
| debug(F101," swcapu","",swcapu); |
| debug(F101," wslotn","", wslotn); |
| debug(F101," whatru","", whatru); |
| } |
| /* R D E B U -- Debugging display of rpar() values */ |
| |
| VOID |
| rdebu(d,len) CHAR *d; int len; { |
| debug(F111,"rpar: data",d,len); |
| debug(F101," rpsiz ","", xunchar(d[0])); |
| debug(F101," rtimo ","", rtimo); |
| debug(F101," mypadn","",mypadn); |
| debug(F101," mypadc","",mypadc); |
| debug(F101," eol ","", eol); |
| debug(F101," ctlq ","", ctlq); |
| debug(F101," sq ","", sq); |
| debug(F101," ebq ","", ebq); |
| debug(F101," ebqflg","",ebqflg); |
| debug(F101," bctr ","", bctr); |
| debug(F101," rptq ","", d[8]); |
| debug(F101," rptflg","",rptflg); |
| debug(F101," capas ","", capas); |
| debug(F101," bits ","",d[capas]); |
| debug(F101," lscapu","",lscapu); |
| debug(F101," atcapu","",atcapu); |
| debug(F101," lpcapu","",lpcapu); |
| debug(F101," swcapu","",swcapu); |
| debug(F101," wslotr","", wslotr); |
| debug(F101," rpsiz(extended)","",rpsiz); |
| } |
| |
| #ifdef COMMENT |
| /* C H K E R R -- Decide whether to exit upon a protocol error */ |
| |
| VOID |
| chkerr() { |
| if (backgrd && !server) fatal("Protocol error"); |
| } |
| #endif /* COMMENT */ |
| #endif /* NOXFER */ |
| |
| /* F A T A L -- Fatal error message */ |
| |
| VOID |
| fatal(msg) char *msg; { |
| extern int initflg; |
| static int initing = 0; |
| if (!msg) msg = ""; |
| debug(F111,"fatal",msg,initflg); |
| |
| if (!initflg) { /* If called from prescan */ |
| if (initing) /* or called from sysinit() */ |
| exit(253); |
| initing = 1; |
| sysinit(); |
| } |
| |
| debug(F111,"fatal",msg,xitsta); |
| tlog(F110,"Fatal:",msg,0L); |
| #ifdef VMS |
| if (strncmp(msg,"%CKERMIT",8)) |
| conol("%CKERMIT-E-FATAL, "); |
| conoll(msg); |
| #else /* !VMS */ |
| conoll(msg); |
| #endif /* VMS */ |
| #ifdef OS2 |
| #ifndef NOXFER |
| if (xfrbel) { |
| bleep(BP_FAIL); |
| sleep(1); |
| bleep(BP_FAIL); |
| } |
| #endif /* NOXFER */ |
| |
| #endif /* OS2 */ |
| doexit(BAD_EXIT,xitsta | 1); /* Exit indicating failure */ |
| } |
| |
| #ifndef NOXFER |
| /* B L D L E N -- Make length-encoded copy of string */ |
| |
| char * |
| bldlen(str,dest) char *str, *dest; { |
| int len; |
| len = (int)strlen(str); |
| if (len > 94) |
| *dest = SP; |
| else |
| *dest = (char) tochar(len); |
| strcpy(dest+1,str); /* Checked below in setgen() */ |
| return(dest+len+1); |
| } |
| |
| |
| /* S E T G E N -- Construct a generic command */ |
| /* |
| Call with Generic command character followed by three string arguments. |
| Trailing strings are allowed to be empty (""). Each string except the last |
| non-empty string must be less than 95 characters long. The final nonempty |
| string is allowed to be longer. |
| */ |
| CHAR |
| #ifdef CK_ANSIC |
| setgen(char type, char * arg1, char * arg2, char * arg3) |
| #else |
| setgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3; |
| #endif /* CK_ANSIC */ |
| /* setgen */ { |
| char *upstr, *cp; |
| #ifdef DYNAMIC |
| if (!cmdstr) |
| if (!(cmdstr = malloc(MAXSP + 1))) |
| fatal("setgen: can't allocate memory"); |
| #endif /* DYNAMIC */ |
| |
| cp = cmdstr; |
| *cp++ = type; |
| *cp = NUL; |
| if (!arg1) arg1 = ""; |
| if (!arg2) arg2 = ""; |
| if (!arg3) arg3 = ""; |
| if (((int)strlen(arg1)+(int)strlen(arg2)+(int)strlen(arg3)+4) < MAXSP) { |
| if (*arg1 != NUL) { |
| upstr = bldlen(arg1,cp); |
| if (*arg2 != NUL) { |
| upstr = bldlen(arg2,upstr); |
| if (*arg3 != NUL) bldlen(arg3,upstr); |
| } |
| } |
| cmarg = cmdstr; |
| debug(F110,"setgen",cmarg,0); |
| return('g'); |
| } |
| return('E'); |
| } |
| #endif /* NOXFER */ |
| |
| #ifndef NOMSEND |
| static char *mgbufp = NULL; |
| |
| /* F N P A R S E -- */ |
| |
| /* |
| Argument is a character string containing one or more filespecs. |
| This function breaks the string apart into an array of pointers, one |
| to each filespec, and returns the number of filespecs. Used by server |
| when it receives a GET command to allow it to process multiple file |
| specifications in one transaction. Sets cmlist to point to a list of |
| file pointers, exactly as if they were command line arguments. |
| |
| This version of fnparse treats spaces as filename separators. If your |
| operating system allows spaces in filenames, you'll need a different |
| separator. |
| |
| This version of fnparse mallocs a string buffer to contain the names. It |
| cannot assume that the string that is pointed to by the argument is safe. |
| */ |
| int |
| fnparse(string) char *string; { |
| char *p, *s, *q; |
| int r = 0, x; /* Return code */ |
| #ifdef RECURSIVE |
| debug(F111,"fnparse",string,recursive); |
| #endif /* RECURSIVE */ |
| |
| if (mgbufp) free(mgbufp); /* Free this from last time. */ |
| mgbufp = malloc((int)strlen(string)+2); |
| if (!mgbufp) { |
| debug(F100,"fnparse malloc error","",0); |
| return(0); |
| } |
| #ifndef NOICP |
| #ifndef NOSPL |
| ckstrncpy(fspec,string,fspeclen); /* Make copy for \v(filespec) */ |
| #endif /* NOSPL */ |
| #endif /* NOICP */ |
| s = string; /* Input string */ |
| p = q = mgbufp; /* Point to the copy */ |
| r = 0; /* Initialize our return code */ |
| while (*s == SP || *s == HT) /* Skip leading spaces and tabs */ |
| s++; |
| for (x = strlen(s); /* Strip trailing spaces */ |
| (x > 1) && (s[x-1] == SP || s[x-1] == HT); |
| x--) |
| s[x-1] = NUL; |
| while (1) { /* Loop through rest of string */ |
| if (*s == CMDQ) { /* Backslash (quote character)? */ |
| if ((x = xxesc(&s)) > -1) { /* Go interpret it. */ |
| *q++ = (char) x; /* Numeric backslash code, ok */ |
| } else { /* Just let it quote next char */ |
| s++; /* get past the backslash */ |
| *q++ = *s++; /* deposit next char */ |
| } |
| continue; |
| } else if (*s == SP || *s == NUL) { /* Unquoted space or NUL? */ |
| *q++ = NUL; /* End of output filename. */ |
| msfiles[r] = p; /* Add this filename to the list */ |
| debug(F111,"fnparse",msfiles[r],r); |
| r++; /* Count it */ |
| if (*s == NUL) break; /* End of string? */ |
| while (*s == SP) s++; /* Skip repeated spaces */ |
| p = q; /* Start of next name */ |
| continue; |
| } else *q++ = *s; /* Otherwise copy the character */ |
| s++; /* Next input character */ |
| } |
| debug(F101,"fnparse r","",r); |
| msfiles[r] = ""; /* Put empty string at end of list */ |
| cmlist = msfiles; |
| return(r); |
| } |
| #endif /* NOMSEND */ |
| |
| char * /* dbchr() for DEBUG SESSION */ |
| dbchr(c) int c; { |
| static char s[8]; |
| char *cp = s; |
| |
| c &= 0xff; |
| if (c & 0x80) { /* 8th bit on */ |
| *cp++ = '~'; |
| c &= 0x7f; |
| } |
| if (c < SP) { /* Control character */ |
| *cp++ = '^'; |
| *cp++ = (char) ctl(c); |
| } else if (c == DEL) { |
| *cp++ = '^'; |
| *cp++ = '?'; |
| } else { /* Printing character */ |
| *cp++ = (char) c; |
| } |
| *cp = '\0'; /* Terminate string */ |
| cp = s; /* Return pointer to it */ |
| return(cp); |
| } |
| |
| /* C K H O S T -- Get name of local host (where C-Kermit is running) */ |
| |
| /* |
| Call with pointer to buffer to put hostname in, and length of buffer. |
| Copies hostname into buffer on success, puts null string in buffer on |
| failure. |
| */ |
| #ifdef BSD44 |
| #define BSD4 |
| #undef ATTSV |
| #endif /* BSD44 */ |
| |
| #ifdef SVORPOSIX |
| #ifndef BSD44 |
| #ifndef apollo |
| #include <sys/utsname.h> |
| #endif /* apollo */ |
| #endif /* BSD44 */ |
| #else |
| #ifdef BELLV10 |
| #include <utsname.h> |
| #endif /* BELLV10 */ |
| #endif /* SVORPOSIX*/ |
| |
| #ifdef CKSYSLOG |
| extern char uidbuf[], * clienthost; |
| #endif /* CKSYSLOG */ |
| |
| VOID |
| ckhost(vvbuf,vvlen) char * vvbuf; int vvlen; { |
| |
| #ifndef NOPUSH |
| extern int nopush; |
| #ifndef NOSERVER |
| extern int en_hos; |
| #endif /* NOSERVER */ |
| #endif /* NOPUSH */ |
| |
| #ifdef pdp11 |
| *vvbuf = NUL; |
| #else /* Everything else - rest of this routine */ |
| |
| char *g; |
| int havefull = 0; |
| #ifdef VMS |
| int x; |
| #endif /* VMS */ |
| |
| #ifdef SVORPOSIX |
| #ifndef BSD44 |
| #ifndef _386BSD |
| #ifndef APOLLOSR10 |
| struct utsname hname; |
| #endif /* APOLLOSR10 */ |
| #endif /* _386BSD */ |
| #endif /* BSD44 */ |
| #endif /* SVORPOSIX */ |
| #ifdef datageneral |
| int ac0 = (char *) vvbuf, ac1 = -1, ac2 = 0; |
| #endif /* datageneral */ |
| |
| #ifndef NOPUSH |
| if (getenv("CK_NOPUSH")) { /* No shell access allowed */ |
| nopush = 1; /* on this host... */ |
| #ifndef NOSERVER |
| en_hos = 0; |
| #endif /* NOSERVER */ |
| } |
| #endif /* NOPUSH */ |
| |
| *vvbuf = NUL; /* How let's get our host name ... */ |
| |
| #ifndef BELLV10 /* Does not have gethostname() */ |
| #ifndef OXOS |
| #ifdef SVORPOSIX |
| #ifdef APOLLOSR10 |
| ckstrncpy(vvbuf,"Apollo",vvlen); |
| #else |
| #ifdef BSD44 |
| if (gethostname(vvbuf,vvlen) < 0) |
| *vvbuf = NUL; |
| #else |
| #ifdef _386BSD |
| if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL; |
| #else |
| #ifdef QNX |
| #ifdef TCPSOCKET |
| if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL; |
| #else |
| if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen); |
| #endif /* TCPSOCKET */ |
| #else /* SVORPOSIX but not _386BSD or BSD44 */ |
| #ifdef __ia64__ |
| if (uname(&hname) > -1) ckstrncpy(vvbuf,hname.nodename,vvlen); |
| #else |
| if (uname(&hname) > -1) { |
| char * p; |
| p = hname.nodename; |
| #ifdef TCPSOCKET |
| #ifndef NOCKGETFQHOST |
| if (!ckstrchr(p,'.')) |
| p = (char *)ckgetfqhostname(p); |
| #endif /* NOCKGETFQHOST */ |
| #endif /* TCPSOCKET */ |
| if (!p) p = ""; |
| if (!*p) p = "(unknown)"; |
| ckstrncpy(vvbuf,p,vvlen); |
| } |
| #endif /* __ia64__ */ |
| #endif /* QNX */ |
| #endif /* _386BSD */ |
| #endif /* BSD44 */ |
| #endif /* APOLLOSR10 */ |
| #else /* !SVORPOSIX */ |
| #ifdef BSD4 |
| if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL; |
| #else /* !BSD4 */ |
| #ifdef VMS |
| g = getenv("SYS$NODE"); |
| if (g) ckstrncpy(vvbuf,g,vvlen); |
| x = (int)strlen(vvbuf); |
| if (x > 1 && vvbuf[x-1] == ':' && vvbuf[x-2] == ':') vvbuf[x-2] = NUL; |
| #else |
| #ifdef datageneral |
| if (sys($HNAME,&ac0,&ac1,&ac2) == 0) /* successful */ |
| vvlen = ac2 + 1; /* enh - have to add one */ |
| #else |
| #ifdef OS2 /* OS/2 */ |
| g = os2_gethostname(); |
| if (g) ckstrncpy(vvbuf,g,vvlen); |
| #else /* OS2 */ |
| #ifdef OSK |
| #ifdef TCPSOCKET |
| if (gethostname(vvbuf, vvlen) < 0) *vvbuf = NUL; |
| #endif /* TCPSOCKET */ |
| #endif /* OSK */ |
| #endif /* OS2 */ |
| #endif /* datageneral */ |
| #endif /* VMS */ |
| #endif /* BSD4 */ |
| #endif /* SVORPOSIX */ |
| #else /* OXOS */ |
| /* If TCP/IP is not installed, gethostname() fails, use uname() */ |
| if (gethostname(vvbuf,vvlen) < 0) { |
| if (uname(&hname) > -1) |
| ckstrncpy(vvbuf,hname.nodename,vvlen); |
| else |
| *vvbuf = NUL; |
| } |
| #endif /* OXOS */ |
| #endif /* BELLV10 */ |
| if (*vvbuf == NUL) { /* If it's still empty */ |
| g = getenv("HOST"); /* try this */ |
| if (g) ckstrncpy(vvbuf,g,vvlen); |
| } |
| vvbuf[vvlen-1] = NUL; /* Make sure result is terminated. */ |
| #endif /* pdp11 */ |
| } |
| #ifdef BSD44 |
| #undef BSD4 |
| #define ATTSV |
| #endif /* BSD44 */ |
| |
| /* |
| A S K M O R E -- Poor person's "more". |
| Returns 0 if no more, 1 if more wanted. |
| */ |
| int |
| askmore() { |
| char c; |
| int rv, cx; |
| #ifdef IKSD |
| extern int timelimit; |
| #endif /* IKSD */ |
| #ifdef IKSDCONF |
| extern int iksdcf; |
| #endif /* IKSDCONF */ |
| #ifdef CK_APC |
| extern int apcstatus, apcactive; |
| #endif /* CK_APC */ |
| |
| #ifdef NOICP |
| return(1); |
| #else |
| if (!xaskmore) |
| return(1); |
| #ifdef IKSDCONF |
| if (inserver && !iksdcf) |
| return(1); |
| #endif /* IKSDCONF */ |
| #ifdef CK_APC |
| if (apcactive == APC_LOCAL || |
| (apcactive == APC_REMOTE && (apcstatus & APC_NOINP))) |
| return(1); |
| #endif /* CK_APC */ |
| #ifdef VMS |
| if (batch) |
| return(1); |
| #else |
| #ifdef UNIX |
| if (backgrd) |
| return(1); |
| #endif /* UNIX */ |
| #endif /* VMS */ |
| |
| #ifndef VMS |
| concb((char)escape); /* Force CBREAK mode. */ |
| #endif /* VMS */ |
| |
| rv = -1; |
| while (rv < 0) { |
| #ifndef OS2 |
| printf("more? "); |
| #ifdef UNIX |
| #ifdef NOSETBUF |
| fflush(stdout); |
| #endif /* NOSETBUF */ |
| #endif /* UNIX */ |
| #else |
| printf("more? "); |
| fflush(stdout); |
| #endif /* OS2 */ |
| |
| #ifdef IKSD |
| if (inserver) { |
| cx = cmdgetc(timelimit); |
| if (cx < -1 && timelimit) { |
| printf("\n?IKS idle timeout - Goodbye.\n"); |
| doexit(GOOD_EXIT,0); |
| } else if (cx == -1) { /* Connection lost */ |
| doexit(BAD_EXIT,0); |
| } |
| c = (char) cx; |
| } else { |
| #endif /* IKSD */ |
| #ifdef VMS |
| conbin((char)escape); /* Protect against Ctrl-Z */ |
| cx = coninc(0); |
| concb((char)escape); |
| #else |
| cx = cmdgetc(0); |
| #endif /* VMS */ |
| debug(F101,"askmore cmdgetc","",cx); |
| if (cx == EOF) { |
| debug(F100,"askmore EOF","",0); |
| #ifdef VMS |
| c = '\032'; |
| #else |
| c = 'n'; |
| #endif /* VMS */ |
| } else { |
| c = (char)cx; |
| } |
| debug(F101,"askmore c","",c); |
| |
| #ifdef IKSD |
| } |
| #endif /* IKSD */ |
| switch (c) { |
| /* Yes */ |
| case 'p': case 'P': case 'g': case 'G': /* Proceed or Go */ |
| xaskmore = 0; |
| /* fall thru on purpose */ |
| |
| case SP: case 'y': case 'Y': case 012: case 015: |
| #ifdef OSK |
| write(1, "\015 \015", sizeof "\015 \015" - 1); |
| #else |
| printf("\015 \015"); |
| #endif /* OSK */ |
| rv = 1; |
| break; |
| /* No */ |
| case 'n': case 'N': case 'q': case 'Q': |
| #ifdef OSK |
| printf("\n"); |
| #else |
| printf("\015\012"); |
| #endif /* OSK */ |
| rv = 0; |
| break; |
| case '\003': |
| case '\004': |
| case '\032': |
| #ifdef OSK |
| printf("^%c...\n", (c + 0100)); |
| #else |
| printf("^%c...\015\012", (c + 0100)); |
| #endif /* OSK */ |
| rv = 0; |
| break; |
| /* Invalid answer */ |
| default: |
| debug(F111,"askmore","invalid answer",c); |
| printf("Y or space-bar for yes, N for no, G to show the rest\n"); |
| continue; |
| } |
| #ifdef OS2 |
| printf("\r \r"); |
| fflush(stdout); |
| #endif /* OS2 */ |
| } |
| return(rv); |
| #endif /* NOICP */ |
| } |
| |
| /* T R A P -- Terminal interrupt handler */ |
| |
| SIGTYP |
| #ifdef CK_ANSIC |
| trap(int sig) |
| #else |
| trap(sig) int sig; |
| #endif /* CK_ANSIC */ |
| /* trap */ { |
| extern int b_save, f_save; |
| #ifndef NOICP |
| extern int timelimit; |
| #endif /* NOICP */ |
| #ifdef OS2 |
| extern unsigned long startflags; |
| #ifndef NOSETKEY |
| extern int os2gks; |
| #endif /* NOSETKEY */ |
| int i; |
| #endif /* OS2 */ |
| #ifndef NOSPL |
| extern int i_active, instatus; |
| #endif /* NOSPL */ |
| #ifdef VMS |
| int i; FILE *f; |
| #endif /* VMS */ |
| extern int zchkod, zchkid; |
| #ifndef NOSPL |
| extern int unkmacro; |
| #endif /* NOSPL */ |
| |
| debok = 1; |
| #ifdef NTSIG |
| connoi(); |
| #endif /* NTSIG */ |
| #ifdef __EMX__ |
| signal(SIGINT, SIG_ACK); |
| #endif |
| #ifdef GEMDOS |
| /* GEM is not reentrant, no i/o from interrupt level */ |
| cklongjmp(cmjbuf,1); /* Jump back to parser now! */ |
| #endif /* GEMDOS */ |
| |
| #ifdef DEBUG |
| if (deblog) { |
| if (sig == SIGINT) |
| debug(F101,"trap caught SIGINT","",sig); |
| else |
| debug(F101,"trap caught signal","",sig); |
| } |
| #endif /* DEBUG */ |
| |
| #ifdef OS2 |
| if ( sig == SIGBREAK && (startflags & 128) ) { |
| debug(F101,"trap ignoring SIGBREAK","",sig); |
| return; |
| } |
| #endif /* OS2 */ |
| |
| #ifndef NOICP |
| timelimit = 0; /* In case timed ASK interrupted */ |
| #ifndef NOSPL |
| unkmacro = 0; /* Or ON_UNKNOWN_MACRO interrupted.. */ |
| #endif /* NOSPL */ |
| #endif /* NOICP */ |
| zchkod = 0; /* Or file expansion interrupted... */ |
| zchkid = 0; |
| interrupted = 1; |
| |
| if (what & W_CONNECT) { /* Are we in CONNECT mode? */ |
| /* |
| The HP workstation Reset key sends some kind of ueber-SIGINT that can not |
| be SIG_IGNored, so we wind up here somehow (even though this is *not* the |
| current SIGINT handler). Just return. |
| */ |
| debug(F101,"trap: SIGINT caught during CONNECT","",sig); |
| SIGRETURN; |
| } |
| #ifndef NOSPL |
| if (i_active) { /* INPUT command was active? */ |
| i_active = 0; /* Not any more... */ |
| instatus = INP_UI; /* INPUT status = User Interrupted */ |
| } |
| #endif /* NOSPL */ |
| |
| #ifndef NOXFER |
| ftreset(); /* Restore global protocol settings */ |
| binary = b_save; /* Then restore these */ |
| fncnv = f_save; |
| bye_active = 0; |
| diractive = 0; |
| cdactive = 0; |
| #endif /* NOXFER */ |
| zclose(ZIFILE); /* If we were transferring a file, */ |
| zclose(ZOFILE); /* close it. */ |
| #ifndef NOICP |
| cmdsquo(cmd_quoting); /* If command quoting was turned off */ |
| #ifdef CKLEARN |
| { |
| extern FILE * learnfp; |
| extern int learning; |
| if (learnfp) { |
| fclose(learnfp); |
| learnfp = NULL; |
| learning = 0; |
| } |
| } |
| #endif /* CKLEARN */ |
| #endif /* NOICP */ |
| #ifdef CK_APC |
| delmac("_apc_commands",1); |
| apcactive = APC_INACTIVE; |
| #endif /* CK_APC */ |
| |
| #ifdef VMS |
| /* |
| Fix terminal. |
| */ |
| if (ft_win) { /* If curses window open */ |
| debug(F100,"^C trap() curses","",0); |
| xxscreen(SCR_CW,0,0L,""); /* Close it */ |
| conres |