From 5e42ed7ef542f98b19dec6d8e14dcbd5d1e94d72 Mon Sep 17 00:00:00 2001 From: Ian Beckwith Date: Fri, 17 Jun 2011 20:29:34 +0100 Subject: [PATCH] popped all patches --- .pc/010_makefile-destdir-support.patch/.timestamp | 0 .pc/010_makefile-destdir-support.patch/makefile | 7838 --------- .pc/020_man-hyphen-quoting.patch/.timestamp | 0 .pc/020_man-hyphen-quoting.patch/ckuker.nr | 1827 --- .pc/030_fix-if-else.patch/.timestamp | 0 .pc/030_fix-if-else.patch/ckuus6.c | 10878 ------------- .pc/030_fix-if-else.patch/ckuusr.c | 13121 --------------- .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/050_ck_patch.patch/.timestamp | 0 .pc/050_ck_patch.patch/ckcmai.c | 3592 ---- .pc/060_speeling.patch/.timestamp | 0 .pc/060_speeling.patch/ckcftp.c | 17126 -------------------- .pc/060_speeling.patch/ckcpro.w | 3591 ---- .pc/060_speeling.patch/ckermit80.txt | 10349 ------------ .pc/060_speeling.patch/ckuker.nr | 1827 --- .pc/060_speeling.patch/ckututor.txt | 1959 --- .pc/060_speeling.patch/ckuus2.c | 13838 ---------------- .pc/060_speeling.patch/ckuusr.h | 2974 ---- .pc/applied-patches | 6 - ckcftp.c | 2 +- ckcmai.c | 2 +- ckcpro.w | 2 +- ckermit80.txt | 2 +- ckufio.c | 11 +- ckuker.nr | 696 +- ckututor.txt | 4 +- ckuus2.c | 6 +- ckuus6.c | 2 +- ckuus7.c | 27 +- ckuusr.c | 3 +- ckuusr.h | 2 +- makefile | 22 +- 34 files changed, 378 insertions(+), 112572 deletions(-) delete mode 100644 .pc/010_makefile-destdir-support.patch/.timestamp delete mode 100644 .pc/010_makefile-destdir-support.patch/makefile delete mode 100644 .pc/020_man-hyphen-quoting.patch/.timestamp delete mode 100644 .pc/020_man-hyphen-quoting.patch/ckuker.nr delete mode 100644 .pc/030_fix-if-else.patch/.timestamp delete mode 100644 .pc/030_fix-if-else.patch/ckuus6.c delete mode 100644 .pc/030_fix-if-else.patch/ckuusr.c 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 delete mode 100644 .pc/050_ck_patch.patch/.timestamp delete mode 100644 .pc/050_ck_patch.patch/ckcmai.c delete mode 100644 .pc/060_speeling.patch/.timestamp delete mode 100644 .pc/060_speeling.patch/ckcftp.c delete mode 100644 .pc/060_speeling.patch/ckcpro.w delete mode 100644 .pc/060_speeling.patch/ckermit80.txt delete mode 100644 .pc/060_speeling.patch/ckuker.nr delete mode 100644 .pc/060_speeling.patch/ckututor.txt delete mode 100644 .pc/060_speeling.patch/ckuus2.c delete mode 100644 .pc/060_speeling.patch/ckuusr.h delete mode 100644 .pc/applied-patches diff --git a/.pc/010_makefile-destdir-support.patch/.timestamp b/.pc/010_makefile-destdir-support.patch/.timestamp deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/010_makefile-destdir-support.patch/makefile b/.pc/010_makefile-destdir-support.patch/makefile deleted file mode 100644 index c2380eb..0000000 --- a/.pc/010_makefile-destdir-support.patch/makefile +++ /dev/null @@ -1,7838 +0,0 @@ -# makefile / Makefile / ckuker.mak / CKUKER.MAK -# -# Sat Apr 17 14:49:18 2004 -BUILDID=20040417 -# -CKVER= "8.0.211" -# -# -- Makefile to build C-Kermit for UNIX and UNIX-like platforms -- -# -# 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. -# -# Author: Frank da Cruz, Columbia University -# 612 West 115th Street, New York NY 10025-7799, USA -# E-mail: fdc@columbia.edu -# Fax: +1 212 662-6442 -# Web: http://www.columbia.edu/kermit/ -# -# Contributions from many others. Special thanks to Jeff Altman for the -# secure-target entries, Peter Eichhorn, assyst GmbH, for the consolidated -# HP-UX entries and the "uninstall" target, to Robert Lipe for the updated -# and consolidated SCO UNIX / ODT / OSR5 entries, to Ric Anderson for the -# IRIX 6.x entries. -# -# Most entries use the "xermit" target, which uses the select()-based CONNECT -# module, ckucns.c. The "wermit" target uses the older fork()-base CONNECT -# module, ckucon.c, which has some drawbacks (but is more portable). If your -# entry still uses the "wermit" target, please try substituting the "xermit" -# one and if it works, let us know (mailto:kermit-support@columbia.edu). -# When changing a target over from wermit to xermit, also remove -DNOLOEARN. -# -# CAREFUL: Don't put the lowercase word "if", "define", or "end" as the first -# word after the "#" comment introducer in the makefile, even if it is -# separated by whitespace. Some versions of "make" understand these as -# directives. Uppercase letters remove the danger, e.g. "# If you have..." -# -# WARNING: This is a huge makefile and it contains nested makes. Some "make" -# programs might run out of memory. If this happens to you, edit away the -# parts that do not apply to your platform and try again. -# -# Certain UNIX variations have their own separate makefiles: -# . For 2.10 or 2.11 BSD on DEC PDP-11s, use ckubs2.mak. -# . For Plan 9, use ckpker.mk. -# -# Separate build procedures are provided non-UNIX platforms: VMS, VOS, -# AOS/VS, etc. See the ckaaaa.txt file for details. -# -# -# DIRECTIONS -# -# Rename this file to "makefile" or "Makefile" if necessary. Pick out the -# entry most appropriate for your UNIX version from the list below and then -# give the appropriate "make" command, for example "make aix43", "make sys5r4", -# "make linux". If you experience any difficulties with the build procedure, -# then please also read any comments that accompany the make entry itself -# (search for the make entry name on the left margin). -# -# Other entries: -# 'make install' is an installation script (read accompanying comments!). -# 'make clean' removes intermediate and object files. -# -# IMPORTANT: -# For more detailed installation instructions, read the files ckuins.txt -# and ckccfg.txt, also available at the Kermit website in HTML form: -# http://www.columbia.edu/kermit/ckuins.html -# http://www.columbia.edu/kermit/ckccfg.html -# -# For descriptions of known problems and limitations, -# read the files ckcbwr.txt and ckubwr.txt (the "beware files") or: -# http://www.columbia.edu/kermit/ckcbwr.html -# http://www.columbia.edu/kermit/ckubwr.html -# -# Most entries build C-Kermit with its symbol table included. To reduce the -# size of the executable program, add "LNKFLAGS=-s" to the end of your 'make' -# command or to the makefile entry, or 'strip' the executable after -# building. To further reduce the size after building, use 'mcs -d' if your -# Unix version has such a command. For further details on size reduction, read -# ckccfg.txt to find out how to remove features that you don't need. -# -# TCP/IP networking support: If your C-Kermit version does not include TCP/IP -# networking, but your UNIX system does, try adding -DTCPSOCKET to the CFLAGS -# of your makefile entry. If that doesn't work, look at some of the other -# entries that include this flag for ideas about what libraries might need to -# be included (typically -lsocket and/or -lBSD and/or -lnsl and/or -linet). -# NOTE: In some cases (old versions of SCO or HP-UX), you might need not only -# a C compiler, but also a "TCP/IP developers kit" for the required object -# libraries and header files. -# -# Fullscreen file transfer display support: If you are going to use C-Kermit -# for establishing connections (dialed, network, etc), you can configure it to -# produce a formatted file transfer display by including the curses library -# and adding -DCK_CURSES to the CFLAGS for your option, and linking with the -# appropriate libraries. There are many examples below, usually ending in -# "c", like sunos41c. Also add -DCK_WREFRESH if your curses library includes -# clearok() and wrefresh() functions (or remove -DNOWREFRESH if the linker -# complains that it can't find these functions). -# -# Please report modifications, failures (preferably with fixes) or successes -# to the author. -# -# SECURE TARGETS -# These are described after the next section. Search for ******* below. -# -# TARGETS FOR DIFFERENT UNIX PLATFORMS AND VERSIONS: -# -# + Marks those that have been built successfully for C-Kermit 8.0 or later. -# - Those that once built OK but no longer do (e.g. too big). -# ? Those that worked in a previous version but have not been tested recently. -# -------------------------- -# ? for 386BSD (Jolix) 0.0, 0.1, "make 386bsd" (see comments in entry), -# or (preferably, if it works) "make bsd44" or "make bsd44c". -# ? for Acorn RISCiX, "make riscix" or "make riscix-gcc" -# ? for Alliant FX/8 with Concentrix 4.1 or later, "make bsdlck" -# ? for Altos 486, 586, 986 with Xenix 3.0, "make altos" -# ? for Altos ACS68000, 8Mhz 68000, UNIX System 3 Rel 2, 512K, "make altos3" -# ? for Amdahl UTS 2.4 on IBM 370 series & compatible mainframes, "make uts24" -# ? for Amdahl UTSV IBM 370 series & compatible mainframes, "make utsv" -# ? for Amdahl UTSV IBM 370 series mainframes with TCP/IP, "make utsvtcp" -# ? for Amdahl mainframes with UNIX System V R 5.2.6b 580, "make sys3" -# ? for Apollo Aegis 9.x, DOMAIN/IX 9.x, "make aegis" -# (Last tested in C-Kermit 5A(189)) -# ? for Apollo DOMAIN/IX, if the above fails, try "make apollobsd" -# ? for Apollo with SR10.0 or later, BSD environment, "make sr10-bsd" -# ? for Apollo with SR10.0 or later, System V environment, "make sr10-s5r3" -# ? for Apple Macintosh II with A/UX pre-3.0, "make aux", "auxgcc" or "auxufs" -# ? for Apple Macintosh with A/UX 3.0 and gcc, "make aux3gcc" or aux3gccc -# ? for Apple PowerMac with MkLinux, "make mklinux" (read Linux entry first) -# + for Apple PowerMac with LinuxPPC, "make linuxppc" -# ? for Apple Macintosh with Minix 1.5.10, "make minix68k" or "make minixc68" -# + for Apple Macintosh with Mac OS X 1.0 (Rhapsody), "make macosx10" -# (no curses), "make macosx10c" (curses), or "make macosx10nc" (ncurses). -# Or "make macosx10ncx" (ncurses but "make macosx10nc" doesn't work). -# + for Apple Macintosh with Mac OS X 10.2, "make macosx102nc" (ncurses). -# + for Apple Macintosh with Mac OS X 10.3, "make macosx103" -# ? for Arix System 90 with AT&T SVR3, "make sys5r3na" -# - for AT&T 6300 with IN/ix, "make sys5" -# - for AT&T 6300 PLUS, "make att6300" or (with no debugging) "make att6300nd" -# ? for AT&T 6386 WGS UNIX PC, "make sys5r3" -# + for AT&T 3B2, 3B20 systems, "make att3b2". -# for AT&T 3B1, 7300 UNIX PC (see notes with the entries): -# In C-Kermit 7.0, only the gcc entries work: -# + "make sys3upcg", "make sys3upcgc", "make att351gm" -# The others fail with "too many defines" (usually in ckuusr.h): -# - "make sys3upc", "make sys3upcold", "make sys3upcc", "make sys3upcx", -# "make sys3upcm", "make att351m" -# ? for AT&T System III/System V R2 or earlier, "make sys3" or "make sys3nid" -# ? for AT&T System III/System V with Honey DanBer UUCP, "make sys3hdb" -# ? for AT&T System V on DEC VAX, "make sys3" or "make sys5r3" -# + for AT&T System V R3, use "make sys5r3" or "make sys5r3c" -# + for AT&T System V/386 R3.2 built on Interactive 4.1.1, "make sys5r32is". -# ? for AT&T System V/386 R320.0 Versyss Systems, use "make sys5r3" -# or "make sys5r3c". -# + for AT&T System V R4, "make sys5r4", "make sys5r4sx", or "make sys5r4nx", -# or if the ANSI C function prototyping makes trouble, add -DNOANSI, -# as in "sys5r4sxna" entry -# + for AT&T (USL) System V R4.2 use the sys5r4* entries. -# ? for Atari Falcon with MiNT, "make posix" -# ? for Atari ST with Minix ST 1.5.10.3, "make minix68k" or "make minixc68" -# ? for BBN C/70 with IOS 2.0, "make c70" -# ? for BeBox with Be OS 1.x DR7, "make beboxdr7" -# Compiles OK but doesn't link with default linker which is limited to 64K. -# Links OK with "Code Warrior Gold". Many hacks in the source code need -# to be removed when DR8 and later come out. -# (Last tested in C-Kermit 6.0) -# - for BeBox with Be OS 1.x DR8, "make bebox" -# (Needed functions missing from operating system and/or not working.) -# - for Bell Labs UNIX Version 6 (6th Edition), there is no makefile entry. -# ? for Bell Labs UNIX Version 7 (7th Edition), "make v7" (but see notes below) -# (last built successfully in C-Kermit 5A188) -# ? for Bell Labs Research UNIX Version 10, "make bellv10" -# (last built successfully in C-Kermit 6.0) -# ? for Bell Labs / Lucent Plan 9, use separate makefile ckpker.mk: -# can be built for Intel, MIPS, 680x0, and PowerPC (last built C-Kermit 7.0) -# + for BSDI BSD/386 1.x, "make bsdi" -# + for BSDI BSD/OS 2.x, "make bsdi2" -# + for BSDI BSD/OS 3.0 or 3.1, "make bsdi3" -# + for BSDI BSD/OS 4.x, "make bsdi4" -# + for BSDI BSD/OS 4.x, to build a binary that also works on FreeBSD, -# "make bsdix". -# ? for Berkeley Unix 2.4, "make v7" (but read v7 material below) -# ? for Berkeley Unix 2.9 (DEC PDP-11 or Pro-3xx), "make bsd29" -# - for Berkeley Unix 2.10, use ckubs2.mak (a separate makefile) -# - for Berkeley Unix 2.11, use ckubs2.mak (a separate makefile) -# This makefile is too big. Read the instructions in ckubs2.mak. -# "make -f ckubs2.mak bsd210" or "make -f ckubs2.mak bsd211". -# (last built successfully in C-Kermit 6.0 - later versions too big) -# + for Berkeley Unix 2.11 "make -f ckubs2.mak bsd210noicp" (no command parser) -# ? for Berkeley Unix 4.1, "make bsd41" -# + for Berkeley Unix 4.2 on VAX, "make bsd42" or "make bsd42c" -# ? for Berkeley Unix 4.2 or 4.3 with HoneyDanBer UUCP, "make bsdhdb" -# + for Berkeley Unix 4.3 on VAX, "make bsd43", "make bsd43nc". -# + for Berkeley Unix 4.3 on VAX, no networking "make bsd43nonet. -# + for Berkeley Unix 4.3 without acucntrl program, "make bsd42" or "bsd42c" -# NOTE: all the C-Kermit 7.0 full builds for old BSDs fail with -# "too many defines" in CPP, even on big architectures like VAX. This -# can be worked around with a clever ruse. See comments at target. -# + for Berkeley Unix 4.3, command-line only, "make bsdm". -# + for Berkeley Unix 4.3-Tahoe, same as 4.3 BSD -# + for Berkeley Unix 4.3-Reno, "make bsd43" or "make bsd44" or "make bsd44c" -# + for Berkeley Unix 4.3-Carson City, "make bsd44" or "make bsd44c" -# + for Berkeley Unix 4.4-Networking/2 or -Alpha, "make bsd44" or "make bsd44c" -# + for Berkeley Unix 4.4, "make bsd44" or "make bsd44c" -# + for Berkeley Unix 4.4-Lite, "make bsd44" or "make bsd44c" -# ? for Bull DPX/2 with BOS/X, "make bulldpx2" -# ? for Cadmus, "make sys3" -# for Caldera, see SCO, Linux. -# ? for Callan Unistar, "make sys3" -# ? for CDC VX/VE 5.2.1 System V emulation, "make vxve" -# ? for Charles River Data Systems Universe 680x0 with UNOS 9.2, maybe -# also other UNOS versions, "make crds" -# ? for CIE Systems 680/20 with Regulus, "make cie" -# + for Commodore Amiga 3000UX Sys V R4, "make sys5r4sx" -# + for Commodore Amiga 3000UX Sys V R4 and TCP/IP, "make svr4amiganet" -# ? for Commodore Amiga with Minix 1.5.10, "make minix68k" of "make minixc68" -# ? for Concurrent/Masscomp with RTU 4.0 or later, BSD environment, "make -# rtubsd", "make rtubsd2", "make rtubsd3" (depending on where ndir.h -# is stored, see entries below). -# ? for Concurrent/Masscomp with RTU 4.0 or later, System V R2, "make rtus5" -# ? for Concurrent (Perkin-Elmer) 3200 series, "make sys5". -# ? for Concurrent (Perkin-Elmer) 3200 series with , "make ccop1" -# + for Concurrent PowerMAX OS SVR4, "make powermax" -# ? for Consensys UNIX SV/386 R4V3, "make sys5r4sxtcpc" or "make sys5r4sx" -# ? for Convergent with CTIX Sys V R2, "make sys5" -# ? for Convergent with CTIX 6.4.1, "make ctix" -# ? for Convex C1, "make convex" -# ? for Convex C210 with Convex/OS 8, "make convex8" -# ? for Convex C2 with Convex/OS 9.1, "make convex9" -# ? for Convex C2 with Convex/OS 10.1 and gcc 2.x, "make convex10gcc" -# ? for Cray Research X/MP or YMP or C90 with UNICOS 6.x (System V R3), -# "make cray" -# ? for Cray Research X/MP or YMP or C90 with UNICOS 7.x (System V R4), -# "make cray" -# ? for Cray Research X/MP or YMP or C90 with UNICOS 8.0 Alpha, "make cray8" -# ? for Cray Research X/MP or Y-MP or C90 with UNICOS 9.0, "make cray9" -# ? for Cray Computer Cray-2 or Cray3 with CSOS, "make craycsos" -# ? for Cyber 910 (Silicon-Graphics Iris) with Irix 3.3, "irix33" -# ? for Data General AViiON with DG/UX 5.4 before R3.00, "make dgux540" -# or "make dgux540c" (compile ckwart separately if necessary) -# + for DG/UX 5.4 on AViiON Intel models, "make dgux540i" or dgux540ic. -# ? for DG/UX 5.4R4.11 on AViiON, all models, "make dgux54411" -# + for DG/UX 5.4R4.20 on AViiON, all models, "make dgux54420" -# + for Data General AViiON with DG/UX 4.3x using Sys V-isms, "make dgux430" -# ? for Data General AViiON with DG/UX 4.3x using BSD-isms, "make dgux430bsd" -# ? for Data General AViiON, earlier UNIX versions, -# "make sys5r3" (maybe compile ckwart separately, or "touch ckcpro.c") -# ? for Data General MV systems with DG/UX, ??? -# ? for Data General MV systems with MV/UX, use AOS/VS C-Kermit (CKDKER.MAK) -# ? for Data General MV systems with AOS/VS, use CKDKER.MAK (last = C-K 7.0) -# for DEC PDP-11 with Berkeley UNIX 2.x, see Berkeley UNIX 2.x. -# ? for DEC PDP-11 with Mini-UNIX (Bell 6th Edition for PDP-11 with no MMU), -# probably no way to fit C-Kermit without I&D space. -# ? for DEC PDP-11 with Ultrix-11 3.x, ??? (probably needs overlays) -# ? for DEC VAX with Ultrix 1.x "make bsd" -# ? for DEC VAX with Ultrix 2.x "make ultrix2x" -# ? for DEC VAX or DECstation with Ultrix 3.0, 3.1, "make ultrix3x" -# ? for DECstation or VAX with Ultrix 4.0 or 4.1, "make ultrix40" -# ? for DECstation or VAX with Ultrix 4.2, "make ultrix42" or "make ultrix42c" -# ? for DECstation or VAX with Ultrix 4.x, POSIX world, "make posix" -# + for DECstation or VAX with Ultrix 4.3, "make ultrix43". -# + for DECstation or VAX with Ultrix 4.4, "make ultrix44". -# ? for DECstation 5000/50, /150 or /260 (R4x00 MIPS CPU), Ultrix 4.3A or later -# "make ultrix43-mips3" or "make ultrix43c-mips3" -# ? for DECstation (MIPS) with Berkeley Sprite, "make bsd44"? -# ? for DECstation (MIPS) with OSF/1 V1.0 to 1.3, "make dec-osf" -# ? for DEC Alpha with OSF/1 1.0 to 1.3, "make dec-osf" -# ? for DEC PC 486 with OSF/1, "make dec-osf" -# ? for DEC Alpha with OSF/1 2.x, "make dec-osf20" -# + for DEC Alpha with OSF/1 3.0, "make dec-osf30" -# + for DEC Alpha with Digital UNIX 3.2, "make du32" -# + for DEC Alpha with Digital UNIX 4.0-4.0D, "make du40" or "make du40gcc" -# + for DEC Alpha with Digital UNIX 4.0E or higher, see Tru64. -# - for DEC Pro-350 with Pro/Venix V1.x, "make provx1" (version 5A is too big) -# ? for DEC Pro-380 with Pro/Venix V2.0 (Sys V), "make sys3" or "make sys3nid" -# ? for DEC Pro-380 with 2.9, 2.10, or 2.11 BSD, "make bsd29" or "make bsd210" -# for DEC PDP-11 with 2.xBSD (use separate makefile ckubs2.mak) -# ? for Dell UNIX Issue 2.x (= USL Sys V/386 R4.x + fixes), "make dellsys5r4" -# or "make dellsys5r4c" (last tested in C-Kermit 5A). -# ? for DIAB DS90 with DNIX (any version) create an empty if -# this file does not already exist (or add -DNOFILEH to the make entry). -# ? for DIAB DS90 with DNIX 5.2 (Sys V.2) or earlier, "make dnix", -# "make dnixnd", or (to add curses and TCP/IP) "make dnixnetc", -# ? for DIAB DS90 with DNIX 5.3 (Sys V.3), "make dnix5r3" -# ? for DIAB DS90 with DNIX 5.3 (Sys V.3) and TCP/IP, "make dnix5r3net" -# ? for DIAB DS90 with DNIX 5.3 2.2 (Sys V.3), ANSI C, "make dnix5r3ansi" -# or, to include TCP/IP, "make dnix5r3ansinet", -# but you have to fix a bug in /usr/include/stdlib.h first: -# change "extern void free(char *str);" to "extern void free(void *str);" -# ? for Dolphin Server Technology Triton 88/17 with SV/88 R3.2, "make sv88r32" -# ? for Encore Multimax 310, 510 with Umax 4.2, "make umax42" -# ? for Encore Multimax 310, 510 with Umax 4.3, "make umax43" -# ? for Encore Multimax 310, 510 with Umax V 2.2, use Berkeley cc, "make bsd" -# ? for Encore 88K with Umax V 5.2, "make encore88k" -# ? for ESIX System V R4.0.3 or 4.04 with TCP/IP support, "make esixr4" -# NOTE: You can also build on Unixware 2.x with "make esixr4", and run -# on ESIX, but there you must first: -# ln /usr/lib/libsocket.so /usr/lib/libsocket.so.1 -# ln /usr/lib/libnsl.so /usr/lib/libnsl.so.1 -# (This worked for C-Kermit 6.0 but does not work for 7.0) -# (But you can probably still build a non-networking version this way) -# ? for Everex STEP 386/25 Rev G with ESIX Sys V R3.2D, "make sys5r3" -# ? for Fortune 32:16, For:Pro 1.8, "make ft18" -# ? for Fortune 32:16, For:Pro 2.1, "make ft21" -# ? for FPS 500 with FPX 4.1, "made bsd" -# + for FreeBSD 1.0, "make freebsd1" -# + for FreeBSD 2.x, "make freebsd2" (ncurses) or "make freebsd2c" (curses) -# + for FreeBSD 3.x, "make freebsd3" (ncurses) or "make freebsd3c" (curses) -# + for FreeBSD 4.0, "make freebsd4" -# + for FreeBSD 4.1, "make freebsd41" -# + for FreeBSD 4.2, "make freebsd42" -# + for FreeBSD 4.3, "make freebsd43" -# + for FreeBSD 4.4, "make freebsd44" -# + for FreeBSD 4.5, "make freebsd45" -# + for FreeBSD 4.6, "make freebsd46" -# + for FreeBSD 4.7, "make freebsd47" -# + for FreeBSD 4.8, "make freebsd48" -# + for FreeBSD 4.9, "make freebsd49" -# ? for FreeBSD 5.0, "make freebsd50" -# ? for FreeBSD 5.1, "make freebsd51" -# ? for Harris HCX-2900, "make sys5r3" -# ? for Harris Night Hawk 88K or 68K with CX/UX pre-6.1, "make sys5r3" -# ? for Harris Night Hawk 88K or 68K with CX/UX 6.1 or later, "make cx_ux" -# ? for Heurikon, "make sys3" -# ? for HP-3000, MPE/ix, "make posix"? -# + for HP-9000 Series 300 with 4.4BSD, "make bsd44" -# + for HP-9000 Series 500, HP-UX 5.21 and no networking "make hpux0500" -# + for HP-9000 Series 500, HP-UX 5.21 with WIN/TCP 1.2 "make hpux0500wintcp" -# + for HP-9000 Series, HP-UX 6.5, without long filenames, -# "make hpux0650" or "make hpux0650c" -# + for HP-9000 Series, HP-UX 7.0 or later no long filenames, "make hpux0700sf" -# or (to include tcp/ip, curses, etc) "make hpux0700sftcpc" -# + for HP-9000 Series with HP-UX 7.0, TCP/IP,long filenames,"make hpux0700lfn" -# + for HP-9000 300/400 Series (680x0) with HP-UX 8.0, TCP/IP, "make hpux0800" -# or "make hpux0800c" -# + for HP-9000 700/800 Series (PA-RISC), HP-UX 8.0, TCP/IP, "make hpux0800pa" -# or "make hpux0800pac" -# + for HP-9000 Series with HP-UX 8.0, no TCP/IP, long filenames, -# "make hpux0800notcp" -# + for HP-9000 Series, HP-UX 9.0 - 9.10, TCP/IP, curses, restricted compiler -# (no optimization, no ANSI), all models, "make hpux0900". Read the -# hpux0900 entry below for more info. -# + for HP-9000 700 and 800 Series, HP-UX 9.x, TCP/IP, curses, -# HP optimizing ANSI C compiler, "make hpux0900o700". -# + for HP-9000 with Motorola CPUs, HP-UX 9.x, TCP/IP, curses, -# HP optimizing ANSI C compiler, "make hpux0900mot". -# + for HP-9000 on other CPUs, HP-UX 9.x, TCP/IP, curses, -# HP optimizing ANSI C compiler, "make hpux0900o". -# + for HP-9000 series, HP-UX 9.x, TCP/IP, curses, gcc, all models, -# "make hpux0900gcc" -# + for HP-9000 700/800 Series, HP-UX 10.00,10.01,10.10,10.20,10.30, TCP/IP, -# curses, restricted compiler (no optimization, no ANSI) "make hpux1000". -# + for HP-9000 700/800 Series, HP-UX 10.00,10.01,10.10,10.20,10.30, TCP/IP, -# curses, HP ANSI/optimizing compiler "make hpux1000o" or "make hpux1000o+" -# + for HP-9000 HP-UX 10.00 or later with gcc, "make hpux1000gcc" -# + for Trusted HP-UX 10.xx "make hpux1000t", "make hpux1000to", -# or make hpux1000to+" -# + for HP-9000 700/800 Series, HP-UX 11.00,TCP/IP,curses, restricted compiler -# (no optimization, no ANSI) "make hpux1100". -# + for HP-9000 700/800 Series, HP-UX 11.00,TCP/IP,curses, restricted compiler -# HP ANSI/optimizing compiler "make hpux1100o" or "make hpux1100o+" -# + for Trusted HP-UX 11.xx "make hpux1100t", "make hpux1100to", -# make hpux1100to+" -# + for HP-9000 PA-RISC models with NeXTSTEP 3.3, "make nextquadfat". -# + for HP-9000 PA-RISC models with OPENSTEP/Mach 4.1, "make nextquadfat". -# ? for IBM 370 Series with IX/370, "make ix370" -# ? for IBM 370 Series with AIX/370 1.2, "make aix370" -# ? for IBM 370 Series with AIX/370 3.0, "make aix370" -# ? for IBM 370 Series with AIX/ESA 2.1, "make aixesa" -# - for IBM PC/AT 286 & compatibles with Mark Williams Coherent OS, -# command-line-only version, "make coherent" (version 5A & later too big) -# ? for IBM PC 386 & compatibles with Mark Williams Coherent OS, -# minimum interactive version, "make coherentmi" -# ? for IBM PC 386 & compatibles with Mark Williams Coherent OS, -# full interactive version, prior to v4.2, "make coherentmax" -# + for IBM PC 386 & compatibles with Mark Williams Coherent OS 4.2, -# "make coherent42" -# ? for IBM PC 386 & compatibles with LynxOS 2.0 or 2.1, "make lynx21" -# ? for IBM PC 386 & compatibles with LynxOS 2.2, "make lynx" -# - for IBM PC/AT & compatibles with original MINIX, "make minix" (too big) -# ? for IBM PC family, 386-based, with MINIX/386 1.5, "make minix386" -# or if you have GNU CC, "make minix386gcc" -# + for IBM PC family, 386-based, with MINIX 2.0, "make minix20" -# + for IBM PS/2 with PS/2 AIX 1.0, 1.1, or 1.2, "make ps2aix" or ps2aixnetc. -# ? for IBM PS/2 with PS/2 AIX 1.3, "make ps2aix3" -# ? for IBM RISC System/6000 with AIX 3.0, "make aix30" -# ? for IBM RISC System/6000 with AIX 3.1.x, "make aix31" -# + for IBM RISC System/6000 with AIX 3.2.0 thru 3.2.5, "make aix32" -# + for IBM RS/6000 or Power Series with AIX 4.1.x, "make aix41" -# + for IBM RS/6000 or Power Series with AIX 4.1.x with gcc, "make aix41g" -# + for IBM RS/6000 or Power Series with AIX 4.1 with X.25, "make aix41x25" -# + for IBM RS/6000 or Power Series with AIX 4.2, "make aix42" -# + for IBM RS/6000 or Power Series with AIX 4.3, "make aix43" (or aix43gcc) -# + for IBM RS/6000 or Power Series with AIX 4.4, "make aix44" (or aix44gcc) -# + for IBM RS/6000 or Power Series with AIX 4.5, "make aix45" (or aix45gcc) -# + for IBM RS/6000 or Power Series with AIX 5.0, "make aix50" (or aix50gcc) -# + for IBM RS/6000 or Power Series with AIX 5.1, "make aix51" (or aix51gcc) -# ? for IBM RS/6000 or Power Series with AIX 5.2, "make aix52" (or aix52gcc) -# ? for IBM RS/6000 or Power Series with AIX 5.3, "make aix53" (or aix53gcc) -# ? for IBM RT PC with AIX 2.1, "make sys3" -# + for IBM RT PC with AIX 2.2.1, "make rtaix" or "make rtaixc" -# ? for IBM RT PC with ACIS 4.2, "make bsd" -# ? for IBM RT PC with ACIS 4.3, "make rtacis" or "make bsd KFLAGS=-DNOANSI" -# ? for IBM RT PC with 4.3BSD/Reno, "make bsd44" or "make bsd44c" -# ? for ICL DRS400 or 400E, "make iclsys5r3" -# ? for ICL DRS3000 (80486) with DRS/NX, "make iclsys5r4_486" -# ? for ICL DRS6000 (SPARC) with DRS/NX, "make iclsys5r4" -# + for ICL DRS6000 (SPARC) with DRS/NX 4.2MP 7MPlus, "make iclsys5r4m+" -# ? Ditto but with IKSD support included, "make iclsys5r4m+iksd" -# ? for Integrated Solutions Inc V8S VME 68020, "make isi" -# ? for Intel 302 with Bell Tech Sys V/386 R3.2, "make sys5r3" -# ? for Intel Xenix/286, "make sco286" -# ? for Interactive System III (PC/IX), "make pcix" or "make is3" -# ? for Interactive System III (PC/IX) with gcc, "make is3gcc" -# ? for Interactive 386/ix 1.0.6 with TCP/IP networking, "make is5r3net2" -# ? for Interactive 386/ix 2.0.x, "make is5r3" or (POSIX) "make is5r3p" -# ? for Interactive 386/ix 2.0.x with TCP/IP networking, "make is5r3net" -# or "make is5r3net2" -# ? for Interactive 386/ix 2.2.1, job control, curses, no net, gcc, -# "make is5r3gcc" -# + for Interactive UNIX Sys V R3.2 V2.2 - 4.0 without TCP/IP, "make is5r3jc" -# + for Interactive UNIX Sys V R3.2 V2.2 - 4.0 with TCP/IP, "make is5r3netjc" -# + for Intergraph Clipper, "make clix" or "make clixnet" -# ? for Jolix (see 386BSD) -# + for Red Hat Linux 7.1 (and higher) fully configured (krb5, SSL, etc): -# "make redhat71", "make redhat72", "make redhat73", "make redhat80" -# "make redhat9" -# NOTE: You must use this target for Red Hat 7.1 since it -# also includes a workaround for its broken curses library. -# WARNING: These targets create binaries that include code for -# strong encryption and are therefore not exportable. DO NOT PUT -# THESE BINARIES ON US OR CANADIAN WEB OR FTP SITES. -# + for Linux 1.2 and later, "make linux". Uses ncurses. This version -# handles serial speeds up to 460800 bps, Linux FSSTD 1.2, TCP/IP, and -# should work on both libc and glibc systems. For static linking, use -# "make linux LNKFLAGS=-static". Please read the comments that accompany -# the linux entry. -# + for Linux builds that fail with "sys/select.h: No such file or directory", -# "make linuxns" -# + for Linux 1.2 and later but with curses.h and libcurses (rather than -# ncurses.h and libncurses), use "make linuxc". -# + for Linux 1.2 and later with no curses support at all, "make linuxnc". -# + for Linux on PowerMac (Mklinux DR3), "make mklinux". -# + for Linux 1.2 and later, to build with egcs, "make linuxegcs". -# + for Linux with no TCP/IP, "make linuxnotcp" -# + for Linux with lcc compiler, no TCP/IP, "make linuxnotcp-lcc" -# ? for Linux 1.0 or earlier, "make linux10", or (to remove TCP/IP) -# "make linuxnotcp". -# IMPORTANT: Read the comments that accompany the "linux:" entry. -# ? for Mach 2.6 on (anything, e.g. DECstation), "make bsd42" or "make bsd43". -# ? for MachTen (Tenon) 2.1.1.D on (e.g.) Apple Powerbook, "make machten". -# ? for Masscomp RTU AT&T System III, "make rtu" -# for other Masscomp, see Concurrent. -# ? for Microport SV/AT (System V R2), "make mpsysv" (last edit tested: 144) -# ? for Microport SVR4 2.2, 3.1, or 4.1 "make sys5r4sx" -# ? for Microsoft,IBM Xenix (/286, PC/AT, etc), "make xenix" or "make sco286" -# ? for MIPS System with RISC/os (UMIPS) 4.52 = AT&T SVR3, "make mips" -# or "make mipstcpc" -# + for MkLinux on Power Macintosh, "make mklinux" -# ? for Modcomp 9730, Real/IX, "make sys5r3" (or modify to use gcc = GLS cc) -# ? for Modcomp Realstar 1000 with REAL/IX D.1, "make sv88r32" -# ? for Motorola Four Phase, "make sys3" or "make sys3nid" -# + for Motorola Delta System V/68 R3, "make sv68r3" -# + for Motorola Delta System V/68 R3V5, "make sv68r3v5" -# + for Motorola Delta System V/68 R3V5.1, "make sv68r3v51" -# + for Motorola Delta System V/68 R3V6 with NSE TCP/IP, "make sv68r3v6" -# + for Motorola Delta System V/88 R32, "make sv88r32" -# + for Motorola Delta System V/88 R40, "make sv88r40" -# ? for Mt Xinu Mach386 on 386/486-based PCs, "make bsd43" -# ? for NCR Tower 1632, OS 1.02, "make tower1" -# ? for NCR Tower 1632 or Minitower with System V R2, "make sys3" -# or "make sys3nv" -# ? for NCR Tower 32, OS Release 1.xx.xx, "make tower32-1" -# ? for NCR Tower 32, OS Release 2.xx.xx, "make tower32-2" -# ? for NCR Tower 32, OS Releases based on Sys V R3, "make tower32" -# ? for NCR Tower 32, OS Releases based on Sys V R3 with gcc "make tower32g" -# ? for NCR System 3000, AT&T UNIX System V R4 2.0, "make sys5r4sxna" -# ? for NCR System 3000, AT&T UNIX System V R4 2.0 with Wollongong TCP/IP, -# "make sys5r4net2" or "make sys5r4net2c". -# Some header files might be misplaced; try this: -# ln /usr/include/netinet/in.h /usr/include/sys/in.h -# ln /usr/include/arpa/inet.h /usr/include/sys/inet.h -# ln /usr/include/sys/termiox.h /usr/include/termiox.h -# ? for NCR System 3000, NCR UNIX 02.02.01, same as above. -# + for NCR MP-RAS System V R4 V2.03 or 3.02, "make mpras" or "make mprastcpc" -# + for NetBSD through 1.4.x on any architecture, "make netbsd" -# + for NetBSD 1.5.0 and later, "make netbsd15" -# + for NeXT with NeXTSTEP 1.0 through 3.2, "make next" (on a NeXT) -# + for NeXT with NeXTSTEP 3.3, "make next33" -# ? for NeXT with OPENSTEP/Mach 4.1, "make nextquadfat". -# + for NeXT with OPENSTEP/Mach 4.2, "make openstep42". -# ? for NeXTSTEP/486, "make next" (on a PC) -# ? for NeXTSTEP portable binary (runs on Intel or Motorola), "make nextfat" -# ? for NeXTSTEP portable binary (Intel, Motorola, HP PA-RISC, or SPARC), -# "make nextquadfat" -# ? for Nixdorf Targon/31, "make t31tos40x" -# ? for Norsk Data Uniline 88/17 with SV/88 R3.2, "make sv88r32" -# for Novell UnixWare - see UnixWare -# ? for OSF/1 (vanilla, from OS/F), "make posix" -# ? for OkiStation 7300 Series, "make sys5r4sxtcp" -# ? for Olivetti LSX-3020 with X/OS R.2.3, "make xos23" or "make xos23c" -# + for OpenBSD, "make openbsd" (also see secure targets listed below). -# ? for OPENSTEP/Mach 4.1, "make nextquadfat" (NeXT, Intel, PA-RISC, SPARC) -# + for OPENSTEP/Mach 4.2, "make openstep42" (tested on NeXT) -# ? for Perkin-Elmer (Concurrent) 3200 series, "make sys5". -# ? for Perkin-Elmer (Concurrent) 3200 series with , "make ccop1" -# ? for Perkin-Elmer/Concurrent 3200 with Xelos R02, "make ccop1" -# ? for PFU Compact A Series SX/A TISP V10/E50 (Japan), "make sxae50" -# ? for Plexus, "make sys3" -# + for Pyramid 9XXX (e.g. 9845) or MIServer T series, OSx 4.4b thru 5.1, -# "ucb make pyramid" or for HDB UUCP, "ucb make pyramid-hdb" or: -# + for Pyramid MIServer S or ES Series, DataCenter/OSx, "make pyrdcosx" -# + for Pyramid MIS-S MIPS R3000, DataCenter OSx System V R4, "make pyrdcosx" -# + for POSIX on anything, "make posix" (but adjustments might be necessary). -# ? for Prime 8000 MIPS, SVR3, "make mips" or "make mipstcpc" -# - for QNX 2.x (sorry we don't have a version of C-Kermit for QNX 2.x) -# ? for QNX 4.0 or 4.1, 16-bit, on 286 PC, Watcom C 8.5, "make qnx16_41" -# + for QNX 4.21 - 4.22A (286+), and 4.23 (386+), or higher, 16-bit, -# Watcom C 9.5x or higher, "make qnx16" -# + for QNX 4.21-4.25, 32-bit, 386 or above, Watcom C 10.6, "make qnx32" -# NOTE: ("make qnx" == "make qnx32") -# ? for QNX Neutrino 2+, "make qnx_nto2+" (crosscompiled on QNX4 with Watcom C) -# + for QNX 6 = Neutrino 2.xx, "make qnx6" -# ? for Ridge 32 (ROS3.2), "make ridge32" -# ? for Samsung MagicStation, "make sys5r4" -# ? for SCO Xenix 2.2.1 with development system 2.2 on 8086/8 "make sco86" -# ? for SCO Xenix/286 2.2.1 with development system 2.2 on 80286, "make sco286" -# NOTE: reportedly this makefile is too long for SCO Xenix/286 make, but it -# works with "makeL", or if some of the other make entries are edited out. -# ? for SCO Xenix/386 2.2.2, "make sco386" -# ? for SCO Xenix/386 2.3.x, "make sco3r2" -# ? for SCO Xenix/386 SCO 2.3.3 or 2.3.4 with gcc 1.37 or later, -# "make sco386gcc" or (to add curses) "make sco386gccc". -# ? for SCO Xenix/386 or UNIX/386 with Excelan TCP/IP, "make sco3r2net" -# or (to add curses support) "make sco3r2netc" or "sco386netc" -# + for SCO XENIX 2.3.4, "make sco234" or "make sco234c" to add curses. -# + for SCO XENIX 2.3.4 with SCO TCP/IP & curses, "make sco234netc". -# ? for SCO Xenix 2.3.x with Racal-InterLan TCP/IP, "make sco3r2netri" -# for other UNIX varieties with Racal Interlan TCP/IP, read sco3r2netri entry -# ? for SCO Xenix 2.3.x with SCO (Lachman) TCP/IP, "make sco3r2lai" -# or (to add curses) "make sco3r2laic" -# for SCO UNIX... ALSO READ COMMENTS in the SCO UNIX entries for more info! -# ? for SCO UNIX/386 3.2.0 or 3.2.1, "make sco3r2" or "make sco3r2x" -# ? for SCO UNIX/386 3.2.2, "make sco3r22" or "make sco3r22gcc" -# or "make sco3r22c" -# ? for SCO UNIX/386 3.2.2 with SCO TCP/IP, "make sco3r22net" -# or "make sco3r22netc" (curses) -# ? for SCO ODT 1.1, "make sco3r22net" or "make sco3r22netc" (curses) -# + for SCO UNIX/386 3.2 V4.x, no network support, "make sco32v4" -# + or "make sco32v4ns" (this one uses no select() or sockets library) -# + for SCO UNIX/386 3.2 V4.x with TCP/IP, "make sco32v4net" -# (also sco32v4gcc, sco32v4netgcc) -# + for SCO UNIX/386 3.2 V5.0 - see SCO OpenServer. -# + for SCO UNIX 3.2v4.x with TCP/IP, for Extended Acer File -# System (EAFS), curses, ANSI C compilation, "make sco32v4net" -# + or (to use select()-based CONNECT module) "make sco32v4netx". -# + for SCO UNIX 3.2v4.2, "make sco-odt30" (includes TCP/IP). -# + for SCO MPX 3.0 - The SCO UNIX binary runs on the corresponding MPX system. -# -# NOTE: Also see below for other entries that are variations on these. -# Also be sure to read the comments accompanying each SCO entry. -# Also see Unixware section. -# -# + for SCO ODT 2.0, "make sco32v4net" -# + for SCO ODT 3.0, "make sco-odt30" -# + for SCO OpenServer 5.0 (OSR5), "make sco32v500" -# + for SCO OpenServer 5.0 (OSR5) with networking, "make sco32v500net" -# + for SCO OpenServer 5.0 (OSR5), gcc, "make sco32v500gcc" -# + for SCO OpenServer 5.0 (OSR5), gcc, with networking, "make sco32v500netgcc" -# + for SCO OpenServer 5.0 (OSR5), as above, ELF, "make sco32v500netgccelf" -# + for SCO OpenServer 5.0.2, use "make sco32v502xxx" entries as above. -# + for SCO OpenServer 5.0.4, use "make sco32v504xxx" entries as above. -# + for SCO OpenServer 5.0.5, use "make sco32v505xxx" entries as above. -# Use the sco32v505udkxxx entries if you have the UDK rather than /bin/cc. -# + for SCO OpenServer 5.0.6, use "make sco32v506xxx" entries as above. -# + for SCO OpenServer 5.0.6a,use "make sco32v506axxx" entries as above. -# + for SCO OpenServer 5.0.7, use "make sco32v507", "make sco32v507net" -# ? for SCO (Univel) UnixWare 1.x, "make unixware" or "make unixwarenetc". -# If there are problems with this in C-K 7+ see notes at unixware entry. -# + for SCO UnixWare 2.0.x, "make uw20" -# + for SCO UnixWare 2.1.0, "make uw21" -# + for SCO UnixWare 2.1.3, "make uw213" -# + for SCO UnixWare 7, "make uw7" -# + for SCO UnixWare 7 with IKSD support, "make uw7iksd" or "make uw7iksdudk" -# + for SCO UnixWare 7 with OpenSSL, "make uw7ssl" -# + for SCO (Caldera) Open UNIX 8, "make ou8" -# + for Sharp Zaurus SL5500 PDA, "make zsl5500". -# ? for Sequent with DYNIX/ptx 1.2.1, "make dynixptx12" -# ? for Sequent with DYNIX/ptx 1.3 or 1.4 with TCP/IP, "make dynixptx13" -# ? for Sequent with DYNIX/ptx 2.0 or 2.1 with TCP/IP, "make dynixptx20" -# or "dynixptx20c" -# + for Sequent with DYNIX/ptx 2.1.6 on i486, "dynixptx216c" -# ? for Sequent with DYNIX/ptx V4.1.3 with TCP/IP, "make dynixptx41c" -# + for Sequent with DYNIX/ptx V4.4.2 with TCP/IP, "make dynixptx44" -# ? for Sequent Balance 8000 or B8 with DYNIX 3.0.xx, "make dynix3" -# or "make dynix3noacu" -# ? for Sequent Symmetry S81 with DYNIX 3.0.xx, "make dynix3" -# ? for Sequent DYNIX 3.1.xx, "make dynix31" or "make dynix31c" -# + for Siemens/Nixdorf SINIX-L Intel V5.41, "make sinix541i" -# + for Siemens/Nixdorf SINIX-N MIPS V5.42, "make sinix542" -# + for Siemens/Nixdorf SINIX-P MIPS V5.42 with gcc, "make sinix542g" -# + for Siemens/Nixdorf SINIX-Z Intel V5.42, "make sinix542i" -# + for Siemens/Nixdorf Reliant UNIX V5.43, "make sni543" -# + for Siemens/Nixdorf Reliant UNIX V5.44, "make sni544" -# ? for Silicon Graphics Iris System V IRIX 3.2 or earlier, "make iris" -# ? for Silicon Graphics Sys V R3 with IRIX 3.3 or later, "make sys5r3" -# ? for Silicon Graphics Iris Indigo with IRIX 4.0 or 5.0, "make irix40" or -# (to include Yellow Pages and Curses) "make irix40ypc" -# ? for Silicon Graphics Iris Indigo or Elan with IRIX 4.0.x with microcode -# optimization and -O4, "make irix40u" or "irix40uc" (and read notes -# accompanying these entries). -# + for Silicon Graphics IRIX 5.1, "make irix51" or "irix51x" (no optimize) -# + for Silicon Graphics IRIX 5.2, "make irix52" -# + for Silicon Graphics IRIX 5.3, "make irix53" or "irix53x" (no optimize) -# + for Silicon Graphics IRIX 6.0, "make irix60". -# + for Silicon Graphics IRIX 6.2, "make irix62". -# + for Silicon Graphics IRIX 6.3, "make irix63". -# + for Silicon Graphics IRIX 6.4, "make irix64" or "make irix64gcc". -# + for Silicon Graphics (SGI) IRIX 6.5, "make irix65" or "make irix65mips2" -# ? for Solaris 2.0-2.3 on SPARC or Intel, SunPro CC, "make solaris2x", -# ? or to add SunLink X.25 8.0x support, "make solaris2x25". -# + for Solaris 2.4 built with gcc, "make solaris24g". -# + for Solaris 2.0-2.3 on SPARC or Intel, GNU CC, "make solaris2xg". -# + for Solaris 2.4 with X.25, "make solaris24x25". -# + for Solaris 2.5 on SPARC or Intel, SunPro CC, "make solaris25". -# + or to add SunLink X.25 8.0x support, "make solaris25x25". -# + for Solaris 2.5 on SPARC or Intel, GNU CC, "make solaris25g". -# + for Solaris 2.6 on SPARC or Intel, "make solaris26". -# + for Solaris 7 on SPARC or Intel, SunPro CC, "make solaris7". -# + for Solaris 7 on SPARC or Intel, GNU CC, "make solaris7g". -# + for Solaris 8 on SPARC or Intel, SunPro CC, "make solaris8". -# + for Solaris 8 on SPARC or Intel, GNU CC, "make solaris8g". -# + for Solaris 9 on SPARC (or Intel?), 32-bit, SunPro CC, "make solaris9". -# + for Solaris 9 on SPARC (or Intel?), 32-bit, GNU CC, "make solaris9g". -# + for Solaris 9 on SPARC (or Intel?), 64-bit, GNU CC, "make solaris9g64". -# + for Solbourne 4/500 with OS/MP 4 "make sunos4" -# + for Solbourne 4/500 with OS/MP 4.1 "make sunos41" or "make sunos41c" -# ? for SONY NEWS with NEWS-OS 4.0.1C, "make sonynews" -# ? for SONY NEWS with NEWS-OS 4.1.2C, "make sonynews" -# ? for Sperry/UNISYS 5000/20, UTS V 5.2 3R1, "make sys5" -# ? for Sperry/UNISYS 5000/30/35/50/55, UTS V 5.2 2.01, "make unisys5r2" -# ? for Sperry/UNISYS 5000/80 with System V R3, "make sys5r3" -# ? for Sperry/UNISYS 5000/95 with System V R3, "make sys5r3" -# For UNISYS SVR3 it might be necessary to "make sys5r3 KFLAGS=-UDYNAMIC" -# ? for Stardent 1520, "make sys5r3" -# ? for Stratus FTX 2.x, try "make ftx" or else "make sys5r4" or "sys5r4sx" -# + for Stratus FTX 3.x, PA-RISC 1.0 or 2.0, "make ftx" or "make ftxtcp" -# ? for Sun with Sun UNIX 3.5 and gcc, "make sunos3gcc" -# ? for Sun with pre-4.0 SunOS versions, "make bsd" (or appropriate variant) -# ? for Sun with SunOS 4.0, BSD environment, "make sunos4" -# ? for Sun with SunOS 4.0, BSD, with SunLink X.25, make sunos4x25 -# + for Sun with SunOS 4.1 or 4.1.1, BSD environment, "make sunos41" -# or "make sunos41c" (curses) or "make sunos41gcc" (compile with gcc) -# + for Sun with SunOS 4.1.x, BSD, with SunLink X.25 7.00 or earlier, -# "make sunos41x25" or "make sunos41x25c" (curses) -# + for Sun with SunOS 4.1, 4.1.1, AT&T Sys V R3 environment, "make sunos41s5" -# + for Sun with SunOS 4.1.2, "make sunos41" or any of its variations. -# NOTE: All SunOS 4.x systems -- Shared libraries are used by default. -# If this causes problems, add -Bstatic to CFLAGS. -# NOTE2: When building C-Kermit under SunOS for the BSD universe, -# but /usr/5bin/cc is ahead of /usr/ucb/cc in your PATH, add -# "CC=/usr/ucb/cc CC2=/usr/ucb/cc" to the make entry. -# NOTE3: If an executable built on one type of Sun hardware does not work -# on another type, rebuild the program from source on the target machine. -# for Sun with Solaris 1.x use SunOS 4.1 entries. -# for Sun with Solaris 2.0 and higher use Solaris entries. -# + for Sun SPARC with Linux, "make linux" -# ? for Sun SPARC with OPENSTEP/Mach 4.1, "make nextquadfat" -# ? for Sun SPARC with OPENSTEP/Mach 4.2, "make openstep42" -# - for Tandy 16/6000 with Xenix 3.0, "make trs16" (C-Kermit 7.0 is too big) -# ? for Tektronix 6130/4132/43xx (e.g.4301) with UTek OS, "make utek" -# or (for models without hardware flow control), "make uteknohwfc" -# ? for Tektronix XD88 series with UTekV OS, "make utekvr3" -# ? for Tri Star Flash Cache with Esix SVR3.2, "make sys5r3" -# + for Tru-64 UNIX 4.0E, "make tru64-40e" -# + for Tru-64 UNIX 4.0F, "make tru64-40f" -# + for Tru-64 UNIX 4.0G, "make tru64-40g" -# + for Tru-64 UNIX 5.0A, "make tru64-50a" -# + for Tru-64 UNIX 5.1A, "make tru64-51a" -# ? for Unistar, "make sys5" -# ? for Unisys S/4040 68040 CTIX SVR3.2 6.4.1, "make ctix" or "make sys5r3" -# ? for Unisys U5000 UNIX SVR3 6.x, "make sys5r3" or "make sys5r3c" -# ? for Unisys U6000 UNIX SVR4 1.x, "make sys5r4nx" or "make sys5r4nxnetc" -# for Unisys ... (also see Sperry) -# for Univel - see UnixWare -# for Unixware - see SCO -# ? for Valid Scaldstar, "make valid" -# ? for Whitechapel MG01 Genix 1.3, "make white" -# ? for Zilog ZEUS 3.21, "make zilog" -# -# The result should be a runnable program called "wermit" in the current -# directory. After satisfactory testing, you can rename wermit to "kermit" -# and put it where users can find it. -# -# To remove intermediate and object files, "make clean". -# If your C compiler produces files with an extension other than "o", -# then "make clean EXT=u", "make clean EXT=s", or whatever. -# -# To run lint on the source files, "make lintsun", "make lintbsd", -# "make lints5", as appropriate. -# -# ****************************** -# SECURE TARGETS -# -# Beginning with C-Kermit 7.0, secure targets are included, as are the -# source modules (ckuat*.[ch], ck_*.[ch]) needed to build them. Secure -# target names are like the regular names, but with security features -# indicated by plus (+) signs. The features are: -# -# krb4 MIT Kerberos IV -# krb5 MIT Kerberos V -# openssl OpenSSL (SSL/TLS) -# zlib ZLIB compression for SSL/TLS -# srp Stanford Secure Remote Password -# pam PAM (pluggable authentication module) -# shadow Shadow Password File -# -# You can build these targets if you have the Kermit source files and the -# required libraries (Kerberos, OpenSSL, SRP, etc) and header files. See: -# http://www.columbia.edu/kermit/security.html -# for specific details regarding supported versions. -# -# NOTE: OpenSSL 0.9.6 and earlier are not compatible with 0.9.7 and later. -# C-Kermit code is designed for 0.9.6. To build with 0.9.7 you must add -# -DOPENSSL_097 to avoid missing symbols in the DES library and to use the -# entry points that were renamed to avoid conflict with Kerberos 4. -# -# In OpenSSL builds add -ldl if you get unresolved references for -# dlopen, dlclose, dlsym, and/or dlerror. -# -# The following symbols are used to specify library and header file locations -# Redefine them to the values used on your system by: -# . editing this file -# . defining the values on the command line -# . defining the values in the environment and use the -e option -# -prefix = /usr/local -srproot = $(prefix) -sslroot = $(prefix) -manroot = $(prefix) - -K4LIB=-L/usr/kerberos/lib -K4INC=-I/usr/kerberos/include -K5LIB=-L/usr/kerberos/lib -K5INC=-I/usr/kerberos/include -SRPLIB=-L$(srproot)/lib -SRPINC=-I$(srproot)/include -SSLLIB=-L$(sslroot)/ssl/lib -SSLINC=-I$(sslroot)/ssl/include -# -# aix41+krb5+krb4: IBM AIX 4.1 with Kerberos IV and V -# aix43gcc+krb5+krb4: IBM AIX 4.3 built with gcc, ditto -# aix43gcc+krb5+krb4+openssl: Ditto, plus OpenSSL (SSL/TLS) -# aix43gcc+openssl: IBM AIX 4.3 with OpenSSL -# freebsd44+srp+openssl FreeBSD 4.4 with SRP and OpenSSL -# freebsd50+openssl FreeBSD 5.0 with OpenSSL -# hpux1100o+openssl: HP-UX 11.xx with OpenSSL -# hpux1000gcc+openssl: HP-UX 10.xx with OpenSSL (build with gcc) -# hpux1100gcc+openssl: HP-UX 11.xx with OpenSSL (build with gcc) -# irix6x+krb5: IRIX 6.x with Kerberos V -# irix65+krb5: etc etc... -# linux+krb5: -# linux+krb5+krb4: -# linux+srp: -# linux+srp+pam: -# linux+srp+gmp: -# linux+srp+gmp+no-des: -# linux+srp+gmp-export: -# linux+srp+gmp+pam: -# linux+shadow+pam: -# linux+openssl: -# linux+openssl+shadow: -# linux+openssl+zlib+shadow+pam: -# linux+srp+openssl: -# linux+krb5+krb4+srp: -# linux+krb5+krb4+srp+openssl: -# linux+krb5+krb4+openssl: -# linux+krb5+krb4+openssl+shadow: -# linux+krb5+krb4+openssl+zlib+shadow: -# linux+krb5+krb4+srp-export: -# linux+krb5+krb4+srp+pam: -# linux+krb5+krb4+srp+openssl+pam-debug: -# linux+krb5+krb4+srp+openssl+pam: -# linux+krb5+krb4+srp+openssl+zlib+pam: -# linux+krb5+krb4+openssl+shadow+pam: -# linux+krb5+openssl+zlib+shadow+pam: -# openbsd30+ssl (includes OpenSSL): -# redhat71, redhat72, redhat73, redhat80, redhat9 -# (Krb5, OpenSSL, Showdow, PAM, Zlib) -# sco32v500net+ssl: -# sco32v505net+ssl: -# solaris2x+krb4: -# solaris2xg+krb4: -# solaris2xg+openssl+pam+shadow: -# solaris2xg+openssl+zlib+pam+shadow: -# solaris2xg+krb5+krb4+openssl+shadow: -# solaris25+krb4: -# solaris25g+krb4: -# solaris26g+openssl: -# solaris8g+openssl+zlib+pam+shadow: -# solaris8g+krb4: -# solaris9g+openssl+zlib+pam+shadow: -# solaris9g+openssl+shadow+pam+zlib -# sunos41gcc+krb4: SunOS 4.1 built with gcc with Kerberos IV -# sunos41gcc+openssl: SunOS 4.1 built with gcc with OpenSSL -# sunos41gcc+krb4+openssl: ...with Kerberos IV and OpenSSL -# sunos41gcc+krb4+openssl+zlib: ditto, plus ZLIB compression -# sunos41gcc+krb4+srp+openssl+zlib: ditto, plus SRP -# sunos41gcc+srp+openssl+zlib: -# uw7ssl -# -############################################################################## -# -# NOTES FOR V7 AND 2.X BSD (BASED ON VERSION 4E OF C-KERMIT, 1987): -# -# For Unix Version 7, several variables must be defined to the values -# associated with your system. BOOTNAME=/edition7 is the kernel image on -# okstate's Perkin-Elmer 3230. Others will probably be /unix. PROCNAME=proc -# is the name of the structure assigned to each process on okstate's system. -# This may be "_proc" or some other variation. See for more -# info on your systems name conventions. NPROCNAME=nproc is the name of a -# kernel variable that tells how many "proc" structures there are. Again -# this may be different on your system, but nproc will probably be somewhere. -# The variable NPTYPE is the type of the nproc variable -- int, short, etc. -# which can probably be gleaned from . The definition of DIRECT -# is a little more complicated. If nlist() returns, for "proc" only, the -# address of the array, then you should define DIRECT as it is below. If -# however, nlist() returns the address of a pointer to the array, then you -# should give DIRECT a null definition (DIRECT= ). The extern declaration in -# should clarify this for you. If it is "extern struct proc -# *proc", then you should NOT define DIRECT. If it is "extern struct proc -# proc[]", then you should probably define DIRECT as it is below. See -# ckuv7.hlp for further information. -# -# For 2.9 BSD, the makefile may use pcc rather than cc for compiles; that's -# what the CC and CC2 definitions are for (the current version of the -# makefile uses cc for both; this was tested in version 4E of C-Kermit and -# worked OK on the DEC Pro 380, but all bets are off for version 5A). 2.9 -# support basically follows the 4.1 path. Some 2.9 systems use "dir.h" for -# the directory header file, others will need to change this to "ndir.h". -# -# The v7 and 2.9bsd versions assume I&D space on a PDP-11. When building -# C-Kermit for v7 on a PDP-11, you should probably add the -i option to the -# link flags. Without I&D space, overlays will be necessary (if available), -# or code segment mapping (a`la Pro/Venix) if that's available. -# -# C-Kermit 5A (and 6.0?) can be built for 2.10 and 2.11BSD, using overlays, -# but a separate makefile is used because this one is too big. -# -############################################################################## -# -# V7-specific variables. -# These are set up for Perkin-Elmer 3230 V7 Unix: -# -PROC=proc -DIRECT= -NPROC=nproc -NPTYPE=int -BOOTFILE=/edition7 -# -# ( For old Tandy TRS-80 Model 16A or 6000 V7-based Xenix, use PROC=_proc, -# DIRECT=-DDIRECT, NPROC=_Nproc, NPTYPE=short, BOOTFILE=/xenix ) -# -########################################################################### -# -# Compile and Link variables: -# -# EXT is the extension (file type) for object files, normally o. -# See MINIX entry for what to do if another filetype must be used. -# -EXT=o -#LNKFLAGS= -SHAREDLIB= -CC= cc -CC2= cc -MAKE= make -SHELL=/bin/sh - -########################################################################### -# SAMPLE INSTALLATION SCRIPT -# -# Modify to suit your own computer's file organization and permissions. If -# you don't have write access to the destination directories, "make install" -# fails. In most cases, a real installation also requires you to chown / -# chgrp the Kermit binary for the UUCP lockfile and/or tty devices, and -# perhaps also to chmod +s the corresponding permission fields. -# -# Default binary, man, and doc directories are supplied below. You can -# override them in your 'make' command. Examples: -# -# make install # Accept defaults. -# make "INFODIR=/usr/share/lib/kermit" install # Override INFODIR default. -# -# You can also build and install in one step, e.g.: -# -# make solaris8 install -# -# If you use the 'install' target to install C-Kermit, it creates an -# UNINSTALL script that can be used to uninstall it. -# -WERMIT = makewhat -BINARY = wermit -DESTDIR = -BINDIR = $(prefix)/bin -MANDIR = $(manroot)/man/man1 -MANEXT = 1 -SRCDIR = -INFODIR = -CERTDIR = - -TEXTFILES = COPYING.TXT ckcbwr.txt ckubwr.txt ckuins.txt ckccfg.txt \ - ckcplm.txt ckermit.ini ckermod.ini ckermit70.txt ckermit80.txt - -ALL = $(WERMIT) - -all: $(ALL) - -.c.o: - $(CC) $(CFLAGS) -DKTARGET=\"$(KTARGET)\" -c $< - -#Clean up intermediate and object files -clean: - @echo 'Removing object files...' - -rm -f ckcmai.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \ -ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckcpro.$(EXT) ckcfns.$(EXT) \ -ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) ckucon.$(EXT) ckutio.$(EXT) \ -ckufio.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) ckwart.$(EXT) ckuusx.$(EXT) \ -ckuusy.$(EXT) ckcnet.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) ckusig.$(EXT) \ -ckucns.$(EXT) ckcmdb.$(EXT) ckuath.$(EXT) ckctel.$(EXT) ckclib.$(EXT) \ -ckcuni.$(EXT) ck_crp.$(EXT) ck_ssl.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \ -ckcpro.c wart - -# Install C-Kermit after building -- IMPORTANT: Read the instructions above -# (SAMPLE INSTALLATION SCRIPT). For SSL/TLS versions, ca_certs.pem file -# should be installed in the appropriate place for your OpenSSL library, e.g.: -# -# cp ca_certs.pem /usr/local/ssl/ -# cp ca_certs.pem /usr/share/ssl/ -# -# To make sure 'man' notices the new source file and doesn't keep -# showing the old formatted version, remove the old formatted version, -# something like this: -# rm -f $(MANDIR)/../cat$(MANEXT)/kermit.$(MANEXT) -# or this (which requires CATDIR to be defined): -# rm -f $(CATDIR)/kermit.$(MANEXT) -# -# As of C-Kermit 8.0.205 this target also builds an UNINSTALL script, and -# so it might be too long for some old Bourne shells, in which case you can -# use a different shell: -# -# make SHELL=ksh install -# make SHELL=/bin/posix/sh install -# -install: - @echo Installing C-Kermit version $(CKVER)...;\ - rm -f UNINSTALL;\ - exec 3>./UNINSTALL;\ - echo "# C-Kermit UNINSTALL script" >&3;\ - echo "# `date`\n" >&3;\ - echo "CKVER=$(CKVER)" >&3;\ - echo "PrN Uninstalling C-Kermit version $(CKVER)..." >&3;\ - echo DESTDIR=$(DESTDIR);\ - if test -n "$(DESTDIR)"; then\ - if test -d $(DESTDIR); then\ - echo "$(DESTDIR) exists...\n";\ - else\ - echo "Creating $(DESTDIR)...";\ - DESTDIR=`echo $(DESTDIR) | sed 's!/*$$!!'`;\ - mkdir $$DESTDIR || exit 1;\ - fi;\ - chmod 755 $(DESTDIR) || exit 1;\ - fi;\ - echo BINARY=$(BINARY);\ - if test -f $(BINARY); then\ - ls -l $(BINARY);\ - else\ - echo "?$(BINARY) not found";\ - exit 1;\ - fi;\ - if test -z "$(DESTDIR)$(BINDIR)"; then\ - echo "Binary directory not specified";\ - exit 1;\ - fi;\ - if test -d $(DESTDIR)$(BINDIR); then\ - echo "$(DESTDIR)$(BINDIR) exists...";\ - else\ - echo "Creating $(DESTDIR)$(BINDIR)/...";\ - mkdir $(DESTDIR)$(BINDIR) || exit 1;\ - chmod 755 $(DESTDIR)$(BINDIR);\ - fi;\ - rm -f $(DESTDIR)$(BINDIR)/kermit;\ - cp $(BINARY) $(DESTDIR)$(BINDIR)/kermit || exit 1;\ - chmod 755 $(DESTDIR)$(BINDIR)/kermit || exit 1;\ - rm -f $(DESTDIR)$(BINDIR)/kermit-sshsub;\ - ln -s $(DESTDIR)$(BINDIR)/kermit\ - $(DESTDIR)$(BINDIR)/kermit-sshsub || exit 1;\ - echo 'set flag=f\nPrC Removing binaries' >&3;\ - echo "RmF $(DESTDIR)$(BINDIR)/kermit-sshsub" >&3;\ - echo "RmF $(DESTDIR)$(BINDIR)/kermit" >&3;\ - if test -f ckermit.ini; then\ - echo "#!$(DESTDIR)$(BINDIR)/kermit" >\ - $(DESTDIR)$(BINDIR)/_tmp.ini;\ - cat ckermit.ini >> $(DESTDIR)$(BINDIR)/_tmp.ini;\ - mv $(DESTDIR)$(BINDIR)/_tmp.ini\ - $(DESTDIR)$(BINDIR)/ckermit.ini;\ - chmod 755 $(DESTDIR)$(BINDIR)/ckermit.ini;\ - echo "RmF $(DESTDIR)$(BINDIR)/ckermit.ini" >&3;\ - fi;\ - echo;\ - echo 'EfM' >&3;\ - echo "Kermit binary installed:";\ - ls -l $(DESTDIR)$(BINDIR)/kermit\ - $(DESTDIR)$(BINDIR)/kermit-sshsub\ - $(DESTDIR)$(BINDIR)/ckermit.ini;\ - echo;\ - echo " WARNING: If C-Kermit is to be used for dialing out,";\ - echo " you must change its owner and group and permissions";\ - echo " to match the 'cu' program. See the ckuins.txt file";\ - echo " for details.";\ - echo;\ - echo MANDIR=$(MANDIR);\ - if test -n "$(MANDIR)"; then\ - if test -d $(MANDIR); then\ - echo "$(MANDIR) exists...";\ - else\ - echo "Creating $(MANDIR)...";\ - mkdir $(MANDIR) || exit 1;\ - chmod 755 $(MANDIR) || exit 1;\ - fi;\ - echo "Installing man page...";\ - rm -f $(MANDIR)/kermit.$(MANEXT);\ - cp ckuker.nr $(MANDIR)/kermit.$(MANEXT) || exit 1;\ - chmod 644 $(MANDIR)/kermit.$(MANEXT) || exit 1;\ - echo 'set flag=f\nPrC Removing man pages' >&3;\ - echo "RmF $(MANDIR)/kermit.$(MANEXT)" >&3;\ - echo 'EfM' >&3;\ - echo;\ - else\ - echo "Not installing man page!\n";\ - fi;\ - echo CERTDIR=$(CERTDIR);\ - if test -n "$(CERTDIR)"; then\ - if test -f ca_certs.pem; then\ - if test -d $(CERTDIR); then\ - echo "$(CERTDIR) exists...";\ - else\ - echo "Creating $(CERTDIR)...";\ - mkdir $(CERTDIR) || exit 1;\ - chmod 755 $(CERTDIR) || exit 1;\ - fi;\ - echo "Installing certificates file...";\ - cp ca_certs.pem $(CERTDIR) || exit 1;\ - echo 'set flag=f' >&3;\ - echo 'PrC Removing certificates file' >&3;\ - echo "RmF $(CERTDIR)/ca_certs.pem" >&3;\ - echo 'EfM' >&3;\ - echo;\ - fi;\ - else\ - echo "Not installing certificates file!\n";\ - fi;\ - echo SRCDIR=$(DESTDIR)$(SRCDIR);\ - if test -n "$(SRCDIR)"; then\ - echo "Installing source files...";\ - if test -d $(DESTDIR)$(SRCDIR); then\ - echo "$(DESTDIR)$(SRCDIR) exists...";\ - else\ - echo "Creating $(DESTDIR)$(SRCDIR)/...";\ - mkdir $(DESTDIR)$(SRCDIR) || exit 1;\ - chmod 755 $(DESTDIR)$(SRCDIR);\ - fi;\ - echo "Copying source files to $(DESTDIR)$(SRCDIR)...";\ - echo 'set flag=f\nPrC Removing source files' >&3;\ - for TextFile in COPYING.TXT ck[cuw_]*.[cwh] makefile; do\ - cp $$TextFile $(DESTDIR)$(SRCDIR)/ && echo ".\c";\ - echo "RmF $(DESTDIR)$(SRCDIR)/$$TextFile" >&3;\ - done; echo;\ - echo 'EfM' >&3;\ - ( cd $(DESTDIR)$(SRCDIR)/ &&\ - ls -l COPYING.TXT ck[cuw_]*.[cwh] makefile );echo;\ - else\ - echo "Not installing source code!\n";\ - fi;\ - echo INFODIR=$(DESTDIR)$(INFODIR);\ - if test -n "$(INFODIR)"; then\ - echo "Installing info files...";\ - if test -d $(DESTDIR)$(INFODIR); then\ - echo "$(DESTDIR)$(INFODIR) exists...";\ - else\ - echo "Creating $(DESTDIR)$(INFODIR)/...";\ - mkdir $(DESTDIR)$(INFODIR) || exit 1;\ - chmod 755 $(DESTDIR)$(INFODIR);\ - fi;\ - echo "Copying text files to $(DESTDIR)$(INFODIR)...";\ - echo 'set flag=f\nPrC Removing text files' >&3;\ - FileCopyList='';\ - for TextFile in $(TEXTFILES); do\ - test -f $$TextFile || continue;\ - cp $$TextFile $(DESTDIR)$(INFODIR) && echo ".\c" &&\ - FileCopyList="$$FileCopyList $$TextFile";\ - echo "RmF $(DESTDIR)$(INFODIR)/$$TextFile" >&3;\ - done; echo;\ - echo 'EfM' >&3;\ - ( cd $(DESTDIR)$(INFODIR)/ && chmod 644 $$FileCopyList );\ - ( cd $(DESTDIR)$(INFODIR)/ && pwd && ls -l $$FileCopyList );\ - else\ - echo "Not installing text files!\n";\ - fi;\ - echo "set flag=d\nPrN Removing empty dirs..." >&3;\ - echo "RmD $(DESTDIR)$(BINDIR)" >&3;\ - echo "RmD $(DESTDIR)$(SRCDIR)" >&3;\ - echo "RmD $(DESTDIR)$(INFODIR)" >&3;\ - echo "RmD $(CERTDIR)" >&3;\ - echo "RmD $(MANDIR)" >&3;\ - echo "RmD $(DESTDIR)" >&3;\ - echo "EfM" >&3;\ - echo "PrN C-Kermit version $(CKVER) is uninstalled!" >&3;\ - echo C-Kermit version $(CKVER) installed! - -# UN-Install C-Kermit after building -# Please to not remove the extra blanks before and after '{}' within the -# functions. You would get syntax errors for some older Bourne shells! Best is -# you don't change or remove anything. -# -uninstall: - @if test ! -f UNINSTALL; then\ - echo "?C-Kermit UNINSTALL data file not found!";\ - exit 1;\ - fi; \ - X=`grep '^CKVER='$(CKVER)'$$' ./UNINSTALL || :`;\ - if test -z "$$X"; then\ - echo "?UNINSTALL file is not for C-Kermit version $(CKVER)";\ - exit 2;\ - fi;\ - PrN () { echo "$$*"; };\ - PrC () { echo "$$* \c"; };\ - RmF () { test -f "$$1" && rm -f "$$1" && echo ".\c" && flag=F ; };\ - RmD () { \ - dir=$$1;\ - while test -d "$$dir"; do\ - rmdir "$$dir" 2>&- || return && echo "$$dir" && flag=D;\ - dir=`echo "$$dir" | sed 's!/[^/]*/*$$!!'`;\ - done; \ - };\ - EfM () { \ - case "$$flag" in\ - f) echo "- Nothing to remove!";;\ - d) echo "Nothing to remove!";;\ - F) echo " done";;\ - D) echo "done";;\ - esac; \ - };\ - while read Act Args; do\ - case $$Act in\ - EfM) EfM;;\ - RmD) RmD $$Args;;\ - RmF) RmF $$Args;;\ - PrN) PrN $$Args;;\ - PrC) PrC $$Args;;\ - set) eval $$Args;;\ - esac;\ - done < ./UNINSTALL - -makewhat: - @echo 'make what? You must tell which platform to make C-Kermit for.' - @echo Examples: make linux, make hpux1100, make aix43, make solaris8. - @echo Please read the comments at the beginning of the makefile. - -########################################################################### -# -# Dependencies Section: - -# Normal version - -wermit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \ - ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \ - ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckucon.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \ - ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \ - ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) - $(CC2) $(LNKFLAGS) -o wermit \ - ckcmai.$(EXT) ckclib.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckcpro.$(EXT) ckucmd.$(EXT) ckuus2.$(EXT) ckuus3.$(EXT) \ - ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) \ - ckuusx.$(EXT) ckuusy.$(EXT) ckuusr.$(EXT) ckucon.$(EXT) \ - ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) \ - ckusig.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \ - $(LIBS) - -# Version with CONNECT module that uses select() instead of fork() - -xermit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \ - ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \ - ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \ - ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \ - ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) ckuath.$(EXT) \ - ck_crp.$(EXT) ck_ssl.$(EXT) - $(CC2) $(LNKFLAGS) -o wermit \ - ckcmai.$(EXT) ckclib.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckcpro.$(EXT) ckucmd.$(EXT) ckuus2.$(EXT) ckuus3.$(EXT) \ - ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) \ - ckuusx.$(EXT) ckuusy.$(EXT) ckuusr.$(EXT) ckucns.$(EXT) \ - ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckusig.$(EXT) \ - ckctel.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \ - ckuath.$(EXT) ck_crp.$(EXT) ck_ssl.$(EXT) $(LIBS) - -# Malloc Debugging version - -mermit: ckcmdb.$(EXT) ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) \ - ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \ - ckcpro.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) \ - ckuxla.$(EXT) ckucon.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \ - ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) \ - ckusig.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) - $(CC2) $(LNKFLAGS) -o mermit ckcmdb.$(EXT) ckclib.$(EXT) ckcmai.$(EXT)\ - ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \ - ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \ - ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \ - ckuusr.$(EXT) ckucon.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \ - ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckcuni.$(EXT) \ - ckupty.$(EXT) ckcftp.$(EXT) $(LIBS) - -# Kerberized Version - Subject to USA export restrictions. - -# NOTE: We don't use this any more -- As of 15 Feb 2003, the "xermit" -# target is used for both secure and regular version. - -krbmit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \ - ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \ - ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \ - ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \ - ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) \ - ckcftp.$(EXT) ck_ssl.$(EXT) - $(CC2) $(LNKFLAGS) -o krbmit ckcmai.$(EXT) ckclib.$(EXT) \ - ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \ - ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \ - ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \ - ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \ - ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \ - ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) \ - ck_ssl.$(EXT) $(LIBS) - -krbmit-debug: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) \ - ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \ - ckcpro.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) \ - ckuxla.$(EXT) ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) \ - ckudia.$(EXT) ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) \ - ckusig.$(EXT) ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) \ - ckupty.$(EXT) ck_ssl.$(EXT) ckcmdb.$(EXT) ckcftp.$(EXT) - $(CC2) $(LNKFLAGS) -o krbmit ckcmdb.$(EXT) ckcmai.$(EXT) \ - ckclib.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) \ - ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) \ - ckucmd.$(EXT) ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) \ - ckuus5.$(EXT) ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) \ - ckuusy.$(EXT) ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) \ - ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \ - ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) \ - ckcftp.$(EXT) ck_ssl.$(EXT) $(LIBS) - -# SRP(TM) Version - Subject to USA export restrictions. - -srpmit: ckcmai.$(EXT) ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \ - ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \ - ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \ - ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \ - ckuath.$(EXT) ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) \ - ckcftp.$(EXT) ck_ssl.$(EXT) - $(CC2) $(LNKFLAGS) -o srpmit ckcmai.$(EXT) ckclib.$(EXT) \ - ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \ - ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \ - ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \ - ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \ - ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \ - ck_crp.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ck_ssl.$(EXT) \ - ckcftp.$(EXT) $(LIBS) - -# Kerberized Version - Not subject to USA export restrictions. - -krbmit-export: ckcmai.$(EXT) \ - ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \ - ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \ - ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \ - ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \ - ckuath.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) - $(CC2) $(LNKFLAGS) -o krbmit-export ckcmai.$(EXT) ckclib.$(EXT) \ - ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \ - ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \ - ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \ - ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \ - ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \ - ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) $(LIBS) - -# SRP(TM) Version - Not subject to USA export restrictions. - -srpmit-export: ckcmai.$(EXT) \ - ckclib.$(EXT) ckucmd.$(EXT) ckuusr.$(EXT) ckuus2.$(EXT) \ - ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) ckuus6.$(EXT) \ - ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) ckcpro.$(EXT) \ - ckcfns.$(EXT) ckcfn2.$(EXT) ckcfn3.$(EXT) ckuxla.$(EXT) \ - ckucns.$(EXT) ckutio.$(EXT) ckufio.$(EXT) ckudia.$(EXT) \ - ckuscr.$(EXT) ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) \ - ckuath.$(EXT) ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) - $(CC2) $(LNKFLAGS) -o srpmit-export ckcmai.$(EXT) ckclib.$(EXT) \ - ckutio.$(EXT) ckufio.$(EXT) ckcfns.$(EXT) ckcfn2.$(EXT) \ - ckcfn3.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) ckucmd.$(EXT) \ - ckuus2.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuusx.$(EXT) ckuusy.$(EXT) \ - ckuusr.$(EXT) ckucns.$(EXT) ckudia.$(EXT) ckuscr.$(EXT) \ - ckcnet.$(EXT) ckctel.$(EXT) ckusig.$(EXT) ckuath.$(EXT) \ - ckcuni.$(EXT) ckupty.$(EXT) ckcftp.$(EXT) $(LIBS) - -########################################################################### -# man page... -# -ckuker.nr: - @echo This target is obsolete. - @echo The ckuker.nr file no longer needs any preprocessing. - -########################################################################### -# Dependencies for each module... -# -ckcmai.$(EXT): ckcmai.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcnet.h ckcsig.h \ - ckuusr.h ckctel.h ckclib.h - -ckclib.$(EXT): ckclib.c ckclib.h ckcdeb.h ckcasc.h ckcsym.h - -ckcpro.$(EXT): ckcpro.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckclib.h - -ckcpro.c: ckcpro.w wart ckcdeb.h ckcsym.h ckcasc.h ckcker.h ckcnet.h ckctel.h \ - ckclib.h - ./wart ckcpro.w ckcpro.c - -ckcfns.$(EXT): ckcfns.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcxla.h ckcuni.h \ - ckuxla.h ckclib.h ckcnet.h - -ckcfn2.$(EXT): ckcfn2.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcxla.h \ - ckuxla.h ckctel.h ckclib.h ckcnet.h ckcuni.h - -ckcfn3.$(EXT): ckcfn3.c ckcker.h ckcdeb.h ckcsym.h ckcasc.h ckcxla.h \ - ckuxla.h ckclib.h ckcuni.h - -ckuxla.$(EXT): ckuxla.c ckcker.h ckcsym.h ckcdeb.h ckcxla.h ckuxla.h ckclib.h \ - ckcuni.h - -ckcuni.$(EXT): ckcuni.c ckcdeb.h ckcker.h ckucmd.h ckcuni.h ckcxla.h ckuxla.h - -ckuusr.$(EXT): ckuusr.c ckucmd.h ckcker.h ckuusr.h ckcsym.h ckcdeb.h ckcxla.h \ - ckuxla.h ckcasc.h ckcnet.h ckctel.h ckclib.h ckcuni.h - -ckuus2.$(EXT): ckuus2.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \ - ckcasc.h ckcnet.h ckcsym.h ckctel.h ckclib.h ckcuni.h - -ckuus3.$(EXT): ckuus3.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \ - ckcasc.h ckcnet.h ckcsym.h ckctel.h ckclib.h ckcuni.h - -ckuus4.$(EXT): ckuus4.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \ - ckcasc.h ckcnet.h ckuver.h ckcsym.h ckctel.h ckclib.h ckcuni.h - -ckuus5.$(EXT): ckuus5.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcasc.h ckcnet.h \ - ckcsym.h ckctel.h ckclib.h ckcxla.h ckuxla.h ckcuni.h - -ckuus6.$(EXT): ckuus6.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcasc.h ckcnet.h \ - ckcsym.h ckctel.h ckclib.h - -ckuus7.$(EXT): ckuus7.c ckucmd.h ckcker.h ckuusr.h ckcdeb.h ckcxla.h ckuxla.h \ - ckcasc.h ckcnet.h ckcsym.h ckctel.h ckclib.h ckcuni.h - -ckuusx.$(EXT): ckuusx.c ckcker.h ckuusr.h ckcdeb.h ckcasc.h ckcsym.h \ - ckcsig.h ckcnet.h ckctel.h ckclib.h ckcxla.h ckuxla.h ckcuni.h - -ckuusy.$(EXT): ckuusy.c ckcker.h ckcdeb.h ckcasc.h ckcnet.h ckcsym.h ckctel.h \ - ckclib.h - -ckucmd.$(EXT): ckucmd.c ckcasc.h ckucmd.h ckcdeb.h ckcsym.h ckctel.h ckclib.h - -ckufio.$(EXT): ckufio.c ckcdeb.h ckuver.h ckcsym.h ckclib.h \ - ckcxla.h ckuxla.h ckcuni.h - -ckutio.$(EXT): ckutio.c ckcdeb.h ckcnet.h ckuver.h ckcsym.h ckctel.h ckclib.h - -ckucon.$(EXT): ckucon.c ckcker.h ckcdeb.h ckcasc.h ckcnet.h ckcsym.h ckctel.h \ - ckclib.h - -ckucns.$(EXT): ckucns.c ckcker.h ckcdeb.h ckcasc.h ckcnet.h ckcsym.h ckctel.h \ - ckclib.h ckcxla.h ckuxla.h ckcuni.h - -ckcnet.$(EXT): ckcnet.c ckcdeb.h ckcker.h ckcnet.h ckcsym.h ckcsig.h ckctel.h \ - ckclib.h - -ckctel.$(EXT): ckcsym.h ckcdeb.h ckcker.h ckcnet.h ckctel.h ckclib.h - -wart: ckwart.$(EXT) - $(CC) $(LNKFLAGS) -o wart ckwart.$(EXT) $(LIBS) - -ckcmdb.$(EXT): ckcmdb.c ckcdeb.h ckcsym.h ckclib.h - -ckwart.$(EXT): ckwart.c - -ckudia.$(EXT): ckudia.c ckcker.h ckcdeb.h ckucmd.h ckcasc.h ckcsym.h ckcsig.h \ - ckcnet.h ckctel.h ckclib.h - -ckuscr.$(EXT): ckuscr.c ckcker.h ckcdeb.h ckcasc.h ckcsym.h ckcsig.h \ - ckcnet.h ckctel.h ckclib.h - -ckusig.$(EXT): ckusig.c ckcasc.h ckcdeb.h ckcker.h ckcnet.h ckuusr.h \ - ckcsig.h ckctel.h ckclib.h - -ckcftp.$(EXT): ckcftp.c ckcdeb.h ckcasc.h ckcker.h ckucmd.h ckuusr.h \ - ckcnet.h ckctel.h ckcxla.h ckuxla.h ckcuni.h - -ckupty.$(EXT): ckupty.c ckupty.h ckcdeb.h - -ckuath.$(EXT): ckuath.c ckcdeb.h ckucmd.h ckuath.h ckuat2.h ckctel.h \ - ckclib.h ckcnet.h - -ck_crp.$(EXT): ck_crp.c ckcdeb.h ckcnet.h ckuath.h ckclib.h - -ck_ssl.$(EXT): ck_ssl.c ckcdeb.h ckucmd.h ckuath.h ckuat2.h ckctel.h \ - ckclib.h ck_ssl.h - -########################################################################### -# -# Entries to make C-Kermit for specific systems. -# -# Put the ones that need short makefiles first. - -#Apollo Aegis 9.x. Includes TCP/IP support. -#You can also add processor-dependent optimization switches like -M570. -aegis: - @echo Making C-Kermit $(CKVER) for Apollo Aegis 9.x... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DNOCSETS -DCK_CURSES -O $(KFLAGS)" \ - "LIBS = -lcurses -ltermcap" - -#Apple Mac II, A/UX pre-3.0 -#Warning, if "send *" doesn't work, try the auxufs makefile entry below. -aux: - @echo Making C-Kermit $(CKVER) for Macintosh A/UX... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DAUX -DTCPSOCKET $(KFLAGS) -i -O" "LNKFLAGS = -i" - -#Apple Mac II, A/UX pre-3.0, compiled with gcc -auxgcc: - @echo Making C-Kermit $(CKVER) for Macintosh A/UX... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DAUX -DTCPSOCKET -traditional $(KFLAGS) -i -O" \ - "LNKFLAGS = " "CC = gcc" "CC2 = gcc" - -#Apple Mac II, A/UX, pre-3.0, but with ufs file volumes, uses . -auxufs: - @echo Making C-Kermit $(CKVER) for Macintosh A/UX... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DAUX -DTCPSOCKET -DDIRENT $(KFLAGS) -i -O" "LNKFLAGS = -i" - -#Apple Mac II, A/UX 3.0, compiled with gcc -aux3gcc: - @echo Making C-Kermit $(CKVER) for Macintosh A/UX 3.0... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DAUX -DHDBUUCP -DLFDEVNO -DTCPSOCKET -DDIRENT $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS = $(LIBS)" \ - "CC=gcc -pipe -traditional" "CC2=gcc -pipe -traditional" - -#Apple Mac II, A/UX 3.0, compiled with gcc, uses curses -aux3cgcc: - @echo Making C-Kermit $(CKVER) for Macintosh A/UX 3.0... - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) aux3gcc \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DCK_CURSES" "LIBS = -lcurses $(LIBS)" - -# Tenon MachTen, tested on Apple Powerbook with MachTen 2.1.1.D. -# NOTE: This doesn't do anything about UUCP. It only works if /usr/spool/uucp -# has permission of 777, and dialout device is world read/writeable. -machten: - @echo Making C-Kermit $(CKVER) for MachTen... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD43 -DTCPSOCKET -DSIG_V -DNDGPWNAM -DCK_CURSES -O \ - $(KFLAGS)" "LIBS=-lcurses -ltermcap" - -#Bell Labs Research UNIX V10 -#Can't add TCP/IP because there is no sockets library. It would have to -#be done using streams, but there is no code in C-Kermit for that. -#Remove -DNOJC if desired (if your system has csh, ksh, or bash). -bellv10: - @echo Making C-Kermit $(CKVER) for Bell Labs Research UNIX V10... - $(MAKE) wermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBELLV10 -DBSD4 -DNDIR -DNOJC -DNOSYSIOCTLH -DNOSETREU \ - -DNOCSETS -MINIDIAL $(KFLAGS)" - -# WARNING: The early BSD entries do not build in version 7.0 with the stock -# BSD compiler: "Too many defines". Unless you can rebuild cpp to have more -# space for defines, these builds must be accomplished by: -# copying the /usr/include tree to someplace else, preprocessing there with cc -# -E -I./include or whatever (plus all the same -D's, adding any necessary -# -U/-D to override the architecture)), renaming the the resulting files back -# to their original names, bringing them back to the original BSD system, and -# running the make target there. This technique was used for 4.2 and 4.3 BSD -# on a VAX in C-Kermit 7.0 (later, cpp on that machine was rebuilt to allow -# more symbols, so the C-Kermit 8.0 build proceeds normally). - -#Berkeley Unix 4.1 -bsd41: - @echo Making C-Kermit $(CKVER) for 4.1BSD... - $(MAKE) wermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD41" "LIBS = -ljobs" - -#Berkeley 4.2, 4.3, also Ultrix-32 1.x, 2.x, 3.x, many others -# Add -O, -s, etc, if they work. -# If you have a version of BSD but signal() is void rather than int, -# "make bsd KFLAGS=-DSIG_V". -bsd42: - @echo Making C-Kermit $(CKVER) for 4.2BSD... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DNOREALPATH -DNOTIMEH -DNOIKSD \ - -DCK_CURSES -DSYSTIMEBH -DNOPUTENV -DNOANSI -DBIGBUFOK -DBSD42HACK \ - $(KFLAGS)" "LIBS=-lcurses -ltermcap $(LIBS)" - -bsd: - $(MAKE) CC=$(CC) CC2=$(CC2) bsd42 KTARGET=$${KTARGET-$(@)} - -#Berkeley Unix 4.2 or 4.3 with HoneyDanBer UUCP -bsdhdb: - @echo Making C-Kermit $(CKVER) for 4.2BSD with HDB UUCP... - $(MAKE) CC=$(CC) CC2=$(CC2) bsd KTARGET=$${KTARGET-$(@)} \ - "KFLAGS= -DHDBUUCP $(KFLAGS)" - -#Berkeley Unix 4.3 with acucntrl program, curses, TCP/IP included. -bsd43: - @echo Making C-Kermit $(CKVER) for 4.3BSD... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DBSD43 -DTCPSOCKET -DNOREALPATH -DNOTIMEH -DNOIKSD \ - -DCK_CURSES -DACUCNTRL -DSYSTIMEBH -DNOPUTENV -DNOANSI -DBIGBUFOK \ - -DBSD42HACK $(KFLAGS)" "LIBS=-lcurses -ltermcap $(LIBS)" - -#4.3BSD, curses excluded -bsd43nc: - @echo Making C-Kermit $(CKVER) for 4.3BSD... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DBSD43 -DTCPSOCKET -DNOREALPATH -DNOTIMEH \ - -DACUCNTRL -DSYSTIMEBH -DNOIKSD -DNOPUTENV -DNOANSI -DBIGBUFOK \ - -DBSD42HACK $(KFLAGS)" "LIBS=$(LIBS)" - -#4.3BSD, TCP/IP excluded. -bsd43nonet: - @echo Making C-Kermit $(CKVER) for 4.3BSD + curses... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DBSD43 -DTCPSOCKET -DNOREALPATH -DNOTIMEH -DNOIKSD \ - -DCK_CURSES -DACUCNTRL -DSYSTIMEBH -DNOPUTENV -DNOANSI -DBIGBUFOK \ - -DBSD42HACK -DNONET $(KFLAGS)" "LIBS=-lcurses -ltermcap $(LIBS)" - -#Berkeley Unix 4.2 or 4.3 with lock directory /usr/spool/uucp/LCK/LCK..ttyxx, -#but without acucntrl program -bsdlck: - @echo Making C-Kermit $(CKVER) for 4.2BSD, /usr/spool/uucp/LCK/... - $(MAKE) CC=$(CC) CC2=$(CC2) bsd KTARGET=$${KTARGET-$(@)} \ - "KFLAGS= -DLCKDIR $(KFLAGS)" - -#Berkeley UNIX 4.4-Lite, 4.4-Encumbered, Net/2, etc (Post-Reno), -#with TCP/IP networking. This was the basis for FreeBSD, NetBSD, OpenBSD, -#BSDI, BSD/OS, and Mac OS X (each of which has its own set of targets that -#are newer than this one). -# -#NOTE: This is not a pure POSIX configuration. Using -DPOSIX instead of -# -DBSD44 prevents any kind of directory-reading (for wildcard expansion), -#and disallows use of ENOTCONN symbol for detecting broken network -#connections, and disallows RTS/CTS flow control, and would also require -#definition of the appropriate UUCP lockfile convention. -#Do not add -DCK_POSIX_SIG without reading first! For example, -#sigsetjmp(), etc, tend to be defined but not implemented. -# -#NOTE: originally crypt was in libc - later it was unbundled. -#Remove the LIBS clause to build on an early 4.4BSD platform. -# -bsd44: - @echo Making C-Kermit $(CKVER) for 4.4BSD... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DTCPSOCKET $(KFLAGS) -O" "LIBS=-lcrypt" - -#Berkeley UNIX 4.4, as above, but with curses for fullscreen display -#Please read notes for bsd44 entry just above. -# NOTE: This one dumped core on the real 4.4BSD development system at -# UC Berkeley (an HP-9000/300), so the no-curses version was used -# for that one, which was unplugged years ago. -bsd44c: - @echo Making C-Kermit $(CKVER) for 4.4BSD with curses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET $(KFLAGS) -O" \ - "LIBS= -lcurses -ltermcap -lcrypt $(LIBS)" - -#For FreeBSD 1.x. -freebsd1: - @echo 'Making C-Kermit $(CKVER) for FreeBSD...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC -funsigned-char \ - -DFNFLOAT -DNOHTERMCAP -DNOREALPATH -DNOSYSCONF $(KFLAGS) -O -pipe" \ - "LIBS= -lcurses -ltermcap -lm $(LIBS)" - -#FreeBSD 2.x with ncurses -freebsd2: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 2.x with ncurses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DTCPSOCKET -DNOCOTFMC -DUSE_STRERROR \ - -DTPUTSARGTYPE=int -DTPUTSARG1CONST -DFREEBSD2 -funsigned-char \ - -DFNFLOAT $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -ltermlib -lcrypt -lm $(LIBS)" - -#For FreeBSD 2.x -- Uses curses rather than ncurses -freebsd2c: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 2.x with curses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC -DUSE_STRERROR \ - -DTPUTSARGTYPE=int -DTPUTSARG1CONST -DFREEBSD2 -DFNFLOAT \ - -funsigned-char $(KFLAGS) -O -pipe" \ - "LIBS= -lcurses -ltermlib -lcrypt -lm $(LIBS)" - -#FreeBSD 3.x with ncurses and uu_lock() -#(Note: uu_lock() goes back to 2.2.2, but not necessarily 2.0) -freebsd3: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 3.x with ncurses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DTCPSOCKET -DNOCOTFMC -funsigned-char \ - -DTPUTSARGTYPE=int -DUSE_STRERROR -DFREEBSD3 -DUSE_UU_LOCK -DFNFLOAT \ - $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#As above but with curses rather than ncurses. -freebsd3c: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 3.x with curses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC -DUSE_UU_LOCK \ - -DTPUTSARGTYPE=int -DUSE_STRERROR -DFREEBSD3 $(KFLAGS) -DFNFLOAT \ - -funsigned-char -pipe -O" \ - "LIBS= -lcurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.0 with ncurses and uu_lock(). Note - there is no curses in 4.0. -#ncurses 5.0 is broken requiring us to work around with setbuf(). -freebsd4: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.x with ncurses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DTCPSOCKET -DNOCOTFMC -DFNFLOAT \ - -funsigned-char -DTPUTSARGTYPE=int -DUSE_STRERROR -DFREEBSD4 \ - -DNONOSETBUF -DUSE_UU_LOCK $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.1, as above but without the NONOSETBUF hack and with CK_NEWTERM. -#This works with ncurses 5.1. -freebsd41: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.1 with ncurses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DFREEBSD41 -DUSE_UU_LOCK -DFNFLOAT \ - -funsigned-char -DTPUTSARGTYPE=int -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#Default FreeBSD make for C-Kermit 8.0... -freebsd: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - KTARGET=$${KTARGET-$(@)} freebsd45 - -#FreeBSD 4.2, like 4.1. -freebsd42: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.2...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DFREEBSD41 -DFREEBSD42 -DUSE_UU_LOCK -DFNFLOAT \ - -funsigned-char -DTPUTSARGTYPE=int -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.3, like 4.2. -freebsd43: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.3...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DUSE_UU_LOCK \ - -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int -DUSE_STRERROR $(KFLAGS) \ - -O -pipe" "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.4, like 4.3. -freebsd44: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.4...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 \ - -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.5, like 4.3 and 4.4. -freebsd45: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.5...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.6, like 4.5 -freebsd46: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.6...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DFREEBSD46 -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.7, like 4.6 -freebsd47: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.7...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DFREEBSD46 -DFREEBSD47 -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.8, like 4.7 -freebsd48: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.7...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DFREEBSD46 -DFREEBSD47 -DFREEBSD48 \ - -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 4.9 -freebsd49: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.7...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DFREEBSD46 -DFREEBSD47 -DFREEBSD48 -DFREEBSD49 \ - -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 5.0, like 4.6 -freebsd50: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 5.0 with ncurses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DFREEBSD46 -DFREEBSD50 -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#FreeBSD 5.1 -freebsd51: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 5.0 with ncurses...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DFREEBSD46 -DFREEBSD50 -DFREEBSD51 \ - -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lutil -lm $(LIBS)" - -#Secure builds for FreeBSD... gcc required. - -freebsd44+srp+openssl: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 4.3 with SRP,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DFREEBSD4 -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 \ - -DCK_AUTHENTICATION -DCK_SRP \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \ - -DCK_CURSES -DTCPSOCKET \ - $(SRPINC) $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(SSLLIB) \ - -lncurses -ltermcap -lsrp -lssl -lkrypto -lcrypto \ - -lcrypt " - -# The following fragmentary FreeBSD+SLL target was suggested, but it's not -# clear which version of FreeBSD it applies to. -# -# ALL_TARGET= xermit -# MAKE_ARGS= KTARGET=freebsd \ -# CFLAGS="${CFLAGS} -DBSD44 -DCK_NCURSES -DCK_NEWTERM \ -# -DTCPSOCKET -DNOCOTFMC -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT \ -# -funsigned-char -DTPUTSARGTYPE=int -DUSE_STRERROR -DCKHTTP \ -# -DCK_SSL -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_DES" \ -# LIBS="-lssl -lcrypto -ldes -lncurses -lcrypt -lutil -lm" - -#FreeBSD 5.0 with OpenSSL 0.9.7. -freebsd50+openssl: - @echo 'Making C-Kermit $(CKVER) for FreeBSD 5.0, ncurses, openssl' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_NCURSES -DCK_NEWTERM -DTCPSOCKET -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SSL $(SSLINC) -DZLIB \ - -DFREEBSD4 -DUSE_UU_LOCK -DFNFLOAT -funsigned-char -DTPUTSARGTYPE=int \ - -DFREEBSD41 -DFREEBSD42 -DFREEBSD43 -DFREEBSD44 -DFREEBSD45 \ - -DFREEBSD46 -DFREEBSD50 -DUSE_STRERROR $(KFLAGS) -O -pipe" \ - "LIBS= -lncurses -lcrypt -lssl -lcrypto -lutil -lm $(SSLLIB) $(LIBS)" - -#NetBSD - all versions - with curses, not ncurses. -#Some builds seem to need KFLAGS=-DTPUTSFNTYPE=int, others don't. -#(Only to get rid of a warning -- the binaries are identical.) -netbsd: - @echo Making C-Kermit $(CKVER) for NetBSD with curses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DUSE_STRERROR -DTPUTSISVOID \ - -DCK_DTRCD -DCK_DTRCTS -DTPUTSARGTYPE=int -DFNFLOAT $(KFLAGS) -O" \ - "LIBS= -lcurses -lcrypt -lm $(LIBS)" - -#NetBSD 1.5.x in which the return type of the function pointer that is the -#third argument of tputs() was changed from void to int... The regular NetBSD -#target builds OK here but this one eliminates the (harmless) warning. -netbsd15: - @echo Making C-Kermit $(CKVER) for NetBSD with curses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DUSE_STRERROR -DNETBSD15 \ - -DCK_DTRCD -DCK_DTRCTS -DTPUTSARGTYPE=int -DFNFLOAT $(KFLAGS) -O" \ - "LIBS= -lcurses -lcrypt -lm $(LIBS)" - -#NetBSD 1.6 - like 1.5.x but with vanity banner saying 1.6. -netbsd16: - @echo Making C-Kermit $(CKVER) for NetBSD with curses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DUSE_STRERROR \ - -DNETBSD15 -DNETBSD16 \ - -DCK_DTRCD -DCK_DTRCTS -DTPUTSARGTYPE=int -DFNFLOAT $(KFLAGS) -O" \ - "LIBS= -lcurses -lcrypt -lm $(LIBS)" - -#NetBSD with ncurses requested explicitly rather than curses-which-is-ncurses -netbsdn: - @echo Making C-Kermit $(CKVER) for NetBSD with ncurses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC -DCK_DTRCD \ - -DCK_DTRCTS -DFNFLOAT -DUSE_STRERROR -DTPUTSISVOID -DTPUTSARGTYPE=int \ - $(KFLAGS) -O" \ - "LIBS= -L/usr/pkg/lib -lncurses -lcrypt -lm $(LIBS)" - -#OpenBSD - All versions. -#Uses ncurses as its curses so use -ltermlib, not -ltermcap -#But it doesn't use uu_lock() which was introduced in OpenBSD 2.3. -#For that use the next entry. -#Add -DMAINTYPE=int if you get complaints about main: return type is not int. -openbsdold: - @echo Making C-Kermit $(CKVER) for OpenBSD... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \ - -DFNFLOAT -DNDSYSERRLIST $(KFLAGS) -O" "LIBS= -lcurses -ltermlib -lm" - -#OpenBSD 2.3 or later -#Add -DMAINTYPE=int if you get complaints about main: return type is not int. -#For C-Kermit 8.0 (Christian Weisgerber): -# -ltermlib removed (presumably because -lcurses==ncurses already includes it) -# -DUSE_UU_LOCK and -lutil added for uu_lock() -# -DNDSYSERRLIST changed to -DUSE_STRERROR -#If this gives you trouble use the previous entry. -openbsd: - @echo Making C-Kermit $(CKVER) for OpenBSD 2.3 or later... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \ - -DUSE_UU_LOCK -DFNFLOAT -DUSE_STRERROR $(KFLAGS) -O" \ - "LIBS= -lcurses -lutil -lm" - -#OpenBSD 3.0 or later includes OpenSSL -#Add -DMAINTYPE=int if you get complaints about main: return type is not int. -#For C-Kermit 8.0 (Christian Weisgerber): -# -ltermlib removed (presumably because -lcurses==ncurses already includes it) -# -DUSE_UU_LOCK and -lutil added for uu_lock() -# -DNDSYSERRLIST changed to -DUSE_STRERROR -#If this gives you trouble use the previous entry. -openbsd30+ssl: - @echo Making C-Kermit $(CKVER) for OpenBSD 3.0 or later... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET -DOPENBSD \ - -DUSE_UU_LOCK -DFNFLOAT -DUSE_STRERROR -DCK_AUTHENTICATION \ - -DCK_SSL $(KFLAGS) -O" \ - "LIBS= -lcurses -lutil -lm -lssl -lcrypto" - -# make 386bsd 0.0new, posix -# for 386bsd 0.1.24, change /usr/include/termios.h to #define NCCS if -# _POSIX_SOURCE is #defined. (source: lewine, posix prgmrs guide, o`reilly) -#NOTE: Lock directory is /var/spool/lock. Formerly, it was /var/spool/uucp, -#but reportedly that was due to a typo in 'man tip'. -386bsd: - @echo 'Making C-Kermit $(CKVER) for jolix 386BSD 0.0new and 0.1.24...' - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DSETREUID -DPIDSTRING -DUSLEEP \ - -D_386BSD -DCK_CURSES -DTCPSOCKET \ - -DLOCK_DIR=\\\"/var/spool/lock\\\" \ - $(KFLAGS) -O" "LNKFLAGS = -s" "LIBS = -lcurses -ltermcap" - -#Mac OS X 1.0 (Rhapsody, Darwin) -- TCP/IP but no curses. -macosx10: - @echo Making C-Kermit $(CKVER) for `uname -s`... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DMACOSX10 -DTCPSOCKET -DUSE_STRERROR -O $(KFLAGS)" - -#Mac OS X 1.0 (Rhapsody, Darwin) -- TCP/IP and curses. -#Note: curses must be obtained separately. See next entry for ncurses. -#Add "LIBS = -lcurses -ltermcap" if necessary (but reportedly it is not). -macosx10c: - @echo Making C-Kermit $(CKVER) for `uname -s` + curses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DMACOSX10 -DCK_CURSES -DTPUTSFNTYPE=void -DTPUTSISVOID \ - -DTCPSOCKET -DUSE_STRERROR -O $(KFLAGS)" - -#Mac OS X 1.0 (Rhapsody, Darwin) -- TCP/IP and ncurses. -#Note: ncurses must be obtained separately. -#In the event of trouble with this one try the next one. -macosx10nc: - @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DMACOSX10 -DCK_NCURSES -DTCPSOCKET -DUSE_STRERROR -O \ - $(KFLAGS)" "LIBS= -lncurses $(LIBS)" - -#Mac OS X 10.2 (Jaguar) ncurses. -macosx102nc: - @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DMACOSX10 -DCK_NCURSES -DTCPSOCKET -DUSE_STRERROR -O \ - $(KFLAGS) " "LIBS= -lncurses $(LIBS)" - -#The problem here is that if curses.h also exists, it conflicts with -#ncurses.h and and we have fatal errors. If this happens to you, then -#try this entry. -macosx10ncx: - @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses... - @rm -f ./curses.h; touch ./curses.h - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DMACOSX10 -DCK_NCURSES -DTCPSOCKET -DUSE_STRERROR \ - -I. -O $(KFLAGS) " \ - "LIBS= -lncurses $(LIBS)" - @rm -f ./curses.h - -#Mac OS X 10.3 (Panther) - Assumes ncurses is installed. -macosx103: - @echo Making C-Kermit $(CKVER) for `uname -s` + ncurses... - $(MAKE) CC=$(CC) CC2=$(CC2) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DMACOSX10 -DMACOSX103 -DCK_NCURSES -DTCPSOCKET \ - -DUSE_STRERROR -DUSE_NAMESER_COMPAT -O \ - $(KFLAGS) " "LIBS= -lncurses -lresolv $(LIBS)" - -macosx103nc: - $(MAKE) MAKE=$(MAKE) CC=$(CC) CC2=$(CC2) macosx103 - -#Acorn RISCiX, based on ... -#Berkeley Unix 4.2 or 4.3 with lock directory /usr/spool/uucp/LCK/LCK..ttyxx, -#but without acucntrl program -riscix: - @echo Making C-Kermit $(CKVER) for RISCiX, /usr/spool/uucp/LCK..ttyxx - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD42 -DBSD4 -DRISCIX -DNOCSETS \ - -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DDIRENT -DCK_CURSES \ - -DMAXSP=9024 -DMAXRD=9024 -DSBSIZ=9050 -DRBSIZ=9050 \ - -DDFTTY=\\\"/dev/serial\\\" -DNOCSETS -DNOCYRIL \ - -DNOANSI -w -O2 -fomit-frame-pointer" \ - "LIBS= -lcurses -ltermcap " \ - "CC= /usr/ucb/cc" \ - "CC2= /usr/ucb/cc" - -#Acorn RISCiX, as above, but using gcc -riscix-gcc: - @echo Making C-Kermit $(CKVER) for RISCiX, /usr/spool/uucp/LCK..ttyxx - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD42 -DBSD4 -DRISCIX -DNOCSETS \ - -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DDIRENT -DCK_CURSES \ - -DMAXSP=9024 -DMAXRD=9024 -DSBSIZ=9050 -DRBSIZ=9050 \ - -DDFTTY=\\\"/dev/serial\\\" -DNOCSETS -DNOCYRIL \ - -DNOANSI -w -O2 -fomit-frame-pointer" \ - "LIBS= -lcurses -ltermcap " \ - "CC= gcc -mbsd" \ - "CC2= gcc -mbsd" - -#Convergent CTIX 6.4.1 -ctix: - @echo 'Making C-Kermit $(CKVER) for Convergent CTIX 6.4.1' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSVR3 -DDIRENT -DTCPSOCKET -DHDBUUCP -DCK_CURSES \ - -DNONAWS -DNOLEARN $(KFLAGS) -XO" \ - "LNKFLAGS=-s" "LIBS=-lsocket -lcurses -lc_s" - mcs -d wermit - -# The following makefile entry should work for any Harris Night Hawk system -# (either 88k or 68k based) running release 6.1 or later of the CX/UX -# operating system. This is a POSIX and ANSI-C compliant system which also -# supports BSD networking. (Earlier CX/UX releases will probably work with -# sys5r3, but this has not been verified). -# -cx_ux: - @echo Making C-Kermit $(CKVER) for Harris Night Hawk CX/UX 6.1 or later - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS=-DPOSIX -DTCPSOCKET -DHDBUUCP -DPID_T=pid_t -DWAIT_T=int \ - -Dd_ino=d_fileno -DUID_T=uid_t -DGID_T=gid_t $(KFLAGS) -Xa \ - -O3 -g" "LNKFLAGS=-O3" - -#Intergraph Clipper, CLIX, job control, HDB UUCP. -clix: - @echo 'Making C-Kermit $(CKVER) for Intergraph CLIX...' - $(MAKE) wermit "CC=acc" "CC2=acc" KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -w -DSVR3 -DCLIX -DDIRENT -DHDBUUCP -DNOSYSLOG -DUSE_MEMCPY \ - -DNOGETUSERSHELL -DNOREALPATH -DNOLEARN $(KFLAGS) -O" \ - "LNKFLAGS=" "LIBS= -lbsd" - -#As above + TCP/IP... -clixnet: - @echo 'Making networked C-Kermit $(CKVER) for Intergraph CLIX...' - $(MAKE) wermit "CC=acc" "CC2=acc" KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -w -DSVR3 -DCLIX -DDIRENT -DHDBUUCP -DNOSYSLOG -DUSE_MEMCPY \ - -DTCPSOCKET -DNOGETUSERSHELL -DNOLEARN -DNOREALPATH $(KFLAGS) -O" \ - "LNKFLAGS=" "LIBS= -lbsd" - -#Mark Williams Coherent 286 or 386 on IBM PC family. -#There is a 64K limit on program size, so this is a command-line only version. -coherent: - $(MAKE) "CFLAGS = -O -DCOHERENT -DNOANSI -DNOICP -DNOSETKEY -DNOLEARN \ - -DNOCSETS -DNOHELP -DNODIAL -DNOSCRIPT -DNODEBUG -DNOTLOG -DNOXMIT \ - -DNOMSEND -DNOFRILLS -DNOSYSIOCTLH -DSELECT_H $(KFLAGS) -VSUVAR" \ - -DNOFLOAT KTARGET=$${KTARGET:-$(@)} wermit - -#Mark Williams Coherent 386 on IBM PC family. -#This will make a "minimum interactive" version - no scripts, -#no character sets, no help, no dial, no debug/transaction logging, no -#transmit, msend, mail, type, etc. -coherentmi: - $(MAKE) "CFLAGS = -O -DCOHERENT -DNOANSI -DNOSETKEY -DNOLEARN \ - -DNOSHOW -DNOCSETS -DNOHELP -DNODIAL -DNOSCRIPT -DNODEBUG -DNOTLOG \ - -DNOXMIT -DNOMSEND -DNOFRILLS -DNOSYSIOCTLH -DNOSERVER -DNOUUCP \ - -DNOSPL -DNOPUSH -DNOMDMHUP -DNOJC -DNOFDZERO -DNOESCSEQ -DNOFLOAT \ - -DNOCMDL $(KFLAGS) -VSUVAR -DSELECT_H" KTARGET=$${KTARGET:-$(@)} \ - wermit - -#Mark Williams Coherent 386 on IBM PC/AT family. -coherentmax: - $(MAKE) "CFLAGS = -O -DCOHERENT -DNOANSI -DSELECT_H -DNOLEARN \ - -DNOFLOAT -DNOSYSIOCTLH $(KFLAGS) -VSUVAR" "LNKFLAGS = -O -s" \ - KTARGET=$${KTARGET:-$(@)} wermit - -#Mark Williams Coherent 386 4.2. Includes curses but not TCP/IP. -#Requires updates to the 4.2.10 compiler; the regular compiler fails to -#to handle "complex expressions". NOFLOAT is so it can work on old PCs -#without floating-point hardware. -coherent42: - $(MAKE) "CFLAGS = -T500000 -DNOFLOAT -DCOHERENT -DNOANSI -DSELECT \ - -DNOSYSLOG -DDIRENT -DCK_CURSES -DCK_NEWTERM -DCK_WREFRESH -VSUVAR \ - -DDCLGETCWD -DNOSYSIOCTLH -DNOINITGROUPS -DNOSYMLINK -DSELECT_H \ - -DDCLGETCWD -O $(KFLAGS)" \ - "LNKFLAGS = -O -s" KTARGET=$${KTARGET:-$(@)} \ - "LIBS = -lsocket -lcurses" wermit - -#DEC Ultrix 2.x -# Add -O, -DDYNAMIC, -s, etc, if they work. -ultrix2x: - @echo Making C-Kermit $(CKVER) for Ultrix 2.x ... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DDU2 -DNOGETUSERSHELL $(KFLAGS)" - -du2: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix2x - -#DEC Ultrix 3.0 and 3.1 -ultrix30: - @echo Making C-Kermit $(CKVER) for Ultrix 3.0... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DDIRENT -DSIG_V -DNOGETUSERSHELL \ - -DULTRIX3 -DCK_CURSES $(KFLAGS) -O" "LIBS= -lcurses -ltermcap" - -du3: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix30 - -ultrix3x: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix30 - -#DEC Ultrix 4.0 or 4.1 on DECstation, VAXstation, VAX, etc. -ultrix40: - @echo Making C-Kermit $(CKVER) for Ultrix 4.0 or 4.1... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DDU4 -DNOGETUSERSHELL \ - $(KFLAGS) -Olimit 1450" "LNKFLAGS = -s" - -#DEC Ultrix 4.2-4.5 on DECstation, DECsystem, VAXstation, VAX, etc. -#Like ultrix40, except now C compiler supports -O2 optimization. -ultrix42: - @echo Making C-Kermit $(CKVER) for Ultrix 4.2 or later... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL $(KFLAGS) \ - -O2 -Olimit 1750" "LNKFLAGS = -s" - -du42: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET-$(@)} ultrix42 - -#DEC Ultrix 4.2-4.5 on DECstation, DECsystem, VAXstation, VAX, etc. -#Like du42, but with curses support added and a couple features. -ultrix42c: - @echo Making C-Kermit $(CKVER) for Ultrix 4.2 or later... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL \ - -DCK_CURSES -DNOIKSD $(KFLAGS)-G6 -O2 -Olimit 3000 " \ - "LNKFLAGS = -s" "LIBS= -lcurses -ltermcap" - -ultrix43: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - "KFLAGS=-DULTRIX43 $(KFLAGS)" KTARGET=$${KTARGET-$(@)} ultrix42c - -ultrix43notcp: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - "KFLAGS=-DULTRIX43 -DNONET $(KFLAGS)" \ - KTARGET=$${KTARGET-$(@)} ultrix42c - -# NOTE: need -DNODEBUG on MIPS to avoid relocation errors at link time. -# Actually now (8.0) that we have discovered the -G option maybe debugging -# can be put back. -ultrix44: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - "KFLAGS=-DULTRIX44 -G7 -DNODEBUG -DNETPTY -DNO_DEVTTY $(KFLAGS)" \ - KTARGET=$${KTARGET-$(@)} ultrix42c - -ultrix45: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - "KFLAGS=-DULTRIX45 $(KFLAGS)-DNETPTY -DNO_DEVTTY $(KFLAGS)" \ - KTARGET=$${KTARGET-$(@)} ultrix42c - -du42c: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - KTARGET=$${KTARGET-$(@)} ultrix42c - -#DEC Ultrix 4.3A or later on DECsystem and DECstation 5000/50, /150 or /260 -#with MIPS R4x00 processor. The "-mips3" switch generates R4000-specific -#code, which is faster and more compact, but *won't* run on earlier -#DECsystems and DECstations. -ultrix43-mips3: - @echo Making C-Kermit $(CKVER) for Ultrix 4.3A or later, R4000 cpu... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL \ - $(KFLAGS) -O2 -Olimit 1750 -mips3" "LNKFLAGS = -s -mips3" - -du43-mips3: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) ultrix43-mips3 - -#DEC Ultrix 4.3A or later on MIPS R4x000 based systems. -#Like ultrix43-mips3 but with curses support added -ultrix43c-mips3: - @echo Making C-Kermit $(CKVER) for Ultrix 4.3A or later, R4000 cpu... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL -DCK_CURSES \ - $(KFLAGS) -O2 -Olimit 3000 -mips3" "LNKFLAGS = -s -mips3" \ - "LIBS= -lcurses -ltermcap" - -du43c-mips3: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - KTARGET=$${KTARGET-$(@)} ultrix43c-mips3 - -#DEC Ultrix 4.4 on DECstation 5000/50 or /150 with R4000 MIPS processor, -#or 5000/260 with R4400. The "-mips3" switch generates R4000-specific code, -#which is faster and more compact but *won't* run on earlier DECstations. -ultrix44-mips3: - @echo Making C-Kermit $(CKVER) for Ultrix 4.4, R4000 cpu ... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DSIG_V -DNOGETUSERSHELL \ - $(KFLAGS) -O2 -Olimit 1450 -mips3" "LNKFLAGS = -s -mips3" - -du44-mips3: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - KTARGET=$${KTARGET-$(@)} ultrix44c-mips3 - -#DEC Ultrix 4.2 on DECstation, VAXstation, VAX, etc, System V R4 environment -ultrix42s5r4: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4 on Ultrix...' - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS = -O2 -Olimit 1500 -DSVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \ - -DTCPSOCKET $(KFLAGS)" "LNKFLAGS = -s" - -#OSF/1 -osf: - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD4 -DOSF -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \ - -DCK_CURSES -DCK_RTSCTS -DFNFLOAT $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS = -lbsd -lcurses -ltermcap -lm" - -#DEC OSF/1 V1.0-1.3 on DECstation, VAX, Alpha, or PC. -dec-osf: - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD4 -DOSF -DOSF13 -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \ - -DNOREALPATH -DNOIKSD -DCK_CURSES -DCK_RTSCTS -DFNFLOAT -DNODEBUG \ - -DNOUNICODE $(KFLAGS)" \ - "LNKFLAGS = -non_shared" "LIBS = -lbsd -lcurses -ltermcap -lm" - -# This one causes "relocation out-of-range" errors in the linker. -old-dec-osf: - @echo Making C-Kermit $(CKVER) for DEC OSF/1 V1.x... - @echo If you are building for DEC OSF/1 2.0, please use dec-osf20. - @echo Remove or adjust -O2 and/or -Olimit if they cause trouble. - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -O2 -Olimit 2400 $(KFLAGS)" - -#DEC OSF/1 2.0 on Alpha and probably nowhere else. -#The only difference from OSF/1 is that optimization is omitted. -#The optimized version gets strange runtime errors, like the PAUSE command -#not working. Add "-unsigned" to make all chars unsigned. -dec-osf20: - @echo Making C-Kermit $(CKVER) for DEC OSF/1 V2.0... - @echo Optimization omitted because it causes runtime errors. - @echo See comments in makefile. - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF20 $(KFLAGS)" - -dec-osf30: - @echo Making C-Kermit $(CKVER) for DEC OSF/1 V3.0... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF30 -O2 -Olimit 2400 $(KFLAGS)" - -#Digital UNIX 3.2 -# Must compile ckuus[6x].c separately without optimization otherwise -# the optimizer dumps core - keep CFLAGS here in sync with those from osf. -du32: - @echo Making C-Kermit $(CKVER) for Digital UNIX 3.2... - $(MAKE) CC=$(CC) CC2=$(CC2) ckuus6.$(EXT) \ - "CFLAGS= -DBSD4 -DOSF -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \ - -DCK_CURSES -DCK_RTSCTS -DFNFLOAT -DOSF32 -DHDBUUCP $(KFLAGS)" - $(MAKE) CC=$(CC) CC2=$(CC2) ckuusx.$(EXT) \ - "CFLAGS= -DBSD4 -DOSF -D_BSD -DTCPSOCKET -DCK_ANSIC -DSIG_V \ - -DCK_CURSES -DCK_RTSCTS -DFNFLOAT -DOSF32 -DHDBUUCP $(KFLAGS)" - $(MAKE) CC=$(CC) CC2=$(CC2) osf \ - "KFLAGS= -DOSF32 -DHDBUUCP -O2 -Olimit 3200 $(KFLAGS)" - -dec-osf32: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) du32 \ - KTARGET=$${KTARGET:-$(@)} - -#Digital UNIX 4.0 through 4.0D (use tru64 targets for 4.0E and above)... -du40: - @echo Making C-Kermit $(CKVER) for Digital UNIX 4.0... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF40 -DHDBUUCP -DFNFLOAT \ - -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm" - -du40gcc: - @echo Making C-Kermit $(CKVER) for Digital UNIX 4.0 with gcc ... - $(MAKE) osf CC=gcc CC2=gcc KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF40 -DHDBUUCP $(KFLAGS)" - -#Tru64 Unix 4.0E -tru64-40e: - @echo Making C-Kermit $(CKVER) for Tru64 UNIX 4.0E... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF40 -DOSF40E -DTRU64 -DHDBUUCP -DFNFLOAT -DNOCOTFMC \ - -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm" - -tru64-40f: - @echo Making C-Kermit $(CKVER) for Tru64 UNIX 4.0F... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF40 -DOSF40F -DTRU64 -DHDBUUCP -DFNFLOAT -DNOCOTFMC \ - -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm" - -tru64-40g: - @echo Making C-Kermit $(CKVER) for Tru64 UNIX 4.0G... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF40 -DOSF40G -DTRU64 -DHDBUUCP -DFNFLOAT -DNOCOTFMC \ - -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" "LIBS=-lm" - -tru64-50a: - @echo Making C-Kermit $(CKVER) for Tru64 UNIX 5.0A... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DTRU64 -DOSF50 -DHDBUUCP \ - -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" - -tru64-51a: - @echo Making C-Kermit $(CKVER) for Tru64 UNIX 5.1A... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DTRU64 -DOSF50 -DOSF51A -DHDBUUCP \ - -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" - -tru64-51b: - @echo Making C-Kermit $(CKVER) for Tru64 UNIX 5.1A... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DTRU64 -DOSF50 -DOSF51A -DOSF51B -DHDBUUCP \ - -unsigned -std1 -O3 -Olimit 2400 $(KFLAGS)" - -du50: - $(MAKE) CC=$(CC) CC2=$(CC2) tru64-50a KTARGET=$${KTARGET:-$(@)} - -du40-ridiculous-checking: - @echo Making C-Kermit $(CKVER) for Digital UNIX 4.0. - @echo Checking everything - assumes DECC... - $(MAKE) CC=$(CC) CC2=$(CC2) osf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DOSF40 -DHDBUUCP -w0 -warnprotos -check -portable \ - -unsigned -std1 -O3 -Olimit 1760 $(KFLAGS)" - -#Sequent DYNIX/ptx 1.2.1 -dynixptx12: - @echo Making C-Kermit $(CKVER) for Sequent DYNIX/ptx 1.2.1... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DPTX -DNOGETUSERSHELL -DNOLEARN \ - -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t $(KFLAGS) -i -O" \ - "LNKFLAGS = -i" - -#Sequent DYNIX/ptx 1.3 or 1.4 -dynixptx13: - @echo Making C-Kermit $(CKVER) for Sequent DYNIX/ptx 1.3 TCP/IP... - $(MAKE) xermit "CFLAGS= -O KTARGET=$${KTARGET:-$(@)} \ - -DSVR3 -DDIRENT -DHDBUUCP -DPTX -DCK_POLL -DNOGETUSERSHELL \ - -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DTCPSOCKET $(KFLAGS) -i" \ - "LNKFLAGS = -i" "LIBS = -lsocket -linet -lnsl" - -#Sequent DYNIX/ptx 2.0, ANSI C compilation -#Should work on any hardware platform when DYNIX/ptx runs, including -#386, 486, Pentium. -dynixptx20: - @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.0...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DHDBUUCP -DTCPSOCKET \ - -DWAIT_T=int -DPTX -DNOGETUSERSHELL $(KFLAGS) -O" \ - "LIBS = -lsocket -linet -lnsl" - -#Sequent DYNIX/ptx 2.0, ANSI C compilation, with curses -dynixptx20c: - @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.0...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DHDBUUCP -DTCPSOCKET -DWAIT_T=int -DPTX -DCK_CURSES \ - -DCK_NEWTERM -DNOGETUSERSHELL $(KFLAGS) -O" \ - "LIBS = -lsocket -linet -lnsl -lcurses -ltermcap" - -#Sequent DYNIX/ptx 2.1.6, 80486, ANSI C compilation, with curses: -# -Xa -- use ANSI compiler. -# -Wc,-pw -- suppress portability warnings. -# -Wc,-i386 -- 80386 cpu. -# -Wc,-i486 -- 80486 cpu. -# -Wc,-P5 -- Pentium (default). -# -Wc,-O3 -- highest optimization. -# -Wa,-N17061 -- increase symbol table from default of 15013 for ckcuni.c. -# Early versions of DYNIX/ptx 2.1.x may need -DCK_POLL instead of -DSELECT. -# Add "$&" after the colon in the "xermit" target for parallel makes. -dynixptx216c: - @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.1.6' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DHDBUUCP -DDYNAMIC -DTCPSOCKET \ - -DSELECT -DCK_REDIR -DCK_NAWS -DCK_WREFRESH -DSW_ACC_ID \ - -DTCP_NODELAY=1 -DTRMBUFL=2048 -DBIGBUFOK -DHADDRLIST \ - -DPTX -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL -DNOREALPATH \ - $(KFLAGS) -Xa -Wc,-pw -Wc,-i486 -Wc,-O3 -Wa,-N17061" \ - "LIBS = -lXbsd -lseq -lsocket -linet -lnsl -lmalloc -lm -lcurses" \ - "LNKFLAGS = -s" - -#Sequent DYNIX/ptx 2.1.6, gcc 2.7.2.2, with curses: -dynixptx216cgcc: - @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 2.1.6 gcc' - $(MAKE) xermit "CC = gcc" "CC2 = gcc" KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DHDBUUCP -DDYNAMIC -DTCPSOCKET \ - -DSELECT -DCK_REDIR -DCK_NAWS -DCK_WREFRESH -DSW_ACC_ID \ - -DTCP_NODELAY=1 -DTRMBUFL=2048 -DBIGBUFOK -DHADDRLIST \ - -DPTX -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL -DNOREALPATH \ - $(KFLAGS) -O3 -pipe -funsigned-char" \ - "LIBS = -lXbsd -lseq -lsocket -linet -lnsl -lmalloc -lm -lcurses" \ - "LNKFLAGS = -s" - -#Sequent DYNIX/ptx 4.0, ANSI C compilation, with curses -dynixptx41c: - @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 4.0...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DHDBUUCP -DTCPSOCKET \ - -DWAIT_T=int -DPTX -DPTX4 -DCK_CURSES -DCK_NEWTERM \ - -DNOGETUSERSHELL $(KFLAGS) -O" \ - "LIBS = -lsocket -lnsl -lcurses -ltermcap" - -#Sequent DYNIX/ptx 4.4, ANSI C compilation, with curses -dynixptx44: - @echo 'Making C-Kermit $(CKVER) for POSIX, Sequent DYNIX/ptx 4.4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPTX -DPTX4 -DPOSIX -DHDBUUCP -DTCPSOCKET -DWAIT_T=int \ - -DCK_CURSES -DCK_NEWTERM -DBIGBUFOK -DSELECT -DNOGETUSERSHELL \ - $(KFLAGS) -O" "LIBS = -lsocket -lnsl -lcurses -ltermcap" - -#Sequent DYNIX 3.0.x -dynix3: - @echo Making C-Kermit $(CKVER) for Sequent DYNIX 3.0.x... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD43 -DACUCNTRL -DTCPSOCKET -O \ - -DPWUID_T=int -DGID_T=int $(KFLAGS)" - -#Sequent DYNIX 3.0.x, no ACUCNTRL -dynix3noacu: - @echo Making C-Kermit $(CKVER) for Sequent DYNIX 3.0.x... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD43 -DLCKDIR -DTCPSOCKET -O \ - -DUID_T=int -DGID_T=int $(KFLAGS)" - -#Sequent DYNIX 3.1.x -dynix31: - @echo Making C-Kermit $(CKVER) for Sequent DYNIX 3.1.x... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DDCLPOPEN -DLCKDIR -DBSD4 -DTCPSOCKET $(KFLAGS)" - -#Sequent DYNIX 3.1.2, as above but with curses, to be compiled by gcc 2.3.3. -dynix31c: - @echo 'Making C-Kermit $(CKVER) for Sequent DYNIX 3.1.2, curses...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O2 -DDCLPOPEN -DACUCNTRL \ - -DBSD43 -DTCPSOCKET -DCK_CURSES -DUID_T=int \ - $(KFLAGS)" "LIBS= -lcurses -ltermcap" - -#Convex C1 with Berkeley Unix -convex: - @echo Making C-Kermit $(CKVER) for Convex C1 / BSD... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD4 -DNOLEARN $(KFLAGS) -Dmsleep=mnap" - -#Convex C210 with Convex/OS 8 -convex8: - @echo Making C-Kermit $(CKVER) for Convex C210 with OS 8 - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DNODEBUG -DDIRENT -DNOFILEH \ - $(KFLAGS) -DSIG_V -Dmsleep=mnap" - -#Convex C2 with Convex OS 9.1 (should also work with 8.1 or later) -#with ANSI C compiler, uses BSD 4.3 uucp lockfile convention. -convex9: - @echo Making C-Kermit $(CKVER) for Convex C210 with OS 9.1 - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DCONVEX9 -DNOIEXTEN -DDIRENT -DNOFILEH -DTCPSOCKET \ - -D__STDC__ -DLCKDIR -Dmsleep=mnap -O -ext -tm c1 $(KFLAGS)" \ - "LNKFLAGS = -ext" - -#Convex C2 with Convex OS 10.1 or later -#with gcc 2.x C compiler -convex10gcc: - @echo Making C-Kermit $(CKVER) for Convex C2 with OS 10.1 using gcc - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DCONVEX9 -DNOIEXTEN -DDIRENT -DNOFILEH -DTCPSOCKET \ - -D__STDC__ -Dmsleep=mnap -O2 $(KFLAGS)" CC=gcc CC2=gcc - -#Cray X-MP or Y-MP UNICOS 6.x or 7.x. -#NOTE: NPROC tells how many parallel makes to run. If your Cray has multiple -#processors, you can set NPROC up to the number of CPUs, e.g. NPROC=16. -cray: - @echo 'Making C-Kermit $(CKVER) for Cray X/Y-MP UNICOS 6.x or 7.0... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS) -O1" - -#Cray X-MP or Y-MP UNICOS 8.0 Alpha. -cray8: - @echo 'Making C-Kermit $(CKVER) for Cray X/Y-MP UNICOS 8.0 Alpha... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \ - "CFLAGS= -DSVR4 -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS) -O1" - -#Cray X-MP or Y-MP UNICOS 9.0. -#This one was executed successfully for C-Kermit 8.0.209. -#Earlier versions of Unicos will probably need the same flags. -cray9: - @echo 'Making C-Kermit $(CKVER) for Cray X/Y-MP UNICOS 9.0... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \ - "CFLAGS= -DSVR4 -DDIRENT -DHDBUUCP -DNOLFDEVNO \ - -DTCPSOCKET $(KFLAGS) -O1" - -#Cray-2 or Cray 3-CSOS -#NOTE: NPROC tells how many parallel makes to run. If your Cray has multiple -#processors, you can set NPROC up to the number of CPUs, e.g. NPROC=16. -craycsos: - @echo 'Making C-Kermit $(CKVER) for Cray-2/3 CSOS - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} NPROC=1 \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET \ - $(KFLAGS) -DCK_ANSIC -DCK_CURSES" "LIBS=-lnet" - -#NeXTSTEP 1.0 through 3.2. -#Includes fullscreen file transfer display (curses) and TCP/IP support. -#Uses shared library to make executable program about 80K smaller. -#Remove "LIBS = -lsys_s" if this causes trouble. -next: - @echo Making C-Kermit $(CKVER) for NeXTSTEP... - @echo 'If you get errors in ckutio.c about w_S, w_T, etc,' - @echo 'add KFGLAGS=-DNOREDIRECT to your make command.' - $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DNEXT -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \ - -pipe -DCK_CURSES $(KFLAGS) -O -w" "LIBS = -lsys_s -lcurses -ltermcap" - -nextc: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \ - KTARGET=$${KTARGET:-$(@)} - -nextg: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \ - KFLAGS=-Wall KTARGET=$${KTARGET:-$(@)} - -nextgc: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \ - KFLAGS=-Wall KTARGET=$${KTARGET:-$(@)} - -#NeXTSTEP 3.3. -#Includes fullscreen file transfer display and TCP/IP. -next33: - @echo Making C-Kermit $(CKVER) for NeXTSTEP 3.3... - $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DNEXT33 -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \ - -pipe -DCK_CURSES $(KFLAGS) -O -w" "LIBS = -lsys_s -lcurses -ltermcap" - -#OPENSTEP 4.2 for Sparc, m680x0, HP PA-RISC, and Intel. -#Includes fullscreen file transfer display and TCP/IP. -#ckcpro.c compiled without optimization because it crashes the compiler. -openstep42: - @echo Making C-Kermit $(CKVER) for OPENSTEP 4.2... - $(MAKE) ckcpro.$(EXT) \ - "CFLAGS= -DOPENSTEP42 -DNEXT33 -DTCPSOCKET -DLCKDIR -DNOPUTENV \ - -DFNFLOAT -pipe -DCK_CURSES $(KFLAGS) -w" - $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DOPENSTEP42 -DNEXT33 -DTCPSOCKET -DLCKDIR -DNOPUTENV \ - -DFNFLOAT -pipe -DCK_CURSES $(KFLAGS) -O -w" \ - "LIBS = -lsys_s -lcurses -ltermcap" - -#NeXT with malloc debugger -nextmd: - @echo Making C-Kermit $(CKVER) for NeXT with malloc debugging... - $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DNEXT -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \ - -DCK_CURSES $(KFLAGS) -O -w -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG" \ - "LIBS = -lsys_s -lcurses -ltermcap" - -#Build for NeXTSTEP with "fat" binaries (MABs) that run on both Motorola -#and Intel platforms. -nextfat: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) \ - next KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-Wall -arch m68k -arch i386" "LNKFLAGS = -arch m68k -arch i386" - -#NeXTSTEP on Intel Platforms. -next486: - @echo Making C-Kermit $(CKVER) for NeXTSTEP on Intel Platforms... - @echo 'If you get errors in ckutio.c about w_S, w_T, etc,' - @echo 'add KFGLAGS=D-DNOREDIRECT to your make command.' - $(MAKE) xermit CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DNEXT -DTCPSOCKET -DLCKDIR -DNOPUTENV -DFNFLOAT \ - -DNODEBUG -O3 -fno-omit-frame-pointer -fschedule-insns2 -pipe \ - -DCK_CURSES $(KFLAGS) -w" "LIBS = -lsys_s -lcurses -ltermcap" - -#Single binary that runs on NeXT 68030 and 68040, Intel, HP, and Sparc, -#as well as on OpenStep/Mach. -nextquadfat: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) next \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-Wall -arch m68k -arch i386 -arch hppa -arch sparc" \ - "LNKFLAGS = -arch m68k -arch i386 -arch hppa -arch sparc" - -#BeBox -beboxdr7: - @echo 'Making C-Kermit $(CKVER) for the BeBox...' - @echo 'Link step will fail with default Metroworks linker 64K limit.' - @echo 'Code Warrior Gold required to link big programs.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CC=/boot/develop/tools/mwcc" "CC2=/boot/develop/tools/mwld" \ - "CFLAGS= -DBEBOX -DBE_DR_7 -DPOSIX -DNOUUCP -DNOLEARN $(KFLAGS) -O" - -#BeBox BeOS DR7 only -bebox: - @echo 'Making C-Kermit $(CKVER) for BeBox...' - @echo 'Link step will fail with default Metroworks linker 64K limit.' - @echo 'Code Warrior Pro 3.0 for BeBox required to link big programs.' - $(MAKE) wermit "CC=mwcc" "CC2=mwld" KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBEBOX -DPOSIX -DNOLEARN -DNOUUCP $(KFLAGS) -O" - -#BeOS 4.5 -#We have to use the wermit target because 'fd_set' is unknown. -beos45: - $(MAKE) wermit "CC=$(CC)" "CC2=$(CC2)" KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBEOS -DBEOS45 -DPOSIX -DNOIKSD -DNOREALPATH -DSYSTIMEH \ - -DNOCOTFMC -DNOUUCP -DNOLEARN $(KFLAGS) -O" \ - "LIBS = $(LIBS)" - -#BeOS 4.5 -beos45net: - $(MAKE) CC=$(CC) CC2=$(CC2) beos45 \ - "KFLAGS=-DTCPSOCKET -DNO_DNS_SRV $(KFLAGS)" "LIBS=-lnet -lnetapi" - -#Plan 9 from Bell Labs -plan9: - @echo 'C-Kermit for Plan 9 from Bell Labs - calling ckpker.mk...' - make -f ckpker.mk - -#POSIX -posix: - @echo 'Making C-Kermit $(CKVER) for pure POSIX...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DPOSIX -DNOUUCP -DNOLEARN $(KFLAGS) -O" - -# PowerMAX OS (SVR4) from Concurrent (tested on PowerMAX 5.1) -powermax: - @echo 'Making C-Kermit $(CKVER) for Concurrent PowerMAX OS...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DPOWERMAX \ - -DNETPTY -DHAVE_STREAMS -DHAVE_GRANTPT -DHAVE_PTSNAME -DPUSH_PTEM \ - -DPUSH_LDTERM -DPUSH_TTCOMPAT \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lresolv -lcurses -lgen -lc -lucbc" - -#Berkeley Software Design Inc. BSDI -# Substitute "LIBS= -lnewcurses -ltermcap" if desired. -bsdi: - @echo 'Making C-Kermit $(CKVER) for BSDI ...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD44 -DSETREUID -DSW_ACC_ID -DBIGBUFOK -DFIXCRTSCTS \ - -DTCPSOCKET -DCK_CURSES -DFNFLOAT $(KFLAGS) -O" \ - "LIBS= -lcurses -ltermcap -lm" - -#Berkeley Software Design Inc. BSDI - has higher serial speeds than 1.x. -bsdi2: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DBSDI2 $(KFLAGS)" - -bsdi3: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DBSDI2 -DBSDI3 $(KFLAGS)" - -bsdi4: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DBSDI2 -DBSDI3 -DBSDI4 -DTPUTSFNTYPE=void -DTPUTSISVOID \ - -m486 $(KFLAGS)" - -# (old name for the above) -bsdiposix: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi - - -#Build a BSDI 4.x binary that also runs under FreeBSD (Terry Kennedy). -#But watch out for details like serial-port locking. -bsdix: - $(MAKE) "MAKE=$(MAKE)" CC=$(CC) CC2=$(CC2) bsdi \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DBSDI2 -DBSDI3 -DBSDI4 -DTPUTSFNTYPE=void -DTPUTSISVOID \ - -m486 $(KFLAGS)" "LNKFLAGS=-static -Wl,-m,i386bsdi -Wl,-e,_start" - -#Pyramid 9XXX (e.g. 9845) or MIServer T series, OSx 4.4b thru 5.1 -pyramid: - @echo Making C-Kermit $(CKVER) for Pyramid Dual Port OSx - ucb $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD43 -DTCPSOCKET -DPYRAMID -O $(KFLAGS)" "LNKFLAGS = -s" - -#Pyramid Dual Port OSx using HoneyDanBer UUCP, curses and TCP -pyramid-hdb: - @echo Making C-Kermit $(CKVER) for Pyramid Dual Port OSx - ucb $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DBSD43 -DTCPSOCKET -DHBDUUCP -DCK_CURSES -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS = -lcurses -ltermcap" - -#Pyramid DC/OSx (UNIX System V R4). -#Has , regular Berkeley sockets library, i.e. in.h and inet.h -#are not misplaced in sys (rather than netinet and arpa, respectively). -#Uses ANSI C. -#NOTE: Remove -O and Olimit:2500 from CFLAGS if TELNET connections do not work. -pyrdcosx: - @echo 'Making C-Kermit $(CKVER) for Pyramid DC/OSx...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -Xa -O -DSVR4 -DDIRENT -DHDBUUCP -DSELECT -DNOGETUSERSHELL \ - -DCK_CURSES -DSTERMIOX -DTCPSOCKET -DPYRAMID -K Olimit:3100 \ - -DNO_DNS_SRV $(KFLAGS)" "LIBS= -lcurses -lsocket -lnsl" "LNKFLAGS = -s" - -#IBM's AIX 3.0 on IBM 370 mainframe, tested on AIX F44 thru F50. -aix370: - @echo Making C-Kermit $(CKVER) for IBM System/370 AIX 3.0... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIX370 -DTCPSOCKET -DLCKDIR -DDIRENT $(KFLAGS)" \ - "LIBS = -lbsd" - -#IBM's AIX/ESA 2.1 (OSF/1) on IBM mainframe -aixesa: - @echo Making C-Kermit $(CKVER) for IBM AIX/ESA... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXESA -DTCPSOCKET $(KFLAGS) -O" - -#IBM PS/2 with AIX 1.0 thru 1.3. -# Reports indicate that -O switch must be omitted. -# It is also possible that "make bsd" will work (reports welcome). -# One report said "make LIBS=-lbsd bsd" did the trick. -# NOTLOG is to get around a 'tlog' symbol defined in one of the headers. -ps2aix: - @echo 'Making C-Kermit $(CKVER) for IBM AIX 1.x PS/2...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DNOREALPATH -DPS2AIX10 -DSIG_V \ - -DNOUNICODE -DNOTLOG -DNOLEARN $(KFLAGS) -i" \ - "LNKFLAGS = -i" - -ps2aixnetc: - @echo 'Making C-Kermit $(CKVER) for IBM AIX 1.x PS/2...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DNOREALPATH -DPS2AIX10 -DTCPSOCKET -DCK_CURSES \ - -DSIG_V -DNOUNICODE -DNOTLOG -DNOLEARN $(KFLAGS) -i" \ - "LIBS = -lcurses" "LNKFLAGS = -i" - -ps2aix3: - $(MAKE) ps2aix KTARGET=$${KTARGET:-$(@)} - -#IBM RT PC with AIX 2.2.1, valid as of C-Kermit 8.0. -#NOTLOG because of a conflict in . -#This one has unique and strange lockfiles. -# -O removed on purpose (8.0). -# In case of "compiler error: symbol table full", increase the -Nn number. -# In case of "compiler error: Constant pool too big", boost the -Np number. -# Add -DNOPUTENV if putenv() causes trouble. -# Put -DNOIKSD back if IKSD-related problems occur. -rtaix: - @echo 'Making C-Kermit $(CKVER) for IBM RT PC, AIX 2.2.1...' - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS = -DATTSV -DRTAIX -DHDBUUCP -DDIRENT -DNOTLOG -DTCPSOCKET \ - -DNOGETUSERSHELL -DCLSOPN -DNOREALPATH -DNOUNICODE -DBSD_INCLUDES \ - -DUSE_LSTAT -DFNFLOAT -Nn2500 -Np1000 -Wq,-SJ2 -a -w $(KFLAGS)" \ - "LIBS = -lm $(LIBS)" "LNKFLAGS = -s" - -#IBM RT PC with AIX 2.2.1 + curses -rtaixc: - $(MAKE) rtaix CC=$(CC) CC2=$(CC2) "KFLAGS=-DCK_CURSES" "LIBS=-lcurses" - -#IBM RT PC with AIX (ACIS) 2.2.1 (BSD 4.3) -# Add -O, -DDYNAMIC, -s, etc, if they work. -rtacis: - @echo Making C-Kermit $(CKVER) for RT PC with ACIS 2.2.1 = BSD 4.3... - $(MAKE) xermit KTARGET=$${KTARGET-$(@)} \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DNOREALPATH -DNOIKSD -DNOPUTENV \ - $(KFLAGS) -U__STDC__" "LNKFLAGS = -s" - -#IBM AIX 3.0, 3.1, or 3.2 for RISC System/6000. -rs6000: - @echo Making C-Kermit $(CKVER) for IBM AIX 3.0 or 3.1, RS/6000... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR3 -DDIRENT -DCK_ANSIC \ - -DCK_POLL -DCLSOPN -DSELECT_H -DNOTTYLOCK -O $(KFLAGS)" \ - "LNKFLAGS = -s" - -#IBM AIX 3.0, 3.1, or 3.2 for RISC System/6000, with curses. -rs6000c: - @echo Making C-Kermit $(CKVER) for IBM AIX 3.0 or 3.1, RS/6000... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR3 -DDIRENT -DCK_ANSIC \ - -DCK_POLL -DCLSOPN -DCK_CURSES -DSELECT_H -DNOTTYLOCK -DNOREALPATH \ - -O $(KFLAGS)" "LIBS= -lcurses -ltermcap" "LNKFLAGS = -s" - -aix30: - $(MAKE) rs6000 CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} - -aix31: - $(MAKE) rs6000 CC=$(CC) CC2=$(CC2) KTARGET=$${KTARGET:-$(@)} - -#IBM AIX 3.2 for RISC System/6000. -#In case of "subprogram too complex" warnings, add "-qmaxmem=16000" to CFLAGS. -rs6aix32: - @echo Making C-Kermit $(CKVER) for IBM AIX 3.2, RS/6000... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR4 -DDIRENT -DCK_ANSIC -DNOREALPATH \ - -DSELECT_H -DCLSOPN -DNOTTYLOCK -O $(KFLAGS)" "LNKFLAGS = -s" - -#IBM AIX 3.2 for RISC System/6000. -rs6aix32c: - @echo Making C-Kermit $(CKVER) for IBM AIX 3.2, RS/6000, TCP+curses... - @echo In case of Subprogram Too Complex warnings, - @echo add -qmaxmem=16000 to CFLAGS. - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DTCPSOCKET -DSVR4 -DDIRENT -DCK_ANSIC -DNOREALPATH \ - -DCLSOPN -DCK_CURSES -DSELECT_H -DNOTTYLOCK -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS=-lcurses" - -aix32: - $(MAKE) rs6aix32c KTARGET=$${KTARGET:-$(@)} - -#IBM AIX 4.1, 4.1.x on RISC System/6000 or Power Series. -#Generates common binary for all platforms if using xlc (IBM C compiler). -#When using gcc, add -mcpu=common to generate common binary. -#Note that this one needs CK_NEWTERM. -# Add -bbigtoc in case ld fails with TOC overflow. -aix41: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \ - -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DNOGETUSERSHELL -qmaxmem=16000 -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS=-lcurses" - -#Ditto but with gcc. -#Remove "CC=gcc CC2=gcc" if you have gcc installed as cc. -aix41g: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC=gcc" "CC2=gcc" \ - "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \ - -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DNOGETUSERSHELL -O $(KFLAGS)" \ - "LNKFLAGS = -s -Xlinker -bbigtoc" "LIBS=-lcurses" - -# Add -bbigtoc in case ld fails with TOC overflow. -aix41+krb5+krb4: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \ - -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_DES $(K5INC) $(K5INC)/krb5 \ - -DNOGETUSERSHELL -qmaxmem=16000 -O $(KFLAGS)" \ - "LNKFLAGS = -s" \ - "LIBS = $(K5LIB) -lcurses -lkrb4 -ldes425 -lkrb5 \ - -lcom_err -lk5crypto -lgssapi_krb5" - -#Old name for "aix41". -rs6aix41c: - $(MAKE) aix41 KTARGET=$${KTARGET:-$(@)} - -#IBM AIX 4.1, 4.1.x, or 4.2 on RISC System/6000 or Power Series, -# with X.25 support -#Generates common binary for all platforms if using xlc (IBM C compiler). -#When using gcc, add -mcpu=common to generate common binary. -# Add -bbigtoc in case ld fails with TOC overflow. -aix41x25: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \ - -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DIBMX25 -DDEBUG -DNOGETUSERSHELL -qmaxmem=16000 -g $(KFLAGS)" \ - "LNKFLAGS = -g -bI:/lib/pse.exp" "LIBS=-lcurses -lodm -lcfg" - -@echo "]0;kermit done\c" - -#As above but without -g in LNKFLAGS. -# Add -bbigtoc in case ld fails with TOC overflow. -aix41x25o: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.1.1 RS/6000 or PowerPC... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DAIX41 -DSVR4 -DSTERMIOX -DTCPSOCKET -DDIRENT \ - -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DIBMX25 -DNODEBUG -DNOGETUSERSHELL -qmaxmem=16000 $(KFLAGS)" \ - "LNKFLAGS = -bI:/lib/pse.exp" "LIBS=-lcurses -lodm -lcfg" - -@echo "]0;kermit done\c" - -#AIX 4.2 -- Must have CK_NEWTERM or echoing is lost after curses. -# Add -bbigtoc in case ld fails with TOC overflow. -aix42: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.2 or higher... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DAIX41 -DAIX42 -DSVR4 -DSTERMIOX -DTCPSOCKET \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DCK_NEWTERM -DFNFLOAT \ - -DSELECT -DSELECT_H -DNOGETUSERSHELL -qmaxmem=16000 -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS=-lcurses -lm" - -#AIX 4.3 -- Must NOT have CK_NEWTERM or else C-Kermit hangs after curses. -# -bbigtoc needed on some systems but not others to avoid TOC overflow. -# "man ld" says -bbigtoc makes program run slower. -aix43: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DAIX41 -DAIX43 -DSVR4 -DSTERMIOX -DTCPSOCKET \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DFNFLOAT -DNOGETUSERSHELL -qmaxmem=16000 -bbigtoc -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS=-lcurses -lm" - -#AIX 4.3 with IBM X.25. -aix43x25: - @echo "Making C-Kermit $(CKVER) for IBM AIX 4.3 with X.25..." - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DAIXRS -DAIX41 -DAIX43 -DSVR4 -DSTERMIOX -DTCPSOCKET \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DFNFLOAT -DNOGETUSERSHELL -DIBMX25 \ - -qmaxmem=16000 -bbigtoc -O $(KFLAGS)" \ - "LNKFLAGS = -bI:/lib/pse.exp" "LIBS=-lcurses -lodm -lcfg -lm" - -#AIX 4.3 -- Must NOT have CK_NEWTERM or else C-Kermit hangs after curses. -# -mminimal-toc needed on some systems but not others to avoid TOC overflow. -# "man ld" says -bbigtoc makes program run slower. -aix43g: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \ - "LIBS=-lcurses -lm" - -aix43gcc: - $(MAKE) aix43g - -# None of the following aix43gcc attempts work on a gcc-only AIX 4.3.3 box. -# It just plain can't find the math routines (fmod, pow, exp, sqrt, log10,...) -# Which is odd because nm /usr/lib/libC.a finds them... - -#in case aix43gcc can't find its math library... -aix43gccx: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \ - "LIBS= -L/usr/local/lib/gcc-lib/powerpc-ibm-aix4.3.1.0/2.95.2 \ - -lcurses -bloadmap -bnoquiet" - -#in case aix43gccx can't find its math library... -aix43gccy: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \ - "LIBS= -lcurses -bloadmap -bnoquiet" - -#in case aix43gccx can't find its math library... -aix43gccz: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 gcc... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL $(KFLAGS)" \ - "LIBS= -L. -lcurses -bloadmap -bnoquiet" - - -#AIX 4.3 with MIT Kerberos 5 and Kerberos 4 compatibility mode -# Must NOT have CK_NEWTERM or else C-Kermit hangs after curses. -# -mminimal-toc needed on some systems but not others to avoid TOC overflow. -# "man ld" says -bbigtoc makes program run slower. -aix43gcc+krb5+krb4: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher w/Kerberos... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_DES -funsigned-char $(K5INC) $(K5INC)/krb5 \ - $(KFLAGS)" \ - "LIBS=$(K5LIB) -lcurses -lm -lkrb4 -ldes425 -lkrb5 \ - -lcom_err -lk5crypto -lcrypt -lgssapi_krb5" - -#AIX 4.3 with MIT Kerberos 5, Kerberos 4 compatibility mode and OpenSSL -# Must NOT have CK_NEWTERM or else C-Kermit hangs after curses. -# -mminimal-toc needed on some systems but not others to avoid TOC overflow. -# "man ld" says -bbigtoc makes program run slower. -aix43gcc+krb5+krb4+openssl: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher w/Kerberos... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_DES -DCK_CAST -DLIBDES -DCK_SSL \ - -funsigned-char $(K5INC) $(K5INC)/krb5 $(SSLINC) $(KFLAGS)" \ - "LIBS=$(K5LIB) $(SSLLIB) -lssl -lcrypto \ - -lcurses -lm -lkrb4 -ldes425 -lkrb5 -lcom_err -lk5crypto -lcrypt \ - -lgssapi_krb5" - -aix43gcc+openssl: - @echo Making C-Kermit $(CKVER) for IBM AIX 4.3 or higher w/OpenSSL... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS= -mminimal-toc -g -O -DAIXRS -DAIX41 -DAIX43 -DSVR4 \ - -DDIRENT -DCK_ANSIC -DCLSOPN -DCK_CURSES -DSELECT -DSELECT_H \ - -DSTERMIOX -DTCPSOCKET -DFNFLOAT -DNOGETUSERSHELL \ - -DCK_AUTHENTICATION -DCK_SSL -funsigned-char $(SSLINC) $(KFLAGS)" \ - "LIBS=$(SSLLIB) -lssl -lcrypto -lcurses -lm -lcrypt" - -aix44: - $(MAKE) aix42 "KFLAGS=-DAIX44 -qmaxmem=20000 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix45: - $(MAKE) aix42 "KFLAGS=-DAIX45 -qmaxmem=20000 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix50: - $(MAKE) aix42 "KFLAGS=-DAIX50 -qmaxmem=20000 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix51: - $(MAKE) aix42 "KFLAGS=-DAIX51 -qmaxmem=20000 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix52: - $(MAKE) aix42 "KFLAGS=-DAIX52 -qmaxmem=20000 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix53: - $(MAKE) aix42 "KFLAGS=-DAIX53 -qmaxmem=20000 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix44gcc: - $(MAKE) aix43g "KFLAGS=-DAIX44 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix45gcc: - $(MAKE) aix43g "KFLAGS=-DAIX45 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix50gcc: - $(MAKE) aix43g "KFLAGS=-DAIX50 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix51gcc: - $(MAKE) aix43g "KFLAGS=-DAIX51 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix52gcc: - $(MAKE) aix43g "KFLAGS=-DAIX52 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -aix53gcc: - $(MAKE) aix43g "KFLAGS=-DAIX53 $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} - -#Bull DPX/2 with BOS/X, like AIX/RS6000 -bulldpx2: - @echo Making C-Kermit $(CKVER) for Bull DPX/2 with BOS/X... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSVR3 -DDIRENT -DCK_ANSIC -DCKTYP_H= \ - -DCK_POLL -DNOGETUSERSHELL -DCLSOPN -DNOLEARN -O $(KFLAGS)" \ - "LNKFLAGS = -s" - -#Sun UNIX 3.5 with gcc 2.3.3. -sunos3gcc: - @echo Making C-Kermit $(CKVER) for Sun UNIX 3.5 and gcc... - $(MAKE) xermit CC=gcc CC2=gcc KTARGET=$${KTARGET:-$(@)} \ - CFLAGS="-g -O -DBSD4 -DTCPSOCKET $(KFLAGS)" - -#SunOS version 4.0, BSD environment, has saved original euid feature. -# Add "CC=/usr/ucb/cc CC2=/usr/ucb/cc" if necessary. -# Note: Including Unicode crashes the assembler in ckcuni.c. -sunos4: - @echo Making C-Kermit $(CKVER) for SunOS 4.0, BSD environment... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DSUNOS4 -DFNFLOAT -DNOUNICODE $(KFLAGS)" \ - "LIBS=-lm" - -#As above, but with SunLink X.25 support -sunos4x25: - @echo SunLink X.25 support - $(MAKE) "MAKE=$(MAKE)" sunos4 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DFNFLOAT -DSUNX25" \ - "LIBS=-lm" - -#SUN OS version 4.1 - 4.1.3, BSD environment, has saved original euid feature. -#Uses Honey DanBer UUCP. Requires presence of /usr/spool/locks directory. -# /var/spool/ should be a symbolic link to /usr/spool/. -# ... or 'make xermit "CC= /usr/ucb/cc " \' -# Note: "xermit" means use the select() version of the CONNECT module. -sunos41: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 / BSD... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNOUNICODE $(KFLAGS)" \ - "LIBS= $(LIBS) -lresolv -lm" - -#As above, but compiled with gcc. Gives 24-32K size reduction -#with gcc 2.1 or 2.2.2. CAUTION: make sure "fixincludes" has been run on -#the include files, so gcc's are in sync with the regular Sun ones! -#This includes the curses library for fullscreen file transfer display. -#NDGPWNAM needed for GCC 2.5.6, not needed for 2.4.0, but it's uncertain -#whether it will do any harm for 2.4.0 compilation -- if so, remove it. -sunos41gcc: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -funsigned-char $(KFLAGS)" "LIBS= -lcurses -ltermcap -lresolv -lm" - -# As above, but without -funsigned-char so I can see the warnings that -# everybody else will get when they use ANSI compilers that don't have this -# option (gsc = gcc signed char). -sunos41gsc: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - $(KFLAGS)" "LIBS= -lcurses -ltermcap -lresolv -lm" - -#As above but with ckucon.c rather than ckucns.c (for testing only) -sunos41gccfork: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -DNOLEARN -funsigned-char $(KFLAGS)" \ - "LIBS= -lcurses -ltermcap -lresolv -lm" - -#as above but configured for Kerberos IV -sunos41gcc+krb4: - @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, krb4... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -DTCPSOCKET -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 \ - -DCK_ENCRYPTION -DCK_DES -DCK_CAST -DBIGBUFOK -funsigned-char \ - $(K4INC) $(KFLAGS)" \ - "LIBS= $(K4LIB) -lcurses -ltermcap -lresolv -lm -lkrb -ldes" - -#as above but configured for SSL/TLS -sunos41gcc+openssl: - @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, ssl... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -DCK_AUTHENTICATION -funsigned-char \ - -DCK_SSL -DTCPSOCKET -DBIGBUFOK $(SSLINC) $(KFLAGS)" \ - "LIBS= $(SSLLIB) -lcurses -ltermcap -lresolv -lm -lssl -lcrypto" - -#as above but configured for Kerberos IV and SSL/TLS -sunos41gcc+krb4+openssl: - @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, krb4... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION -DCK_DES \ - -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \ - $(K4INC) $(SSLINC) $(KFLAGS)" \ - "LIBS= $(K4LIB) $(SSLLIB) \ - -lcurses -ltermcap -lresolv -lm -lkrb -lssl -lcrypto" - -#as above but configured for Kerberos IV and ZLIB enabled SSL/TLS -sunos41gcc+krb4+openssl+zlib: - @echo Making C-Kermit $(CKVER) for SunOS 4.1, gcc, curses, krb4... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION -DCK_DES \ - -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \ - -DZLIB $(K4INC) $(SSLINC) \ - $(KFLAGS)" \ - "LIBS= $(K4LIB) $(SSLLIB) \ - -lcurses -ltermcap -lresolv -lm -lkrb -lssl -lcrypto -lz" - -#as above but configured for Kerberos IV and SRP and ZLIB enabled SSL/TLS -sunos41gcc+krb4+srp+openssl+zlib: - @echo "C-Kermit $(CKVER) SunOS 4.1: gcc,curses,krb4,srp,ssl,zlib..." - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION -DCK_DES \ - -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \ - -DZLIB -DCK_SRP $(K4INC) $(SRPINC) $(SSLINC) $(KFLAGS)" \ - "LIBS= $(K4LIB) $(SRPLIB) $(SSLLIB) \ - -lcurses -ltermcap -lresolv -lm -lkrb -lkrypto \ - -lsrp -lssl -lcrypto -lz" - -#as above but configured for Kerberos IV and SRP and ZLIB enabled SSL/TLS -sunos41gcc+srp+openssl+zlib: - @echo "C-Kermit $(CKVER) SunOS 4.1: gcc,curses,srp,ssl,zlib..." - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNDGPWNAM -DCK_CURSES -DFNFLOAT \ - -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_DES \ - -DCK_CAST -DCK_SSL -DLIBDES -DTCPSOCKET -DBIGBUFOK -funsigned-char \ - -DZLIB -DCK_SRP $(SRPINC) $(SSLINC) \ - $(KFLAGS)" \ - "LIBS= $(SRPLIB) $(SSLLIB) \ - -lcurses -ltermcap -lresolv -lm -lkrypto -lsrp -lssl -lcrypto -lz " - -#SUNOS 4.1 as sunos41 above, but also with curses support -sunos41c: - @echo Curses support - $(MAKE) "MAKE=$(MAKE)" sunos41 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DCK_CURSES -DFNFLOAT " \ - "LIBS= -lcurses -ltermcap" - -#As SunOS 4.1.x, gcc, configured as Internet Kermit Server. -# . NOLOCAL removes capability to make connections -# . TNCODE allows server-side Telnet negotiation. -# . used to include -lpwent, why? -# . used to include -L/usr/local/lib -lm, why? -sunos41giks: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc for IKS... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc" "CC2= gcc" \ - "CFLAGS= -O -DSUNOS41 -DNDGPWNAM -DFNFLOAT \ - -DNOLOCAL -DTCPSOCKET -DTNCODE -DNOPUSH $(KFLAGS)" \ - "LIBS= -lm -lresolv" - -#SUNOS 4.1 with SunLink X.25 support -sunos41x25: - @echo SunLink X.25 support - $(MAKE) "MAKE=$(MAKE)" wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNOUNICODE -DFNFLOAT -DSUNX25 \ - -DNOLEARN $(KFLAGS)" "LIBS= $(LIBS) -lresolv -lm" - -#SUNOS 4.1 with SunLink X.25 support and curses -sunos41x25c: - @echo SunLink X.25 support + curses - $(MAKE) "MAKE=$(MAKE)" wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DNOUNICODE -DFNFLOAT -DSUNX25 \ - -DCK_CURSES -DNOLEARN $(KFLAGS)" \ - "LIBS= $(LIBS) -lcurses -ltermcap -lresolv -lm" - -#SUN with Solaris 2.0 = SunOS 5.0. -#Mostly the same as System V R4. Don't use this with later Solaris versions. -solaris20: - @echo 'Making C-Kermit $(CKVER) for Sun with Solaris 2.0 and curses...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DSOLARIS -DDIRENT -DHDBUUCP -DSTERMIOX \ - -DTCPSOCKET -DCK_CURSES -DFNFLOAT -DCK_POLL $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermlib -lm" "LNKFLAGS = -s" - -#SUN with Solaris 2.0. -#As above, but built with the gcc compiler from the Cygnus CD-ROM. -solaris20g: - @echo 'Making C-Kermit $(CKVER) for Sun Solaris 2.0, gcc, and curses..' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DSOLARIS -DDIRENT -DHDBUUCP -DSTERMIOX \ - -DTCPSOCKET -DCK_CURSES -DCK_POLL -DFNFLOAT $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermlib -lm" "LNKFLAGS = -s" \ - CC=/opt/cygnus-sol2-1.1/bin/gcc CC2=/opt/cygnus-sol2-1.1/bin/gcc - -#SunOS 5.1 = Solaris 2.1. -#NOTE: A C compiler is no longer bundled with SunOS 5.1, so to compile C -#programs, you might have to change your PATH to include the directory -#/usr/ccs/bin AFTER the directory containing the compiler. SunPRO C is -#installed by default in /opt/SUNWspro/bin. So a sample PATH might be: -# -# /usr/local/bin:/usr/bin:/opt/SUNWspro/bin:/usr/ccs/bin:\ -# /usr/ucb:/usr/sbin:/sbin:. -# -# or: -# -# /usr/openwin/bin:/export/home/SUNWspro/bin:/usr/ccs/bin:/usr/sbin:/usr/bin. -# -#NOTE 2: Compilation with the Apogee C compiler (apcc) might not work, -#because it refuses to allow "-Usun". Reportedly, newer releases of apcc -#(such as 1.2.17) work OK, use: "make -e sunos51 CC=apcc CC2=apcc". -solaris21: - @echo 'Making C-Kermit $(CKVER) for SunOS 5.x....' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -Usun -DSVR4 -DSOLARIS -DDIRENT -DHDBUUCP -DFNFLOAT \ - -DSELECT -DNODEBUG -DSTERMIOX $(KFLAGS)" "LIBS = -lm" "LNKFLAGS = -s" - -#C-Kermit for Solaris 2.0-2.4 compiled with gcc, includes curses and TCP/IP. -#Change -O2 to -O if -O2 gives trouble. -#Remove -Usun if it causes trouble. -#Your PATH should start with something like: -# /usr/local/gnu/bin:/usr/ccs/bin: -#Produces a huge executable -- strip with /usr/ccs/bin/strip (not Gnu strip). -#Also don't add "LNKFLAGS = -s" -- strip manually instead. -#Also note: this can NOT be linked statically - Sun makes it impossible. -#And for Solaris 2.4, you might have to replace: -# /usr/local/lib/gcc-lib/i486-sun-solaris2/2.4.5/include/sys/stat.h -#with /usr/include/sys/stat.h. -solaris2xg: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with GNU cc...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv $(LIBS)" - -#ditto but no curses. -solaris2xgnc: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with GNU cc...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lm -lresolv $(LIBS)" - -#and with Kerberos IV -solaris2xg+krb4: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with GNU cc, krb4...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 -DCK_ENCRYPTION \ - -DCK_DES -DCK_CAST -DBIGBUFOK $(K4INC) $(KFLAGS)" \ - "LIBS= $(K4LIB) -ltermlib -lsocket -lnsl -lm -lresolv -lkrb -ldes \ - $(LIBS)" - -#and with OpenSSL,ZLIB,PAM,SHADOW -solaris2xg+openssl+zlib+pam+shadow: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \ - -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DCK_SHADOW -DZLIB \ - -DBIGBUFOK $(SSLINC) $(KFLAGS)" \ - "LIBS= $(SSLLIB) -ltermlib \ - -lsocket -lnsl -lm -lresolv -lssl -lcrypto -lpam -lz" - -#Ditto but with GCC 3.1 in which you have to specify 32-bit with -m32. -#In Solaris 9 (and maybe 8) you'll also need specifiy the Library path. -#Reportedly this can't be done here, but only with: -# crle -l /usr/lib:/usr/local/ssl/lib -#prior to building. Note: 64-bit not tested with SSL. -#For no-crypto 64-bit builds see the solaris9g64 target. -solaris2xg32+openssl+zlib+pam+shadow: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC="gcc -m32" CC2="gcc -m32" \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \ - -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DCK_SHADOW -DZLIB \ - -DBIGBUFOK $(SSLINC) $(KFLAGS)" \ - "LIBS= $(SSLLIB) -ltermlib \ - -lsocket -lnsl -lm -lresolv -lssl -lcrypto -lpam -lz" - -#and with Krb5,Krb4,OpenSSL,SHADOW -solaris2xg+krb5+krb4+openssl+shadow: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc,k5,k4,ssl...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS = -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_SSL -DCK_DES -DCK_CAST -DBIGBUFOK \ - $(K5INC) $(K5INC)/krb5 $(SSLINC) $(KFLAGS)" \ - "LIBS= $(K5LIB) $(SSLLIB) -ltermlib -lsocket -lnsl -lm -lresolv \ - -lkrb4 -lssl -lcrypto -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto \ - -ldes $(LIBS)" - -#and with OpenSSL -solaris2xg+openssl+pam+shadow: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET \ - -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DCK_SHADOW \ - -DBIGBUFOK $(SSLINC) $(KFLAGS)" \ - "LIBS= $(SSLLIB) -ltermlib \ - -lsocket -lnsl -lm -lresolv -lssl -lcrypto -lpam" - -solaris2xg+openssl+zlib+srp+pam+shadow: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with gcc, OpenSSL...' - @echo 'Please read the comments that accompany the solaris2xg target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DFNFLOAT \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET -DBIGBUFOK \ - -DCK_AUTHENTICATION -DCK_ENCRYPTION -DCK_DES -DLIBDES -DCK_CAST \ - -DCK_SSL -DCK_PAM -DCK_SHADOW -DZLIB -DCK_SRP $(SSLINC) $(KFLAGS)" \ - "LIBS= $(SSLLIB) -ltermlib -lsocket -lnsl -lm -lresolv -lsrp -lssl \ - -ldes -lkrypto -lcrypto -lpam -lz" - -solaris22g: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DPOSIX_CRTSCTS $(KFLAGS)" solaris2xg \ - KTARGET=$${KTARGET:-$(@)} - -solaris23g: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DPOSIX_CRTSCTS $(KFLAGS)" solaris2xg \ - KTARGET=$${KTARGET:-$(@)} - -#Solaris 2.4 built with gcc -solaris24g: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} \ - solaris2xg "KFLAGS=-DSOLARIS24 -DPOSIX_CRTSCTS $(KFLAGS)" - -#Solaris 2.5 built with gcc -solaris25g: - $(MAKE) "MAKE=$(MAKE)" solaris2xg KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-funsigned-char -DSOLARIS25 $(KFLAGS)" - -#Solaris 2.5 built with gcc and Kerberos IV -solaris25g+krb4: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb4 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-funsigned-char -DSOLARIS25 $(KFLAGS)" - -#Solaris 2.5 built with gcc and Kerberos V/IV, SSL, ... -solaris25g+krb5+krb4+openssl+shadow: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb5+krb4+openssl+shadow \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-funsigned-char -DSOLARIS25 $(KFLAGS)" - -#Solaris 2.6 with gcc -solaris26g: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xg \ - "KFLAGS= -DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS = -lpam" - -#Solaris 2.6 with gcc and SSL -solaris26g+openssl: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+pam+shadow \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS= -DSOLARIS26 $(KFLAGS)" - -#Solaris 2.6 with gcc, no curses (e.g. because libtermlib is missing). -solaris26gnc: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xgnc \ - "KFLAGS= -DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 7 with gcc (32-bit) -solaris7g: - $(MAKE) "MAKE=$(MAKE)" solaris2xg KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 7 with gcc + Kerberos IV (32-bit) -solaris7g+krb4: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb4 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -solaris7g+openssl+zlib+pam+shadow: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+pam+shadow \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" - -#Solaris 7 with gcc + OpenSSL (32-bit) -solaris7g+openssl+zlib+srp+pam+shadow: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+srp+pam+shadow \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" - -#Solaris 8 with gcc (32-bit) -solaris8g: - $(MAKE) "MAKE=$(MAKE)" solaris2xg KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS8 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 9 with gcc + OpenSSL + Shadow (32-bit) -solaris9g+openssl+shadow+pam+zlib: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+pam+shadow \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS9 -DHDBUUCP -DDIRENT -DZLIB -DCK_PAM -DCK_SHADOW \ - -DLIBDES $(KFLAGS)" "LIBS= -lpam -ldes425 -lz $(LIBS)" - -#Solaris 9 with gcc + OpenSSL + Kerberos 5 + Krb4 + Shadow (32-bit) -solaris9g+krb5+krb4+openssl+shadow+pam+zlib: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb5+krb4+openssl+shadow \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS9 -DHDBUUCP -DDIRENT -DZLIB -DCK_PAM -DCK_SHADOW \ - -DLIBDES $(KFLAGS)" "LIBS= -lpam -ldes425 -lz $(LIBS)" - -#Solaris 9 with gcc 3.1 (32-bit) -solaris9g: - @echo 'Making C-Kermit $(CKVER) for Solaris 9 with gcc' - $(MAKE) "MAKE=$(MAKE)" CC="gcc -m32" CC2="gcc -m32" xermit \ - KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSOLARIS9 -DUSE_STRERROR \ - -DSTERMIOX -DSELECT -DFNFLOAT -DCK_PAM -DCK_SHADOW -funsigned-char \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv -lpam" - -#Solaris 9 with gcc 3.1 (64-bit) -#Peeking inside struct FILE at its members ist strengst verboten. -solaris9g64: - @echo 'Making C-Kermit $(CKVER) for Solaris 9 with gcc' - $(MAKE) "MAKE=$(MAKE)" CC="gcc -m64" CC2="gcc -m64" xermit \ - KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSOLARIS9 -DNOARROWKEYS \ - -DSTERMIOX -DSELECT -DFNFLOAT -DUSE_STRERROR -DCK_PAM -DCK_SHADOW \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv -lpam" - -# In OpenSSL builds add -ldl if you get unresolved references for -# dlclose, dlsym, dlopen, dlerror. - -#Solaris 8 with gcc + OpenSSL (32-bit) -solaris8g+openssl+zlib+pam+shadow: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+openssl+zlib+pam+shadow \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DSOLARIS8 $(KFLAGS)" - -#Solaris 9 with gcc 3.1 + OpenSSL (32-bit) -solaris9g+openssl+zlib+pam+shadow: - $(MAKE) "MAKE=$(MAKE)" solaris2xg32+openssl+zlib+pam+shadow \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS9 -DUSE_STRERROR $(KFLAGS)" - -#Solaris 8 with gcc + Kerberos IV (32-bit) -solaris8g+krb4: - $(MAKE) "MAKE=$(MAKE)" solaris2xg+krb4 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS8 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 2.0-2.4, gcc, SunLink X.25 added. -#NOTE: Can't use xermit target with X.25. -solaris2xgx25: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x + X.25 with GNU cc...' - @echo 'Please read the comments that accompany the solaris2xg entry.' - $(MAKE) wermit CC=gcc CC2=gcc KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -g -O -Usun -DSVR4 -DSOLARIS -DSTERMIOX -DSELECT -DSUNX25 \ - -DCK_CURSES -DCK_NEWTERM -DDIRENT -DHDBUUCP -DTCPSOCKET -DFNFLOAT \ - -DNOLEARN $(KFLAGS)" \ - "LIBS= -ltermlib -lm -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \ - -lsockx25 -lsocket -lnsl" - -#Solaris 2.5, gcc, SunLink X.25 added. -solaris25gx25: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xgx25 \ - "KFLAGS=-DSOLARIS25 $(KFLAGS)" - -#Solaris 2.6, gcc, SunLink X.25 added. -solaris26gx25: - $(MAKE) "MAKE=$(MAKE)" KTARGET=$${KTARGET:-$(@)} solaris2xgx25 \ - "KFLAGS=-DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 2.0 - 2.4, SunPro compiler, includes curses and TCP/IP. -#When using SUNWspro CC 2.0.1 under Solaris 2.3, be sure all cc patches -#are applied, otherwise corrupt or truncated object files can result. -#To build, set your PATH as follows: -# /usr/local/bin:/usr/bin:/opt/SUNWspro/bin:/usr/ccs/bin:\ -# /usr/ucb:/usr/sbin:/sbin:. -# or (depending on where the compiler has been installed): -# /usr/openwin/bin:/export/home/SUNWspro/bin:/usr/ccs/bin:/usr/sbin:/usr/bin. -#For additional optimization try using "-fast -xO4 -xdepend". -solaris2x: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with SunPro cc...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -Usun -i -DSVR4 -DDIRENT -DSOLARIS -DHDBUUCP -DFNFLOAT \ - -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv" - -#as above but configured for Kerberos IV -solaris2x+krb4: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x, SunPro cc, krb4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -Usun -i -DSVR4 -DDIRENT -DSOLARIS -DHDBUUCP -DFNFLOAT \ - -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX -DTCPSOCKET \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB4 \ - -DCK_ENCRYPTION -DCK_DES -DCK_CAST $(K4INC) $(KFLAGS)" \ - "LNKFLAGS = -s" \ - "LIBS= $(K4LIB) -ltermlib -lsocket -lnsl -lm -lresolv -lkrb -ldes" - -solaris23: - $(MAKE) "MAKE=$(MAKE)" solaris2x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS)" - -solaris24: - $(MAKE) "MAKE=$(MAKE)" solaris2x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS24 -DPOSIX_CRTSCTS $(KFLAGS)" - -# template for Solaris 2.5 and above. -solaris25x: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x with SunPro cc...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DFNFLOAT -O -Usun -i $(KFLAGS)" \ - "LNKFLAGS = -s" \ - "LIBS= -ltermlib -lsocket -lnsl -lm -lresolv $(LIBS)" - -#Solaris 2.5, SunPro compiler, curses, TCP/IP -solaris25: - $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS25 $(KFLAGS)" - -#Solaris 2.5, SunPro compiler, curses, TCP/IP, Kerberos IV -solaris25+krb4: - $(MAKE) "MAKE=$(MAKE)" solaris25x+krb4 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS25 $(KFLAGS)" - -#Solaris 2.6, SunPro compiler, curses, TCP/IP -solaris26: - $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS26 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 7 (aka 2.7) -solaris7: - $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS7 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 8 -solaris8: - $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS8 -DCK_PAM -DCK_SHADOW $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 9 -solaris9: - $(MAKE) "MAKE=$(MAKE)" solaris25x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSOLARIS9 -DCK_PAM -DCK_SHADOW -DUSE_STRERROR $(KFLAGS)" \ - "LIBS= -lpam" - -#Solaris 9 with malloc debugging -solaris9md: - $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DFNFLOAT -O -Usun -i \ - -DSOLARIS9 -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG \ - -DCK_PAM -DCK_SHADOW -DUSE_STRERROR $(KFLAGS)" \ - "LIBS= -lpam -ltermlib -lsocket -lnsl -lm -lresolv" - -#Solaris 2.0-2.3, SunPro compiler, with SunLink X.25 support. -#This will only run if user has /opt/SUNWconn/lib/libsockx25.so.1 -#exists and can be dynamically linked. -#NOTE: Do not change target to xermit -- it doesn't support X.25. -solaris2x25: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.x+X.25 with SunPro cc...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS -DDIRENT \ - -DSUNX25 -DTCPSOCKET -DHDBUUCP -DFNFLOAT -DNOLEARN \ - -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX $(KFLAGS)" \ - "LNKFLAGS = -s" \ - "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \ - -lsockx25 -lsocket -lnsl -lm -lresolv" - -#Solaris 2.4, SunPro compiler, with SunLink X.25 support. -#This will only run if user has /opt/SUNWconn/lib/libsockx25.so.1 -#exists and can be dynamically linked. -solaris24x25: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.4+X.25 with SunPro cc...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS -DSOLARIS24 -DDIRENT -DNOLEARN \ - -DSUNX25 -DTCPSOCKET -DHDBUUCP -DFNFLOAT -DPOSIX_CRTSCTS \ - -DSELECT -DCK_CURSES -DCK_NEWTERM -DSTERMIOX $(KFLAGS)" \ - "LNKFLAGS = -s" \ - "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \ - -lsockx25 -lsocket -lnsl -lm -lresolv" - -#Solaris 2.5, SunPro compiler, with SunLink X.25 support. -solaris25x25: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.5+X.25 with SunPro cc...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS25 -DDIRENT -DSUNX25 \ - -DTCPSOCKET -DHDBUUCP -DSELECT -DCK_CURSES \ - -DCK_NEWTERM -DSTERMIOX -DFNFLOAT -DPOSIX_CRTSCTS -DNOLEARN \ - -I/opt/SUNWconn/include $(KFLAGS)" \ - "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \ - -lsockx25 -lsocket -lnsl -lm -lresolv" - -#Solaris 2.6, SunPro compiler, with SunLink X.25 support. -solaris26x25: - @echo 'Making C-Kermit $(CKVER) for Solaris 2.6+X.25 with SunPro cc...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -i -Usun -DSVR4 -DSOLARIS26 -DDIRENT -DSUNX25 \ - -DTCPSOCKET -DHDBUUCP -DSELECT -DCK_CURSES -DCK_PAM -DCK_SHADOW \ - -DCK_NEWTERM -DSTERMIOX -DFNFLOAT -DPOSIX_CRTSCTS -DNOLEARN \ - -I/opt/SUNWconn/include $(KFLAGS)" \ - "LIBS= -ltermlib -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib \ - -lsockx25 -lsocket -lnsl -lm -lresolv -lpam" - -#The following sunosxxx entries are for debugging and testing only. - -sunos41x: - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DSUNOS41 -DDIRENT -DNOTLOG -DNOMSEND \ - -DNOUUCP -DNOSIGWINCH -DNOREDIRECT -DNOPUSH -DNOCCTRAP \ - -DNOICP -DNOLOCAL $(KFLAGS)" - -#SunOS 4.1.x, debugging with Pure Software, Inc., Purify 2 (commercial runtime -#error-detection software for catching wild array references, etc). -#Before running the resulting wermit, you'll also need to define and export -#the following environment variables (as in this example): -#PURIFYHOME=/usr/local/purify ; export PURIFYHOME -#PURIFYCACHEDIR=/tmp ; export PURIFYCACHEDIR -sunos41cp: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 / BSD / Curses / Purify... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CC2= purify -cache_dir=/usr/tmp cc" \ - "CFLAGS= -g -DSUNOS41 -DHDBUUCP -DDIRENT -DTCPSOCKET \ - -DSAVEDUID -DCK_CURSES $(KFLAGS)" \ - "LIBS= -lcurses -ltermcap" - -#SunOS 4.1 with malloc debugger -sunos41md: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 malloc debug... - $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DSUNOS41 -DHDBUUCP -DDIRENT -DTCPSOCKET \ - -DSAVEDUID $(KFLAGS) -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG" - -sunos41gmd: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 with gcc and curses... - $(MAKE) mermit KTARGET=$${KTARGET:-$(@)} "CC= gcc " "CC2= gcc" \ - "CFLAGS= -g -DSUNOS41 -DHDBUUCP -DDIRENT -DTCPSOCKET \ - -DNDGPWNAM -DSAVEDUID -DCK_CURSES -DRLOGCODE \ - $(KFLAGS) -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG" \ - "LIBS= -lcurses -ltermcap" - -#SunOS version 4.1, gcc, profiling with gprof, no debugging. -#To get profile, "make sunos41p" (on Sun), then "./wermit". After running -#wermit, "gprof ./wermit | lpr" (or whatever) to get execution profile. -sunos41p: - @echo Making C-Kermit $(CKVER) for SunOS 4.x with profiling... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC= gcc " "CC2= gcc" \ - "CFLAGS= -DSUNOS41 -DNODEBUG -DSAVEDUID -DDIRENT -DTCPSOCKET \ - -DNDGPWNAM $(KFLAGS) -pg" "LNKFLAGS = -pg" - -#SunOS version 4.1 or later, BSD environment, minimum features. -sunos41min: - @echo Minimum interactive - $(MAKE) "MAKE=$(MAKE)" sunos41 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DNOSPL -DNOXMIT -DNOMSEND -DNOFRILLS -DNORETRY \ - -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG -DNOSCRIPT -DNOCSETS \ - -DNOSHOW -DNOSETKEY -DNOUUCP -DNORECALL -DNOREDIRECT \ - -DNOPUSH -DNOMDMHUP -DNOJC -DNOFDZERO -DNOESCSEQ \ - -DNONET -DCK_SMALL -DNOCKSPEED -DNOCKTIMERS -DNOLOGIN \ - -DNOCKXYZ -DNOKERBEROS -DNOMKDIR -DNOPATTERNS -DNOPERMS -DNOPIPESEND \ - -DNORECURSIVE -DNORENAME -DNORESEND -DNOSETKEY \ - -DNOTRIGGER -DNOTUNING $(KFLAGS)" "LNKFLAGS = -s" - -#SunOS version 4.1, BSD environment, min size, command-line only... -sunos41m: - @echo Minimum size - $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DNOICP $(KFLAGS)" - -#SunOS version 4.1, BSD environment, min size, cmd-line only, remote only... -# -sunos41mr: - @echo Minimum size - $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DNOICP -DNOLOCAL $(KFLAGS)" - -#SunOS version 4.1, BSD environment, min size, interactive... -sunos41mi: - @echo Minimum size - $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DNOCMDL $(KFLAGS)" - -#SunOS version 4.1, BSD environment, min size, interactive, remote only... -sunos41mir: - @echo Minimum size - $(MAKE) "MAKE=$(MAKE)" sunos41min KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DNOCMDL -DNOLOCAL $(KFLAGS)" - -#SunOS 4.1, System V R3 environment (-i option omitted). -sunos41s5: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 System V R3... - @echo For testing purposes only - NOT for production use. - @echo For a useable version, make sunos41 instead. - $(MAKE) wermit "CC= /usr/5bin/cc " "CC2=/usr/5bin/cc " \ - KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSUN4S5 -DDIRENT -DHDBUUCP -DNOLEARN -DCK_POLL $(KFLAGS) -O" - -#As above, but with curses support -sunos41s5c: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 System V R3... - @echo Curses included. - @echo For testing purposes only - NOT for production use. - @echo For a useable version, make sunos41 instead. - $(MAKE) wermit "CC= /usr/5bin/cc " "CC2=/usr/5bin/cc " \ - KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSUN4S5 -DDIRENT -DHDBUUCP -DNOLEARN \ - -DCK_POLL -DCK_CURSES -DCK_NEWTERM $(KFLAGS) -O" "LIBS= -lcurses" - -#As above, but with curses support AND net support -sunos41s5tcpc: - @echo Making C-Kermit $(CKVER) for SunOS 4.1 System V R3... - @echo TCP/IP and curses included. No debug log. - @echo For testing purposes only - NOT for production use. - @echo For a useable version, make sunos41 instead. - $(MAKE) xermit "CC= /usr/5bin/cc " "CC2=/usr/5bin/cc " \ - KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSUN4S5 -DDIRENT -DHDBUUCP -DCK_POLL \ - -DNODEBUG -DCK_CURSES -DCK_NEWTERM -DTCPSOCKET $(KFLAGS) -O" \ - "LIBS= -lcurses -lresolv" - -# (End of SunOS test entries...) - -#Apollo with Domain SR10.0 or later, BSD environment -#Reportedly, it might also help to add '-A,systype=bsd4.3' to CFLAGS. -#Reportedly, there is also a problem with getc & putc macros that can -#be handled by using '#ifdef apollo' somewhere to redefine them??? -#On the other hand, other reports indicate that it works fine as-is. -#NOTE: This entry was previously like this: -# $(MAKE) wermit "CFLAGS= -DNOFILEH -DBSD4 $(KFLAGS) -Uaegis \ -# -DTCPSOCKET -U__STDC__" -#Reports (Dec 91) indicate SR10 has an ANSI-compliant C compiler, -#in addition to an older one that claimed to be ANSI-compliant but wasn't. -#The following make entry (plus checks that are made in ckcdeb.h) detect -#which compiler is used and define the CK_ANSIC or NOANSI flags accordingly. -sr10-bsd: - @echo Making C-Kermit $(CKVER) for Apollo SR10.0 / BSD ... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DAPOLLOSR10 -DBSD43 -DTCPSOCKET -DCK_CURSES -DNOLEARN \ - -Uaegis $(KFLAGS)" "LIBS= -lcurses -ltermcap" - -#Apollo with Domain SR10.0 or later, System V R3 environment. -#Don't use the optimizer (-O), it causes problems at runtime. -sr10-s5r3: - @echo Making C-Kermit $(CKVER) for Apollo SR10.0 / Sys V R3 ... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DNOFILEH -DSVR3 -DAPOLLOSR10 -DNOLEARN $(KFLAGS) \ - -Uaegis -U__STDC__" - -#Apollo Domain/IX (untested, try this if sr10-bsd doesn't work) -# -DTCPSOCKET can probably be added here. -apollobsd: - @echo Making C-Kermit $(CKVER) for Apollo Domain/IX... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CC= /bin/cc " "CC2= /bin/cc " \ - "CFLAGS= -DNOFILEH -DBSD4 -DAPOLLOBSD -DNOLEARN $(KFLAGS) -Uaegis" - -#Version 7 Unix (see comments near top of makefile) -v7: - @echo Making C-Kermit $(CKVER) for UNIX Version 7. - @echo Read the makefile if you have trouble with this... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS=-DV7 -DPROCNAME=\\\"$(PROC)\\\" \ - -DBOOTNAME=\\\"$(BOOTFILE)\\\" -DNPROCNAME=\\\"$(NPROC)\\\" \ - -DNPTYPE=$(NPTYPE) $(DIRECT) -DO_RDWR=2 -DO_NDELAY=0 -DO_SCCS_ID \ - -DNOLEARN $(KFLAGS)" - -#AT&T UNIX System V R3, signal() is void rather than int. -#Uses dirent.h and Honey DanBer UUCP. -#Add the -i link option if necessary. -#If you get errors like "ws_row undefined" in ckutio.c, add -DNONAWS. -sys5r3: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DNOLEARN $(KFLAGS) -O" \ - "LNKFLAGS=" - -#As above, plus curses. -sys5r3c: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3 + curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DCK_CURSES -DNONAWS -DNOLEARN \ - $(KFLAGS) -O" "LNKFLAGS=" "LIBS = -ltermlib" - -#System V R3.2 for PCs built on Interactive UNIX SV/386 R4.x -#but with all calls to dup2() disabled because generic SVR3 does not have dup2. -# (The -linet library might not need to be in this one.) -sys5r32is: - @echo 'Making C-Kermit $(CKVER) for System V/386 R32 - $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \ - -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES -DNONAWS \ - -DPOSIX_JC -DCK_REDIR -DCK_POLL -DDCLGETCWD -DNOFDZERO -DNOREDIRECT \ - -DNOZEXEC -DNOLEARN $(KFLAGS)" "LIBS=-lcurses -lc_s -linet" - -#System V R3.2 for PCs built on Interactive UNIX SV/386 R4.x -#but with all calls to dup2() disabled because generic SVR3 does not have dup2. -#With TCP/IP added. -sys5r32isnet: - @echo 'Making C-Kermit $(CKVER) for System V/386 R32 + TCP/IP - $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \ - -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES -DNONAWS \ - -DPOSIX_JC -DCK_REDIR -DCK_POLL -DDCLGETCWD -DNOFDZERO -DNOREDIRECT \ - -DNOLEARN -DNOZEXEC -DTCPSOCKET $(KFLAGS)" "LIBS=-lcurses -lc_s -linet" - -iclsys5r3: - make sys5r3 KTARGET=$${KTARGET:-$(@)} KFLAGS=-DICLSVR3 - -#AT&T UNIX System V R3. As above, but no ANSI prototyping. -sys5r3na: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -DNOANSI -DNOLEARN $(KFLAGS) -O" \ - "LNKFLAGS=" - -#AT&T UNIX System V R3, for 3B computers with Wollongong TCP/IP. -sys5r3net3b: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX SVR3/3B/Wollongong...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DWOLLONGONG -DNOLEARN $(KFLAGS) \ - -O" "LIBS= -lnet -lnsl_s" "LNKFLAGS =" - -#AT&T UNIX System V R3, signal() is void rather than int. -#Uses dirent.h and Honey DanBer uucp, has . -#Has for RTS/CTS flow control. -sys5r3tx: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DTERMIOX -DNOLEARN \ - $(KFLAGS) -i -O" "LNKFLAGS =" - -#AT&T UNIX System V R3, signal() is void rather than int. -#Uses dirent.h and Honey DanBer uucp, has . -#Has for RTS/CTS flow control. -sys5r3sx: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R3...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DSTERMIOX -DNOLEARN \ - $(KFLAGS) -i -O" "LNKFLAGS =" - -#AT&T UNIX System V R4. -#Has . -sys5r4: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DTERMIOX -DNOLEARN $(KFLAGS)" \ - "LNKFLAGS = -s" - -#AT&T UNIX System V R4 with Wollongong TCP/IP. -#Has . -sys5r4net: - @echo 'Making C-Kermit $(CKVER) for System V R4 + Wollongong TCP/IP...' - @echo ' If sockets-library routines are missing at link time, then' - @echo ' try the sys5r4net2 entry.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOLEARN \ - -DTERMIOX -DWOLLONGONG $(KFLAGS)" "LNKFLAGS = -s" - -#As above, but needs libs included. -sys5r4net2: - @echo ' PLEASE READ ckuins.txt IF YOU GET MISSING HEADER FILES.' - @echo ' (Search for WOLLONGONG...)' - $(MAKE) sys5r4net KTARGET=$${KTARGET:-$(@)} "LIBS= -lsocket -lnsl" - -#As above plus curses. -sys5r4net2c: - echo 'Making C-Kermit $(CKVER) for System V R4 + Wollongong TCP/IP...' - @echo ' PLEASE READ ckuins.txt IF YOU GET MISSING HEADER FILES.' - @echo ' (Search for WOLLONGONG...)' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOLEARN \ - -DTERMIOX -DWOLLONGONG -DCK_CURSES $(KFLAGS)" "LNKFLAGS = -s" \ - "LIBS= -lsocket -lnsl -lcurses" - -#DELL UNIX System V R4. -#Has , regular Berkeley sockets library, i.e. in.h and inet.h -#are not misplaced in sys (rather than netinet and arpa, respectively). -#Uses ANSI C constructs, advisory file locking on devices, etc. -#Warning: -DSTERMIOX enables hardware flow control (RTS/CTS), but reportedly -#this does not work with the normal drivers. However, it might still work -#on non-Dell systems, or even Dell systems with different drivers installed. -dellsys5r4: - @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT -DHDBUUCP \ - -DTCPSOCKET -DSTERMIOX -DCK_POLL $(KFLAGS)" \ - "LIBS= -lsocket -lnsl" "LNKFLAGS = -s" - -#As above, curses support added... -dellsys5r4c: - @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT -DHDBUUCP \ - -DTCPSOCKET -DSTERMIOX -DCK_CURSES -DCK_POLL \ - $(KFLAGS)" "LIBS= -lsocket -lnsl -lcurses -ltermcap" "LNKFLAGS = -s" - -#Minimum interactive: As above, but with every conceivable option removed. -dellsys5r4mi: - @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...' - @echo 'Minimum-size interactive' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT \ - -UTCPSOCKET -DNOCMDL -DNOSPL -DNOXMIT -DCK_POLL \ - -DNOMSEND -DNOFRILLS -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \ - -DNOSCRIPT -DNOCSETS -DNOSHOW -DNOSETKEY -DNOSERVER -DNOUUCP \ - -DNOPUSH -DNOMDMHUP -DNOJC -DNOFDZERO -DNOESCSEQ \ - $(KFLAGS)" "LNKFLAGS = -s" - -#Command-line only version. -dellsys5r4m: - @echo 'Making C-Kermit $(CKVER) for DELL UNIX System V R4...' - @echo 'Command-line only' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDELL_SVR4 -DDIRENT \ - -UTCPSOCKET -DNOICP -DNOFRILLS -DNODIAL -DNODEBUG -DNOTLOG -DNOCSETS \ - -DNOSETKEY -DNOESCSEQ -DNOJC -DNOFDZERO -DCK_POLL \ - $(KFLAGS)" "LNKFLAGS = -s" - -#AT&T UNIX System V R4. -#Has . -sys5r4sx: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DSTERMIOX -DNOLEARN \ - $(KFLAGS)" "LNKFLAGS = -s" "LIBS=$(LIBS)" - -#AT&T UNIX System V R4. -#Has , regular Berkeley sockets library, i.e. in.h and inet.h -#are not misplaced in sys (rather than netinet and arpa, respectively). -#Uses ANSI C constructs, , etc etc. -sys5r4sxtcp: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \ - -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -lsocket -lnsl $(LIBS)" "LNKFLAGS= -s" - -#AT&T UNIX System V R4. -#As above + curses. -sys5r4sxtcpc: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \ - -DSTERMIOX -DCK_CURSES -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap $(LIBS)" "LNKFLAGS = -s" - -#AT&T UNIX System V R4. CONSENSYS SVR4.2-1. -#Has , regular Berkeley sockets library, i.e. in.h and inet.h -#are not misplaced in sys (rather than netinet and arpa, respectively). -#Uses ANSI C constructs, , etc. -# Fullscreen -DCK_CURSES added (with curses & termcap libs) -# Submission by Robert Weiner/Programming Plus, rweiner@watsun.cc.columbia.edu -sys5r4sxtcpf: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -L/usr/ccs/lib -lcurses -ltermcap" \ - "LIBS=$(LIBS)" "LNKFLAGS = -s" - -#Smallest possible version for System V R4 -s5r4m: - @echo Minimum size - $(MAKE) "MAKE=$(MAKE)" sys5r4sx KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \ - -DNOSCRIPT -DNOCSETS -DNOICP -DNOMSEND -UTCPSOCKET" "LNKFLAGS = -s" - -#Smallest possible interactive version of above -s5r4mi: - @echo Minimum interactive - $(MAKE) "MAKE=$(MAKE)" sys5r4sx \ - "KFLAGS=-DNOSPL -DNOXMIT -DNOMSEND -DNOFRILLS -DNOSHOW \ - -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG -DNOSCRIPT -DNOCSETS -DNOSETKEY \ - -UTCPSOCKET $(KFLAGS)" "LNKFLAGS = -s" - -#AT&T UNIX System V R4, has -#ANSI C function prototyping disabled. -sys5r4sxna: - @echo No ANSI C prototyping... - $(MAKE) "MAKE=$(MAKE)" sys5r4sx KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DNOANSI" - -#Stratus FTX. -ftx: - @echo 'Making C-Kermit $(CKVER) for Stratus FTX 3.x...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DFTX -DDIRENT -DHDBUUCP -DSTERMIOX \ - -DNOGETUSERSHELL -DNOLEARN +DA1.1 $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS=$(LIBS)" - -#Stratus FTX + TCP/IP. -ftxtcp: - @echo 'Making C-Kermit $(CKVER) for Stratus FTX 3.x...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DFTX -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \ - -DSTERMIOX -DTCPSOCKET -DNO_DNS_SRV +DA1.1 $(KFLAGS)" \ - "LIBS= -lsocket -lnsl $(LIBS)" "LNKFLAGS= -s" - -#NCR MP-RAS 2.03 or 3.02 -mpras: - @echo 'Making C-Kermit $(CKVER) for NCR MP-RAS...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DNCRMPRAS -DDIRENT -DHDBUUCP -DSTERMIOX \ - -DNOGETUSERSHELL -DUSE_FILE__CNT -DNOLEARN -DNO_DNS_SRV $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS=$(LIBS)" - -#NCR MP-RAS 2.03 or 3.02 with TCP/IP and curses -mprastcpc: - @echo 'Making C-Kermit $(CKVER) for NCR MP-RAS + TCP/IP + curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CFLAGS=-DTCPSOCKET \ - -DCK_CURSES -DSVR4 -DNCRMPRAS -DDIRENT -DHDBUUCP -DSTERMIOX -DNOLEARN \ - -DNOGETUSERSHELL -DNO_DNS_SRV DUSE_FILE__CNT -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS= -lsocket -lnsl -lcurses -ltermcap $(LIBS)" - -#SINIX-L V5.41 - includes curses, tcp/ip - Use this one for i386. -#This version of SINIX doesn't like fdopen() or popen(). -sinix541: - @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf SINIX V5.41/i386' - $(MAKE) ckcpro.$(EXT) "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP \ - -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DNO_DNS_SRV \ - -DSNI541 -DNOGETUSERSHELL -DNONETCMD -DNOPOPEN -kansi -W0 $(KFLAGS)" - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DNO_DNS_SRV -DNOPOPEN \ - -DFNFLOAT -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC \ - -DSNI541 -DNOGETUSERSHELL -DNONETCMD -kansi -W0 -O $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" "LNKFLAGS = -s" - -sinix541i: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sinix541 - -#SINIX V5.42 - includes curses, tcp/ip, everything - Use this one for MIPS. -# As of C-Kermit 7.1, optimization removed -- takes (literally) forever. -sinix542: - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DNO_DNS_SRV \ - -DFNFLOAT -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC \ - -DSNI542 -DNOGETUSERSHELL -kansi -W0 $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" "LNKFLAGS = -s" - -#SINIX V5.42 gcc - includes curses, tcp/ip, everything. -#This one was used to build the Pyramid-architecture RM600 version -#on SINIX-P 5.42 A10 with gcc but should work for SINIX 5.42 on any other -#architecture with gcc. -sinix542g: - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC=gcc" "CC2=gcc" \ - "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DNO_DNS_SRV \ - -DFNFLOAT -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC \ - -DSNI542 -DNOGETUSERSHELL $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" \ - "LNKFLAGS = -s" - -#SINIX V5.42 - includes curses, tcp/ip, everything - Use this one for Intel. -# (Note: SNI discontinued Intel support after 5.42.) -sinix542i: - @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf SINIX-Z V5.42...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSINIX -DSVR4 -DDIRENT -DHDBUUCP -DFNFLOAT -DSTERMIOX \ - -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DNO_DNS_SRV -kansi \ - -DSNI542 $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap -lm" \ - "LNKFLAGS = -s" - -#Siemens Nixdorf Reliant UNIX V5.43 - includes curses, tcp/ip, everything: -# . gettimeofday() suddenly has only one arg instead of two (GTODONEARG). -# . The syntax of the Olimit specifier changed. -# . The name was changed from SINIX to Reliant UNIX in version 5.43C. -sni543: - @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf Reliant UNIX V5.43' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSINIX -DSNI543 -DSVR4 -DDIRENT -DHDBUUCP \ - -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DGTODONEARG \ - -DNO_DNS_SRV -kansi -W0 -O -F Olimit,3100 $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap" "LNKFLAGS = -s" - -#Siemens Nixdorf Reliant UNIX V5.44 - Like 5.43 but with different banner. -sni544: - @echo 'Making C-Kermit $(CKVER) for Siemens/Nixdorf Reliant UNIX V5.44' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSINIX -DSNI544 -DSVR4 -DDIRENT -DHDBUUCP \ - -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DSELECT -DCK_ANSIC -DGTODONEARG \ - -DNO_DNS_SRV -kansi -W0 -O -K Olimit,3100 $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap" "LNKFLAGS = -s" - -#Commodore Amiga with AT&T UNIX System V R4 and TCP/IP support. -#Has . -svr4amiganet: - @echo 'Making C-Kermit $(CKVER) for Amiga SVR4 + TCP/IP...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC=gcc" "CC2=gcc" \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DSTERMIOX \ - -DTCPSOCKET -DCK_CURSES $(KFLAGS)" "LNKFLAGS = -s" \ - "LIBS = -lsocket -lnsl -ltermlib" - -#SCO (Novell (Univel)) UnixWare 1.x or 2.0, no TCP/IP. -#This assumes the Novell SDK 1.0, which has . -#UnixWare users with the "Prime Time Freeware" CD-ROM SDK will probably have -#to use the sys5r4 entry (no termiox.h file, so no hardware flow control). -#Change -DSELECT to -DCK_POLL if -DSELECT causes problems. -# NOTE: Unixware 1.x builds have not been tried in C-Kermit 7.0. -unixware: - $(MAKE) "MAKE=$(MAKE)" sys5r4sx KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DOLD_UNIXWARE -DCK_NEWTERM -DSELECT -DNOGETUSERSHELL \ - -DNOSYSLOG $(KFLAGS)" "LIBS=-lcrypt" - -#UnixWare 1.x or 2.0 with TCP/IP and curses. -#fork()-based CONNECT - no high serial speeds. -unixwarenetc: - $(MAKE) "MAKE=$(MAKE)" sys5r4sxtcpc KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DOLD_UNIXWARE -DCK_NEWTERM -DSELECT -DNOGETUSERSHELL \ - -DNOSYSLOG $(KFLAGS)" "LIBS=-lcrypt -lresolv" - -uw10: - $(MAKE) unixwarenetc KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)" - -#This is for Unixware 2.0.x only - use unixware21 for UW 2.1.x. -#Has special library search and enables special kludge around library -#foulup regarding vfork() (which Kermit doesn't use). Forces POSIX-style -#hangup. -unixware20: - @echo 'Making C-Kermit $(CKVER) for UnixWare 2.0.x...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DOLD_UNIXWARE -DUNIXWARE2 -DSELECT -DSVR4 -DDIRENT \ - -DHDBUUCP -DBIGBUFOK -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES \ - -DTCPSOCKET -DUW200 -DFNFLOAT -DCK_NEWTERM -DNOSYSLOG $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap -lcrypt -lgen -lm -lresolv" \ - "LNKFLAGS = -s" - -uw20: - $(MAKE) unixware20 KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)" - -#Adds big buffers ("large memory model") - otherwise the same as UnixWare 1.x. -unixware21: - @echo 'Making C-Kermit $(CKVER) for UnixWare 2.1.x...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \ - -DNOSYSLOG -DSTERMIOX -DCK_CURSES -DTCPSOCKET \ - -DCK_NEWTERM -DFNFLOAT -DUNIXWARE2 $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv \ - $(LIBS)" "LNKFLAGS = -s" - -#Unixware 2.1.0 -uw21: - $(MAKE) unixware21 KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)" - -#Unixware 2.1.3 -uw213: - $(MAKE) unixware21 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DUSE_FILE__CNT $(KFLAGS)" - -#Unixware 2.1 with IKSD support -uw21iksd: - $(MAKE) unixware21 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DCK_SHADOW $(KFLAGS)" "LIBS= -lgen" - -#UnixWare 7 with tc[gs]etspeed() high serial speeds & select()-based CONNECT -#NOTE: This is the one we use. -unixware7t: - @echo 'Making C-Kermit $(CKVER) for UnixWare 7 with POSIX i/o...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \ - -DFNFLOAT -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DPOSIX \ - -DUW7 -DUSETCSETSPEED -DCK_NEWTERM -DNOLSTAT -DDCLTIMEVAL \ - -DNEEDMDMDEFS $(KFLAGS)" \ - "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \ - "LNKFLAGS = -s" - -#UnixWare 7 - select()-based CONNECT - no POSIX i/o - no high serial speeds. -#In other words, just like the UnixWare 1 and 2 builds. -unixware7x: - @echo 'Making C-Kermit $(CKVER) for UnixWare 7...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \ - -DUW7 -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DNOLSTAT \ - -DFNFLOAT -DCK_NEWTERM $(KFLAGS)" \ - "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \ - "LNKFLAGS = -s" - -#UnixWare 7 with POSIX cfset[oi]speed() to allow high serial speeds. -#(but the high speeds don't work) -unixware7p: - @echo 'Making C-Kermit $(CKVER) for UnixWare 7 with POSIX i/o...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \ - -DUW7 -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DPOSIX \ - -DFNFLOAT -DCK_NEWTERM -DNOLSTAT $(KFLAGS)" \ - "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \ - "LNKFLAGS = -s" - -# UnixWare 7 built with gcc - This does not work at all... -# Reportedly gcc 2.8.1 is broken on Unixware 7. Try egcs? -unixware7g: - @echo 'Making C-Kermit $(CKVER) for UnixWare 7 with gcc...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s -shlib" - "CFLAGS = -O -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \ - -DUW7 -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DNOLSTAT \ - -DFNFLOAT -DCK_NEWTERM $(KFLAGS)" \ - "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv $(LIBS)" \ - "LNKFLAGS = -s" - -unixware7: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" unixware7t \ - KTARGET=$${KTARGET:-$(@)} - -uw7: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" unixware7t \ - KTARGET=$${KTARGET:-$(@)} - -#SCO OpenUNIX 8.0 -ou8: - @echo 'Making C-Kermit $(CKVER) for Open UNIX 8...' - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DOU8 $(KFLAGS)" unixware7t \ - KTARGET=$${KTARGET:-$(@)} - -#UnixWare 7 with OpenSSL -uw7ssl: - @echo 'Making C-Kermit $(CKVER) for UnixWare 7 and OpenSSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DCK_AUTHENTICATION -DCK_SSL -DCK_SHADOW \ - -DUNIXWARE -DSELECT -DSVR4 -DDIRENT -DHDBUUCP -DBIGBUFOK \ - -DFNFLOAT -DNOGETUSERSHELL -DSTERMIOX -DCK_CURSES -DTCPSOCKET -DPOSIX \ - -DUW7 -DUSETCSETSPEED -DCK_NEWTERM -DNOLSTAT -DDCLTIMEVAL \ - $(SSLINC) $(KFLAGS)" \ - "LIBS=-lsocket -lnsl -lcurses -ltermcap -lcrypt -lm -lresolv \ - -lgen -lcudk70 $(SSLLIB) -lssl -lcrypto $(LIBS)" \ - "LNKFLAGS = -s" - -#As above but includes Shadow password support needed for IKSD. -uw7iksd: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DCK_SHADOW $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} "LIBS= -lgen" unixware7t - -#As above but links with static API for realpath() so a binary built -#with this target on UW7.1 will also work on 7.0. Requires SCO UDK -#rather than the stock compiler. -uw7iksdudk: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=-DCK_SHADOW $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} "LIBS= -lgen -lcudk70" unixware7t - -#ESIX SVR4.0.3 or 4.04 with TCP/IP support. -#Has , ANSI C function prototyping disabled. -#Add -m486 to CFLAGS if desired. -esixr4: - @echo 'Making C-Kermit $(CKVER) for ESIX SVR4 + TCP/IP...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOANSI \ - -DSTERMIOX -DTCPSOCKET $(KFLAGS)" "LNKFLAGS = -s" \ - "LIBS = -lsocket -lnsl" - -#AT&T UNIX System V R4. -#Has , Wollongong WIN/TCP TCP/IP. -sys5r4sxnet: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \ - -DSTERMIOX -DWOLLONGONG $(KFLAGS)" "LNKFLAGS = -s" - -#AT&T UNIX System V R4, no or . -sys5r4nx: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DNOLEARN $(KFLAGS)" \ - "LNKFLAGS = -s" - -#AT&T UNIX System V R4, no or , curses, TCP/IP. -sys5r4nxnetc: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP \ - -DCK_CURSES -DTCPSOCKET $(KFLAGS)" \ - "LIBS = -lcurses -lsocket -lnsl -ltcpip" \ - "LNKFLAGS = -s" - -#AT&T UNIX System V R4, no or , Wollongong TCP/IP. -sys5r4nxtwg: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System V R4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DDIRENT -DHDBUUCP -DWOLLONGONG $(KFLAGS)" - "LNKFLAGS = -s" - -#ICL UNIX System V R4.(DRS N/X) version :- -#UNIX System V Release 4.0 ICL DRS 6000 (SPARC) -#DRS/NX 6000 SVR4 Version 5 Level 1 Increment 4 -#Has , regular Berkeley sockets library, i.e. in.h and inet.h -#are not misplaced in sys (rather than netinet and arpa, respectively). -#Uses ANSI C constructs, advisory file locking on devices, etc. -#Remove -lnsl if it causes trouble. -iclsys5r4: - @echo 'Making C-Kermit $(CKVER) for ICL UNIX System V R4 (DRS N/X)' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DICL_SVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \ - -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lresolv " "LNKFLAGS = -s" - -#As above but for DRS/NX 4.2MP 7MPlus. -iclsys5r4m+: - @echo 'Making C-Kermit $(CKVER) for ICL UNIX System V R4 DRS/NX 4.2MP+' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DICL_SVR4 -DDIRENT -DHDBUUCP -DNOIKSD \ - -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lm -lc -g -lgen " "LNKFLAGS = -s" - -#As above but for DRS/NX 4.2MP 7MPlus with IKSD support. -iclsys5r4m+iksd: - @echo 'Making C-Kermit $(CKVER) for ICL UNIX System V R4 DRS/NX 4.2MP+' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DICL_SVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \ - -DSTERMIOX -DTCPSOCKET $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lm -lc -g -lgen -lresolv " "LNKFLAGS = -s" - -iclsys5r4_486: - $(MAKE) "MAKE=$(MAKE)" iclsys5r4 KTARGET=$${KTARGET:-$(@)} - -#Data General DG/UX 4.30 (System V R3) for DG AViiON, with TCP/IP support. -dgux430: - @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 4.30...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX430 -DSVR3 -DDIRENT -DTCPSOCKET \ - -DNOINADDRX -DNOGETUSERSHELL $(KFLAGS)" - -#Data General DG/UX 4.30 for DG AViiON, with TCP/IP support with BSDisms. -dgux430bsd: - @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 4.30...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX430 -D_BSD_SOURCE -DBSD4 \ - -DNOINADDRX -DTCPSOCKET -DNOGETUSERSHELL $(KFLAGS)" - -#Data General DG/UX 5.4 (System V R4) for DG AViiON, with TCP/IP support. -#Add -lsocket -lnsl if inet_addr comes up missing... -#Hmmm - I really think CK_POLL can be removed from this one in which case -#there is no difference between dgux540 and dgux540i. -dgux540: - @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.40...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \ - -DSTERMIOX -DTCPSOCKET -DCK_POLL -DNOGETUSERSHELL $(KFLAGS)" - -#Data General DG/UX 5.40 (System V R4) for Intel AViiON, with TCP/IP support. -dgux540i: - @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.40...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \ - -DSTERMIOX -DTCPSOCKET -DNOGETUSERSHELL $(KFLAGS)" \ - "LIBS = -lsocket -lnsl" - -dgux54: - make dgux540 KTARGET=$${KTARGET:-$(@)} - -#Data General DG/UX 5.4 (= System V R4) for DG AViiON, with TCP/IP support. -# And curses. -dgux540c: - @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.4...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \ - $(KFLAGS)" "LIBS= -lcurses8 -ltermcap" "LNKFLAGS = -s" - -#As above but for Intel - only difference is name library names. -dgux540ic: - @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.40...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX540 -DDIRENT -DHDBUUCP -DNOINADDRX \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \ - $(KFLAGS)" "LIBS = -lsocket -lnsl -lcurses -ltermcap" - -dgux54c: - make dgux540c KTARGET=$${KTARGET:-$(@)} - -#DG/UX 5.4R3.10 -dgux54310: - @echo 'Making C-Kermit $(CKVER) for DG AViiON DG/UX 5.4R3...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DDGUX540 -DDGUX54310 -DDIRENT -DHDBUUCP -DSELECT \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \ - -DNOINADDRX $(KFLAGS)" "LIBS= -lcurses8 -ltermcap" "LNKFLAGS = -s" - -#DG/UX 5.4R4.10 - Includes everything. -dgux54410: - @echo 'Making C-Kermit $(CKVER) for DG/UX 5.4R4.10...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX540 -DDGUX54410 -DDIRENT -DHDBUUCP -DSELECT \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \ - -DNOINADDRX $(KFLAGS)" "LIBS = -lsocket -lnsl -lcurses -ltermcap" - -#DG/UX 5.4R4.11 - Includes everything. -dgux54411: - @echo 'Making C-Kermit $(CKVER) for DG/UX 5.4R4.11...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX540 -DDGUX54411 -DDIRENT -DHDBUUCP -DSELECT \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \ - -DNOINADDRX $(KFLAGS)" "LIBS = -lsocket -lnsl -lcurses -ltermcap" - -#DG/UX 5.4R4.20 - Includes everything. -dgux54420: - @echo 'Making C-Kermit $(CKVER) for DG/UX 5.4R4.20...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DDGUX540 -DDGUX54420 -DDIRENT -DHDBUUCP -DSELECT \ - -DSTERMIOX -DTCPSOCKET -DCK_CURSES -DCK_NEWTERM -DNOGETUSERSHELL \ - -DNOINADDRX $(KFLAGS)" \ - "LIBS = -lsocket -lresolv -lnsl -lcurses -ltermcap" - -#Silicon Graphics System V R3 with BSD file system (IRIS) -iris: - @echo Making C-Kermit $(CKVER) for Silicon Graphics IRIX pre-3.3... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR3 -DLONGFN -DNOLEARN $(KFLAGS) -I/usr/include/bsd" \ - "LIBS = -lbsd" - -#Silicon Graphics IRIS System V R3 -irix33: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 3.3...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNOLEARN $(KFLAGS) -O" \ - "LNKFLAGS = -s" - -#Silicon Graphics Iris Indigo with IRIX 4.0.0 or 5.0... -#Strict ANSI C compilation, TCP/IP support included -irix40: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DPWID_T=uid_t \ - -DCK_ANSIC -DTCPSOCKET $(KFLAGS) -O -Olimit 1600 -I/usr/include/bsd" \ - "LNKFLAGS = -s" - -#As above, but with fullscreen display (curses) and Sun Yellow Pages support. -#NOTE: IRIX versions prior to 5 run COFF binaries. -irix40ypc: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0.' - @echo 'Includes fullscreen file display and Sun Yellow Pages...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DCK_CURSES \ - -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET $(KFLAGS) \ - -O -Olimit 1600 -I/usr/include/bsd" \ - "LIBS = -lcurses -lsun" "LNKFLAGS = -s" - -# Silicon Graphics Iris Series 4D/*, IRIX 4.0.x, -O4 ucode optimized. -# Huge temporary file space needed for ucode optimizer. If you get an error -# like "ugen: internal error writing to /tmp/ctmca08777: Error 0", define the -# the TMPDIR environment variable to point to a file system that has more -# space available, e.g. "setenv TMPDIR /usr/tmp". -irix40u: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DPWID_T=uid_t \ - -DCK_ANSIC -DTCPSOCKET $(KFLAGS) -O4 -Olimit 1600" \ - "LNKFLAGS=-O4 -Olimit 1600 -s" "EXT=u" - -# As above, with Curses Support added -irix40uc: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 4.0...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DIRIX40 -DSVR3 -DDIRENT -DHDBUUCP -DPWID_T=uid_t \ - -DCK_ANSIC -DCK_CURSES -DTCPSOCKET $(KFLAGS) -O4 -Olimit 1600" \ - "LNKFLAGS=-O4 -Olimit 1600 -s" "EXT=u" "LIBS= -lcurses -ltermcap" - -#Silicon Graphics IRIX 5.x. -#Yellow Pages and Curses support included. -#IRIX version 5.x can run COFF or ELF binaries. -irix51: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 5.x' - @echo 'Includes fullscreen file display and Yellow Pages...' - @echo 'Add -mips to CFLAGS specify a particular hardware target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DIRIX51 -DSVR4 -DDIRENT -DHDBUUCP -DCK_CURSES -DCK_NEWTERM \ - -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET -DSELECT -DNOGETUSERSHELL \ - -DSYSTIMEH -DDCLPOPEN -DDCLFDOPEN $(KFLAGS) -ansi -O -Olimit 3000" \ - "LIBS = -lcurses" "LNKFLAGS = -s" - -#Use this one if irix51 blows up due to lack of swap space or whatever. -irix51x: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 5.x' - @echo 'Includes fullscreen file display and Yellow Pages...' - @echo 'Add -mips to CFLAGS specify a particular hardware target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DIRIX51 -DSVR4 -DDIRENT -DHDBUUCP -DCK_CURSES -DCK_NEWTERM \ - -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET -DSELECT -DNOGETUSERSHELL \ - -DSYSTIMEH -DDCLPOPEN -DDCLFDOPEN $(KFLAGS)" \ - "LIBS = -lcurses" "LNKFLAGS = -s" - -irix51ypc: - $(MAKE) "MAKE=$(MAKE)" irix51 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS)" - -#IRIX 5.2 adds RTS/CTS -irix52: - $(MAKE) "MAKE=$(MAKE)" irix51 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DIRIX52 -DCK_RTSCTS $(KFLAGS)" - -irix53: - $(MAKE) "MAKE=$(MAKE)" irix51 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DIRIX52 -DIRIX53 -DCK_RTSCTS $(KFLAGS)" - -irix53x: - $(MAKE) "MAKE=$(MAKE)" irix51x KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DIRIX52 -DIRIX53 -DCK_RTSCTS $(KFLAGS)" - -#Silicon Graphics IRIX 6.[024] common stuff. -#Yellow Pages and Curses support included. -#IRIX version 6.0 and later runs only ELF binaries. -#Depends on code changes in ckudeb.h that make -DIRIX6x define all -#lower IRIX6x values and IRIX51. -irix6x: - @echo 'Includes fullscreen file display and Yellow Pages...' - @echo 'Add -mips to specify a particular hardware target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \ - -DCK_CURSES -DCK_NEWTERM -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET \ - -DSELECT -DCK_RTSCTS -O $(KFLAGS)" \ - "LIBS = -lcurses" "LNKFLAGS = -s $(LNKFLAGS)" - -#Silicon Graphics IRIX 6.0. -irix60: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.0' - @$(MAKE) "MAKE=$(MAKE)" \ - "KFLAGS=-DIRIX60 -Olimit 2138 $(KFLAGS)" \ - irix6x KTARGET=$${KTARGET:-$(@)} - -#Silicon Graphics IRIX 6.2. -#Serial speeds > 38400 are available in IRIX 6.2 on O-class machines only. -#Note: Olimit must be a number > 0. -irix62: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.2' - @$(MAKE) "MAKE=$(MAKE)" \ - LNKFLAGS="-Wl,-woff,84" \ - "KFLAGS=-DIRIX62 -Olimit 4700 $(KFLAGS)" \ - irix6x KTARGET=$${KTARGET:-$(@)} - -#Silicon Graphics IRIX 6.3. -irix63: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.3' - @$(MAKE) "MAKE=$(MAKE)" irix62 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DIRIX63" - -#Silicon Graphics IRIX 6.4. -# -woff,84 to linker stops complaints about no symbols loaded from -# curses, and -woff 1110 stops complaints about unreachable "break;" -# statements in ckcpro.c among others. -# tested on SGI Octane, running IRIX 6.4 up to 115200 bps. -# -Olimit 0 means infinite. -irix64: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.4' - @$(MAKE) "MAKE=$(MAKE)" \ - LNKFLAGS="-Wl,-woff,84" \ - "KFLAGS=-DIRIX64 -DCK_RTSCTS -Olimit 3000 -woff 1110 $(KFLAGS)" \ - irix6x KTARGET=$${KTARGET:-$(@)} - -irix64gcc: - @echo 'Making C-Kermit $(CKVER) for Silicon Graphics IRIX 6.4 gcc' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS= -DSVR4 -DIRIX64 -DCK_CURSES -DTCPSOCKET -DNOCOTFMC \ - $(KFLAGS) -O" "LIBS= -lcurses -ltermcap -lcrypt" - -#Note the new Optimization option syntax for MIPSpro CC 7.2.1.2m. -irix65: - @echo 'Making C-Kermit $(CKVER) for SGI IRIX 6.5' - @$(MAKE) "MAKE=$(MAKE)" LNKFLAGS="-Wl,-woff,84" \ - "KFLAGS=-DIRIX65 -DCK_RTSCTS -OPT:Olimit=0 -woff 1110,1552,1174 \ - $(KFLAGS)" \ - irix6x KTARGET=$${KTARGET:-$(@)} - -#Dumb down to MIPS-2 if building on R5000 or higher... -irix65mips2: - @echo 'Making C-Kermit $(CKVER) for SGI IRIX 6.5 MIPS-2' - @$(MAKE) "MAKE=$(MAKE)" LNKFLAGS="-o32 -mips2 -Wl,-woff,84" \ - "KFLAGS=-DIRIX65 -DCK_RTSCTS -OPT:Olimit=0 -o32 -mips2 \ - -woff 1110,1552,1174 $(KFLAGS)" \ - irix6x KTARGET=$${KTARGET:-$(@)} - -irix6x+krb5: - @echo 'Includes fullscreen file display and Yellow Pages...' - @echo 'Add -mips to specify a particular hardware target.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR4 -DDIRENT -DHDBUUCP -DNOGETUSERSHELL \ - -DCK_CURSES -DCK_NEWTERM -DPWID_T=uid_t -DCK_ANSIC -DTCPSOCKET\ - -DSELECT -DCK_RTSCTS -O \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DCK_ENCRYPTION -DCK_DES \ - $(K5INC) $(K5INC)/krb5 $(KFLAGS)" \ - "LIBS = -lcurses $(K5LIB) -ldes425 -lkrb5 \ - -lcom_err -lcrypto -lcrypt -lgssapi_krb5" \ - "LNKFLAGS = -s $(LNKFLAGS)" - -irix65+krb5: - @echo 'Making C-Kermit $(CKVER) for SGI IRIX 6.5' - @$(MAKE) "MAKE=$(MAKE)" \ - LNKFLAGS="-Wl,-woff,84" \ - "KFLAGS=-DIRIX65 -DCK_RTSCTS -OPT:Olimit=0 -woff 1110,1552,1174 \ - $(KFLAGS)" \ - irix6x+krb5 KTARGET=$${KTARGET:-$(@)} - -#In case they type "make sys5"... -sys5: - $(MAKE) "MAKE=$(MAKE)" sys3 KTARGET=$${KTARGET:-$(@)} - -#Generic ATT System III or System V (with I&D space) -sys3: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III' - @echo 'or System V R2 or earlier...' - @echo 'add -DNOMKDIR if mkdir is an undefined symbol.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DNOUNICODE -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL \ - -DNOINITGROUPS -DNOFTRUNCATE -DNOREALPATH -DNOLEARN $(KFLAGS) -i -O" \ - "LNKFLAGS = -i" - -#Generic ATT System III or System V (no I&D space) -sys3nid: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III' - @echo 'or System V R2 or earlier, no I&D space...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DNOREALPATH -DNOUNICODE -DNOSYSLOG -DNOSYMLINK \ - -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE -DNOLEARN $(KFLAGS) -O" \ - "LNKFLAGS =" - -#Generic ATT System III or System V R2 or earlier, "no void": -#special entry to remove "Illegal pointer combination" warnings. -sys3nv: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III' - @echo 'or System V R2 or earlier...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DATTSV -DNOREALPATH -DNOUNICODE -DNOSYSLOG -DNOGETUSERSHELL \ - -DNOSYMLINK -DNOFTRUNCATE -DNOINITGROUPS -DNOLEARN \ - -Dvoid=int $(KFLAGS) -i -O" \ - "LNKFLAGS = -i" - -# AT&T 7300 UNIX PC. As of C-Kermit 6.1, many of these entries don't work -# any more due to "Out of memory" or "Too many defines" errors during -# compilation, at least not on systems without lots of memory. The sys3upcgc -# entry works (using gcc) with optimization removed, and might also work -# with optimization enabled on machines with larger memories. - -#AT&T 7300/UNIX PC (3B1) systems, sys3 but special handling for internal modem. -#Link with the shared library -- the conflict with openi in shared library -#is solved with -Dopeni=xopeni. Note that the xermit target can't be used -#for the Unix PC; there is no select(). -sys3upc: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, shared lib...' - @echo 'If shared lib causes trouble, use make sys3upcold.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DATT7300 -DNOMKDIR -DUSE_MEMCPY -DNOREALPATH -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOREDIRECT -DNOGFTIMER -DNOUNICODE $(KFLAGS) -Dopeni=xopeni" \ - "CC2 = ld /lib/crt0s.o /lib/shlib.ifile" "LNKFLAGS = -s" - -#AT&T 7300/Unix PC systems, minimum kermit for those with smaller amounts -#of memory. -sys3upcm: - @echo Minimum interactive - $(MAKE) "MAKE=$(MAKE)" sys3upc KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DNOSPL -DNOFRILLS -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS \ - -DNOSYSLOG -DNOSETKEY -DNOREALPATH" - -#AT&T 7300/UNIX PC (3B1) systems, with curses support. -#Curses and the shared library don't get along, so we don't use the -#shared library. We need to include CK_NEWTERM to avoid a conflict -#with curses and buffering on stdout. Merged with submission by -#Robert Weiner/Programming Plus, rweiner@watsun.cc.columbia.edu. -#We don't need -Dopeni=xopeni since we're not using the shared library, -#but we keep it to be consistent with the other entries. -sys3upcc: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DATT7300 -DNOREALPATH \ - -DCK_CURSES -DCK_NEWTERM -DNOMKDIR -DNOREDIRECT -DNOGFTIMER -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DUSE_MEMCPY -DNOUNICODE $(KFLAGS) -Dopeni=xopeni" \ - "LIBS = -lcurses" "LNKFLAGS = -s" - -#Like sys3upcc but for AT&T UNIX 3.51m (released as a patch on Fix Disk 2), -#adds hardware flow control. -att351m: - $(MAKE) "MAKE=$(MAKE)" sys3upcc KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DCK_RTSCTS -DUNIX351M" - -#As above but with gcc. -att351gm: - $(MAKE) "MAKE=$(MAKE)" sys3upcgc KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DCK_RTSCTS -DUNIX351M" - -#AT&T 7300 UNIX PC (3B1), as above, but no newterm(). -sys3upcx: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DATT7300 -DNOREALPATH -DNOUNICODE -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DCK_CURSES -DNOMKDIR -DNOREDIRECT -DNOGFTIMER -DUSE_MEMCPY $(KFLAGS) \ - -Dopeni=xopeni" "LIBS = -lcurses -ltermcap" "LNKFLAGS = -s" - -#AT&T 7300/UNIX PC (3B1) systems, with curses and shared library support. -sys3upcshcc: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, shared lib...' - @echo 'With curses. Requires shcc.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DATT7300 -DNOMKDIR -DNOREALPATH -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DCK_NEWTERM -DCK_CURSES -DNOREDIRECT -DNOGFTIMER \ - -DUSE_MEMCPY -DNOUNICODE $(KFLAGS) -Dopeni=xopeni" \ - "LNKFLAGS = -i -s" "CC = shcc" "CC2 = shcc" "LIBS = -lcurses" - -#AT&T 7300/UNIX PC (3B1) systems, as above, no curses, but use gcc. -sys3upcg: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATT7300 -DNOREDIRECT -DUSE_MEMCPY -DNOUNICODE -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOGFTIMER -DNOMKDIR -DNOREALPATH $(KFLAGS) -Dopeni=xopeni" \ - "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s -shlib" - -#AT&T 7300/UNIX PC (3B1) systems, curses and gcc. -#Optimization omitted -- add it back in if your machine has lots of memory. -sys3upcgc: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC, curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATT7300 -DNOREDIRECT -DUSE_MEMCPY -DNOGFTIMER -DNOUNICODE \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DCK_CURSES -DCK_NEWTERM -DNOMKDIR -DNOREALPATH -DNOLEARN $(KFLAGS)" \ - "CC = gcc" "CC2 = gcc" "LIBS = -lcurses" "LNKFLAGS = -s" - -#AT&T 7300/UNIX PC (3B1) systems, special handling for internal modem. -#No FULLSCREEN file transfer display (curses). -sys3upcold: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATT7300 -DNOMKDIR -DUSE_MEMCPY -DNOUNICODE -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOGFTIMER -DNOREDIRECT -DNOREALPATH $(KFLAGS) -O" "LNKFLAGS = -i" - -#As above, but with gcc. mininum features - fits on a 400K UNIX PC floppy -#after compression with room to spare; add -DNOSHOW or other -DNOxxxx items -#to reduce size even further. -sys3upcgm: - @echo Minimum interactive - $(MAKE) "MAKE=$(MAKE)" sys3upcg KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DNOSPL -DNOFRILLS -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS \ - -DNOSETKEY $(KFLAGS)" - -#This target is designed to create a version with the most features possible -#that, after compression, still fits on a 400K UNIX PC floppy. -sys3upcgfd: - @echo 'Making C-Kermit $(CKVER) for AT&T 7300 UNIX PC floppy...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATT7300 -DNOREDIRECT -DUSE_MEMCPY -DNOSPL -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOGFTIMER -DNOREALPATH -Dopeni=xopeni \ - -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS -DNOSETKEY -DNOMKDIR $(KFLAGS)" \ - "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s" - -#AT&T 6300 PLUS (warning, -O might make it run out of space). -#NOTE: Remove -DHDBUUCP if not using Honey DanBer UUCP. -att6300: - @echo 'Making C-Kermit $(CKVER) for AT&T 6300 PLUS...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATT6300 -DHDBUUCP -DNOFILEH -DNOREALPATH -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOUNICODE $(KFLAGS) -O -Ml -i" "LNKFLAGS = -i -Ml" - -#As above, but with curses support. Debugging disabled to prevent thrashing. -att6300c: - @echo 'Making C-Kermit $(CKVER) for AT&T 6300 PLUS...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATT6300 -DHDBUUCP -DNOFILEH -DNOCSETS -DNOREALPATH \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DCK_CURSES -DNODEBUG -DNOUNICODE -DNOLEARN $(KFLAGS) -O -Ml -i" \ - "LNKFLAGS = -i -Ml" "LIBS = -lcurses" - -#AT&T 6300 PLUS with no curses, no debugging (about 34K smaller) -# -Optimization saves about 20K too. -att6300nd: - @echo 'Making C-Kermit $(CKVER) for AT&T 6300 PLUS, no debugging...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATT6300 -DHDBUUCP -DNODEBUG -DNOFILEH -DNOREALPATH \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOUNICODE -DNOLEARN $(KFLAGS) -O -i -Ml" "LNKFLAGS = -i -Ml" - -#AT&T 3B2 and maybe 3B20-series computers running AT&T UNIX System V R3. -#This one was actually used to build C-Kermit 7.0 successfully on a 3B2/300. -att3b2: - @echo 'Making C-Kermit $(CKVER) for AT&T 3B2' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DNOREDIRECT -DUSE_MEMCPY \ - -DNOTIMEVAL -DNOTIMEZONE -DMINIDIAL -DNOCHANNELIO -DNOBIGBUF \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOGFTIMER -DNOREALPATH -Dopeni=xopeni -DNOFRILLS -DNOLEARN \ - -DNOHELP -DNODEBUG -DNOTLOG -DNOCSETS -DNOSETKEY -DNOMKDIR $(KFLAGS)" \ - "CC = gcc" "CC2 = gcc" "LNKFLAGS = -s" - -# The next two are likely not to work as-is. - -#AT&T 3B2, 3B20-series computers running AT&T UNIX System V. -#This is just generic System V with Honey DanBer UUCP, so refer to sys3hdb. -#Remove -DNONAWS if you can get away with it. -att3bx: - $(MAKE) "MAKE=$(MAKE)" sys3hdb KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DNONAWS -DNOTIMEVAL" - -# 3Bx with charsets (except Unicode) but no curses. -att3bx1: - @echo 'Making C-Kermit $(CKVER) for AT&T 3B2 or 3B20' - @echo 'with Honey DanBer UUCP no curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DHDBUUCP $(KFLAGS) -DNOREDIRECT \ - -DNOTIMEVAL -DNOTIMEZONE -DMINIDIAL -DNOCHANNELIO -DNOBIGBUF \ - -DNOHELP -DNODEBUG -DNOGFTIMER -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOREALPATH -DNOUNICODE -i" \ - "CC = gcc" "CC2 = gcc" "LNKFLAGS = -i -s" - -#AT&T 3B2, 3B20-series computers running AT&T UNIX System V, -#with fullscreen file transfer display. -att3bxc: - @echo 'Making C-Kermit $(CKVER) for AT&T 3B2 or 3B20' - @echo 'with Honey DanBer UUCP and curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DHDBUUCP -DNONAWS -DNOTIMEVAL $(KFLAGS) \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOREALPATH -DCK_CURSES -DCK_NEWTERM -DNOUNICODE -DNOLEARN -i -O" \ - "LNKFLAGS = -i" "LIBS=-lcurses" - -#3bx with curses but no charsets -att3bxc3: - @echo 'Making C-Kermit $(CKVER) for AT&T 3B2 or 3B20' - @echo 'with Honey DanBer UUCP with curses... no CSETS' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DHDBUUCP $(KFLAGS) -DNOREDIRECT \ - -DNOTIMEVAL -DNOTIMEZONE -DMINIDIAL -DNOCHANNELIO -DNOBIGBUF \ - -DNOHELP -DNODEBUG -DNOGFTIMER -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOREALPATH -DNOCSETS -DCK_CURSES -DCK_NEWTERM -i" \ - "CC = gcc" "CC2 = gcc" "LNKFLAGS = -i -s" "LIBS = -lcurses" - -#Any System V R2 or earlier with Honey DanBer UUCP (same as above) -sys3hdb: - @echo 'Making C-Kermit $(CKVER) for AT&T UNIX System III' - @echo 'or System V R2 or earlier with Honey DanBer UUCP...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DHDBUUCP -DNOREALPATH -DNOUNICODE -DNOLEARN \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - $(KFLAGS) -i -O" "LNKFLAGS = -i" - -#Sperry/UNISYS 5000 UTS V 5.2 (System V R2), Honey DanBer UUCP -unisys5r2: - @echo 'Making C-Kermit $(CKVER) for Sperry/UNISYS 5000 UTS V 5.2...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DUNISYS52 -DHDBUUCP -DNOREALPATH -DNOUNICODE \ - -DNOSYSLOG -DNOSYMLINK -DNOGETUSERSHELL -DNOINITGROUPS -DNOFTRUNCATE \ - -DNOLEARN $(KFLAGS) -i -O" "LNKFLAGS = -i" - -#In case they say "make sys5hdb" instead of "make sys3hdb"... -sys5hdb: - $(MAKE) "MAKE=$(MAKE)" sys3hdb - -#Create the common header line for all hpux[5-10]* entries. This extra entry is -#here because our header message length may differ for each C-Kermit version. -#Don't use 'fold -s' for HP-UX 5.x - 7.x! This option is there only since -#HP-UX 8.0! -hpux-header: - @HPUX=`uname -r | sed -e 's/^[^1-9]*//' -e 's/\.00$$/.0/'` ; \ - [ "$(MESSAGE0)" ] && MESSAGE1="$(MESSAGE0)" ; \ - Message0='Making C-Kermit $(CKVER) for HP9000 HP-UX' ; \ - Message1=$${MESSAGE1:='without any extra compiler optimization'} ; \ - MessageH="$$Message0 $$HPUX" ; \ - case $$HPUX in \ - [567].*) echo "$$MessageH\n$$Message1" ;; \ - *.*) echo "$$MessageH $${Message1}$(MESSAGE1A)" | fold -s ;; \ - esac | sed -e 's/^ //' -e 's/ *$$//' - -# Peter E's updated HP-UX 5.xx entries Oct 2001. - -#HP-9000 500 HP-UX 5.xx, no TCP/IP. -hpux0500: - @MESSAGE0="no TCP/IP and no compiler optimization";\ - MESSAGE0=$${MESSAGE1:-$$MESSAGE0} \ - $(MAKE) hpux-header - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUX -DHPUX5 -DHPUXPRE65 -DNOREDIRECT -DDCLGETCWD \ - -DNOGETUSERSHELL -DNOGFTIMER -DNOSYSLOG -DNOTOMACROS -DNOLSTAT \ - -DNOSYMLINK -DNOINITGROUPS -DNOUNICODE -DNOLEARN $(KFLAGS)" \ - "LIBS = $(LIBS)" "LNKFLAGS = " - -#HP-9000 500 HP-UX 5.21 with Wollongong WIN/TCP 1.2 TCP/IP. -#Requires /usr/wins/usr/include and /usr/lib/libnet.a from Wollongong. -#Optimization skipped - takes forever. Really. -# WARNING: this doesn't work if a file called "hpux0500" is on the disk. -hpux0500wintcp: - @MESSAGE1="with WIN/TCP but without any extra compiler optimization" \ - $(MAKE) hpux0500 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = -DTCPSOCKET -DHPUX5WINTCP -DINADDRX -DNO_DNS_SRV -DNOMHHOST \ - -DNOHADDRLIST -I/usr/wins/usr/include $(KFLAGS)" \ - "LIBS = /usr/lib/libnet.a" - -#HP-UX 6.5, short filenames, no network and no curses support. -#ckcpro, ckuusr, ckuus3 and others are broken out because they make the -#optimizer run away. Note that xermit target does not work with this one! -#If you get compiler warnings like 'Switch table overflow' increase the '...' -#value in '-Wc,-Nw...'! -hpux0650: - @$(MAKE) hpux-header - @echo 'supporting: NO long filenames, NO network${MESSAGE2}.' - - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - ckuusr.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuxla.$(EXT) ckcpro.$(EXT) \ - "CFLAGS = -DHPUX -DHPUX6 -DSIG_V -DNOSYSLOG -DNOSELECT -DFNFLOAT \ - -DDCLGETCWD -DNOGETUSERSHELL -DNO_DNS_SRV -DNOLEARN $(KFLAGS) \ - -Wc,-Nw260" - - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUX -DHPUX6 -DSIG_V -DNOSYSLOG -DNOSELECT -DFNFLOAT \ - -DDCLGETCWD -DNOGETUSERSHELL -DNO_DNS_SRV -DNOLEARN $(KFLAGS) \ - -Wc,-Nw260 $(OFLAGS)" "LNKFLAGS = -s" "LIBS = -lm $(LIBS)" - -#Exactly as above, plus curses: -hpux0650c: - @MESSAGE2=", but with curses" \ - $(MAKE) hpux0650 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DCK_CURSES $(KFLAGS)" \ - "LIBS= -lcurses" - -#Exactly as above, plus curses + network: -#(doesn't work -- HP-UX 6 lacks the FD_SET macros -- this can be addressed - -hpux0650tcpc: - @MESSAGE2=", but with curses and with tcp/ip" \ - $(MAKE) hpux0650 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DCK_CURSES -DTCPSOCKET -DNOHADDRLIST $(KFLAGS)" \ - "LIBS= -lcurses" - -#Exactly as hpux0650 but with compiler optimization: -hpux0650o: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0650 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS)" "OFLAGS = -O" - -#Exactly as hpux0650c but with compiler optimization: -hpux0650oc: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0650c KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS)" "OFLAGS = -O" - -#Take this as startup entry for all 'none optimized' files under HP-UX 7.x! -#Make sure we doesn't call it with the '-O' option because this will blow up -#the compiler! -hpux0700noopt: - @case "$(CFLAGS)" in \ - *-O*) echo "Don't use CFLAGS= -O here!" ;; \ - *) $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - ckuusr.$(EXT) ckuus3.$(EXT) ckuus4.$(EXT) ckuus5.$(EXT) \ - ckuus6.$(EXT) ckuus7.$(EXT) ckuxla.$(EXT) \ - ckcuni.$(EXT) ckcftp.$(EXT) ckcpro.$(EXT) \ - ;; \ - esac - -#HP-UX 7.0, no long filenames, no network support, no curses. -#If you get compiler warnings like 'Switch table overflow' increase the '...' -#value in '-Wc,-Nw...'! -hpux0700sf: - @$(MAKE) hpux-header - @echo 'supporting: NO long filenames, NO network, NO curses.' - $(MAKE) hpux0700noopt KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUX -DHPUX7 -DSIG_V -DNOGETUSERSHELL -DFNFLOAT \ - -DNO_DNS_SRV $(KFLAGS) -Wc,-Nw260" - - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUX -DHPUX7 -DSIG_V -DNOGETUSERSHELL -DFNFLOAT \ - -DNO_DNS_SRV $(KFLAGS) -Wc,-Nw260 $(OFLAGS)" \ - "LNKFLAGS = -s" "LIBS = -lm $(LIBS)" - -#Exactly as hpux0700sf but with compiler optimization: -hpux0700osf: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0700sf KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS)" "OFLAGS = -O" - -#HP-UX 7.0, short filenames, but with tcp/ip and curses. -#To use this, you must have bought the ARPA Services Product from HP, and you -#must have /usr/lib/libBSD.a. -hpux0700sftcpc: - @$(MAKE) hpux-header - @echo 'supporting: NO long filenames, \c' - @echo 'but with networking, curses, HDB uucp...' - $(MAKE) hpux0700noopt KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V \ - -DCK_REDIR -DCK_RTSCTS -DCK_CURSES -DNOGETUSERSHELL -DFNFLOAT \ - -DNO_DNS_SRV -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" $(KFLAGS) \ - -Wc,-Nw260" - - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V \ - -DCK_REDIR -DCK_RTSCTS -DCK_CURSES -DNOGETUSERSHELL -DFNFLOAT \ - -DNO_DNS_SRV -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" $(KFLAGS) \ - -Wc,-Nw260 $(OFLAGS)" "LNKFLAGS = -s" "LIBS= -lm -lBSD -lcurses" - -#Exactly as above but with compiler optimization: -hpux0700osftcpc: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0700sftcpc KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS)" "OFLAGS = -O" - -#HP 9000 series 300/800 HP-UX 7.0, long filenames, network support, HDB uucp, -#but NO curses. See comments in hpux0700sftcpc about TCP/IP support. -hpux0700lfn: - @$(MAKE) hpux-header - @echo 'supporting: long filenames, networking, HDB uucp$(MESSAGE2)...' - $(MAKE) hpux0700noopt KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V -DFNFLOAT \ - -DNOGETUSERSHELL -DNOSETBUF -DCK_REDIR -DCK_RTSCTS -DLONGFN \ - -DNO_DNS_SRV -DDIRENT -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" \ - $(KFLAGS) -Wc,-Nw260" - - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUXDEBUG -DHPUX -DHPUX7 -DTCPSOCKET -DSIG_V -DFNFLOAT \ - -DNOGETUSERSHELL -DNOSETBUF -DCK_REDIR -DCK_RTSCTS -DLONGFN \ - -DNO_DNS_SRV -DDIRENT -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" \ - $(KFLAGS) -Wc,-Nw260 \ - $(OFLAGS)" "LNKFLAGS = -s" "LIBS = -lm -lBSD $(LIBS)" - -#Exactly as above + curses. -hpux0700lfnc: - @MESSAGE2=', curses' \ - $(MAKE) hpux0700lfn KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= -DCK_CURSES $(KFLAGS)" \ - "LIBS= -lcurses" - -#Exactly as above hpux0700lfn but with compiler optimization: -hpux0700olfn: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0700lfn KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS)" "OFLAGS = -O" - -#Exactly as above hpux0700lfnc but with compiler optimization: -hpux0700olfnc: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0700lfnc KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS)" "OFLAGS = -O" - -#HP 9000 Series 300 or 400, HP-UX 8.0, long filenames and TCP/IP support. -#This one should also work on 700/800, but without PA-specific optimization. -#In case -DCK_RTSCTS and -DCK_REDIR make trouble, remove them. -#NOTE: ckcpro.c, ckuusr.c and ckuus3.c blow up the optimizer, so don't optimize -#them. -#For HP-UX 8.0 on Motorola CPUs, you might have to reinstall your kernel with -#maxdsiz >= 0x03000000. But if physical memory is small, that still will not -#help much. -hpux0800: - @$(MAKE) hpux-header - @MESSAGE3=$${MESSAGE3:='TCP/IP'}; \ - echo "supporting: long filenames, $$MESSAGE3, HDB UUCP$(MESSAGE2)..." - $(MAKE) -B "CC=$(CC)" "CC2=$(CC2)" KTARGET=$${KTARGET:-$(@)} \ - ckcpro.$(EXT) ckuusr.$(EXT) ckuus3.$(EXT) \ - "CFLAGS = -DCK_REDIR -DHPUXDEBUG -DHPUX -DHPUX8 -DRENAME -DSIG_V \ - -DNOSETBUF -DDIRENT -DCK_RTSCTS -DSTERMIOX -DLONGFN -DTCPSOCKET \ - -DHDBUUCP -DNO_DNS_SRV -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT \ - $(KFLAGS)" - - $(MAKE) -B "CC=$(CC)" "CC2=$(CC2)" xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DCK_REDIR -DHPUXDEBUG -DHPUX -DHPUX8 -DRENAME -DSIG_V \ - -DNOSETBUF -DDIRENT -DCK_RTSCTS -DSTERMIOX -DLONGFN -DTCPSOCKET \ - -DHDBUUCP -DNO_DNS_SRV -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT \ - $(KFLAGS) $(OFLAGS)" "LNKFLAGS = -s" "LIBS = -lm -lBSD $(LIBS)" - -#Exactly as above hpux0800 + curses. -hpux0800c: - @MESSAGE2=', curses' \ - $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS) -DCK_CURSES" "LIBS = -lcurses" - -#HP 9000 HP-UX 8.0, no TCP/IP because /usr/lib/libBSD.a can't be found, -#or TCP/IP header files missing. -hpux0800notcp: - @MESSAGE3='NO network, NO curses' \ - $(MAKE) "MAKE=$(MAKE)" hpux0800 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS) -UTCPSOCKET" - -#Now the same as above hpux0800 but with compiler optimization -hpux0800o: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS)" "OFLAGS = -O" - -#Exactly as above hpux0800 + curses and with compiler optimization. -hpux0800oc: - @MESSAGE1="with compiler optimization" \ - $(MAKE) hpux0800c KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS)" "OFLAGS = -O" "LIBS = -lcurses" - -#Exactly as above hpux0800notcp but with compiler optimization -hpux0800onotcp: - @MESSAGE1="with compiler optimization" \ - $(MAKE) "MAKE=$(MAKE)" hpux0800notcp KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS)" "OFLAGS = -O" - -#HP 9000 Series 700 or 800, HP-UX 8.0, long filenames and TCP/IP support. -# Like the previous entries, but with PA-RISC-specific optimization. -hpux0800pa: - @MESSAGE1="with PA-RISC-specific optimization" \ - $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS) +Obb1100" - -#As above, but with curses. -hpux0800pac: - @MESSAGE1="with PA-RISC-specific optimization" \ - $(MAKE) hpux0800c KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS) +Obb1100" - -#As above, but compiled with GCC 2.3.3. -hpux0800pagcc: - @MESSAGE1='using the gcc compiler' \ - $(MAKE) hpux0800 KTARGET=$${KTARGET:-$(@)} \ - "CC=gcc" "CC2=gcc" "KFLAGS= -funsigned-char $(KFLAGS)" - -#HP-UX 9.0, 9.01, 9.03, 9.04, 9.05, 9.07, 9.10 ..., + TCP/IP + curses, fully -#configured. Use this entry with the restricted compiler: no optimization, no -#ANSI support. If you get unresolved sockets library references at link time, -#then try adding -lBSD to LIBS, or else remove -DTCPSOCKET to build a version -#without TCP/IP support. -hpux0900: - @MESSAGE1A='. Read hpux0900 entry comments if you have trouble.' \ - $(MAKE) hpux-header - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DHPUXDEBUG -DHPUX9 -DSTERMIOX -DDIRENT -DUTIMEH \ - -DNOSETBUF -DCK_CURSES -DTCPSOCKET -DRENAME -DCK_REDIR -DLONGFN \ - -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS = -lm -lcurses" "CC=$(CC)" "CC2=$(CC2)" - -#Like hpux0900, but for the "value-added" compiler on all HP 9000 models. -#Adds optimization and ANSI compilation: -# +O2 makes smaller executable (= -O = Level-1 and global optimization) -# +O3 adds interprocedural global optimization, makes bigger executable. -# If optimization fails on some modules, you can add: -# +Obb, +Olimit , or +Onolimit, depending on your cc version, -# where is a number, e.g. +Obb1200. In other words, if you get optimizer -# warnings, add (for example) +Obb1200; if you still get optimizer warnings, -# increase the number. Repeat until warnings go away. If your compiler -# permits it, use +Onolimit. If optimizer blows up on ckcpro.c, see next entry. -# Reportedly, on some configurations, such as HP9000/425e or /340, perhaps -# depending on the amount of main memory, this entry might fail no matter what -# you do ("Out of Memory", "cc: Fatal error in /lib/c.c1", etc). In that case -# use "make hpux0900" (no "o"). -hpux0900o: - @MESSAGE1=$${MESSAGE1:-"with compiler optimization"} \ - $(MAKE) hpux0900 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS) -Aa -DCK_ANSIC -D_HPUX_SOURCE +O2" - -# For HP-UX 9.0 on Motorola CPUs, optimization of ckcpro.c tends to blow up -# the compiler. You might have to reinstall your kernel with maxdsiz >= -# 0x03000000. But if physical memory is small, that still will not help much. -# In that case, use this entry to skip optimization of ckcpro.c. But for -# C-Kermit 8.0.208 you need a kernel with maxdsiz >= 0x02000000 to compile an -# optimized ckcftp.c. -hpux0900m68ko: - @MESSAGE1='without compiler optimization for ckcpro.$(EXT) ...' \ - $(MAKE) hpux-header - $(MAKE) ckuusr.$(EXT) ckuus3.$(EXT) ckcpro.$(EXT) \ - "CFLAGS = -DHPUXDEBUG -DHPUX9 -DSTERMIOX -DDIRENT \ - -DNOSETBUF -DCK_CURSES -DTCPSOCKET -DRENAME -DCK_REDIR -DLONGFN \ - -DHDBUUCP -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DFNFLOAT $(KFLAGS)" - @echo - @MESSAGE1="with compiler optimization for the rest" \ - $(MAKE) hpux0900 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS) -Aa -DCK_ANSIC -D_HPUX_SOURCE +O2" - -# Old name for hpux0900m68ko. -hpux0900mot: - $(MAKE) hpux0900m68ko KTARGET=$${KTARGET:-$(@)} "KFLAGS = $(KFLAGS)" - -#Like hpux0900o but with additional model-700/800-specific optimizations. -# +ESlit = consolidate strings in read-only memory. -# +ESfsc = inline millicode calls when comparing pointers. -hpux0900o700: - @echo 'If you get optimizer warnings \c' - @echo 'try "make hpux0900o700 KFLAGS=+Obb1200"' - @MESSAGE1="with PA-RISC-specific optimizations" \ - $(MAKE) hpux0900o KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS = $(KFLAGS) +ESlit +ESsfc" - -#HP-UX 9.0, 9.01, 9.03, 9.04, 9.05, 9.07, 9.10 ..., + TCP/IP + curses, fully -#configured, built with gcc, all models except 800 series. -#You might need to add the include path for gcc headers, for example: -# 'KFLAGS=-I/usr/gnu/lib/gcc-lib/hppa1.1-hp-hpux/2.4.5/include/' -hpux0900gcc: - @MESSAGE1='using the gcc compiler' \ - $(MAKE) hpux0900 KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "KFLAGS = $(KFLAGS) -DCK_ANSIC -funsigned-char -O2" - -#HP-9000 HP-UX 10.0 + TCP/IP + curses, fully configured. -#Use with restricted (bundled) compiler: no optimization, no ANSI support. -#libcurses needed for fullscreen file xfer display in HP-UX 10.00 and 10.01. -#libHcurses (NOT libcurses!) for fullscreen display, to work around fatal bugs -#in HP-UX 10.10 and 10.20 curses. Maybe we could use lcurses for 10.30, since -#the 10.10 curses problem is supposedly fixed in 10.30. -# +DA1.0 = Generate PA-RISC 1.0 code that runs on both 700 and 800 models. -# +DA1.1 = Generate PA-RISC 1.1 code that runs on both 700 and 800 models. -# Note that HP-UX 10.20 and upwards not support PA-RISC 1.0 systems. -# And that as of Dec 2001, 11.00 and 11.11 are PA-only and 11.20 is IA64-only. -# Later 11.2x releases are expected to be for both. Architecture can be -# determined with the model command, at least in 10.20 and later... -#For future releases, we need to include +DA1.1 for PA builds, so that a -#binary built on PA 2.0 will still work on PA 1.1 machines, whereas +DA1.1 -#must NOT be included for IA64 builds. -# -hpux1000: - @$(MAKE) hpux-header - @LIBS='-lHcurses' ; \ - AFLAGS='+DA1.1' ; \ - case `uname -r` in \ - [AB].10.0*) KFLAGS='-DHPUX1000 $(KFLAGS)' ; \ - AFLAGS='+DA1.0' ; LIBS='-lcurses' ;; \ - [AB].10.1*) KFLAGS='-DHPUX1010 -D__HP_CURSES $(KFLAGS)' ; \ - ;; \ - [AB].10.2*) KFLAGS='-DHPUX1020 -D__HP_CURSES $(KFLAGS)' ; \ - ;; \ - [AB].10.3*) KFLAGS='-DHPUX1030 -D__HP_CURSES $(KFLAGS)' ; \ - ;; \ - [AB].10.?*) KFLAGS='-DHPUX10XX -D__HP_CURSES $(KFLAGS)' ; \ - ;; \ - [AB].11.0*) KFLAGS='-DHPUX1100 -D__HP_CURSES $(KFLAGS)' ; \ - ;; \ - [AB].11.1*) KFLAGS='-DHPUX1100 -D__HP_CURSES $(KFLAGS)' ; \ - ;; \ - [AB].11.?*) KFLAGS='-DHPUX1100 -D__HP_CURSES $(KFLAGS)' ; \ - AFLAGS='' ; LIBS='-lcurses' ;; \ - esac ; \ - OFLAGS=$${OFLAGS:-$$AFLAGS} ; \ - $(MAKE) "SHELL=/usr/bin/sh" xermit KTARGET=$${KTARGET:-$(@)} \ - "CC=$(CC)" "CC2=$(CC2)" \ - "CFLAGS = -DHPUX10 -DDIRENT -DSTERMIOX -DCK_DSYSINI -DHDBUUCP \ - -DCK_CURSES -DCK_WREFRESH -DTCPSOCKET -DCK_REDIR -DRENAME -DFNFLOAT \ - $$KFLAGS $$OFLAGS" \ - "LNKFLAGS=-s $(LNKFLAGS)" "LIBS = -lm $$LIBS $(KLIBS)" - -# This is a kludge, copying hpux0900gcc and adapting hpux1000 -# (add CC and CC2, drop the A1.[0||1]) -# Builds w/ no compiler warnings but minimally tested. -# -hpux1000gcc: - @MESSAGE1="using the gcc compiler $(MESSAGE1)" \ - $(MAKE) hpux1000 KTARGET=$${KTARGET:-$(@)} CC=gcc CC2=gcc \ - "KFLAGS = $(KFLAGS)" OFLAGS=" -DCK_ANSIC -funsigned-char -O2" - -# Trusted HP-UX 10 -# echo KFLAGS=$(KFLAGS) YTARGET YTARGET=$(YTARGET) $(XTARGET) ; -hpux1000t: - @case "$(KTARGET)" in \ - *+openssl) \ - KENTRY=hpux1000o+openssl ;; \ - *gcc) \ - KENTRY=hpux1000gcc ;; \ - *o+) KENTRY=hpux1000o+ ;; \ - *o) KENTRY=hpux1000o ;; \ - *) KENTRY=hpux1000 ;; \ - esac ; \ - MESSAGE1="and support for 'Trusted HP-UX'" \ - $(MAKE) $$KENTRY KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $(KFLAGS) -DHPUX10_TRUSTED" "KLIBS=-lsec" - -hpux1000to: - $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)} - -hpux1000to+: - $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)} - -hpux1000tgcc: - $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)} - -hpux1000to+openssl: - $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)} - -hpux1000tgcc+openssl: - $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)} - -#HP-9000 HP-UX 10.00 and higher with ANSI prototyping and optimization. -#PA-RISC only, no Motorola or other hardware is support in HP-UX 10.00++. -#The unbundled optional compiler is required. -#Your path should start with /opt/ansic/bin. -# -Wl,-Fw = Remove stack unwind table (info used by debuggers). -# +O2 makes a smaller executable (= -O = Level-1 and global optimization). -# +O3 adds interprocedural global optimization, makes a bigger executable. -# +Onolimit allows all modules to be optimized, no matter how complex. But: -# (a) +Onolimit does not seem to always be there in HP-UX 10.00, and: -# (b) some modules might take hours on low-memory and/or slow systems. -# The following are PA-RISC-specific optimizations: -# +ESlit = Consolidate strings in read-only memory. -# +ESfsc = Inline millicode calls when comparing pointers. -# You might need to configure your kernel for a maxdsiz of 0x0B000000 (176MB) -# or greater to prevent the optimizer from running out of space. -# December 2001: +ESlit +ESsfc removed because not supported on IA64. -# Somebody who cares can use 'model' to see whether it's PA-RISC or IA64 -# and include the architecture-specific optimization flags. Also note: -# +DA1.1 is PA-only. If this is included in in HP-UX 11.00 or later, -# then +DS2.0 should be included too (but don't use +DS2.0 without +DA1.1, -# or else the binary won't run on older PA hardware). -hpux1000o: - @case `uname -m` in \ - ia64) ;; \ - *) MFLAGS='+ESlit +ESsfc' ;; \ - esac ; \ - MESSAGE1="with PA-RISC-specific optimizations $(MESSAGE1)" \ - $(MAKE) "SHELL=/usr/bin/sh" "PATH=/opt/ansic/bin:$$PATH" hpux1000 \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = $(KFLAGS) \ - -Aa -D_HPUX_SOURCE -DCK_ANSIC -DUTIMEH \ - +O2 -Wl,-Fw $$MFLAGS" - -#Like hpux1000o but with "+Onolimit". -#On 700 series set kernel parameter maxdsiz >= 0x0D000000 (=208MB). -#Takes a long time. -hpux1000o+: - @MESSAGE1="and +Onolimit $(MESSAGE1)" KTARGET=$${KTARGET:-$(@)} \ - $(MAKE) hpux1000o \ - "KFLAGS = $(KFLAGS) +Onolimit" - -#HP-UX 10.xx + 11.xx with optimizing ANSI compiler and OpenSSL. -#Define SSLLIB and SSLINC appropriately for your OpenSSL installation. -#Do overwrite the default SSLLIB and SSLINC settings you can also use the -#command-line variable KSSLLIB and KSSLINC like: -#make hpux1000o+openssl KSSLLIB=-L/opt/openssl/lib KSSLINC=-I/... -#Ditto for the Zlib location. -#This entry works for C-Kermit 8.0.206 on HP-UX 10.20 + 11.11 -#with OpenSSL 0.9.6 + 0.9.7 -#NOTE: an ANSI C compiler is required for the SSL interface. If you don't -#have the HP Optimizing ANSI compiler, see the hpux1000gcc+openssl target -#below. -hpux1000o+openssl: - @case "$(KTARGET)" in \ - *gcc+*) KENTRY=hpux1000gcc ;; \ - *) KENTRY=hpux1000o ;; \ - esac ; \ - SSLINC=$${KSSLINC:-$(SSLINC)}; \ - SSLLIB=$${KSSLLIB:-$(SSLLIB)}; \ - MESSAGE1="and with OpenSSL $(MESSAGE1)" \ - $(MAKE) $$KENTRY KTARGET=$${KTARGET:-$(@)} \ - KFLAGS="-DCK_AUTHENTICATION -DCK_SSL -DOPENSSL_097 -DZLIB \ - $$SSLINC $(KFLAGS)" \ - KLIBS="$(KLIBS) \ - $$SSLLIB -lssl -lcrypto \ - -L/opt/zlib/lib -lz \ - " - -#HP-UX 10.00 or higher with OpenSSL 0.9.7. Compiled with gcc. -#From Chris Chaney, NEC America Inc. His instructions: -# (1) Install gcc version 3.2.3 & binutils version 2.13.2 -# (used binary depot from http://hpux.cs.utah.edu/) -# (2) Install gcc make version 3.80 from http://hpux.cs.utah.edu/ -# -# or: gcc 2.9.2000-12-1 from "Linux to hp-ux 11.0/11i porting kit version 1.0 -# (2CD)" free from: http://www.software.hp.com -# -# (3) Install openSSL version 0.9.7b from http://www.software.hp.com -# (4) Install flex version 2.5.4 from http://hpux.cs.utah.edu/ -# (5) Install gmp version 3.1.1 from http://hpux.cs.utah.edu/ -# -#Note from Peter Eichhorn, assyst Munich. It works also without gcc make! -hpux1000gcc+openssl: - $(MAKE) hpux1000o+openssl KTARGET=$${KTARGET:-$(@)} - -# Same for HP-UX 11 -hpux1100o+openssl: - $(MAKE) hpux1000o+openssl KTARGET=$${KTARGET:-$(@)} - -hpux1100gcc+openssl: - $(MAKE) hpux1000gcc+openssl KTARGET=$${KTARGET:-$(@)} - -# HP-UX 11 -hpux1100: - $(MAKE) hpux1000 KTARGET=$${KTARGET:-$(@)} - -hpux1100o: - $(MAKE) hpux1000o KTARGET=$${KTARGET:-$(@)} - -hpux1100o+: - $(MAKE) hpux1000o+ KTARGET=$${KTARGET:-$(@)} - -hpux1100gcc: - $(MAKE) hpux1000gcc KTARGET=$${KTARGET:-$(@)} - -# Trusted HP-UX 11 -hpux1100t: - $(MAKE) hpux1000t KTARGET=$${KTARGET:-$(@)} - -hpux1100to: - $(MAKE) hpux1000to KTARGET=$${KTARGET:-$(@)} - -hpux1100to+: - $(MAKE) hpux1000to+ KTARGET=$${KTARGET:-$(@)} - -hpux1100tgcc: - $(MAKE) hpux1000tgcc KTARGET=$${KTARGET:-$(@)} - -hpux1100to+openssl: - $(MAKE) hpux1000to+openssl KTARGET=$${KTARGET:-$(@)} - -hpux1100tgcc+openssl: - $(MAKE) hpux1000tgcc+openssl KTARGET=$${KTARGET:-$(@)} - -#Regulus on CIE Systems 680/20 -cie: - @echo 'Making C-Kermit $(CKVER) for CIE Systems 680/20 Regulus...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DATTSV -DNOFILEH -DCIE -DNOLEARN $(KFLAGS) -O" "LNKFLAGS =" - -# Linux 1.2 or later with gcc, dynamic libraries, ncurses, TCP/IP. -# -# If your Linux system has curses rather than ncurses, use the linuxc -# entry, or if that doesn't work, linuxnc. -# -# The Kermit "large memory model" is used by default to configure big packet -# and script buffers, etc. For small-memory or limited-resource systems, -# "make linux KFLAGS=-DNOBIGBUF". -# -# -DLINUXFSSTND (Linux File System Standard 1.2) gives UUCP lockfile /var/lock -# with string pid. Remove this to get /usr/spool/uucp with int pid, used in -# very early Linux versions. FSSTND 1.2 also says that the PID string in the -# UUCP lock file has leading spaces. This is a change from FSSTND 1.0, which -# used leading zeros. Add -DFSSTND10 to support FSSTND 1.0 instead of 1.2. -# I hope subsequent editions of the file-system standard did not change these -# again. -# -# Add -DOLINUXHISPEED (Old Linux High Speed support) to turn on an ugly kludge -# in Linux 1.0 and earlier to support speeds of 57600 and 115200. Extremely -# old Linux systems (pre-0.99pl15) will not support this. If OLINUXHISPEED is -# not defined, then only the standard POSIX termios methods of setting the port -# speed will be used, and in this case speeds can be as high as 460800 in most -# modern Linux versions. -# -# -DCK_POSIX_SIG (POSIX signal handling) is good for Linux releases back to at -# least 0.99.14; if it causes trouble for you, remove it from the CFLAGS. -# -# -pipe removes the need for temp files - remove it if it causes trouble. -# -# -funsigned-char makes all characters unsigned, as they should have been -# in the first place. -# -# Add -DCK_DSYSINI if you want a shared system-wide init file. -# -# See ckubwr.txt about -DNOCOTFMC. In fact, you really should read the -# entire Linux section of ckubwr.txt. -# -# The "linuxa" entry can be referenced directly on LIBC systems, but not -# GLIBC, where -lcrypt is required. The "make linux" entry should normally -# be used for all builds on all Linux distributions unless you have special -# requirements, in which case keep reading. CK_NEWTERM added after 7.0B04 -# due to new complaints about ncurses changing buffering of tty. - -linuxa: - @echo 'Making C-Kermit $(CKVER) for Linux 1.2 or later...' - @echo 'IMPORTANT: Read the comments in the linux section of the' - @echo 'makefile if you have trouble.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -DLINUX -pipe -funsigned-char -DFNFLOAT -DCK_POSIX_SIG \ - -DCK_NEWTERM -DTCPSOCKET -DLINUXFSSTND -DNOCOTFMC -DPOSIX \ - -DUSE_STRERROR $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" "LIBS = $(LIBS) -lm" - -# As above but with profiling -linuxp: - $(MAKE) linuxa KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS) -pg" \ - "LIBS=-pg -lcrypt -lresolv" - -#New primary Linux entry for C-Kermit 8.0, replacing big nested -#if-then-else construction full of repeated clauses with a simpler scheme -#for automatically detecting: -# . Old versus new pty handling (new == glibc 2.1++) -# . Presence or absence of librypt.a and -# . Presence or absence of libresolv.a -#Unlike the previous scheme, this one is easily extended to include more tests. -#Note: The HAVE_PTMX test was previously "if test -c /dev/ptmx" but this was -#not sufficient for Debian 2.1, because although it had /dev/ptmx, it did not -#have grantpt(), unlockpt(), or ptsname(), so has been changed to look for a -#grantpt() prototype in the header files. Warning: uses a temporary file in -#the current directory. Modified in 8.0.206 to allow for libraries that -#contain .so's but no .a's, e.g. Mandrake 9.0. -#HAVE_BAUDBOY added in 8.0.210 for Red Hat -- it's like AIX ttylock(). -linux: - @if test \ - `grep grantpt /usr/include/*.h /usr/include/sys/*.h | wc -l` -gt 0; \ - then if test -c /dev/ptmx; then HAVE_PTMX='-DHAVE_PTMX'; \ - else HAVE_PTMX=''; fi; fi ; \ - if test -f /usr/include/baudboy.h ; \ - then HAVE_BAUDBOY='-DHAVE_BAUDBOY' ; \ - else HAVE_BAUDBOY='' ; fi ; \ - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DCK_NCURSES -I/usr/include/ncurses \ - $$HAVE_PTMX $$HAVE_BAUDBOY \ - `if test -f /usr/include/crypt.h; then echo -DHAVE_CRYPT_H; fi` \ - $(KFLAGS)" \ - "LIBS=-lncurses \ - `if test -f /usr/lib/libresolv.a || test -f /usr/lib/libresolv.so; \ - then echo -lresolv; fi` \ - `if test -f /usr/lib/libcrypt.a || test -f /usr/lib/libcrypt.so; \ - then echo -lcrypt; fi`" \ - linuxa - -# As above but for Linux systems that have no . -linuxns: - $(MAKE) linux KTARGET=$${KTARGET:-$(@)} KFLAGS=-DNO_SYS_SELECT_H - -# As above, but forces use of curses rather than ncurses. -# Add -ltermcap to LIBS if necessary. -# Also watch out for libcurses and/or libtermcap having been moved. -# In that case you might need something like: -# "LIBS = -L/usr/lib/curses -lcurses -L/usr/lib/termcap -ltermcap" - -linuxc: - @if test \ - `grep grantpt /usr/include/*.h /usr/include/sys/*.h | wc -l` -gt 0; \ - then if test -c /dev/ptmx; then HAVE_PTMX='-DHAVE_PTMX'; \ - else HAVE_PTMX=''; fi; fi ; \ - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DCK_CURSES $$HAVE_PTMX \ - `if test -f /usr/lib/libcrypt.a; then echo -DHAVE_CRYPTH; fi` \ - $(KFLAGS)" \ - "LIBS=-lcurses \ - `if test -f /usr/lib/libresolv.a; then echo -lresolv; fi` \ - `if test -f /usr/lib/libcrypt.a; then echo -lcrypt; fi`" \ - linuxa - -# As above but with with no curses support, for example because you installed -# the developer tools but did not install (n)curses. -linuxnc: - @if test \ - `grep grantpt /usr/include/*.h /usr/include/sys/*.h | wc -l` -gt 0; \ - then if test -c /dev/ptmx; then HAVE_PTMX='-DHAVE_PTMX'; \ - else HAVE_PTMX=''; fi; fi ; \ - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS= $$HAVE_PTMX \ - `if test -f /usr/lib/libcrypt.a; then echo -DHAVE_CRYPTH; fi` \ - $(KFLAGS)" "LIBS= \ - `if test -f /usr/lib/libresolv.a; then echo -lresolv; fi` \ - `if test -f /usr/lib/libcrypt.a; then echo -lcrypt; fi`" \ - linuxa - -#Sharp Zaurus SL-5500 - Linux based -zsl5500: - @echo 'Making C-Kermit $(CKVER) for Sharp Zaurus SL-5500...' - @touch ckcpro.c - @touch wart - $(MAKE) linuxnc KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DZSL5500" \ - "CC = gcc" "CC2 = gcc" - -# A minimum-size version for Linux that does only scripting and -# serial communication -- no networks, no file transfer. -linuxso: - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -DLINUX -pipe -funsigned-char -DPOSIX -DCK_POSIX_SIG \ - -DLINUXFSSTND -DNOCOTFMC -DNOXFER -DNODEBUG -DNOCSETS -DNOHELP \ - -DNONET -DMINIDIAL -DNOSCRIPT -DNOIKSD -DNOPUSH $(KFLAGS)" \ - "LNKFLAGS = $(LNKFLAGS)" "LIBS = " - -#Mklinux DR3 has horrible bug in - see ckufio.c. -mklinux: - $(MAKE) KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DUTMPBUG" \ - "LIBS=-lcrypt -lresolv" linuxa - -#LinuxPPC 1999 -linuxppc: - @echo 'Making C-Kermit $(CKVER) for LinuxPPC 1999...' - @if test -f /usr/lib/libcrypt.a; then \ - if test -f /usr/lib/libresolv.a; then \ - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(NCURSES_CPP) -DHAVE_CRYPT_H \ - -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \ - "LIBS=-lncurses -lresolv -lcrypt" linuxa ; \ - else \ - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(NCURSES_CPP) -DHAVE_CRYPT_H \ - -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \ - "LIBS=-lncurses -lcrypt" linuxa ; \ - fi \ - else \ - if test -f /usr/lib/libresolv.a; then \ - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(NCURSES_CPP) \ - -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \ - "LIBS=-lncurses -lresolv" linuxa ; \ - else \ - $(MAKE) KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(NCURSES_CPP) \ - -DLOCK_DIR=\\\\\\"\"/var/lock/modem\\\\\\"\" $(KFLAGS)" \ - "LIBS=-lncurses" linuxa ; \ - fi \ - fi - - -# The remaining Linux entries are for special or customized builds. They -# have not been generalized like the ones above. Ideally, we should allow -# for every combination of libc vs glibc, gcc vs egcs, curses vs ncurses, -# Kerberos IV vs Kerberos V vs SRP (in any combination), and so on -- -# volunteers welcome. - -# If you get "Internal compiler error xxx, output pipe has been closed", -# try removing -pipe. - -# Like "make linux" but built with egcs rather than gcc. -linuxegcs: - @echo 'Making C-Kermit $(CKVER) for Linux 1.2 or later with egcs...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = egcs" "CC2 = egcs" \ - "CFLAGS = -O -DLINUX -pipe -funsigned-char \ - -DPOSIX -DCK_POSIX_SIG -DCK_NCURSES -DNOCOTFMC \ - -DTCPSOCKET -DLINUXFSSTND $(KFLAGS)" \ - "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lncurses -lcrypt -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.1 (no K4 compatibility). -linux+krb5: - @echo 'Making C-Kermit $(CKVER) for Linux on Intel with Kerberos...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 \ - -DCK_ENCRYPTION -DCK_DES -DCK_CURSES -DCK_POSIX_SIG \ - -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H $(K5INC) $(K5INC)/krb5 \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) -lncurses -ltermcap -ldes425 -lkrb5 \ - -lcom_err -lk5crypto -lgssapi_krb5 -lcrypt -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.1 with K4 compatibility. -# -# Requires the Kerberos 1.2.1 be compiled with KRB4 compatibility. -linux+krb5+krb4: - @echo 'Making C-Kermit $(CKVER) for Linux on Intel with Kerberos...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_DES -DCK_CURSES -DCK_POSIX_SIG \ - -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H $(K5INC) $(K5INC)/krb5 \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) -lncurses -ltermcap -lkrb4 -ldes425 -lkrb5 \ - -lcom_err -lk5crypto -lcrypt -lgssapi_krb5 -lresolv" - -# Linux on Intel PC with SRP 1.7.4 using GNU MP, Krypto, and Eric Young's -# DES library. Remove the -DCK_DES, -DLIBDES and -ldes if you do not have -# Eric Young's# libdes.a installed. -# -linux+srp+gmp: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...' - $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) \ - -lncurses -ltermcap -lsrp -lgmp -ldes -lkrypto -lcrypt -lresolv" - -linux+srp+gmp+no-des: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP ...' - $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP \ - -DCK_ENCRYPTION -DCK_CAST \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) \ - -lncurses -ltermcap -lsrp -lgmp -lkrypto -lcrypt -lresolv" - -linux+srp+gmp-export: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...' - $(MAKE) srpmit-export KTARGET=$${KTARGET:-$(@)} \ - "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DFNFLOAT \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) \ - -lncurses -ltermcap -lsrp -lgmp -lkrypto -lcrypt -lm -lresolv" - -linux+srp+gmp+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...' - $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DCK_PAM -DFNFLOAT $(SRPINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) -lncurses -ltermcap -lsrp -lgmp -ldes -lkrypto \ - -lcrypt -lpam -ldl -lm -lresolv" - -#Linux on Intel PC with SRP 1.7.4 built with OpenSSL for Big Number Math -#and Cryptographic functionality. -# -linux+srp: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...' - $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(SRPINC) $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(SSLLIB) \ - -lncurses -ltermcap -lsrp -lkrypto -lcrypto -lcrypt -lresolv" - -linux+srp+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...' - $(MAKE) srpmit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DCK_PAM -DFNFLOAT $(SRPINC) $(SSLINC) $(KFLAGS)" \ - "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(SSLLIB) -lncurses -ltermcap -lsrp -lkrypto \ - -lcrypto -lcrypt -lpam -ldl -lm -lresolv" - -linux+shadow+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with Shadow+PAM...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DCK_SHADOW -DCK_PAM -DFNFLOAT \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = -lncurses -ltermcap -lcrypt -lpam -ldl -lm -lresolv" - -#Linux configured for SSL/TLS. -#Remove -ltermcap if it causes trouble e.g. in Debian 2.2. -#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+openssl: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SSL/TLS...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SSL \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DFNFLOAT $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS= $(SSLLIB) \ - -lncurses -ltermcap -lssl -lcrypto -lm -lresolv -lcrypt" - -#Linux configured for SSL/TLS and Shadow Passwords -#Remove -ltermcap if it causes trouble e.g. in Debian 2.2. -#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+openssl+shadow: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SSL/TLS...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SSL \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DFNFLOAT -DCK_SHADOW $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS= $(SSLLIB) \ - -lncurses -ltermcap -lssl -lcrypto -lm -lresolv -lcrypt" - -#Linux configured for SSL/TLS, ZLIB, PAM and Shadow Passwords -#Remove -ltermcap if it causes trouble e.g. in Debian 2.2. -#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+openssl+zlib+shadow+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SSL/TLS...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SSL -DCK_PAM -DZLIB \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DFNFLOAT -DCK_SHADOW $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS= $(SSLLIB) \ - -lncurses -ltermcap -lssl -lcrypto -lm -lresolv -lcrypt -lz -lpam -ldl" - -#Linux on Intel PC with SRP and SSL/TLS. -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 or higher to be compiled with KRB4 compatibility. -#Remove -ltermcap if it causes trouble e.g. in Debian 2.2. -#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+srp+openssl: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(SRPINC) $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(SSLLIB) \ - -lncurses -ltermcap -lsrp -lssl -lkrypto -lcrypto \ - -lcrypt -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2 and SRP. -# -# libsrp.a should be build with GNU MP (libgmp.a) -# instead of AT&T CryptoLib (libcrypt.a) due to naming conflicts with -# standard distribution Linux libraries. -# Requires the Kerberos 1.2.2 or higher to be compiled with KRB4 compatibility. -linux+krb5+krb4+srp: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB54+SRP...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SRPINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SRPLIB) \ - -lncurses -ltermcap -lsrp -lgmp -lgssapi_krb5 -lkrypto \ - -ldes -lkrb4 -ldes425 -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP and SSL/TLS. -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 or higher to be compiled with KRB4 compatibility. -# Requires OpenSSL 0.9.6a or higher -#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+srp+openssl: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SRPLIB) $(SSLLIB) \ - -lncurses -ltermcap -lsrp \ - -lkrb4 -lssl -lkrypto -lcrypto \ - -lkrb5 -lcom_err -lk5crypto -lgssapi_krb5 -lcrypt -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SSL/TLS. -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -#If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+openssl: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SSLLIB) \ - -lncurses -ltermcap \ - -lkrb4 -lssl -lcrypto -lkrb5 -lcom_err \ - -lk5crypto -lgssapi_krb5 -lcrypt -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.1, SSL/TLS. -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+openssl+shadow: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_SHADOW \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SSLLIB) \ - -lncurses -ltermcap \ - -lkrb4 -lssl -lcrypto -lkrb5 -lcom_err \ - -lk5crypto -lgssapi_krb5 -lcrypt -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2, SSL/TLS. -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+openssl+zlib+shadow: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 -DZLIB \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_SHADOW \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SSLLIB) \ - -lncurses -ltermcap \ - -lkrb4 -lssl -lcrypto -lkrb5 -lcom_err \ - -lk5crypto -lgssapi_krb5 -lcrypt -lresolv -lz" - -linux+krb5+krb4+srp-export: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...' - $(MAKE) xermit-export KTARGET=$${KTARGET:-$(@)} \ - "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SRPINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(K5LIB) \ - -lncurses -ltermcap -lsrp -lgmp -lkrb4 -ldes425 -lkrb5 -lgssapi_krb5 \ - -lcom_err -lk5crypto -lkrypto -lcrypt -lresolv" - -linux+krb5+krb4+srp+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with SRP...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DCK_PAM $(K5INC) $(K5INC)/krb5 $(SRPINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(K5LIB) \ - -lncurses -ltermcap -lsrp -lgmp -ldes -lkrb4 -ldes425 -lkrb5 \ - -lcom_err -lk5crypto -lgssapi_krb5 -lkrypto -lcrypt -lpam -ldl \ - -lresolv" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP and SSL/TLS. -# and PAM. -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+srp+openssl+pam-debug: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...' - $(MAKE) xermit-debug KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -w -Dmalloc=dmalloc -Dfree=dfree -DMDEBUG $(K5INC) $(K5INC)/krb5 \ - $(SRPINC) $(SSLINC) $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \ - -lncurses -ltermcap -lsrp -lkrb4 -lssl -lkrypto -lcrypto \ - -lkrb5 -lcom_err -lk5crypto -lgssapi_krb5 -lcrypt -lresolv -lpam -ldl" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.1, SRP and SSL/TLS. -# and PAM. -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+srp+openssl+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \ - -lm -lncurses -ltermcap -lsrp \ - -lkrb4 -lssl -lkrypto -lcrypto -lgssapi_krb5 \ - -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP, OpenSSL -# with ZLIB and PAM -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+srp+openssl+zlib+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \ - -lm -lncurses -ltermcap -lsrp \ - -lkrb4 -lssl -lkrypto -lcrypto -lgssapi_krb5 \ - -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, SRP, OpenSSL -# with ZLIB, Shadow Passwords, and PAM -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+srp+openssl+zlib+shadow+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_SRP -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DCK_SHADOW $(K5INC) $(K5INC)/krb5 $(SRPINC) $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(SRPLIB) $(K5LIB) $(SSLLIB) \ - -lm -lncurses -ltermcap -lsrp -lkrypto \ - -lkrb4 -lssl -lcrypto -lgssapi_krb5 \ - -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, OpenSSL -# with Shadow Passwords, PAM -# -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -linux+krb5+krb4+openssl+shadow+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SSL,...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DCK_SHADOW $(K5INC) $(K5INC)/krb5 $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SSLLIB) \ - -lm -lncurses -ltermcap \ - -lkrb4 -lssl -lcrypto -lgssapi_krb5 \ - -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, OpenSSL -# with ZLIB, Shadow Passwords, PAM -# -# libsrp.a should be build with OpenSSL -# Requires the Kerberos 1.2.2 be compiled with KRB4 compatibility. -# If you have OpenSSL 0.9.7 or later, add -DOPENSSL_097 to KFLAGS. -linux+krb5+krb4+openssl+zlib+shadow+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB,SRP,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DKRB4 -DKRB524 \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - -DCK_SHADOW $(K5INC) $(K5INC)/krb5 $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SSLLIB) \ - -lm -lncurses -ltermcap \ - -lkrb4 -lssl -lcrypto -lgssapi_krb5 \ - -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz" - -#Red Hat 9 - full install includes Kerberos 5 (4 compat), PAM, SSL. -#Also works around bug in curses in which terminal goes dead after -#returning from file-transfer display. Assumes OpenSSL 0.9.7 or later. -redhat9: - @echo "Building SECURE Kermit for Red Hat 9.0..." - $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH90 -DOPENSSL_097 $(KFLAGS)" - -#Ditto plus SRP (which is not normally included with RH Linux). -redhat9+srp: - @echo "Building SECURE Kermit for Red Hat 9.0..." - $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH90 -DOPENSSL_097 $(KFLAGS)" - -#Red Hat Linux 8.0 - full install includes Kerberos 5 (4 compat), PAM, SSL. -#Also works around bug in curses in which terminal goes dead after -#returning from file-transfer display. -redhat80: - @echo "Building SECURE Kermit for Red Hat 8.0..." - $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH80 $(KFLAGS)" - -redhat80+srp: - @echo "Building SECURE Kermit for Red Hat 8.0..." - $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH80 $(KFLAGS)" - -#Red Hat Linux 7.3 - full install includes Kerberos 5 (4 compat), PAM, SSL. -#Also works around bug in curses in which terminal goes dead after -#returning from file-transfer display. -redhat73: - @echo "Building SECURE Kermit for Red Hat 7.3..." - $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH73 $(KFLAGS)" - -redhat73+srp: - @echo "Building SECURE Kermit for Red Hat 7.3..." - $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH73 $(KFLAGS)" - -#Red Hat Linux 7.2 - full install includes Kerberos 5 (4 compat), PAM, SSL. -#Also works around bug in curses in which terminal goes dead after -#returning from file-transfer display. -redhat72: - @echo "Building SECURE Kermit for Red Hat 7.2..." - $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH72 $(KFLAGS)" - -redhat72+srp: - @echo "Building SECURE Kermit for Red Hat 7.2..." - $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH72 $(KFLAGS)" - -#Red Hat Linux 7.1 - full install includes Kerberos 5 (4 compat), PAM, SSL. -#Also works around bug in curses in which terminal goes dead after -#returning from file-transfer display. -redhat71: - @echo "Building SECURE Kermit for Red Hat 7.1..." - $(MAKE) linux+krb5+krb4+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH71 $(KFLAGS)" - -redhat71+srp: - @echo "Building SECURE Kermit for Red Hat 7.1..." - $(MAKE) linux+krb5+krb4+srp+openssl+zlib+shadow+pam \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DRH71 $(KFLAGS)" - -#Linux on Intel PC with Cygnus or MIT Kerberos 5 1.2.2, OpenSSL -# with ZLIB and PAM and Shadow passwords -linux+krb5+openssl+zlib+shadow+pam: - @echo 'Making C-Kermit $(CKVER) for Linux on i386 with KRB5,SSL...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -g -O -funsigned-char -pipe -DPOSIX -DLINUX -DNOCOTFMC \ - -DCK_AUTHENTICATION -DCK_KERBEROS -DKRB5 -DCK_SHADOW \ - -DCK_ENCRYPTION -DCK_CAST -DCK_DES -DLIBDES -DCK_SSL -DCK_PAM -DZLIB \ - -DCK_CURSES -DCK_POSIX_SIG -DTCPSOCKET -DLINUXFSSTND -DHAVE_CRYPT_H \ - $(K5INC) $(K5INC)/krb5 $(SSLINC) \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" \ - "LIBS = $(K5LIB) $(SSLLIB) \ - -lm -lncurses -ltermcap -lssl -lcrypto -lgssapi_krb5 \ - -lkrb5 -lcom_err -lk5crypto -lcrypt -lresolv -lpam -ldl -lz" - -linuxnotcp: - $(MAKE) linux KTARGET=$${KTARGET:-$(@)} "KFLAGS = -DNONET $(KFLAGS)" - -# "make linuxnotcp" with lcc (see http://www.cs.princeton.edu/software/lcc) -# lcc does not understand various gcc extensions: -# "__inline__" -- can be eliminated by adding "-D__inline__=" -# "__asm__ and "long long" -- in header files, should be surrounded by -# "#ifndef(__STRICT_ANSI__)"/"#endif" -# however, TCP requires some __asm__ functions, so cannot be compiled -linuxnotcp-lcc: - @echo 'Making C-Kermit $(CKVER) for Linux with lcc ...' - @echo 'Read comments in makefile for additional information.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = lcc" "CC2 = lcc" \ - "CFLAGS = -DLINUX -DPOSIX -DCK_CURSES -DCK_POSIX_SIG \ - -UTCPSOCKET -DLINUXFSSTND -DNOLEARN $(KFLAGS)" \ - "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lcurses -ltermcap" - -# Linux 0.99.14 thru 1.0 with gcc, dynamic libraries, curses, TCP/IP. -# For Linux 1.2 or later, use "make linux" (above). -# -# -DLINUXFSSTND (Linux File System Standard) gives UUCP lockfile /var/lock with -# string pid. Remove this and get /usr/spool/uucp with int pid, which was used -# in early Linux versions. -# -# If you get compiler errors regarding , add -DNOHISPEED. -# -# -DCK_POSIX_SIG (POSIX signal handling) is good for Linux releases back to at -# least 0.99.14; if it causes trouble for you, just remove it. -# -# -DCK_CURSES: Here we link with the regular curses library. But you should -# be using ncurses. Internally, the ckuusx.c module includes , but -# this really should be . Thus if you have the new curses -# material, you should either install it with the standard names, or else -# create symbolic links from the standard names to the new ones. If you get -# compile-time errors complaining about data definitions in termcap.h, it -# means you have new kernel material mixed with older libc header files. To -# fix, add "#include " to the file. Or if all this is -# too confusing, create a new makefile entry based on this one, but with -# -DCK_CURSES removed from CFLAGS and the entire LIBS= clause removed. -# -# But wait, there's more. On most Linux systems, -ltermcap must be included -# in LIBS. But on others, the linker complains that libtermcap can't be -# found. In that case, try removing -ltermcap from LIBS=. -# -# But wait, there's more. The format of the PID string in the UUCP lockfile -# changed between Linux FSSTND 1.0 and 1.2. In the earlier standard, it had -# leading zeros; in the second, it has leading spaces. By default this entry -# uses the newer standard. To force the older one, add -DFSSTND10. -# -# "The nice thing about the Linux standard is there are so many to choose from" -# -# NOTE: Remove -DBIGBUFOK for small-memory or limited-resource systems. -linux10: - @echo 'Making C-Kermit $(CKVER) for Linux 1.0 or earlier...' - @echo 'IMPORTANT: Read the comments in the linux section of the' - @echo 'makefile if you get compilation or link errors.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -DPOSIX -DCK_CURSES -DCK_POSIX_SIG -DLINUX \ - -DTCPSOCKET -DLINUXFSSTND -DOLINUXHISPEED -DNOLEARN $(KFLAGS)" \ - "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lcurses -ltermcap" - -#This version was used for Linux prior to C-Kermit 6.0.192. -#Now the "Linux File System Standard" is considered standard, ditto TCP/IP. -linuxold: - @echo 'Making C-Kermit $(CKVER) for Linux...' - @echo 'For FSSTND-recommended UUCP lockfiles, use:' - @echo ' make linux "KFLAGS=-DLINUXFSSTND".' - @echo 'Read comments in makefile for additional options.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS = -O -DLINUX -DPOSIX -DCK_CURSES -DCK_POSIX_SIG -DNOLEARN \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS)" "LIBS = -lcurses -ltermcap" - -# LynxOS 2.2 with GCC compiler, TCP/IP and fullscreen display. -# Probably also works with Lynx 2.1, and maybe even Lynx 2.0. -# -X means use termios serial drivers rather than BSD4.3-style sgtty drivers. -# If you have trouble with this, try "make bsd KFLAGS=-DNOFDZERO". -lynx: - @echo 'Making C-Kermit $(CKVER) for LynxOS 2.2 with TCP/IP' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS= -O -DPOSIX -DDIRENT -DSETREUID -DCK_CURSES -DTCPSOCKET \ - -DCK_ANSIC -DLYNXOS -DNOLEARN" "LNKFLAGS = -X" "LIBS = -lcurses -lbsd" - -lynx22: - $(MAKE) lynx KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)" - -# LynxOS 2.1 with GCC compiler 1.40 and TCP/IP. -lynx21: - @echo 'Making C-Kermit $(CKVER) for LynxOS 2.1 with TCP/IP' - $(MAKE) kermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS= -O -DSETREUID -DTCPSOCKET -DCK_ANSIC -DBSD4 -DLYNXOS" \ - "LIBS = -lbsd" - -#SCO Xenix 2.2.1 for IBM PC, XT, PS2/30, or other 8088 or 8086 machine -#Should this not work, try some of the tricks from sco286. -#NOTE: -DRENAME is omitted for early SCO Xenix releases because it didn't -#exist, or its semantics were different from the later POSIX-compliant -#version of rename(). -sco86: - @echo 'Making C-Kermit $(CKVER) for SCO Xenix/86...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DXENIX -DNOFILEH -DNOIKSD -DNOUNICODE -DNOLEARN \ - $(KFLAGS) -Dunix -F 3000 -i -M0me" \ - "LNKFLAGS = -F 3000 -i -s -M0me" "LIBS = -lx" - -#SCO Xenix/286 2.2.1, e.g. for IBM PC/AT, PS/2 Model 50, etc. -#Reportedly, this "make" can fail simply because of the size of this -#makefile. If that happens, use "makeL", or edit out some of the -#other entries. No debugging or character-set translation. -sco286: - @echo 'Making C-Kermit $(CKVER) for SCO Xenix/286...' - @echo 'If make fails, try using makeL.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -xenix -s -O -LARGE -DXENIX -DNOFILEH -Dunix -DRDCHK -DNAP \ - -DNOIKSD -DNODEBUG -DNOTLOG -DNOCSETS -DNOLEARN \ - $(KFLAGS) -F 3000 -i -M2let16" \ - "LIBS = -lx" "LNKFLAGS = -xenix -s -O -LARGE -F 3000 -i -M2let16" - -#SCO Xenix/286 2.2.1, e.g. for IBM PC/AT, PS/2 Model 50, etc. -#As above, but with HDBUUCP (This one might need fixing -- see sco286). -sco286hdb: - @echo 'Making C-Kermit $(CKVER) for SCO Xenix/286 with HDB UUCP...' - @echo 'If make fails, try using makeL.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -s -O -LARGE -DXENIX -DNOFILEH -Dunix -DRDCHK -DNAP \ - -DHDBUUCP -DNOIKSD -DNOUNICODE -DNOLEARN \ - $(KFLAGS) -F 3000 -i -M2let32" \ - "LIBS = -lx" "LNKFLAGS = -s -O -LARGE -F 3000 -i -M2let32" - -#SCO Xenix/386 2.2.2 and 2.2.3 -sco386: - @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.2.2...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DXENIX -DNOFILEH -DNOIKSD -DNOREDIRECT -DNOLEARN \ - -Dunix -DRDCHK -DNAP -DNOUNICODE $(KFLAGS) -Otcl -M3e" \ - "LNKFLAGS = -s" "LIBS = -lx" - -#SCO XENIX/386 2.2.3 with Excelan TCP/IP + curses. -# NOTE: This one might need some work in C-Kermit 6.0. -# You might need to include /usr/include/sys/types.h -# containing "typedef char *caddr_t;". Then at least it compiles. -sco386netc: - @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.2.3 + Excelan TCP' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -I/usr/include/exos -DXENIX -DCK_CURSES -DNOUNICODE \ - -Dunix -DRDCHK -DNAP -DTCPSOCKET -DEXCELAN -DNOJC -DNOMKDIR -DNOFILEH \ - -DNOLEARN -DNOREDIRECT -DNOIKSD -DNO_DNS_SRV $(KFLAGS) -Otcl -M3e" \ - "LNKFLAGS = -s" "LIBS = -lc -lx -lsocket -lcurses -ltermcap" - -#SCO XENIX/386 2.3.3 with gcc 1.37 or later... -sco386gcc: - @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.3.3, gcc...' - @echo 'Add -D_NO_PROTOTYPE if you have trouble with Xenix header files' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS= -O -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP \ - -DNOJC -DNODEBUG -DNOUNICODE -DNOLEARN $(KFLAGS) \ - -traditional -fpcc-struct-return -fstrength-reduce \ - -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM \ - -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \ - -DM_SYSIII -DM_SYSV -DM_WORDSWAP -DM_XENIX -DNOIKSD -DNOREDIRECT \ - -DPWID_T=int " "LNKFLAGS = -s" "LIBS = -lx" - -#As above, but with curses... -sco386gccc: - @echo 'Making C-Kermit $(CKVER) for SCO Xenix/386 2.3.3, gcc...' - @echo 'Add -D_NO_PROTOTYPE if you have trouble with Xenix header files' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2 = gcc" \ - "CFLAGS= -O -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP \ - -DNOJC -DNODEBUG -DCK_CURSES -DNOUNICODE -DNOLEARN $(KFLAGS) \ - -traditional -fpcc-struct-return -fstrength-reduce \ - -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DNOREDIRECT \ - -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \ - -DM_SYSIII -DM_SYSV -DM_WORDSWAP -DM_XENIX -DNOIKSD \ - -DPWID_T=int " "LNKFLAGS = -s" "LIBS = -lx -lcurses -ltermlib" - -#SCO UNIX (and ODT) entries... -# -#NOTE: All SCO UNIX entry LIBS should have "-lc_s -lc -lx" IN THAT ORDER (if -#shared C library is desired), or else "-lc -lx" IN THAT ORDER. Use shared C -#libraries to save memory, but then don't expect to run the resulting binary -#on a different machine. When using -lc_s, you must also use -lc, because the -#shared C library does not contain all of libc.a. And in all cases, -lc must -#ALWAYS precede -lx. -# -#ANOTHER NOTE: -DRENAME is included in all SCO UNIX entries. Remove it if it -#causes trouble. No harm is done by removing it (see ckuins.txt). -# -#AND ANOTHER: In theory, it should be possible to run SCO UNIX binaries on -#SCO Xenix 2.3 and later. In practice, this might not work because of the -#libraries, etc. Also, don't add the -link -z switch (which is supposed to -#root out references to null pointers) because it makes UNIX binaries core -#dump when they are run under Xenix. - -#NOTE: -Otcl removed and replaced by -O, since -Otcl produced incorrect code. -#SCO UNIX/386 3.2.0, 3.2.1, and SCO Xenix 2.3.x -sco3r2: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2.0 or 3.2.1 ...' - @echo 'Warning: If make blows up, edit the makefile to join' - @echo 'the following three continued lines into one line.' - @echo 'Also, remove -DRENAME if _rename unresolved at link time.' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DNOLEARN \ - -DRENAME -DNOIKSD -DNOJC $(KFLAGS) -O" \ - "LNKFLAGS = -s" "LIBS = -lc -lx" - -#SCO UNIX/386 3.2.0 and SCO Xenix 2.3.x with Excelan TCP/IP support. -#In case of compilation or runtime problems, try adding -#"-DUID_T=int -DGID_T=int" to the CFLAGS. If that doesn't work, try -#"-DUID_T=uid_t -DGID_T=gid_t". -sco3r2net: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 / Excelan...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -I/usr/include/exos -DXENIX -DSVR3 -DNOFILEH -DNOLEARN \ - -DHDBUUCP -DRDCHK -DNAP -DRENAME -DTCPSOCKET -DEXCELAN -DNOJC \ - -DNOIKSD -DNOREDIRECT $(KFLAGS) -O" \ - "LNKFLAGS = -s" "LIBS = -lc -lx -lsocket" - -#SCO UNIX/386 3.2.0 and SCO Xenix 2.3.x with Excelan TCP/IP support. -#As above, with curses added. -sco3r2netc: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 / Excelan / curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -I/usr/include/exos -DXENIX -DSVR3 -DNOFILEH -DNOLEARN \ - -DHDBUUCP -DRDCHK -DNAP -DTCPSOCKET -DEXCELAN -DNOJC $(KFLAGS) \ - -DRENAME -DCK_CURSES -DNOREDIRECT -DNOIKSD -O" "LNKFLAGS = -s" \ - "LIBS = -lc -lx -lsocket -lcurses -ltermcap" - -#SCO UNIX 3.2.x or SCO Xenix 2.3.x with Racal InterLan TCP/IP support -# Extra compile flags for other version of Racal InterLan TCP/IP: -# Xenix286/NP621-286, use -Ml -DPARAMH -DINTERLAN -Di286 -DSYSV -# Xenix386/NP621-386, use -DPARAMH -DINTERLAN -Di386 -DSYSV -# ISC386ix/NP622I, use -DSYSV -Di386 -# SCO Unix3.2/NP622S, use -DSYSV -Di386 -DSCO_UNIX -# AT&T SVR3.2/NP622A, use -DSYSV -Di386 -DATT -sco3r2netri: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 / Racal InterLan...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -I/usr/include/interlan -DXENIX -DNOFILEH -DHDBUUCP \ - -DSVR3 -DRDCHK -DNAP -DTCPSOCKET -DPARAMH -DINTERLAN -Di386 -DSYSV \ - -DRENAME -DNOREDIRECT -DNOIKSD -DNOJC -DNOLEARN $(KFLAGS) -Otcl -M3e" \ - "LNKFLAGS = -s" "LIBS = -lc -lx -ltcp" - -# SCO XENIX/386 2.3.3 SysV with SCO TCP/IP -# System V STREAMS TCP developed by Lachman Associates Inc and -# Convergent Technologies. -# -DRENAME removed since some reports indicate it is not supported -# (whereas others say it is.) -sco3r2lai: - @echo 'Making C-Kermit $(CKVER) for SCO XENIX/386 2.3.3 + TCP/IP...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DLAI_TCP -Di386 -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK \ - -DNAP -DTCPSOCKET -DPWID_T=int -DNOREDIRECT -DNOIKSD -DNOLEARN \ - $(KFLAGS) -Otcl -i -M3e" \ - "LNKFLAGS = -i -s" "LIBS = -lc -lx -lsocket" - -sco3r2laic: - @echo 'Making C-Kermit $(CKVER) for SCO XENIX/386 2.3.3 + TCP/IP...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DLAI_TCP -Di386 -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK \ - -DNAP -DTCPSOCKET -DCK_ANSIC -DCK_CURSES -DM_TERMINFO -DNOLEARN \ - -DPWID_T=int -DNOREDIRECT -DNOIKSD $(KFLAGS) -Otcl -i -M3e" \ - "LNKFLAGS = -i -s" "LIBS = -ltinfo -lc -lx -lsocket" - -#SCO UNIX/386 3.2v2 (POSIX job control), shared libraries. -sco3r22: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2 ...' - make wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \ - -DNAP -DRENAME -DPID_T=pid_t -DPWID_T=int -DDIRENT -DNOIKSD \ - -DNOREDIRECT $(KFLAGS) -O" \ - "LNKFLAGS = -s" "LIBS = -lc_s -lc -lx" - -#SCO UNIX/386 3.2v2, POSIX job control, fullscreen file transfer display, -#dynamic memory allocation, shared C library -sco3r22c: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2 ...' - @echo 'Warning: If make blows up, edit the makefile to join' - @echo 'the following four continued lines into one line.' - make wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DNOLEARN \ - -DCK_CURSES -DDIRENT -DRENAME -DNOREDIRECT -DNOIKSD \ - -DPID_T=pid_t -DPWID_T=int $(KFLAGS) -O" \ - "LNKFLAGS = -s" "LIBS = -lcurses -lc_s -lc -lx" - -#SCO UNIX/386 3.2v2 with gcc 1.40 or later (POSIX job control) -sco3r22gcc: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2, gcc' - @echo 'Warning: If make blows up, edit the makefile to join' - @echo 'the following seven continued lines into one line.' - make wermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" \ - "CFLAGS= -O -DPOSIX -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP \ - -DNOLEARN -DRENAME -traditional -fpcc-struct-return -fstrength-reduce \ - -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM \ - -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \ - -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \ - -DPID_T=pid_t -DPWID_T=int -DNOREDIRECT -DNOIKSD $(KFLAGS) " \ - "LNKFLAGS = -s" "LIBS = -lc_s -lc -lx" - -#SCO UNIX/386 3.2v2 (ODT 1.1) (POSIX job control) with SCO TCP/IP, shared libs -#Requires SCO TCP/IP or ODT development system for telnet.h, etc. -sco3r22net: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2.2 + TCP/IP...' - @echo 'Warning: If make blows up, edit the makefile to join' - @echo 'the following three continued lines into one line.' - make xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DTCPSOCKET \ - -DRENAME -DPID_T=pid_t -DPWID_T=int -DDIRENT -DNOREDIRECT -DNOIKSD \ - $(KFLAGS) -O" "LNKFLAGS = -s" "LIBS = -lsocket -lc_s -lc -lx" - -#As above, but with curses for fullscreen file transfer display. -#Requires SCO TCP/IP or ODT development system for telnet.h, etc. -sco3r22netc: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v2 + TCP/IP...' - @echo 'Warning: If make blows up, edit the makefile to join' - @echo 'the following three continued lines into one line.' - make xermit KTARGET=$${KTARGET:-$(@)} "CFLAGS= \ - -DXENIX -DSVR3 -DNOFILEH -DHDBUUCP -DRDCHK -DNAP -DTCPSOCKET -DRENAME \ - -DCK_CURSES -DDIRENT -DNOIKSD -DNOREDIRECT \ - -DPID_T=pid_t -DPWID_T=int -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS = -lcurses -lsocket -lc_s -lc -lx" - -#SCO XENIX 2.3.4, no curses, no TCP/IP, no IKSD. -#This one built and tested in C-Kermit 7.0. -#lcfp is C library floating-point support. -#Use -M3 to generate 32-bit i386 code instead of 16-bit segmented i286 code. -#Use -Me to enable MS nonstandard keywords in system headers. -#Use -W2 or W3 to increase the warning level. -sco234: - @echo 'Making C-Kermit $(CKVER) for SCO XENIX 2.3.4...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSCO32 -DXENIX -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \ - -DNAP -DNOJC -DNOCOTFMC -DNOIKSD -DNOREDIRECT -DNOTNCODE -DNOGFTIMER \ - -DNOTIMEVAL -DNOTIMEZONE -DNOSYMLINK -DSCO234 -DDCLGETCWD $(KFLAGS) \ - -Otcl" "LNKFLAGS = -s" "LIBS = -lcfp -lc -lx" - -#SCO XENIX 2.3.4, no TCP/IP, no IKSD, but with curses. -# Built and tested in C-Kermit 7.0. -# Note: XENIX 2.3.4 does not have newterm() so no point in adding -DCK_NEWTERM. -sco234c: - @echo 'Making C-Kermit $(CKVER) for SCO XENIX 2.3.4 + curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSCO32 -DXENIX -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \ - -DNAP -DNOJC -DNOCOTFMC -DNOIKSD -DNOREDIRECT -DNOTNCODE -DNOGFTIMER \ - -DNOTIMEVAL -DNOTIMEZONE -DNOSYMLINK -DCK_CURSES -DSCO234 \ - -DDCLGETCWD $(KFLAGS) -Otcl" \ - "LNKFLAGS = -s" "LIBS = -lcfp -lc -ltinfo -lx" - -#SCO XENIX 2.3.4 with SCO TCP/IP and curses, no IKSD. -# Built and tested in C-Kermit 7.0. TCP/IP works and curses works. -# Previous versions of this target included -lmalloc, but this caused "error: -# " _calloc : symbol defined more than once" at link time so I removed it. -# Results are likely to vary depending on exactly which version of the SDK -# and TCP/IP SDK you have. -sco234netc: - @echo 'Making C-Kermit $(CKVER) for SCO XENIX 2.3.4 + TCP + curses...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DSCO32 -DXENIX -DNOFILEH -DHDBUUCP -DRDCHK -DNOLEARN \ - -DNAP -DNOJC -DNOCOTFMC -DNOIKSD -DNOREDIRECT -DNOTNCODE -DNOGFTIMER \ - -DNOTIMEVAL -DNOTIMEZONE -DNOSYMLINK -DCK_CURSES -DSCO234 \ - -DDCLGETCWD -DTCPSOCKET -DNO_DNS_SRV $(KFLAGS) -Otcl" \ - "LNKFLAGS = -s" "LIBS = -ltinfo -lsocket -lcfp -lc -lx" - -# SCO 3.2v4.x targets... - -# NOTE: Add -DDCLPOPEN and/or -DDCLFDOPEN to anySCO 3.2v4.x non-gcc entries -# that complain about fdopen() or popen() at compile time. They compile OK -# without these flags as of July 1999. However, the gcc entries seem to -# need them, at least for gcc 2.7.2.2. - -# NOTE 2: To enable IKSD support, add: -# -DCK_LOGIN -DNOGETUSERSHELL -DNOINITGROUPS -# to CFLAGS (not tested). - -#SCO UNIX/386 3.2v4 (POSIX job control), curses, ANSI C compilation, -# (EAFS) file system. Remove -lmalloc if it causes trouble. It was -#put there to avoid core dumps caused by regular libc.a malloc. Add -J to make -#all chars unsigned. This version uses select() for CONNECT and also has -#high-precision timers and so might not work on non-TCP systems, in which case -#sco32v4ns should be used instead. -# If you get _ftime redefinition_ complaint, try adding -DODT30 to CFLAGS. -sco32v4: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...' - make xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DCK_SCO32V4 -DNOFILEH -DHDBUUCP -DCK_CURSES -DM_TERMINFO \ - -DNOANSI -DSELECT -DNOIKSD -DDCLGETCWD -NOLSTAT \ - -DNOLINKBITS -DDCLGETCWD $(KFLAGS) -O" \ - "LNKFLAGS = -s" "LIBS = -lcurses -lmalloc -lsocket -lc_s -lc -lx" - -# As above, but with no dependence on sockets library or select(). -sco32v4ns: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...' - @echo 'No select() and no sockets library.' - make wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DCK_SCO32V4 -DNOFILEH -DHDBUUCP -DCK_CURSES -DM_TERMINFO \ - -DNOANSI -DNOIKSD -DNOGFTIMER -DCK_POLL -DNAP -DDCLGETCWD -DNOLSTAT \ - -DNOLINKBITS -DDCLGETCWD -DNOLEARN -O $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS = -lcurses -lmalloc -lc_s -lc -lx" - -#SCO UNIX/386 3.2v4 (POSIX job control), TCP/IP, curses, ANSI C compilation, -# (EAFS) file system. With DIRENT, -lc must come before -lx. -#Reportedly it's OK to add -DCK_REDIR and -DCK_WREFRESH, and to remove -lc_s. -#Requires SCO TCP/IP development system or ODT for telnet.h, etc. -#See sco32v4 above for additional comments. -#NOTE: No more room for -Dxxx -- 25 seems to be the limit. Move some to -#ckcdeb.h or somewhere... -sco32v4net: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...' - @echo 'If you get _ftime redefinition_ complaint,' - @echo 'use make sco-odt30.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DNOFILEH -DHDBUUCP -DTCPSOCKET -DCK_ANSIC -DCK_CURSES \ - -DNAP -DCK_WREFRESH -DNOLINKBITS -D_IBCS2 -DSELECT -DNOLSTAT \ - -DDCLGETCWD -DCK_SCO32V4 -DNOIKSD -O \ - $(KFLAGS)" "LNKFLAGS = $(LNKFLAGS) -s" \ - "LIBS = $(LIBS) -lcurses -lsocket -lmalloc -lsocket -lc_s -lc -lx" - -#SCO UNIX/386 3.2v4 with gcc 1.40 or later, POSIX job control. -#Also see comments in sco32r4 entry. -sco32v4gcc: - make xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" \ - "CFLAGS= -O -DNOFILEH -DHDBUUCP -DNOANSI -DCK_CURSES -DM_TERMINFO \ - -traditional -fpcc-struct-return -fstrength-reduce -funsigned-char \ - -D_KR -D_NO_PROTOTYPE -D_SVID -DNOIKSD -DCK_SCO32V4 -DNOLINKBITS \ - -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DSELECT -DNOLSTAT \ - -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 -DDCLGETCWD \ - -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \ - -DDCLPOPEN -DDCLFDOPEN $(KFLAGS) " \ - "LNKFLAGS = -s" "LIBS = -lcurses -lsocket -lc_s -lc -lx" - -#SCO UNIX/386 3.2v4 (POSIX job control), TCP/IP, curses, ANSI C compilation, -#Requires SCO TCP/IP or ODT development system for telnet.h, etc. -# (EAFS) file system. With DIRENT, -lc must come before -lx. -#gcc 1.40 or later. Also see comments in sco32r4 entry. -sco32v4netgcc: - make xermit KTARGET=$${KTARGET:-$(@)} "CC = gcc" "CC2=gcc" \ - "CFLAGS= -O2 -DNOFILEH -DHDBUUCP -DSELECT -DNOLSTAT \ - -DNOANSI -DTCPSOCKET -DCK_CURSES -DM_TERMINFO \ - -D_KR -D_NO_PROTOTYPE -D_SVID -DNOIKSD -DCK_SCO32V4 -DNOLINKBITS \ - -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DDCLGETCWD \ - -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 \ - -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \ - -DDCLPOPEN -DDCLFDOPEN $(KFLAGS)" \ - "LNKFLAGS = -s" "LIBS = -lcurses -lsocket -lc_s -lc -lx" - -#As above but with bgcc BOUNDS CHECKING (for developers only). -lcheck has -#bounds-checking replacements for malloc, memcpy, bcopy, etc, so must come -#before -lsocket and -lc. -sco32v4netbgcc: - make xermit KTARGET=$${KTARGET:-$(@)} \ - "CC = bgcc -pipe -m386" "CC2=bgcc -pipe -m386" \ - "CFLAGS= -O1 -g -DNOFILEH -DHDBUUCP -DSELECT \ - -DNOANSI -DTCPSOCKET -DCK_CURSES -DM_TERMINFO \ - -D_KR -D_NO_PROTOTYPE -D_SVID -DNOIKSD -DCK_SCO32V4 -DNOLSTAT \ - -DM_BITFIELDS -DM_COFF -DM_I386 -DM_I86 -DM_I86SM -DNOLINKBITS \ - -DM_INTERNAT -DM_SDATA -DM_STEXT -DM_SYS3 -DM_SYS5 -DDCLGETCWD \ - -DM_SYSIII -DM_SYSV -DM_UNIX -DM_WORDSWAP -DM_XENIX -Dunix \ - -DDCLPOPEN -DDCLFDOPEN $(KFLAGS) " \ - "LNKFLAGS = -g" "LIBS = -lcurses -lcheck -lsocket -lx" - -sco32v4netnd: - @echo sco32v4net with no debug - $(MAKE) "MAKE=$(MAKE)" sco32v4net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DNODEBUG -DNOTLOG" "LIBS=$(LIBS)" - -sco3r2netnd: - @echo sco32v4netnd built for SCO XENIX 2.3 under SCO UNIX... - @echo requires copying /lib/386/Slibc.a to /lib/386/Slibc_s.a and - @echo getting /lib/386/Slibsocket.a from a XENIX devkit. - @echo WARNING: poll/CK_POLL supported only on XENIX 2.3.4 - echo For earlier XENIX systems, replace CK_POLL with RDCHK. - $(MAKE) "MAKE=$(MAKE)" sco32v4netnd KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -x2.3 -DNORENAME -DNOSYMLINK" \ - "LNKFLAGS = $(LNKFLAGS) -x2.3" \ - "LIBS=-ldir -lcfp $(LIBS)" - -#SCO UNIX/386 3.2v4 (POSIX job control), TCP/IP, curses, ANSI C compilation, -# (EAFS) file system. With DIRENT, -lc must come before -lx. -#Reportedly it's OK to add -DCK_REDIR and -DCK_WREFRESH, and to remove -lc_s. -#Requires SCO TCP/IP development system or ODT for telnet.h, etc. -#See sco32v4 above for additional comments. -# Note: "xermit" means use the select() version of the CONNECT module. -sco32v4netx: - @echo 'Making C-Kermit $(CKVER) for SCO UNIX/386 3.2v4...' - @echo 'If you get _ftime redefinition_ complaint,' - @echo 'use make sco-odt30.' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DNOFILEH -DHDBUUCP -DTCPSOCKET -DCK_ANSIC -DCK_CURSES -DNAP \ - -DCK_WREFRESH -DNOLINKBITS -D_IBCS2 -DSELECT -DDCLGETCWD \ - -DCK_SCO32V4 -DNOIKSD -DNOLSTAT -O $(KFLAGS)" \ - "LNKFLAGS = $(LNKFLAGS) -s" \ - "LIBS = $(LIBS) -lcurses -lsocket -lmalloc -lsocket -lc_s -lc -lx" - -sco32v4netndx: - @echo sco32v4netx with no debug - $(MAKE) "MAKE=$(MAKE)" sco32v4netx KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DNODEBUG -DNOTLOG" "LIBS=$(LIBS)" - -sco3r2netndx: - @echo sco32v4netndx built for SCO XENIX 2.3 under SCO UNIX... - @echo requires copying /lib/386/Slibc.a to /lib/386/Slibc_s.a and - @echo getting /lib/386/Slibsocket.a from a XENIX devkit. - @echo WARNING: poll/CK_POLL supported only on XENIX 2.3.4 - echo For earlier XENIX systems, replace CK_POLL with RDCHK. - $(MAKE) "MAKE=$(MAKE)" sco32v4netndx KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -x2.3 -DNORENAME -DNOSYMLINK" \ - "LNKFLAGS = $(LNKFLAGS) -x2.3" \ - "LIBS=-ldir -lcfp $(LIBS)" - -sco-odt30: - @echo SCO ODT 3.0 - $(MAKE) "MAKE=$(MAKE)" sco32v4net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=$(KFLAGS) -DODT30" - -#SCO OpenServer 5.0 (SCO UNIX 3.2v5.0) with SCO development tools, no TCP/IP. -#SCO OSR5 is much more like standard System V than previous SCO releases. -#The SCO development tools include TCP/IP, so this target is only for creating -#artificially limited versions of kermit required by site policy rather than -#the operating system. NOSYSLOG is included because syslog() requires the -#sockets library. -sco32v500: - @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \ - -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DNOSYSLOG \ - $(KFLAGS)" \ - "LIBS=-lcurses $(LIBS)" "LNKFLAGS=$(LNKFLAGS)" - -sco32v5: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sco32v500 - - -#SCO OpenServer 5.0 with networking, SCO development tools. -#Networking libraries are now provided with the OS. -sco32v500net: - @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \ - -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DTCPSOCKET \ - -DNO_DNS_SRV $(KFLAGS)" \ - "LIBS=-lcurses -lsocket $(LIBS)" "LNKFLAGS=$(LNKFLAGS)" - -sco32v5net: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sco32v500net - -#SCO OpenServer 5.0 with networking and OpenSSL, SCO development tools. -#Networking libraries are now provided with the OS. -sco32v500net+ssl: - @echo Making C-Kermit $(CKVER) for SCO OSR5 with OpenSSL... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -O -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \ - -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DTCPSOCKET \ - -DNO_DNS_SRV -DCK_AUTHENTICATION -DCK_SSL -DCK_TRIGGER \ - $(SSLINC) $(SSLLIB) $(KFLAGS)" \ - "LIBS=$(SSLLIB) -lcurses -lsocket -lssl -lcrypto $(LIBS)" \ - "LNKFLAGS=$(LNKFLAGS)" - -#SCO OpenServer 5.0 with gcc, no networking. -#Note: NOSYSLOG required for non-net entries because it requires -sco32v500gcc: - @echo Using gcc... - $(MAKE) "MAKE=$(MAKE)" sco32v500CC=gcc CC2=gcc \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS= $(KFLAGS)" - -#SCO OpenServer 5.0 with networking, gcc. -sco32v500netgcc: - @echo TCP/IP networking added - using gcc... - $(MAKE) "MAKE=$(MAKE)" sco32v500net CC=gcc CC2=gcc \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS=$(KFLAGS)" - -#SCO OpenServer 5.0 with networking, gcc, elf. -sco32v500netgccelf: - @echo TCP/IP networking added - using gcc, dynamic elf library - $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS=-O3 -belf" "LNKFLAGS=-belf" - -sco32v502: - $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR502 $(KFLAGS)" - -#SCO OpenServer 5.0.2 with networking, SCO development tools. -sco32v502net: - @echo TCP/IP networking added... - $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-b elf -DSCO_OSR502 $(KFLAGS)" - -#SCO OpenServer 5.0.4 (SCO UNIX 3.2v5.0.4) with SCO development tools. -#Like 5.0, but adds high serial speeds. First POSIX-based SCO version. -#Note: the -O flag is deliberately omitted for /bin/cc (= /usr/ccs/bin/cc). -sco32v504: - @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5.0.4... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \ - -DSCO_OSR504 -b elf -DPOSIX \ - -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DNOSYSLOG $(KFLAGS)" \ - "LIBS=-lcurses $(LIBS)" "LNKFLAGS=$(LNKFLAGS)" - -#SCO OpenServer 5.0.4 with gcc, no networking. -sco32v504gcc: - @echo Using gcc... - $(MAKE) "MAKE=$(MAKE)" sco32v504 "CC=gcc" "CC2=gcc" \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS= $(KFLAGS)" - -#SCO OpenServer 5.0.4 with networking. -#SCO development tools (/bin/cc = /usr/ccs/bin/cc). -#Optimization deliberately suppressed. -sco32v504net: - @echo Making C-Kermit $(CKVER) for SCO OpenServer Release 5.0.4... - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DDIRENT -DHDBUUCP -DSVR4 -DCK_SCOV5 -DCK_RTSCTS \ - -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DSELECT -DSELECT_H \ - -DNOGETUSERSHELL -DNOLSTAT -DNOLINKBITS -DTCPSOCKET \ - -b elf -DSCO_OSR504 -DPOSIX -DNO_DNS_SRV $(KFLAGS)" \ - "LIBS=-lcurses -lsocket $(LIBS)" "LNKFLAGS=$(LNKFLAGS)" - -#SCO OpenServer 5.0.4 with networking, gcc. -sco32v504netgcc: - @echo TCP/IP networking added - using gcc... - @echo If gcc crashes on ckwart.c then build it by hand: - @echo " gcc -o wart -DCK_SCOV5 ckwart.c" - $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \ - KTARGET=$${KTARGET:-$(@)} "KFLAGS=-DSCO_OSR504 -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.4 with networking, gcc, elf. -sco32v504netgccelf: - @echo TCP/IP networking added - using gcc, dynamic elf library - $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR504 -DPOSIX -O3 -belf $(KFLAGS)" \ - LNKFLAGS="-belf" - -#SCO OpenServer 5.0.5 (SCO UNIX 3.2v5.0.5) with SCO /bin/cc. -#Like 5.0, but adds high serial speeds. First POSIX-based SCO version. -#You might have to add "LIBS=-ltinfo" (some do, some don't). -sco32v505: - $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DNOSHADOW -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.5 (SCO UNIX 3.2v5.0.5) with SCO UDK. -#This one can't see the high serial speeds and anything to do with modem -#signals doesn't work because UKD cc has its own alternative universe of -#header files. -sco32v505udk: - $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DDCLTIMEVAL -DNOSHADOW -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.5 with networking, SCO /bin/cc. -#See comments with sco32v505 targets. -sco32v505net: - @echo TCP/IP networking added... - $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DNOSHADOW -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.5 with networking and OpenSSL, SCO /bin/cc. -#See comments with sco32v505 targets. -sco32v505net+ssl: - @echo TCP/IP networking and OpenSSL added... - $(MAKE) "MAKE=$(MAKE)" sco32v500net+ssl KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DNOSHADOW -b elf -DPOSIX $(KFLAGS) " \ - -#SCO OpenServer 5.0.5 with networking, SCO UDK. -#See comments with above sco32v505 targets. -sco32v505udknet: - @echo TCP/IP networking added... - $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DDCLTIMEVAL -DNOSHADOW -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.5 with gcc, no networking. -sco32v505gcc: - @echo Using gcc... - $(MAKE) "MAKE=$(MAKE)" sco32v500 "CC=gcc" "CC2=gcc" \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DPOSIX -funsigned-char $(KFLAGS)" - -#SCO OpenServer 5.0.5 with gcc, no networking, no shadow passwords. -sco32v505xgcc: - @echo Using gcc... - $(MAKE) "MAKE=$(MAKE)" sco32v500 "CC=gcc" "CC2=gcc" \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DNOSHADOW -DPOSIX -funsigned-char $(KFLAGS)" - -#SCO OpenServer 5.0.5 with networking, gcc. -sco32v505netgcc: - @echo TCP/IP networking added - using gcc... - @echo If gcc crashes on ckwart.c then build it by hand: - @echo " gcc -o wart -DCK_SCOV5 ckwart.c" - $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \ - KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DNOSHADOW -DPOSIX -funsigned-char $(KFLAGS)" - -#egcs is just like gcc but generates ELF by default. -#Or you can include -melf (not -belf) to force it. -sco32v505netegcs: - $(MAKE) "MAKE=$(MAKE)" "KFLAGS=$(KFLAGS)" sco32v505netgcc \ - KTARGET=$${KTARGET:-$(@)} - -#SCO OpenServer 5.0.5 with networking, gcc, elf. -sco32v505netgccelf: - @echo TCP/IP networking added - using gcc, dynamic elf library - $(MAKE) "MAKE=$(MAKE)" sco32v500net "CC=gcc" "CC2=gcc" \ - "KFLAGS=-DSCO_OSR505 -DPOSIX -funsigned-char -O3 -belf $(KFLAGS)" \ - KTARGET=$${KTARGET:-$(@)} LNKFLAGS="-belf" - -#SCO OpenServer 5.0.6 with SCO /bin/cc. -# Add -DDCLTIMEVAL when building with UDK. -#Like 5.0.5. IMPORTANT: Use sco32v506a target for 5.0.6a. -sco32v506: - $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.6 with networking, SCO /bin/cc. -# Add -DDCLTIMEVAL when building with UDK. -# IMPORTANT: Use sco32v506a target for 5.0.6a. -sco32v506net: - @echo TCP/IP networking added... - $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.6a, no networking, SCO development tools. -#This one has patched sio drivers that, for the first time, -#actually handle modem signals correctly. -# Add -DDCLTIMEVAL when building with UDK. -sco32v506a: - $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR506A -DNEEDMDMDEFS \ - -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.6a with networking, SCO development tools. -# Add -DDCLTIMEVAL when building with UDK. -sco32v506anet: - @echo TCP/IP networking added... - $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR506A -DNEEDMDMDEFS \ - -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.7, no networking, SCO development tools. -#Adds flags to make PTY and SSH commands work. These have been tested -#only in 5.0.7 but probably they can also be added to earlier OSR5 targets. -sco32v507: - $(MAKE) "MAKE=$(MAKE)" sco32v500 KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR507 -DNEEDMDMDEFS \ - -DHAVE_PTSNAME -DHAVE_PTMX -DHAVE_GRANTPT \ - -b elf -DPOSIX $(KFLAGS)" - -#SCO OpenServer 5.0.7 as above but with networking. -sco32v507net: - @echo TCP/IP networking added... - $(MAKE) "MAKE=$(MAKE)" sco32v500net KTARGET=$${KTARGET:-$(@)} \ - "KFLAGS=-DSCO_OSR505 -DSCO_OSR506 -DSCO_OSR507 -DNEEDMDMDEFS \ - -DHAVE_PTSNAME -DHAVE_PTMX -DHAVE_GRANTPT \ - -b elf -DPOSIX $(KFLAGS)" - -#Tandy 16/6000 with Xenix 3.0 -#Add more -DNOxxx options to remove features if program won't load. -#Successful operation is a function of program size, physical memory, -#available swap space, etc. The following stripped-down configuration -#seems to work on most Tandy 6000s. NOTE: "-+" means allow long variable -#names, needed for C-Kermit 6.0 because some identifiers are not unique -#within the first six characters. -#C-Kermit 7.0 does not build here; "too many defines". -trs16: - @echo 'Making C-Kermit $(CKVER) for Tandy 16/6000, Xenix 3.0...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -+ -DATTSV -DTRS16 -DNOMKDIR -DDCLPOPEN -DCK_CURSES \ - -DNODEBUG -DNOTLOG -DNOHELP -DNOSCRIPT -DNOCSETS -DNOIKSD \ - -DNOREDIRECT -DNOSYSLOG -DNOPUTENV -DNOREALPATH -DNOLEARN \ - $(KFLAGS) -O" "LIBS= -lcurses -ltermcap" "LNKFLAGS = -+ -n -s" - -#MINIX/2.0 32 Bit version for intel 386+ running the POSIX-compliant MINIX -# version 2.0 (The definition of fatal avoids a conflict with a symbol by -# the same name in the curses library.) It is impossible to compile with -# network support since Minix does not support Berkeley sockets. -# Note: use chmem liberally on the compiler passes, make, and the final -# kermit executable. (3 megabytes of memory for each is sufficient.) -# From Terry McConnell, Syracuse U, and Will Rose. Will says: -# The stacks for make and some compiler passes needed to be increased -# with chmem as follows: -# make 1MB -# /usr/lib/em_cemcom.ansi 3MB -# /usr/lib/em_opt 1MB -# /usr/lib/i386/cg 1MB -# /usr/lib/i386/as 1MB -# The compiler temporary directory was set to /usr/tmp via the TMPDIR -# environment variable; more than 1MB of temporary space was needed. -# Kermit itself needs at least 1MB of stack. -minix20: - @echo 'Making C-Kermit $(CKVER) for MINIX 2.0/386...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} EXT=o \ - "CFLAGS= -wo -DV7 -DMINIX2 -DMINIX -DSIG_V -D_POSIX_SOURCE \ - -DCKCPU=\\\"i-386\\\" -DNOIKSD -Dfatal=myfatal -DCK_CURSES -DNOLEARN \ - -DNOSYSLOG -DUSE_MEMCPY -DNOREALPATH $(KFLAGS)" "LIBS= -lcurses" - -#MINIX/386 (PC Minix modified by Bruce Evans in Australia for 386 addressing) -# For MINIX 1.5+ (but < 2.0) -minix386: - @echo 'Making C-Kermit $(CKVER) for MINIX/386...' - @echo 'TOTALLY UNTESTED!' - $(MAKE) wermit EXT=s KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DV7 -DMINIX -D_POSIX_SOURCE -DNOLEARN $(KFLAGS)" - -#MINIX/386 Minix modified by Bruce Evans in Australia to use 386 addressing -minix386gcc: - @echo 'Making C-Kermit $(CKVER) for MINIX/386 with gcc...' - @echo 'TOTALLY UNTESTED!' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} "CC=gcc -g -O" "CC2=gcc -g" \ - "CFLAGS= -DV7 -DMINIX -D_POSIX_SOURCE -DNOLEARN $(KFLAGS)" - -#MINIX - 68k version with ACK compiler. -# If you have trouble compiling or running wart, "touch wart". -# If it still doesn't work, "touch ckcpro.c". -# The version configured below has many features removed, including -# the TRANSMIT, MSEND, HELP, and SCRIPT commands, international -# character set support, and the entire script programming language. -# But it does have an interactive command parser. -# Make sure make(1) has (at least) 100000 chmemory! -# If you are using the Amsterdam C compiler, you might have to add "-D__ACK__". -minix68k: - @echo 'Making C-Kermit $(CKVER) for MINIX 68k with ACK... - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DV7 -DMINIX -D_MINIX -D_POSIX_SOURCE -DNOLEARN \ - -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \ - -DNOSCRIPT -DNOCSETS -DNOSPL $(KFLAGS) \ - -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V" - -#MINIX - 68k version with c68 compiler. -# If you have trouble compiling or running wart, "touch wart" or -# "touch ckcpro.c". Compiling ckudia.c (no -DNODIAL!) might fail. :-( -# Give c68 250000 bytes of stack+heap; make sure make(1) has at least -# 100000 chmemory. On a 1MB Atari ST this means that the recursive -# call of make fails due to memory shortage. Try "make -n minixc68 >makeit", -# followed by ". makeit". Otherwise, as above. -minixc68: - @echo 'Making C-Kermit $(CKVER) for MINIX 68k with c68... - $(MAKE) wermit "CC= cc -c68" KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DV7 -DMINIX -D_MINIX -D_POSIX_SOURCE -DNOLEARN \ - -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \ - -DNOSCRIPT -DNOCSETS -DNOSPL $(KFLAGS) \ - -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V" - -#MINIX - 68k version with c68 compiler. -#A variation on the above that was recently (Sep 95) reported to work. -minixc68a: - @echo 'Making C-Kermit $(CKVER) for MINIX 68k with c68... - $(MAKE) wermit "CC= cc -c68" KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS= -DV7 -DMINIX -D_MINIX -D_POSIX_SOURCE \ - -DCK_ANSIC -DNODEBUG -DNOTLOG -DMINIDIAL -DEXTEN -DMYCURSES \ - -DNOSCRIPT -DNOCSETS -DNOSPL -DNOJC -DDIRENT -DNOLEARN \ - -DNOSETKEY -DNOESCSEQ $(KFLAGS) \ - -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V" - -#MIPS Computer Systems with UMIPS RISC/OS 4.52 = AT&T UNIX System V R3.0. -#Remove -DNOJC if job control can be safely used. -mips: - @echo 'Making C-Kermit $(CKVER) for MIPS RISC/OS...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DMIPS -DDIRENT -DCK_POLL -DNOJC -DNOLEARN -DPID_T=int \ - -DGID_T=gid_t -DUID_T=uid_t -i -O1500 $(KFLAGS)" - -#As above, but with TCP/IP and fullscreen support. -mipstcpc: - @echo 'Making C-Kermit $(CKVER) for MIPS RISC/OS...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DMIPS -DDIRENT -DCK_POLL -DNOJC \ - -DTCPSOCKET -DCK_CURSES -I/usr/include/bsd \ - -DPID_T=int -DGID_T=gid_t -DUID_T=uid_t -i -O1500 $(KFLAGS)" \ - "LIBS = -lcurses -lbsd" - -#Motorola Delta System V/68 R3, signal() is void rather than int. -#Uses dirent.h and Honey DanBer uucp. Supports TCP/IP. -#After building, use "mcs -d" to reduce size of the executable program. -sv68r3: - @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3...' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR3 -DSV68 -DDIRENT -DHDBUUCP -DNO_DNS_SRV -DTCPSOCKET \ - -DNOUNICODE -DNOLEARN -DUSE_MEMCPY $(KFLAGS) -O" "LNKFLAGS =" - -#Motorola Delta System V/68 R3V5, signal() is void rather than int. -#Uses dirent.h and Honey DanBer UUCP. Supports TCP/IP. -#After building, use "mcs -d" to reduce size of the executable program. -sv68r3v5: - @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3V5' - $(MAKE) wermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR3 -DSV68 -DDIRENT -DHDBUUCP -DNO_DNS_SRV -DUSE_MEMCPY \ - -DTCPSOCKET -DINADDRX -DNOUNICODE -DFNFLOAT -DNOLEARN $(KFLAGS) -O" \ - "LNKFLAGS =" "LIBS = -linet -lm" - -#Motorola MVME147 System V/68 R3 V5.1. Requires gcc 2.1 to compile. -#After building, use "mcs -d" to reduce size of the executable program. -sv68r3v51: - @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3V5.1' - $(MAKE) wermit "CC=gcc-delta" "CC2=gcc-delta" \ - KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNODEBUG -DNO_DNS_SRV -DNOLEARN \ - -DNOUNICODE -DFNFLOAT -DSV68 -DUSE_MEMCPY $(KFLAGS) \ - -O2 -v -ftraditional" \ - "LNKFLAGS = -s -v" "LIBS = -lm881 -lm" - -#Motorola MVME147 System V/68 R3V6. derived from Motorola Delta System R3V5. -#Checked on larger Motorola System V/68 R3V6 (with NSE Network Services Ext.) -#After building, use "strip" to reduce size of the executable program. -# "LIBS = -lnsl" removed in C-Kermit 6.1 - put back if needed. -# "LIBS = lm" added in 7.1/8.0 for floating-point math. -# ckuusr.c clobbers the optimizer. -sv68r3v6: - @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/68 R3V6' - $(MAKE) ckuusr.$(EXT) KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSV68R3V6 -DDIRENT -DHDBUUCP -DNOLOGIN -DNOINITGROUPS \ - -DNOSYMLINK -DNOREDIRECT -DNOGFTIMER -DTCPSOCKET -DDCLGETCWD -DSV68 \ - -DNO_DNS_SRV -DNOUNICODE -DFNFLOAT -DSELECT -DUSE_MEMCPY $(KFLAGS)" - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSV68R3V6 -DDIRENT -DHDBUUCP -DNOLOGIN -DNOINITGROUPS \ - -DNOSYMLINK -DNOREDIRECT -DNOGFTIMER -DTCPSOCKET -DDCLGETCWD -DSV68 \ - -DNO_DNS_SRV -DNOUNICODE -DFNFLOAT -DSELECT -DUSE_MEMCPY $(KFLAGS)" \ - "LNKFLAGS =" "LIBS = -lm" - -#Motorola Delta System V/88 R32, signal() is void rather than int. -#Uses dirent.h and Honey DanBer uucp. Needs for setting -#file dates. Supports TCP/IP. -#After building, use "mcs -d" to reduce size of the executable program. -sv88r32: - @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/88 R32...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -DSV88R32 -DDIRENT -DHDBUUCP -DTCPSOCKET \ - -DSYSUTIMEH -DCK_CURSES -DNOGETUSERSHELL -DGTODONEARG $(KFLAGS) -O" \ - "LIBS= -lcurses -lresolv" "LNKFLAGS = -s" - -#Motorola Delta System V/88 R40. Has , regular Berkeley -#sockets library, i.e. in.h and inet.h are not misplaced in sys (rather than -#netinet and arpa, respectively). Uses ANSI C constructs, advisory file -#locking on devices, etc. curses support added. Reportedly, the -#/usr/include/sys/vnode.h file has a bug which must be fixed before this -#makefile entry can work correctly. The "if DEBUG" directive at about line -#320 must be changed to "ifdef DEBUG" (Reportedly, this was fixed in -#in System V/88 R4.3). -#After building, use "mcs -d" to reduce size of the executable program. -sv88r40: - @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/88 R40...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DMOTSV88R4 -DDIRENT -DHDBUUCP -DSTERMIOX \ - -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL -DGTODONEARG -DFNFLOAT \ - $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -lresolv -lm" "LNKFLAGS = -s" - -#As above but without the floating-point math library. -sv88r40nm: - @echo 'Making C-Kermit $(CKVER) for Motorola UNIX System V/88 R40...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - "CFLAGS = -O -DSVR4 -DMOTSV88R4 -DDIRENT -DHDBUUCP -DSTERMIOX \ - -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL -DGTODONEARG $(KFLAGS)" \ - "LIBS= -lsocket -lnsl -lcurses -lresolv" "LNKFLAGS = -s" - -#As above but with floating-point math library support \ffp...() functions -#and S-Expressions. - -#Olivetti X/OS R2.3, 3.x. -#NOTES: -# . If you build the executable on 2.x X/OS, it will also run on 3.x. -# . If you build it on 3.x X/OS, it will NOT run on 2.x. -# . Kermit can run with no privileges unless the uucp lines are protected, -# in which case kermit must be owned by uucp with suid bit set: -# chown uucp kermit ; chmod 4111 kermit. -xos23: - @echo 'Making C-Kermit $(CKVER) for Olivetti X/OS...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - 'CFLAGS=-OLM -DOXOS -DTCPSOCKET -DHDBUUCP $(KFLAGS)' \ - "LIBS=" "LNKFLAGS=" - -#As above, but with curses. -xos23c: - @echo 'Making C-Kermit $(CKVER) for Olivetti X/OS with curses...' - $(MAKE) xermit KTARGET=$${KTARGET:-$(@)} \ - 'CFLAGS=-OLM -DOXOS -DTCPSOCKET -DHDBUUCP -DCK_CURSES $(KFLAGS)' \ - "LIBS=-lcurses" "LNKFLAGS=" - -ckuuid: - @echo 'building C-Kermit $(CKVER) set-UID/set-GID test programs' - $(CC) -DANYBSD -DSAVEDUID -o ckuuid1 ckuuid.c - $(CC) -DANYBSD -o ckuuid2 ckuuid.c - $(CC) -DANYBSD -DNOSETREU -o ckuuid3 ckuuid.c - $(CC) -DANYBSD -DSETEUID -DNOSETREU -o ckuuid4 ckuuid.c - $(CC) -o ckuuid5 ckuuid.c - @echo 'Read the top of ckuuid.c for directions...for testing' - @echo 'you must make these programs setuid and setgid' - -############################################################################ -# A N T I Q U I T I E S -# -# The following are antique targets from C-Kermit 5A or earlier. They have -# not been updated or tested in years. Most of them will need recent features -# disabled, usually with some combination of -DNOUNICODE, -DNOIKSD, -DNOANSI, -# -DNOCKGHNLHOST, -DNO_DNS_SRV, -DNOREDIRECT, -DNOREALPATH, -DNOCURSES, etc. -# They are also missing the KTARGET=$${KTARGET:-$(@)} business. -# For details see ckuins.txt and ckccfg.txt. -# -############################################################################ - -#Berkeley Unix 2.8, 2.9 for PDP-11s with I&D space, maybe also Ultrix-11??? -#C-Kermit(5A) is simply too large (even turning off almost every feature -#available) to run without both I&D space plus overlays. The old comment -#suggested running 'pcc' but that won't help. Changing 'cc' to 'ckustr.sed' -#will cause a string extraction to be done, saving D space by moving strings -#to a file. -bsd29: - @echo Making C-Kermit $(CKVER) for 2.8 or 2.9BSD. - @echo Read the makefile if you have trouble with this... - $(MAKE) ovwermit \ - "CFLAGS= -DBSD29 -DNODEBUG -DNOTLOG -DNOCSETS -DNOHELP \ - -DNOSCRIPT -DNOSPL -DNOXMIT -DNODIAL $(KFLAGS)" \ - "LNKFLAGS= -i -lndir" "CC= cc " "CC2= cc" - -bsd210: - @echo Please use ckubs2.mak to build C-Kermit $(CKVER) for 2.10BSD. - -bsd211: - @echo Please use ckubs2.mak to build C-Kermit $(CKVER) for 2.11BSD. - -#Charles River Data Systems Universe with UNOS Version 9.2 -crds: - @echo 'Making C-Kermit $(CKVER) for Charles River Data Systems...' - make xermit \ - "CFLAGS = -DATTSV -DNOANSI -DDIRENT -DLONGFN -DTCPSOCKET \ - -DLOCK_DIR=\\\"/usr/spool/uucp\\\" -DNOSETREU \ - -Dsuspend=ksuspend $(KFLAGS) -O" "LNKFLAGS =" - -#Microport SV/AT for IBM PC/AT 286 and clones, System V R2. -#The -O flag may fail on some modules (like ckuus2.c), in which case you -#should compile them by hand, omitting the -O. If you get "hash table -#overflow", try adding -DNODEBUG. -#Also, reportedly this compiles better with gcc than with cc. -mpsysv: - @echo 'Making C-Kermit $(CKVER) for Microport SV/AT 286...' - $(MAKE) wermit \ - "CFLAGS= -DATTSV -DNOLEARN $(KFLAGS) -O -Ml" "LNKFLAGS = -Ml" - -#Microsoft "Xenix/286" e.g. for IBM PC/AT -xenix: - @echo 'Making C-Kermit $(CKVER) for Xenix/286' - $(MAKE) wermit \ - "CFLAGS= -DXENIX -DNOFILEH -DNOLEARN $(KFLAGS) -Dunix -F 3000 -i" \ - "LNKFLAGS = -F 3000 -i" - -#PC/IX, Interactive Corp System III for IBM PC/XT -pcix: - @echo 'Making C-Kermit $(CKVER) for PC/IX...' - $(MAKE) wermit \ - "CFLAGS= -DPCIX -DISIII -DNOLEARN $(KFLAGS) \ - -Dsdata=sdatax -O -i" "LNKFLAGS = -i" - -#Integrated Solutions Inc V8S VME 68020 -isi: - @echo Making C-Kermit $(CKVER) for 4.2BSD on ISI... - $(MAKE) wermit "CC = cc" \ - "CFLAGS= -DBSD4 -DTCPSOCKET -DINADDRX -DDCLPOPEN -DDEBUG -DNOSETREU \ - -DCK_CURSES -DNOLEARN $(KFLAGS)" "LIBS = -lcurses -ltermcap" - -#Interactive Corp version of AT&T System III -#is3: (very old, probably not sufficient for 5A or later) -# @echo 'Making C-Kermit $(CKVER) for Interactive System III...' -# make wermit "CFLAGS = -DISIII -Ddata=datax -O -i" "LNKFLAGS = -i" -#The following should work, use it if you don't have gcc. -#Use is3gcc if you have gcc. -is3: - @echo 'Making C-Kermit $(CKVER) for Interactive System III...' - $(MAKE) wermit \ - "CFLAGS= -DISIII $(KFLAGS) -Ddata=datax -DNAP -DHDBUUCP - -DLOCK_DIR=\"/usr/spool/uucp\" -DSIGTYP=void -O -i" "LNKFLAGS = -i" - -#Interactive UNIX System V R3, no network support. Uses and Honey -#DanBer UUCP. If this entry does not compile correctly, try any or all of the -#following. These suggestions also apply more or less to the other is5r3xxx -#entries that follow this one. -# . Remove the UID_T and GID_T definitions, or change them as required. -# . Change -DDIRENT to -DSDIRENT. -# . Add -DSIGTYP=void. -# . Remove -g from LNKFLAGS. -# . Add -DNOANSI to remove compiler complaints about ANSI C constructions -# . Add other -DNOxxx's to save space (e.g. -DNOCSETS) -# See the next few makefile entries for related examples. -# Also see sys5r32is for making a portable i386 SVR3 binary. -is5r3: - @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix or later...' - @echo 'If this does not work please read the makefile entry.' - $(MAKE) wermit \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -g -DNOCSETS -DNOREALPATH \ - -DUID_T=ushort -DGID_T=ushort -DI386IX $(KFLAGS)" \ - "LNKFLAGS = -g" - -#Interactive Corp System System V R3 with gcc -is3gcc: - @echo 'Making C-Kermit $(CKVER) for Interactive System V R3 / gcc...' - $(MAKE) wermit CC=gcc CC2=gcc \ - 'CFLAGS = -D_SYSV3 -DISIII -Ddata=datax -DNAP -DHDBUUCP -DNOREALPATH \ - -DLOCK_DIR=\"/usr/spool/uucp\" -DSIGTYP=void -O' "LNKFLAGS =" - -#Interactive UNIX System V R3, POSIX variant. Untested. -#Uses dirent.h and Honey DanBer uucp. Read comments in is5r3 entry. -is5r3p: - @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix or later...' - $(MAKE) wermit \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP -g -DNOCSETS -DNOREALPATH \ - -DI386IX -DPOSIX $(KFLAGS)" "LNKFLAGS=" "LIBS=-lcposix" - -#Interactive UNIX SVR3 2.2.1, job control, curses, no net, gcc. -is5r3gcc: - $(MAKE) wermit CC=gcc CC2=gcc \ - "CFLAGS=-g -posix -DSVR3 -DDIRENT -DNOREALPATH \ - -DHDBUUCP -O -DNOCSETS -DI386IX -DSVR3JC -DCK_CURSES \ - $(KFLAGS)" LNKFLAGS="-posix" LIBS="-lcurses -lc_s" - -#Interactive UNIX System V R3 with TCP/IP network support. -#Needs -linet for net functions. signal() is void rather than int. -#Uses dirent.h and Honey DanBer uucp. Read comments in is5r3 entry. -#Also see is5r3net2 if you have trouble with this entry. -is5r3net: - @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix...' - @echo 'If this does not work please read the makefile entry.' - $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET -DNOREALPATH \ - -DI386IX $(KFLAGS) -O" "LIBS = -linet" - -is5r3netgcc: - $(MAKE) is5r3net CC=gcc CC2=gcc - -#Interactive UNIX System V R3, no job control, signal() void rather than int. -#Uses dirent.h and Honey DanBer uucp. Needs -linet for net functions. -#Read comments in is5r3 entry. Use this entry if is5r3net fails. -#Saves some space by stripping (-s) and using shared library (-lc_s). -is5r3net2: - @echo 'Making C-Kermit $(CKVER) for Interactive 386/ix...' - $(MAKE) wermit \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DTCPSOCKET -DNOJC -DNOREALPATH \ - -DSIGTYP=void -DNOANSI -DI386IX $(KFLAGS) -O" \ - "LNKFLAGS= -s" "LIBS = -linet -lc_s" - -#Interactive UNIX System V R3 (version 2.2 or later) with job control & curses. -#Uses dirent.h and Honey DanBer UUCP. -is5r3jc: - @echo 'Making C-Kermit $(CKVER) for Interactive Unix 2.2 or later...' - $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \ - -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES \ - -DPOSIX_JC -DCK_REDIR -DCK_POLL -DDCLGETCWD \ - $(KFLAGS)" "LIBS=-lcurses -lc_s -linet" - -is5r3jcgcc: - $(MAKE) is5r3jc CC="gcc -DCK_ANSILIBS -DDCGPWNAM -O4" CC2=gcc \ - KFLAGS="$(KFLAGS)" LNKFLAGS="$(LNKFLAGS)" - -#Sunsoft/Interactive UNIX System V R3 (version 2.2 or later) -#with job control, curses, and TCP/IP networking. -#Uses dirent.h and Honey DanBer UUCP. -is5r3netjc: - @echo 'Making C-Kermit $(CKVER) for Interactive Unix 2.2 or later...' - $(MAKE) wermit CC="$(CC)" CC2="$(CC2)" \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -O -DNOCSETS -DNOREALPATH \ - -DUID_T=ushort -DGID_T=ushort -DI386IX -DSVR3JC -DCK_CURSES \ - -DPOSIX_JC -DCK_REDIR -DTCPSOCKET -DSELECT \ - $(KFLAGS)" "LIBS=-linet -lcurses -lc_s" - -is5r3netjcgcc: - $(MAKE) is5r3netjc CC="gcc -DCK_ANSILIBS -DDCGPWNAM -O4" CC2=gcc \ - KFLAGS="$(KFLAGS)" LNKFLAGS="$(LNKFLAGS)" - -#Masscomp System III -rtu: - @echo 'Making C-Kermit $(CKVER) for Masscomp RTU System III...' - $(MAKE) wermit \ - "CFLAGS= -UFIONREAD -DATTSV $(KFLAGS) -O" "LNKFLAGS =" "LIBS= -ljobs" - -#Masscomp/Concurrent RTU 4.0 or later, Berkeley environment. -#Includes = /usr/include/ndir.h -#Note "LIBS = -lndir" might not be necessary because of "ucb make". -rtubsd: - @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.1A...' - ucb make wermit \ - "CFLAGS= -DBSD4 -DRTU -DNDIR -DHDBUUCP -DTCPSOCKET $(KFLAGS)" \ - "LIBS = -lndir" - -#Masscomp/Concurrent RTU 4.0 or later, same as above, -#Includes "usr/lib/ndir.h" -#Note "LIBS = -lndir" might not be necessary because of "ucb make". -rtubsd2: - @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.1A...' - ucb make wermit \ - "CFLAGS= -DBSD4 -DRTU -DXNDIR -DHDBUUCP $(KFLAGS)" \ - "LIBS = -lndir" - -#Masscomp/Concurrent RTU 4.0 or later, same as above, -#Includes -#Note "LIBS = -lndir" might not be necessary because of "ucb make". -rtubsd3: - @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.x BSD...' - ucb make wermit "CFLAGS= -DBSD4 -DRTU -DHDBUUCP $(KFLAGS)" \ - "LIBS = -lndir" - -#Masscomp/Concurrent RTU 4.0 or later, System V R2, using . -#In case of problems, add back the -DRTU switch. -#In case -DTCPSOCKET gives trouble, remove it. -rtus5: - @echo 'Making C-Kermit $(CKVER) for Masscomp RTU 4.x...' - $(MAKE) wermit \ - "CFLAGS= -DATTSV -DHDBUUCP -DDIRENT -DTCPSOCKET $(KFLAGS)" - -#Masscomp/Concurrent RTU 4.x, System V R3, using . -#Use this one if rtus5 gives warnings about pointer type mismatches. -#In case of problems, add back the -DRTU switch. -rtus5r3: - @echo 'Making C-Kermit $(CKVER) for Masscomp RTU Sys V R3...' - $(MAKE) wermit "CFLAGS= -DSVR3 -DHDBUUCP -DDIRENT $(KFLAGS)" - -#DEC Pro-3xx with Pro/Venix V1.0 or V1.1 -# Requires code-mapping on non-I&D-space 11/23 processor, plus some -# fiddling to get interrupt targets into resident code section. -# This almost certainly doesn't work any more. -provx1: - @echo 'Making C-Kermit $(CKVER) for DEC Pro-3xx, Pro/Venix 1.x...' - $(MAKE) wart "CFLAGS= -DPROVX1 $(KFLAGS)" "LNKFLAGS= " - $(MAKE) wermit "CFLAGS = -DPROVX1 -DNOFILEH -md780" \ - "LNKFLAGS= -u _sleep -lc -md780" - -#Nixdorf Targon/31. -#AT&T UNIX System V R3, signal() is void rather than int. -#Uses dirent.h without Honey DanBer uucp. -t31tos40x: - @echo 'Making C-Kermit $(CKVER) for Targon/31 with TOS 4.0.xx...' - $(MAKE) wermit \ - "CFLAGS= -DSVR3 -DDIRENT $(KFLAGS) -O" \ - "LNKFLAGS=" - -#NCR Tower 1632, OS 1.02 -tower1: - @echo 'Making C-Kermit $(CKVER) for NCR Tower 1632, OS 1.02...' - $(MAKE) wermit "CFLAGS= -DTOWER1 $(KFLAGS)" - -#NCR Tower 32, OS Release 1.xx.xx -tower32-1: - @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 Rel 1 System V R2...' - @echo 'Add KFLAGS=-DISDIRBUG if you get errors about S_ISREG/S_ISDIR.' - $(MAKE) wermit \ - "CFLAGS = -DATTSV $(KFLAGS) -O" "LNKFLAGS = -n" - -#NCR Tower 32, OS Release 2.xx.xx -tower32-2: - @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 Rel 2 System V R2...' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DHDBUUCP $(KFLAGS) -O2" \ - "LNKFLAGS = -n" - -#NCR Tower 32, OS Releases based on System V R3 -#Don't add -DNAP (doesn't work right) or -DRDCHK (not available in libc). -tower32: - @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 System V R3...' - $(MAKE) wermit \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNOSYSIOCTLH $(KFLAGS) \ - -DUID_T=ushort -DGID_T=ushort -O1" - -#NCR Tower 32, OS Releases based on System V R3 -tower32g: - @echo 'Making C-Kermit $(CKVER) for NCR Tower 32 System V R3, gcc...' - $(MAKE) wermit "CC = gcc" \ - "CFLAGS = -DSVR3 -DDIRENT -DHDBUUCP -DNOSYSIOCTLH $(KFLAGS) \ - DUID_T=ushort -DGID_T=ushort -O -fstrength-reduce -fomit-frame-pointer" - -#Fortune 32:16, For:Pro 1.8 (mostly like 4.1bsd) -ft18: - @echo 'Making C-Kermit $(CKVER) for Fortune 32:16 For:Pro 1.8...' - $(MAKE) wermit \ - "CFLAGS= -DNODEBUG -DBSD4 -DFT18 -DNOFILEH $(KFLAGS) \ - -DPID_T=short" - -#Fortune 32:16, For:Pro 2.1 (mostly like 4.1bsd). -#The modules that break the optimizer are compiled separately. -ft21: - @echo 'Making C-Kermit $(CKVER) for Fortune 32:16 For:Pro 2.1...' - $(MAKE) ckuusx.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \ - -SYM 800 -DCK_CURSES $(KFLAGS) -DPID_T=short" \ - "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet" - $(MAKE) ckuxla.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \ - -SYM 800 -DCK_CURSES $(KFLAGS) -DPID_T=short" \ - "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet" - $(MAKE) ckudia.$(EXT) "CFLAGS= -DNODEBUG -DBSD4 -DFT21 -DNOFILEH \ - -SYM 800 -DCK_CURSES $(KFLAGS) -DPID_T=short" \ - "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet" - $(MAKE) wermit \ - "CFLAGS= -O -DNODEBUG -DBSD4 -DFT21 -DNOFILEH -SYM 800 \ - -DCK_CURSES $(KFLAGS) -DPID_T=short" \ - "LNKFLAGS= -n -s" "LIBS= -lcurses -ltermcap -lv -lnet" - -#Valid Scaldstar -#Berkeleyish, but need to change some variable names. -valid: - @echo 'Making C-Kermit $(CKVER) for Valid Scaldstar...' - $(MAKE) wermit \ - "CFLAGS= -DBSD4 -DNODEBUG -DNOTLOG -Dcc=ccx -DFREAD=1 $(KFLAGS)" - -#IBM IX/370 on IBM 370 Series mainframes -#Mostly like sys3, but should buffer packets. -ix370: - @echo 'Making C-Kermit $(CKVER) for IBM IX/370...' - $(MAKE) wermit "CFLAGS = -DIX370 -DATTSV $(KFLAGS) -i -O" \ - "LNKFLAGS = -i" - -#Amdahl UTS 2.4 on IBM 370 series compatible mainframes. -#Mostly like V7, but can't do initrawq() buffer peeking. -uts24: - @echo 'Making C-Kermit $(CKVER) for Amdahl UTS 2.4...' - $(MAKE) wermit "CFLAGS=-DV7 -DPROCNAME=\\\"$(PROC)\\\" \ - -DUTS24 -DBOOTNAME=\\\"$(BOOTFILE)\\\" -DNPROCNAME=\\\"$(NPROC)\\\" \ - -DNPTYPE=$(NPTYPE) $(DIRECT) $(KFLAGS)" - -#Amdahl UTSV UNIX System V = System V R2 or earlier. -utsv: - @echo 'Making C-Kermit $(CKVER) for Amdahl UTSV...' - $(MAKE) wermit \ - "CFLAGS = -DUTSV $(KFLAGS) -i -O" "LNKFLAGS = -i" - -#Amdahl UTSV UNIX System V = System V R2 or earlier, with TCP sockets library. -utsvtcp: - @echo 'Making C-Kermit $(CKVER) for Amdahl UTSV w/tcp...' - $(MAKE) wermit "CFLAGS = \ - -DTCPSOCKET -DUTSV $(KFLAGS) -i -O" "LNKFLAGS = -i" \ - "LIBS = -lsocket" - -#BBN C/70 with IOS 2.0 -#Mostly Berkeley-like, but with some ATTisms -c70: - @echo 'Making C-Kermit $(CKVER) for BBN C/70 IOS 2.0...' - $(MAKE) wermit "CFLAGS= -DBSD4 -DC70 $(KFLAGS)" - -#Zilog ZEUS 3.21 -zilog: - @echo 'Making C-Kermit $(CKVER) for Zilog Zeus 3.21...' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DZILOG -DNODEBUG $(KFLAGS) -i -O" \ - "LNKFLAGS = -i -lpw" - -#Whitechapel MG-1 Genix 1.3 -white: - @echo 'Making C-Kermit $(CKVER) for Whitechapel MG-1 Genix 1.3...' - @touch ckcpro.c - $(MAKE) wermit "CFLAGS= -DBSD4 -Dzkself()=0 $(KFLAGS)" - -#Pixel 1000 -pixel: - @echo 'Making C-Kermit $(CKVER) for Pixel 1000...' - $(MAKE) wermit "CFLAGS= -DBSD4 -Dzkself()=0 $(KFLAGS)" - -ptx: - $(MAKE) "MAKE=$(MAKE)" dynixptx12 - -#CDC VX/VE 5.2.1 -vxve: - @echo 'Making C-Kermit $(CKVER) for CDC VX/VE 5.2.1...' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DVXVE -DNODEBUG -DNOTLOG $(KFLAGS) -i -O" \ - "LNKFLAGS = -i" - -#DIAB DS90 or LUXOR ABC-9000 with pre-5.2 DNIX. Sys V with nap() and rdchk(). -# nd = no opendir(), readdir(), closedir(), etc. -# Some of the modules fail to compile with -O. -dnixnd: - @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with very old DNIX 5.2.' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DNAP -DRDCHK -DDCLPOPEN \ - -U__STDC__ $(KFLAGS)" - -#DIAB DS90 with DNIX 5.2. Sys V with nap() and rdchk(). -# This one has opendir(), readdir(), closedir(), etc. -# Some of the modules fail to compile with -O. -dnix: - @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with old DNIX 5.2...' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DNAP -DRDCHK -DDIRENT \ - -U__STDC__ $(KFLAGS)" - -#DIAB DS90 with DNIX 5.2. Sys V with nap() and rdchk(). -# As above, but with curses and TCP/IP. -# You might get complaints about redefinition of O_RDONLY, etc, because -# of bugs in the DNIX header files, which can be fixed by adding #ifndef... -# around the offending definitions in the header files. -dnixnetc: - @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with old DNIX 5.2...' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DNAP -DRDCHK -DDIRENT \ - -DTCPSOCKET -DCK_CURSES -I/usr/include/bsd -U__STDC__ $(KFLAGS)" \ - "LIBS = -ln -lcurses" - -#DIAB DS90 with DNIX 5.3 or later, with HDB UUCP, nap() and rdchk(). -dnix5r3: - @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...' - @echo 'with Honey DanBer UUCP' - $(MAKE) wermit \ - "CFLAGS = -DSVR3 -DHDBUUCP -DNAP -DRDCHK -DDIRENT \ - -DCK_CURSES -DRENAME $(KFLAGS) -O" "LIBS= -lcurses" - -#DIAB DS90 with DNIX 5.3 or later, with HDB UUCP, nap() and rdchk() + TCP/IP -dnix5r3net: - @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...' - @echo 'with Honey DanBer UUCP and TCP/IP' - $(MAKE) wermit \ - "CFLAGS = -DSVR3 -DHDBUUCP -DNAP -DRDCHK -DDIRENT \ - -DTCPSOCKET -DCK_CURSES -DRENAME $(KFLAGS) -O \ - -I/usr/include/bsd" "LIBS = -ln -lcurses" - -#DIAB DS90 with DNIX 5.3 2.2 or later, with HDB UUCP, nap() and rdchk(), -#ANSI C compilation and libraries. -#Note that for DNIX 5.3 2.2 you have to correct a bug in /usr/include/stdlib.h: -#change "extern void free(char *str);" -#to "extern void free(void *str);" -#NOTE: This bug is reportedly fixed in DNIX 5.3 2.2.1. -#Should you get fatal errors caused by harmless pointer-type mismatches, -#like between signed and unsigned char, just remove -X7. -dnix5r3ansi: - @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...' - @echo 'with ANSI C Honey DanBer UUCP' - $(MAKE) wermit \ - "CFLAGS = -DSVR3 -DDIAB -DHDBUUCP -DNAP -DRDCHK -DDIRENT \ - -DCK_ANSILIBS -DCK_CURSES -DRENAME -O -X7 -X9 $(KFLAGS)" \ - "LIBS= -lcurses" - -#DIAB DS90 with DNIX 5.3 2.2 or later, with HDB UUCP, nap() and rdchk(), -# + TCP/IP, ANSI C compilation and libraries. -#Should you get fatal errors caused by harmless pointer-type mismatches, -#like between signed and unsigned char, just remove -X7. -dnix5r3ansinet: - @echo 'Making C-Kermit $(CKVER) for DIAB DS90 with DNIX 5.3...' - @echo 'with ANSI C Honey DanBer UUCP' - $(MAKE) wermit \ - "CFLAGS = -DSVR3 -DDIAB -DHDBUUCP -DNAP -DRDCHK -DDIRENT \ - -DTCPSOCKET -DCK_ANSILIBS -DCK_CURSES -DRENAME -O -X7 -X9 $(KFLAGS) \ - -I/usr/include/bsd" "LIBS= -ln -lcurses" - -# QNX 4.21 and above, 32-bit version, Watcom C32 10.6, fully configured, -# except no job control because QNX 4.x does not support it. New NCURSES -# library used instead of CURSES. -# -# -Oatx optimizes to favor speed over size: loop optimization, inline fn's. -# -Os favors size over speed. Saves 30-40K out of about 1.75M. -# -3r = generate 386 code with register-based arg passing. -# -3s = generate 386 code with stack-based arg passing. -# -ms = separate code & data 4GB segments (32-bit builds only). -# -mf = flat memory model code+data in one 4GB segment (ditto). -# -zc = place literal strings in code segment. -# -N4M = Big stack (increase the digit upon SIGSEGVs at runtime). -# chars are unsigned by default (-j makes them signed by default). -# -NOUUCP is included because QNX doesn't use it. -# Add these to the end if you like but they dump core on my QNX 4.25 system: -# -# @wermit -h >use.qnx -# @usemsg wermit use.qnx -# @rm use.qnx -# -# If you get warnings about HEADER or C_IN add -DNO_DNS_SRV. -qnx32: - @echo 'Making C-Kermit $(CKVER) for QNX 4.2x, 32-bit...' - $(MAKE) xermit \ - "LNKFLAGS = -N4M -3r" \ - "CFLAGS = -ms -3r -DQNX -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL \ - -DCK_WREFRESH -DCK_REDIR -DSELECT -DSELECT_H -DCK_RTSCTS -DNOJC \ - -DNOINITGROUPS -DNOUUCP -DCK_ANSIC -DPID_T=pid_t -Oatx -zc $(KFLAGS)" \ - "LIBS= -lsocket -lncurses -ltermcap" - -# As above but no networking since some QNX systems do not have TCP/IP -# installed, or the TCP/IP developers kit, which includes all the needed -# header files. This entry has not been tested on a QNX system that, in -# fact, does not have TCP/IP installed; some adjustments might be necessary, -# in particular regarding the use of select(): is -lsocket needed, can we -# get the needed definitions from non-TCP/IP header files (FD_SET, etc)? -qnx32nonet: - @echo 'Making C-Kermit $(CKVER) for QNX 4.2x, 32-bit, no net...' - $(MAKE) xermit \ - "LNKFLAGS = -N4M -3r" \ - "CFLAGS = -3r -ms -DQNX -DNONET -DNOIKSD -DCK_CURSES \ - -DCK_WREFRESH -DCK_REDIR -DSELECT -DSELECT_H -DCK_RTSCTS -DNOJC \ - -DNOUUCP -DCK_ANSIC -DPID_T=pid_t -Oatx -zc $(KFLAGS)" \ - "LIBS= -lsocket -lncurses -ltermcap" - @wermit -h >use.qnx - @usemsg wermit use.qnx - @rm use.qnx - -# Synonym for qnx32. -qnx: - $(MAKE) qnx32 "KFLAGS=$(KFLAGS)" - -# QNX 4.21 and above, 16-bit version, Watcom C 8.5 - and higher on i286 PCs -# and above. -# -# IMPORTANT: Do not use Watcom C 10.6!!! -# If you have it installed, add "-v9.52 to CFLAGS" -# -# NOTE: QNX 4.23 onward does not work on 286's anyway. -# Stacksize 26000, objects larger than 100 bytes in their own segments, -# string constants to the codesegment, etc. Fully configured except job ctrl. -# This entry works for building a 16-bit executable on a 32-bit system, but -# has not been tested on a 16-bit system. Uses large memory model, links -# explicitly with large-model sockets library. Correct-model curses library -# is chosen automatically. See comment in qnx32 entry about -DNOUUCP. -# -# WARNING: -# -# Watcom C prior to 10.6 never had released curses library. To link against it, -# you must obtain ported free curses source from ftp://ftp.qnx.com/usr/free, -# then compile and build library (cursesl.lib) and place it in /usr/lib. You -# must also copy curses.h to /usr/include. Be aware that if you have Watcom -# 10.6 installed, you should already have curses.h, which is the new ncurses -# library. You must back it up and use free curses.h instead, since ncurses is -# only for 32-bit applications and some definitions in these files are -# different (e.g., clearok()). For safety, curses is not defined in build. -# -# In 7.0 -DNOHELP added to keep ckuus2.c from blowing up; NOCSETS and NOSPL -# added because ckuus4 was blowing up, and NOFLOAT just because it seemed -# dangerous (remove -DNOFLOAT if you want to try it), The result works OK -# except for some mysterious beeps upon termination of the top-level keyword. -# -# Things to try next time we get in trouble: -# . Change -zt100 to something smaller like -zt25 -# . Change -Oatx to -Omilerat (enable stack checking) -# . Maybe get rid of -v9.52 -- it's only there because we were warned. -# -qnx16: - @echo 'Making C-Kermit $(CKVER) for QNX 4.21, 16-bit...' - $(MAKE) xermit \ - "LNKFLAGS = -2 -ml -N 26000" \ - "CFLAGS = -2 -Oatx -zc -zt100 -ml -DQNX -DQNX16 -DNOUUCP -DNOHELP \ - -DCK_REDIR -DSELECT -DSELECT_H -DNOJC -DNOGETUSERSHELL -DNOCSETS \ - -v9.52 -DTCPSOCKET -DCK_RTSCTS -DCK_ANSIC -DNOINITGROUPS -DNOKVERBS \ - -DNORANDOM -DNOCSETS -DNOSPL -DNOFLOAT -DPID_T=pid_t $(KFLAGS)" - -# QNX 4.1, 16-bit version, with Watcom C 8.5 on i286 PCs and above. -# stacksize 26000, objects larger than 100 bytes in their own segments, -# string constants to the codesegment, etc. Add -DNOUUCP if desired. -qnx16_41: - @echo 'Making C-Kermit $(CKVER) for QNX 4.1, 16-bit...' - $(MAKE) xermit \ - "LNKFLAGS = -mh -N 26000" "CFLAGS = -Wc,-fpc -Wc,-j -DNOGETUSERSHELL \ - -Wc,-Ols -Wc,-zdf -Wc,-zc -Wc,-zt100 -mh -DPOSIX -DQNX -DDIRENT \ - -DNOCYRIL -DNODEBUG -DNOMSEND -DMINIDIAL -DNOXMIT -DNOSCRIPT -DNOSPL \ - -DNOSETKEY -DNOINITGROUPS -DQNX16 -DPID_T=pid_t $(KFLAGS)" - -# QNX Neutrino 2 (pwaechtler@qnx.de) crosscompiled on QNX 4.25. -# Gets lots of compiler warnings. -qnx_nto2+: - @echo 'Making C-Kermit $(CKVER) for QNX Neutrino 2+ ' - cc -o wart ckwart.c - $(MAKE) xermit \ - "CC = qcc -Vgcc_ntox86" \ - "CC2 = qcc -Vgcc_ntox86" \ - "LNKFLAGS = " \ - "CFLAGS = -DNEUTRINO -DTCPSOCKET -DCK_CURSES -DNOGETUSERSHELL \ - -DNOUUCP -DCK_WREFRESH -DCK_REDIR -DSELECT -DSELECT_H -DCK_RTSCTS \ - -DNOJC -DNOINITGROUPS -DCK_ANSIC -DPID_T=pid_t -DUNIX -DDIRENT \ - -DMYREAD -DBSD44ORPOSIX -DSVORPOSIX -DNDGPWNAM $(KFLAGS)" \ - "LIBS= -lsocket -lncurses " - -# QNX 6 (= Neutrino 2.xx) native build (kirussel@cisco.com). -qnx6: - @echo 'Making C-Kermit $(CKVER) for QNX6' - $(MAKE) xermit KTARGET=QNX6 \ - "CFLAGS = -DPOSIX -DCK_POSIX_SIG -DNETPTY -DNOARROWKEYS \ - -DUSE_TIOCSDTR -DBIGBUFOK -DCKMAXOPEN=100 -DRLOGCODE -DNOREALPATH \ - -DMAXNAMLEN=48 -DQNX6 -DUSE_TERMIO -DINIT_SPTY \ - -DCK_CURSES -DCK_WREFRESH -DCK_NEWTERM -DDYNAMIC \ - -DTCPSOCKET -DNOGETUSERSHELL -DCK_REDIR -DSELECT -DSELECT_H \ - -DCK_RTSCTS -DNOJC -DSVORPOSIX -DBSD44ORPOSIX -DNOUUCP -DCK_ANSIC \ - $(KFLAGS) -O" \ - "LIBS= -lsocket -lncurses" - -#Ridge 32 with ROS 3.2 -ridge32: - @echo 'Making C-Kermit $(CKVER) Ridge 32 ROS 3.2' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DNOFILEH -DNODEBUG -DNOTLOG $(KFLAGS) -i -O" \ - "LNKFLAGS = -i" - -#Altos 486, 586, or 986 with Xenix 3.0 -altos: - @echo 'Making C-Kermit $(CKVER) for Altos x86 with Xenix 3.0...' - $(MAKE) wermit \ - "CFLAGS= -DATTSV -DA986 -DNODEBUG -DNOTLOG $(KFLAGS) -i -O" \ - "LNKFLAGS= -i" - -#Altos 986 with Xenix 3.0, as above, but command-line only, minimal size. -#For systems with small memories. It might also be necessary to chop certain -#modules up into smaller pieces, e.g. ckuus3-6, because of symbol table -#overflow. If this makefile is too big or complex for the Altos, compile -#and link by hand or write shell scripts. -altosc: - @echo 'Making C-Kermit $(CKVER) for Altos x86 Xenix 3.0, remote...' - $(MAKE) wermit \ - "CFLAGS= -DATTSV -DA986 -DNODEBUG -DNOTLOG -DNOSCRIPT -DNODIAL \ - -DNOCSETS -DNOANSI -DNOMSEND -DNOSPL -DNOICP $(KFLAGS) -Mm -O" \ - "LNKFLAGS= -Mm -s" - -#Altos 986 with Xenix 3.0, as above, but interactive only, minimal size. -altosi: - @echo 'Making C-Kermit $(CKVER) for Altos x86 Xenix 3.0, local...' - $(MAKE) wermit \ - "CFLAGS= -DATTSV -DA986 -DNODEBUG -DNOTLOG -DNOSCRIPT -DNODIAL \ - -DNOCSETS -DNOANSI -DNOMSEND -DNOSPL -DNOCMDL -DNOFRILLS -DNOHELP \ - -DNOSETKEY $(KFLAGS) -Mm -O" "LNKFLAGS= -Mm -s" - -# Altos ACS68000 68000 System, UNIX System 3 Release 2, 512k memory. -# also needs getcwd() external function; see ckuins.txt file. -# also, sys/types.h needed modifying: -# #ifdef __SYS_TYPES_H__, #define ..., #endif -# also, ckuus2.c MUST be compiled NOOPT else symbol table is destroyed! -# Submission by Robert Weiner/Programming Plus, rweiner@progplus.com. -# -altos3: - @echo 'Making C-Kermit $(CKVER) for Altos ACS68k UNIX System III' - $(MAKE) ckuus2.$(EXT) "CFLAGS = -DATTSV -DNOCSETS -DNOSETKEY -DNOJC \ - -DNODIAL -DDCLPOPEN -DNOSCRIPT -DNOHELP $(KFLAGS) -i" - $(MAKE) wermit \ - "CFLAGS = -DATTSV -DNOCSETS -DNOSETKEY -DNOJC \ - -DNODIAL -DDCLPOPEN -DNOSCRIPT -DNOHELP $(KFLAGS) -i -O" \ - "LNKFLAGS = -i" "LIBS = getcwd.$(EXT)" - -#MINIX - Original PC version with 64K+64K limit. -# Reportedly, the linker (asld) can run out of space while linking. The only -# way around this is to make a copy of libc.a from which all modules that are -# not used by Kermit are removed. If you have trouble compiling or running -# wart, "touch wart". If that doesn't help, "touch ckcpro.c". -# The version configured below has no interactive command parser. -# If you can build this version successfully, maybe there will be room for -# a minimal interactive command parser too; try replacing -DNOICP with -# -DNOSPL, plus every other -DNOxxx flag there is, except for -DNOICP -# (see ckccfg.txt). -minix: - @echo 'Making C-Kermit $(CKVER) for MINIX, no command parser... - @echo 'TOTALLY UNTESTED!' - $(MAKE) wermit EXT=s \ - "CFLAGS= -DV7 -DMINIX -i -D_MINIX -D_POSIX_SOURCE \ - -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V \ - -DNOXMIT -DNOMSEND -DNOFRILLS -DNODIAL -DNOHELP -DNODEBUG -DNOTLOG \ - -DNOSCRIPT -DNOCSETS -DNOICP -DNOSETKEY $(KFLAGS)" \ - "LNKFLAGS= -i -T" - -#MINIX - PC version with 64K+64K limit, new (as yet unreleased) ACK 2.0 beta C -#compiler, which outputs .o object files, rather than .s. But 'make' still -#expects .s files, so must be patched to use .o. Tested on Minix 1.5.10. -minixnew: - @echo 'Making C-Kermit $(CKVER) for MINIX (new ACK 2.0 compiler),' - @echo 'no command parser... TOTALLY UNTESTED!' - $(MAKE) wermit \ - "CFLAGS= -DV7 -DMINIX -i -D_MINIX -D_POSIX_SOURCE \ - -DPID_T=pid_t -DUID_T=uid_t -DGID_T=gid_t -DSIG_V -DNODIAL \ - -DNOHELP -DNODEBUG -DNOTLOG -DNOSCRIPT -DNOCSETS -DNOICP $(KFLAGS)" \ - "LNKFLAGS= -i -T" - -#PFU Compact A Series UNIX System V R3, SX/A TISP V10/L50 (Japan) -#Maybe the -i link option should be removed? -sxae50: - @echo 'Making C-Kermit $(CKVER) for PFU SX/A V10/L50...' - $(MAKE) xermit \ - "CFLAGS= -DSVR3 -DDIRENT -DsxaE50 -DTCPSOCKET $(KFLAGS) -i -O" \ - "LNKFLAGS= " - -#Tektronix 6130, 4319, 4301, etc, with UTek OS, /usr/spool/uucp/LCK./... -#The models that support hardware flow control. -utek: - @echo 'Making C-Kermit $(CKVER) for 4.2BSD/UTek, hardware flow control' - $(MAKE) wermit \ - "CFLAGS= -O -DLCKDIR -DBSD4 -DTCPSOCKET \ - -DUTEK -DDCLPOPEN -DLOCK_DIR=\\\"/usr/spool/uucp/LCK.\\\" \ - -DTRMBUFL=2048 -DCK_DTRCTS $(KFLAGS)" - -#Tektronix 4315, 4316, 4317 with UTek OS, /usr/spool/uucp/LCK./... -#The models that do not fully support hardware flow control. -uteknohwfc: - @echo 'Making C-Kermit $(CKVER) for 4.2BSD/UTek, no h/w flow control' - $(MAKE) wermit \ - "CFLAGS= -O -DLCKDIR -DBSD4 -DTCPSOCKET \ - -DUTEK -DDCLPOPEN -DLOCK_DIR=\\\"/usr/spool/uucp/LCK.\\\" \ - -DTRMBUFL=2048 $(KFLAGS)" - -#Tektronix XD88 with UTekV OS -utekvr3: - @echo 'Making C-Kermit $(CKVER) for Tektronix XD88 UTekV R3...' - $(MAKE) wermit \ - "CFLAGS= -DSVR3 -DDIRENT -DHDBUUCP \ - -DTCPSOCKET -DSYSUTIMEH -DCK_CURSES $(KFLAGS) -O" \ - "LIBS= -lcurses" "LNKFLAGS= -s" - -#Perkin-Elmer 3200 Xelos R02 or earlier -ccop1: - @echo 'Making C-Kermit $(CKVER) for Xelos & Public Domain Dirent calls' - @echo 'or System V R2 or earlier...' - $(MAKE) wermit \ - "CFLAGS = -DATTSV -Dvoid=int -DDIRENT -DCK_CURSES \ - $(KFLAGS) -O" "LNKFLAGS =" "LIBS= -lcurses -ltermlib" - -#Encore, UMAX 4.3 (BSD) but without acucntrl program. -encore: - $(MAKE) "MAKE=$(MAKE)" umax43 "KFLAGS=$(KFLAGS)" - -#Encore, as above, but with curses file transfer display included. -encorec: - $(MAKE) "MAKE=$(MAKE)" umax43 "KFLAGS=-DCK_CURSES $(KFLAGS)" \ - "LIBS= -lcurses -ltermcap" - -#Encore, UMAX 4.3 (BSD) but without acucntrl program. -umax43: - @echo Making C-Kermit $(CKVER) for Encore UMAX 4.3... - $(MAKE) "MAKE=$(MAKE)" PARALLEL=4 xermit \ - "CFLAGS= -DBSD43 -DENCORE -DTCPSOCKET $(KFLAGS) -O" - -#Encore, UMAX 4.2 (BSD) -umax42: - @echo Making C-Kermit $(CKVER) for Encore UMAX 4.2... - $(MAKE) "MAKE=$(MAKE)" PARALLEL=4 xermit \ - "CFLAGS= -DBSD4 -DENCORE -DTCPSOCKET $(KFLAGS) -O" - -#Encore 88K UMAX 5.3 with TCP/IP support -encore88k: - @echo 'Making C-Kermit $(CKVER) for Encore 88K UMAX V, TCP/IP...' - $(MAKE) xermit \ - "CFLAGS = -q ext=pcc -DSVR3 -DTCPSOCKET -DDIRENT \ - -DNOGETID_PROTOS -DHDBUUCP $(KFLAGS) -O" "LNKFLAGS =" - -#Encore 88K UMAX 5.3 with TCP/IP support -encore88kgcc: - @echo 'Making C-Kermit $(CKVER) for Encore 88K UMAX V, TCP/IP, gcc...' - $(MAKE) xermit CC=gcc CC2=gcc \ - "CFLAGS = -DSVR3 -DTCPSOCKET -DDIRENT \ - -DNOGETID_PROTOS -DHDBUUCP $(KFLAGS) -O" "LNKFLAGS =" - -#SONY NEWS, NEWS-OS 4.01C -sonynews: - @echo Making C-Kermit $(CKVER) for SONY NEWS-OS 4.01C... - $(MAKE) xermit "CFLAGS= -DBSD43 -DACUCNTRL -DTCPSOCKET -O" - -#Run Lint on this mess for selected versions. -#These are pretty much obsolete since ANSI C / gcc. -lintsun: - @echo 'Running Lint on C-Kermit $(CKVER) sources for SunOS version...' - lint -x -DSUNOS4 -DDIRENT -DTCPSOCKET -DSAVEDUID \ - ck[cu]*.c > ckuker.lint.sun - -lintbsd: - @echo 'Running Lint on C-Kermit $(CKVER) sources for BSD 4.2 version..' - lint -x -DBSD4 -DTCPSOCKET ck[cu]*.c > ckuker.lint.bsd42 - -lints5: - @echo 'Running Lint on C-Kermit $(CKVER) sources for Sys V version...' - lint -x -DATTSV ck[cu]*.c > ckuker.lint.s5 - -#Who remembers TECO? -love: - @echo 'Not war?' diff --git a/.pc/020_man-hyphen-quoting.patch/.timestamp b/.pc/020_man-hyphen-quoting.patch/.timestamp deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/020_man-hyphen-quoting.patch/ckuker.nr b/.pc/020_man-hyphen-quoting.patch/ckuker.nr deleted file mode 100644 index b26801d..0000000 --- a/.pc/020_man-hyphen-quoting.patch/ckuker.nr +++ /dev/null @@ -1,1827 +0,0 @@ -.\" @(#) kermit.1 8.0.211 2004/04/10 Columbia University -.TH KERMIT 1 "APRIL 2004" "User Manuals" -.na -.SH NAME -kermit \- -.B C-Kermit 8.0: -transport- and platform-independent -interactive and scriptable communications software. -.IP - -This document is intended to give the beginner sufficient information to make -basic (if not advanced) use of C-Kermit 8.0. Although it might be rather long -for a Unix manual page, it's still far shorter than the C-Kermit manual, which -should be consulted for advanced topics such as customization, character-sets, -scripting, etc. We also attempt to provide a clear structural overview of -C-Kermit's many capabilities, functional areas, states, and modes and their -interrelation, that should be helpful to beginners and veterans alike, as well -as to those upgrading to version 8.0 from earlier releases. -.PP -This document is also available as a Web page at: -.IP -http://www.columbia.edu/kermit/ckututor.html -.SH DESCRIPTION -C-Kermit is an all-purpose communications software package from the Kermit -Project at Columbia University that: -.PP -.nf -\(bu Is portable to many platforms, Unix and non-Unix alike. -.br -\(bu Can make both serial and network connections. -.br -\(bu Can conduct interactive terminal sessions over its connection. -.br -\(bu Can transfer text or binary files over the same connection. -.br -\(bu Can convert character sets in the terminal session. -.br -\(bu Can convert character sets during text-file file transfer. -.br -\(bu Is customizable in every aspect of its operation. -.fi -.PP -C-Kermit is a modem program, a Telnet client, an Rlogin client, an FTP -client, an HTTP client, and on selected platforms, also an X.25 client. It -can make its own secure Internet connections using IETF-approved security -methods including Kerberos IV, Kerberos V, SSL/TLS, and SRP and it can also -make SSH connections through your external SSH client application. It can -be the far-end file-transfer or client/server partner of your desktop -Kermit client. It can also accept incoming dialed and network connections. -It can even be installed as an Internet service on its own standard TCP -socket, 1649 [RFC2839, RFC2840]. -.PP -And perhaps most important, everything you can do "by hand" (interactively) -with C-Kermit, can be "scripted" (automated) using its built-in -cross-platform transport-independent script programming language, which -happens to be identical to its interactive command language. -.PP -This manual page offers an overview of C-Kermit 8.0 for Unix ("Unix" is an -operating system family that includes AIX, DG/UX, FreeBSD, HP-UX, IRIX, -Linux, Mac OS X, NetBSD, OpenBSD, Open Server, Open Unix, QNX, Solaris, -SunOS, System V R3, System V R4, Tru64 Unix, Unixware, Xenix, and many -others). For thorough coverage, please consult the published C-Kermit -manual and supplements (see DOCUMENTATION below). For further information -about C-Kermit, Kermit software for other platforms, and Kermit manuals, -visit the Kermit Project website: -.PP - http://www.columbia.edu/kermit/ -.PP -This is a longer-than-average manual page, and yet it barely scratches the -surface. Don't be daunted. C-Kermit is a large and complex package, -evolving over decades of practice and experience, but that doesn't mean -it's hard to learn or use. Its most commonly used functions are explained -here with pointers to additional information elsewhere. -.SH SYNOPSIS -.B kermit [ -.I filename -.B ] [ -.I options -.B ] [ {=,--,+} -.I text -.B ] ] -.PP -or: -.PP -.B kermit -.I URL -.PP -If the first command-line argument is the name of a file, interactive-mode -commands are executed from the file. The '=' (or "--") argument tells -Kermit not to parse the remainder of the command line, but to make the -words following '=' available as \e%1, \e%2, ... \e%9. The "+" argument is -like "=" but for use in "kerbang scripts" (explained below). A second -command-line format allows the one and only argument to be a Telnet, FTP, -HTTP, or IKSD URL. -.PP -Order of execution: -.TP - 1. -The command file (if any). -.TP -.nf - 2. -The initialization file, if any, unless suppressed with -Y. -.fi -.TP - 3. -The customization file (if it is executed by the initialization file). -.TP - 4. -The command-line URL (if any, and if so, execution stops here). -.TP - 5. -Command-line options (if any). -.TP - 6. -Interactive commands. -.PP -Some command-line options can cause actions (such as -s to send a file); -others just set parameters. If any action options are included on the -command line, Kermit exits when finished unless also given the -S ("stay") -option. If no action options are given, no initialization or command files -contained an EXIT or QUIT command, and no fatal errors occurred, Kermit -issues its prompt and waits for you to type commands. -.IP -Bear in mind that C-Kermit can be built with selected features -disabled, and also that certain features are not available on all -platforms. For example, C-Kermit can't be built with TCP/IP -support on a platform that does not have TCP/IP header files and -libraries (and even if Kermit does include TCP/IP support, it -can't be used to make TCP/IP connections on a computer that does -not have a TCP/IP stack installed). If your version of lacks -C-Kermit a feature mentioned here, use its SHOW FEATURES command to -see what might have been excluded. -.PP -C-Kermit has three kinds of commands: regular single-letter command-line -options, extended-format command-line options, and interactive commands. -.PP -Like most Unix commands, C-Kermit can be be given options on the command -line. But C-Kermit also can be used interactively by giving it commands -composed of words, which are more intuitive than cryptic command-line -options, and more flexible too. In other words, you don't have to use -C-Kermit's command-line options, but they are available if you want to. (By -the same token, you don't have to use its interactive commands either -- -you can use either or both in any combination.) -.PP -C-Kermit is generally installed in the PATH as "kermit", and therefore is -invoked by typing the word "kermit" (lowercase) at the shell prompt, and -then pressing the Return or Enter key. If you wish to include command-line -options, put them after the word "kermit" but before pressing Return or -Enter, separated by spaces, for example: -.PP - $ kermit -s ckermit.tar.gz -.PP -('$' is the shell prompt; "kermit -s ckermit.tar.gz" is what you type, -followed by Return or Enter.) -.SH OPTIONS -Here is a list of C-Kermit's single-letter command-line options, which -start with a single dash (-), in ASCII ("alphabetical") order. Alphabetic -case is significant (-A is not the same as -a). Action options are -tagged "ACTION". -.TP --0 -(digit zero) 100% transparent Connect state for -"in-the-middle" operation: 8 bits, no parity, no -escape character, everything passes through. -.TP --8 -(digit eight) Connection is 8-bit clean (this is the -default in C-Kermit 8.0). Equivalent to the EIGHTBIT -command, which in turn is a shortcut for SET TERMINAL -BYTESIZE 8, SET COMMAND BYTESIZE 8, SET PARITY NONE. -.TP --9 arg -(digit nine) Make a connection to an FTP server. -Equivalent to the FTP OPEN command. -Argument: IP-address-or-hostname[:optional-TCP-port]. -NOTE: C-Kermit also has a separate FTP command-line -personality, with regular FTP-like command-line -syntax. More about this below. -.TP --A -Kermit is to be started as an Internet service (IKSD) -(only from inetd.conf). -.TP --B -Kermit is running in Batch or Background (no -controlling terminal). To be used in case Kermit -doesn't automatically sense its background status. -Equivalent to the SET BACKGROUND ON command. -.TP --C arg -Interactive-mode Commands to be executed. -Argument: Commands separated by commas, list in -doublequotes. -.TP --D arg -Delay before starting to send in Remote mode. -Equivalent to the SET DELAY command. -Argument: Number of seconds. -.TP --E -Exit automatically when connection closes. Equivalent -to SET EXIT ON-DISCONNECT ON. -.TP --F arg -Use an open TCP connection. -Argument: Numeric file descriptor of open TCP -connection. -Also see: -j, -J. -.TP --G arg -(ACTION) Get file(s) from server, send contents to standard -output, which normally would be piped to another -process. -Argument: Remote file specification, in quotes if it -contains metacharacters. -Also see: -g, -k. -.TP --H -Suppress program startup Herald and greeting. -.TP --I -Tell Kermit it has a reliable connection, to force streaming to be used where -it normally would not be. Equivalent to the SET RELIABLE ON command. -.TP --J arg -(ACTION) "Be like Telnet." Like -j but implies -E. Argument: IP -hostname/address optionally followed by service. NOTE: C-Kermit also has a -separate Telnet command-line personality, with regular Telnet-like -command-line syntax. More about this below. -.TP --L -Recursive directory descent for files in -s option. -.TP --M arg -My user name (for use with Telnet, Rlogin, FTP, etc). -Equivalent to the SET LOGIN USER command. -Argument: Username string. -.TP --O -(ACTION) (Uppercase letter O) Be a server for One command only. -Also see: -x. -.TP --P -Don't convert file (Path) names of transferred files. -Equivalent to SET FILE NAMES LITERAL. -.TP --Q -Quick Kermit protocol settings. Equivalent to the FAST -command. This is the default in C-Kermit 7.0 and later. -.TP --R -Remote-only (this just makes IF REMOTE true). -.TP --S -Stay (enter command parser after action options). -.TP --T -Force Text mode for file transfer; implies -V. -Equivalent to SET TRANSFER MODE MANUAL, SET FILE TYPE TEXT. -.TP --V -Disable automatic per-file text/binary switching. -Equivalent to SET TRANSFER MODE MANUAL. -.TP --Y -Skip (don't execute) the initialization file. -.TP --a arg -As-name for file(s) in -s, -r, or -g. -Argument: As-name string (alternative filename). When -receiving files, this can be a directory name. -.TP --b arg -Speed for serial device. Equivalent to SET SPEED. -Argument: Numeric Bits per second for serial -connections. -.TP --c -(ACTION) Enter Connect state before transferring files. -.TP --d -Create a debug.log file with detailed debugging -information (a second -d adds timestamps). Equivalent -to LOG DEBUG but takes effect sooner. -.TP --e arg -Maximum length for incoming Kermit file-transfer -packets. Equivalent to SET RECEIVE PACKET-LENGTH. -Argument: Length in bytes. -.TP --f -(ACTION) Send a FINISH command to a Kermit server. -.TP --g arg -Get file(s) from a Kermit server. -Argument: File specification on other computer, in -quotes if it contains metacharacters. Equivalent to -GET. Also see: -a, -G, -r. -.TP --h -(ACTION) Print Help text for single-letter command-line options -(pipe thru 'more' to prevent scrolling). -.TP --i -Force binary (Image) mode for file transfer; implies --V. Equivalent to SET TRANSFER MODE MANUAL, SET FILE -TYPE BINARY. -.TP --j arg -Make a TCP/IP connection. -Argument: IP host name/address and optional service -name or number. Equivalent to the TELNET command. -Also see: -J, -F. -.TP --k -(ACTION) Receive file(s) to standard output, which normally -would be piped to another process. -Also see: -r, -G. -.TP --l arg -(Lowercase letter L) Make a connection on the given -serial communications device. Equivalent to the SET -LINE (SET PORT) command. -Argument: Serial device name, e.g. /dev/ttyS0. -.TP --m arg -Modem type for use with the -l device. Equivalent to -the SET MODEM TYPE command. -Argument: Modem name as in SET MODEM TYPE command, -e.g. "usrobotics". -.TP --n -(ACTION) Enter Connect state after transferring files (historical). -.TP --p arg -Parity. Equivalent to the SET PARITY command. -Argument: One of the following: e(ven), o(dd), m(ark), -n(one), s(pace). -.TP --q -Quiet (suppress most messages). Equivalent to SET QUIET ON. -.TP --r -(ACTION) Receive file(s). Equivalent to the RECEIVE command. -Argument: (none, but see -a) -.TP --s arg -Send file(s). -Argument: One or more local file specifications. -Equivalent to the SEND command. -Also see: -a. -.TP --t -(Historical) Xon (Ctrl-Q) Turnaround character for -half-duplex connections (used on serial linemode -connections to old mainframes). Equivalent to SET -DUPLEX HALF, SET HANDSHAKE XON. -.TP --v arg -Window size for Kermit protocol (ignored when -streaming). Equivalanet to SET WINDOW-SIZE. -Argument: Number, 1 to 32. -.TP --w -Incoming files Write over existing files. Equivalent -to SET FILE COLLISION OVERWRITE. -.TP --x -(ACTION) Enter server mode. Equivalent to the SERVER command. -Also see: -O. -.TP --y arg -Alternative initialization file. -Argument: Filename. -.TP --z -Force foreground behavior. To be used in case Kermit -doesn't automatically sense its foreground status. -Equivalent to the SET BACKGROUND OFF command. -.PP -Extended command-line options (necessary because single-letter ones are -about used up) start with two dashes (--), with words rather than single -letters as option names. If an extended option takes an argument, it is -separated from the option word by a colon (:). Extended options include: - -.TP - --bannerfile:filename -File to display upon startup or IKSD login. -.TP - --cdfile:filename -File to be sent for display to the client when -server changes directory (filename is relative to -the changed-to directory). -.TP - --cdmessage:{on,off} -Enable/disable the server CD message feature. -.TP - --help -Prints usage message for extended options. -.TP - --helpfile:filename -Designates a file containing custom text to -replace the top-level HELP command. -.TP - --nointerrupts -Disables keyboard interrupts. -.TP - --noperms -Disables the Kermit protocol file Permissions -attribute, to prevent transmission of file -permissions (protection) from sender to receiver. -.TP - --version -(ACTION) C-Kermit prints its version number. -.PP -Plus several other IKSD-Only options described at: -.PP - http://www.columbia.edu/kermit/iksd.html -.PP -See the file-transfer section for examples of command-line invocation. -.SH COMMAND LANGUAGE -C-Kermit's interactive command language is the subject of a 622-page book -and another several hundred pages of updates, far too much for a manual -page. But it's not hard to get started. At the shell prompt, just type -"kermit" to get C-Kermit's interactive command prompt: -.PP -.nf - $ kermit - (/current/directory) C-Kermit> -.fi -.PP -Begin by typing "help" (and then press the Return or Enter key) for a -top-level overview, read it, and go from there. Your second command should -probably be "intro" (introduction). Note the prompt shows your current -directory (unless you tell Kermit to prompt you with something else). -.PP -Interactive commands are composed mainly of regular English words, usually -in the form of imperative sentences, such as: -.PP - send oofa.txt -.PP -which tells Kermit to send (transfer) the file whose name is oofa.txt, or: -.PP - set transfer mode automatic -.PP -which sets Kermit's "transfer mode" to "automatic" (whatever that means). -.PP -While typing commands, you can abbreviate, ask for help (by pressing the -"?" key anywhere in a command), complete keywords or filenames (with the -Tab or Esc key), and edit your typing with Backspace or Delete, Ctrl-W, -Ctrl-U, etc. You can also recall previous commands, save your command -history, and who knows what else. Give the INTRO command for details. -.PP -C-Kermit has hundreds of commands, and they can be issued in infinite -variety and combinations, including commands for: -.nf -.PP -\(bu Making connections (SET LINE, DIAL, TELNET, SSH, FTP, ...) -.br -\(bu Breaking connections (HANGUP, CLOSE) -.br -\(bu Transferring files (SEND, GET, RECEIVE, MOVE, RESEND, ...) -.br -\(bu Establishing preferences (SET) -.br -\(bu Displaying preferences (SHOW) -.br -\(bu Managing local files (CD, DELETE, MKDIR, DIR, RENAME, TYPE, ...) -.br -\(bu Managing remote files (RCD, RDEL, RMKDIR, RDIR, ...) -.br -\(bu Using local files (FOPEN, FCLOSE, FREAD, FWRITE) -.br -\(bu Programming (TAKE, DEFINE, IF, FOR, WHILE, SWITCH, DECLARE, ...) -.br -\(bu Interacting with the user (ECHO, ASK, ...) -.br -\(bu Interacting with a remote computer (INPUT, OUTPUT, ...) -.br -\(bu Interacting with local programs (RUN, EXEC, PTY, ...) -.br -\(bu Logging things (LOG SESSION, LOG PACKETS, LOG DEBUG, ...) -.PP -.fi -And of course QUIT or EXIT to get out and HELP to get help, and for -programmers: loops, decision making, variables, arrays, associative arrays, -integer and floating point arithmetic, macros, built-in and user-defined -functions, string manipulation, pattern matching, block structure, scoping, -recursion, and all the rest. To get a list of all C-Kermit's commands, type -a question mark (?) at the prompt. To get a description of any command, -type HELP followed by the name of the command, for example: -.PP - help send -.PP -The command interruption character is Ctrl-C (hold down the Ctrl key and -press the C key). -.PP -The command language "escape character", used to introduce variable names, -function invocations, and so on, is backslash (\). If you need to include a -literal backslash in a command, type two of them, e.g.: -.PP - get c:\ek95\ek95custom.ini -.SS Command Files, Macros, and Scripts -A file containing Kermit commands is called a Kermit command file or Kermit -script. It can be executed with Kermit's TAKE command: -.PP - (/current/dir) C-Kermit> take commandfile -.PP -(where "commandfile" is the name of the command file). Please don't pipe a -command file into Kermit's standard input (which might or might not work); -if you have Kermit commands in a file, tell Kermit to TAKE the file. -.PP -In Unix only, a Kermit command file can also be executed directly by -including a "kerbang" line as the first line of the file: -.PP - #!/usr/local/bin/kermit + -.PP -That is, a top line that starts with "#!", followed immediately by the full -path of the Kermit executable, and then, if the Kermit script is to be -given arguments on the command line, a space and a plus sign. The script -file must also have execute permission: -.PP - chmod +x commandfile -.PP -Except for the " +" part, this is exactly the same as you would do for a -shell script, a Perl script, etc. Here's a simple but useless example -script that regurgitates its arguments (up to three of them): -.PP - #!/usr/local/bin/kermit + - if defined \e%1 echo "Argument 1: \e%1" - if defined \e%2 echo "Argument 2: \e%2" - if defined \e%3 echo "Argument 3: \e%3" - if defined \e%4 echo "etc..." - exit -.PP -If this file is stored in your current directory as "commandfile", then: -.PP - ./commandfile one two three four five -.PP -prints: -.PP - Argument 1: one - Argument 2: two - Argument 3: three - etc... -.PP -This illustrates the basic structure of a standalone Kermit script: the -"kerbang line", then some commands. It should end with "exit" unless you -want the Kermit prompt to appear when it is finished. \e%1 is the first -argument, \e%2 the second, and so on. -.PP -You can also create your own commands by defining named macros composed of -other Kermit commands (or macros). For example: -.PP -.nf - define mydelete { - local trash - assign trash \ev(home)trashcan/ - if not defined \e%1 end 1 "Delete what?" - if wild \e%1 { - end 1 "Deleting multiple files is too scary" - } - if not exist \e%1 end 1 "I can't find \e%1" - if not directory \em(trash) { - mkdir \em(trash) - if fail end 1 "No trash can" - } - rename /list \e%1 \em(trash) - } - define myundelete { - local trash - assign trash \ev(home)trashcan/ - if not defined \e%1 end 1 "Undelete what?" - if wild \e%1 { - end 1 "Undeleting multiple files is too hard" - } - if not directory \em(trash) end 1 "No trash can" - if not exist \em(trash)\e%1 { - end 1 "I can't find \e%1 in trash can" - } - rename /list \em(trash)\e%1 . - } -.PP -.fi -These sample macros are not exactly production quality (they don't handle -filenames that include path segments, they don't handle multiple files, -etc), but you get the idea: you can pass arguments to macros, and they can -check them and make other kinds of decisions. If you put the above lines -into your initialization or customization file (explained below), you'll -have MYDELETE and MYUNDELETE commands available every time you start -Kermit, at least as long as you don't suppress execution of the -initialization file. (Exercise for the reader: Make these macros generally -useful: remove limitations, add trashcan display, browsing, emptying, etc.) -.PP -Kerbang scripts execute without the initialization file. This to keep them -portable and also to make them start faster. If you want to write Kerbang -scripts that depend on the initialization file, include the command -.PP - take \ev(home).kermrc -.PP -at the desired spot in the script. By the way, \ev(xxx) is a built-in -variable (xxx is the variable name, "home" in this case). To see what -built-in variables are available, type "show variables" at the C-Kermit -prompt. To see what else you can show, type "show ?". \em(xxx) is a user -defined variable (strictly speaking, it is a macro used as a variable). -.SS Command List -C-Kermit has more than 200 top-level commands, and some of these, such as -SET, branch off into hundreds of subcommands of their own, so it's not -practical to describe them all here. Instead, here's a concise list of the -most commonly used top-level commands, grouped by category. To learn about -each command, type "help" followed by the command name, e.g. "help set". -Terms such as Command state and Connect state are explained in subsequent -sections. -.PP -Optional fields are shown in [ brackets ]. "filename" means the -name of a single file. filespec means a file specification that is allowed -to contain wildcard characters like '*' to match groups of files. options -are (optional) switches like /PAGE, /NOPAGE, /QUIET, etc, listed in the -HELP text for each command. Example: -.PP -.nf - send /recursive /larger:10000 /after:-1week /except:*.txt * -.fi -.PP -which can be read as "send all the files in this directory and all the ones -underneath it that are larger than 10000 bytes, no more than one week old, -and whose names don't end with ".txt". -.SS -Basic Commands -.RS -.TP -HELP -Requests top-level help. -.TP -HELP command -Requests help about the given command. -.TP -INTRODUCTION -Requests a brief introduction to C-Kermit. -.TP -LICENSE -Displays the C-Kermit software copyright and license. -.TP -VERSION -Displays C-Kermit's version number. -.TP -EXIT [ number ] -Exits from Kermit with the given -status code. Synonyms: QUIT, E, Q. -.TP -TAKE filename [ parameters... ] -Executes commands from the given -.TP -LOG item [ filename ] -Keeps a log of the given item in the given file. -.TP -[ DO ] macro [ parameters... ] -Executes commands from the given macro. -.TP -SET parameter value -Sets the given parameter to the given value. -.TP -SHOW category -Shows settings in a given category. -.TP -STATUS -Tells whether previous command succeeded or failed. -.TP -DATE [ date-and/or-time ] -Shows current date-time or interprets given date-time. -.TP -RUN [ extern-command [ parameters... ] -Runs the given external command. Synonym: !. -.TP -EXEC [ extern-command [ params... ] -Kermit overlays itself with the given command. -.TP -SUSPEND -Stops Kermit and puts it in the background. Synonym: Z. -.RE -.SS -Local File Management -.RS -.TP -TYPE [ options ] filename -Displays the contents of the given file. -.TP -MORE [ options ] filename -Equivalent to TYPE /PAGE (pause after each screenful). -.TP -CAT [ options ] filename -Equivalent to TYPE /NOPAGE. -.TP -HEAD [ options ] filename -Displays the first few lines of a given file. -.TP -TAIL [ options ] filename -Displays the last few lines of a given file. -.TP -GREP [ options ] pattern filespec -Displays lines from files that match -the pattern. Synonym: FIND. -.TP -DIRECTORY [ options ] [filespec ] -Lists files (built-in, many options). -.TP -LS [ options ] [ filespec ] -Lists files (runs external "ls" command). -.TP -DELETE [ options ] [ filespec ] -Deletes files. Synonym: RM. -.TP -PURGE [ options ] [ filespec ] -Removes backup (*.~n~) files. -.TP -COPY [ options ] [ filespecs... ] -Copies files. Synonym: CP. -.TP -RENAME [ options ] [ filespecs... ] -Renames files. Synonym: MV. -.TP -CHMOD [ options ] [ filespecs... ] -Changes permissions of files. -.TP -TRANSLATE filename charsets [ filename ] -Converts file's character set. Synonym: XLATE. -.TP -CD -Changes your working directory to your home directory. -.TP -CD directory -Changes your working directory to the one given. -.TP -CDUP -Changes your working directory one level up. -.TP -PWD -Displays your working directory. -.TP -BACK -Returns to your previous working directory. -.TP -MKDIR [ directory ] -Creates a directory. -.TP -RMDIR [ directory ] -Removes a directory. -.RE -.SS -Making Connections -.RS -.TP -SET LINE [ options ] devicename -Opens the named serial port. Synonym: SET PORT. -.TP -OPEN LINE [ options ] devicename -Same as SET LINE. Synonym: OPEN PORT. -.TP -SET MODEM TYPE [ name ] -Tells Kermit what kind of modem is on the port. -.TP -DIAL [ number ] -Tells Kermit to dial the given phone number with the modem. -.TP -REDIAL -Redials the most recently dialed phone number. -.TP -ANSWER -Waits for and answers an incoming call on the modem. -.TP -AUTHENTICATE [ parameters... ] -Performs secure authentication on a TCP/IP connection. -.TP -SET NETWORK TYPE { TCP/IP, X.25, ... } -Selects network type for subsequent SET HOST commands. -.TP -SET HOST [ options ] host [ port ] -Opens a network connection to the given host and port. -.TP -SET HOST * port -Waits for an incoming TCP/IP connection on the given port. -.TP -TELNET [ options ] host -Opens a Telnet connection to the host and enters Connect state. -.TP -RLOGIN [ options ] host -Opens an Rlogin connection to the host and enters Connect state. -.TP -IKSD [ options ] host -Opens a connection to an Internet Kermit Service. -.TP -SSH [ options ] host -Opens an SSH connection to the host and enters Connect state. -.TP -FTP OPEN host [ options ] -Opens an FTP connection to the host. -.TP -HTTP [ options ] OPEN host -Opens an HTTP connection to the host. -.TP -PTY external-command -Runs the command on a pseudoterminal as if it were a connection. -.TP -PIPE external-command -Runs the command through a pipe as if it were a connection. -.RE -.SS -Using Connections -.RS -.TP -CONNECT [ options ] -Enters Connect (terminal) state. Synonym: C. -.TP -REDIRECT command -Redirects the given external command over the connection. -.TP -TELOPT command -Sends a Telnet protocol command (Telnet connections only). -.TP -Ctrl-\eC -"Escapes back" from Connect state to Command state. -.TP -Ctrl-\eB -(In Connect state) Sends a BREAK signal (serial or Telnet). -.TP -Ctrl-\e! -(In Connect state) Enters inferior shell; "exit" to return. -.TP -Ctrl-\e? -(In Connect state) Shows a menu of other escape-level options. -.TP -Ctrl-\eCtrl-\e -(In Connect state) Type two -Ctrl-Backslashes to send one of them. -.TP -SET ESCAPE [ character ] -Changes Kermit's Connect-state escape character. -.RE -.SS -Closing Connections -.RS -.TP -HANGUP -Hangs up the currently open -serial-port or network connection. -.TP -CLOSE -Closes the currently open -serial-port or network connection. -.TP -SET LINE (with no devicename) -Closes the currently open -serial-port or network connection. -.TP -SET HOST (with no hostname) -Closes the currently open serial-port or network connection. -.TP -FTP CLOSE -Closes the currently open FTP connection. -.TP -HTTP CLOSE -Closes the currently open HTTP connection. -.TP -EXIT -Also closes all connections. Synonym: QUIT. -.TP -SET EXIT WARNING OFF -Suppresses warning about open connections on exit or close. -.RE -.SS -File Transfer -.RS -.TP -SEND [ options ] filename [ as-name ] -Sends the given file. Synonym: S. -.TP -SEND [ options ] filespec -Sends all files that match. -.TP -RESEND [ options ] filespec -Resumes an interupted SEND from the point of failure. -.TP -RECEIVE [ options ] [ as-name ] -Waits passively for files to arrive. Synonym: R. -.TP -LOG TRANSACTIONS [ filename ] -Keeps a record of file transfers. -.TP -FAST -Use fast file-transfer settings (default). -.TP -CAUTIOUS -Use cautious and less fast file-transfer settings. -.TP -ROBUST -Use ultra-conservative and slow file-transfer settings. -.TP -STATISTICS [ options ] -Gives statistics about the most recent file transfer. -.TP -WHERE -After transfer: "Where did my files go?". -.TP -TRANSMIT [ options ] [ofilename ] -Sends file without protocol. Synonym: XMIT. -.TP -LOG SESSION [ filename ] -Captures remote text or files without protocol. -.TP -SET PROTOCOL [ name... ] -Tells Kermit to use an external file-transfer protocol. -.TP -FTP { PUT, MPUT, GET, MGET, ... } -FTP client commands. -.TP -HTTP { PUT, GET, HEAD, POST, ... } -HTTP client commands. -.RE -.SS -Kermit Server -.RS -.TP -ENABLE, DISABLE -Controls which server features can be used by clients. -.TP -SET SERVER -Sets parameters prior to entering Server state. -.TP -SERVER -Enters Server state. -.RE -.SS -Client of Kermit or FTP Server -.RS -.TP -[ REMOTE ] LOGIN [ user password ] -Logs in to a Kermit server or IKSD that requires it. -.TP -[ REMOTE ] LOGOUT -Logs out from a Kermit server or IKSD. -.TP -SEND [ options ] filename [ as-name ] -Sends the given file to the server. Synonyms: S, PUT. -.TP -SEND [ options ] filespec -Sends all files that match. -.TP -RESEND [ options ] filespec -Resumes an interupted SEND from the point of failure. -.TP -GET [ options ] remote-filespec -Asks the server to send the given files. Synonym: G. -.TP -REGET [ options ] remote-filespec -Resumes an interrupted GET from the point of failure. -.TP -REMOTE CD [ directory ] -Asks server to change its working -directory. Synonym: RCD. -.TP -REMOTE PWD [ directory ] -Asks server to display its working directory. Synonym: RPWD. -.TP -REMOTE DIRECTORY [ filespec... ] -Asks server to send a directory listing. Synonym: RDIR. -.TP -REMOTE DELETE [ filespec... ] -Asks server to delete files. Synonym: RDEL. -.TP -REMOTE [ command... ] -(Many other commands: "remote ?" for a list). -.TP -MAIL [ options ] filespec -Sends file(s) to be delivered as e-mail (Kermit only). -.TP -FINISH -Asks the server to exit server state (Kermit only). -.TP -BYE -Asks the server to log out and close the connection. -.RE -.SS -Script Programming -.PP -.RS -DEFINE, DECLARE, UNDEFINE, UNDECLARE, ASSIGN, EVALUATE, SEXPRESSION, -ARRAY, SORT, INPUT, OUTPUT, IF, FOR, WHILE, SWITCH, GOTO, ECHO, ASK, -GETC, GETOK, ASSERT, WAIT, SLEEP, FOPEN, FREAD, FWRITE, FCLOSE, STOP, -END, RETURN, LEARN, SHIFT, TRACE, VOID, INCREMENT, DECREMENT, ... For -these and many more you'll need to consult the manual and supplements, -and/or visit the Kermit Script Library, which also includes a brief -tutorial. Hint: HELP LEARN to find out how to get Kermit to write -simple scripts for you. -.RE -.PP -Many of Kermit's commands have synonyms, variants, relatives, and so on. -For example, MSEND is a version of SEND that accepts a list of file -specifications to be sent, rather than just one file specification, and -MPUT is a synonym of MSEND. MOVE means to SEND and then DELETE the source -file if successful. MMOVE is like MOVE, but accepts a list of filespecs, -and so on. These are described in the full documentation. -.PP -Use question mark to feel your way through an unfamiliar command, as in -this example: -.PP -.nf - C-Kermit> remote ? One of the following: - assign directory kermit print rmdir - cd exit login pwd set - copy help logout query space - delete host mkdir rename type - C-Kermit> remote set ? One of the following: - attributes file retry transfer - block-check receive server window - C-Kermit> remote set file ? One of the following: - character-set incomplete record-length - collision names type - C-Kermit> remote set file names ? One of the following: - converted literal - C-Kermit> remote set file names literal - C-Kermit> -.PP -.fi -This is called menu on demand: you get a menu when you want one, but menus -are not forced on you even when know what you're doing. Note that you can -also abbreviate most keywords, and you can complete them with the Tab or -Esc key. Also note that ? works for filenames too, and that you can use it -in the middle of a keyword or filename, not just at the beginning. For -example, "send x?" lists all the files in the current directory whose names -start with 'x'. -.SH INITIALIZATION FILE -In its default configuration, C-Kermit executes commands from a file -called .kermrc in your home directory when it starts, unless it is given the --Y or -y command-line option. Custom configurations might substitute a shared -system-wide initialization file. The SHOW FILE command tells what -initialization file, if any, was used. The standard initialization file -"chains" to an individual customization file, .mykermc, in the home directory, -in which each user can establish her/his own preferences, define macros, and -so on. -.PP -Since execution of the initialization file (at least the standard one) -makes C-Kermit take longer to start, it might be better not to have an -initialization file, especially now that Kermit's default startup -configuration is well attuned to modern computing and networking -- in -other words, you no longer have do anything special to make Kermit -transfers go fast. So instead of having an initialization file that is -executed every time Kermit starts, you might consider making one or more -kerbang scripts (with names other that .kermrc) that do NOT include an -"exit" command, and invoke those when you need the settings, macro -definitions, and/or scripted actions they contain, and invoke C-Kermit -directly when you don't. -.PP -To put it another way... We still distribute the standard initialization -file since it's featured in the manual and backwards compatibility is -important to us. But there's no harm in not using it if you don't need the -stuff that's in it (services directory, dialing directory, network -directory, and associated macro definitions). On the other hand, if there -are settings or macros you want in effect EVERY time you use Kermit, the -initialization file (or the customization file it chains to) is the place -to put them, because that's the only place Kermit looks for them -automatically each time you start it. -.SH MODES OF OPERATION -Kermit is said to be in Local mode if it has made a connection to another -computer, e.g. by dialing it or establishing a Telnet connection to it. The -other computer is remote, so if you start another copy of Kermit on the -remote computer, it is said to be in Remote mode (as long as it has not -made any connections of its own). The local Kermit communicates over the -communications device or network connection, acting as a conduit between -the the remote computer and your keyboard and screen. The remote Kermit is -the file-transfer partner to the local Kermit and communicates only through -its standard input and output. -.PP -At any moment, a Kermit program can be in any of the following states. It's -important to know what they are and how to change from one to the other. -.TP -Command state -In this state, Kermit reads commands from: -.sp -\(bu Your keyboard; or: -.br -\(bu A file, or: -.br -\(bu A macro definition. -.sp -You can exit from Command state back to Unix with the EXIT or QUIT -command (same thing). You can enter Connect state with any of various -commands (CONNECT, DIAL, TELNET, etc). You can enter file transfer -state with commands like SEND, RECEIVE, and GET. You can enter Server -state with the SERVER command. The TAKE command tells Kermit to read -and execute commands from a file. The (perhaps implied) DO command -tells Kermit to read and execute commands from a macro definition. -While in Command state, you can interrupt any command, macro, or -command file by typing Ctrl-C (hold down the Ctrl key and press the C -key); this normally brings you back to the prompt. -.TP -Shell state -You can invoke an inferior shell or external command from the Kermit -command prompt by using the PUSH, RUN (!), EDIT, or BROWSE command. -While the inferior shell or command is active, Kermit is suspended and -does nothing. Return to Kermit Command state by exiting from the -inferior shell or application. -.TP -Connect state -In this state, which can be entered only when in Local mode (i.e. when -Kermit has made a connection to another computer), Kermit is acting as -a terminal to the remote computer. Your keystrokes are sent to the -remote computer and characters that arrive over the communication -connection are displayed on your screen. This state is entered when -you give a CONNECT, DIAL, TELNET, RLOGIN, or IKSD command. You can -return to command state by logging out of the remote computer, or by -typing: -.sp - Ctrl-\ec -.sp -That is: Hold down the Ctrl key and press the backslash key, then let -go of the Ctrl key and press the C key. This is called escaping back. -Certain other escape-level commands are also provided; type Ctrl-\e? -for a list. For example, you can enter Shell state with: -.sp - Ctrl-\e! -.sp -To send a Ctrl-\e to the host while in Connect state, type two of them -in a row. See HELP CONNECT and HELP SET ESCAPE for more info. -.TP -Local file-transfer state -In this state, Kermit is sending packets back and forth with the other -computer in order to transfer a file or accomplish some other -file-related task. And at the same time, it is displaying its progress -on your screen and watching your keyboard for interruptions. In this -state, the following single-keystroke commands are accepted: -.sp -.RS -.TP -X -Interrupt the current file and go on to the next (if any). -.TP -Z -Interrupt the current file and skip all the rest. -.TP -E -Like Z but uses a "stronger" protocol (use if X or Z don't work). -.TP -Ctrl-C -Interrupt file-transfer mode (use if Z or E don't work). -.sp -.RE -Kermit returns to its previous state (Command or Connect) when the -transfer is complete or when interrupted successfully by X, Z, E, or -Ctrl-C (hold down the Ctrl key and press the C key). -.TP -Remote file-transfer state -In this state, Kermit is exchanging file-transfer packets with its -local partner over its standard i/o. It leaves this state -automatically when the transfer is complete. In case you find your -local Kermit in Connect state and the remote one in File-transfer -state (in which it seems to ignore your keystrokes), you can usually -return it to command state by typing three Ctrl-C's in a row. If that -doesn't work, return your local Kermit to Command state (Ctrl-\e C) and -type "e-packet" and then press the Return or Enter key; this forces a -fatal Kermit protocol error. -.TP -Remote Server state -This is like Remote File-transfer state, except it never returns -automatically to Command state. Rather, it awaits further instructions -from the client program; that is, from your Local Kermit program. You -can return the Remote Server to its previous state by issuing a -"finish" command to the client, or if you are in Connect state, by -typing three Ctrl-C's in a row. You can tell the server job to log out -and break the connection by issuing a "bye" command to the client. -.TP -Local Server state -Like Remote-Server state, but in local mode, and therefore with its -file-transfer display showing, and listening for single-key commands, -as in Local File-transfer state. Usually this state is entered -automatically when a remote Kermit program gives a GET command. -.sp -C-Kermit, Kermit 95, and MS-DOS Kermit all can switch automatically from -Connect state to Local File-transfer state when you initiate a file -transfer from the remote computer by starting Kermit and telling it to send -or get a file, in which case, Connect state is automatically resumed after -the file transfer is finished. -.sp -Note that C-Kermit is not a terminal emulator. It is a communications -application that you run in a terminal window (e.g. console or Xterm). The -specific emulation, such as VT100, VT220, Linux Console, or Xterm, is -provided by the terminal window in which you are running C-Kermit. Kermit -95 and MS-DOS Kermit, on the other hand, are true terminal emulators. Why -is C-Kermit not a terminal emulator? CLICK HERE to read about it. -.SH MAKING CONNECTIONS -Here is how to make different kinds of connections using interactive Kermit -commands (as noted above, you can also make connections with command-line -options). Note that you don't have to make connections with Kermit. It can -also be used on the far end of a connection as the remote file transfer and -management partner of your local communications software. -.TP -Making a Telnet Connection -At the C-Kermit command prompt, simply type: -.sp -.nf - telnet foo.bar.com -.fi -.sp -(substituting desired hostname or address). -You can also include a port number: -.sp -.nf - telnet xyzcorp.com 3000 ; -.fi -.sp -If the connection is successful, Kermit automically enters Connect -state. When you logout from the remote host, Kermit automatically -returns to its prompt. More info: HELP TELNET, HELP SET TELNET, HELP -SET TELOPT. Also see the IKSD section below. -.TP -Making an Rlogin connection -This is just like Telnet, except you have to be root to do it because -Rlogin uses a privileged TCP port: -.sp -.nf - rlogin foo.bar.com -.fi -.sp -More info: HELP RLOGIN. -.TP -Making an SSH Connection -Unlike Telnet and Rlogin, SSH connections are not built-in, but -handled by running your external SSH client through a pseudoterminal. -Using C-Kermit to control the SSH client gives you all of Kermit's -features (file transfer, character-set conversion, scripting, etc) -over SSH. -.sp - ssh foo.bar.com -.sp -More info: HELP SSH, HELP SET SSH. -.TP -Dialing with a Modem -If it's an external modem, make sure it is connected to a usable -serial port on your computer with a regular (straight-through) modem -cable, and to the telephone jack with a telephone cable, and that it's -turned on. Then use these commands: -.sp -.nf - set modem type usrobotics ; Or other supported type - set line /dev/ttyS0 ; Specify device name - set speed 57600 ; Or other desired speed - set flow rts/cts ; Most modern modems support this - set dial method tone ; (or pulse) - dial 7654321 ; Dial the desired number -.fi -.sp -Type "set modem type ?" for a list of supported modem types. If you -omit the SET MODEM TYPE command, the default type is -"generic-high-speed", which should work for most modern AT-command-set -modems. If the line is busy, Kermit redials automatically. If the call -does not succeed, use "set dial display on" and try it again to watch -what happens. If the call succeeds, Kermit enters Connect state -automatically and returns to its prompt automatically when you log out -from the remote computer or the connection is otherwise lost. -.sp -You can also dial from a modem that is accessible by Telnet, e.g. to a -reverse terminal server. In this case the command sequence is: -.sp -.nf - set host ts.xxx.com 2000 ; Terminal-server and port - set modem type usrobotics ; Or other supported type - set dial method tone ; (or pulse) - dial 7654321 ; Dial the desired number -.fi -.sp -If the terminal server supports the Telnet Com Port Option, RFC 2217, -you can also give serial-port related commands such as SET SPEED, SET -PARITY, and so on, and Kermit relays them to the terminal server using -the protocol specified in the RFC. -.sp -More info: HELP SET MODEM, HELP SET LINE, HELP SET SPEED, HELP SET -FLOW, HELP DIAL, HELP SET DIAL, HELP SET MODEM, HELP SET -CARRIER-WATCH, SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL. -.TP -Direct Serial Port -Connect the two computers, A and B, with a null modem cable (or two -modem cables interconnected with a null-modem adapter or modem -eliminator). From Computer A: -.sp -.nf - set modem type none ; There is no modem - set line /dev/ttyS0 ; Specify device name - set carrier-watch off ; If DTR CD are not cross-connected - set speed 57600 ; Or other desired speed - set flow rts/cts ; If RTS and CTS are cross-connected - set parity even ; (or "mark" or "space", if necessary) - set stop-bits 2 ; (rarely necessary) - set flow xon/xoff ; If you can't use RTS/CTS - connect ; Enter Connect (terminal) state -.fi -.sp -This assumes Computer B is set up to let you log in. If it isn't, you -can run a copy of Kermit on Computer B and follow approximately the -same directions. More info: As above plus HELP CONNECT. -.PP -With modems or direct serial connections, you might also have to "set -parity even" (or "mark" or "space") if it's a 7-bit connection. -.PP -Of the connection types listed above, only one can be open at a time. -However, any one of these can be open concurrently with an FTP or HTTP -session. Each connection type can be customized to any desired degree, -scripted, logged, you name it. See the manual. -.PP -NOTE: On selected platforms, C-Kermit also can make X.25 connections. See -the manual for details. -.SH TRANSFERRING FILES WITH KERMIT -There is a widespread and persistent belief that Kermit is a slow protocol. -This is because, until recently, it used conservative tuning by default to -make sure file transfers succeeded, rather than failing because they -overloaded the connection. Some extra commands (or command-line options, -like -Q) were needed to make it go fast, but nobody bothered to find out -about them. Also, it takes two to tango: most non-Kermit-Project Kermit -protocol implementations really ARE slow. The best file-transfer partners -for C-Kermit are: another copy of C-Kermit (7.0 or later) and Kermit 95. -These combinations work well and they work fast by default. MS-DOS Kermit -is good too, but you have to tell it to go fast (by giving it the FAST -command). -.PP -Furthermore, all three of these Kermit programs support "autodownload" and -"autoupload", meaning that when they are in Connect state and a Kermit -packet comes in from the remote, they automatically switch into file -transfer mode. -.PP -And plus, C-Kermit and K95 also switch automatically between text and -binary mode for each file, so there is no need to "set file type binary" or -"set file type text", or to worry about files being corrupted because they -were transferred in the wrong mode. -.PP -What all of these words add up to is that now, when you use up-to-date -Kermit software from the Kermit Project, file transfer is not only fast, -it's ridiculously easy. You barely have to give any commands at all. -.TP -Downloading Files -Let's say you have Kermit 95, C-Kermit, or MS-DOS Kermit on your -desktop computer, with a connection to a Unix computer that has -C-Kermit installed as "kermit". To download a file (send it from Unix -to your desktop computer), just type the following command at your -Unix shell prompt: -.sp - kermit -s oofa.txt -.sp -(where oofa.txt is the filename). If you want to send more than one -file, you can put as many filenames as you want on the command line, -and they can be any combination of text and binary: -.sp - kermit -s oofa.txt oofa.zip oofa.html oofa.tar.gz -.sp -and/or you can use wildcards to send groups of files: -.sp - kermit -s oofa.* -.sp -If you want to send a file under an assumed name, use: -.sp - kermit -s friday.txt -a today.txt -.sp -This sends the file friday.txt but tells the receiving Kermit that its -name is today.txt. In all cases, as noted, when the file transfer is -finished, your desktop Kermit returns automatically to Connect state. -No worries about escaping back, re-connecting, text/binary mode -switching. Almost too easy, right? -.TP -Uploading Files -To upload files (send them from your desktop computer to the remote -Unix computer) do the same thing, but use the -g (GET) option instead -of -s: -.sp - kermit -g oofa.txt -.sp -This causes your local Kermit to enter server mode; then the remote -Kermit program requests the named file and the local Kermit sends it -and returns automatically to Connect state when done. -.sp -If you want to upload multiple files, you have have use shell quoting -rules, since these aren't local files: -.sp -.nf - kermit -g "oofa.txt oofa.zip oofa.html oofa.tar.gz" - kermit -g "oofa.*" -.fi -.sp -If you want to upload a file but store it under a different name, use: -.sp - kermit -g friday.txt -a today.txt -.TP -Kermit Transfers the Old-Fashioned Way -If your desktop communications software does not support autoupload or -autodownload, or it does not include Kermit server mode, the procedure -requires more steps. -.sp -To download a file, type: -.sp - kermit -s filename -.sp -on the host as before, but if nothing happens automatically in -response to this command, you have to switch your desktop -communications software into Kermit Receive state. This might be done -by escaping back using keyboard characters or hot keys (Alt-x is -typical) and/or with a command (like RECEIVE) or a menu. When the file -transfer is complete, you have to go back to Connect state, Terminal -emulation, or whatever terminology applies to your desktop -communications software. -.sp -To upload a file, type: -.sp - kermit -r -.sp -on the host (rather than "kermit -g"). This tells C-Kermit to wait -passively for a file to start arriving. Then regain the attention of -your desktop software (Alt-x or whatever) and instruct it to send the -desired file(s) with Kermit protocol. When the transfer is finished, -return to the Connect or Terminal screen. -.TP -If File Transfer Fails -Although every aspect of Kermit's operation can be finely tuned, there -are also three short and simple "omnibus tuning" commands you can use -for troubleshooting: -.RS -.TP -FAST -Use fast file-transfer settings. This has been the default since -C-Kermit 7.0 now that most modern computers and connections -support it. If transfers fail with fast settings, try . . . -.TP -CAUTIOUS -Use cautious but not paranoid settings. File transfers, if they -work, will go at medium speed. If not, try . . . -.TP -ROBUST -Use the most robust, resilient, conservative, safe, and reliable -settings. File transfers will almost certainly work, but they -will be quite slow (of course this is a classic tradeoff; ROBUST -was C-Kermit's default tuning in versions 6.0 and earlier, which -made everybody think Kermit protocol was slow). If ROBUST doesn't -do the trick, try again with SET PARITY SPACE first in case it's -not an 8-bit connection. -.RE -.sp -Obviously the success and performance of a file transfer also depends -on C-Kermit's file transfer partner. Up-to-date, real Kermit Project -partners are recommended because they contain the best Kermit protocol -implementations and because we can support them in case of trouble. -.sp -If you still have trouble, consult Chapter 10 of Using C-Kermit, or -send email to kermit-support@columbia.edu. -.TP -Advanced Kermit File-Transfer Features -Obviously there is a lot more to Kermit file transfer, including all -sorts of interactive commands, preferences, options, logging, -debugging, troubleshooting, and anything else you can imagine but -that's what the manual and updates are for. Here are a few topics you -can explore if you're interested by Typing HELP for the listed -commands: -.RS -.TP -Logging transfers: -LOG TRANSACTIONS (HELP LOG) -.TP -Automatic per-file text/binary mode switching: -SET TRANSFER MODE { AUTOMATIC, MANUAL } (HELP SET TRANSFER). -.TP -Cross-platform recursive directory tree transfer: -SEND /RECURSIVE, GET /RECURSIVE (HELP SEND, HELP GET). -.TP -File collision options: -SET FILE COLLISION { OVERWRITE, BACKUP, DISCARD, ... } (HELP SET FILE). -.TP -Update: Transfer only files that changed since last time: -SET FILE COLLISION UPDATE (HELP SET FILE). -.TP -Filename selection patterns: -(HELP WILDCARD). -.TP -Flexible file selection: -SEND (or GET) /BEFORE /AFTER /LARGER /SMALLER /TYPE /EXCEPT, ... -.TP -Character-set conversion: -SET { FILE, TRANSFER } CHARACTER-SET, ASSOCIATE, ... -.TP -File/Pathname control: -SET { SEND, RECEIVE } PATHNAMES, SET FILE NAMES. -.TP -Atomic file movement: -SEND (or GET) /DELETE /RENAME /MOVE-TO -.TP -Transferring to/from standard i/o of other commands: -SEND (or GET) /COMMAND -.TP -Recovery of interrupted transfer from point of failure: -RESEND, REGET (HELP RESEND, HELP REGET). -.RE -.TP -Non-Kermit File Transfer -You can also use C-Kermit to transfer files with FTP or HTTP Internet -protocols; see below. -.sp -On a regular serial or Telnet connection where the other computer -doesn't support Kermit protocol at all, you have several options. For -example, if your desktop communications software supports Zmodem, use -"rz" and "sz" on the host rather than Kermit. But if Kermit is your -desktop software, and you are using it to make calls or network -connections to other computers that don't support Kermit protocol (or -that don't have a good implementation of it), then if your computer -also has external X, Y, or Zmodem programs that are redirectable, -Kermit can use them as external protocols. HELP SET PROTOCOL for -details. -.sp -You can also capture "raw" data streams from the other computer with -LOG SESSION (HELP LOG and HELP SET SESSION-LOG for details), and you -can upload files without any protocol at all with TRANSMIT (HELP -TRANSMIT, HELP SET TRANSMIT). -.SH KERMIT'S BUILT-IN FTP AND HTTP CLIENTS -Kermit's FTP client is like the regular Unix FTP client that you're used -to, but with some differences: -.TP -\(bu -It has lots more commands and features. -.TP -\(bu -Each FTP command must be prefixed with "ftp", for example "ftp open", -"ftp get", "ftp bye", etc (this is not strictly true, but until you're -more familiar with it, it's best to follow this rule). -.TP -\(bu -Commands like "cd", "directory", etc, execute locally, not on the -server. Use "ftp cd", "ftp dir", etc, to have them act on the server. -.TP -\(bu -You can have an FTP session and a regular Kermit serial or Telnet -session open at the same time. -.TP -\(bu -FTP sessions can be fully automated. -.PP -Pending publication of the next edition of the manual, the Kermit FTP -client is thoroughly documented at the Kermit Project website: -.sp - http://www.columbia.edu/kermit/ftpclient.html -.sp -You also can use HELP FTP and HELP SET FTP to get descriptions of Kermit's -FTP-related commands. -.PP -The HTTP client is similar to the FTP one, except you prefix each command -with HTTP instead of FTP: HTTP OPEN, HTTP GET, HTTP PUT, HTTP CLOSE, etc. -Type HELP HTTP for details, or visit the to view the manual supplements. -HTTP connections can be open at the same time as regular serial or Telnet -connections and FTP connections. So Kermit can manage up to three types -connections simultaneously. -.SH INTERNET KERMIT SERVICE -C-Kermit can be configured and run as an Internet service (called IKSD), -similar to an FTP server (FTPD) except you can (but need not) interact with -it directly, plus it does a lot more than an FTP server can do. The TCP -port for IKSD is 1649. It uses Telnet protocol. C-Kermit can be an Internet -Kermit Server, or it can be a client of an IKSD. You can make connections -from C-Kermit to an IKSD with any of the following commands: -.sp -.nf - telnet foo.bar.edu 1649 - telnet foo.bar.edu kermit ; if "kermit" is listed in /etc/services - iksd foo.bar.edu -.fi -.sp -The IKSD command is equivalent to a TELNET command specifying port 1649. -For more information about making and using connections to an IKSD, see: -.sp - http://www.columbia.edu/kermit/cuiksd.html -.sp -You can run an Internet Kermit Service on your own computer too (if you are -the system administrator). For instructions, see: -.sp - http://www.columbia.edu/kermit/iksd.html -.SH SECURITY -All of C-Kermit's built-in TCP/IP networking methods (Telnet, Rlogin, IKSD, -FTP, and HTTP) can be secured by one or more of the following IETF-approved -methods: -.PP -\(bu MIT Kerberos IV -.br -\(bu MIT Kerberos V -.br -\(bu SSL/TLS -.br -\(bu Stanford SRP -.PP -For complete instructions see: -.PP - http://www.columbia.edu/kermit/security.html -.PP -And as noted previously, you can also make SSH connections with C-Kermit if -you already have an SSH client installed. -.SH ALTERNATIVE COMMAND-LINE PERSONALITIES -When invoked as "kermit" or any other name besides "ftp" or "telnet", -C-Kermit has the command-line options described above in the OPTIONS -section. However, if you invoke C-Kermit as "telnet" or "ftp", it changes -its command-line personality to match. This can be done (among other ways) -with symbolic links (symlinks). For example, if you want C-Kermit to be -your regular Telnet client, or the Telnet helper of your Web browser, you -can create a link like the following in a directory that lies in your PATH -ahead of the regular telnet program: -.sp - ln -s /usr/local/bin/kermit telnet -.sp -Now when you give a "telnet" command, you are invoking Kermit instead, but -with its Telnet command-line personality so, for example: -.sp - telnet xyzcorp.com -.sp -Makes a Telnet connection to xyzcorp.com, and Kermit exits automatically -when the connection is closed (just like the regular Telnet client). Type -"telnet -h" to get a list of Kermit's Telnet-personality command-line -options, which are intended to be as compatible as possible with the -regular Telnet client. -.PP -Similarly for FTP: -.sp - ln -s /usr/local/bin/kermit ftp -.sp -And now type "ftp -h" to see its command-line options, and command lines -just like you would give your regular FTP client: -.sp - ftp xyzcorp.com -.sp -but with additional options allowing an entire session to be specified on -the command line. Finally, if Kermit's -first command-line option is a Telnet, FTP, IKSD, or HTTP URL, Kermit -automatically makes the appropriate kind of connection and, if indicated by -the URL, takes the desired action: -.TP -kermit telnet:xyzcorp.com -Opens a Telnet session -.TP -kermit telnet://olga@xyzcorp.com -Ditto for user olga -.TP -kermit ftp://olga@xyzcorp.com/public/oofa.zip -Downloads a file -.TP -kermit kermit://kermit.columbia.edu/kermit/f/READ.ME -Ditto for IKSD -.TP -kermit iksd://kermit.columbia.edu/kermit/f/READ.ME -(This works too) -.TP -kermit http://www.columbia.edu/kermit/index.html -Grabs a web page -.fi -.SH LICENSE -C-Kermit has an unusual license, but a fair and sensible one since the -Kermit Project must support itself out of revenue: it's not a BSD license, -not GPL, not Artistic, not commercial, not shareware, not freeware. It can -be summed up like this: if you want C-Kermit for your own use, you can -download and use it without cost or license (but we'd appreciate it if you -would purchase the manual). But if you want to sell C-Kermit or bundle it -with a product or otherwise distribute it in a commercial setting EXCEPT -WITH AN OPEN-SOURCE OPERATING SYSTEM DISTRIBUTION such as Linux, FreeBSD, -NetBSD, or OpenBSD, you must license it. To see the complete license, give -the LICENSE command at the prompt, or see the COPYING.TXT file distributed -with C-Kermit 7.0 or later, or download it from -.sp - ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT -.sp -Send licensing inquiries to kermit@columbia.edu. -.SH BUGS -See the following files for listings of known bugs, limitations, -workarounds, hints and tips: -.TP -ckcbwr.txt -General C-Kermit bugs, hints, tips. -.TP -ckubwr.txt -Unix-specific C-Kermit bugs, hints, tips. -.PP -Report bugs and problems by email to: -.sp - kermit-support@columbia.edu. -.sp -Before requesting technical support, please read the hints here: -.sp - http://www.columbia.edu/kermit/support.html -.sp -and also read the C-Kermit Frequently Asked Questions: -.sp - http://www.columbia.edu/kermit/ckfaq.html -.SH OTHER TOPICS -There's way more to C-Kermit than we've touched on here -- troubleshooting, -customization, character sets, dialing directories, sending pages, script -writing, and on and on, all of which are covered in the manual and updates -and supplements. For the most up-to-date information on documentation (or -updated documentation itself) visit the Kermit Project website: -.sp - http://www.columbia.edu/kermit/ -.PP -There you will also find Kermit software packages for other platforms: -different Unix varieties, Windows, DOS, VMS, IBM mainframes, and many -others: 20+ years' worth. -.SH DOCUMENTATION AND UPDATES -The manual for C-Kermit is: -.TP -.I -Using C-Kermit -Frank da Cruz and Christine M. Gianone, -Second Edition, Digital Press / Butterworth-Heinemann, Woburn, MA, 1997, 622 -pages, ISBN 1-55558-164-1. This is a printed book. It covers C-Kermit 6.0. -.TP -The C-Kermit 7.0 Supplement -http://www.columbia.edu/kermit/ckermit2.html -.TP -The C-Kermit 8.0 Supplement -http://www.columbia.edu/kermit/ckermit3.html -.PP -Visit C-Kermit home page: -.sp - http://www.columbia.edu/kermit/ckermit.html -.sp -to learn about new versions, Beta tests, and other news; to -read case studies and tutorials; to download source code, install packages, -and prebuilt binaries for many platforms. Also visit: -.TP -http://www.columbia.edu/kermit/scriptlib.html -The Kermit script library and tutorial -.TP -http://www.columbia.edu/kermit/newfaq.html -The Kermit FAQ (Frequently Asked Questions about Kermit) -.TP -http://www.columbia.edu/kermit/ckfaq.html -The C-Kermit FAQ (Frequently Asked Questions about C-Kermit) -.TP -http://www.columbia.edu/kermit/telnet.html -C-Kermit Telnet client documentation -.TP -http://www.columbia.edu/kermit/security.html -C-Kermit security documentation (Kerberos, SSL/TLS, etc) -.TP -http://www.columbia.edu/kermit/cuiksd.html -Internet Kermit Service user documentation -.TP -http://www.columbia.edu/kermit/iksd.html -Internet Kermit Service administrator documentation -.TP -http://www.columbia.edu/kermit/studies.html -Case studies. -.TP -http://www.columbia.edu/kermit/support.html -Technical support. -.TP -http://www.columbia.edu/kermit/k95tutorial.html -Kermit 95 tutorial. -.TP -comp.protocols.kermit.misc -The Kermit newsgroup (unmoderated). -.SH FILES -.TP -COPYING.TXT -C-Kermit license. -.TP -~/.kermrc -Initialization file. -.TP -~/.mykermrc -Customization file. -.TP -~/.kdd -Kermit dialing directory (see manual). -.TP -~/.knd -Kermit network directory (see manual). -.TP -~/.ksd -Kermit services directory (see manual). -.TP -ca_certs.pem -Certificate Authority certifcates used for SSL connections. -.TP -ckuins.txt -Installation instructions for Unix. Also at -http://www.columbia.edu/kermit/ckuins.html. -.TP -ckcbwr.txt -General C-Kermit bugs, hints, tips. -.TP -ckubwr.txt -Unix-specific C-Kermit bugs, hints, tips. -.TP -ckcplm.txt -C-Kermit program logic manual. -.TP -ckccfg.txt -C-Kermit compile-time configuration options. -.TP -ssh -(in your PATH) SSH connection helper. -.TP -rz, sz, etc. -(in your PATH) external protocols for XYZmodem. -.TP -/var/spool/locks (or whatever) -UUCP lockfile for dialing out (see installation instructions). -.SH AUTHORS -.TP -Software -Frank da Cruz and Jeffrey E Altman, -.br -1985-present, with contributions from hundreds of others all over the -world. -.TP -Documentation -Frank da Cruz and Christine M Gianone -.TP -Address -.nf -The Kermit Project - Columbia Univerity -612 West 115th Street -New York NY 10025-7799 -USA -.fi -.TP -E-Mail -kermit@columbia.edu -.TP -Web -http://www.columbia.edu/kermit/ -.fi -.br diff --git a/.pc/030_fix-if-else.patch/.timestamp b/.pc/030_fix-if-else.patch/.timestamp deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/030_fix-if-else.patch/ckuus6.c b/.pc/030_fix-if-else.patch/ckuus6.c deleted file mode 100644 index 5dcd828..0000000 --- a/.pc/030_fix-if-else.patch/ckuus6.c +++ /dev/null @@ -1,10878 +0,0 @@ -#include "ckcsym.h" -#ifndef NOICP - -/* C K U U S 6 -- "User Interface" for Unix Kermit (Part 6) */ - -/* - 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. -*/ - -/* Includes */ - -#include "ckcdeb.h" -#include "ckcasc.h" -#include "ckcker.h" -#include "ckuusr.h" -#include "ckcxla.h" -#include "ckcnet.h" /* Network symbols */ -#include - -#ifdef VMS -#ifndef TCPSOCKET -#include -#endif /* TCPSOCKET */ -#endif /* VMS */ - -#ifdef datageneral -#define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd) -#endif /* datageneral */ - -#ifdef QNX6 -#define readblock kreadblock -#endif /* QNX6 */ - -/* External Kermit Variables, see ckmain.c for description. */ - -extern xx_strp xxstring; - -extern int local, xitsta, binary, parity, escape, flow, cmd_rows, turn, - turnch, duplex, ckxech, seslog, dfloc, cnflg, tlevel, pflag, msgflg, mdmtyp, - zincnt, quiet, repars, techo, network, nzxopts, what, filepeek, recursive; - -extern int xaskmore, tt_rows, tt_cols, cmd_cols, g_matchdot, diractive, - xcmdsrc, nscanfile, reliable, nolinks; - -#ifdef VMSORUNIX -extern int zgfs_dir, zgfs_link; -#endif /* VMSORUNIX */ - -#ifdef CK_IFRO - extern int remonly; -#endif /* CK_IFRO */ - -#ifdef OS2 -extern int StartedFromDialer ; -extern int vmode; -extern int k95stdout; -#ifndef NT -#define INCL_NOPM -#define INCL_VIO /* Needed for ckocon.h */ -#include -#undef COMMENT -#else -#define APIRET ULONG -#include -#include -#include "ckntap.h" -#endif /* NT */ -#include "ckocon.h" -#endif /* OS2 */ - -extern long vernum, speed; -extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv; -extern char *dialv, *loginv, *for_def[], *whil_def[], *xif_def[], *sw_def[]; -extern char *foz_def[]; -extern char *ckxsys, *ckzsys; -#ifndef OS2 -extern char *DIRCMD; -#ifndef UNIX -extern char *DELCMD; -#endif /* UNIX */ -#endif /* OS2 */ -extern char ttname[], filnam[]; -extern CHAR sstate, feol; -extern char *zinptr; - -#ifdef UNIX -extern char ** mtchs; /* zxpand() file list */ -#endif /* UNIX */ - -#ifndef NOXFER -extern int oopts, omode, oname, opath; /* O-Packet options */ - -extern int stdinf, sndsrc, size, rpsiz, urpsiz, fncnv, fnrpath, displa, - stdouf, isguest, pktlog, nfils, keep, maxrps, fblksiz, frecl, frecfm, - atcapr, atdiso, spsizf, spsiz, spsizr, spmax, wslotr, prefixing, - fncact, fnspath, nprotos, g_proto, g_urpsiz, g_spsizf, - g_spsiz, g_spsizr, g_spmax, g_wslotr, g_prefixing, g_fncact, g_fncnv, - g_fnspath, g_fnrpath, xfrxla, g_xfrxla; - -extern char *cmarg, *cmarg2; - -#ifndef NOMSEND /* Multiple SEND */ -extern char *msfiles[]; -#endif /* NOMSEND */ -extern char fspec[]; /* Most recent filespec */ -extern int fspeclen; - -#ifdef CK_TMPDIR -extern int f_tmpdir; /* Directory changed temporarily */ -extern char savdir[]; /* For saving current directory */ -#endif /* CK_TMPDIR */ - -extern struct keytab protos[]; /* File transfer protocols */ -extern struct ck_p ptab[NPROTOS]; -#endif /* NOXFER */ - -#ifdef DCMDBUF /* Declarations from cmd package */ -extern char *cmdbuf, *atmbuf; /* Command buffers */ -#else -extern char cmdbuf[], atmbuf[]; /* Command buffers */ -#endif /* DCMDBUF */ - -extern int nopush; - -#ifndef NOSPL -int askflag = 0; /* ASK-class command active */ -extern char **a_ptr[]; -extern int a_dim[]; -extern char **m_xarg[]; -extern int n_xarg[]; -extern struct mtab *mactab; -extern int nmac; -extern long ck_alarm; -extern char alrm_date[], alrm_time[]; -extern int x_ifnum; -#endif /* NOSPL */ - -extern int inserver; /* I am IKSD */ -extern int backgrd; /* Kermit executing in background */ -extern char psave[]; /* For saving & restoring prompt */ -extern char *tp; /* Temporary buffer */ - -int readblock = 4096; /* READ buffer size */ -CHAR * readbuf = NULL; /* Pointer to read buffer */ -int readsize = 0; /* Number of chars actually read */ -int getcmd = 0; /* GET-class command was given */ - -extern int zchkod, zchkid; - -struct keytab deltab[] = { /* DELETE Command Options */ - { "/all", DEL_ALL, CM_INV }, - { "/after", DEL_AFT, CM_ARG }, - { "/ask", DEL_ASK, 0 }, - { "/before", DEL_BEF, CM_ARG }, - { "/directories", DEL_DIR, 0 }, - { "/dotfiles", DEL_DOT, 0 }, - { "/except", DEL_EXC, CM_ARG }, - { "/heading", DEL_HDG, 0 }, - { "/l", DEL_LIS, CM_INV|CM_ABR }, - { "/larger-than", DEL_LAR, CM_ARG }, - { "/list", DEL_LIS, 0 }, - { "/log", DEL_LIS, CM_INV }, - { "/noask", DEL_NAS, 0 }, - { "/nodotfiles", DEL_NOD, 0 }, - { "/noheading", DEL_NOH, 0 }, - { "/nol", DEL_NOL, CM_INV|CM_ABR }, - { "/nolist", DEL_NOL, 0 }, - { "/nolog", DEL_NOL, CM_INV }, - { "/nopage", DEL_NOP, 0 }, - { "/not-after", DEL_NAF, CM_ARG }, - { "/not-before", DEL_NBF, CM_ARG }, - { "/not-since", DEL_NAF, CM_INV|CM_ARG }, - { "/page", DEL_PAG, 0 }, - { "/quiet", DEL_QUI, CM_INV }, - { "/recursive", DEL_REC, 0 }, - { "/simulate", DEL_SIM, 0 }, - { "/since", DEL_AFT, CM_ARG|CM_INV }, - { "/smaller-than", DEL_SMA, CM_ARG }, - { "/summary", DEL_SUM, 0 }, - { "/tree", DEL_ALL, 0 }, - { "/type", DEL_TYP, CM_ARG }, - { "/verbose", DEL_VRB, CM_INV } -}; -int ndeltab = sizeof(deltab)/sizeof(struct keytab); - -/* /QUIET-/VERBOSE (/LIST-/NOLIST) (/LOG-/NOLOG) table */ - -struct keytab qvswtab[] = { - { "/l", DEL_LIS, CM_INV|CM_ABR }, - { "/list", DEL_LIS, 0 }, - { "/log", DEL_LIS, CM_INV }, - { "/nol", DEL_NOL, CM_INV|CM_ABR }, - { "/nolist", DEL_NOL, 0 }, - { "/nolog", DEL_NOL, CM_INV }, - { "/quiet", DEL_QUI, CM_INV }, - { "/verbose", DEL_VRB, CM_INV } -}; -int nqvswtab = sizeof(qvswtab)/sizeof(struct keytab); - -struct keytab copytab[] = { - { "/append", 998, 0 }, -#ifndef NOSPL - { "/fromb64", 997, 0 }, -#endif /* NOSPL */ - { "/l", DEL_LIS, CM_INV|CM_ABR }, - { "/list", DEL_LIS, 0 }, - { "/log", DEL_LIS, CM_INV }, - { "/nol", DEL_NOL, CM_INV|CM_ABR }, - { "/nolist", DEL_NOL, 0 }, - { "/nolog", DEL_NOL, CM_INV }, - { "/quiet", DEL_QUI, CM_INV }, - { "/swap-bytes", 999, 0 }, -#ifndef NOSPL - { "/tob64", 996, 0 }, -#endif /* NOSPL */ - { "/verbose", DEL_VRB, CM_INV } -}; -int ncopytab = sizeof(copytab)/sizeof(struct keytab); - -#ifndef NOXFER -static struct keytab gettab[] = { /* GET options */ - { "/as-name", SND_ASN, CM_ARG }, - { "/binary", SND_BIN, 0 }, -#ifdef CALIBRATE - { "/calibrate", SND_CAL, CM_INV }, -#endif /* CALIBRATE */ -#ifdef PIPESEND - { "/command", SND_CMD, CM_PSH }, -#endif /* PIPESEND */ - { "/delete", SND_DEL, 0 }, - { "/except", SND_EXC, CM_ARG }, - { "/filenames", SND_NAM, CM_ARG }, -#ifdef PIPESEND - { "/filter", SND_FLT, CM_ARG|CM_PSH }, -#endif /* PIPESEND */ -#ifdef VMS - { "/image", SND_IMG, 0 }, - { "/labeled", SND_LBL, 0 }, -#else - { "/image", SND_BIN, CM_INV }, -#endif /* VMS */ -#ifdef CK_TMPDIR - { "/move-to", SND_MOV, CM_ARG }, -#endif /* CK_TMPDIR */ - { "/pathnames", SND_PTH, CM_ARG }, - { "/pipes", SND_PIP, CM_ARG|CM_PSH }, - { "/quiet", SND_SHH, 0 }, -#ifdef CK_RESEND - { "/recover", SND_RES, 0 }, -#endif /* CK_RESEND */ - { "/recursive", SND_REC, 0 }, - { "/rename-to", SND_REN, CM_ARG }, -#ifdef COMMENT - { "/smaller-than", SND_SMA, CM_ARG }, -#endif /* COMMENT */ - { "/subdirectories", SND_REC, CM_INV }, - { "/text", SND_TXT, 0 }, - { "/transparent", SND_XPA, 0 } -}; -#define NGETTAB sizeof(gettab)/sizeof(struct keytab) -static int ngettab = NGETTAB; - -static struct keytab rcvtab[] = { /* RECEIVE options */ - { "/as-name", SND_ASN, CM_ARG }, - { "/binary", SND_BIN, 0 }, -#ifdef CALIBRATE - { "/calibrate", SND_CAL, CM_INV }, -#endif /* CALIBRATE */ -#ifdef PIPESEND - { "/command", SND_CMD, CM_PSH }, -#endif /* PIPESEND */ - { "/except", SND_EXC, CM_ARG }, - { "/filenames", SND_NAM, CM_ARG }, -#ifdef PIPESEND - { "/filter", SND_FLT, CM_ARG|CM_PSH }, -#endif /* PIPESEND */ -#ifdef VMS - { "/image", SND_IMG, 0 }, - { "/labeled", SND_LBL, 0 }, -#else - { "/image", SND_BIN, CM_INV }, -#endif /* VMS */ -#ifdef CK_TMPDIR - { "/move-to", SND_MOV, CM_ARG }, -#endif /* CK_TMPDIR */ - { "/pathnames", SND_PTH, CM_ARG }, - { "/pipes", SND_PIP, CM_ARG|CM_PSH }, -#ifdef CK_XYZ - { "/protocol", SND_PRO, CM_ARG }, -#else - { "/protocol", SND_PRO, CM_ARG|CM_INV }, -#endif /* CK_XYZ */ - { "/quiet", SND_SHH, 0 }, - { "/recursive", SND_REC, 0 }, - { "/rename-to", SND_REN, CM_ARG }, - { "/text", SND_TXT, 0 }, - { "/transparent", SND_XPA, 0 } -}; -#define NRCVTAB sizeof(rcvtab)/sizeof(struct keytab) -static int nrcvtab = NRCVTAB; -#endif /* NOXFER */ - -/* WAIT table */ - -#define WAIT_FIL 997 -#define WAIT_MDM 998 - -struct keytab waittab[] = { - { "cd", BM_DCD, CM_INV }, /* (Carrier Detect) */ - { "cts", BM_CTS, CM_INV }, /* (Clear To Send) */ - { "dsr", BM_DSR, CM_INV }, /* (Data Set Ready) */ - { "file", WAIT_FIL, 0 }, /* New category selector keywords */ - { "modem-signals", WAIT_MDM, 0 }, /* ... */ - { "ri", BM_RNG, CM_INV } /* (Ring Indicator) */ -}; -int nwaittab = (sizeof(waittab) / sizeof(struct keytab)); - -/* Modem signal table */ - -struct keytab mstab[] = { - { "cd", BM_DCD, 0 }, /* Carrier Detect */ - { "cts", BM_CTS, 0 }, /* Clear To Send */ - { "dsr", BM_DSR, 0 }, /* Data Set Ready */ - { "ri", BM_RNG, 0 } /* Ring Indicator */ -}; -int nms = (sizeof(mstab) / sizeof(struct keytab)); - -#define WF_MOD 1 -#define WF_DEL 2 -#define WF_CRE 3 - -struct keytab wfswi[] = { /* WAIT FILE switches */ - { "creation", WF_CRE, 0 }, /* Wait for file to be created */ - { "deletion", WF_DEL, 0 }, /* Wait for file to be deleted */ - { "modification", WF_MOD, 0 } /* Wait for file to be modified */ -}; -int nwfswi = (sizeof(wfswi) / sizeof(struct keytab)); - -#ifndef NOSPL -struct keytab asgtab[] = { /* Assignment operators for "." */ - { "::=", 2, 0 }, /* ASSIGN and EVALUATE */ - { ":=", 1, 0 }, /* ASSIGN */ - { "=", 0, 0 } /* DEFINE */ -}; -int nasgtab = (sizeof(asgtab) / sizeof(struct keytab)); - -struct keytab opntab[] = { -#ifndef NOPUSH - { "!read", OPN_PI_R, CM_INV }, - { "!write", OPN_PI_W, CM_INV }, -#endif /* NOPUSH */ - { "append", OPN_FI_A, 0 }, - { "host", OPN_NET, 0 }, -#ifdef OS2 - { "line", OPN_SER, CM_INV }, - { "port", OPN_SER, 0 }, -#else - { "line", OPN_SER, 0 }, - { "port", OPN_SER, CM_INV }, -#endif /* OS2 */ - { "read", OPN_FI_R, 0 }, - { "write", OPN_FI_W, 0 } -}; -int nopn = (sizeof(opntab) / sizeof(struct keytab)); - -/* IF conditions */ - -#define XXIFCO 0 /* IF COUNT */ -#define XXIFER 1 /* IF ERRORLEVEL */ -#define XXIFEX 2 /* IF EXIST */ -#define XXIFFA 3 /* IF FAILURE */ -#define XXIFSU 4 /* IF SUCCESS */ -#define XXIFNO 5 /* IF NOT */ -#define XXIFDE 6 /* IF DEFINED */ -#define XXIFEQ 7 /* IF EQUAL (strings) */ -#define XXIFAE 8 /* IF = (numbers) */ -#define XXIFLT 9 /* IF < (numbers) */ -#define XXIFGT 10 /* IF > (numbers) */ -#define XXIFLL 11 /* IF Lexically Less Than (strings) */ -#define XXIFLG 12 /* IF Lexically Greater Than (strings) */ -#define XXIFEO 13 /* IF EOF (READ file) */ -#define XXIFBG 14 /* IF BACKGROUND */ -#define XXIFNU 15 /* IF NUMERIC */ -#define XXIFFG 16 /* IF FOREGROUND */ -#define XXIFDI 17 /* IF DIRECTORY */ -#define XXIFNE 18 /* IF NEWER */ -#define XXIFRO 19 /* IF REMOTE-ONLY */ -#define XXIFAL 20 /* IF ALARM */ -#define XXIFSD 21 /* IF STARTED-FROM-DIALER */ -#define XXIFTR 22 /* IF TRUE */ -#define XXIFNT 23 /* IF FALSE */ -#define XXIFTM 24 /* IF TERMINAL-MACRO */ -#define XXIFEM 25 /* IF EMULATION */ -#define XXIFOP 26 /* IF OPEN */ -#define XXIFLE 27 /* IF <= */ -#define XXIFGE 28 /* IF >= */ -#define XXIFIP 29 /* IF INPATH */ -#define XXIFTA 30 /* IF TAPI */ -#define XXIFMA 31 /* IF MATCH */ -#define XXIFFL 32 /* IF FLAG */ -#define XXIFAB 33 /* IF ABSOLUTE */ -#define XXIFAV 34 /* IF AVAILABLE */ -#define XXIFAT 35 /* IF ASKTIMEOUT */ -#define XXIFRD 36 /* IF READABLE */ -#define XXIFWR 37 /* IF WRITEABLE */ -#define XXIFAN 38 /* IF ... AND ... */ -#define XXIFOR 39 /* IF ... OR ... */ -#define XXIFLP 40 /* IF left parenthesis */ -#define XXIFRP 41 /* IF right parenthesis */ -#define XXIFNQ 42 /* IF != (== "NOT =") */ -#define XXIFQU 43 /* IF QUIET */ -#define XXIFCK 44 /* IF C-KERMIT */ -#define XXIFK9 45 /* IF K-95 */ -#define XXIFMS 46 /* IF MS-KERMIT */ -#define XXIFWI 47 /* IF WILD */ -#define XXIFLO 48 /* IF LOCAL */ -#define XXIFCM 49 /* IF COMMAND */ -#define XXIFFP 50 /* IF FLOAT */ -#define XXIFIK 51 /* IF IKS */ -#define XXIFKB 52 /* IF KBHIT */ -#define XXIFKG 53 /* IF KERBANG */ -#define XXIFVE 54 /* IF VERSION */ -#define XXIFDC 55 /* IF DECLARED */ -#define XXIFGU 56 /* IF GUI */ - -struct keytab iftab[] = { /* IF commands */ - { "!", XXIFNO, 0 }, - { "!=", XXIFNQ, 0 }, - { "&&", XXIFAN, 0 }, - { "(", XXIFLP, 0 }, - { ")", XXIFRP, 0 }, - { "<", XXIFLT, 0 }, - { "<=", XXIFLE, 0 }, - { "=", XXIFAE, 0 }, - { "==", XXIFAE, CM_INV }, - { ">", XXIFGT, 0 }, - { ">=", XXIFGE, 0 }, - { "absolute", XXIFAB, 0 }, - { "alarm", XXIFAL, 0 }, - { "and", XXIFAN, 0 }, - { "asktimeout", XXIFAT, 0 }, - { "available", XXIFAV, 0 }, - { "background", XXIFBG, 0 }, - { "c-kermit", XXIFCK, 0 }, - { "command", XXIFCM, 0 }, - { "count", XXIFCO, 0 }, - { "dcl", XXIFDC, CM_INV }, - { "declared", XXIFDC, 0 }, - { "defined", XXIFDE, 0 }, -#ifdef CK_TMPDIR - { "directory", XXIFDI, 0 }, -#endif /* CK_TMPDIR */ - { "emulation", XXIFEM, 0 }, -#ifdef COMMENT - { "eof", XXIFEO, 0 }, -#endif /* COMMENT */ - { "equal", XXIFEQ, 0 }, - { "error", XXIFFA, CM_INV }, - { "exist", XXIFEX, 0 }, - { "failure", XXIFFA, 0 }, - { "false", XXIFNT, 0 }, - { "flag", XXIFFL, 0 }, -#ifdef CKFLOAT - { "float", XXIFFP, 0 }, -#endif /* CKFLOAT */ - { "foreground", XXIFFG, 0 }, -#ifdef OS2 - { "gui", XXIFGU, 0 }, -#else - { "gui", XXIFGU, CM_INV }, -#endif /* OS2 */ -#ifdef IKSD - { "iksd", XXIFIK, 0 }, -#else - { "iksd", XXIFIK, CM_INV }, -#endif /* IKSD */ - { "integer", XXIFNU, CM_INV }, - { "k-95", XXIFK9, 0 }, - { "kbhit", XXIFKB, 0 }, -#ifdef UNIX - { "kerbang", XXIFKG, 0 }, -#else - { "kerbang", XXIFKG, CM_INV }, -#endif /* UNIX */ - { "lgt", XXIFLG, 0 }, - { "llt", XXIFLL, 0 }, - { "local", XXIFLO, 0 }, - { "match", XXIFMA, 0 }, - { "ms-kermit", XXIFMS, CM_INV }, -#ifdef ZFCDAT - { "newer", XXIFNE, 0 }, -#endif /* ZFCDAT */ - { "not", XXIFNO, 0 }, - { "numeric", XXIFNU, 0 }, - { "ok", XXIFSU, CM_INV }, - { "open", XXIFOP, 0 }, - { "or", XXIFOR, 0 }, - { "quiet", XXIFQU, 0 }, - { "readable", XXIFRD, 0 }, - { "remote-only",XXIFRO, 0 }, - { "started-from-dialer",XXIFSD, CM_INV }, - { "success", XXIFSU, 0 }, - { "tapi", XXIFTA, 0 }, -#ifdef OS2 - { "terminal-macro", XXIFTM, 0 }, -#else - { "terminal-macro", XXIFTM, CM_INV }, -#endif /* OS2 */ - { "true", XXIFTR, 0 }, - { "version", XXIFVE, 0 }, - { "wild", XXIFWI, 0 }, - { "writeable", XXIFWR, 0 }, - { "||", XXIFOR, 0 }, - { "", 0, 0 } -}; -int nif = (sizeof(iftab) / sizeof(struct keytab)) - 1; - -struct keytab iotab[] = { /* Keywords for IF OPEN */ - { "!read-file", ZRFILE, CM_INV }, - { "!write-file", ZWFILE, CM_INV }, - { "append-file", ZWFILE, CM_INV }, - { "connection", 8888, 0 }, -#ifdef CKLOGDIAL - { "cx-log", 7777, 0 }, -#endif /* CKLOGDIAL */ - { "debug-log", ZDFILE, 0 }, - { "error", 9999, 0 }, - { "packet-log", ZPFILE, 0 }, - { "read-file", ZRFILE, 0 }, - { "screen", ZSTDIO, 0 }, - { "session-log", ZSFILE, 0 }, - { "transaction-log", ZTFILE, 0 }, - { "write-file", ZWFILE, 0 } -}; -int niot = (sizeof(iotab) / sizeof(struct keytab)); -#endif /* NOSPL */ - -/* Variables and prototypes */ - -#ifdef NETCONN -extern int nnetdir; /* How many network directories */ -#endif /* NETCONN */ -#ifdef CK_SECURITY -_PROTOTYP(int ck_krb4_is_installed,(void)); -_PROTOTYP(int ck_krb5_is_installed,(void)); -_PROTOTYP(int ck_ntlm_is_installed,(void)); -_PROTOTYP(int ck_srp_is_installed,(void)); -_PROTOTYP(int ck_ssleay_is_installed,(void)); -_PROTOTYP(int ck_ssh_is_installed,(void)); -_PROTOTYP(int ck_crypt_is_installed,(void)); -#else -#define ck_krb4_is_installed() (0) -#define ck_krb5_is_installed() (0) -#define ck_ntlm_is_installed() (0) -#define ck_srp_is_installed() (0) -#define ck_ssleay_is_installed() (0) -#define ck_ssh_is_installed() (0) -#define ck_crypt_is_installed() (0) -#endif /* CK_SECURITY */ - -#define AV_KRB4 1 -#define AV_KRB5 2 -#define AV_NTLM 3 -#define AV_SRP 4 -#define AV_SSL 5 -#define AV_CRYPTO 6 -#define AV_SSH 7 - -struct keytab availtab[] = { /* Available authentication types */ - { "crypto", AV_CRYPTO, CM_INV }, /* and encryption */ - { "encryption", AV_CRYPTO, 0 }, - { "k4", AV_KRB4, CM_INV }, - { "k5", AV_KRB5, CM_INV }, - { "kerberos4", AV_KRB4, 0 }, - { "kerberos5", AV_KRB5, 0 }, - { "krb4", AV_KRB4, CM_INV }, - { "krb5", AV_KRB5, CM_INV }, - { "ntlm", AV_NTLM, 0 }, - { "srp", AV_SRP, 0 }, - { "ssh", AV_SSH, 0 }, - { "ssl", AV_SSL, 0 }, - { "tls", AV_SSL, 0 }, - { "", 0, 0 } -}; -int availtabn = sizeof(availtab)/sizeof(struct keytab)-1; - -#ifndef NODIAL -_PROTOTYP(static int ddcvt, (char *, FILE *, int) ); -_PROTOTYP(static int dncvt, (int, int, int, int) ); -_PROTOTYP(char * getdname, (void) ); - -static int partial = 0; /* For partial dial */ -static char *dscopy = NULL; -int dialtype = -1; - -char *dialnum = (char *)0; /* Remember DIAL number for REDIAL */ -int dirline = 0; /* Dial directory line number */ -extern char * dialdir[]; /* Dial directory file names */ -extern int dialdpy; /* DIAL DISPLAY on/off */ -extern int ndialdir; /* How many dial directories */ -extern int ntollfree; /* Toll-free call info */ -extern int ndialpxx; /* List of PBX exchanges */ -extern char *dialtfc[]; -char * matchpxx = NULL; /* PBX exchange that matched */ -extern int nlocalac; /* Local area-code list */ -extern char * diallcac[]; -extern int tttapi; -#ifdef CK_TAPI -extern int tapiconv; /* TAPI Conversions */ -extern int tapipass; /* TAPI Passthrough */ -#endif /* CK_TAPI */ -extern int dialatmo; -extern char * dialnpr, * dialsfx; -extern char * dialixp, * dialixs, * dialmac; -extern char * dialldp, * diallds, * dialtfp; -extern char * dialpxi, * dialpxo, * diallac; -extern char * diallcp, * diallcs, * diallcc; -extern char * dialpxx[]; - -extern int dialcnf; /* DIAL CONFIRMATION */ -int dialfld = 0; /* DIAL FORCE-LONG-DISTANCE */ -int dialsrt = 1; /* DIAL SORT ON */ -int dialrstr = 6; /* DIAL RESTRICTION */ -int dialtest = 0; /* DIAL TEST */ -int dialcount = 0; /* \v(dialcount) */ - -extern int dialsta; /* Dial status */ -int dialrtr = -1, /* Dial retries */ - dialint = 10; /* Dial retry interval */ -extern long dialcapas; /* Modem capabilities */ -extern int dialcvt; /* DIAL CONVERT-DIRECTORY */ -#endif /* NODIAL */ - -#ifndef NOSPL -#define IFCONDLEN 256 -int ifc, /* IF case */ - not = 0, /* Flag for IF NOT */ - ifargs = 0; /* Count of IF condition words */ -char ifcond[IFCONDLEN]; /* IF condition text */ -char *ifcp; /* Pointer to IF condition text */ -#ifdef DCMDBUF -extern int - *ifcmd, *count, *iftest, *intime, - *inpcas, *takerr, *merror, *xquiet; -#else -extern int ifcmd[]; /* Last command was IF */ -extern int iftest[]; /* Last IF was true */ -extern int count[]; /* For IF COUNT, one for each cmdlvl */ -extern int intime[]; /* Ditto for other stackables... */ -extern int inpcas[]; -extern int takerr[]; -extern int merror[]; -extern int xquiet[]; -#endif /* DCMDBUF */ -#else -extern int takerr[]; -#endif /* NOSPL */ - -#ifdef DCMDBUF -extern char *line; /* Character buffer for anything */ -extern char *tmpbuf; -#else -extern char line[], tmpbuf[]; -#endif /* DCMDBUF */ -extern char *lp; /* Pointer to line buffer */ - -int cwdf = 0; /* CWD has been done */ - -/* Flags for ENABLE/DISABLE */ -extern int en_cwd, en_cpy, en_del, en_dir, en_fin, - en_get, en_hos, en_ren, en_sen, en_set, en_spa, en_typ, en_who, en_bye, - en_asg, en_que, en_ret, en_mai, en_pri, en_mkd, en_rmd, en_xit, en_ena; - -extern FILE *tfile[]; /* File pointers for TAKE command */ -extern char *tfnam[]; /* Names of TAKE files */ -extern int tfline[]; /* TAKE-file line number */ - -extern int success; /* Command success/failure flag */ -extern int cmdlvl; /* Current position in command stack */ - -#ifndef NOSPL -extern int maclvl; /* Macro to execute */ -extern char *macx[]; /* Index of current macro */ -extern char *mrval[]; /* Macro return value */ -extern char *macp[]; /* Pointer to macro */ -extern int macargc[]; /* ARGC from macro invocation */ - -#ifdef COMMENT -extern char *m_line[]; -#endif /* COMMENT */ - -extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */ -extern char *g_var[]; /* Global variables %a, %b, etc */ - -#ifdef DCMDBUF -extern struct cmdptr *cmdstk; /* The command stack itself */ -#else -extern struct cmdptr cmdstk[]; /* The command stack itself */ -#endif /* DCMDBUF */ -#endif /* NOSPL */ - -#define xsystem(s) zsyscmd(s) - -static int x, y, z = 0; -static char *s, *p; - -#ifdef OS2 -_PROTOTYP( int os2settitle, (char *, int) ); -#endif /* OS2 */ - -extern struct keytab yesno[], onoff[], fntab[]; -extern int nyesno, nfntab; - -#ifndef NOSPL - -/* Do the ASK, ASKQ, GETOK, and READ commands */ - -int asktimedout = 0; - -#define ASK_PUP 1 -#define ASK_TMO 2 -#define ASK_GUI 3 -#define ASK_QUI 4 -#define ASK_DEF 5 - -static struct keytab asktab[] = { - { "/default", ASK_DEF, CM_ARG }, - { "/gui", ASK_GUI, -#ifdef KUI - 0 -#else /* KUI */ - CM_INV -#endif /* KUI */ - }, - { "/popup", ASK_PUP, -#ifdef OS2 - 0 -#else /* OS2 */ - CM_INV -#endif /* OS2 */ - }, - { "/quiet", ASK_QUI, 0 }, - { "/timeout", ASK_TMO, CM_ARG }, - { "", 0, 0 } -}; -static int nasktab = sizeof(asktab)/sizeof(struct keytab)-1; - -int -doask(cx) int cx; { - extern int cmflgs, asktimer, timelimit; -#ifdef CK_RECALL - extern int on_recall; -#endif /* CK_RECALL */ - int popupflg = 0; - int guiflg = 0; - int nomsg = 0; - int mytimer = 0; -#ifdef CK_APC - extern int apcactive, apcstatus; -#endif /* CK_APC */ - - char dfbuf[1024]; /* Buffer for default answer */ - char * dfanswer = NULL; /* Pointer to it */ - - char vnambuf[VNAML+1]; /* Buffer for variable names */ - char *vnp = NULL; /* Pointer to same */ - - dfbuf[0] = NUL; - vnambuf[0] = NUL; - -#ifdef CK_APC - if ( apcactive != APC_INACTIVE && (apcstatus & APC_NOINP) ) { - return(success = 0); - } -#endif /* CK_APC */ - - mytimer = asktimer; /* Inherit global ASK timer */ - - if (cx == XXASK || cx == XXASKQ) { - struct FDB sw, fl; - int getval; - char c; - if (cx == XXASKQ) /* Don't log ASKQ response */ - debok = 0; - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Variable name or switch", - "", /* default */ - "", /* addtl string data */ - nasktab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - asktab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Anything that doesn't match */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - NULL, - NULL, - NULL - ); - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (cmresult.nresult) { - case ASK_QUI: - nomsg = 1; - break; - case ASK_PUP: - popupflg = 1; - break; - case ASK_GUI: - guiflg = 1; - break; - case ASK_TMO: { - if ((y = cmnum("seconds","1",10,&x,xxstring)) < 0) - return(y); - if (x < 0) - x = 0; - mytimer = x; - break; - } - case ASK_DEF: { - if ((y = cmfld("Text to supply if reply is empty", - "",&s,xxstring)) < 0) - return(y); - ckstrncpy(dfbuf,s,1024); - dfanswer = dfbuf; - break; - } - default: return(-2); - } - } - /* Have variable name, make copy. */ - ckstrncpy(vnambuf,cmresult.sresult,VNAML); - vnp = vnambuf; - if (vnambuf[0] == CMDQ && - (vnambuf[1] == '%' || vnambuf[1] == '&')) - vnp++; - y = 0; - if (*vnp == '%' || *vnp == '&') { - if ((y = parsevar(vnp,&x,&z)) < 0) - return(y); - } - } else if (cx != XXGOK && cx != XXRDBL) { /* Get variable name */ - if ((y = cmfld("Variable name","",&s,NULL)) < 0) { - if (y == -3) { - printf("?Variable name required\n"); - return(-9); - } else return(y); - } - ckstrncpy(vnambuf,s,VNAML); /* Make a copy. */ - vnp = vnambuf; - if (vnambuf[0] == CMDQ && - (vnambuf[1] == '%' || vnambuf[1] == '&')) - vnp++; - y = 0; - if (*vnp == '%' || *vnp == '&') { - if ((y = parsevar(vnp,&x,&z)) < 0) - return(y); - } - } - if (cx == XXREA || cx == XXRDBL) { /* READ or READBLOCK command */ - if ((y = cmcfm()) < 0) /* Get confirmation */ - return(y); - if (chkfn(ZRFILE) < 1) { /* File open? */ - printf("?Read file not open\n"); - return(success = 0); - } - if (!(s = (char *)readbuf)) { /* Where to read into. */ - printf("?Oops, no READ buffer!\n"); - return(success = 0); - } - y = zsinl(ZRFILE, s, readblock); /* Read a line. */ - debug(F111,"read zsinl",s,y); - if (y < 0) { /* On EOF or other error, */ - zclose(ZRFILE); /* close the file, */ - delmac(vnp,0); /* delete the variable, */ - return(success = 0); /* and return failure. */ - } else { /* Read was OK. */ - readsize = (int) strlen(s); - success = (addmac(vnp,s) < 0 ? 0 : 1); /* Define variable */ - debug(F111,"read addmac",vnp,success); - return(success); /* Return success. */ - } - } - - /* ASK, ASKQ, GETOK, or GETC */ - - if (cx == XXGOK) { /* GETOK can take switches */ - struct FDB sw, fl; - int getval; - char c; - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Variable name or question prompt", - "", /* default */ - "", /* addtl string data */ - nasktab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - asktab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Anything that doesn't match */ - _CMTXT, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - NULL, - NULL, - NULL - ); - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (cmresult.nresult) { - case ASK_PUP: - popupflg = 1; - break; - case ASK_GUI: - guiflg = 1; - break; - case ASK_TMO: { - if ((y = cmnum("seconds","1",10,&x,xxstring)) < 0) - return(y); - if (x < 0) - x = 0; - mytimer = x; - break; - } - case ASK_DEF: { - if ((y = cmfld("Text to supply if reply is empty", - "",&s,xxstring)) < 0) - return(y); - ckstrncpy(dfbuf,s,1024); - dfanswer = dfbuf; - break; - } - case ASK_QUI: - nomsg = 1; - break; - default: return(-2); - } - } - p = cmresult.sresult; - } else - if ((y = cmtxt( -"Prompt,\n\ - enclose in { braces } or \" quotes \" to preserve leading and trailing\n\ - spaces, precede question mark with backslash (\\).", - "",&p,xxstring)) < 0) - return(y); - - if (!p) p = ""; -#ifndef NOLOCAL -#ifdef OS2 - if (popupflg) { /* Popup requested */ - int len = -1; - ckstrncpy(tmpbuf,brstrip(p),TMPBUFSIZ); - p = tmpbuf; - if (cx == XXASK || cx == XXASKQ) { - if (cx == XXASK) - len = popup_readtext(vmode,NULL,p,line,LINBUFSIZ,mytimer); - else - len = popup_readpass(vmode,NULL,p,line,LINBUFSIZ,mytimer); - asktimedout = ( len < 0 && mytimer ); - } else if (cx == XXGOK) { - printf("?Sorry, GETOK /POPUP not implemented yet\n"); - timelimit = 0; - return(-9); - } - if (len >= 0) { - y = addmac(vnp,(char *)line); /* Add it to the macro table. */ - } else if ( asktimedout && dfanswer ) { - y = addmac(vnp,dfanswer); /* Add it to the macro table. */ - asktimedout = 0; - len = 0; - } - timelimit = 0; - return(success = ((len >= 0) && (y >= 0)) && !asktimedout); - } -#ifdef KUI - if (guiflg) { /* GUI requested */ - int rc, n; - char * s1; - s1 = tmpbuf; - n = TMPBUFSIZ-1; - zzstring(brstrip(p),&s1,&n); - p = tmpbuf; - if (cx == XXASK || cx == XXASKQ) { - rc = gui_txt_dialog(NULL,p,(cx == XXASK), - line,LINBUFSIZ,dfanswer,mytimer); - asktimedout = (rc == -1 && mytimer); - if (rc == 1) { - y = addmac(vnp,(char *)line); /* Add it to the macro table. */ - } else if ( asktimedout && dfanswer ) { - y = addmac(vnp,dfanswer); /* Add default to macro table. */ - asktimedout = 0; - rc = 1; - } - timelimit = 0; - return(success = (rc == 1 && (y >= 0)) && !asktimedout); - } else if (cx == XXGOK) { - int x; - x = lookup(yesno,dfanswer,nyesno,NULL); - if (x != 1) x = 2; - rc = uq_ok(NULL, p, 3, NULL, x); - return(success = (rc == 1)); - } - } -#endif /* KUI */ -#endif /* OS2 */ -#endif /* NOLOCAL */ - - concb((char)escape); /* Enter CBREAK mode */ - cmsavp(psave,PROMPTL); /* Save old prompt */ - cmsetp(brstrip(p)); /* Make new prompt */ -reprompt: - if (cx == XXASKQ) { /* For ASKQ, */ - cmini(0); /* no-echo mode. */ - } else { /* For others, regular echoing. */ - cmini(ckxech); - } - askflag = 1; - x = -1; /* This means to reparse. */ - cmflgs = 0; - if (pflag) - prompt(xxstring); /* Issue prompt. */ - - asktimedout = 0; /* Handle timed responses. */ - timelimit = mytimer; -reparse: - cmres(); - if (cx == XXGOK) { /* GETOK */ -#ifdef CK_RECALL - on_recall = 0; -#endif /* CK_RECALL */ - askflag = 0; - /* GETOK uses keyword table */ - x = cmkey(yesno,nyesno,"",dfanswer,xxstring); - if (x < 0) { /* Parse error */ - if (x == -10) { - char * ds; - ds = dfanswer ? dfanswer : "No"; - if (!nomsg) - printf("?Timed out, assuming \"%s\"",ds); - printf("\n"); - asktimedout = 1; - x = lookup(yesno,ds,nyesno,NULL); - if (x != 1) x = 0; - goto gokdone; - } else if (x == -3) { /* No answer? */ - printf("Please respond Yes or No\n"); /* Make them answer */ - cmini(ckxech); - goto reprompt; - } else if (x == -1) { - goto reparse; - } else - goto reprompt; - } - if (cmcfm() < 0) /* Get confirmation */ - goto reparse; - gokdone: - askflag = 0; - cmsetp(psave); /* Restore prompt */ -#ifdef VMS - if (cmdlvl > 0) /* In VMS and not at top level, */ - conres(); /* restore console again. */ -#endif /* VMS */ - timelimit = 0; - return(x); /* Return success or failure */ - } else if (cx == XXGETC /* GETC */ -#ifdef OS2 - || cx == XXGETK /* or GETKEYCODE */ -#endif /* OS2 */ - ) { /* GETC */ - char tmp[16]; - conbin((char)escape); /* Put keyboard in raw mode */ -#ifndef NOSETKEY -#ifdef OS2 - if (cx == XXGETK) { /* GETKEYCODE */ - extern int os2gks; - int t; - t = os2gks; /* Turn off kverb recognition */ - os2gks = 0; - x = congks(timelimit); /* Read a key event, blocking */ - os2gks = t; /* Put back kverb recognition */ - } else /* GETC */ -#endif /* OS2 */ -#endif /* NOSETKEY */ - { - debug(F101,"GETC conchk","",conchk()); - x = coninc(timelimit); /* Just read one character */ - debug(F101,"GETC coninc","",x); - } - concb((char)escape); /* Put keyboard back in cbreak mode */ - if (x > -1) { - if (xcmdsrc == 0) - printf("\r\n"); -#ifdef OS2 - if (cx == XXGETK) { /* GETKEYCODE */ - sprintf(tmp,"%d",x); /* SAFE */ - } else { -#endif /* OS2 */ - tmp[0] = (char) (x & 0xff); - tmp[1] = NUL; -#ifdef OS2 - } -#endif /* OS2 */ - y = addmac(vnp,tmp); /* Add it to the macro table. */ - debug(F111,"getc/getk addmac",vnp,y); - } else y = -1; - cmsetp(psave); /* Restore old prompt. */ - if (x < -1) { - asktimedout = 1; - if (!quiet && !nomsg) - printf("?Timed out"); - printf("\n"); - } - timelimit = 0; - return(success = ((y < 0 ? 0 : 1) && (asktimedout == 0))); - } else { /* ASK or ASKQ */ -#ifdef CK_RECALL - on_recall = 0; -#endif /* CK_RECALL */ - y = cmdgquo(); /* Get current quoting */ - cmdsquo(0); /* Turn off quoting */ - while (x == -1) { /* Prompt till they answer */ - x = cmtxt("Please respond.",dfanswer,&s,NULL); - debug(F111,"ASK cmtxt",s,x); - cmres(); - } - cmdsquo(y); /* Restore previous quoting */ - if (cx == XXASKQ) /* ASKQ must echo CRLF here */ - printf("\r\n"); - if (x == -10 && dfanswer) { /* Don't fail on timeout if */ - s = dfanswer; /* a default was specified */ - asktimedout = 0; /* and don't fail */ - x = 0; - } - if (x < 0) { /* If cmtxt parse error, */ - cmsetp(psave); /* restore original prompt */ -#ifdef VMS - if (cmdlvl > 0) /* In VMS and not at top level, */ - conres(); /* restore console again. */ -#endif /* VMS */ - if (x == -10) { /* Timed out with no response */ - if (!nomsg) - printf("?Timed out"); - printf("\n"); - asktimedout = 1; - if (dfanswer) /* Supply default answer if any */ - s = dfanswer; - success = x = 0; /* (was "x = -9;") */ - } - timelimit = 0; - return(x); /* and return cmtxt's error code. */ - } - if (!s || *s == NUL) { /* If user typed a bare CR, */ - cmsetp(psave); /* Restore old prompt, */ - delmac(vnp,0); /* delete variable if it exists, */ -#ifdef VMS - if (cmdlvl > 0) /* In VMS and not at top level, */ - conres(); /* restore console again. */ -#endif /* VMS */ - timelimit = 0; - return(success = 1); /* and return. */ - } - y = addmac(vnp,s); /* Add it to the macro table. */ - debug(F111,"ask addmac",vnp,y); - cmsetp(psave); /* Restore old prompt. */ -#ifdef VMS - if (cmdlvl > 0) /* In VMS and not at top level, */ - conres(); /* restore console again. */ -#endif /* VMS */ - timelimit = 0; - return(success = (y < 0 ? 0 : 1) && (asktimedout == 0)); - } -} -#endif /* NOSPL */ - -#ifndef NOSPL -int -doincr(cx) int cx; { /* INCREMENT, DECREMENT */ - char vnambuf[VNAML+1]; /* Buffer for variable names */ - int eval = 0; - eval = (cx == XX_DECR || cx == XX_INCR); - - if ((y = cmfld("Variable name","",&s, eval ? xxstring : NULL)) < 0) { - if (y == -3) { - printf("?Variable name required\n"); - return(-9); - } else return(y); - } - ckstrncpy(vnambuf,s,VNAML); - if ((y = cmnum("by amount","1",10,&x,xxstring)) < 0) - return(y); - if ((y = cmcfm()) < 0) - return(y); - - z = (cx == XX_INCR || cx == XXINC) ? 1 : 0; /* Increment or decrement? */ - - if (incvar(vnambuf,x,z) < 0) { - printf("?Variable %s not defined or not numeric\n",vnambuf); - return(success = 0); - } - return(success = 1); -} - -/* Used by doundef() */ -static int -xxundef(s,verbose,simulate) char * s; int verbose, simulate; { - int rc = 0; - if (!s) return(0); - if (*s == CMDQ && *(s+1) == '%') { - char c = *(s+2), * p = NULL; - if (c >= '0' && c <= '9') { - if (maclvl < 0) - p = g_var[c]; - else - p = m_arg[maclvl][c - '0']; - } else { - if (isupper(c)) c += ('a'-'A'); - if (c >= 'a' && c <= 'z') - p = g_var[c]; - } - if (!p) return(-1); - } - if (verbose) - printf(" %s ",s); - if (simulate) { - printf("(SELECTED)\n"); - } else if ((x = delmac(s,1)) > -1) { /* Full name required */ - rc = 1; - if (verbose) printf("(OK)\n"); - } else if (verbose) - printf("(FAILED)\n"); - return(rc); -} - -/* Do the (_)DEFINE, (_)ASSIGN, and UNDEFINE commands */ - -#define UND_MAT 1 -#define UND_VRB 2 -#define UND_EXC 3 -#define UND_SIM 3 - -static struct keytab undefswi[] = { - { "/list", UND_VRB, 0 }, -#ifdef COMMENT - { "/except", UND_EXC, CM_ARG }, -#endif /* COMMENT */ - { "/matching", UND_MAT, 0 }, - { "/simulate", UND_SIM, 0 }, - { "/verbose", UND_VRB, CM_INV } -}; -static int nundefswi = sizeof(undefswi) / sizeof(struct keytab); - -#define UNDEFMAX 64 -static char ** undeflist = NULL; -int -doundef(cx) int cx; { /* UNDEF, _UNDEF */ - int i, j, n, rc = 0, arraymsg = 0; - int domatch = 0, verbose = 0, errors = 0, simulate = 0, flag = 0; - char *vnp, vnbuf[4]; -#ifdef COMMENT - char *except = NULL; -#endif /* COMMENT */ - struct FDB sw, fl; - int getval; - char c; - - if (!undeflist) { /* Allocate list if necessary */ - undeflist = (char **)malloc(UNDEFMAX * sizeof(char *)); - if (!undeflist) { - printf("?Memory allocation failure\n"); - return(-9); - } - for (i = 0; i < UNDEFMAX; i++) - undeflist[i] = NULL; - } - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Variable name or switch", - "", /* default */ - "", /* addtl string data */ - nundefswi, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - undefswi, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Anything that doesn't match */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - (cx == XXUNDEF) ? NULL : xxstring, - NULL, - NULL - ); - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - switch (cmresult.nresult) { - case UND_MAT: domatch = 1; break; - case UND_SIM: simulate = 1; /* fall thru on purpose */ - case UND_VRB: verbose = 1; break; - -#ifdef COMMENT - case UND_EXC: - if (!getval) break; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Pattern required\n"); - x = -9; - } - goto xgetx; - } - makestr(&except,cmresult.sresult); - break; -#endif /* COMMENT */ - - default: - return(-2); - } - } - n = 0; - makestr(&(undeflist[n++]),cmresult.sresult); - for (i = 1; i < UNDEFMAX; i++) { - x = cmfld("Macro or variable name","",&s, - ((cx == XXUNDEF) ? NULL : xxstring) - ); - if (x == -3) { - if ((y = cmcfm()) < 0) - return(y); - break; - } else if (y < 0) { - return(y); - } - makestr(&(undeflist[n++]),s); - } - /* Now we have a list of n variables or patterns to undefine */ - - for (i = 0; i < n; i++) { - flag = 0; - if (!(vnp = undeflist[i])) - continue; - if (vnp[0] == CMDQ && (vnp[1] == '%' || vnp[1] == '&')) { - flag++; - vnp++; - } - if (!domatch) { /* Pattern match not requested */ - if (flag) { - if ((y = parsevar(vnp,&x,&z)) < 0) { - vnp--; - if (verbose) printf(" %s...error\n",vnp); - continue; - } - vnp--; - } - x = xxundef(vnp,verbose,simulate); - if (x > -1) { - if (!x && !simulate) errors++; - rc += x; - } - continue; - } - /* Pattern match requested */ - - if (!flag) { /* It's a macro */ - for (j = 0; j < nmac; j++) { - if (ckmatch(vnp,mactab[j].kwd,0,1)) { - x = xxundef(mactab[j].kwd,verbose,simulate); - if (x > -1) { - rc += x; - if (!x) errors++; - } - if (!simulate) - j--; /* Because mactab shifted up */ - } - } - } else if (vnp[0] == '%') { /* It's a \%x variable */ - vnbuf[0] = CMDQ; - vnbuf[1] = '%'; - vnbuf[3] = NUL; - for (j = '0'; j <= 'z'; j++) { /* 0..9 a..z */ - vnbuf[2] = j; - if (ckmatch(vnp,&vnbuf[1],0,1)) { - x = xxundef(vnbuf,verbose,simulate); - if (x > -1) { - if (!x) errors++; - rc += x; - } - } - if (j == '9') j = (int)'a' - 1; /* 9 -> a */ - } - } else if (vnp[0] == '&') { - if (!arraymsg && !quiet) { - printf("?UNDEFINE /MATCH can't be used with arrays.\n"); - printf("(Type HELP ARRAY to see other methods.)\n"); - } - arraymsg++; - errors++; - } - } - if (verbose) - printf("undefined: %d, errors: %d\n",rc,errors); - - for (i = 0; i < UNDEFMAX; i++) { /* Check them all */ - if (undeflist[i]) { /* in case we were interrupted */ - free(undeflist[i]); /* previously... */ - undeflist[i] = NULL; - } - } - return(success = (errors == 0) ? 1 : 0); -} - -int -dodef(cx) int cx; { - extern int xxdot; - extern char ppvnambuf[]; - int doeval = 0; - char vnambuf[VNAML+1]; /* Buffer for variable names */ - char *vnp; /* Pointer to same */ - int k, mydot; - mydot = xxdot; /* Copy */ - xxdot = 0; /* and reset */ -/* - In case we got here from a command that begins like ".\%a", cmkey() has - already evaluated \%a, but we don't want that, so we retrieve the variable - name from a special pre-evaluation buffer in the command module, and we - undo the "unget word" that would be done because of the token, because if - the variable was defined, it will unget its value rather than its name. -*/ - s = NULL; - - if (mydot && ppvnambuf[0] == '.' && ppvnambuf[1]) { - s = ppvnambuf+1; - unungw(); - } - if (!s) { - if (cx == XXDFX || cx == XXASX) - /* Evaluate variable name */ - y = cmfld("Macro or variable name","",&s,xxstring); - else - /* Don't evaluate the variable name */ - y = cmfld("Macro or variable name","",&s,NULL); - if (y < 0) { - if (y == -3) { - printf("?Variable name required\n"); - return(-9); - } else return(y); - } - } - k = strlen(s); - if (k > VNAML) { - printf("?Name too long: \"%s\"\n",s); - return(-9); - } - ckstrncpy(vnambuf,s,VNAML); - vnambuf[VNAML] = NUL; - vnp = vnambuf; - if (vnambuf[0] == CMDQ && (vnambuf[1] == '%' || vnambuf[1] == '&')) vnp++; - if (*vnp == '%' || *vnp == '&') { - if ((y = parsevar(vnp,&x,&z)) < 0) return(y); -#ifdef COMMENT - if (cx == XXUNDEF) { /* Undefine */ - if ((y = cmtxt("Text to be ignored","",&s,NULL)) < 0) return(y); - delmac(vnp,0); - return(success = 1); - } -#endif /* COMMENT */ - debug(F101,"dodef parsevar x","",x); - if (mydot) { - if ((doeval = cmkey(asgtab,nasgtab,"operator","=",NULL)) < 0) - return(doeval); - if (doeval > 0) /* Type of assignment */ - cx = XXASS; - } - if (y == 1) { /* Simple variable */ - if ((y = cmtxt("Definition of variable","",&s,NULL)) < 0) - return(y); - s = brstrip(s); - debug(F110,"xxdef var name",vnp,0); - debug(F110,"xxdef var def",s,0); - } else if (y == 2) { /* Array element */ - if ((y = arraynam(vnp,&x,&z)) < 0) return(y); - if (x == 96) { - printf("?Argument vector array is read-only\n"); - return(-9); - } - if (chkarray(x,z) < 0) return(-2); - if ((y = cmtxt("Definition of array element","",&s,NULL)) < 0) - return(y); - debug(F110,"xxdef array ref",vnp,0); - debug(F110,"xxdef array def",s,0); - } - } else { /* Macro */ -#ifdef COMMENT - if (cx == XXUNDEF) { /* Undefine */ - if ((y = cmtxt("Text to be ignored","",&s,NULL)) < 0) return(y); - delmac(vnp,0); - return(success = 1); - } -#endif /* COMMENT */ - if (mydot) { - if ((doeval = cmkey(asgtab,nasgtab,"operator","=",NULL)) < 0) - return(doeval); - if (doeval > 0) - cx = XXASS; - } - if ((y = cmtxt("Definition of macro","",&s,NULL)) < 0) return(y); -#ifdef DEBUG - if (deblog) { - debug(F110,"xxdef macro name",vnp,0); - debug(F010,"xxdef macro def",s,0); - } -#endif /* DEBUG */ - s = brstrip(s); - } - if (*s == NUL) { /* No arg given, undefine */ - delmac(vnp,1); /* silently... */ - return(success = 1); /* even if it doesn't exist... */ - } - /* Defining a new macro or variable */ - - if (cx == XXASS || cx == XXASX) { /* ASSIGN rather than DEFINE? */ - int t; - t = LINBUFSIZ-1; - lp = line; /* If so, expand its value now */ - zzstring(s,&lp,&t); - s = line; - } - if (doeval == 2) { /* Arithmetic evaluation wanted too? */ - ckstrncpy(line,evala(s),LINBUFSIZ); - line[LINBUFSIZ] = NUL; - } - /* debug(F111,"calling addmac",s,(int)strlen(s)); */ - - y = addmac(vnp,s); /* Add it to the appropriate table. */ - if (y < 0) { - printf("?%s failed\n",(cx == XXASS || cx == XXASX) ? - "ASSIGN" : "DEFINE"); - return(success = 0); - } else if (cx == XXASX || cx == XXDFX) /* For _ASG or _DEF, */ - return(1); /* don't change success variable */ - else - return(success = 1); -} -#endif /* NOSPL */ - - -#ifndef NODIAL -/* - L U D I A L -- Lookup up dialing directory entry. - - Call with string to look up and file descriptor of open dialing directory - file. On success, returns number of matches found, with numbers stored - in an array accessible via getdnum(). -*/ -static char *dn_p[MAXDNUMS + 1]; /* Dial Number pointers */ -static char *dn_p2[MAXDNUMS + 1]; /* Converted dial number pointers */ -static int dn_x[MAXDNUMS + 1]; /* Type of call */ -static int dncount = 0; -char * d_name = NULL; /* Dial name pointer */ - -char * /* Get dial directory entry name */ -getdname() { - return(d_name ? d_name : ""); -} - -char * -getdnum(n) int n; { /* Get dial number n from directory */ - if (n < 0 || n > dncount || n > MAXDNUMS) - return(""); - else - return(dn_p[n]); -} - -char * /* Check area code for spurious leading digit */ -chk_ac(i,buf) int i; char buf[]; { - char *p; - if (!buf) - return(""); - p = (char *) buf; /* Country we are calling: */ - if (i == 44 || /* UK */ - i == 49 || /* Germany */ - i == 39 || /* Italy */ - i == 31 || /* Netherlands */ - i == 351 || /* Portugal */ - i == 55 || /* Brazil */ - i == 972 || /* Israel */ - i == 41 || /* Switzerland */ - i == 43 || /* Austria */ - i == 42 || /* Czech Republic */ - i == 36 || /* Hungary */ - i == 30 || /* Greece */ - i == 352 || /* Luxembourg */ - i == 48 || /* Poland */ - i == 27 || /* South Africa */ - i == 33 || /* France (as of 1997) */ - i == 358 /* Finland (ditto) */ - ) { - if (buf[0] == '0') - p++; - } - return(p); -} - -/* Call Is Long Distance -- Expand this to cover 10-digit local dialing etc */ -/* - src = area code of caller - dest = area code of callee - Returns: - 0 if call is local - 1 if call is long distance - 2 if call is local but area code must be dialed anyway -*/ -static int -callisld(src, dest) char * src, * dest; { - int i; - if (dialfld) /* Force long distance? */ - return(1); - if (!strcmp(src,dest)) { /* Area codes are the same */ - for (i = 0; i < nlocalac; i++) /* Is AC in the lc-area-codes list? */ - if (!strcmp(src,diallcac[i])) - return(2); /* Yes so must be dialed */ - return(0); /* No so don't dial it. */ - } - for (i = 0; i < nlocalac; i++) /* ACs not the same so look in list */ - if (!strcmp(dest,diallcac[i])) /* Match */ - return(2); /* So local call with area code */ - return(1); /* Not local so long-distance */ -} - -char pdsfx[64] = { NUL, NUL }; - -#ifndef NOSPL -static char * -xdial(s) char *s; { /* Run dial string thru macro */ - int x, m; - if (!dialmac) /* Dial macro name given? */ - return(NULL); - if ((x = mxlook(mactab,dialmac,nmac)) < 0) /* Is the macro defined? */ - return(NULL); - m = maclvl; - x = dodo(x,s,0); /* Set up the macro */ - if (x > 0) { - while (maclvl > m) /* Execute the parser */ - parser(1); - return(mrval[maclvl+1]); /* Return the result */ - } - return(NULL); -} -#endif /* NOSPL */ - -static int -dncvt(k,cx, prefix, suffix) - int k, cx, prefix, suffix; { /* Dial Number Convert */ - int i, j, n, what; /* cx is top-level command index */ - char *ss; /* prefix - add prefixes? */ - char *p, *p2, *pxo; /* suffix - add suffixes? */ - char *lac; - char *npr; - char *sfx; - /* char *psfx; */ - char ccbuf[128]; - int cc; - char acbuf[24]; - char *acptr; - char outbuf[256]; -/* - First pass for strict (punctuation-based) interpretation. - If it fails, we try the looser (length-based) one. -*/ - dialtype = -1; - what = 0; /* Type of call */ - s = dn_p[k]; /* Number to be converted. */ - debug(F111,"dncvt",s,k); - if (dn_p2[k]) { - free(dn_p2[k]); - dn_p2[k] = NULL; - } - if (!s) { - printf("Error - No phone number to convert\n"); - return(-1); - } - if ((int)strlen(s) > 200) { - ckstrncpy(outbuf,s,40); - printf("?Too long: \"%s...\"\n",outbuf); - return(-1); - } - npr = (prefix && dialnpr) ? dialnpr : ""; - sfx = (suffix && dialsfx) ? dialsfx : ""; - /* if (partial) psfx = dialsfx ? dialsfx : ""; */ - pxo = (prefix && dialpxo) ? dialpxo : ""; - lac = diallac ? diallac : ""; /* Local area code */ - - outbuf[0] = NUL; /* Initialize conversion buffer */ - ss = s; /* Remember original string */ - - if (*s != '+') { /* Literal number */ - dn_x[k] = DN_UNK; /* Sort key is "unknown". */ - ckmakmsg(outbuf,256, /* Sandwich it between */ - pxo,npr,s,sfx /* DIAL PREFIX and SUFFIX */ - ); -#ifdef CK_TAPI - if (tttapi && /* TAPI does its own conversions */ - !tapipass && /* if not in passthru mode */ - tapiconv == CK_AUTO || /* and TAPI conversions are AUTO */ - tapiconv == CK_ON /* OR if TAPI conversions are ON */ - ) { - char * p = NULL; - dialtype = -2; - if (!cktapiConvertPhoneNumber(dn_p[k], &p)) - return(-1); - makestr(&dn_p2[k], p); - if (p) free(p); - return(0); - } else -#endif /* CK_TAPI */ - makestr(&dn_p2[k], outbuf); /* Not TAPI */ - dialtype = what; - return(0); /* Done. */ - } - i = 0; /* Portable number */ - s++; /* Tiptoe past the plus sign */ - ccbuf[0] = NUL; /* Do country code first */ - - if (!diallcc) { /* Do we know our own? */ - if (cx != XXLOOK) - printf("Error - prior SET DIAL COUNTRY-CODE command required\n"); - return(-1); - } - - /* Parse the number */ - - while (1) { /* Get the country code */ - while (*s == HT || *s == SP) - s++; - if (!s) /* Not in standard format */ - break; - if (*s == '(') { /* Beginning of area code */ - s++; /* Skip past parenthesis */ - ccbuf[i] = NUL; /* End of country code */ - if (!s) { /* Check for end of string */ - printf("Error - phone number ends prematurely: \"%s\"\n",ss); - return(-1); - } - break; - } else { /* Collect country code */ - if (isdigit(*s)) - ccbuf[i++] = *s; /* copy this character */ - s++; - if (!*s || i > 127) /* watch out for memory leak */ - break; - } - } - cc = atoi(ccbuf); /* Numeric version of country code */ - - i = 0; /* Now get area code */ - acbuf[0] = NUL; /* Initialize area-code buffer */ - acptr = acbuf; /* and pointer. */ - while (1) { - while (*s == HT || *s == SP) /* Ignore whitespace */ - s++; - if (!s) /* String finished */ - break; - if (*s == ')') { /* End of area code */ - s++; /* Skip past parenthesis */ - acbuf[i] = NUL; /* Terminate area-code buffer */ - break; - } else { /* Part of area code */ - if (isdigit(*s)) /* If it's a digit, */ - acbuf[i++] = *s; /* copy this character */ - s++; /* Point to next */ - if (!*s || i > 23) /* Watch out for overflow */ - break; - } - } - -/* - Here we strip any leading 0 for countries that we know have - 0 as a long-distance prefix and do not have any area codes that - start with 0 (formerly also ditto for "9" in Finland...) -*/ - i = atoi(ccbuf); - acptr = chk_ac(i,acbuf); - - while (*s == HT || *s == SP) /* Skip whitespace */ - s++; - -/* printf("S=[%s], ACPTR=[%s]\n",s,acptr); */ - - if (*s && *acptr) { /* Area code was delimited */ - - while (*s == '-' || *s == '.') /* Skip past gratuitious punctuation */ - s++; - if (!*s) s--; /* But not to end of string */ - - if (strcmp(diallcc,ccbuf)) { /* Out of country? */ - if (!dialixp) { /* Need intl-prefix */ - if (cx != XXLOOK) - printf("Error - No international dialing prefix defined\n"); - return(-1); - } - what = dn_x[k] = DN_INTL; - p = (prefix && dialixp) ? dialixp : ""; /* Intl-prefix */ - p2 = (suffix && dialixs) ? dialixs : ""; /* Intl-suffix */ - - /* Form the final phone number */ -#ifdef COMMENT - sprintf(pdsfx,"%s%s",p2,sfx); /* UNSAFE */ - sprintf(outbuf, - "%s%s%s%s%s%s%s%s", - pxo,npr,p,ccbuf,acptr,s,p2,sfx - ); -#else - ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL); - ckmakxmsg(outbuf,256,pxo,npr,p,ccbuf,acptr,s,p2,sfx, - NULL,NULL,NULL,NULL); -#endif /* COMMENT */ - - } else if ((x = callisld(lac,acptr)) >= 1) { /* In-country LD */ - if (!diallac && cx != XXLOOK) { /* Don't know my own area code */ - if (cc == 1) - printf("WARNING - Prior SET DIAL AREA-CODE needed\n"); - } - if (x == 2) { /* Local call with area code */ - what = dn_x[k] = DN_LOCAL; /* Local-call */ - p = (prefix && diallcp) ? diallcp : ""; /* local-prefix */ - p2 = (suffix && diallcs) ? diallcs : ""; /* local-suffix */ - } else { - what = dn_x[k] = DN_LONG; /* Long-distance */ - for (i = 0; i < ntollfree; i++) { /* But toll-free too? */ - if (!strcmp(acptr,dialtfc[i])) { - what = dn_x[k] = DN_FREE; - break; - } - } - if (what == DN_FREE) { /* Toll-free call */ - p = (prefix && dialtfp) ? dialtfp : - ((prefix && dialldp) ? dialldp : ""); - p2 = ""; /* no suffix */ - } else { /* normal long distance */ - p = (prefix && dialldp) ? dialldp : ""; /* ld-prefix */ - p2 = (suffix && diallds) ? diallds : ""; /* ld-suffix */ - } - } - /* Form the number to be dialed */ -#ifdef COMMENT - sprintf(outbuf,"%s%s%s%s%s%s%s", - pxo,npr,p,acptr,s,p2,sfx - ); - sprintf(pdsfx,"%s%s",p2,sfx); -#else - ckmakxmsg(outbuf,256, - pxo,npr,p,acptr,s,p2,sfx, - NULL,NULL,NULL,NULL,NULL); - ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL); -#endif /* COMMENT */ - } else { /* Same country, same area code */ - what = dn_x[k] = DN_LOCAL; /* So it's a local call. */ - if (!prefix || !(dialpxo || ndialpxx)) { /* Not dialing from PBX */ - p = (prefix && diallcp) ? diallcp : ""; /* local-prefix */ - p2 = (suffix && diallcs) ? diallcs : ""; /* local-suffix */ -#ifdef COMMENT - if (x == 2) - sprintf(outbuf,"%s%s%s%s%s%s",npr,p,acptr,s,p2,sfx); - else - sprintf(outbuf,"%s%s%s%s%s",npr,p,s,p2,sfx); - sprintf(pdsfx,"%s%s",p2,sfx); -#else - if (x == 2) - ckmakxmsg(outbuf,256, - npr,p,acptr,s,p2,sfx, - NULL,NULL,NULL,NULL,NULL,NULL); - else - ckmakxmsg(outbuf,256, - npr,p,s,p2,sfx, - NULL,NULL,NULL,NULL,NULL,NULL,NULL); - ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL); -#endif /* COMMENT */ - - } else { /* Dialing from a PBX and not TAPI */ - if (ndialpxx) { /* Is it internal? */ -#ifdef COMMENT - i = (int) strlen(dialpxx); - j = (int) strlen(s); - x = -1; - if (j > i) - x = ckstrcmp(dialpxx,s,i,0); -#else - int kx; - x = -1; - j = (int) strlen(s); - for (kx = 0; kx < ndialpxx; kx++) { - i = (int) strlen(dialpxx[kx]); - if (j > i) - if (!(x = ckstrcmp(dialpxx[kx],s,i,0))) - break; - } -#endif /* COMMENT */ - if (!x) { - char * icp, buf[32]; - makestr(&matchpxx,dialpxx[kx]); - debug(F111,"dncvt matchpxx",matchpxx,kx); - what = dn_x[kx] = DN_INTERN; /* Internal call. */ - s += i; - /* Internal-call prefix */ - icp = dialpxi; -#ifndef NOSPL - if (icp) { - if (*icp == '\\') { - char c, *bp; - int n; - c = *(icp+1); - if (isupper(c)) c = tolower(c); - if (c == 'v' || c == 'f') { - n = 32; - bp = buf; - zzstring(icp,&bp,&n); - icp = buf; - } - } - } -#endif /* NOSPL */ - p = (prefix && icp) ? icp : ""; -#ifdef COMMENT - sprintf(outbuf,"%s%s%s%s",npr,p,s,sfx); -#else - ckmakmsg(outbuf,256,npr,p,s,sfx); -#endif /* COMMENT */ - } else { /* External local call */ - /* local-prefix */ - p = (prefix && diallcp) ? diallcp : ""; - /* local-suffix */ - p2 = (prefix && diallcs) ? diallcs : ""; -#ifdef COMMENT - if (x == 2) - sprintf(outbuf,"%s%s%s%s%s%s%s", - dialpxo ? dialpxo : "", - npr,p,acptr,s,p2,sfx); - else - sprintf(outbuf, - "%s%s%s%s%s%s", - dialpxo ? dialpxo : "", - npr,p,s,p2,sfx - ); -#else - if (x == 2) - ckmakxmsg(outbuf, 256, - dialpxo ? dialpxo : "", - npr,p,acptr,s,p2,sfx, - NULL,NULL,NULL,NULL,NULL); - else - ckmakxmsg(outbuf, 256, - dialpxo ? dialpxo : "", - npr,p,s,p2,sfx, - NULL,NULL,NULL,NULL,NULL,NULL); -#endif /* COMMENT */ - } - } - } - } - - } else { /* Area code was not delimited */ - - char xbuf[256]; /* Comparison based only on length */ - char ybuf[256]; - int x, j; - - s = ss; - - for (i = 0; i < 255; i++) { - if (!*s) break; - while (!isdigit(*s)) { /* Pay attention only to digits */ - s++; - if (!*s) break; - } - xbuf[i] = *s++; - } - xbuf[i] = NUL; - - x = 1; /* Assume LD */ - n = 0; - if (!dialfld) { /* If LD not forced */ - for (j = 0; j < nlocalac; j++) { /* check local AC list? */ - ckmakmsg(ybuf,256,diallcc,diallcac[j],NULL,NULL); - n = (int) strlen(ybuf); - if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0)) { - x = 2; - break; - } - } - if (x == 1) { /* Or exact match with local CC+AC? */ - ckmakmsg(ybuf,256,diallcc,lac,NULL,NULL); - n = (int) strlen(ybuf); - if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0)) - x = 0; - } - } - if (x == 0 || x == 2) { /* Local call */ - int xx,kx; /* Begin 1 Dec 2001... */ - /* Account for PBX internal calls */ - if (ndialpxx) { - xx = -1; - j = (int) strlen(ybuf); - for (kx = 0; kx < ndialpxx; kx++) { - i = (int) strlen(dialpxx[kx]); - if (j >= i) - if (!(xx = ckstrcmp(dialpxx[kx],&xbuf[j],i,0))) - break; - } - } - if (!xx) { - char * icp, buf[32]; - makestr(&matchpxx,dialpxx[kx]); - debug(F111,"dncvt matchpxx",matchpxx,kx); - what = dn_x[kx] = DN_INTERN; /* Internal call. */ - s = xbuf + j + i; - icp = dialpxi; /* Internal-call prefix */ -#ifndef NOSPL - if (icp) { - if (*icp == '\\') { - char c, *bp; - int n; - c = *(icp+1); - if (isupper(c)) c = tolower(c); - if (c == 'v' || c == 'f') { - n = 32; - bp = buf; - zzstring(icp,&bp,&n); - icp = buf; - } - } - } -#endif /* NOSPL */ - p = (prefix && icp) ? icp : ""; - ckmakmsg(outbuf,256,npr,p,s,sfx); - /* End 1 Dec 2001... */ - - } else { /* Not PBX internal */ - - dn_x[k] = DN_LOCAL; - p = (prefix && diallcp) ? diallcp : ""; - p2 = (suffix && diallcs) ? diallcs : ""; - s = (char *) (xbuf + ((x == 0) ? n : (int)strlen(diallcc))); - ckmakxmsg(outbuf,256, - pxo,npr,p,s,p2,sfx, - NULL,NULL,NULL,NULL,NULL,NULL); - ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL); - } - } else { /* Not local */ - n = ckstrncpy(ybuf,diallcc,256); - if (n > 0 && !ckstrcmp(xbuf,ybuf,n,0)) { /* Long distance */ - dn_x[k] = DN_LONG; - p = (prefix && dialldp) ? dialldp : ""; - p2 = (suffix && diallds) ? diallds : ""; - s = xbuf + n; - while (*s == '-' || *s == '.') - s++; -#ifdef COMMENT - sprintf(outbuf,"%s%s%s%s%s%s",pxo,npr,p,s,p2,sfx); - sprintf(pdsfx,"%s%s",p2,sfx); -#else - ckmakxmsg(outbuf,256, - pxo,npr,p,s,p2,sfx, - NULL,NULL,NULL,NULL,NULL,NULL); - ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL); -#endif /* COMMENT */ - } else { - dn_x[k] = DN_INTL; /* International */ - if (!dialixp) { - if (cx != XXLOOK) { - printf( - "Error - No international dialing prefix defined\n" - ); - return(-1); - } - } - p = (prefix && dialixp) ? dialixp : ""; - p2 = (suffix && dialixs) ? dialixs : ""; -#ifdef COMMENT - sprintf(outbuf,"%s%s%s%s%s%s",pxo,npr,p,xbuf,p2,sfx); - sprintf(pdsfx,"%s%s",p2,sfx); -#else - ckmakxmsg(outbuf,256, - pxo,npr,p,xbuf,p2,sfx, - NULL,NULL,NULL,NULL,NULL,NULL); - ckmakmsg(pdsfx,64,p2,sfx,NULL,NULL); -#endif /* COMMENT */ - } - } - } -#ifdef CK_TAPI - if (tttapi && /* TAPI performs the conversions */ - !tapipass && - tapiconv == CK_AUTO || - tapiconv == CK_ON - ) { - p = NULL; - dialtype = -2; - if (!cktapiConvertPhoneNumber(dn_p[k],&p)) - return(-1); - makestr(&dn_p2[k], p); - if (p) free(p); - return(0); - } else { -#endif /* CK_TAPI */ - makestr(&dn_p2[k], outbuf); -#ifdef CK_TAPI - } -#endif /* CK_TAPI */ - dialtype = what; - return(0); -} - -static int -ddcvt(s, f, n) char * s; FILE * f; int n; { /* Dial Directory Convert */ - char linebuf[1024], *s2; /* Buffers and pointers */ -#ifdef VMS - char * temp = NULL; -#endif /* VMS */ - char *info[8]; /* Pointers to words from entry */ - FILE * f2 = NULL; - int x, rc; - rc = -1; - - debug(F110,"ddcvt file",s,0); - - if (!s || !f) /* No filename or file */ - return(-1); - if (!*s) - - fclose(f); - znewn(s,&s2); /* s2 = address of static buffer */ - debug(F110,"ddcvt newname",s2,0); - -#ifdef VMS - /* In VMS, znewn() returns the same file name with a new version number */ - makestr(&temp,s); /* Swap - otherwise the new */ - s = s2; /* version has the older version */ - s2 = temp; /* number... */ - debug(F110,"ddcvt after swap s",s,0); - debug(F110,"ddcvt after swap s2",s2,0); - makestr(&(dialdir[n]),s); /* New file gets new version number */ - debug(F110,"ddcvt after makestr s2",s2,0); - debug(F111,"ddcvt dialdir[n]",dialdir[n],n); -#else - if (zrename(s,s2) < 0) { /* Not VMS - rename old file */ - perror(s2); /* to new (wierd) name. */ - goto ddexit; - } -#endif /* VMS */ - debug(F110,"ddcvt s2 (old)",s2,0); - if ((f = fopen(s2,"r")) == NULL) { /* Reopen old file with wierd name */ - debug(F110,"ddcvt s2 open error",ck_errstr(),0); - dirline = 0; /* (or in VMS, old version) */ - perror(s2); - goto ddexit; - } - debug(F110,"ddcvt fopen(s2) OK",s2,0); - - debug(F110,"ddcvt s (new)",s,0); - if ((f2 = fopen(s,"w")) == NULL) { /* Create new file with old name */ - debug(F110,"ddcvt s open error",ck_errstr(),0); - perror(s); /* (or in VMS, new version) */ - goto ddexit; - } - debug(F110,"ddcvt fopen(s) OK",s,0); - - printf("\nSaving old directory as %s.\nConverting %s...",s2,s); - fprintf(f2,"; %s - Kermit dialing directory\n", s); - fprintf(f2,"%-16s %-20s ; %5s %-6s ; %s\n", - "; Name","Number","Speed","Parity","Comment" - ); - - while (1) { - linebuf[0] = NUL; /* Read a line */ - if (fgets(linebuf,1023,f) == NULL) - break; - debug(F110,"ddcvt linebuf",linebuf,0); - if (!linebuf[0]) { /* Empty line */ - fprintf(f2,"\n"); - continue; - } - x = (int) strlen(linebuf); /* Strip line terminator, */ - while (x-- > 0) { /* if any. */ - if (linebuf[x] <= SP) - linebuf[x] = NUL; - else - break; - } - xwords(linebuf,5,info,1); /* Parse it the old way */ - for (x = 1; x < 6; x++) - if (!info[x]) info[x] = ""; - fprintf(f2,"%-16s %-20s ; %5s %-6s %s\n", - info[1],info[2],info[3],info[4],info[5] - ); - } - printf(" OK\n\n"); - rc = 0; /* Success */ - ddexit: - if (f) fclose(f); - if (f2) fclose(f2); -#ifdef VMS - if (temp) free(temp); -#endif /* VMS */ - return(rc); -} - -int /* s = name to look up */ -#ifdef CK_ANSIC /* cx = index of command */ -ludial(char *s, int cx) /* (DIAL, LOOKUP, etc) */ -#else -ludial(s, cx) char *s; int cx; -#endif /* CK_ANSIC */ -/* ludial */ { - - int dd, n1, n2, n3, i, j, t; /* Workers */ - int olddir, newdir, oldentry, newentry; - int pass = 0; - int oldflg = 0; - int ambiguous = 0; /* Flag for lookup was ambiguous */ - char *info[7]; /* Pointers to words from entry */ - char *pp; /* Pointer to element of array */ - FILE * f; - char *line; /* File input buffer */ - -/* #define LUDEBUG */ - -#ifdef LUDEBUG -int zz = 1; -#endif /* LUDEBUG */ - - if (!s || ndialdir < 1) /* Validate arguments */ - return(-1); - - if ((n1 = (int) strlen(s)) < 1) /* Length of string to look up */ - return(-1); - - if (!(line = malloc(1024))) /* Allocate input buffer */ - return(-1); - -#ifdef LUDEBUG -if (zz) printf("LUDIAL 1 s[%s], n1=%d\n",s,n1); -#endif /* LUDEBUG */ - - pass = 0; - lu_again: - f = NULL; /* Dial directory file descriptor */ - t = dncount = 0; /* Dial-number match count */ - dd = 0; /* Directory counter */ - olddir = 0; - newdir = 0; -/* - We need to recognize both old- and new-style directories. - But we can't allow old-style and new-style entries in the same - directory because there is no way to tell for sure the difference between - an old-style entry like this: - - foo 5551212 9600 - - and a new-style literal entry like this: - - foo 555 9600 - - I.e. is the "9600" a speed, or part of the phone number? -*/ - while (1) { /* We make one pass */ - if (!f) { /* Directory not open */ - if (dd >= ndialdir) /* No directories left? */ - break; /* Done. */ - debug(F111,"ludial dialdir[dd]",dialdir[dd],dd); - if ((f = fopen(dialdir[dd],"r")) == NULL) { /* Open it */ - perror(dialdir[dd]); /* Can't, print message saying why */ - if (line) { - free(line); - line = NULL; - } - dd++; /* Go on to next one, if any... */ - continue; - } - dirline = 0; /* Directory file line number */ - if (dialdpy && !pass) - printf("Opening: %s...\n",dialdir[dd]); - dd++; - if (!oldflg) olddir = 0; - newdir = 0; - } - oldentry = 0; - newentry = 0; - line[0] = NUL; - if (getnct(line,1023,f,1) < 0) { /* Read a line */ - if (f) { /* f can be clobbered! */ - fclose(f); /* Close the file */ - f = NULL; /* Indicate next one needs opening */ - oldflg = 0; - } - continue; - } - if (!line[0]) /* Empty line */ - continue; -#ifdef LUDEBUG -if (zz) printf("LUDIAL 2 s[%s]\n",s); -#endif /* LUDEBUG */ - - /* Make a copy and parse it the old way */ - /* A copy is needed because xwords() pokes NULs into the string */ - - if ((pp = malloc((int)strlen(line) + 1))) { - strcpy(pp,line); /* safe */ - xwords(pp,5,info,0); /* Parse it the old way */ - -#ifdef LUDEBUG -if (zz) printf("LUDIAL 3 s[%s]\n",s); -#endif /* LUDEBUG */ - - if (!info[1]) - continue; - if (*info[1] == ';') { /* If full-line comment, */ - newdir = 1; /* (only new directories have them) */ - continue; /* keep reading. */ - } - if (!info[2]) - continue; - if (*info[2] == '+') - newentry = 1; - if (info[4]) { - if ((*info[4] == '=') || - !ckstrcmp(info[4],"none", 4,0) || - !ckstrcmp(info[4],"even", 4,0) || - !ckstrcmp(info[4],"space",5,0) || - !ckstrcmp(info[4],"mark", 4,0) || - !ckstrcmp(info[4],"odd", 3,0) - ) - oldentry = 1; - } - } - if (pp) { - free(pp); - pp = NULL; - } - - /* Check consistency */ - - if ((oldentry || olddir) && (newentry || newdir)) { - printf( -"\nERROR: You seem to have old- and new-format entries mixed in your\n"); - printf( -"dialing directory. You'll have to edit it by hand to convert it to the\n"); -#ifndef NOHELP - printf("new format. Type HELP DIAL for further information.\n\n"); -#else - printf("new format.\n\n"); -#endif /* NOHELP */ - if (line) { - free(line); - line = NULL; - } - return(-1); - } - if (!olddir && oldentry) { - int convert = 0; - olddir = 1; - if (dialcvt == 2) { /* 2 == ASK */ - sprintf(tmpbuf, -"WARNING: Old-style dialing directory detected:\n%s", line); - convert = uq_ok(tmpbuf, - "Shall I convert it for you? ",3,NULL,0); - } else - convert = dialcvt; - if (convert) { - debug(F111,"ludial calling ddcvt",dialdir[dd-1],dd); - if (ddcvt(dialdir[dd-1],f,dd-1) < 0) { - debug(F111,"ludial ddcvt failed",dialdir[dd-1],dd); - oldflg = 1; - printf( -" Sorry, can't convert."); - printf( -" Will ignore speed and parity fields, continuing...\n\n"); - } else { - olddir = newdir = 0; - debug(F111,"ludial ddcvt ok",dialdir[dd-1],dd); - } - dd--; - f = NULL; - continue; - } else { - if (dialcvt == 2) - printf( -" OK, will ignore speed and parity fields, continuing...\n\n"); - olddir = 1; - } - } - -#ifdef LUDEBUG -if (zz) printf("LUDIAL XX s[%s], n1=%d\n",s,n1); -#endif /* LUDEBUG */ - - /* Now parse again for real */ - - if (oldentry) /* Parse it the old way */ - xwords(line,5,info,0); - else /* Parse it the new way */ - xwords(line,2,info,1); - -#ifdef LUDEBUG -if (zz) printf("LUDIAL YY s[%s], n1=%d\n",s,n1); -if (zz) printf("%s [%s]\n",info[1],info[2]); -#endif /* LUDEBUG */ - - if (info[1]) { /* First word is entry name */ - if ((n3 = (int) strlen(info[1])) < 1) /* Its length */ - continue; /* If no first word, keep reading. */ - if (n3 < n1) /* Search name is longer */ - continue; /* Can't possibly match */ - if (ambiguous && n3 != n1) - continue; - -#ifdef LUDEBUG -if (zz) printf("MATCHING: [%s] [%s], n1=%d\n",s,info[1],n1); -#endif /* LUDEBUG */ - - if (ckstrcmp(s,info[1],n1,0)) /* Caseless string comparison */ - continue; - -#ifdef LUDEBUG -if (zz) printf("MATCH OK: [%s] [%s], n1=%d\n",s,info[1],n1); -#endif /* LUDEBUG */ - - if (!info[2]) /* No phone number given */ - continue; - if ((n2 = (int) strlen(info[2])) < 1) /* Length of phone number */ - continue; /* Ignore empty phone numbers */ - - /* Got one */ - - if (!(pp = (char *)malloc(n2 + 1))) { /* Allocate storage for it */ - printf("?internal error - ludial malloc 1\n"); - if (line) { - free(line); - line = NULL; - } - dncount = 0; - return(-1); - } - strcpy(pp,info[2]); /* safe */ - - if (dncount > MAXDNUMS) { - printf("Warning: %d matches found, %d max\n", - dncount, - MAXDNUMS - ); - dncount = MAXDNUMS; - break; - } - dn_p[dncount++] = pp; /* Add pointer to array. */ - if (dncount == 1) { /* First one... */ - if (d_name) free(d_name); - if (!(d_name = (char *)malloc(n3 + 1))) { /* Save its name */ - printf("?internal error - ludial malloc 2\n"); - if (line) { - free(line); - line = NULL; - } - dncount = 0; - return(-1); - } - t = n3; /* And its length */ - strcpy(d_name,info[1]); /* safe */ - } else { /* Second or subsequent one */ - -#ifdef LUDEBUG - if (zz) - printf("d_name=[%s],info[1]=%s,t=[%d]\n",d_name,info[1],t); -#endif /* LUDEBUG */ - - if ((int) strlen(info[1]) == t) /* Lengths compare */ - if (!ckstrcmp(d_name,info[1],t,0)) /* Caseless compare OK */ - continue; - - /* Name given by user matches entries with different names */ - - if (ambiguous) /* Been here before */ - break; - - ambiguous = 1; /* Now an exact match is required */ - for (j = 0; j < dncount; j++) { /* Clean out previous list */ - if (dn_p[j]) { - free(dn_p[j]); - dn_p[j] = NULL; - } - } - pass++; /* Second pass... */ - goto lu_again; /* Do it all over again. */ - } - } - } - if (line) free(line); - if (dncount == 0 && ambiguous) { - printf(" Lookup: \"%s\" - ambiguous%s\n", - s, - cx == XXLOOK ? "" : " - dialing skipped" - ); - return(-2); - } - return(dncount); -} - -char * -pncvt(s) char *s; { /* Phone number conversion */ - char *p = NULL; /* (just a wrapper for dncvt() */ - char *q = NULL; - static char pnbuf[128]; - makestr(&p,dn_p[0]); /* Save these in case they are */ - makestr(&q,dn_p2[0]); /* being used */ - makestr(&dn_p[0],s); /* Copy the argument string to here */ - dncvt(0,XXLOOK,1,1); /* Convert it */ - if (!dn_p2[0]) /* Put result where can return it */ - pnbuf[0] = NUL; - else - ckstrncpy(pnbuf,dn_p2[0],127); - makestr(&dn_p[0],p); /* Restore these */ - makestr(&dn_p2[0],q); - makestr(&p,NULL); /* Free these */ - makestr(&q,NULL); - return((char *)pnbuf); -} - -int -dodial(cx) int cx; { /* DIAL or REDIAL */ - int i = 0, x = 0; /* Workers */ - int sparity = -1; /* For saving global parity value */ - int previous = 0; - int len = 0; - int literal = 0; - int flowsave; - int lufound = 0; /* Did any lookup succeed? */ - int prefix = 1; - int postfix = 1; - int wasalpha = 0; - int xredial = 0; - int braces = 0; - - char *p = NULL, *s3 = NULL, * sav = NULL; - int j = 0, t = 0, n = 0; - int xretries, xlcc; - - debug(F101,"dodial cx","",cx); - debug(F111,"dodial diallcc",diallcc,diallcc); - - xretries = dialrtr; /* If retries not set, */ - if (diallcc) { /* choose default based on */ - xlcc = atoi(diallcc); /* local country code. */ - if (xretries < 0) { - switch (xlcc) { - case 1: xretries = 10; break; /* No restrictions in NANP */ - /* Add other country codes here */ - /* that are known to have no restrictions on redialing. */ - default: xretries = 1; - } - } - } - if (cx == XXPDIA) { /* Shortcut... */ - cx = XXDIAL; - partial = 1; - debug(F100,"PDIAL sets partial=1","",0); - postfix = 0; /* Do not add postfix */ - } else { - partial = 0; - debug(F100,"DIAL sets partial=0","",0); - } - previous = dialsta; /* Status of previous call, if any */ - if (previous == DIA_PART) { - prefix = 0; /* do not add prefix */ - } - s = NULL; /* Initialize user's dial string */ - if (cx == XXRED) { /* REDIAL or... */ - if ((y = cmcfm()) < 0) - return(y); - } else if (cx == XXANSW) { /* ANSWER or ... */ - if ((y = cmnum("timeout (seconds)","0",10,&x,xxstring)) < 0) - return(y); - dialatmo = x; - if ((y = cmcfm()) < 0) - return(y); - } else { /* DIAL or LOOKUP */ - if (ndialdir > 0) - s3 = "Number to dial or entry from dial directory"; - else - s3 = "Number to dial"; - if ((x = cmtxt(s3, dialnum ? dialnum : "",&s,xxstring)) < 0) - return(x); - if (s) { - len = (int) strlen(s); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Save literal copy */ -#ifdef COMMENT - if (len > 1) { /* Strip outer braces if given */ - if (*s == '{') { - if (s[len-1] == '}') { - s[len-1] = NUL; - s++; - len -= 2; - } - } - } -#else - s = brstrip(s); /* Strip outer braces or quotes */ -#endif /* COMMENT */ - } - } - - if (cx != XXLOOK) { /* Not LOOKUP */ -#ifdef IKSD - if (inserver) { - printf("Sorry, dialing is disabled.\r\n"); - return(success = 0); - } -#endif /* IKSD */ -#ifdef CK_TAPI - if (tttapi && !tapipass) { - ; /* Skip the modem test if TAPI */ - } else -#endif /* CK_TAPI */ - if (mdmtyp < 1 && !dialtest) { - if (network -#ifdef TN_COMPORT - && !istncomport() -#endif /* TN_COMPORT */ - ) - printf("Please SET HOST first, and then SET MODEM TYPE\n"); - else - printf("Sorry, you must SET MODEM TYPE first\n"); - dialsta = DIA_NOMO; - return(success = 0); - } - if (!local && !dialtest) { - printf("Sorry, you must SET %s or SET HOST first\n", -#ifdef OS2 - "PORT" -#else - "LINE" -#endif /* OS2 */ - ); - dialsta = DIA_NOLI; - return(success = 0); - } - if ((!network -#ifdef TN_COMPORT - || istncomport() -#endif /* TN_COMPORT */ - ) && !dialtest && -#ifdef CK_TAPI - !tttapi && -#endif /* CK_TAPI */ - (speed < 0L) -#ifdef UNIX - && (strcmp(ttname,"/dev/null")) -#else -#ifdef OSK - && (strcmp(ttname,"/nil")) -#endif /* OSK */ -#endif /* UNIX */ - ) { - printf("\nSorry, you must SET SPEED first\n"); - dialsta = DIA_NOSP; - return(success = 0); - } - } - if (cx != XXANSW) { - for (j = 0; j < MAXDNUMS; j++) { /* Initialize dial-number list */ - if (!dialnum) { /* First time dialing */ - dn_p[j] = NULL; /* initialize all pointers. */ - dn_p2[j] = NULL; - } else if (dn_p[j]) { /* Not the first time, */ - free(dn_p[j]); /* free previous, if any, */ - dn_p[j] = NULL; /* then set to NULL. */ - if (dn_p2[j]) - free(dn_p2[j]); - dn_p2[j] = NULL; - } else break; /* Already NULL */ - } - if (len == 0) - s = NULL; - if (!s) - s = dialnum; - if (!s) { - if (cx == XXLOOK) - printf("?Lookup what?\n"); - else - printf("%s\n", (cx == XXRED) ? - "?No DIAL command given yet" : - "?You must specify a number to dial" - ); - return(-9); - } - - /* Now we have the "raw" dial or lookup string and s is not NULL */ - - makestr(&dscopy,s); /* Put it in a safe place */ - s = dscopy; - n = 0; - - debug(F111,"dodial",s,ndialdir); - - wasalpha = 0; - if (isalpha(*s)) { - wasalpha = 1; - if (ndialdir > 0) { /* Do we have a dialing directory? */ - n = ludial(s,cx); /* Look up what the user typed */ - if (n == 0) - printf(" Lookup: \"%s\" - not found%s\n", - s, - cx == XXLOOK ? "" : " - dialing as given\n" - ); - } - debug(F101,"dodial",s,n); - if (n < 0 && cx != XXLOOK) { /* Error out if they wanted to dial */ - if (n == -1) /* -2 means ludial already gave msg */ - printf(" Lookup: fatal error - dialing skipped\n"); - dialsta = DIA_DIR; - return(-9); - } - if (n > 0) /* A successful lookup */ - lufound = 1; - } else if (*s == '=') { /* If number starts with = sign */ - s++; /* strip it */ - literal = 1; /* remember this */ - while (*s == SP) s++; /* and then also any leading spaces */ - } else if (tmpbuf[0] == '{' && tmpbuf[1] == '{') { - makelist(tmpbuf,dn_p,MAXDNUMS); - makestr(&dscopy,tmpbuf); - s = tmpbuf; - for (n = 0; n < MAXDNUMS; n++) /* (have to count how many) */ - if (!dn_p[n]) break; - braces = 1; - } - if (cx == XXLOOK && !wasalpha && !braces) { - /* We've been told to lookup a number or a quoted name */ - char *p; - n = 0; - p = literal ? s : pncvt(dscopy); - if (!p) p = ""; - if (*p) { - printf("%s => %s\n", dscopy, p); - return(success = 1); - } else { - printf("?Bad phone number\n"); - return(success = 0); - } - } - /* Save DIAL or successful LOOKUP string for future DIAL or REDIAL */ - /* But don't save pieces of partial dial ... */ - - debug(F101,"DIAL save dialnum partial","",partial); - debug(F101,"DIAL save dialnum previous","",previous); - if ((cx == XXDIAL && partial == 0 && previous != DIA_PART) || - (cx == XXLOOK && n > 0)) { - makestr(&dialnum,dscopy); - if (!quiet && dscopy && !dialnum) - printf("WARNING - memory allocation failure: redial number\n"); - } - if (n > 0) { - if (!quiet && !backgrd && !braces /* && dialdpy */ ) { - if (!strcmp(d_name,s)) - printf(" Lookup: \"%s\" - exact match\n",s); - else - printf(" Lookup: \"%s\" - uniquely matches \"%s\"\n", - s, - d_name - ); - } - if ((cx == XXLOOK) || - ((n > 1) && !quiet && !backgrd /* && dialdpy */ )) { - printf(" %d telephone number%sfound for \"%s\"%s\n", - n, - (n == 1) ? " " : "s ", - s, - (n > 0) ? ":" : "." - ); - s3 = getdname(); - } - for (i = 0; i < n; i++) { /* Convert */ - dn_x[i] = -1; - if (dncvt(i,cx,prefix,postfix) < 0) { - if (cx != XXLOOK) { - dialsta = DIA_DIR; - return(-9); - } - } - } - if (dialsrt && n > 1) { /* Sort into optimal order */ - for (i = 0; i < n-1; i++) { - for (j = i+1; j < n; j++) { - if (dn_x[j] < dn_x[i]) { - t = dn_x[j]; - dn_x[j] = dn_x[i]; - dn_x[i] = t; - p = dn_p[j]; - dn_p[j] = dn_p[i]; - dn_p[i] = p; - p = dn_p2[j]; - dn_p2[j] = dn_p2[i]; - dn_p2[i] = p; - } - } - } - } - if ((cx == XXLOOK) || - ((n > 1) && !quiet && !backgrd /* && dialdpy */ )) { - int nn = n; -#ifndef NOSPL - char * p; -#endif /* NOSPL */ - if (cx != XXLOOK) - if (n > 12) nn = 12; - for (i = 0; i < nn; i++) { - printf("%3d. %-12s %-20s => %-20s (%d)\n",i+1, - s3, dn_p[i], - dn_p2[i] ? dn_p2[i] : "(processing failed)", - dn_x[i] - ); - } - if (cx != XXLOOK && n != nn) - printf("And %d more...\n", n - nn); - } - } else if (n == 0) { /* Not found in directory */ - makestr(&(dn_p[0]),literal ? s : dscopy); - makestr(&d_name,literal ? s : dscopy); - dncount = 1; - n = 1; - if (dncvt(0,cx,prefix,postfix) < 0) { /* In case they typed a */ - dialsta = DIA_DIR; /* portable-format number ... */ - return(-9); - } - } - -#ifndef NONET -#ifdef NETCONN - /* It's not good that the networks directory depends on NOT-NODIAL.. */ - if (cx == XXLOOK && dscopy) { /* Networks here too... */ - extern char *nh_p[], *nh_p2[], *n_name; - extern char *nh_px[4][MAXDNUMS+1]; - n = -1; - if (nnetdir > 0) { /* Do we have a network directory? */ - dirline = 0; - n = lunet(dscopy); /* Look up what the user typed */ - } - if (n > -1) { - int k; - if (n > 0) /* A successful lookup */ - lufound = 1; - if (cx == XXLOOK && n == 0) - printf(" Lookup: \"%s\" - not found\n",dscopy); - else - printf("%s %d network entr%s found for \"%s\"%s\n", - cx == XXLOOK ? " Lookup:" : "", - n, - (n == 1) ? "y" : "ies", - dscopy, - (n > 0) ? ":" : "." - ); - - for (i = 0; i < n; i++) { - - printf("%3d. %-12s => %-9s %s", - i+1,n_name,nh_p2[i],nh_p[i]); - for (k = 0; k < 4; k++) { - if (nh_px[k][i]) { - printf(" %s",nh_px[k][i]); - } else - break; - } - printf("\n"); - } - } - } -#endif /* NETCONN */ -#endif /* NONET */ - if (cx == XXLOOK) - return(success = lufound); - } /* cx != XXANSW */ - -#ifdef VMS - conres(); /* So Ctrl-C/Y will work */ -#endif /* VMS */ -/* - Some modems do not react well to parity. Also, if we are dialing through a - TCP/IP TELNET modem server, parity can be fatally misinterpreted as TELNET - negotiations. - - This should work even if the user interrupts the DIAL command, because the - DIAL module has its own interrupt handler. BUT... if, for some reason, a - dialing device actually *requires* parity (e.g. CCITT V.25bis says that even - parity should be used), this might prevent successful dialing. For that - reason, we don't do this for V.25bis modems. -*/ - sparity = parity; /* Save current parity */ - if ((dialcapas & CKD_V25) == 0) /* If not V.25bis... */ - parity = 0; /* Set parity to NONE */ - - flowsave = flow; -/* - These modems use some kind of screwy flow control while in command mode, - and do not present CTS as they should. So if RTS/CTS is set (or even if - it isn't) disable flow control during dialing. -*/ -#ifndef MINIDIAL - if (mdmtyp == n_ATT1910 || mdmtyp == n_ATT1900) { - flow = FLO_NONE; /* This is not enough */ -#ifdef CK_TTSETFLOW - ttsetflow(FLO_NONE); /* Really turn it off */ -#endif /* CK_TTSETFLOW */ - } -#endif /* MINIDIAL */ - if (!network -#ifdef TN_COMPORT - || istncomport() -#endif /* TN_COMPORT */ - ) { - int x; - if ((x = ttgmdm()) > -1) { - if (!x && msgflg) { - printf( -"WARNING - No modem signals detected. Is your modem turned on? If not,\n\ -use Ctrl-C to interrupt dialing, turn on your modem, then %s.\n", - cx == XXANSW ? - "ANSWER again" : - "REDIAL" - ); - } - if (flow == FLO_RTSC) { - if (!(x & BM_CTS)) { - if (msgflg) - printf( -"WARNING - SET FLOW RTS/CTS is in effect but modem's CTS signal is off.\n\ -Disabling flow control temporarily %s...\n", - cx == XXANSW ? - "while waiting for call" : - "during dialing" - ); - flow = FLO_NONE; - } - } - } - } - if (cx == XXANSW) { /* ANSWER */ - success = ckdial("",0,0,1,0); - goto dialfin; - } - -/* Edit 192 adds the ability to dial repeatedly. */ - - i = 0; - dialcount = 0; - do { - if (i > 0) printf("\nDial attempt %d of %d...\n", i+1, xretries); - dialcount = i+1; - success = 0; - /* And the ability to dial alternate numbers. */ - /* Loop to dial each in a list of numbers for the same name... */ - for (j = 0; j < n && !success; j++) { /* until one answers. */ - s = dn_p2[j]; /* Next number in list */ - if (dn_x[j] >= dialrstr) { /* Dial restriction */ - printf("Restricted: %s, skipping...\n",dn_p[j]); - continue; - } - xredial = (i == 0 && j == 0) ? 0 : 1; - if (!s) s = dn_p[j]; - -#ifndef NOSPL - sav = s; - p = xdial(s); /* Apply DIAL macro now */ - if (p) s = p; -#endif /* NOSPL */ - - /* Dial confirmation */ - /* NOTE: the uq_xxx() calls allow for a GUI dialog */ - - if (i == 0 && dialcnf) { - char msgbuf[128]; - ckmakmsg(msgbuf,128,"Dialing ",s,NULL,NULL); - x = uq_ok(msgbuf,"Is this number correct? ",3,NULL,0); - if (!x) { - -#ifndef COMMENT - x = uq_txt( /* Allow GUI dialog */ -#ifdef OS2 -" Please enter the correct number,\r\n or press Enter to skip.", -#else -" Please enter the correct number,\r\n or press Return to skip.", -#endif /* OS2 */ - "Corrected phone number: ", - 1, - NULL, - atmbuf, - ATMBL, - s, - DEFAULT_UQ_TIMEOUT - ); - if (x && atmbuf[0]) { /* They gave a new one */ - s = atmbuf; - makestr(&(dn_p2[j]), s); - } - -#else /* COMMENT */ - -#ifdef CK_RECALL - extern int on_recall; -#endif /* CK_RECALL */ - cmsavp(psave,PROMPTL); - cmsetp( -#ifdef OS2 -" Please enter the correct number,\r\n or press Enter to skip: " -#else -" Please enter the correct number,\r\n or press Return to skip: " -#endif /* OS2 */ - ); - cmini(ckxech); - x = -1; - if (pflag) prompt(NULL); -#ifdef CK_RECALL - on_recall = 0; -#endif /* CK_RECALL */ - y = cmdgquo(); - cmdsquo(0); - while (x < 0) { - x = cmtxt("Corrected phone number","",&s,NULL); - cmres(); - } - if ((int) strlen(s) < 1) { - cmsetp(psave); - continue; - } - makestr(&(dn_p2[j]), s); - cmdsquo(y); - cmsetp(psave); -#endif /* COMMENT */ - } - } - if (dialtest) { /* Just testing */ - if (i + j == 0) - printf("\nTESTING...\n"); - if (dialmac) - printf(" Number: \"%s\" => \"%s\"\n",sav,s); - else - printf(" Number: \"%s\"\n",s); - dialsta = DIA_BUSY; - success = 0; - } else { - what |= W_DIALING; - success = ckdial(s,i,j,partial ? 3 : 0, xredial); /* Dial it */ - what &= ~(W_DIALING); - if (!success) { - if (dialsta < 8 || /* Break out if unrecoverable error */ - dialsta == DIA_INTR || - dialsta == DIA_ERR || - previous == DIA_PART - ) - break; - } - } - } - if (success) /* Succeeded, leave the outer loop */ - break; - if (dialsta < 8 || /* Break out if unrecoverable error */ - dialsta == DIA_INTR || /* Interrupted */ - dialsta == DIA_NODT || /* No dialtone */ - dialsta == DIA_NOAC || /* Access forbidden */ - dialsta == DIA_BLCK || /* Blacklisted */ - dialsta == DIA_DIR || /* Dialing directory error */ - dialsta == DIA_ERR || /* Modem command error */ - previous == DIA_PART) - break; - if (++i >= xretries) /* Break out if too many tries */ - break; - if (!backgrd && !quiet) { - if (dialint > 5) - printf( -"\nWill redial in %d second%s- press any key to redial immediately.\n", - dialint, - dialint == 1 ? " " : "s " - ); - printf("Ctrl-C to cancel...\n"); - } - x = dialint; /* Redial interval */ - while (x-- > 0) { - if ((y = conchk()) > 0) { /* Did they type something? */ - while (y--) coninc(0); /* Yes, absorb it */ - break; /* And wake up */ - } - sleep(1); /* No interrupt, sleep a sec */ - } - } while (!success); - - dialfin: - - if (cx != XXLOOK) { - if (!success) - bleep((short) BP_FAIL); - else if (!quiet) - bleep((short) BP_NOTE); -#ifdef OS2 - setint(); /* Fix OS/2 interrupts */ -#endif /* OS2 */ - if (sparity > -1) - parity = sparity; /* Restore parity if we saved it */ - flow = flowsave; -#ifdef OS2 - ttres(); /* Restore DIAL device */ -#endif /* OS2 */ -#ifdef VMS - concb((char)escape); /* Restore console */ -#endif /* VMS */ -#ifdef OS2 - { /* Set session title */ - char * p, name[72]; /* in window list. */ - char * q; - if (cx == XXANSW) { - q = "Incoming call"; - } else { - if (d_name) - q = d_name; - else if (dialnum) - q = dialnum; - else if (ttname[0]) - q = ttname; - else q = ""; - } - p = name; - if (success) { - strncpy(name,q,48); - while (*p) { /* Uppercase it for emphasis. */ - if (islower(*p)) - *p = toupper(*p); - p++; - } - } else - name[0] = NUL ; - os2settitle((char *) name, TRUE); - } -#endif /* OS2 */ - } - if (cx != XXLOOK) { - if (success) { - if (reliable == SET_AUTO) { /* It's not a reliable connection. */ - reliable = SET_OFF; - debug(F101,"dodial reliable","",reliable); - } - } else { -#ifndef NOHINTS - extern int hints; - if (hints && !quiet && dialsta != 9) { /* 9 == User interrupted */ - extern int dialmhu, dialhng, dialdpy; - extern char * dialmsg[]; - printf("\n*************************\n"); - printf("DIAL-class command failed.\n"); - printf("Modem type: %s\n", gmdmtyp()); - printf("Device: %s\n", ttname); - printf("Speed: %ld\n", speed); - printf("Dial status: %d",dialsta); - if (dialsta < 35 && dialmsg[dialsta]) - printf(" [%s]",dialmsg[dialsta]); - printf("\n"); - if (dialsta == DIA_TIMO || - dialsta == DIA_NRDY || - (dialsta > 13 && dialsta != DIA_BUSY && dialsta != DIA_NOAN) - ) { - switch (dialsta) { - case DIA_TIMO: - printf( -" . SET DIAL TIMEOUT to a greater value and try again.\n" - ); - break; - case DIA_NRSP: - case DIA_NRDY: - case DIA_NOIN: - printf( -" . Is the modem turned on?\n" - ); - printf( -" . Are you using the right communication port?\n" - ); - break; - case DIA_NODT: - printf( -" . Is the modem connected to the telephone line?\n" - ); - } - if (mdmtyp == n_GENERIC) { - printf( -" . Please choose a specific modem type with SET MODEM TYPE and try again.\n" - ); - printf( -" SET MODEM TYPE ? to see the list of known modem types.\n" - ); - } else { - printf( -" . Are you sure you have chosen the appropriate modem type?\n" - ); - } - if (speed > 19200L) { - printf( -" . Maybe the interface speed (%ld) is too fast:\n", speed - ); - printf( -" SET SPEED to a lower speed and try again.\n" - ); - printf( -" SET SPEED ? to see the list of valid speeds.\n" - ); - } - if (dialhng) { - if (dialmhu) - printf( -" . SET MODEM HANGUP-METHOD RS232 and try again.\n" - ); - else - printf( -" . SET MODEM HANGUP-METHOD MODEM-COMMAND and try again.\n" - ); - printf( -" . If that doesn't work, try again with SET DIAL HANGUP OFF.\n" - ); - } else { - printf( -" . Give a HANGUP or SET DIAL HANGUP ON command and try again.\n" - ); - } - if (!dialdpy) - printf( -" . Use SET DIAL DISPLAY ON to watch the dialog between Kermit and modem.\n" - ); - } -#ifndef NOSHOW - printf( -" . SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL to see current settings.\n" - ); -#endif /* NOSHOW */ - -#ifndef NOHELP - printf( -" . HELP SET MODEM, HELP SET DIAL, and HELP DIAL for more information.\n" - ); -#endif /* NOHELP */ - printf("(Use SET HINTS OFF to suppress future hints.)\n"); - printf("*************************\n\n"); - } -#endif /* NOHINTS */ - } - } - return(success); -} -#endif /* NODIAL */ - -/* D O T Y P E -- Type (display) a file with various options... */ - -#ifdef BIGBUFOK -#define TYPBUFL 16384 -#else -#define TYPBUFL 256 -#endif /* BIGBUFOK */ - -int typ_lines = 0; /* \v(ty_ln) */ -int typ_mtchs = 0; /* \v(ty_lm) */ -static int typ_int = 0; /* Flag if TYPE interrupted */ - -#ifdef UNICODE -extern int fcharset, fileorder, byteorder, ucsorder; -#define TYPXBUFL TYPBUFL+TYPBUFL+TYPBUFL+4 -static char * mp = NULL; -static char * mbuf = NULL; -static long xn = 0L; - -static int -#ifdef CK_ANSIC -storechar(char c) -#else -storechar(c) char c; -#endif /* CK_ANSIC */ -{ - if (!mp) return(-1); - if (++xn > TYPXBUFL) - return(-1); - debug(F111,"storechar xn",ckitoa((int)c),xn); - *mp++ = c; - return(0); -} -#endif /* UNICODE */ - -static FILE * ofp = NULL; /* For /OUTPUT: file */ - -static int -typeline(buf,len,outcs,ofp) char * buf; int len, outcs; FILE * ofp; { - register int i; - - debug(F011,"typeline buf",buf,len); - /* debug(F101,"typeline outcs","",outcs); */ - -#ifdef OS2 -#ifndef NOLOCAL -#ifdef UNICODE - /* In K95 only, the buffer is guaranteed to be in UCS-2 if outcs >= 0. */ - /* Len is its length in bytes. There is no line terminator. */ - /* outcs is the file character-set number (FC_xxx) of the target set */ - /* that was requested by the user. */ - if (!inserver && !k95stdout) { - extern int wherex[], wherey[]; - extern unsigned char colorcmd; - - VscrnWrtUCS2StrAtt( VCMD, (unsigned short *)buf, len/2, - wherey[VCMD], wherex[VCMD], &colorcmd); - printf("\r\n"); - return(0); - } -#endif /* UNICODE */ -#endif /* NOLOCAL */ -#endif /* OS2 */ - -/* In Unix, VMS, etc, the line has already been converted to the desired */ -/* character-set, if one was given. OR... on all platforms, including in */ -/* K95, we don't know the character set. In either case we dump the line */ -/* byte by byte in case it contains NULs (printf() would truncate). */ - -#ifdef COMMENT - for (i = 0; i < len; i++) - putchar(buf[i]); -#else - for (i = 0; i < len; i++) { - if (ofp == stdout) { - putchar(buf[i]); - } else { - putc(buf[i],ofp); - } - } -#endif /* COMMENT */ - -#ifdef IKSD - if (inserver) { -#ifdef UNICODE - if (outcs == FC_UCS2) { - if (ofp == stdout) { - putchar(NUL); - } else { - putc(NUL,ofp); - } - } -#endif /* UNICODE */ - if (ofp == stdout) { - putchar('\r'); - } else { - putc('\r',ofp); - } - } -#endif /* IKSD */ -#ifdef UNICODE - if (outcs == FC_UCS2) { - if (ofp == stdout) { - putchar(NUL); - } else { - putc(NUL,ofp); - } - } -#endif /* UNICODE */ - if (ofp == stdout) { - putchar('\n'); - } else { - putc('\n',ofp); - } - fflush(stdout); - return(0); -} - -static int /* Get translated line */ -typegetline(incs, outcs, buf, n) int incs, outcs, n; char * buf; { - int x = 0, c0, c1, len = 0, count = 0, eof = 0, xlate = 0; -#ifdef UNICODE - int xxn = -1; - int yyn = -9; - xn = 0L; - -#ifdef DEBUG - if (deblog && typ_lines == 0) { - debug(F101,"typegetline incs","",incs); - debug(F101,"typegetline outcs","",outcs); - debug(F101,"typegetline feol","",feol); - debug(F101,"typegetline byteorder","",byteorder); - debug(F101,"typegetline ucsorder ","",ucsorder); - debug(F111,"typegetline fileorder","1",fileorder); - } -#endif /* DEBUG */ - - if (incs < 0) /* Shouldn't happen */ - return(-2); - - if (outcs == -1) /* Can happen */ - outcs = incs; - - if (incs != outcs || incs == FC_UCS2) { /* See if we should translate */ - xlate = 1; - if (!mbuf) { /* Allocate buffer if not allocated */ - mbuf = (char *)malloc(TYPXBUFL+1); /* yet */ - if (!mbuf) { - printf("WARNING: Translation buffer allocation failure.\n"); - printf("Translation will be skipped...\n"); - xlate = 0; - } - } - } - if (xlate) { /* Translating... */ - mp = mbuf; /* Reset working buffer pointer */ -/* - Here we call xgnbyte() in a loop, having it return UCS-2 bytes. In K95, we - use UCS-2 directly. Elsewhere, we feed the UCS-2 bytes into xpnbyte() to - convert them to the desired target character set. But since we are using - UCS-2, we have several sources for confusion: (1) xgnbyte() might return in - LE or BE byte order, with no explicit indication of what the order is; but - (2) xpnbyte() wants BE; but (3) Windows wants LE. -*/ - while (1) { - if (typ_int) /* Quit if interrupted */ - return(0); - c0 = xgnbyte(FC_UCS2,incs,NULL); /* Convert to UCS-2 */ - debug(F000,"typegetline c0","",c0); - if (c0 < 0) { /* EOF */ - eof++; - break; - } - c1 = xgnbyte(FC_UCS2,incs,NULL); /* Convert to UCS-2 */ - debug(F000,"typegetline c1","",c1); - if (c1 < 0) { /* EOF */ - eof++; - break; - } -#ifdef DEBUG - if (deblog && typ_lines == 0) { - if (count == 0) /* Check fileorder after BOM */ - debug(F111,"typegetline fileorder","2",fileorder); - } -#endif /* DEBUG */ - -#ifdef COMMENT -/* Now we have the two UCS-2 bytes. Which order are they in? */ - - if (fileorder > 0) { /* Little Endian */ - int t; /* So swap them */ - debug(F100,"typegetline swapping","",0); - t = c1; - c1 = c0; - c0 = t; - } -#endif /* COMMENT */ - if (c0 == 0 && c1 == 0x0D) /* Now see if we have EOL */ - yyn = xn; - - if (c0 == 0 && c1 == 0x0A) /* Now see if we have EOL */ - xxn = xn; - - count++; /* Count byte */ - -/* Give the two bytes to xpnbyte() in BE order */ - - if ((x = xpnbyte(c0,TC_UCS2,outcs,storechar)) < 0) return(-1); - if ((x = xpnbyte(c1,TC_UCS2,outcs,storechar)) < 0) return(-1); - - if (xxn > -1) { /* Have end of line? */ - xn = xxn; - if (yyn == xxn - 2) /* Adjust for CRLF */ - xn = yyn; - break; /* And break out of loop. */ - } - } - mbuf[xn] = NUL; - if (xn > n) /* Can truncate here... */ - xn = n; - memcpy(buf,mbuf,xn); - debug(F011,"typegetline xlate",buf,xn); - return((eof && (xn == 0)) ? -1 : xn); - } -#endif /* UNICODE */ -#ifdef COMMENT - /* We can't use this because, stupidly, zsinl() doesn't return a length. */ - /* It could be changed but then we'd have to change all ck?fio.c modules */ - x = zsinl(ZIFILE,buf,n); -#else - /* So instead, we copy zsinl() to here... */ - /* But note: This does not necessarily handle UCS-2 alignment properly; */ - /* that's what the code in the first section of this routine is for. */ - /* But it does tolerate files that contain NULs. */ - { - int a; - char *s; - - s = buf; - a = -1; /* Current character, none yet. */ - debug(F101,"typegetline zsinl simulation","",n); - while (n--) { /* Up to given length */ -#ifdef COMMENT - int old = 0; - if (feol) /* Previous character */ - old = a; -#endif /* COMMENT */ - if (zchin(ZIFILE,&a) < 0) { /* Read a character from the file */ - debug(F101,"typegetline zchin fail","",count); - if (count == 0) - x = -1; /* EOF or other error */ - break; - } else - count++; - if (feol) { /* Single-character line terminator */ - if (a == feol) - break; - } else { /* CRLF line terminator */ -#ifdef COMMENT -/* Debug log shows that in Windows, is returned as . */ -/* Apparently we're not reading the file in binary mode. */ - - if (a == '\015') /* CR, get next character */ - continue; - if (old == '\015') { /* Previous character was CR */ - if (a == '\012') { /* This one is LF, so we have a line */ - break; - } else { /* Not LF, deposit CR */ - *s++ = '\015'; - n--; - len++; - } - } -#else - if (a == LF) { - if (s[len] == CR) { /* This probably won't happen */ - s[len] = NUL; - s--; - len--; - } - break; - } -#endif /* COMMENT */ - } - *s = a; /* Deposit character */ - s++; - len++; - } - *s = '\0'; /* Terminate the string */ - } -#endif /* COMMENT */ - return(x < 0 ? -1 : len); -} - - -#ifndef MAC -SIGTYP -#ifdef CK_ANSIC -tytrap(int foo) /* TYPE interrupt trap */ -#else -tytrap(foo) int foo; -#endif /* CK_ANSIC */ -/* tytrap */ { -#ifdef __EMX__ - signal(SIGINT, SIG_ACK); -#endif - debug(F100,"type tytrap SIGINT","",0); - typ_int = 1; /* (Need arg for ANSI C) */ - SIGRETURN; -} -#endif /* MAC */ - -int -dotype(file, paging, first, head, pat, width, prefix, incs, outcs, outfile, z) - char * file, * pat, * prefix; int paging, first, head, width, incs, outcs; - char * outfile; int z; -/* dotype */ { - extern long ffc; - char buf[TYPBUFL+2]; - char * s = NULL; - int rc = 1, lines = 0, ucs2 = 0; - char ** tail = NULL; - int * tlen = NULL; - int tailing = 0, counting = 0; - int x, c, n, i, j, k = 0; - int number = 0, save, len, pfxlen = 0, evalpfx = 1; -#ifdef UNICODE - int ucsbom_sav; - extern int ucsbom; -#endif /* UNICODE */ -#ifdef NT - int gui = 0; -#endif /* NT */ - -#ifndef MAC -#ifdef OS2 -#ifdef NT - SIGTYP (* oldsig)(int); /* For saving old interrupt trap. */ -#else /* NT */ - SIGTYP (* volatile oldsig)(int); -#endif /* NT */ -#else /* OS2 */ - SIGTYP (* oldsig)(); -#endif /* OS2 */ -#endif /* MAC */ - -#ifdef KUI - if (outfile == (char *)1) { - gui = 1; - outfile = ""; - } -#endif /* KUI */ - - if (!file) file = ""; - if (!*file) return(-2); - - if (ofp != stdout) { /* In case of previous interruption */ - if (ofp) fclose(ofp); - ofp = stdout; - } - if (!outfile) outfile = ""; - if (outfile[0]) { - ofp = fopen(outfile,"w"); /* Open output file */ - if (!ofp) { - printf("?Can't open output file %s: %s\n",outfile,ck_errstr()); - ofp = stdout; - return(-9); - } - } - number = z; - if (number && prefix) prefix = NULL; - -#ifdef UNICODE - ucsbom_sav = ucsbom; /* We are not creating a file */ - ucsbom = 0; /* Do not use BOM bytes */ -#endif /* UNICODE */ - - typ_int = 0; - - save = binary; /* Save file type */ - - debug(F101,"dotype incs","",incs); - debug(F101,"dotype outcs","",outcs); - -#ifdef UNICODE - debug(F111,"dotype fileorder","A",fileorder); -#ifdef OS2 - if (!inserver && !k95stdout) - outcs = FC_UCS2; -#endif /* OS2 */ - - if (outcs == FC_UCS2) /* Output is UCS-2? */ - ucs2 = 1; - if (fileorder < 0) - fileorder = ucsorder; - debug(F111,"dotype fileorder","B",fileorder); -#endif /* UNICODE */ - -#ifdef CK_TTGWSIZ -#ifdef OS2 - ttgcwsz(); -#else /* OS2 */ - /* Check whether window size changed */ - if (ttgwsiz() > 0) { - if (tt_rows > 0 && tt_cols > 0) { - cmd_rows = tt_rows; - cmd_cols = tt_cols; - debug(F101,"dotype cmd_rows","",cmd_rows); - debug(F101,"dotype cmd_cols","",cmd_cols); - } - } -#endif /* OS2 */ -#endif /* CK_TTGWSIZ */ - - if (prefix) - pfxlen = strlen(prefix); - - if (paging < 0) { /* Count only, don't print */ - counting = 1; - prefix = NULL; - width = 0; - paging = 0; - } - if (ucs2) /* Crude... */ - width *= 2; - -#ifdef OS2 - if (*file) { - ckstrncpy(buf, file, TYPBUFL); /* Change / to \. */ - p = buf; - while (*p) { - if (*p == '/') *p = '\\'; - p++; - } - file = buf; - } else { - rc = 0; - goto xdotype; - } -#endif /* OS2 */ - - if (zchki(file) == -2) { /* It's a directory */ - debug(F111,"dotype zchki failure",file,-2); - if (xcmdsrc == 0) { - printf("?Not a regular file: \"%s\"\n",file); - rc = -9; - } else - rc = 0; - goto xdotype; - } - if (!zopeni(ZIFILE, file)) { /* Not a directory, open it */ - debug(F111,"dotype zopeni failure",file,0); - if (xcmdsrc == 0) { - printf("?Can't open file: \"%s\"\n",file); - rc = -9; - } else - rc = 0; - goto xdotype; - } - -#ifndef AMIGA -#ifndef MAC - errno = 0; - oldsig = signal(SIGINT, tytrap); /* Save current interrupt trap. */ - debug(F111,"type SIGINT trap set",ckitoa(errno),oldsig); -#endif /* MAC */ -#endif /* AMIGA */ - - if (paging > -1) /* More-prompting */ - xaskmore = paging; - - binary = 0; - - if (head < 0) { /* "tail" was requested */ - tailing = 1; /* Set flag */ - head = 0 - head; /* Get absolute number of lines */ - if (!counting) { - tail = (char **) malloc(head * sizeof(char *)); /* Allocate list */ - if (!tail) { - printf("?Memory allocation failure\n"); - goto xdotype; - - } - tlen = (int *) malloc(head * sizeof(int)); - if (!tlen) { - printf("?Memory allocation failure\n"); - goto xdotype; - - } - for (i = 0; i < head; i++) { /* Initialize each pointer in list. */ - tail[i] = NULL; - tlen[i] = 0; - } - } - } - typ_lines = 0; - typ_mtchs = 0; - -#ifdef UNICODE - if (outcs > -1 && (incs != outcs || incs == FC_UCS2)) { /* Translating? */ - ffc = 0L; - initxlate(incs,outcs); /* Set up translation functions */ - } else -#endif /* UNICODE */ - outcs = -1; /* Means we don't know the charset */ - - debug(F101,"dotype ffc","",ffc); - debug(F101,"dotype outcs 2","",outcs); -#ifdef UNICODE - debug(F111,"dotype fileorder","C",fileorder); -#endif /* UNICODE */ - - /* Allow the buffer to contain NULs */ - - for (n = first; - (len = typegetline(incs,outcs,buf,TYPBUFL)) > -1; - lines++ - ) { - debug(F011,"dotype line",buf,len); -#ifndef MAC - if (typ_int) { /* Interrupted? */ - typ_int = 0; - debug(F101,"type interrupted line","",lines); - printf("^C...\n"); /* Print message */ - if (ofp != stdout) { /* Close any output file */ - if (ofp) fclose(ofp); - ofp = stdout; - } - goto xxdotype; - } -#endif /* MAC */ - typ_lines++; /* For \v(ty_ln) */ - if (pat) /* Matching? */ - if (!ckmatch(pat,buf,1,1+4)) /* Line matches pattern? */ - continue; /* No, skip it */ - typ_mtchs++; - - if (head > 0 && !tailing && lines == head) /* Handle /HEAD:n */ - break; - - buf[TYPBUFL+1] = NUL; /* Just in case... */ - if (prefix) { /* Add specified prefix to each line */ - char pbuf[64]; - char * pp; - pp = prefix; -#ifndef NOSPL - if (evalpfx) { /* Prefix is a variable? */ - int n = 63; /* Maybe - evaluate it and see */ - char * p = pbuf; - zzstring(prefix,&p,&n); /* If there is no change */ - if (!strcmp(prefix,pbuf)) { /* it's not a variable */ - evalpfx = 0; /* So don't do this again. */ - } else { /* It was a variable */ - pp = pbuf; /* So substitute its value */ - pfxlen = 63 - n; /* and get its new length */ - } - } -#endif /* NOSPL */ - if (len + pfxlen + 2 < TYPBUFL) { - /* Shift right to make room for prefix */ - memcpy((char *)line+pfxlen,(char *)buf,len); - lset((char *)line,pp,pfxlen,SP); - debug(F110,"dotype prefix",line,pfxlen); - len += pfxlen; - memcpy((char *)buf,(char *)line,len); - } - } else if (number) { /* Line numbers */ - int x; - sprintf(line,"%4d. ",typ_lines); - x = strlen(line); - len += x; - if (len < LINBUFSIZ) { - memcpy((char *)&line[x],(char *)buf,len); - memcpy((char *)buf,(char *)line,len); - } - } - if (width > 0 && width <= TYPBUFL) { /* Truncate at given width. */ - char * obuf = line; /* But to do that first we must */ - int i,k,z; /* expand tabs; assume every 8 cols. */ - line[0] = NUL; - for (i = 0, k = 0; i < width; k++) { /* Character loop... */ - if (!buf[k]) /* No more chars in this line, done. */ - break; - if (buf[k] != '\t') { /* If it's not a tab */ - if (i >= LINBUFSIZ) /* Check for overflow */ - break; - obuf[i++] = buf[k]; /* and then deposit it. */ - obuf[i] = NUL; /* Keep it null-terminated */ - continue; - } - z = 8 - (i % 8); /* It's a tab, expand it. */ - if (z == 0) z = 8; - for (j = 0; j < z && i < LINBUFSIZ; j++) { -#ifdef UNICODE - if (ucs2 && !ucsorder) - obuf[i++] = NUL; -#endif /* UNICODE */ - obuf[i++] = ' '; -#ifdef UNICODE - if (ucs2 && ucsorder) - obuf[i++] = NUL; -#endif /* UNICODE */ - } - obuf[i++] = NUL; - obuf[i] = NUL; - } - obuf[width] = NUL; /* Now truncate at given width. */ -#ifdef COMMENT - /* This doesn't work for UCS-2 because it contains NULs */ - ckstrncpy(buf,obuf,TYPBUFL); /* and copy it back (again?) */ -#else - memcpy((char *)buf,(char *)obuf,i); /* Copy it back */ -#endif /* COMMENT */ - len = (i > width) ? width : i; /* Spare us another strlen()... */ - } - if (tailing) { /* If /TAIL:n... */ - k = lines % head; /* save this line in circular buffer */ - if (!counting) { - if (tail[k]) free(tail[k]); - tail[k] = malloc(len+2); - if (!tail[k]) { - printf("?Memory allocation failure\n"); - goto xdotype; - } - memcpy(tail[k],buf,len); - tlen[k] = len; - continue; - } - } - if (counting) /* If only counting */ - continue; /* we're done with this line */ - - if (paging) { /* Displaying this line... */ - int u; - u = len; /* Length in BYTES */ - if (ucs2) /* If outputting in UCS-2 */ - u /= 2; /* convert length to CHARACTERS */ - x = (u / cmd_cols) + 1; /* Crudely allow for wrap */ - if (cmd_rows > 0 && cmd_cols > 0) - n += x; /* This assumes terminal will wrap */ - } -#ifdef KUI - if ( gui ) { - int i; - unsigned short * uch = (unsigned short *)buf; - for ( i=0; i 0 && ofp == stdout) { /* Pause at end of screen */ - if (cmd_rows > 0 && cmd_cols > 0) { - if (n > cmd_rows - 3) { - if (!askmore()) - goto xdotype; - else - n = 0; - } - } - } -#endif /* CK_TTGWSIZ */ - } - - xdotype: - if (counting) { - fprintf(ofp, - "%s: %d line%s\n",file,typ_lines,typ_lines == 1 ? "" : "s"); - if (pat) - fprintf(ofp, - "%s: %d match%s\n",pat,typ_mtchs,typ_mtchs == 1 ? "" : "es"); - goto xxdotype; - } - if (tailing && tail) { /* Typing tail of file? */ - if (lines < head) { /* Yes, show the lines we saved */ - k = 0; /* Show all lines */ - } else { /* More lines than tail number */ - lines = k; /* Last line to show */ - k++; /* First line to show */ - if (k >= head) - k = 0; - } - n = first; /* Output line counter */ - for (i = k ;; i++) { /* Loop thru circular buffer */ -#ifndef MAC - if (typ_int) { /* Interrupted? */ - printf("^C...\n"); /* Print message */ - goto xxdotype; - } -#endif /* MAC */ - j = i % head; /* Index of this line */ - s = tail[j]; /* Point to line to display */ - if (!s) /* (shouldn't happen...) */ - break; - if (paging) { /* Crudely allow for line wrap */ - x = tlen[j]; - if (ucs2) x /= 2; - x = x / cmd_cols + 1; - if (cmd_rows > 0 && cmd_cols > 0) - n += x; - } - typeline(s,tlen[j],outcs,ofp); /* Display this line */ - if (paging && ofp == stdout) { /* Pause at end of screen */ - if (cmd_rows > 0 && cmd_cols > 0) { - if (n > cmd_rows - 3) { - if (!askmore()) - break; - else - n = 0; - } - } - } - tail[j] = NULL; - free(s); /* Free the line */ - if (i % head == lines) /* When to stop */ - break; - } - free((char *)tail); /* Free the list */ - tail = NULL; - if (tlen) free((char *)tlen); - tlen = NULL; - } - -/* Come here when finished or on SIGINT */ - - xxdotype: -#ifndef AMIGA -#ifndef MAC - signal(SIGINT,oldsig); /* Put old signal action back. */ -#endif /* MAC */ -#endif /* AMIGA */ - if (tailing && tail) { - for (i = 0; i < head; i++) { /* Free each line. */ - if (tail[i]) - free(tail[i]); - } - free((char *)tail); /* Free list pointer */ - if (tlen) - free((char *)tlen); - } - x = zclose(ZIFILE); /* Done, close the input file */ - if (ofp != stdout) { /* Close any output file */ - if (ofp) fclose(ofp); - ofp = stdout; - } - binary = save; /* Restore text/binary mode */ -#ifdef UNICODE - ucsbom = ucsbom_sav; /* Restore BOM usage */ -#endif /* UNICODE */ - -#ifdef KUI - if ( gui ) - gui_text_popup_wait(-1); /* Wait for user to close the dialog */ -#endif /* KUI */ - return(rc); -} - -/* GREP command */ - -#define GREP_CASE 0 /* /CASE */ -#define GREP_COUN 1 /* /COUNT */ -#define GREP_DOTF 2 /* /DOTFILES */ -#define GREP_NAME 3 /* /NAMEONLY */ -#define GREP_NOBK 4 /* /NOBACKUP */ -#define GREP_NODO 5 /* /NODOTFILES */ -#define GREP_NOLI 6 /* /NOLIST */ -#define GREP_NOMA 7 /* /INVERT = /NOMATCH */ -#define GREP_NOPA 8 /* /NOPAGE */ -#define GREP_NUMS 9 /* /LINENUMBERS */ -#define GREP_PAGE 10 /* /PAGE */ -#define GREP_RECU 11 /* /RECURSIVE */ -#define GREP_TYPE 12 /* /TYPE: */ -#define GREP_OUTP 13 /* /OUTPUTFILE: */ - -static struct keytab greptab[] = { - { "/count", GREP_COUN, CM_ARG }, - { "/dotfiles", GREP_DOTF, 0 }, - { "/linenumbers", GREP_NUMS, 0 }, - { "/nameonly", GREP_NAME, 0 }, - { "/nobackupfiles",GREP_NOBK, 0 }, - { "/nocase", GREP_CASE, 0 }, - { "/nodotfiles", GREP_NODO, 0 }, - { "/nolist", GREP_NOLI, 0 }, - { "/nomatch", GREP_NOMA, 0 }, - { "/nopage", GREP_NOPA, 0 }, - { "/output", GREP_OUTP, CM_ARG }, - { "/page", GREP_PAGE, 0 }, - { "/quiet", GREP_NOLI, CM_INV }, -#ifdef RECURSIVE - { "/recursive", GREP_RECU, 0 }, -#endif /* RECURSIVE */ - { "/type", GREP_TYPE, CM_ARG }, - { "", 0, 0 } -}; -static int ngreptab = sizeof(greptab)/sizeof(struct keytab)-1; - -int -dogrep() { - int match, x, y, fc, getval, mc = 0, count = 0, bigcount = 0; - int fline = 0, sline = 0, wild = 0, len = 0; - int xmode = -1, scan = 0; - char c, name[CKMAXPATH+1], outfile[CKMAXPATH+1], *p, *s, *cv = NULL; - FILE * fp = NULL; - - int /* Switch values and defaults */ - gr_coun = 0, - gr_name = 0, - gr_nobk = 0, - gr_case = 1, - gr_noli = 0, - gr_noma = 0, - gr_nums = 0, - gr_page = xaskmore; - - struct FDB sw, fl; - - g_matchdot = matchdot; /* Save global matchdot setting */ - outfile[0] = NUL; - - if (ofp != stdout) { /* In case of previous interruption */ - if (ofp) fclose(ofp); - ofp = stdout; - } - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "String or pattern to search for, or switch", - "", /* default */ - "", /* addtl string data */ - ngreptab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - greptab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Anything that doesn't match */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, /* xxstring */ - NULL, - NULL - ); - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - if ((cmresult.nresult != GREP_COUN) && !getval && - (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (cmresult.nresult) { - case GREP_COUN: { - gr_coun++; - if (getval) { - if ((x = cmfld("Variable for result","",&s,NULL)) < 0) - return(x); - makestr(&cv,s); - } - break; - } - case GREP_CASE: gr_case=0; break; - case GREP_NAME: gr_name++; gr_noli=0; break; - case GREP_NOBK: gr_nobk++; break; - case GREP_NOLI: gr_noli++; gr_name=0; gr_nums=0; break; - case GREP_NOMA: gr_noma++; break; - case GREP_NOPA: gr_page=0; break; - case GREP_NUMS: gr_nums++; gr_noli=0; break; - case GREP_PAGE: gr_page++; gr_noli=0; break; - case GREP_NODO: - matchdot = 0; - break; - case GREP_DOTF: - matchdot = 1; - break; -#ifdef RECURSIVE - case GREP_RECU: - recursive = 1; - break; -#endif /* RECURSIVE */ - case GREP_TYPE: { - extern struct keytab txtbin[]; - if ((x = cmkey(txtbin,3,"","",xxstring)) < 0) - return(x); - if (x == 2) { /* ALL */ - xmode = -1; - } else { /* TEXT or BINARY only */ - xmode = x; - scan = 1; - } - break; - } - case GREP_OUTP: /* Send output to file */ - if ((x = cmofi("File for GREP'd lines","",&s,xxstring)) < 0) - return(x); - ckstrncpy(outfile,s,CKMAXPATH); - break; - } - } - if (outfile[0]) { - ofp = fopen(outfile,"w"); /* Open output file */ - if (!ofp) { - printf("?Can't open output file %s: %s\n",outfile,ck_errstr()); - ofp = stdout; - return(-9); - } - gr_page = 0; - } - s = cmresult.sresult; - s = brstrip(s); /* Strip braces from pattern */ - if (!*s) { - printf("?Pattern required\n"); - return(-9); - } - ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Save pattern */ - if ((x = cmifi("File(s) to search","",&s,&wild,xxstring)) < 0) { - if (x == -3) { - printf("?File specification required\n"); - x = -9; - } - return(x); - } - s = brstrip(s); /* Strip braces from filename */ -#ifndef ZXREWIND - ckstrncpy(line,s,LINBUFSIZ); -#endif /* ZXREWIND */ - if ((y = cmcfm()) < 0) - return(y); - - if (gr_page > -1) - xaskmore = gr_page; /* Paging... */ - - p = tmpbuf; /* Point to pattern */ -#ifdef COMMENT -/* Now this is done in ckmatch */ - if (*p == '^') { /* '^' anchors pattern to beginning */ - p++; - } else if (*p != '*') { /* Otherwise prepend implied '*' */ - tmpbuf[0] = '*'; - p = tmpbuf; - } - x = strlen(p); /* Get length of result */ - if (x > 0 && x < TMPBUFSIZ) { /* '$' at end anchors pattern to end */ - if (p[x-1] == '$') { - p[x-1] = NUL; - } else if (p[x-1] != '*') { - p[x] = '*'; - p[x+1] = NUL; - } - } -#endif /* COMMENT */ - debug(F111,"grep pat",p,x); - -#ifdef ZXREWIND - fc = zxrewind(); /* Rewind the file list */ -#else - { - int flags = ZX_FILONLY; /* Expand file list */ - if (matchdot) flags |= ZX_MATCHDOT; - if (recursive) flags |= ZX_RECURSE; - fc = nzxpand(line,flags); - } -#endif /* ZXREWIND */ -#ifdef UNIX - sh_sort(mtchs,NULL,fc,0,0,filecase); -#endif /* UNIX */ - - debug(F101,"grep cmd_rows","",cmd_rows); - debug(F101,"grep cmd_cols","",cmd_cols); - - while (1) { /* Loop for each file */ - znext(name); /* Get next file */ - if (!name[0]) /* No more, done */ - break; - if (gr_nobk) /* Skipping backup files? */ - if (ckmatch("*.~[1-9]*~",name,1,1)) /* Backup file? */ - continue; /* Yes, skip */ - if (scan) { /* /TYPE: given? */ - switch (scanfile(name,&y,nscanfile)) { /* Yes, scan the file */ - case FT_BIN: - if (xmode != 1) - continue; - break; - case FT_TEXT: - case FT_7BIT: - case FT_8BIT: -#ifdef UNICODE - case FT_UTF8: - case FT_UCS2: -#endif /* UNICODE */ - if (xmode != 0) - continue; - } - } - fp = fopen(name,"r"); /* Open */ - if (!fp) /* Can't */ - continue; /* Skip */ - count = 0; /* Match count, this file */ - fline = 0; /* Line count, this file */ - while (1) { /* Loop for each line */ - if (fgets(line,LINBUFSIZ,fp) == NULL) { /* Get next line */ - fclose(fp); - fp = NULL; - debug(F100,"GREP EOF","",0); - break; - } - fline++; /* Count this line */ - line[LINBUFSIZ] = NUL; /* Make sure it's terminated */ - debug(F111,"GREP",line,fline); - len = (int)strlen(line); /* Get length */ - while (len > 0 && (line[len-1] == '\n' || line[len-1] == '\r')) - line[--len] = NUL; /* Chop off terminators */ - match = ckmatch(p,line,gr_case,1+4); /* Match against pattern */ - if (gr_noma) /* Invert match sense if requested */ - match = !match; - if (match) { /* Have a matching line */ - mc++; /* Total match count */ - count++; /* Match count this file */ - if (gr_name) { /* Don't care how many lines match */ - fclose(fp); /* Close the file */ - fp = NULL; /* and quit the line-reading loop. */ - break; - } - if (gr_coun || gr_noli) /* Not listing each line */ - continue; /* so don't print anything now. */ - if (wild) { /* If searching multiple files */ - fprintf(ofp,"%s:",name); /* print filename. */ - len += (int)strlen(name) + 1; - } - if (gr_nums) { /* If line numbers wanted */ - char nbuf[32]; - len += ckmakmsg(nbuf,32,ckitoa(fline),":",NULL,NULL); - fprintf(ofp,"%s",nbuf); - } - if (cmd_rows > 0 && cmd_cols > 0) - sline += (len / cmd_cols) + 1; - fprintf(ofp,"%s\n",line); /* Print the line. */ - if (sline > cmd_rows - 3) { - if (!askmore()) goto xgrep; else sline = 0; - } - } - } - if (!gr_noli) { /* If not not listing... */ - x = 0; - if (gr_coun) { /* Show match count only */ - fprintf(ofp,"%s:%d\n",name,count); - x++; - } else if (gr_name && count > 0) { /* Show name only */ - fprintf(ofp,"%s\n",name); - x++; - } - if (x > 0) { - if (++sline > cmd_rows - 3) { - if (!askmore()) goto xgrep; else sline = 0; - } - } - } - bigcount += count; /* Overall count */ - } - xgrep: -#ifndef NOSPL - if (gr_coun && cv) { /* /COUNT:blah */ - addmac(cv,ckitoa(bigcount)); /* set the variable */ - makestr(&cv,NULL); /* free this */ - } -#endif /* NOSPL */ - if (fp) fclose(fp); /* close input file if still open */ - if (ofp != stdout) { /* Close any output file */ - if (ofp) fclose(ofp); - ofp = stdout; - } - return(success = mc ? 1 : 0); -} - -/* System-independent directory */ - -static char ** dirlist = NULL; -static int ndirlist = 0; - -static VOID -freedirlist() { - if (dirlist) { - int i; - for (i = 0; i < ndirlist; i++) { - if (dirlist[i]) - free(dirlist[i]); - } - free((char *)dirlist); - dirlist = NULL; - } - ndirlist = 0; -} - -static struct keytab dirswtab[] = { /* DIRECTORY command switches */ - { "/after", DIR_AFT, CM_ARG }, - { "/all", DIR_ALL, 0 }, -#ifndef NOSPL - { "/array", DIR_ARR, CM_ARG }, -#endif /* NOSPL */ - { "/ascending", DIR_ASC, 0 }, - { "/backup", DIR_BUP, 0 }, - { "/before", DIR_BEF, CM_ARG }, - { "/brief", DIR_BRF, 0 }, - { "/descending", DIR_DSC, CM_INV }, - { "/directories", DIR_DIR, 0 }, - { "/dotfiles", DIR_DOT, 0 }, - { "/englishdate", DIR_DAT, 0 }, - { "/except", DIR_EXC, CM_ARG }, - { "/files", DIR_FIL, 0 }, - { "/heading", DIR_HDG, 0 }, - { "/isodate", DIR_ISO, 0 }, - { "/larger-than", DIR_LAR, CM_ARG }, -#ifdef CKSYMLINK - { "/followlinks", DIR_LNK, 0 }, -#endif /* CKSYMLINK */ - { "/message", DIR_MSG, CM_ARG }, - { "/nobackupfiles",DIR_NOB, 0 }, - { "/nodotfiles", DIR_NOD, 0 }, -#ifdef CKSYMLINK - { "/nofollowlinks",DIR_NLK, 0 }, -#endif /* CKSYMLINK */ - { "/noheading", DIR_NOH, 0 }, - { "/nomessage", DIR_NOM, 0 }, -#ifdef CK_TTGWSIZ - { "/nopage", DIR_NOP, 0 }, -#endif /* CK_TTGWSIZ */ -#ifdef RECURSIVE - { "/norecursive", DIR_NOR, 0 }, -#else -#ifdef VMS - { "/norecursive", DIR_NOR, 0 }, -#else -#ifdef datageneral - { "/norecursive", DIR_NOR, 0 }, -#endif /* datageneral */ -#endif /* VMS */ -#endif /* RECURSIVE */ - { "/nosort", DIR_NOS, 0 }, - { "/not-after", DIR_NAF, CM_ARG }, - { "/not-before", DIR_NBF, CM_ARG }, - { "/not-since", DIR_NAF, CM_INV|CM_ARG }, - { "/noxfermode", DIR_NOT, 0 }, - { "/output", DIR_OUT, CM_ARG }, -#ifdef CK_TTGWSIZ - { "/page", DIR_PAG, 0 }, -#endif /* CK_TTGWSIZ */ -#ifdef RECURSIVE - { "/recursive", DIR_REC, 0 }, -#else -#ifdef VMS - { "/recursive", DIR_REC, 0 }, -#else -#ifdef datageneral - { "/recursive", DIR_REC, 0 }, -#endif /* datageneral */ -#endif /* VMS */ -#endif /* RECURSIVE */ - { "/reverse", DIR_DSC, 0 }, - { "/since", DIR_AFT, CM_ARG|CM_INV }, - { "/smaller-than",DIR_SMA, CM_ARG }, - { "/sort", DIR_SRT, CM_ARG }, - { "/summary", DIR_SUM, 0 }, - { "/type", DIR_BIN, CM_ARG }, - { "/xfermode", DIR_TYP, 0 }, - { "/verbose", DIR_VRB, 0 }, - { "",0,0 } -}; -static int ndirswtab = (sizeof(dirswtab) / sizeof(struct keytab)) - 1; - -static struct keytab dirsort[] = { /* DIRECTORY /SORT: options */ - { "date", DIRS_DT, 0 }, - { "name", DIRS_NM, 0 }, - { "size", DIRS_SZ, 0 } -}; -static int ndirsort = (sizeof(dirsort) / sizeof(struct keytab)); - -static int dir_date = -1; /* Option defaults (-1 means none) */ -static int dir_page = -1; -static int dir_verb = 1; -static int dir_msg = -1; -#ifdef VMS -static int dir_sort = -1; /* Names are already sorted in VMS */ -static int dir_rvrs = -1; -#else -static int dir_sort = 1; /* Sort by default */ -static int dir_rvrs = 0; /* Not in reverse */ -#endif /* VMS */ -static int dir_skey = DIRS_NM; /* By name */ -#ifdef RECURSIVE -static int dir_recu = -1; -#endif /* RECURSIVE */ -static int dir_mode = -1; -static int dir_show = -1; /* Show all files by default */ -int dir_dots = -1; /* Except dot files */ -int dir_back = 1; -int dir_head = 0; -static char * dirmsg = NULL; -static int dirmsglen = 0; - -#ifndef NOSHOW -VOID -showdiropts() { - int x = 0; - extern int optlines; - prtopt(&optlines,"DIRECTORY"); - if (dir_show > 0) { - prtopt(&optlines,(dir_show == 1) ? "/FILES" : - ((dir_show == 2) ? "/DIRECTORIES" : "/ALL")); - x++; - } else { - prtopt(&optlines,"/ALL"); - x++; - } - if (dir_verb > -1) { - prtopt(&optlines,dir_verb ? "/VERBOSE" : "/BRIEF"); - x++; - } - if (dir_page > -1) { - prtopt(&optlines,dir_page ? "/PAGE" : "/NOPAGE"); - x++; - } - if (dir_date > -1) { - prtopt(&optlines,dir_date ? "/ENGLISHDATE" : "/ISODATE"); - x++; - } - if (dir_dots > -1) { - prtopt(&optlines,dir_dots ? "/DOTFILES" : "/NODOTFILES"); - x++; - } - if (dir_back > -1) { - prtopt(&optlines,dir_back ? "/BACKUP" : "/NOBACKUP"); - x++; - } - if (dir_head > -1) { - prtopt(&optlines,dir_head ? "/HEADING" : "/NOHEADING"); - x++; - } -#ifdef RECURSIVE - if (dir_recu > -1) { - prtopt(&optlines,dir_recu ? "/RECURSIVE" : "/NORECURSIVE"); - x++; - } -#endif /* RECURSIVE */ - if (dir_mode > -1) { - prtopt(&optlines,dir_mode ? "/XFERMODE" : "/NOXFERMODE"); - x++; - } - if (dir_sort == 0) { - x++; - prtopt(&optlines,"/NOSORT "); - } else if (dir_sort > 0) { - x++; - if (dir_skey == DIRS_NM) s = "/SORT:NAME"; - else if (dir_skey == DIRS_SZ) s = "/SORT:SIZE"; - else if (dir_skey == DIRS_DT) s = "/SORT:DATE"; - prtopt(&optlines,s); - } - if (dir_rvrs > -1) { - prtopt(&optlines,dir_rvrs ? "/REVERSE" : "/ASCENDING"); - x++; - } - if (dir_msg > -1) { - if (dir_msg == 0) { - prtopt(&optlines,"/NOMESSAGE"); - } else { - ckmakmsg(tmpbuf,TMPBUFSIZ,"/MESSAGE:{",dirmsg,"}",NULL); - prtopt(&optlines,tmpbuf); - } - x++; - } - if (!x) prtopt(&optlines,"(no options set)"); - prtopt(&optlines,""); -} -#endif /* NOSHOW */ - -int -setdiropts() { /* Set DIRECTORY option defaults */ - int xb = -1, xv = -1, xp = -1, xd = -1, xh = -1, xf = -1; - int xk = -1, xr = -1, xs = -1, xx = -1, xm = -1, xa = -1, xg = -1; - int getval; - char c; - while (1) { - if ((y = cmswi(dirswtab,ndirswtab,"Switch","",xxstring)) < 0) { - if (y == -3) - break; - else - return(y); - } - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (y) { - case DIR_BRF: xv = 0; break; - case DIR_VRB: xv = 1; break; - case DIR_PAG: xp = 1; break; - case DIR_NOP: xp = 0; break; - case DIR_ISO: xd = 0; break; - case DIR_DAT: xd = 1; break; - case DIR_HDG: xh = 1; break; - case DIR_NOH: xh = 0; break; - case DIR_DOT: xf = 1; break; - case DIR_NOD: xf = 0; break; - case DIR_ALL: xa = 3; break; - case DIR_DIR: xa = 2; break; - case DIR_FIL: xa = 1; break; - case DIR_SRT: - x = DIRS_NM; - if (getval) - if ((x = cmkey(dirsort,ndirsort,"Sort key","name",xxstring)) < 0) - return(x); - xk = x; - xs = 1; - break; - case DIR_NOS: xs = 0; break; - case DIR_ASC: xx = 0; break; - case DIR_DSC: xx = 1; break; - case DIR_REC: xr = 1; break; - case DIR_NOR: xr = 0; break; - case DIR_TYP: xm = 1; break; - case DIR_NOT: xm = 0; break; - case DIR_BUP: xb = 1; break; - case DIR_NOB: xb = 0; break; - case DIR_NOM: xg = 0; break; - case DIR_MSG: - if (getval) - if ((x = cmfld("Message to append to each line", - "", - &s, - xxstring - )) < 0) - return(x); - xg = 1; - ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ); - break; - default: - printf("?This option can not be set\n"); - return(-9); - } - } - if ((x = cmcfm()) < 0) /* Get confirmation */ - return(x); - if (xv > -1) dir_verb = xv; /* Confirmed, save defaults */ - if (xp > -1) dir_page = xp; - if (xd > -1) dir_date = xd; - if (xh > -1) dir_head = xh; - if (xs > -1) dir_sort = xs; - if (xk > -1) dir_skey = xk; - if (xx > -1) dir_rvrs = xx; - if (xf > -1) dir_dots = xf; - if (xa > -1) dir_show = xa; - if (xm > -1) dir_mode = xm; - if (xb > -1) dir_back = xb; -#ifdef RECURSIVE - if (xr > -1) dir_recu = xr; -#endif /* RECURSIVE */ - if (xg > -1) dir_msg = xg; - if (xg > 0) - makestr(&dirmsg,tmpbuf); - return(success = 1); -} - -int -domydir() { /* Internal DIRECTORY command */ - extern char *months[]; -#ifdef VMS - _PROTOTYP( char * zrelname, (char *,char *) ); - char * cdp = NULL; -#endif /* VMS */ - - char name[CKMAXPATH+1], outfile[CKMAXPATH+1], *p = NULL, c = NUL; - char linebuf[CKMAXPATH+256]; - char * mstr = NULL, * dstr = NULL, * s2 = NULL; - long len = 0, ndirs = 0, nfiles = 0, nbytes = 0, nmatches = 0; - int verbose = 0, wild = 0, page = 0, n = 0, engdate = 0, summary = 0; - int heading = 0, xsort = 0, reverse = 0, sortby = 0, msg = 0; - int k, i = 0, x = 0, nx = 0, skey = 0, dlen = 0, itsadir = 0; - int show = 3, xfermod = 0, backup = 1, rc = 0, getval = 0; - int fs = 0; - int multiple = 0; - int cmifn1 = 1, cmifn2 = 0; - long minsize = -1L, maxsize = -1L; - struct FDB sw, fi, fl; - char dbuf[32], xbuf[32]; - -#ifndef NOSPL - char array = NUL; - char ** ap = NULL; -#endif /* NOSPL */ - char - * dir_aft = NULL, - * dir_bef = NULL, - * dir_naf = NULL, - * dir_nbf = NULL, - * dir_exc = NULL; - char * xlist[16]; - - g_matchdot = matchdot; /* Save global matchdot setting */ - nolinks = 2; /* (it should already be 2) */ - outfile[0] = NUL; /* No output file yet */ - - if (ofp != stdout) { /* In case of previous interruption */ - if (ofp) fclose(ofp); - ofp = stdout; - } - for (i = 0; i < 16; i++) xlist[i] = NULL; - - name[0] = NUL; - freedirlist(); /* In case not freed last time */ - page = dir_page > -1 ? dir_page : xaskmore; /* Set option defaults */ - engdate = dir_date > -1 ? dir_date : 0; - verbose = dir_verb > -1 ? dir_verb : 1; - heading = dir_head > -1 ? dir_head : 0; - xsort = dir_sort > -1 ? dir_sort : 0; - sortby = dir_skey > -1 ? dir_skey : 0; - reverse = dir_rvrs > -1 ? dir_rvrs : 0; - msg = dir_msg > -1 ? dir_msg : 0; -#ifdef UNIXOROSK - if (dir_dots > -1) matchdot = dir_dots; -#endif /* UNIXOROSK */ - xfermod = dir_mode > -1 ? dir_mode : 0; - backup = dir_back > -1 ? dir_back : 1; -#ifdef RECURSIVE - recursive = dir_recu > -1 ? dir_recu : 0; -#endif /* RECURSIVE */ - show = dir_show > -1 ? dir_show : 3; - -#ifdef CK_TTGWSIZ -#ifdef OS2 - ttgcwsz(); /* Screen length for more-prompting */ -#else /* OS2 */ - /* Check whether window size changed */ - if (ttgwsiz() > 0) { - if (tt_rows > 0 && tt_cols > 0) { - cmd_rows = tt_rows; - cmd_cols = tt_cols; - } - } -#endif /* OS2 */ -#endif /* CK_TTGWSIZ */ - - diractive = 1; - cmifn1 = nolinks | 1; /* 1 = files or directories */ - cmifn2 = 0; /* 0 = not directories only */ - - again: - - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Enter or Return to confirm the command, or\n\ - file specification, or switch", - "", /* default */ - "", /* addtl string data */ - ndirswtab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - dirswtab, /* Keyword table */ - &fi /* Pointer to next FDB */ - ); - cmfdbi(&fi, /* 2nd FDB - filespec to match */ - _CMIFI, /* fcode */ - "File specification", /* hlpmsg */ -#ifdef datageneral - "+", /* Default filespec is wildcard */ -#else /* that matches all files... */ -#ifdef VMS - "*.*", -#else - "*", -#endif /* VMS */ -#endif /* datageneral */ - "", /* addtl string data */ - cmifn1, - cmifn2, /* 1 = only dirs; 0 files or dirs */ - xxstring, - NULL, - &fl - ); - cmfdbi(&fl, /* Anything that doesn't match */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - debug(F101,"domydir cmfdb","",x); - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (k = cmresult.nresult) { - case DIR_BRF: verbose = 0; break; - case DIR_VRB: verbose = 1; break; -#ifdef CK_TTGWSIZ - case DIR_PAG: page = 1; break; - case DIR_NOP: page = 0; break; -#endif /* CK_TTGWSIZ */ - case DIR_ISO: engdate = 0; break; - case DIR_DAT: engdate = 1; break; - case DIR_HDG: heading = 1; break; - case DIR_NOH: heading = 0; break; -#ifdef UNIXOROSK - case DIR_DOT: matchdot = 1; break; - case DIR_NOD: matchdot = 0; break; -#endif /* UNIXOROSK */ - case DIR_ALL: - show = 3; - cmifn1 |= 1; - cmifn2 = 0; - goto again; - case DIR_DIR: - show = 2; - cmifn1 |= 1; - cmifn2 = 1; - goto again; - case DIR_FIL: - show = 1; - cmifn1 &= ~(1); - cmifn2 = 0; - goto again; - case DIR_SRT: - x = DIRS_NM; - if (c == ':' || c == '=') - if ((x = cmkey(dirsort,ndirsort,"Sort key","name",xxstring)) < 0) - return(x); - xsort = 1; - sortby = x; - break; - - case DIR_BUP: backup = 1; fs++; break; - case DIR_NOB: backup = 0; fs++; break; - - case DIR_NOS: xsort = 0; break; - case DIR_ASC: reverse = 0; break; - case DIR_DSC: reverse = 1; break; -#ifdef RECURSIVE - case DIR_REC: recursive = 1; diractive = 1; break; - case DIR_NOR: recursive = 0; diractive = 0; break; -#endif /* RECURSIVE */ - case DIR_TYP: xfermod = 1; break; - case DIR_NOT: xfermod = 0; break; - -#ifdef CKSYMLINK - case DIR_LNK: /* Follow links */ - nolinks = 0; - cmifn1 &= ~(2); - goto again; - case DIR_NLK: /* Don't follow links */ - nolinks = 2; - cmifn1 &= ~(2); - goto again; -#endif /* CKSYMLINK */ - - case DIR_NOM: msg = 0; break; - case DIR_MSG: - if (c == ':' || c == '=') - if ((x = cmfld("Message to append to each line", - "", - &s, - xxstring - )) < 0) - return(x); - msg = 1; - ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ); - break; - - case DIR_SMA: - case DIR_LAR: - if (!getval) break; - if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0) - return(x); - fs++; - show = 1; - switch (cmresult.nresult) { - case DIR_SMA: minsize = y; break; - case DIR_LAR: maxsize = y; break; - } - break; - -#ifndef NOSPL - case DIR_ARR: - if (c != ':' && c != '=') { - printf("?Array name required\n"); - return(-9); - } - if ((x = cmfld("Array name (a single letter will do)", - "", - &s, - NULL - )) < 0) { - if (x == -3) { - printf("?Array name required\n"); - return(-9); - } else - return(x); - } - if (!*s) { - printf("?Array name required\n"); - return(-9); - } - s2 = s; - if (*s == CMDQ) s++; - if (*s == '&') s++; - if (!isalpha(*s)) { - printf("?Bad array name - \"%s\"\n",s2); - return(-9); - } - array = *s++; - if (isupper(array)) array = tolower(array); - if (*s && (*s != '[' || *(s+1) != ']')) { - printf("?Bad array name - \"%s\"\n",s2); - return(-9); - } - break; -#endif /* NOSPL */ - case DIR_AFT: - case DIR_BEF: - case DIR_NAF: - case DIR_NBF: - if (!getval) break; - if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) { - if (x == -3) { - printf("?Date-time required\n"); - rc = -9; - } else - rc = x; - goto xdomydir; - } - fs++; - switch (k) { - case DIR_AFT: makestr(&dir_aft,s); break; - case DIR_BEF: makestr(&dir_bef,s); break; - case DIR_NAF: makestr(&dir_naf,s); break; - case DIR_NBF: makestr(&dir_nbf,s); break; - } - break; - case DIR_EXC: - if (!getval) break; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Pattern required\n"); - rc = -9; - } else - rc = x; - goto xdomydir; - } - fs++; - makestr(&dir_exc,s); - break; - - case DIR_SUM: - summary = 1; break; - - case DIR_BIN: { - extern struct keytab txtbin[]; - extern int xfiletype; - if (!getval) break; - if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0) { - rc = x; - goto xdomydir; - } - if (x == 2) { - xfiletype = -1; - } else { - xfiletype = x; - fs = 1; - } - break; - } - case DIR_OUT: - if ((x = cmofi("File for directory listing","",&s,xxstring)) < 0) - return(x); - ckstrncpy(outfile,s,CKMAXPATH+1); - break; - - default: - printf("?Sorry, not implemented yet - \"%s\"\n", atmbuf); - goto xdomydir; - } - } - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Safe copy of filespec */ - -/* ^^^ START MULTIPLE */ - - while (1) { - x = cmfld("Another filespec or Enter","",&s,xxstring); - if (x == -3) - break; - if (x < 0) - return(x); - ckstrncat(line,",",LINBUFSIZ); - ckstrncat(line,s,LINBUFSIZ); - multiple++; - } - ckmakmsg(tmpbuf,TMPBUFSIZ,"{",line,"}",NULL); - ckstrncpy(line,tmpbuf,LINBUFSIZ); - cmresult.nresult = 1; - cmresult.fcode = _CMIFI; - -/* ^^^ END MULTIPLE */ - - s = line; - - if ((x = cmcfm()) < 0) /* Get confirmation */ - return(x); - if (cmresult.fcode != _CMIFI) { /* Nothing matched */ - char * m; - if (*s == '/') -#ifdef UNIXOROSK - m = "does not match switch or name of accessible file"; -#else -#ifdef OS2 - m = "does not match switch or name of accessible file"; -#else - m = "no switches match"; -#endif /* OS2 */ -#endif /* UNIXOROSX */ - else - m = "not found or not accessible"; - printf("\"%s\" - %s\n",s,m); - rc = -9; - goto xdomydir; - } - wild = cmresult.nresult; /* Wildcard was given? */ - debug(F111,"domydir cmifi2",s,wild); - - if (outfile[0]) { - ofp = fopen(outfile,"w"); /* Open output file */ - if (!ofp) { - printf("?Can't open output file %s: %s\n",outfile,ck_errstr()); - ofp = stdout; - return(-9); - } - page = 0; - } - -#ifdef OS2 - if (!wild) { - if (zchki(s) == -2) { /* Found a directory */ - p = s + (int)strlen(s) - 1; /* Yes */ - if (*p == '\\' || *p == '/') - strcat(s, "*"); - else if (*p == ':') - strcat(s, "./*"); - else - strcat(s, "/*"); - wild = 1; /* Now it's wild */ - } - } -#else - if (!wild) if (isdir(s)) { /* Is it a directory? */ - p = s + (int)strlen(s) - 1; /* Yes */ -#ifdef VMS - { - /* Convert from FOO.DIR;1 to [x.FOO] if necessary */ - char buf[CKMAXPATH+1]; - debug(F000,"domydir directory 0",s,*p); - if (cvtdir(s,buf,CKMAXPATH) > 0) - ckstrncpy(line,buf,LINBUFSIZ); - } -#endif /* VMS */ - debug(F000,"domydir directory 1",s,*p); -#ifdef VMS - if (*p == ']' || *p == '>' || *p == ':') - strcat(s, "*.*"); -#else -#ifdef datageneral - if (*p == ':') - strcat(s, "+"); - else - strcat(s, ":+"); -#else -#ifdef STRATUS - if (*p == '>') - strcat(s, "*"); - else - strcat(s, ">*"); -#endif /* STRATUS */ -#endif /* datageneral */ -#endif /* VMS */ - wild = 1; /* Now it's wild */ - debug(F000,"domydir directory 2",s,*p); - } -#endif /* OS2 */ - -#ifdef ZXREWIND -/* cmifi() already called nzxpand so we can just re-use the same list. */ - if (!multiple) { - x = zxrewind(); /* Rewind the list */ - debug(F111,"domydir zxrewind",s,x); - } else { -#endif /* ZXREWIND */ - nzxopts = (show == ZX_DIRONLY) ? ZX_DIRONLY : - (show == ZX_FILONLY ? ZX_FILONLY : 0); - if (matchdot) nzxopts |= ZX_MATCHDOT; - if (recursive) nzxopts |= ZX_RECURSE; - x = nzxpand(s,nzxopts); /* Expand file list */ - debug(F111,"domydir nzxpand",s,x); -#ifdef ZXREWIND - } -#endif /* ZXREWIND */ - -#ifndef NOSPL - if (array) { - int n, xx; - n = (x < 0) ? 0 : x; - if ((xx = dclarray(array,n)) < 0) { - printf("?Array declaration failure\n"); - rc = -9; - goto xdomydir; - } - array = xx; - ap = a_ptr[array]; - if (n < 1) { - rc = 0; - goto xdomydir; - } - } else -#endif /* NOSPL */ - if (x < 1) { -#ifdef CKROOT - extern int ckrooterr; - if (ckrooterr) - printf("?Off limits: %s\n",s); - else -#endif /* CKROOT */ - if (x == 0 && isdir(s)) - printf("?Empty directory - \"%s\"\n", s); - else - printf("?%s %s match - \"%s\"\n", - (x == 0) ? "No" : "Too many", - (show == 2) ? "directories" : "files", - s - ); - rc = -9; - goto xdomydir; - } - nx = x; /* Remember how many files */ - - if (msg) { - makestr(&dirmsg,tmpbuf); - dirmsglen = strlen(tmpbuf); - } - -#ifdef VMS - cdp = zgtdir(); /* Get current directory */ - debug(F110,"domydir VMS zgtdir",cdp,0); -#endif /* VMS */ - - if (xsort && verbose) { /* If sorting, allocate space */ - if (!(dirlist = (char **) malloc((x + 1) * sizeof(char **)))) { - if (!quiet) { - printf("* Warning: Failure to allocate memory for sorting.\n"); - printf("* Will proceed without sorting...\n"); - } - xsort = 0; - } - debug(F101,"domydir sort malloc","",xsort); - } - - /* Display the listing */ - -#ifndef NOSPL - if (array) /* Storing instead of printing */ - heading = 0; -#endif /* NOSPL */ - - if (heading) { /* If /HEADING print heading */ - zfnqfp(s,TMPBUFSIZ,tmpbuf); - fprintf(ofp,"\nDirectory of %s\n\n",tmpbuf); - n += 3; - } - if (page > -1) /* Paging */ - xaskmore = page; - - if (!verbose) { /* /BRIEF */ - if (outfile[0]) { /* To file */ - int k = 0; - znext(name); - while (name[0]) { /* One line per file */ - k++; - if (fs) if (fileselect(name, - dir_aft,dir_bef,dir_naf,dir_nbf, - minsize,maxsize,!backup,16,xlist) < 1) { - znext(name); - continue; - } - fprintf(ofp,"%s\n",name); - znext(name); - } - if (heading) - fprintf(ofp,"Files: %d\n\n",k); - rc = 1; - goto xdomydir; - } else { - rc = filhelp(x,"","",n,0); - if (rc < 0) - goto xdomydir; - if (heading && rc > 0) - fprintf(ofp,"Files: %d\n\n",x); /* (Might scroll a line or 2) */ - rc = 1; - goto xdomydir; - } - } - ndirs = nfiles = nbytes = 0L; /* Initialize counters */ - - if (dir_exc) /* Have exception list? */ - makelist(dir_exc,xlist,16); /* Yes, convert to array */ - - diractive = 1; - znext(name); /* Get next file */ - while (name[0]) { /* Loop for each file */ - if (fs) if (fileselect(name, - dir_aft,dir_bef,dir_naf,dir_nbf, - minsize,maxsize,!backup,16,xlist) < 1) { - znext(name); - continue; - } - len = zgetfs(name); /* Get file length */ - debug(F111,"domydir zgetfs",name,len); -#ifdef VMSORUNIX - itsadir = zgfs_dir; /* See if it's a directory */ -#else - itsadir = (len == -2 || isdir(name)); -#endif /* VMSOUNIX */ - debug(F111,"domydir itsadir",name,itsadir); - if ((itsadir && (show == 1)) || (!itsadir && (show == 2))) { - znext(name); - continue; - } - /* Get here when we know we have selected this file */ - - nmatches ++; - if (itsadir) { /* Accumulate totals for summary */ - ndirs++; - } else { - nfiles++; - nbytes += len; - } - if (summary) { /* Summary only, no detail */ - znext(name); - continue; - } -#ifndef NOSPL - if (array) { - debug(F111,"domydir array",name,nfiles); - if (ap) - makestr(&(ap[nmatches]),name); - znext(name); - continue; - } -#endif /* NOSPL */ - -/* - NOTE: The sprintf's in this routine should be safe. They involve - permission strings, date/time strings, and filenames, all of which have - known maximum lengths; none of these items is input from users. The - destination buffers are large enough to hold maximum sizes for any and - all items. -*/ - dstr = zfcdat(name); /* Get modification date/time */ - debug(F111,"domydir zcfdat",dstr,0); - if (!dstr) dstr = ""; - { -/* - Note that zfcdat() always returns "" or yyyymmdd hh:mm:ss, so any warnings - about possible out-of-bounds dstr[] array refs do not apply. This block of - code is to stifle the warnings and also allows for any out-of-spec - zfcdat() implementations. -*/ - int x; - char * p = "00000000 00:00:00"; - x = ckstrncpy(xbuf,dstr,32); - if (x < 17) ckstrncpy(&xbuf[x],p+x,32-x); - dstr = xbuf; - } - if (engdate) { /* English date requested? */ - short month, day, year, hour, minute, seconds; - month = (dstr[4]-48)*10 + (dstr[5]-48); - mstr = (month > 0 && month <= 12) ? months[month-1] : "xxx"; - day = (dstr[6]-48)*10 + (dstr[7]-48); - year = (((dstr[0]-48)*10 + - (dstr[1]-48))*10 + - (dstr[2]-48))*10 + - (dstr[3]-48); - hour = (dstr[9]-48)*10 + (dstr[10]-48); - minute = (dstr[12]-48)*10 + (dstr[13]-48); - seconds = (dstr[15]-48)*10 + (dstr[16]-48); - sprintf(dbuf, /* SAFE */ - "%2d-%s-%4d %02d:%02d:%02d", - day,mstr,year,hour,minute,seconds - ); - dstr = dbuf; - } else { /* ISO date */ - dbuf[0] = dstr[0]; /* yyyy */ - dbuf[1] = dstr[1]; - dbuf[2] = dstr[2]; - dbuf[3] = dstr[3]; - dbuf[4] = '-'; - dbuf[5] = dstr[4]; /* mm (numeric) */ - dbuf[6] = dstr[5]; - dbuf[7] = '-'; - dbuf[8] = dstr[6]; /* dd */ - dbuf[9] = dstr[7]; - strcpy(dbuf+10,dstr+8); /* hh:mm:ss */ - dstr = dbuf; - } - dlen = strlen(dbuf); /* Length of date */ - name[CKMAXPATH] = NUL; -#ifdef CK_PERMS -#ifdef VMSORUNIX - p = ziperm(name); /* Get permissions */ - debug(F110,"ziperm perms",p,0); -#else - p = zgperm(name); - debug(F110,"zgperm perms",p,0); -#endif /* VMSORUNIX */ -#else - p = NULL; - debug(F110,"NULL perms",p,0); -#endif /* CK_PERMS */ - -#ifdef VMS - /* Get relative name to save space -- VMS fullnames are long... */ - ckstrncpy(name,zrelname(name,cdp),CKMAXPATH); -#endif /* VMS */ - - if (itsadir && len < 0) { /* Directory */ -#ifdef VMS - sprintf(linebuf,"%-22s%-10s %s %s",p,"",dstr,name); -#else - if (p) - sprintf(linebuf,"%10s%-10s %s %s",p,"",dstr,name); - else - sprintf(linebuf,"%-10s %s %s", "", dstr, name); -#endif /* VMS */ - } else { /* Regular file */ -#ifdef VMS - sprintf(linebuf,"%-22s%10ld %s %s", p, len, dstr, name); -#else - if (p) - sprintf(linebuf,"%10s%10ld %s %s", p, len, dstr, name); - else - sprintf(linebuf,"%10ld %s %s", len, dstr, name); -#endif /* VMS */ - } -#ifdef UNIX -#ifdef CKSYMLINK - if (zgfs_link) { - int n, m; - extern char linkname[]; - n = strlen(linebuf); - m = strlen(linkname) + n; - if (m < CKMAXPATH + 58) - strcpy(linebuf+n, " -> "); /* safe (checked) */ - if (m + 4 < CKMAXPATH - 58) - strcpy(linebuf+n+4, linkname); /* safe (checked) */ - } else -#endif /* CKSYMLINK */ -#endif /* UNIX */ - if (xfermod) { /* Show transfer mode */ - int i, x, y; - char * s = ""; - y = -1; - x = scanfile(name,&y,nscanfile); - switch (x) { - case FT_TEXT: s = " (T)"; break; - case FT_7BIT: s = " (T)(7BIT)"; break; - case FT_8BIT: s = " (T)(8BIT)"; break; -#ifdef UNICODE - case FT_UTF8: s = " (T)(UTF8)"; break; - case FT_UCS2: - s = y ? " (T)(UCS2LE)" : " (T)(UCS2BE)"; - break; -#endif /* UNICODE */ - case FT_BIN: s = " (B)"; break; - } - if (!*s) { - s = binary ? " (B)" : " (T)"; - } - if (*s) { - int n; - n = strlen(linebuf); - if (n + 4 < CKMAXPATH - 58) - strcpy(linebuf+n, s); /* safe (checked) */ - } - } - if (msg && dirmsg) { - int n; - n = strlen(linebuf); - if (n + dirmsglen + 2 < CKMAXPATH) - sprintf((char *)(linebuf+n)," %s", dirmsg); /* SAFE */ - } - if (xsort) { /* Sorting - save line */ - i = strlen(linebuf); - if ((ndirlist >= nx) || - !(dirlist[ndirlist] = (char *)malloc(i+1))) { - printf("?Memory allocation error - try /NOSORT\n"); - rc = -9; - goto xdomydir; - } - strcpy(dirlist[ndirlist],linebuf); /* safe */ - ndirlist++; - } - znext(name); /* Peek ahead to next file */ - - if (!xsort) { - fprintf(ofp,"%s\n",linebuf); - if (page && (name[0] || heading)) { /* If /PAGE */ - if (cmd_cols > 0) { - int x = strlen(linebuf); - int y; - y = (x % cmd_cols) ? 1 : 0; - n += x / cmd_cols + y; - } else { - n++; - } -#ifdef CK_TTGWSIZ - if (n > (cmd_rows - 3)) { /* Do more-prompting */ - if (!askmore()) { - rc = 0; - goto xdomydir; - } else - n = 0; - } -#endif /* CK_TTGWSIZ */ - } - } - } -#ifndef NOSPL - if (array) { - if (ap) - makestr(&(ap[0]),ckitoa(nmatches)); - rc = 1; - goto xdomydir; - } -#endif /* NOSPL */ - if (xsort) { - skey = 0; -#ifdef VMS - switch (sortby) { - case DIRS_NM: skey = dlen + 35; break; - case DIRS_DT: skey = 33; break; - case DIRS_SZ: skey = 21; - } -#else - if (p) { - switch (sortby) { - case DIRS_NM: skey = dlen + 24; break; - case DIRS_DT: skey = 22; break; - case DIRS_SZ: skey = 10; - } - } else { - switch (sortby) { - case DIRS_NM: skey = dlen + 14; break; - case DIRS_DT: skey = 12; break; - case DIRS_SZ: skey = 0; - } - } -#endif /* VMS */ - sh_sort(dirlist,NULL,ndirlist,skey,reverse,filecase); - for (i = 0; i < ndirlist; i++) { - fprintf(ofp,"%s\n",dirlist[i]); - if (page && (i < ndirlist -1 || heading)) { /* If /PAGE */ - if (cmd_cols > 0) { - int x = strlen(dirlist[i]); - int y; - y = (x % cmd_cols) ? 1 : 0; - n += ((int)strlen(dirlist[i]) / cmd_cols) + y; - } else { - n++; - } -#ifdef CK_TTGWSIZ - if (n > (cmd_rows - 3)) { /* Do more-prompting */ - if (!askmore()) { - rc = 0; - goto xdomydir; - } else - n = 0; - } -#endif /* CK_TTGWSIZ */ - } - } - } - - if (heading || summary) { -#ifdef CKFLOAT - CKFLOAT gm; -#endif /* CKFLOAT */ - fprintf(ofp,"\n%ld director%s, %ld file%s, %ld byte%s", - ndirs, - (ndirs == 1) ? "y" : "ies", - nfiles, - (nfiles == 1) ? "" : "s", - nbytes, - (nbytes == 1) ? "" : "s" - ); -#ifdef CKFLOAT - gm = ((CKFLOAT) nbytes ) / 1000000.0; - if (gm > 1000.0) - fprintf(ofp," (%0.2fGB)",(gm / 1000.0)); - else if (gm >= 0.01) - fprintf(ofp," (%0.2fMB)",gm); -#endif /* CKFLOAD */ - fprintf(ofp,"\n\n"); - } - xdomydir: - if (g_matchdot > -1) { - matchdot = g_matchdot; /* Restore these... */ - g_matchdot = -1; - } - freedirlist(); - if (ofp != stdout) { /* Close any output file */ - if (ofp) fclose(ofp); - ofp = stdout; - } - if (rc > 0) - success = 1; - return(rc); -} - -int -dodir(cx) int cx; { /* Do the DIRECTORY command */ - char *dc , *msg; - -#ifdef OS2 - return(domydir()); -#else /* OS2 */ - if (nopush -#ifdef DOMYDIR /* Builds that domydir() by default */ - || (cx == XXDIR || cx == XXLDIR) -#endif /* DOMYDIR */ - ) - return(domydir()); /* Built-in directory command */ - - /* Use the system's directory command. */ - - msg = (cx == XXLS) ? - "Arguments for ls" : - "Directory and/or file specification"; - if ((x = cmtxt(msg,"",&s,xxstring)) < 0) - return(x); - - ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Copy the filespec */ - s = tmpbuf; - - if ((y = cmcfm()) < 0) return(y); - - lp = line; - if (!(dc = getenv("CK_DIR"))) - dc = DIRCMD; - ckmakmsg(lp,LINBUFSIZ,dc," ",s,NULL); - debug(F110,"DIR",line,0); -#ifdef VMS - conres(); -#endif /* VMS */ - x = zshcmd(line); -#ifdef VMS - concb((char)escape); -#endif /* VMS */ - return(success = (x < 1) ? 0 : 1); -#endif /* OS2 */ -} - -#ifndef NOSERVER -#ifndef NOFRILLS -/* Do the ENABLE and DISABLE commands */ - -int -doenable(y,x) int y, x; { -#ifdef CK_LOGIN - if (isguest) /* IKSD: Don't let guests */ - return(0); /* enable anything that's disabled */ -#endif /* CK_LOGIN */ - switch (x) { - case EN_ALL: - en_cwd = en_cpy = en_del = en_dir = en_fin = en_get = y; - en_ren = en_sen = en_set = en_spa = en_typ = en_ret = y; - if (!inserver) - en_who = en_mai = en_pri = y; - en_mkd = en_rmd = y; - en_xit = y; -#ifndef datageneral - en_bye = y; -#endif /* datageneral */ -#ifndef NOPUSH - if (!nopush && !inserver) - en_hos = y; -#endif /* NOPUSH */ -#ifndef NOSPL - en_asg = en_que = y; -#endif /* NOSPL */ - break; - - case EN_BYE: -#ifndef datageneral -/* - In Data General AOS/VS Kermit can't log out its superior process. -*/ - en_bye = y; -#endif /* datageneral */ - break; - case EN_CPY: - en_cpy = y; - break; - case EN_CWD: - en_cwd = y; -#ifdef IKSD - if (inserver && y == 0) { - fnrpath = PATH_OFF; - fnspath = PATH_OFF; - } -#endif /* IKSD */ - break; - case EN_DEL: /* Deleting of files */ - en_del = y; - break; - case EN_DIR: - en_dir = y; - break; - case EN_FIN: - en_fin = y; - break; - case EN_GET: - en_get = y; - break; -#ifndef NOPUSH - case EN_HOS: - if (!nopush) - en_hos = y; - break; -#endif /* NOPUSH */ - case EN_REN: - en_ren = y; - break; - case EN_SEN: - en_sen = y; - break; - case EN_SET: - en_set = y; - break; - case EN_SPA: - en_spa = y; - break; - case EN_TYP: - en_typ = y; - break; - case EN_WHO: - en_who = y; - break; -#ifndef NOSPL - case EN_ASG: - en_asg = y; - break; - case EN_QUE: - en_que = y; - break; -#endif /* NOSPL */ - case EN_RET: - en_del = y; - break; - case EN_MAI: -#ifdef CK_LOGIN - if (isguest && y) { - printf("?Sorry, not valid for guests\n"); - return(-9); - } -#endif /* CK_LOGIN */ - en_mai = y; - break; - case EN_PRI: -#ifdef CK_LOGIN - if (isguest && y) { - printf("?Sorry, not valid for guests\n"); - return(-9); - } -#endif /* CK_LOGIN */ - en_pri = y; - break; - case EN_MKD: - en_mkd = y; - break; - case EN_RMD: - en_rmd = y; - break; - case EN_XIT: - en_xit = y; - break; - case EN_ENA: - if (((y & 1) && !(en_ena & 1)) || - ((y & 2) && !(en_ena & 2))) { - printf("?Sorry, DISABLE ENABLE can not be undone\n"); - return(-9); - } else { - en_ena = y; - break; - } - default: - return(-2); - } - return(1); -} -#endif /* NOFRILLS */ -#endif /* NOSERVER */ - -#ifndef NOFRILLS - -static int del_lis = 0; -static int del_dot = 0; -static int del_hdg = 0; -static int del_pag = -1; -static int del_ask = 0; - -#ifndef NOSHOW -VOID -showdelopts() { - int x = 0; - extern int optlines; - prtopt(&optlines,""); - prtopt(&optlines,"DELETE"); - if (del_ask > -1) { - prtopt(&optlines, del_ask ? "/ASK" : "/NOASK"); - x++; - } -#ifdef UNIXOROSK - if (del_dot > -1) { - prtopt(&optlines, del_dot ? "/DOTFILES" : "/NODOTFILES"); - x++; - } -#endif /* UNIXOROSK */ - if (del_lis > -1) { - prtopt(&optlines, del_lis ? "/LIST" : "/NOLIST"); - x++; - } - if (del_hdg > -1) { - prtopt(&optlines, del_hdg ? "/HEADING" : "/NOHEADING"); - x++; - } -#ifndef CK_TTGWSIZ - if (del_pag > -1) { - prtopt(&optlines, del_pag ? "/PAGE" : "/NOPAGE"); - x++; - } -#endif /* CK_TTGWSIZ */ - if (!x) prtopt(&optlines,"(no options set)"); - prtopt(&optlines,""); -} -#endif /* NOSHOW */ - - -int -setdelopts() { - int x_lis = -1, x_pag = -1, x_dot = -1, x_hdg = -1, x_ask = -1; - int getval = 0; - char c; - while (1) { - if ((y = cmswi(deltab,ndeltab,"Switch","",xxstring)) < 0) { - if (y == -3) - break; - else - return(y); - } - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (y) { - case DEL_DOT: - x_dot = 1; - break; - case DEL_NOD: - x_dot = 0; - break; - case DEL_HDG: - x_hdg = 1; - break; - case DEL_LIS: - x_lis = 1; - break; - case DEL_NOL: - x_lis = 0; - break; -#ifndef CK_TTGWSIZ - case DEL_PAG: - x_pag = 1; - break; - case DEL_NOP: - x_pag = 0; - break; -#endif /* CK_TTGWSIZ */ - case DEL_QUI: - x_lis = 0; - break; - case DEL_VRB: - x_lis = 1; - break; - case DEL_ASK: - x_ask = 1; - break; - case DEL_NAS: - x_ask = 0; - break; - default: - printf("?Sorry, this option can not be set\n"); - return(-9); - } - } - if ((x = cmcfm()) < 0) /* Get confirmation */ - return(x); - if (x_pag > -1) del_pag = x_pag; - if (x_dot > -1) del_dot = x_dot; - if (x_hdg > -1) del_hdg = x_hdg; - if (x_lis > -1) del_lis = x_lis; - if (x_ask > -1) del_ask = x_ask; - return(success = 1); -} - -#ifdef OS2 -static char ** xmtchs = NULL; -static int xmtchn = 0; -#endif /* OS2 */ - -int -dodel() { /* DELETE */ - int i, j, k, x; - int fs = 0; /* Need to call fileselect() */ - int len = 0; - int bad = 0; - int getval = 0, asking = 0; - int simulate = 0, rc = 0; - long minsize = -1L, maxsize = -1L; - int havename = 0, confirmed = 0; - int qflag = 0; - int summary = 0; - int deldirs = 0; - int deltree = 0; - int itsadir = 0; - int argisdir = 0; - int xmode = -1, scan = 0, skip = 0; -#ifdef COMMENT - int pass = 0; -#endif /* COMMENT */ - char c; - char * deldef = ""; - char safebuf[CKMAXPATH+1]; - struct FDB sw, fi, fl; - char - * del_aft = NULL, - * del_bef = NULL, - * del_naf = NULL, - * del_nbf = NULL, - * del_exc = NULL; - int - x_lis = 0, - /* x_dot = -1, */ - x_hdg = 0; - - char * dxlist[8]; - - for (i = 0; i < 8; i++) dxlist[i] = NULL; - - g_matchdot = matchdot; - - if (del_lis > -1) x_lis = del_lis; - if (del_dot > -1) matchdot = del_dot; - if (del_hdg > -1) x_hdg = del_hdg; - if (del_pag > -1) xaskmore = del_pag; - if (del_ask > -1) asking = del_ask; - - diractive = 1; - nolinks = 2; /* By default don't follow links */ - - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "File specification;\n or switch", - "", /* default */ - "", /* addtl string data */ - ndeltab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - deltab, /* Keyword table */ - &fi /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Anything that doesn't match */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - again: - cmfdbi(&fi, /* 2nd FDB - file to delete */ - _CMIFI, /* fcode */ - "File(s) to delete", /* hlpmsg */ - deldef, /* default */ - "", /* addtl string data */ - nolinks | deldirs, /* 0 = files, 1 = files or dirs */ - 0, /* 1 = dirs only */ - xxstring, - NULL, - &fl - ); - while (!havename && !confirmed) { - x = cmfdb(&sw); /* Parse something */ - if (x < 0) { /* Error */ - if (x == -3) - break; - if (x == -2 || x == -9) - printf("?Does not match switch or filename: \"%s\"\n",atmbuf); - return(x); - } - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); /* Get break character */ - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - rc = -9; - goto xdelete; - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - rc = -9; - goto xdelete; - } - switch (k = cmresult.nresult) { - case DEL_AFT: - case DEL_BEF: - case DEL_NAF: - case DEL_NBF: - if (!getval) break; - if ((x = cmdate("File-time","",&s,0,xxstring)) < 0) { - if (x == -3) { - printf("?Date-time required\n"); - x = -9; - } else - rc = x; - goto xdelete; - } - fs++; - deltree = 0; - switch (k) { - case DEL_AFT: makestr(&del_aft,s); break; - case DEL_BEF: makestr(&del_bef,s); break; - case DEL_NAF: makestr(&del_naf,s); break; - case DEL_NBF: makestr(&del_nbf,s); break; - } - break; - case DEL_DOT: - matchdot = 1; - break; - case DEL_NOD: - matchdot = 0; - break; - case DEL_ALL: - fs = 0; -#ifdef VMS - deldef = "*.*"; /* UNIX, Windows, OS/2 */ -#else -#ifdef datageneral - deldef = "+"; /* AOS/VS */ -#else - deldef = "*"; /* UNIX, Windows, OS/2, VMS... */ -#endif /* datageneral */ -#endif /* VMS */ - deltree = 1; - nolinks = 2; - matchdot = 1; - recursive = 1; /* Fall through purposely... */ - case DEL_DIR: - deldirs = 1; - goto again; - case DEL_EXC: - if (!getval) break; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Pattern required\n"); - x = -9; - } else - rc = x; - goto xdelete; - } - fs++; - deltree = 0; - makestr(&del_exc,s); - break; - case DEL_HDG: - x_hdg = 1; - break; -#ifdef RECURSIVE - case DEL_REC: - recursive = 1; - break; -#endif /* RECURSIVE */ - case DEL_LIS: - x_lis = 1; - break; - case DEL_SUM: - summary = 1; - x_lis = 0; - x_hdg = 1; - break; - case DEL_NOL: - x_lis = 0; - break; -#ifndef CK_TTGWSIZ - case DEL_PAG: - xaskmore = 1; - break; - case DEL_NOP: - xaskmore = 0; - break; -#endif /* CK_TTGWSIZ */ - case DEL_QUI: - qflag = 1; - x_lis = 0; - break; - case DEL_VRB: - x_lis = 1; - break; - - case DEL_SMA: - case DEL_LAR: - if (!getval) break; - if ((x = cmnum("File size in bytes","0",10,&y,xxstring)) < 0) - return(x); - fs++; - deltree = 0; - switch (cmresult.nresult) { - case DEL_SMA: minsize = y; break; - case DEL_LAR: maxsize = y; break; - } - break; - - case DEL_SIM: - simulate = 1; - x_lis = 1; - break; - case DEL_ASK: - asking = 1; - break; - case DEL_NAS: - asking = 0; - break; - case DEL_TYP: { - extern struct keytab txtbin[]; - if (!getval) break; - if ((x = cmkey(txtbin,3,"","",xxstring)) < 0) - return(x); - if (x == 2) { /* ALL */ - xmode = -1; - } else { /* TEXT or BINARY only */ - xmode = x; - scan = 1; - } - break; - } - default: - printf("?Not implemented yet - \"%s\"\n",atmbuf); - return(-9); - } - } - if (qflag && (cmresult.fcode == _CMFLD)) { - if ((x = cmcfm()) < 0) - return(x); - else - return(success = 0); - } - if (cmresult.fcode != _CMIFI) { - if (*atmbuf) { - int x; - if (iswild(atmbuf) && nzxpand(atmbuf,nzxopts) == 0) - printf("?No files match: %s\n",atmbuf); - else if ((x = zchki(atmbuf)) == -1) - printf("?File not found: %s\n",atmbuf); - else if (x == -2) - printf("?Not a regular file: %s\n",atmbuf); - else - /* printf("?Not a deletable file: %s\n",atmbuf); */ - goto tryanyway; - } else { - printf("?A file specification is required\n"); - } - return(-9); - } - tryanyway: - ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ); /* Safe copy of filespec */ - if (deldirs) { - ckstrncpy(safebuf,cmresult.sresult,CKMAXPATH); -#ifdef VMSORUNIX - len = zgetfs(tmpbuf); /* Is it a directory name? */ - argisdir = zgfs_dir; /* Then because of how zxpand() */ - if (argisdir && zgfs_link) /* works, we have to add it to */ - argisdir = 0; /* the list. */ - if (itsadir) - len = -2; -#else - len = zchki(tmpbuf); - if (len < 0) - argisdir = isdir(tmpbuf); -#endif /* VMSORUNIX */ - } - debug(F110,"DELETE file",tmpbuf,0); - if ((x = cmcfm()) < 0) - return(x); - -#ifdef IKSD -#ifdef CK_LOGIN - if (inserver && isguest) { - printf("?Sorry, DELETE unavailable to guests\n"); - return(-9); - } -#endif /* CK_LOGIN */ -#endif /* IKSD */ - -#ifndef OS2ORUNIX - if (simulate) { - printf("?Sorry, /SIMULATE not implemented on this platform\n"); - return(-9); - } -#endif /* OS2ORUNIX */ - -#ifdef COMMENT - /* (not needed) */ - if (!iswild(tmpbuf)) { - char *m; - errno = 0; - x = zchki(tmpbuf); - if (x < 0) { - switch (x) { - case -2: m = "Not a regular file"; break; - case -1: m = "File not found or not accessible"; break; - default: m = errno ? ck_errstr() : "Can't delete"; - } - printf("?%s: \"%s\"\n",m,tmpbuf); - return(-9); - } - } -#endif /* COMMENT */ - - makelist(del_exc,dxlist,8); - -/* tmpbuf[] has the name - now do any needed conversions on it */ - -#ifdef OS2 - { /* Lower level functions change / to \, not good for CMD.EXE. */ - char *p = tmpbuf; - while (*p) { /* Change them back to \ */ - if (*p == '/') *p = '\\'; - p++; - } - } -#endif /* OS2 */ - -#ifdef VMS - if (iswild(tmpbuf)) { -#ifdef COMMENT - /* Does not handle '.' as version separator */ - char *p = tmpbuf; - x = 0; - while (*p) { - if (*p == ';') { - x = 1; - break; - } else - p++; - } - if (!x) ckstrncat(tmpbuf,";*",TMPBUFSIZ); -#else - j = 0; x = 0; /* for end_dot and number of dots */ - i = strlen(tmpbuf); - if (tmpbuf[i] == ';') { - ckstrncat(tmpbuf,"0",TMPBUFSIZ); - } else { - if (tmpbuf[i--] == '.') - j++; - for (; i >= 0; i--) { - if (tmpbuf[i] == ';' || tmpbuf[i] == ':' || - tmpbuf[i] == ']' || tmpbuf[i] == '>') - break; - else if (tmpbuf[i] == '.') - x++; - } - if (tmpbuf[i] != ';') { /* dot may have been used */ - if (j) { /* last char is dot */ - if (x) /* second is version separator */ - ckstrncat(tmpbuf,"0",TMPBUFSIZ); - else /* 'foo.' */ - ckstrncat(tmpbuf,";0",TMPBUFSIZ); - } else if (x == 1) /* lacking a version separator */ - ckstrncat(tmpbuf,";0",TMPBUFSIZ); - else if (x == 0) /* x == 2 has a version */ - ckstrncat(tmpbuf,".*;0",TMPBUFSIZ); - } - } -#endif /* COMMENT */ - } -#endif /* VMS */ - - debug(F110,"dodel tmpbuf",tmpbuf,0); /* Filename */ - -#ifndef OS2ORUNIX /* No built-in DELETE code... */ - /* Construct system command. */ - ckmakmsg(line,LINBUFSIZ,DELCMD," ",tmpbuf,NULL); -#else -#ifdef VMS - if (asking) { /* Maybe overwrite in VMS */ - if (x_lis) /* if options are needed... */ - ckmakmsg(line,LINBUFSIZ,DELCMD," /confirm/log ",tmpbuf,NULL); - else - ckmakmsg(line,LINBUFSIZ,DELCMD," /confirm ",tmpbuf,NULL); - } else if (x_lis) - ckmakmsg(line,LINBUFSIZ,DELCMD," /log ",tmpbuf,NULL); - conres(); -#endif /* VMS */ - - debug(F110,"dodel line",line,0); -#endif /* OS2ORUNIX */ - -#ifdef MAC - success = (zdelet(tmpbuf) == 0); - -#else /* !MAC ... */ - -#ifdef OS2ORUNIX - { - int filespace = 0; - int count = 0; - int lines = 0; - int n = 0; - - s = tmpbuf; - -#ifdef CK_TTGWSIZ -#ifdef OS2 - ttgcwsz(); -#else /* OS2 */ - /* Check whether window size changed */ - if (ttgwsiz() > 0) { - if (tt_rows > 0 && tt_cols > 0) { - cmd_rows = tt_rows; - cmd_cols = tt_cols; - } - } -#endif /* OS2 */ -#endif /* CK_TTGWSIZ */ - - if (x_hdg > 0 && !summary) { - printf("Deleting %s...%s\n", s, simulate ? " (SIMULATION)" : ""); - n += 2; - } -#ifdef ZXREWIND - z = zxrewind(); /* Rewind file list */ -#else - if (!deldirs) - nzxopts = ZX_FILONLY; - if (recursive) nzxopts |= ZX_RECURSE; - if (matchdot) nzxopts |= ZX_MATCHDOT; - errno = 0; - z = nzxpand(s,nzxopts); /* Expand file list */ -#endif /* ZXREWIND */ - debug(F111,"dodel",s,z); - - /* If deleting directories, sort in reverse order */ - /* so we delete the files first, then the directory. */ - -#ifdef OS2 - /* In K95, we have no mtchs array, nor any control over */ - /* the order in which znext() returns filenames, so we */ - /* must copy the array and sort it. */ - { - int i; - if (xmtchs) { /* Free previous list in case */ - debug(F101,"dodel freeing previous list","",xmtchn); - for (i = 0; i < xmtchn; i++) /* it wasn't freed last time. */ - if (xmtchs[i]) - free(xmtchs[i]); - free(xmtchs); - } - xmtchn = 0; - xmtchs = (char **)malloc(z * (sizeof(char **))); /* Make new one */ - if (!xmtchs) { - printf("?Memory allocation failure\n"); - return(-9); - } - for (i = 0; i < z; i++) { - xmtchs[i] = NULL; - znext(tmpbuf); - if (!*tmpbuf) - break; - makestr(&(xmtchs[i]),tmpbuf); - if (!xmtchs[i]) { - printf("?Memory allocation failure\n"); - xmtchn = i - 1; - rc = -9; - goto xdelete; - } - /* debug(F111,"dodel add",xmtchs[i],i); */ - } - xmtchn = i; - debug(F101,"dodel xmtchn","",xmtchn); - sh_sort(xmtchs,NULL,z,0,deldirs,0); - } -#else -#ifdef UNIX - sh_sort(mtchs,NULL,z,0,deldirs,filecase); -#endif /* UNIX */ -#endif /* OS2 */ - - if (z > 0) { - int i; -#ifdef OS2 - int ix = 0; -#endif /* OS2 */ - success = 1; - if (x_hdg > 0) - printf("\n"); - - while ( -#ifdef OS2 - ix < xmtchn -#else - 1 -#endif /* OS2 */ - ) { /* Loop for all files */ -#ifdef OS2 - ckstrncpy(tmpbuf,xmtchs[ix++],TMPBUFSIZ); -#else - znext(tmpbuf); /* Get next file */ -#endif /* OS2 */ - if (!*tmpbuf) { /* No more */ - if (deldirs && recursive && argisdir) { - ckstrncpy(tmpbuf,safebuf,TMPBUFSIZ); - argisdir = 0; /* (only do this once) */ - } else - break; - } - skip = 0; - if (!deltree) { - if (fs) - if (fileselect(tmpbuf, - del_aft,del_bef,del_naf,del_nbf, - minsize,maxsize,0,8,dxlist) < 1) { - skip++; - } - } - if (!skip && scan && itsadir) { - skip++; - } - if (!skip && scan) { - switch (scanfile(tmpbuf,&y,nscanfile)) { - case FT_BIN: - if (xmode != 1) - skip++; - break; - case FT_TEXT: - case FT_7BIT: - case FT_8BIT: -#ifdef UNICODE - case FT_UTF8: - case FT_UCS2: -#endif /* UNICODE */ - if (xmode != 0) - skip++; - } - } - if (!skip && asking) { - int x; - ckmakmsg(line,LINBUFSIZ," Delete ",tmpbuf,"? ",NULL); - x = getyesno(line,3); - switch (x) { - case 0: continue; /* no */ - case 1: break; /* yes */ - case 2: goto xdelete; /* quit */ - case 3: asking = 0; break; /* go */ - } - } -#ifdef VMSORUNIX - len = zgetfs(tmpbuf); /* Get length and accessibility */ - itsadir = zgfs_dir; - if (itsadir && zgfs_link) { /* Treat links to directories */ - itsadir = 0; /* as regular files */ - if (scan) /* But not if /TYPE: was given */ - skip++; - } - if (itsadir) /* (emulate non-Unix code) */ - len = -2; -#else - len = zchki(tmpbuf); /* Get accessibility */ - if (len < 0) /* See if it's a directory */ - itsadir = isdir(tmpbuf); -#endif /* VMSORUNIX */ - - if (skip) { -#ifdef COMMENT /* Too verbose */ - if (x_lis > 0) { - lines++; - printf(" %s (SKIPPED)\n",tmpbuf); -#ifdef CK_TTGWSIZ - if (++n > cmd_rows - 3) - if (!askmore()) goto xdelete; else n = 0; -#endif /* CK_TTGWSIZ */ - } -#endif /* COMMENT */ - continue; - } - - debug(F111,"DELETE len",tmpbuf,len); - if (simulate) { - filespace += len; - count++; - if (x_lis > 0) { - lines++; - printf(" %s (SELECTED)\n",tmpbuf); - if (++n > cmd_rows - 3) { - int xx; - xx = askmore(); - if (!xx) goto xdelete; else n = 0; - } - } - } else if (len >= 0 || !itsadir) { /* Regular file */ - zdelet(tmpbuf); /* or symlink, etc... */ - if (zchki(tmpbuf) < 0) { - filespace += len; - count++; - if (x_lis > 0) { - lines++; - printf(" %s (OK)\n",tmpbuf); - if (++n > cmd_rows - 3) - if (!askmore()) goto xdelete; else n = 0; - } - } else { - bad++; - success = 0; - if (x_lis > 0) { - lines++; - printf(" %s (FAILED: %s)\n",tmpbuf,ck_errstr()); - if (++n > cmd_rows - 3) - if (!askmore()) goto xdelete; else n = 0; - } - } - } else if (/* pass > 0 && */ deldirs && itsadir) { - /* It's a directory */ - if (zrmdir(tmpbuf) > -1) { /* Only works if empty */ - count++; - if (x_lis > 0) { - lines++; - printf(" %s (OK)\n",tmpbuf); - if (++n > cmd_rows - 3) - if (!askmore()) goto xdelete; else n = 0; - } - } else { - success = 0; - if (x_lis > 0) { - lines++; - printf(" %s (FAILED: %s)\n", - tmpbuf, - ck_errstr()); - if (++n > cmd_rows - 3) - if (!askmore()) goto xdelete; else n = 0; - } - } - } else if (x_lis > 0) { - lines++; - if (isdir(tmpbuf)) - printf(" %s (FAILED: directory)\n",tmpbuf); - else - printf(" %s (FAILED: not a regular file)\n",tmpbuf); - if (++n > cmd_rows - 3) - if (!askmore()) goto xdelete; else n = 0; - } - } - if (x_hdg > 0) { - if (lines > 0) - printf("\n"); - if (++n > cmd_rows - 3) - if (!askmore()) goto xdelete; else n = 0; - printf("%d file%s %sdeleted, %d byte%s %sfreed%s\n", - count, - count != 1 ? "s" : "", - simulate ? "would be " : "", - filespace, - filespace != 1 ? "s" : "", - simulate ? "would be " : "", - simulate ? " (maybe)" : "" - ); - } - if (!x_lis && !success && !quiet) { - printf("?DELETE failed for %d file%s \ -(use DELETE /LIST to see details)\n", - bad, bad == 1 ? "" : "s" - ); - } - } else if (x_lis > 0) { - if (errno) - printf("?%s: %s\n",ck_errstr(), tmpbuf); - else - printf("?Can't delete: %s\n",tmpbuf); - } - } -#else /* OS2ORUNIX */ -#ifndef VMS /* Others - let the system do it. */ - xsystem(line); - x = nzxpand(tmpbuf,nzxopts); - success = (x > 0) ? 0 : 1; - if (x_hdg > 0) - printf("%s - %sdeleted\n", tmpbuf, success ? "" : "not "); -#else - if (asking) - printf("\n"); - x = xsystem(line); /* zshcmd returns 1 for success */ - success = (x > 0) ? 1 : 0; - if (x_hdg > 0 && !asking) - printf("%s - %sdeleted\n", tmpbuf, success ? "" : "not "); - concb((char)escape); -#endif /* VMS */ -#endif /* OS2ORUNIX */ -#endif /* MAC */ - xdelete: - if (g_matchdot > -1) { - matchdot = g_matchdot; /* Restore these... */ - g_matchdot = -1; - } -#ifdef OS2 - if (xmtchs) { - int i; - debug(F101,"dodel freeing list","",xmtchn); - for (i = 0; i < xmtchn; i++) - if (xmtchs[i]) free(xmtchs[i]); - free(xmtchs); - xmtchs = NULL; - xmtchn = 0; - } -#endif /* OS2 */ - debug(F101,"dodel result","",rc); - return((rc < 0) ? rc : success); -} -#endif /* NOFRILLS */ - -#ifndef NOSPL /* The ELSE command */ -_PROTOTYP( VOID pushqcmd, (char *) ); - -int -doelse() { - if (!ifcmd[cmdlvl]) { - printf("?ELSE doesn't follow IF\n"); - return(-2); - } -#ifdef COMMENT -/* - Wrong. This prevents IF..ELSE IF...ELSE IF...ELSE IF...ELSE... - from working. -*/ - ifcmd[cmdlvl] = 0; -#endif /* COMMENT */ - if (!iftest[cmdlvl]) { /* If IF was false do ELSE part */ - if (maclvl > -1 || tlevel > -1) { /* In macro or command file */ - debug(F100,"doelse pushing","",0); -#ifdef COMMENT - pushcmd(NULL); /* save rest of command. */ -#else - /* This fixes certain obscure problems */ - /* but breaks many other constructions that must work. */ - pushqcmd(NULL); -#endif /* COMMENT */ - } else { /* If interactive, */ - cmini(ckxech); /* just start a new command */ - printf("\n"); /* (like in MS-DOS Kermit) */ - if (pflag) prompt(xxstring); - } - } else { /* Condition is false */ - if ((y = cmtxt("command to be ignored","",&s,NULL)) < 0) - return(y); /* Gobble up rest of line */ - } - return(0); -} -#endif /* NOSPL */ - -#ifndef NOSPL -int -doswitch() { - char *lp, *ap; /* Macro argument pointer */ - int len = 0, x, y, pp = 0; - char brbuf[3]; - - /* Get variable name */ - - tmpbuf[0] = NUL; - brbuf[0] = '{'; - brbuf[1] = '}'; - brbuf[2] = NUL; - - y = cmfld("Variable name","",&s,xxstring); - debug(F111,"doswitch cmfld",s,y); - if (y < 0) { - if (y == -3) /* Because brstrip() writes */ - s = brbuf; /* into its argument. */ - else - return(y); - } - debug(F110,"doswitch A",s,0); - if (!strcmp(s,"(")) { - pp++; - if ((y = cmfld("Variable name","",&s,xxstring)) < 0) { - if (y == -3) - s = brbuf; - else - return(y); - debug(F110,"doswitch B",s,0); - } - } - len = ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ); - if (tmpbuf[0] == CMDQ) { - if (chkvar(s) < 1) { - printf("?Variable name required\n"); - return(-9); - } - } - if (pp > 0) { /* If open paren given parse closing */ - if ((y = cmfld("Closing parenthesis","",&s,NULL)) < 0) - return(y); - if (strcmp(atmbuf,")")) { - printf("?Closing parenthesis required\n"); - return(-9); - } - } - lp = line; - x = ckstrncpy(lp,"_switx ",LINBUFSIZ); /* _switx + space */ - lp += x; - ap = lp; - debug(F010,"SWITCH a",line,0); - -#ifdef COMMENT - x = ckmakmsg(lp,LINBUFSIZ-x,tmpbuf," ",NULL,NULL); /* variable name + SP */ -#else - { /* variable name + SP */ - char * p = tmpbuf; - if (len > 0) { - if (tmpbuf[0] == '(' && tmpbuf[len-1] == ')') { - tmpbuf[len-1] = NUL; - p++; - } - } - x = ckmakmsg(lp,LINBUFSIZ-x,"{",brstrip(p),"}"," "); - } -#endif /* COMMENT */ - debug(F010,"SWITCH b",line,0); - lp += x; - - /* Get body */ - - if ((y = cmtxt("series of cases","",&s,NULL)) < 0) return(y); - if ((y = (int)strlen(s)) < 1) return(-2); - if (s[0] != '{' && s[y-1] != '}') { /* Supply braces if missing */ - ckmakmsg(tmpbuf,TMPBUFSIZ,"{ ",s," }",NULL); - s = tmpbuf; - } - if (litcmd(&s,&lp,(LINBUFSIZ - (lp - (char *)line) - 2)) < 0) { - printf("?Unbalanced braces\n"); - return(0); - } - debug(F010,"SWITCH c",line,0); - - x = mlook(mactab,"_switx",nmac); /* Look up SWITCH macro definition */ - if (x < 0) { /* Not there? */ - addmmac("_switx",sw_def); /* Put it back. */ - if ((x = mlook(mactab,"_switx",nmac)) < 0) { /* Look it up again. */ - printf("?SWITCH macro definition gone!\n"); /* Shouldn't happen. */ - return(success = 0); - } - } - debug(F010,"SWITCH command",line,0); /* Execute the SWITCH macro. */ - success = dodo(x,ap,cmdstk[cmdlvl].ccflgs | CF_IMAC); - debug(F101,"SWITCH status","",success); - return(success); -} - -int -dofor() { /* The FOR command. */ - int i, fx, fy, fz; /* loop variables */ - char *ap, *di; /* macro argument pointer */ - int pp = 0; /* Paren level */ - int mustquote = 0; - - for (i = 0; i < 2; i++) { - if ((y = cmfld("Variable name","",&s,NULL)) < 0) { - if (y == -3) { - printf("?Variable name required\n"); - return(-9); - } else - return(y); - } - if (strcmp(s,"(")) - break; - pp++; - } -#ifdef COMMENT - if ((y = parsevar(s,&x,&z)) < 0) /* Check variable. */ - return(y); -#else - if (*s == CMDQ) /* If loop variable starts with */ - mustquote++; /* backslash, mustquote is > 0. */ -#endif /* COMMENT */ - - lp = line; /* Build a copy of the command */ - ckstrncpy(lp,"_forx ",LINBUFSIZ); - lp += (int)strlen(line); /* "_for" macro. */ - ap = lp; /* Save pointer to macro args. */ - - if (*s == CMDQ) s++; /* Skip past backslash if any. */ - while ((*lp++ = *s++)) ; /* copy it */ - lp--; *lp++ = SP; /* add a space */ - - if ((y = cmnum("initial value","",10,&fx,xxstring)) < 0) { - if (y == -3) return(-2); - else return(y); - } - debug(F101,"dofor fx","",fx); - s = atmbuf; /* Copy the atom buffer */ - - if ((int)strlen(s) < 1) goto badfor; -/* - In edit 192, we change the loop variables to be evaluated at loop entry, - not each time through the loop. This was required in order to allow - \v(argc) to be used as a loop variable, or in a loop-variable expression. - Thus, we can't have FOR loops that modify their own exit conditions by - changing the final value or the increment. The problem with \v(argc) was - that it is on the macro stack; after entry into the _forx macro, it is at - the wrong place. -*/ - sprintf(tmpbuf,"%d",fx); /* (SAFE) Substitute actual value */ - s = tmpbuf; - while ((*lp++ = *s++)) ; /* (what they actually typed) */ - lp--; *lp++ = SP; -#ifdef DEBUG - *lp = NUL; - debug(F110,"FOR A",line,0); -#endif /* DEBUG */ - - if ((y = cmnum("final value","",10,&fy,xxstring)) < 0) { - if (y == -3) return(-2); - else return(y); - } - debug(F101,"dofor fy","",fy); - s = atmbuf; /* Same deal */ - if ((int)strlen(s) < 1) - goto badfor; - - sprintf(tmpbuf,"%d",fy); /* SAFE */ - s = tmpbuf; - while ((*lp++ = *s++)) ; - lp--; - *lp++ = SP; -#ifdef DEBUG - *lp = NUL; - debug(F110,"FOR B",line,0); -#endif /* DEBUG */ - - x_ifnum = 1; /* Increment or parenthesis */ - di = (fx < fy) ? "1" : "-1"; /* Default increment */ - if ((y = cmnum("increment",di,10,&fz,xxstring)) < 0) { - debug(F111,"dofor increment",atmbuf,y); - x_ifnum = 0; - if (y == -3) { /* Premature termination */ - return(-2); - } else if (y == -2) { /* Maybe closing paren */ - if (!strcmp(atmbuf,")")) { - pp--; /* Count it */ - s = di; /* supply default interval */ - fz = atoi(s); - } else /* Not closing paren, invalid */ - return(y); - } else /* Other error */ - return(y); - } else { /* Number */ - x_ifnum = 0; - debug(F101,"dofor fz","",fz); - s = atmbuf; /* Use it */ - } - if ((int)strlen(s) < 1) - goto badfor; - - sprintf(tmpbuf,"%d",fz); /* (SAFE) Same deal */ - s = tmpbuf; - while ((*lp++ = *s++)) ; - lp--; *lp++ = SP; - -#ifdef DEBUG - *lp = NUL; - debug(F110,"FOR C",line,0); -#endif /* DEBUG */ - - /* Insert the appropriate comparison operator */ - if (fz < 0) - *lp++ = '<'; - else - *lp++ = '>'; - *lp++ = SP; - -#ifdef DEBUG - *lp = NUL; - debug(F110,"FOR D",line,0); -#endif /* DEBUG */ - - if (pp > 0) { /* If open paren given parse closing */ - if ((y = cmfld("Closing parenthesis","",&s,NULL)) < 0) - return(y); - if (strcmp(atmbuf,")")) { - printf("?Closing parenthesis required\n"); - return(-9); - } - } - if ((y = cmtxt("Command to execute","",&s,NULL)) < 0) return(y); - if ((y = (int)strlen(s)) < 1) return(-2); - if (s[0] != '{' && s[y-1] != '}') { /* Supply braces if missing */ - ckmakmsg(tmpbuf,TMPBUFSIZ,"{ ",s," }",NULL); - s = tmpbuf; - } - if (litcmd(&s,&lp,(LINBUFSIZ - (lp - (char *)line) - 2)) < 0) { - printf("?Unbalanced braces\n"); - return(0); - } -#ifdef DEBUG - *lp = NUL; - debug(F110,"FOR E",line,0); -#endif /* DEBUG */ - -#ifdef COMMENT -/* Too strict */ - if (fz == 0) { - printf("?Zero increment not allowed\n"); - return(0); - } -#endif /* COMMENT */ -/* - In version 8.0 we decided to allow macro names anyplace a numeric-valed - variable could appear. But this caused trouble for the FOR loops because - the quoting in for_def[] assumed a \%i-style loop variable. We account - for this here in the if (mustquote)...else logic by invoking separate - FOR macro definitions in the two cases. -*/ - if (mustquote) { /* \%i-style loop variable */ - x = mlook(mactab,"_forx",nmac); /* Look up FOR macro definition */ - if (x < 0) { /* Not there? */ - addmmac("_forx",for_def); /* Put it back. */ - if ((x = mlook(mactab,"_forx",nmac)) < 0) { /* Look it up again. */ - printf("?FOR macro definition gone!\n"); - return(success = 0); - } - } - } else { /* Loop variable is a macro */ - x = mlook(mactab,"_forz",nmac); - if (x < 0) { - addmmac("_forz",foz_def); - if ((x = mlook(mactab,"_forz",nmac)) < 0) { - printf("?FOR macro definition gone!\n"); - return(success = 0); - } - } - } - debug(F010,"FOR command",line,0); /* Execute the FOR macro. */ - return(success = dodo(x,ap,cmdstk[cmdlvl].ccflgs | CF_IMAC)); - -badfor: - printf("?Incomplete FOR command\n"); - return(-2); -} -#endif /* NOSPL */ - -#ifndef NOFRILLS -/* Do the BUG command */ - -int -dobug() { - int n; - char * s = ""; - extern char * k_info_dir; - - if (k_info_dir) - s = k_info_dir; - -#ifdef COMMENT - printf("\n%s,%s\n Numeric: %ld",versio,ckxsys,vernum); -#endif /* COMMENT */ - printf( -"\nBefore requesting technical support from Columbia U., please consult:\n\n" - ); - n = 7; -#ifdef OS2 - printf(" . Your \"Kermit 95\" user manual (use the MANUAL command).\n"); - printf(" . The technical reference manual, \"Using C-Kermit\".\n"); - n += 2; -#else - printf(" . The book \"Using C-Kermit\" (type HELP for more info).\n"); - n += 1; -#endif /* OS2 */ - - printf(" . Your own organization's support staff, if any.\n"); - printf( -" . The comp.protocols.kermit.misc newsgroup.\n"); - printf( -" . The Kermit support website, http://www.columbia.edu/kermit/support.html \n" - ); - printf( - -" . The Kermit FAQ, http://www.columbia.edu/kermit/newfaq.html \n"); -#ifdef OS2 - printf( -" . The Kermit 95 FAQ, http://www.columbia.edu/kermit/k95faq.html \n"); - n++; -#endif /* OS2 */ - - printf( -" . The C-Kermit FAQ, http://www.columbia.edu/kermit/ckfaq.html \n"); - n += 4; - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf("\n\ -If you still need help or have a bug to report after consulting these sources," - ); - printf("\nsend e-mail to:\n\n"); - n += 2; - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf(" mailto:kermit-support@columbia.edu\n\n"); - n += 1; - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf("Or contact us by post:\n\n"); - printf( -" Kermit, Columbia University, 612 W 115 Street, New York NY 10025, USA\n\n" - ); - n += 1; - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf("Or by fax at +1 (212) 662-6442.\n\n"); - n += 1; - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; -#ifdef COMMENT - printf("Telephone support is available too:\n\n"); - n += 1; - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf( - " +1 (212) 854-5126, from anywhere, $25.00 USD per call, MC/Visa\n\n"); - n += 1; - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; -#endif /* COMMENT */ -#ifndef NOSHOW -#ifndef NOFRILLS - printf( -"Before reporting problems, please use the SHOW FEATURES command\n"); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf( -"to get detailed program version and configuration information.\n\n"); -#endif /* NOFRILLS */ -#endif /* NOSHOW */ - return(1); -} -#endif /* NOFRILLS */ - -#ifndef NOSPL - -/* T O D 2 S E C -- Convert time of day as hh:mm:ss to secs since midnite */ -/* - Call with a string hh:mm or hh:mm:ss. - Returns a 0 to 86400 on success, or a negative number on failure. -*/ -long -tod2sec(t) char * t; { - long t2; - long hh = 0L, mm = 0L, ss = 0L; - - if (!t) t = ""; - if (!*t) - return(-3L); - debug(F110,"tod2sec",t,0); - - if (isdigit(*t)) /* Get hours from argument */ - hh = *t++ - '0'; - else - return(-1L); - if (isdigit(*t)) - hh = hh * 10 + *t++ - '0'; -#ifdef COMMENT - if (hh > 24L) - return(-1L); -#endif /* COMMENT */ - if (*t == ':') - t++; - else if (!*t) - goto xtod2sec; - else - return(-1L); - - if (isdigit(*t)) /* Minutes */ - mm = *t++ - '0'; - else - return(-1L); - if (isdigit(*t)) - mm = mm * 10 + *t++ - '0'; - if (mm > 60L) - return(-1L); - if (*t == ':') - t++; - else if (!*t) - goto xtod2sec; - else - return(-1L); - - if (isdigit(*t)) /* Seconds */ - ss = *t++ - '0'; - else - return(-1L); - if (isdigit(*t)) - ss = ss * 10 + *t++ - '0'; - if (ss > 60L) - return(-1L); - - if (*t > 32) /* No trailing junk allowed */ - return(-1L); - - xtod2sec: - - t2 = hh * 3600L + mm * 60L + ss; /* Seconds since midnight from arg */ - debug(F101,"tod2sec t2","",t2); - - return(t2); -} - -int waitinterval = 1; - -#ifdef OLDWAIT -#undef OLDWAIT -#endif /* OLDWAIT */ - -int kbchar = NUL; - -int -dopaus(cx) int cx; { - long zz; - extern int sleepcan; - -#ifdef OLDWAIT - zz = -1L; - x_ifnum = 1; /* Turn off internal complaints */ - if (cx == XXWAI) - y = cmnum("seconds to wait, or time of day hh:mm:ss","1",10,&x,xxstring); - else if (cx == XXPAU) - y = cmnum("seconds to pause, or time of day hh:mm:ss", - "1",10,&x,xxstring); - else - y = cmnum("milliseconds to sleep, or time of day hh:mm:ss", - "100",10,&x,xxstring); - x_ifnum = 0; - if (y < 0) { - if (y == -2) { /* Invalid number or expression */ - char *p = tmpbuf; /* Retrieve string from atmbuf */ - int n = TMPBUFSIZ; - *p = NUL; - zzstring(atmbuf,&p,&n); /* Evaluate in case it's a variable */ - zz = tod2sec(tmpbuf); /* Convert to secs since midnight */ - if (zz < 0L) { - printf("?Number, expression, or time of day required\n"); - return(-9); - } else { - char now[32]; /* Current time */ - char *p; - long tnow; - p = now; - ztime(&p); - tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17); - if (zz < tnow) /* User's time before now */ - zz += 86400L; /* So make it tomorrow */ - zz -= tnow; /* Seconds from now. */ - } - } else - return(y); - } - if (x < 0) x = 0; - switch (cx) { - case XXPAU: /* PAUSE */ - case XXMSL: /* MSLEEP */ - if ((y = cmcfm()) < 0) return(y); - break; - case XXWAI: /* WAIT */ - z = 0; /* Modem signal mask */ - while (1) { /* Read zero or more signal names */ - y = cmkey(mstab,nms,"modem signal","",xxstring); - if (y == -3) break; /* -3 means they typed CR */ - if (y < 0) return(y); /* Other negatives are errors */ - z |= y; /* OR the bit into the signal mask */ - } - if ((y = cmcfm()) < 0) return(y); - break; - - default: /* Shouldn't happen */ - return(-2); - } - -/* Command is entered, now do it. */ - - if (zz > -1L) { /* Time of day given? */ - x = zz; - if (zz != (long) x) { - printf( -"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n" - ); - return(-9); - } - } - if (cx == XXMSL) { /* Millisecond sleep */ - msleep(zz < 0 ? x : x * 1000); - return(success = 1); - } - if (cx == XXPAU && !sleepcan) { /* SLEEP CANCELLATION is OFF */ - sleep(x); - return(success = 1); - } - - /* WAIT, or else SLEEP with cancellation allowed... */ - - do { /* Sleep loop */ - int mdmsig; - if (sleepcan) { /* Keyboard cancellation allowed? */ - if (y = conchk()) { /* Did they type something? */ -#ifdef COMMENT - while (y--) coninc(0); /* Yes, gobble it all up */ -#else - /* There is a debate over whether PAUSE should absorb */ - /* its cancelling character(s). There are several */ - /* reasons why it should gobble at least one character: */ - /* (1) MS-DOS Kermit does it */ - /* (2) if not, subsequent PAUSE commands will terminate */ - /* immediately */ - /* (3) if not, subsequent ASK commands will use it as */ - /* valid input. If \13, then it will get no input */ - /* (4) if not, then the character appears on the command */ - /* line after all enclosing macros are complete. */ - kbchar = coninc(0); /* Gobble one up */ -#endif /* COMMENT */ - break; /* And quit PAUSing or WAITing */ - } - } - if (cx == XXWAI) { /* WAIT (z == modem signal mask) */ - debug(F101,"WAIT x","",x); - if (z > 0) { /* Looking for any modem signals? */ - mdmsig = ttgmdm(); /* Yes, get them */ - if (mdmsig < 0) /* Failed */ - return(success = 0); - if ((mdmsig & z) == z) /* Got what we wanted? */ - return(success = 1); /* Succeed */ - } - if (x == 0) /* WAIT 0 and didn't get our signals */ - break; - } - sleep(1); /* No interrupt, sleep one second */ - } while (--x > 0); - - if (cx == XXWAI) /* If WAIT and loop exhausted */ - success = (z == 0); /* Fail. */ - else /* */ - success = (x == 0); /* Set SUCCESS/FAILURE for PAUSE. */ - return(success); - -#else /* New code uses chained FDBs and allows FILE waits... */ - - char * m = ""; /* Help message */ - struct FDB nu, fl; /* Parse function descriptor blocks */ - int filewait = 0; - int mdmsig = 0, fs = 0; - char filedate[32]; - - kbchar = 0; - - switch (cx) { - case XXWAI: m = "seconds to wait, or time of day hh:mm:ss"; break; - case XXPAU: m = "seconds to pause, or time of day hh:mm:ss"; break; - case XXMSL: m = "milliseconds to sleep, or time of day hh:mm:ss"; break; - } - zz = -1L; - cmfdbi(&nu, - _CMNUM, /* Number */ - m, /* Help message */ - (cx == XXMSL) ? "100" : "1", /* Default */ - "", /* N/A */ - 0, /* N/A */ - 0, /* N/A */ - xxstring, /* Processing function */ - NULL, /* N/A */ - &fl /* Next */ - ); - cmfdbi(&fl, /* Time of day */ - _CMFLD, /* Field */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, /* processing func */ - NULL, /* N/A */ - NULL /* No next */ - ); - x = cmfdb(&nu); /* Parse a number or a field */ - if (x < 0) { - if (x == -3) - x = -2; - return(x); - } - switch (cmresult.fcode) { - case _CMNUM: /* Number */ - x = cmresult.nresult; - break; - case _CMFLD: /* Field */ - zz = tod2sec(cmresult.sresult); /* Convert to secs since midnight */ - if (zz < 0L) { - printf("?Number, expression, or time of day required\n"); - return(-9); - } else { - char now[32]; /* Current time */ - char *p; - long tnow; - p = now; - ztime(&p); - tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17); - if (zz < tnow) /* User's time before now */ - zz += 86400L; /* So make it tomorrow */ - zz -= tnow; /* Seconds from now. */ - } - } - debug(F101,"PAUSE/WAIT/MSLEEP zz","",zz); - switch (cx) { - case XXPAU: /* PAUSE */ - case XXMSL: /* MSLEEP */ - if ((y = cmcfm()) < 0) return(y); - break; - case XXWAI: /* WAIT */ - z = 0; /* Modem signal mask */ - y = cmkey(waittab,nwaittab,"","",xxstring); - if (y < 0) { - if (y == -3) { - if ((y = cmcfm()) < 0) - return(y); - break; - } else - return(y); - } - if (y == WAIT_FIL) { /* FILE */ - int wild = 0; - if ((z = cmkey(wfswi,nwfswi,"event","",xxstring)) < 0) - return(z); - filewait = z; - if (filewait == WF_MOD || filewait == WF_DEL) - z = cmifi("Filename","",&s,&wild,xxstring); - else - z = cmfld("Filename","",&s,xxstring); - if (z < 0) - return(z); - if (wild || ((filewait == WF_CRE) && iswild(s))) { - printf("?Wildcards not valid here\n"); - return(-9); - } - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - if ((z = cmcfm()) < 0) - return(z); - break; - } else if (y != WAIT_MDM) { /* A modem signal */ - z |= y; /* OR the bit into the signal mask */ - } - if (!filewait) { /* Modem signals... */ - while (1) { /* Get zero or more signal names */ - y = cmkey(mstab,nms,"modem signal","",xxstring); - if (y == -3) break; /* -3 means they typed CR */ - if (y < 0) return(y); /* Other negatives are errors */ - z |= y; /* OR the bit into the signal mask */ - } - if ((y = cmcfm()) < 0) return(y); - break; - } - - default: /* Shouldn't happen */ - return(-2); - } /* switch (cx) */ - -/* Command is entered, now do it. */ - - if (zz > -1L) { /* Time of day given? */ - x = zz; - if (zz != (long) x) { - printf( -"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n" - ); - return(-9); - } - } - if (sleepcan) - concb((char)escape); /* Ensure single-char wakeup */ - - if (cx == XXMSL) { /* Millisecond sleep */ - msleep(zz < 0 ? x : x * 1000); - return(success = 1); - } - if (cx == XXPAU && !sleepcan) { /* SLEEP CANCELLATION is OFF */ - sleep(x); - return(success = 1); - } - if (filewait) { /* FILE... */ - fs = zchki(tmpbuf); /* Check if file exists */ - switch (filewait) { - case WF_DEL: - if (fs == -1) - return(success = 1); - break; - case WF_MOD: - if (fs == -1) { - printf("?File does not exit: %s\n",tmpbuf); - return(-9); - } - s = zfcdat(tmpbuf); /* Get current modification date */ - if (!s) s = ""; - if (ckstrncpy(filedate,s,32) != 17) { - printf("?Can't get modification time: %s\n",tmpbuf); - return(-9); - } - break; - case WF_CRE: - if (fs > -1) - return(success = 1); - break; - } - } - do { /* Polling loop */ - if (sleepcan) { /* Keyboard cancellation allowed? */ - if ((y = conchk()) > 0) { /* Did they type something? */ - kbchar = coninc(0); /* Yes, get first char they typed */ - debug(F000,"WAIT kbchar","",kbchar); -#ifdef COMMENT - while (--y > 0) /* Gobble the rest up */ - coninc(0); -#endif /* COMMENT */ - return(success = 0); /* And quit PAUSing or WAITing */ - } - } - if (filewait == 0) { - if (cx == XXWAI) { /* WAIT for modem signals */ - if (z != 0) { - mdmsig = ttgmdm(); /* Get them. */ - debug(F101,"WAIT ttgmdm","",mdmsig); - if (mdmsig < 0) /* Failure to get them? */ - return(success = 0); /* Fail. */ - if ((mdmsig & z) == z) /* Got desired ones? */ - return(success = 1); /* Succeed. */ - } else if (x == 0) - return(success = 0); - } - } else { /* FILE... */ - fs = zchki(tmpbuf); /* Get file status */ - if (filewait == WF_MOD) { /* Wait for modification */ - if (fs == -1) /* Failure to get status */ - return(success = 0); /* so WAIT fails. */ - s = zfcdat(tmpbuf); /* Get current modification time */ - if (!s) s = ""; /* And compare with the time */ - if (strcmp(s,filedate)) /* when the WAIT started */ - return(success = 1); - } else if (filewait == WF_DEL) { /* Wait for deletion */ - if (fs == -1) /* If file doesn't exist, */ - return(success = 1); /* succeed. */ - } else if (filewait == WF_CRE) { /* Wait for creation */ - if (fs != -1) /* If file exists */ - return(success = 1); /* succeed. */ - } - } - if (x < 1) /* SLEEP/WAIT/PAUSE 0 */ - break; - sleep(waitinterval); /* No interrupt, sleep */ - x -= waitinterval; /* Deduct sleep time */ - } while (x > 0); - - if (cx == XXWAI) /* WAIT time expired */ - success = (z == 0); /* Succeed if no modem signals */ - else /* For SLEEP or PAUSE, success */ - success = (x == 0); /* depends on whether it was */ - return(success); /* interrupted from the keyboard. */ -#endif /* OLDWAIT */ -} -#endif /* NOSPL */ - -#ifdef OS2ORUNIX -_PROTOTYP(int zcmpfn,(char *, char *)); -#endif /* OS2ORUNIX */ - -#ifndef NOFRILLS -#ifdef NT -int -dolink() { - /* Parse a file or a directory name */ - int i, x, z, listing = 0, havename = 0, wild = 0, rc = 1; - struct FDB sw, fi; - - cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */ - _CMKEY, /* fcode */ - "Filename or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nqvswtab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - qvswtab, /* Keyword table */ - &fi /* Pointer to next FDB */ - ); - - cmfdbi(&fi, /* 1st FDB - file to type */ - _CMIFI, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 3, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - while (!havename) { - x = cmfdb(&sw); /* Parse something */ - if (x < 0) /* Error */ - return(x); - switch (cmresult.fcode) { - case _CMKEY: - switch (cmresult.nresult) { - case DEL_LIS: - case DEL_VRB: - listing = 1; - break; - case DEL_NOL: - case DEL_QUI: - listing = 0; - break; - } - break; - case _CMIFI: - s = cmresult.sresult; - havename = 1; - break; - default: - return(-2); - } - } - wild = cmresult.nresult; /* Source specification wild? */ - - ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */ - s = line; - - if (!wild) - wild = iswild(line); - - p = tmpbuf; /* Place for new name */ - if ((x = cmofi(wild ? "Target directory" : "New name", - "",&s,xxstring)) < 0) { /* Get new name */ - if (x == -3) { - printf("?%s required\n", wild ? "Target directory" : "New name"); - return(-9); - } else return(x); - } - ckstrncpy(p,s,TMPBUFSIZ); /* Make a safe copy of the new name */ - if ((y = cmcfm()) < 0) return(y); - - if (!wild) { /* Just one */ - if (listing) printf("%s => %s ",line,p); - if (zlink(line,p) < 0) { - if (listing) printf("(FAILED: %s\n",ck_errstr()); - rc = 0; - } else { - if (listing) printf("(OK)\n"); - } - return(success = rc); - } - if (!isdir(p)) { /* Multiple */ - printf( /* if target is not a directory */ -"?Multiple source files not allowed if target is not a directory.\n"); - return(-9); - } -#ifdef COMMENT - else { /* Show full path of target */ - char buf[CKMAXPATH]; /* (too much) */ - if (zfnqfp(p,CKMAXPATH,buf)) - ckstrncpy(tmpbuf,buf,TMPBUFSIZ); - } -#endif /* COMMENT */ - -#ifdef VMS - conres(); /* Let Ctrl-C work. */ -#endif /* VMS */ - debug(F110,"dolink line",line,0); - -#ifdef ZXREWIND - z = zxrewind(); /* Rewind file list */ -#else - z = nzxpand(s,0); /* Expand file list */ -#endif /* ZXREWIND */ - debug(F111,"dolink p",p,z); - -#ifdef UNIX - if (wild && z > 1) - sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */ -#endif /* UNIX */ - - while (z-- > 0) { - if (!(z == 0 && !wild)) - znext(line); - if (!line[0]) - break; - if (listing) printf("%s => %s ",line,p); - if (zlink(line,p) < 0) { - if (listing) printf("(FAILED: %s\n",ck_errstr()); - rc = 0; - } else { - if (listing) printf("(OK)\n"); - } - } -#ifdef VMS - concb((char)escape); -#endif /* VMS */ - return(success = rc); -} -#endif /* NT */ - -#ifdef ZCOPY -int -docopy() { - int i, x, listing = 0, nolist = 0, havename = 0; - struct FDB sw, fi; - int targetisdir = 0; - int targetlen = 0; - int swapping = 0; - int appending = 0; - int fromb64 = 0; - int tob64 = 0; - int wild = 0; - int rc = 1; - - cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */ - _CMKEY, /* fcode */ - "Filename or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - ncopytab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - copytab, /* Keyword table */ - &fi /* Pointer to next FDB */ - ); - cmfdbi(&fi, /* 1st FDB - file to type */ - _CMIFI, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - while (!havename) { - x = cmfdb(&sw); /* Parse something */ - if (x < 0) /* Error */ - return(x); - switch (cmresult.fcode) { - case _CMKEY: - switch (cmresult.nresult) { - case DEL_LIS: - case DEL_VRB: - nolist = 0; - listing = 1; - break; - case DEL_NOL: - case DEL_QUI: - nolist = 1; - listing = 0; - break; - case 999: - swapping = 1; - break; - case 998: - appending = 1; - break; -#ifndef NOSPL - case 997: - fromb64 = 1; - break; - case 996: - tob64 = 1; - break; -#endif /* NOSPL */ - } - break; - case _CMIFI: - s = cmresult.sresult; - havename = 1; - break; - default: - return(-2); - } - } - wild = cmresult.nresult; - ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */ - s = line; - p = tmpbuf; /* Place for new name */ - - /* Get destination name */ - if ((x = cmofi("destination name and/or directory", -#ifdef UNIX - "." -#else - "" -#endif /* UNIX */ - ,&s,xxstring)) < 0) { - if (x == -3) { - printf("?Name for destination file required\n"); - return(-9); - } else return(x); - } - ckstrncpy(p,s,TMPBUFSIZ); /* Safe copy of destination name */ - if ((y = cmcfm()) < 0) return(y); - if (appending && swapping) { - printf("?Sorry, /APPEND and /SWAP conflict\n"); - return(-9); - } -#ifdef COMMENT -/* - This unreasonably prevented "COPY /APPEND *.* bifile" from concatenating - a bunch of files into one big file. -*/ - if (appending && wild) { - printf("?Sorry, /APPEND can be used only with single files\n"); - return(-9); - } -#endif /* COMMENT */ - targetisdir = isdir(p); - x = strlen(p); - if (targetisdir) { -#ifdef UNIXOROSK - if (p[x-1] != '/') { - ckstrncat(p,"/",TMPBUFSIZ); - x++; - } -#else -#ifdef OS2 - if (p[x-1] != '/') { - ckstrncat(p,"/",TMPBUFSIZ); - x++; - } -#else -#ifdef STRATUS - if (p[x-1] != '>') { - ckstrncat(p,">",TMPBUFSIZ); - x++; - } -#else -#ifdef datageneral - if (p[x-1] != ':') { - ckstrncat(p,":",TMPBUFSIZ); - x++; - } -#else - if (p[x-1] != '/') { - ckstrncat(p,"/",TMPBUFSIZ); - x++; - } -#endif /* datageneral */ -#endif /* STRATUS */ -#endif /* OS2 */ -#endif /* UNIXOROSK */ - } - targetlen = x; - - if (!appending) { /* If /APPEND not given */ - if (wild && !targetisdir) { /* No wildcards allowed */ - printf( /* if target is not a directory */ -"?Multiple source files not allowed if target is not a directory.\n"); - return(-9); - } - } - -#ifdef VMS - conres(); /* Let Ctrl-C work. */ -#endif /* VMS */ - debug(F110,"docopy line",line,0); - debug(F110,"docopy p",p,0); - -#ifdef ZXREWIND - z = zxrewind(); /* Rewind file list */ -#else - z = nzxpand(s,0); /* Expand file list */ -#endif /* ZXREWIND */ - -#ifdef UNIX - if (wild) - sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */ -#endif /* UNIX */ - -#ifdef IKSD - if (!targetisdir && zchki(p) > -1) { /* Destination file exists? */ - if (inserver && (!ENABLED(en_del) -#ifdef CK_LOGIN - || isguest -#endif /* CK_LOGIN */ - )) { - printf("?Sorry, overwriting existing files is disabled\n"); - return(-9); - } - } -#endif /* IKSD */ - - if (tob64 && fromb64) { /* To and from B64 = no conversion */ - tob64 = 0; - fromb64 = 0; - } - debug(F110,"COPY dest",p,0); - - while (z > 0) { - - znext(line); - if (!line[0]) - break; - - errno = 0; /* Reset errno */ - - if (listing) printf("%s => %s ",line,p); - - /* Straight copy */ - if (!swapping && !appending && !fromb64 && !tob64) { - debug(F110,"COPY zcopy",line,0); - - if ((x = zcopy(line,p)) < 0) { /* Let zcopy() do it. */ - switch (x) { - case -2: - if (listing) - printf("(FAILED: Not a regular file)\n"); - else if (!nolist) - printf("?Not a regular file - %s\n",line); - rc = 0; - break; - case -3: - if (listing) - printf("(FAILED: Not found or not accessible)\n"); - else if (!nolist) - printf("?Not found or not accessible - %s\n",line); - rc = 0; - break; - case -4: - if (listing) - printf("(FAILED: Permission denied)\n"); - else if (!nolist) - printf("?Permission denied - %s\n",line); - rc = 0; - break; - case -5: - if (listing) - printf("(Source and destination are the same file)\n"); - else if (!nolist) - printf( - "?Source and destination are the same file - %s\n", - line - ); - break; - case -6: - if (listing) - printf("(FAILED: Input/Output error)\n"); - else if (!nolist) - printf("?Input/Output error - %s\n",line); - rc = 0; - break; - case -7: - if (listing) - printf("(FAILED: %s - %s)\n",p,ck_errstr()); - else if (!nolist) - printf("?%s - %s\n",ck_errstr(),p); - rc = 0; - break; - default: - if (listing) - printf("(FAILED: %s)\n",ck_errstr()); - else if (!nolist) - printf("?%s\n",ck_errstr()); - rc = 0; - } - } else { - if (listing) printf("(OK)\n"); - } - - } else { /* Special options */ - - int prev, y, x = 0; /* Variables needed for them */ - int i, t; - char ibuf[100]; - char obuf[200]; - FILE * in = NULL; - FILE * out = NULL; - - if ((in = fopen(line,"r")) == NULL) { /* Open input file */ - if (listing) - printf("(FAILED: %s)\n",ck_errstr()); - else if (!nolist) - printf("?%s - %s)\n",ck_errstr(),line); - rc = 0; - continue; - } - if (targetisdir) { /* Target is directory */ - char * buf = NULL; /* so append this filename to it */ - zstrip(line,&buf); - p[targetlen] = NUL; - if (buf) - ckstrncat(p,buf,TMPBUFSIZ); - } -#ifdef OS2ORUNIX - if (zcmpfn(line,p)) { /* Input and output are same file? */ - if (listing) - printf("(FAILED: Source and destination identical)\n"); - else if (!nolist) - printf("?Source and destination identical - %s\n", line); - rc = 0; - continue; - } -#endif /* OS2ORUNIX */ - if ((out = fopen(p, (appending ? "a" : "w"))) == NULL) { - fclose(in); - if (listing) - printf("(FAILED: %s - %s)\n",p,ck_errstr()); - else if (!nolist) - printf("?%s - %s\n",p,ck_errstr()); - rc = 0; - continue; - } -#ifndef NOSPL - if (tob64) { /* Converting to Base-64 */ - - debug(F110,"COPY tob64",line,0); - - while (1) { /* Loop... */ - prev = x; - if ((x = fread(ibuf,1,54,in)) < 1) { /* EOF */ - if (listing) - printf("(OK)\n"); - break; - } - if (prev % 3) { - if (listing) - printf("(FAILED: Phase error at %d)\n",prev); - else if (!nolist) - printf("?Phase error at %d\n",prev); - rc = 0; - break; - } - if (swapping) { - if (x & 1) { - if (listing) - printf("(FAILED: Swap error)\n"); - else if (!nolist) - printf("?Swap error\n"); - rc = 0; - break; - } - for (i = 0; i < x; i+=2) { - t = ibuf[i]; - ibuf[i] = ibuf[i+1]; - ibuf[i+1] = t; - } - } - if ((y = b8tob64(ibuf,x,obuf,180)) < 0) { - if (listing) - printf("(FAILED: Encoding error)\n"); - else if (!nolist) - printf("?Encoding error\n"); - rc = 0; - break; - } - fprintf(out,"%s\n",obuf); - } - - } else if (fromb64) { /* Converting from Base 64 */ - - debug(F110,"COPY fromb64",line,0); - - if ((out = fopen(p,appending ? "a" : "w")) == NULL) { - fclose(in); - if (listing) - printf("(FAILED: %s - %s)\n",p,ck_errstr()); - else if (!nolist) - printf("?%s - %s\n",p,ck_errstr()); - rc = 0; - continue; - } - x = 1; - while (x) { - x = fread(ibuf,1,80,in); - if ((y = b64tob8(ibuf,x,obuf,80)) < 0) { - if (listing) - printf("(FAILED: Decoding error)\n"); - else if (!nolist) - printf("?Decoding error\n"); - rc = 0; - break; - } - if (swapping) { - if (x & 1) { - if (listing) - printf("(FAILED: Swap error)\n"); - else if (!nolist) - printf("?Swap error\n"); - rc = 0; - break; - } - for (i = 0; i < y; i+=2) { - t = obuf[i]; - obuf[i] = obuf[i+1]; - obuf[i+1] = t; - } - } - if (y > 0) { - if (fwrite(obuf,1,y,out) < 1) { - if (listing) - printf("(FAILED: %s - %s)\n",p,ck_errstr()); - else if (!nolist) - printf("?%s - %s\n",p,ck_errstr()); - rc = 0; - break; - } - } - } - - } else -#endif /* NOSPL */ - - if (swapping) { /* Swapping bytes */ - - CHAR c[3]; - c[2] = NUL; - - debug(F110,"COPY swapping",line,0); - - while (1) { - x = fread((char *)c,1,2,in); - if (x < 1) { - if (listing) - printf("(OK)\n"); - break; - } else if (x == 1) { - c[1] = c[0]; - c[0] = NUL; - printf( - "(WARNING: Odd byte count)"); - if (!listing) printf("\n"); - } - if (fprintf(out,"%c%c",c[1],c[0]) == EOF) { - if (listing) - printf("(FAILED: %s - %s)\n",p,ck_errstr()); - else if (!nolist) - printf("?%s - %s\n",p,ck_errstr()); - rc = 0; - break; - } - } - - } else if (appending) { /* Appending to target file */ - - char c; - - debug(F110,"COPY appending",line,0); - - while (1) { - x = fread(&c,1,1,in); - if (x < 1) { - if (listing) - printf("(OK)\n"); - break; - } - if (fwrite(&c,1,1,out) < 1) { - if (listing) - printf("(FAILED: %s - %s)\n",p,ck_errstr()); - else if (!nolist) - printf("?%s - %s\n",p,ck_errstr()); - rc = 0; - break; - } - } - } - if (out) fclose(out); - if (in) fclose(in); - } -#ifdef VMSORUNIX - concb((char)escape); -#endif /* VMSORUNIX */ - } - if (rc > -1) success = rc; - return(rc); -} -#endif /* ZCOPY */ -#endif /* NOFRILLS */ - -#ifndef NORENAME -#ifndef NOFRILLS -#ifdef ZRENAME -int -dorenam() { - /* Parse a file or a directory name */ - int i, x, z, listing = 0, havename = 0, wild = 0, rc = 1; - int nolist = 0; - struct FDB sw, fi; - - cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */ - _CMKEY, /* fcode */ - "Filename or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nqvswtab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - qvswtab, /* Keyword table */ - &fi /* Pointer to next FDB */ - ); - - cmfdbi(&fi, /* 1st FDB - file to type */ - _CMIFI, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 3, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - while (!havename) { - x = cmfdb(&sw); /* Parse something */ - if (x < 0) /* Error */ - return(x); - switch (cmresult.fcode) { - case _CMKEY: - switch (cmresult.nresult) { - case DEL_LIS: - case DEL_VRB: - listing = 1; - break; - case DEL_NOL: - case DEL_QUI: - nolist = 1; - listing = 0; - break; - } - break; - case _CMIFI: - s = cmresult.sresult; - havename = 1; - break; - default: - return(-2); - } - } - wild = cmresult.nresult; /* Source specification wild? */ - - ckstrncpy(line,s,LINBUFSIZ); /* Make a safe copy of source name */ - s = line; - - if (!wild) - wild = iswild(line); - - p = tmpbuf; /* Place for new name */ - if ((x = cmofi(wild ? "Target directory" : "New name", - "",&s,xxstring)) < 0) { /* Get new name */ - if (x == -3) { - printf("?%s required\n", wild ? "Target directory" : "New name"); - return(-9); - } else return(x); - } - ckstrncpy(p,s,TMPBUFSIZ); /* Make a safe copy of the new name */ - if ((y = cmcfm()) < 0) return(y); - - if (!wild) { /* Just one */ - if (listing) printf("%s => %s ",line,p); - if (zrename(line,p) < 0) { - if (listing) - printf("(FAILED: %s)\n",ck_errstr()); - else if (!nolist) - printf("?%s\n",ck_errstr()); - rc = 0; - } else { - if (listing) printf("(OK)\n"); - } - return(success = rc); - } - if (!isdir(p)) { /* Multiple */ - printf( /* if target is not a directory */ -"?Multiple source files not allowed if target is not a directory.\n"); - return(-9); - } -#ifdef COMMENT - else { /* Show full path of target */ - char buf[CKMAXPATH]; /* (too much) */ - if (zfnqfp(p,CKMAXPATH,buf)) - ckstrncpy(tmpbuf,buf,TMPBUFSIZ); - } -#endif /* COMMENT */ - -#ifdef VMS - conres(); /* Let Ctrl-C work. */ -#endif /* VMS */ - debug(F110,"dorename line",line,0); - -#ifdef ZXREWIND - z = zxrewind(); /* Rewind file list */ -#else - z = nzxpand(s,0); /* Expand file list */ -#endif /* ZXREWIND */ - debug(F111,"dorename p",p,z); - -#ifdef UNIX - if (wild && z > 1) - sh_sort(mtchs,NULL,z,0,0,filecase); /* Alphabetize the filename list */ -#endif /* UNIX */ - -/* - Note: COPY, RENAME, DELETE and similar commands should have options to - stop or proceed when they are operating on multiple files and the operation - fails. -*/ - while (z-- > 0) { - if (!(z == 0 && !wild)) - znext(line); - if (!line[0]) - break; - if (listing) printf("%s => %s ",line,p); - if (zrename(line,p) < 0) { - if (listing) - printf("(FAILED: %s)\n",ck_errstr()); - else if (!nolist) - printf("?%s - %s\n",ck_errstr(),line); - rc = 0; - } else { - if (listing) printf("(OK)\n"); - } - } -#ifdef VMS - concb((char)escape); -#endif /* VMS */ - return(success = rc); -} -#endif /* ZRENAME */ -#endif /* NOFRILLS */ -#endif /* NORENAME */ - -#ifndef NOSPL - -/* Do the RETURN command */ - -int -doreturn(s) char *s; { - int x; - extern int tra_asg; - char * line, * lp; - - if (cmdlvl < 1) { - printf("\n?Can't return from level %d\n",maclvl); - return(success = 0); - } - line = malloc(LINBUFSIZ); - if (line == NULL) - return(success = 0); - lp = line; /* Expand return value now */ - x = LINBUFSIZ-1; - if (!s) s = ""; - debug(F110,"RETURN s",s,0); - if (zzstring(s,&lp,&x) > -1) { - s = line; - debug(F110,"RETURN zzstring",s,0); - } - - /* Pop from all FOR/WHILE/SWITCH/XIFs */ - while ((maclvl > 0) && - (m_arg[maclvl-1][0]) && - (cmdstk[cmdlvl].src == CMD_MD) && - (!strncmp(m_arg[maclvl-1][0],"_xif",4) || - !strncmp(m_arg[maclvl-1][0],"_for",4) || - !strncmp(m_arg[maclvl-1][0],"_swi",4) || - !strncmp(m_arg[maclvl-1][0],"_whi",4))) { - debug(F111,"RETURN IF/FOR/WHI/SWI pop",m_arg[maclvl-1][0],maclvl); - dogta(XXPTA); /* Put args back */ - popclvl(); /* Pop up two levels */ - popclvl(); - } - if (tra_asg) { /* If tracing show return value */ - if (*s) - printf("<<< %s: \"%s\"\n", m_arg[maclvl][0], s); - else - printf("<<< %s: (null)\n", m_arg[maclvl][0]); - } - popclvl(); /* Pop from enclosing TAKE or macro */ - debug(F111,"RETURN tolevel",s,maclvl); - if (!s) s = ""; - if (!*s) s = NULL; - makestr(&(mrval[maclvl+1]),s); /* Set the RETURN value */ - free(line); - return(success = 1); /* Macro succeeds if we RETURN */ -} -#endif /* NOSPL */ - -#ifndef NOSPL -/* Do the OPEN command */ - -int -doopen() { /* OPEN { append, read, write } */ - int x, y, z = 0; char *s; - static struct filinfo fcb; /* (must be static) */ - if ((x = cmkey(opntab,nopn,"mode","",xxstring)) < 0) { - if (x == -3) { - printf("?Mode required\n"); - return(-9); - } else return(x); - } - switch (x) { - case OPN_FI_R: /* Old file (READ) */ - if (chkfn(ZRFILE) > 0) { - printf("?Read file already open\n"); - return(-2); - } - if ((z = cmifi("File to read","",&s,&y,xxstring)) < 0) { - if (z == -3) { - printf("?Input filename required\n"); - return(-9); - } else return(z); - } - if (y) { /* No wildcards allowed */ - printf("\n?Please specify a single file\n"); - return(-2); - } - ckstrncpy(line,s,LINBUFSIZ); - if ((int)strlen(line) < 1) return(-2); - if ((z = cmnum("buffer size","4096",10,&y,xxstring)) < 0) - return(z); - if (y < 1) { - printf("?Positive number required\n"); - return(-9); - } - if ((z = cmcfm()) < 0) return(z); - readblock = y; - if (readbuf) - free((char *)readbuf); - if (!(readbuf = (CHAR *) malloc(readblock+1))) { - printf("?Can't allocate read buffer\n"); - return(-9); - } - return(success = zopeni(ZRFILE,line)); - -#ifndef MAC -#ifndef NOPUSH - case OPN_PI_R: /* Pipe/Process (!READ) */ - if (nopush) { - printf("?Read from pipe disabled\n"); - return(success=0); - } - if (chkfn(ZRFILE) > 0) { - printf("?Read file already open\n"); - return(-2); - } - if ((y = cmtxt("System command to read from","",&s,xxstring)) < 0) { - if (y == -3) { - printf("?Command name required\n"); - return(-9); - } else return(y); - } - ckstrncpy(line,brstrip(s),LINBUFSIZ); - if (!line[0]) return(-2); - if ((y = cmcfm()) < 0) return(y); - if (!readbuf) { - if (!(readbuf = (CHAR *) malloc(readblock+1))) { - printf("?Can't allocate read buffer\n"); - return(-9); - } - } - return(success = zxcmd(ZRFILE,line)); - - case OPN_PI_W: /* Write to pipe */ - if (nopush) { - printf("?Write to pipe disabled\n"); - return(success=0); - } - if (chkfn(ZWFILE) > 0) { - printf("?Write file already open\n"); - return(-2); - } - if ((y = cmtxt("System command to write to","",&s,xxstring)) < 0) { - if (y == -3) { - printf("?Command name required\n"); - return(-9); - } else return(y); - } - ckstrncpy(line,brstrip(s),LINBUFSIZ); - if (!line[0]) return(-2); - if ((y = cmcfm()) < 0) return(y); - success = zxcmd(ZWFILE,line); - if (!success && msgflg) - printf("Can't open process for writing: %s\n",line); - return(success); -#endif /* NOPUSH */ -#endif /* MAC */ - - case OPN_FI_W: /* New file (WRITE) */ - case OPN_FI_A: /* (APPEND) */ - if ((z = cmofi("Name of local file to create","",&s,xxstring)) < 0) { - if (z == -3) { - printf("?Filename required\n"); - return(-9); - } else return(z); - } - if (z == 2) { - printf("?Sorry, %s is a directory name\n",s); - return(-9); - } - if (chkfn(ZWFILE) > 0) { - printf("?Write/Append file already open\n"); - return(-2); - } - fcb.bs = fcb.cs = fcb.rl = fcb.fmt = fcb.org = fcb.cc = fcb.typ = 0; - fcb.lblopts = 0; - fcb.dsp = (x == OPN_FI_W) ? XYFZ_N : XYFZ_A; /* Create or Append */ - ckstrncpy(line,s,LINBUFSIZ); - if ((int)strlen(line) < 1) return(-2); - if ((y = cmcfm()) < 0) return(y); - return(success = zopeno(ZWFILE,line,NULL,&fcb)); - -#ifndef NOLOCAL - case OPN_SER: /* OPEN PORT or LINE */ - case OPN_NET: { /* OPEN HOST */ - extern int didsetlin, ttnproto; - if (x == OPN_NET) { - z = ttnproto; - ttnproto = NP_NONE; - } - if ((y = setlin((x == OPN_SER) ? XYLINE : XYHOST, 1, 0)) < 0) { - if (x == OPN_NET) - ttnproto = z; - success = 0; - } - didsetlin++; - return(y); - } -#endif /* NOLOCAL */ - - default: - printf("?Not implemented"); - return(-2); - } -} -#endif /* NOSPL */ - -#ifndef NOXFER -/* D O X G E T -- GET command parser with switches */ - -#ifdef CK_LABELED -int g_lf_opts = -1; -extern int lf_opts; -#endif /* CK_LABELED */ - -int -doxget(cx) int cx; { - extern int /* External variables we need */ -#ifdef RECURSIVE - recursive, -#endif /* RECURSIVE */ - xfermode, fdispla, protocol, usepipes, - g_binary, g_xfermode, g_displa, g_rpath, g_usepipes; - extern char * rcv_move; /* Directory to move new files to */ - extern char * rcv_rename; /* What to rename new files to */ - extern char * rcvexcept[]; /* RECEIVE / GET exception list */ - int opkt = 0; /* Flag for O-Packet needed */ - -#ifdef PIPESEND - extern int pipesend; - extern char * rcvfilter; -#endif /* PIPESEND */ - extern struct keytab rpathtab[]; - extern int nrpathtab; - extern long calibrate; - int asname = 0; /* Flag for have as-name */ - int konly = 0; /* Kermit-only function */ - int c, i, n, confirmed = 0; /* Workers */ - int getval = 0; /* Whether to get switch value */ - int rcvcmd = 0; /* Whether it is the RECEIVE command */ - int mget = 0; /* Whether it is the MGET command */ - struct stringint { /* Temporary array for switch values */ - char * sval; - int ival; - } pv[SND_MAX+1]; - struct FDB sw, fl, cm; /* FDBs for each parse function */ - char * cmdstr = "this command"; - -#ifdef NEWFTP - if (cx == XXGET || cx == XXREGET || cx == XXMGET || cx == XXRETR) { - extern int ftpget; - extern int ftpisopen(); - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) - return(doftpget(cx,0)); - } -#endif /* NEWFTP */ - - debug(F101,"xget cx","",cx); - - oopts = -1; - omode = -1; - - for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */ - pv[i].sval = NULL; - pv[i].ival = -1; - } - /* Preset switch values based on top-level command that called us */ - - switch (cx) { - case XXREC: /* RECEIVE */ - cmdstr = "RECEIVE"; - rcvcmd = 1; break; - case XXGET: /* GET */ - cmdstr = "GET"; - konly = 1; - break; -#ifdef CK_RESEND - case XXREGET: /* REGET */ - cmdstr = "REGET"; - konly = 1; - pv[SND_BIN].ival = 1; /* Implies /BINARY */ - pv[SND_RES].ival = 1; break; -#endif /* CK_RESEND */ - case XXRETR: /* RETRIEVE */ - cmdstr = "RETRIEVE"; - konly = 1; - pv[SND_DEL].ival = 1; break; -#ifdef PIPESEND - case XXCREC: /* CRECEIVE */ - cmdstr = "CRECEIVE"; - konly = 1; - rcvcmd = 1; - pv[SND_CMD].ival = 1; break; - case XXCGET: /* CGET */ - cmdstr = "CGET"; - konly = 1; - pv[SND_CMD].ival = 1; break; -#endif /* PIPESEND */ -#ifndef NOMGET - case XXMGET: /* MGET */ - cmdstr = "MGET"; - konly = 1; - mget = 1; break; -#endif /* NOMGET */ - } - debug(F111,"xget rcvcmd",cmdstr,rcvcmd); - debug(F101,"xget konly","",konly); - -#ifdef CK_XYZ - if (!rcvcmd && protocol != PROTO_K) { - printf("?Sorry, %s works only with Kermit protocol\n",cmdstr); - return(-9); - } -#endif /* CK_XYZ */ - - /* Set up chained parse functions... */ - - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - rcvcmd ? - "Optional name/template to store incoming files under, or switch" : - "Remote filename, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - rcvcmd ? nrcvtab : ngettab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - rcvcmd ? rcvtab : gettab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - if (rcvcmd || mget) /* RECEIVE or MGET */ - cmfdbi(&fl, - _CMTXT, /* fcode */ - rcvcmd ? /* hlpmsg */ - "Output filename or Command" : /* Output filename */ - "File(s) to GET", /* Files we are asking for */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ -#ifdef CK_XYZ - (protocol == PROTO_X || protocol == PROTO_XC) ? - xxstring : - (rcvcmd ? (xx_strp)0 : xxstring) -#else - rcvcmd ? (xx_strp)0 : xxstring /* Processing function */ -#endif /* CK_XYZ */ - , - NULL, - &cm - ); - else - cmfdbi(&fl, /* Remote filename or command */ - _CMFLD, /* fcode */ - "Remote filename", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - &cm - ); - cmfdbi(&cm, /* Confirmation */ - _CMCFM, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - NULL, - NULL, - NULL - ); - - /* (See doxsend() for fuller commentary) */ - - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - debug(F101,"xget cmfdb","",x); - if (x < 0) /* Error */ - goto xgetx; /* or reparse needed */ - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); /* Get break character */ - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - x = -9; - goto xgetx; - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - x = -9; - goto xgetx; - } - n = cmresult.nresult; /* Numeric result = switch value */ - debug(F101,"xget switch","",n); - - switch (n) { /* Process the switch */ -#ifdef PIPESEND - case SND_CMD: /* These take no args */ - if (nopush) { - printf("?Sorry, system command access is disabled\n"); - x = -9; - goto xgetx; - } else if (rcvfilter) { - printf( -"?Sorry, no GET /COMMAND when RECEIVE FILTER selected\n"); - x = -9; - goto xgetx; - } - if (rcvcmd) - sw.hlpmsg = "Command, or switch"; /* Change help message */ - /* Fall thru... */ -#endif /* PIPESEND */ - - case SND_REC: /* /RECURSIVE */ - pv[SND_PTH].ival = PATH_REL; /* Implies relative pathnames */ - pv[n].ival = 1; /* Set the recursive flag */ - break; - - case SND_RES: /* /RECOVER */ - pv[SND_BIN].ival = 1; /* Implies /BINARY */ - pv[n].ival = 1; /* Set the resend flag */ - break; - - case SND_DEL: /* /DELETE */ - case SND_SHH: /* /QUIET */ - case SND_CAL: /* /CALIBRATE */ - case SND_XPA: /* /TRANSPARENT */ - pv[n].ival = 1; /* Just set the appropriate flag */ - break; - - case SND_PIP: /* /PIPES:{ON,OFF} */ - if (!getval) { - pv[n].ival = 1; - break; - } - if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) - goto xgetx; - if (!nopush) - pv[n].ival = x; - break; - - /* File transfer modes - each undoes the others */ - - case SND_BIN: /* Binary */ - case SND_TXT: /* Text */ - case SND_IMG: /* Image */ - case SND_LBL: /* Labeled */ - pv[SND_BIN].ival = 0; /* Unset all */ - pv[SND_TXT].ival = 0; - pv[SND_IMG].ival = 0; - pv[SND_LBL].ival = 0; - pv[n].ival = 1; /* Set the requested one */ - break; - - case SND_EXC: /* Excludes */ - if (!getval) break; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Pattern required\n"); - x = -9; - } - goto xgetx; - } - if (pv[n].sval) free(pv[n].sval); - y = strlen(s); - if (y > 256) { - printf("?Pattern too long - 256 max\n"); - x = -9; - goto xgetx; - } - pv[n].sval = malloc(y+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - break; - -#ifdef COMMENT - /* Not implemented */ - case SND_PRI: /* GET to printer */ - pv[n].ival = 1; - if (!getval) break; - if ((x = cmfld("Print options","",&s,xxstring)) < 0) - goto xgetx; - pv[n].sval = malloc((int)strlen(s)+1); - if (pv[n].sval) - strcpy(pv[n].sval,s); /* safe */ - break; -#endif /* COMMENT */ - - case SND_MOV: /* MOVE after */ - case SND_REN: /* RENAME after */ - if (!getval) break; - if ((x = cmfld(n == SND_MOV ? - "device and/or directory for source file after sending" : - "new name for source file after sending", - "", - &s, - n == SND_MOV ? xxstring : NULL - )) < 0) { - if (x == -3) { - printf("%s\n", n == SND_MOV ? - "?Destination required" : - "?New name required" - ); - x = -9; - } - goto xgetx; - } - if (pv[n].sval) { - free(pv[n].sval); - pv[n].sval = NULL; - } - s = brstrip(s); - y = strlen(s); - if (y > 0) { - pv[n].sval = malloc(y+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - } - break; - - case SND_ASN: /* As-name */ - if (!getval) break; - if (mget) { - printf("?Sorry, as-name not allowed with MGET\n"); - x = -9; - goto xgetx; - } - if ((x = cmfld("Name to store it under","",&s,NULL)) < 0) - goto xgetx; - s = brstrip(s); - if ((y = strlen(s)) > 0) { - if (pv[n].sval) free(pv[n].sval); - pv[n].sval = malloc(y+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - } - break; - -#ifdef PIPESEND - case SND_FLT: /* Filter */ - debug(F101,"xget /filter getval","",getval); - if (!getval) break; - if ((x = cmfld("Filter program to receive through", - "",&s,NULL)) < 0) { - if (x == -3) - s = ""; - else - goto xgetx; - } - if (*s) s = brstrip(s); - y = strlen(s); - for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */ - if (s[x] != '\\') continue; - if (s[x+1] == 'v') break; - } - if (x == y) { - printf( - "?Filter must contain a replacement variable for filename.\n" - ); - x = -9; - goto xgetx; - } - pv[n].ival = 1; - if (pv[n].sval) { - free(pv[n].sval); - pv[n].sval = NULL; - } - if ((y = strlen(s)) > 0) { - if ((pv[n].sval = malloc(y+1))) - strcpy(pv[n].sval,s); /* safe */ - } - break; -#endif /* PIPESEND */ - - case SND_PTH: /* Pathnames */ - if (!getval) { - pv[n].ival = PATH_REL; - break; - } - if ((x = cmkey(rpathtab,nrpathtab,"","on",xxstring)) < 0) - goto xgetx; - pv[n].ival = x; /* Ditto */ - break; - - case SND_NAM: /* Filenames */ - if (!getval) break; - if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0) - goto xgetx; - pv[n].ival = x; - break; - - case SND_PRO: /* Protocol to use */ - if (!getval) break; - if ((x = cmkey(protos,nprotos,"File-transfer protocol","", - xxstring)) < 0) { - if (x == -3) - x = 0; - else - goto xgetx; - } - debug(F111,"xget /proto",atmbuf,x); - pv[n].ival = x; - if (konly && x != PROTO_K) { - printf( -"?Sorry, this command works only with Kermit protocol\n" - ); - x = -9; - goto xgetx; - } - break; - - default: - printf("?Unexpected switch value - %d\n",cmresult.nresult); - x = -9; - goto xgetx; - } - } - debug(F101,"xget cmresult fcode","",cmresult.fcode); - - cmarg = line; /* Initialize string pointers */ - cmarg2 = tmpbuf; - asname = 0; - line[0] = NUL; /* and buffers. */ - tmpbuf[0] = NUL; - - switch (cmresult.fcode) { /* How did we get out of switch loop */ - case _CMFLD: /* (3) Remote filespec */ - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - break; - case _CMTXT: /* (4) As-name */ - if (rcvcmd) { - ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ); - if ((int)strlen(tmpbuf) > 0) - asname = 1; - } else { - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - } - case _CMCFM: /* (6) Confirmation */ - confirmed = 1; - break; - default: - printf("?Unexpected function code: %d\n",cmresult.fcode); - x = -9; - goto xgetx; - } - debug(F110,"xget string",cmarg,0); - debug(F101,"xget confirmed","",confirmed); - - cmarg = brstrip(cmarg); /* Strip any braces */ - - if (!confirmed) { /* CR not typed yet, get more fields */ - if (pv[SND_CMD].ival > 0) { - debug(F100,"xget calling cmtxt","",0); - x = cmtxt("Local command to pipe into","",&s,NULL); - if (x < 0 && x != -3) goto xgetx; - if (x != -3) { - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - asname = 1; - } - } else if (!rcvcmd) { -#ifdef VMS - /* cmofi() fails if you give it a directory name */ - x = cmfld("Name or directory for incoming file","",&s,NULL); - debug(F111,"xget cmfld",s,x); -#else - x = cmofi("Name or directory for incoming file","",&s,NULL); - debug(F111,"xget cmofi",s,x); -#endif /* VMS */ - if (x < 0 && x != -3) goto xgetx; - if (x != -3) { - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - if ((x = cmcfm()) < 0) goto xgetx; - asname = 1; - } - } - } - /* Arrive here with cmarg and cmarg2 all set */ - - debug(F111,"xget asname",cmarg2,asname); - if (!asname) { - if (pv[SND_ASN].sval) - ckstrncpy(tmpbuf,pv[SND_ASN].sval,TMPBUFSIZ); - else - tmpbuf[0] = NUL; - } - cmarg2 = brstrip(cmarg2); /* Strip outer braces if any. */ - debug(F110,"xget cmarg",cmarg,0); - debug(F110,"xget cmarg2",cmarg2,0); - - if (!*cmarg && - (cx == XXGET || cx == XXREGET || cx == XXCGET || cx == XXMGET)) { - printf("?A remote file specification is required\n"); - x = -9; - goto xgetx; - } -#ifdef PIPESEND - if (pv[SND_CMD].ival > 0) { /* /COMMAND sets pipesend flag */ - x = -9; - if (!*cmarg2) { - printf("?Command required\n"); - goto xgetx; - } else if (nopush) { - printf("?Sorry, system command access is disabled\n"); - goto xgetx; - } else if (rcvfilter) { - printf("?Sorry, no GET /COMMAND while RECEIVE FILTER selected\n"); - goto xgetx; - } else - pipesend = 1; - } - debug(F101,"xget /COMMAND pipesend","",pipesend); -#endif /* PIPESEND */ - -#ifdef CK_RESEND - if (pv[SND_RES].ival > 0) { /* REGET or GET /RECOVER */ -#ifdef RECURSIVE - if (pv[SND_REC].ival > 0) { /* RECURSIVE */ -#ifdef COMMENT - printf("?Unsupported option combination: /RECOVER /RECURSIVE\n"); - x = -9; - goto xgetx; -#else - opkt = 1; -#endif /* COMMENT */ - } -#endif /* RECURSIVE */ - if (pv[SND_DEL].ival > 0) { /* /DELETE */ -#ifdef COMMENT - printf("?Unsupported option combination: /RECOVER /DELETE\n"); - x = -9; - goto xgetx; -#else - opkt = 1; -#endif /* COMMENT */ - } - } -#endif /* CK_RESEND */ - - if (pv[SND_EXC].ival > 0) /* /EXCEPT */ - makelist(pv[SND_EXC].sval,rcvexcept,NSNDEXCEPT); - -#ifdef IKS_OPTION - if (!rcvcmd -#ifdef CK_XYZ - && protocol == PROTO_K -#endif /* CK_XYZ */ - ) { - if (!iks_wait(KERMIT_REQ_START,1)) { - printf( - "?A Kermit Server is not available to process this command\n"); - x = -9; /* correct the return code */ - goto xgetx; - } - } -#endif /* IKS_OPTION */ - -#ifdef CK_XYZ - { - int po, pg; /* (for clarity) */ - po = pv[SND_PRO].ival; /* /PROTOCOL option */ - pg = protocol; /* Protocol global */ - if ((rcvcmd && !*cmarg2) && /* If no as-name was given */ - /* and /PROTOCOL is XMODEM or global protocol is XMODEM... */ - ((po < 0 && (pg == PROTO_X || pg == PROTO_XC)) || - (po > -1 && (po == PROTO_X || po == PROTO_XC))) - ) { - printf( -"Sorry, you must specify a name when receiving a file with XMODEM protocol\n" - ); - x = -9; - goto xgetx; - } - } -#endif /* CK_XYZ */ - -#ifdef RECURSIVE - if (pv[SND_REC].ival > 0) { /* RECURSIVE */ - recursive = 1; - pv[SND_PTH].ival = PATH_REL; /* Implies relative pathnames too */ - } -#endif /* RECURSIVE */ - - if (pv[SND_PIP].ival > -1) { - g_usepipes = usepipes; - usepipes = pv[SND_PIP].ival; - } - - /* Save global protocol parameters */ - - g_proto = protocol; -#ifdef CK_LABELED - g_lf_opts = lf_opts; /* Save labeled transfer options */ -#endif /* CK_LABELED */ - g_urpsiz = urpsiz; /* Receive packet length */ - g_spsizf = spsizf; /* Send packet length flag */ - g_spsiz = spsiz; /* Send packet length */ - g_spsizr = spsizr; /* etc etc */ - g_spmax = spmax; - g_wslotr = wslotr; - g_prefixing = prefixing; - g_fncact = fncact; - g_fncnv = fncnv; - g_fnspath = fnspath; - g_fnrpath = fnrpath; - g_xfrxla = xfrxla; - - if (pv[SND_PRO].ival > -1) { /* Change according to switch */ - protocol = pv[SND_PRO].ival; - if (ptab[protocol].rpktlen > -1) /* copied from initproto() */ - urpsiz = ptab[protocol].rpktlen; - if (ptab[protocol].spktflg > -1) - spsizf = ptab[protocol].spktflg; - if (ptab[protocol].spktlen > -1) { - spsiz = ptab[protocol].spktlen; - if (spsizf) - spsizr = spmax = spsiz; - } - if (ptab[protocol].winsize > -1) - wslotr = ptab[protocol].winsize; - if (ptab[protocol].prefix > -1) - prefixing = ptab[protocol].prefix; - if (ptab[protocol].fnca > -1) - fncact = ptab[protocol].fnca; - if (ptab[protocol].fncn > -1) - fncnv = ptab[protocol].fncn; - if (ptab[protocol].fnsp > -1) - fnspath = ptab[protocol].fnsp; - if (ptab[protocol].fnrp > -1) - fnrpath = ptab[protocol].fnrp; - } - debug(F101,"xget protocol","",protocol); - debug(F111,"xget cmarg2",cmarg2,xfermode); - - g_xfermode = xfermode; - g_binary = binary; - if (pv[SND_BIN].ival > 0) { /* Change according to switch */ - xfermode = XMODE_M; - binary = XYFT_B; /* FILE TYPE BINARY */ - omode = GMOD_BIN; /* O-Packet mode */ - debug(F101,"doxget /BINARY xfermode","",xfermode); - } else if (pv[SND_TXT].ival > 0) { /* Ditto for /TEXT */ - xfermode = XMODE_M; - binary = XYFT_T; - omode = GMOD_TXT; - debug(F101,"doxget /TEXT xfermode","",xfermode); - } else if (pv[SND_IMG].ival > 0) { - xfermode = XMODE_M; -#ifdef VMS - binary = XYFT_I; -#else - binary = XYFT_B; -#endif /* VMS */ - omode = GMOD_TXT; - debug(F101,"doxget /IMAGE xfermode","",xfermode); - } -#ifdef CK_LABELED - else if (pv[SND_LBL].ival > 0) { - xfermode = XMODE_M; - binary = XYFT_L; - omode = GMOD_LBL; - debug(F101,"doxget /LABELED xfermode","",xfermode); - } -#endif /* CK_LABELED */ - debug(F101,"xget binary","",binary); - debug(F101,"xget omode","",omode); - - if (pv[SND_XPA].ival > 0) /* /TRANSPARENT */ - xfrxla = 0; /* Don't translate character sets */ - -#ifdef PIPESEND - if (pv[SND_FLT].ival > 0) - makestr(&rcvfilter,pv[SND_FLT].sval); -#endif /* PIPESEND */ - -#ifdef CK_TMPDIR - if (pv[SND_MOV].ival > 0) { - int len; - char * p = pv[SND_MOV].sval; -#ifdef CK_LOGIN - if (isguest) { - printf("?Sorry, /MOVE-TO not available to guests\n"); - x = -9; - goto xgetx; - } -#endif /* CK_LOGIN */ - len = strlen(p); - if (!isdir(p)) { /* Check directory */ -#ifdef CK_MKDIR - char * s = NULL; - s = (char *)malloc(len + 4); - if (s) { - strcpy(s,p); /* safe */ -#ifdef datageneral - if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; } -#else - if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; } -#endif /* datageneral */ - s[len++] = 'X'; - s[len] = NUL; - x = zmkdir(s); - free(s); - if (x < 0) { - printf("?Can't create \"%s\"\n",p); - x = -9; - goto xgetx; - } - } -#else - printf("?Directory \"%s\" not found\n",p); - x = -9; - goto xgetx; -#endif /* CK_MKDIR */ - } - zfnqfp(p,LINBUFSIZ,line); - makestr(&rcv_move,line); - } -#endif /* CK_TMPDIR */ - - if (pv[SND_REN].ival > 0) { /* /RENAME-TO:name */ - char * p = pv[SND_REN].sval; -#ifdef CK_LOGIN - if (isguest) { - printf("?Sorry, /RENAME-TO not available to guests\n"); - x = -9; - goto xgetx; - } -#endif /* CK_LOGIN */ - if (!p) p = ""; - if (!*p) { - printf("?New name required for /RENAME\n"); - x = -9; - goto xgetx; - } - p = brstrip(p); - makestr(&rcv_rename,p); - debug(F110,"xget rcv_rename","",0); - } - -#ifdef CALIBRATE - if (pv[SND_CAL].ival > 0) - calibrate = 1L; -#endif /* CALIBRATE */ - g_displa = fdispla; - if (pv[SND_SHH].ival > 0) - fdispla = 0; - debug(F101,"xget display","",fdispla); - - if (pv[SND_NAM].ival > -1) { /* /FILENAMES */ - g_fncnv = fncnv; /* Save global value */ - fncnv = pv[SND_NAM].ival; - debug(F101,"xsend fncnv","",fncnv); - /* We should also handle O packet filename option here */ - /* but we don't really need to since WHATAMI already handles it */ - } - if (pv[SND_PTH].ival > -1) { /* PATHNAMES */ - g_rpath = fnrpath; /* Save global values */ - fnrpath = pv[SND_PTH].ival; - debug(F101,"xsend fnrpath","",fnrpath); -#ifndef NZLTOR - if (fnrpath != PATH_OFF) { - g_fncnv = fncnv; - fncnv = XYFN_L; - debug(F101,"xsend fncnv","",fncnv); - } - /* We should also handle O packet pathname option here */ - /* but we don't really need to since WHATAMI already handles it */ -#endif /* NZLTOR */ - } - - /* Set protocol start state */ - - if (opkt) { /* Extended GET Options*/ - sstate = (CHAR) 'o'; - oopts = 0; - if (pv[SND_DEL].ival > 0) oopts |= GOPT_DEL; /* GET /DELETE */ - if (pv[SND_RES].ival > 0) oopts |= GOPT_RES; /* GET /RECOVER */ - if (pv[SND_REC].ival > 0) oopts |= GOPT_REC; /* GET /RECURSIVE */ - } else if (rcvcmd) - sstate = (CHAR) 'v'; /* RECEIVE or CRECEIVE */ - else if (pv[SND_DEL].ival > 0) - sstate = (CHAR) 'h'; /* GET /DELETE (= RETRIEVE) */ - else if (pv[SND_RES].ival > 0) - sstate = (CHAR) 'j'; /* GET /RECOVER (= REGET) */ - else - sstate = (CHAR) 'r'; /* Regular GET */ - getcmd = 1; - debug(F000,"xget sstate","",sstate); -#ifdef MAC - what = W_RECV; - scrcreate(); -#endif /* MAC */ - if (local) { - if (pv[SND_SHH].ival != 0) - displa = 1; - ttflui(); - } - x = 0; -#ifdef PIPESEND - if (pipesend) - goto xgetx; -#endif /* PIPESEND */ - -#ifdef CK_TMPDIR -/* - cmarg2 is also allowed to be a device or directory name; - even the name of a directory that doesn't exist. -*/ - y = strlen(cmarg2); - debug(F111,"xget strlen(cmarg2)",cmarg2,y); - if ((y > 0) && -#ifdef OS2 - ((isalpha(cmarg2[0]) && - cmarg2[1] == ':' && - cmarg2[2] == NUL) || - (cmarg[y-1] == '/' || cmarg[y-1] == '\\') || - isdir(cmarg2)) -#else -#ifdef UNIXOROSK - (cmarg2[y-1] == '/' || isdir(cmarg2)) -#else -#ifdef VMS - (cmarg2[y-1] == ']' || cmarg2[y-1] == '>' || isdir(cmarg2)) -#else -#ifdef STRATUS - (cmarg2[y-1] == '>' || isdir(cmarg2)) -#else -#ifdef datageneral - (cmarg2[y-1] == ':' || cmarg[0] == ':' || isdir(cmarg2)) -#else - isdir(cmarg2) -#endif /* datageneral */ -#endif /* STRATUS */ -#endif /* VMS */ -#endif /* UNIXOROSK */ -#endif /* OS2 */ - ) { - debug(F110,"doxget RECEIVE cmarg2 disk or dir",cmarg2,0); - if (!f_tmpdir) { - int x; - s = zgtdir(); - if (s) { - ckstrncpy(savdir,s,TMPDIRLEN); /* remember old disk/dir */ - f_tmpdir = 1; /* and that we did this */ - } else { - printf("?Can't get current directory\n"); - cmarg2 = ""; - f_tmpdir = 0; - x = -9; - goto xgetx; - } -#ifdef CK_MKDIR - x = zchki(cmarg2); /* Does as-name exist? */ - if (x == -1) { /* Doesn't exist */ - char * p = NULL; /* Try to create it */ - x = strlen(cmarg2); - if ((p = (char *)malloc(x+4))) { - sprintf(p,"%s%s",cmarg2,"x.x"); /* SAFE (prechecked) */ - x = zmkdir(p); - free(p); - if (x < 0) { - printf("?Can't create %s\n",cmarg2); - x = -9; - goto xgetx; - } - } - } -#endif /* CK_MKDIR */ - if (!zchdir(cmarg2)) { /* change to given disk/directory, */ - printf("?Can't access %s\n",cmarg2); - x = -9; - goto xgetx; - } - cmarg2 = ""; - } - } -#endif /* CK_TMPDIR */ - - ckstrncpy(fspec,cmarg,CKMAXPATH); /* Note - this is a REMOTE filespec */ - debug(F111,"xget fspec",fspec,fspeclen); - debug(F110,"xget cmarg2",cmarg2,0); - - xgetx: - for (i = 0; i < SND_MAX; i++) - if (pv[i].sval) - free(pv[i].sval); - return(x); -} -#endif /* NOXFER */ - -#ifndef NOSPL - -/* - D O G T A -- Do _GETARGS or _PUTARGS Command. - - Used by XIF, FOR, WHILE, and SWITCH, each of which are implemented as - 2-level macros; the first level defines the macro, the second runs it. - This routine hides the fact that they are macros by importing the - macro arguments (if any) from two levels up, to make them available - in the IF, FOR, SWITCH, and WHILE commands themselves; for example as - loop indices, etc, and within the IF/FOR/WHILE/SWITCH body itself. - _PUTARGS is in case we changed any of these variables or used SHIFT - on them, so the new values won't be lost as we pop up the stack. -*/ -int -dogta(cx) int cx; { - int i, n; - char c, *p, mbuf[4]; - extern int topargc, cmdint; - extern char ** topxarg; - - if ((y = cmcfm()) < 0) - return(y); - debug(F101,"dogta cx","",cx); - debug(F101,"dogta maclvl","",maclvl); - if (cx == XXGTA) { - debug(F101,"dogta _GETARGS maclvl","",maclvl); - } else if (cx == XXPTA) { - debug(F101,"dogta _PUTARGS maclvl","",maclvl); - } else { - return(-2); - } - if (maclvl < 1) - return(success = 0); - - /* Make new copies of macro arguments /%0..9 */ - - mbuf[0] = '%'; mbuf[1] = '0'; mbuf[2] = NUL; /* Argument name buf */ - - if (cx == XXPTA) { /* Go NOINT because _PUTARGS */ - if (cmdint) /* temporarily changes maclvl. */ - connoi(); /* Interrupts OFF. */ - } - for (i = 0; i < 10; i++) { /* For all args */ - c = (char) (i + '0'); /* Make name */ - mbuf[1] = (char) c; /* Insert digit */ - if (cx == XXGTA) { /* Get arg from level-minus-2 */ - if (maclvl == 1) p = g_var[c]; /* If at level 1 use globals 0..9 */ - else p = m_arg[maclvl-2][i]; /* Otherwise they're on the stack */ - addmac(mbuf,p); -#ifdef COMMENT - if (maclvl > 1) - makestr(&(m_line[maclvl]),m_line[maclvl-2]); -#endif /* COMMENT */ - } else if (cx == XXPTA) { /* Put args level+2 */ - maclvl -= 2; /* This is gross, it's because we're */ - addmac(mbuf,m_arg[maclvl+2][i]); /* adding macros two levels up */ - maclvl += 2; /* and addmac() uses maclvl. */ - count[cmdlvl - 2] = count[cmdlvl]; - intime[cmdlvl - 2] = intime[cmdlvl]; - inpcas[cmdlvl - 2] = inpcas[cmdlvl]; - takerr[cmdlvl - 2] = takerr[cmdlvl]; - merror[cmdlvl - 2] = merror[cmdlvl]; - xquiet[cmdlvl - 2] = xquiet[cmdlvl]; - } else return(success = 0); /* Bad call to this routine */ - } - if (cx == XXPTA) { /* Restore interrupts if we */ - if (cmdint) /* turned them off above. */ - conint(trap,stptrap); - } - /* Now take care of the argument vector array \&_[], \v(return), */ - /* and \v(argc) by just copying the pointers. */ - - if (cx == XXGTA) { /* GETARGS from 2 levels up */ - if (maclvl == 1) { - a_ptr[0] = topxarg; /* \&_[] array */ - a_dim[0] = topargc - 1; /* Dimension doesn't include [0] */ - m_xarg[maclvl] = topxarg; - n_xarg[maclvl] = topargc; /* But \v(argc) does include \%0 */ - macargc[maclvl] = topargc; - makestr(&(mrval[maclvl+1]),mrval[0]); /* (see vnlook()) */ - } else { - a_ptr[0] = m_xarg[maclvl-2]; - a_dim[0] = n_xarg[maclvl-2]; - m_xarg[maclvl] = m_xarg[maclvl-2]; - n_xarg[maclvl] = n_xarg[maclvl-2]; - macargc[maclvl] = n_xarg[maclvl-2]; - makestr(&(mrval[maclvl+1]),mrval[maclvl-1]); /* (see vnlook()) */ - - } - } else { /* PUTARGS 2 levels up */ - if (maclvl > 1) { - a_ptr[0] = m_xarg[maclvl]; - m_xarg[maclvl-2] = m_xarg[maclvl]; - a_dim[0] = n_xarg[maclvl]; - n_xarg[maclvl-2] = n_xarg[maclvl]; - macargc[maclvl-2] = n_xarg[maclvl]; - } - } - return(1); /* Internal command - don't change success */ -} -#endif /* NOSPL */ - -#ifndef NOSPL -/* - Do the GOTO and [_]FORWARD commands. - s = Label to search for, cx = function code: XXGOTO, XXFWD, or XXXFWD. -*/ -#ifdef BIGBUFOK -#define LBLMAXLEN 255 /* Max label length */ -#else -#define LBLMAXLEN 63 -#endif /* BIGBUFOK */ - -int -dogoto(s, cx) char *s; int cx; { - int i, j, x, y, z, bc; - int empty = 0, stopflg = 0; - char * cmd; /* Name of this command */ - char tmplbl[LBLMAXLEN+1], *lp; /* Current label from command stream */ - char tmp2[LBLMAXLEN+1]; /* SWITCH label conversion buffer */ - char tmp3[LBLMAXLEN+1]; /* Target label */ - - stopflg = (cx == XXXFWD); /* _FORWARD (used in SWITCH) */ - bc = 0; /* Brace counter */ - - cmd = (cx == XXGOTO) ? "GOTO" : ((cx == XXFWD) ? "FORWARD" : "_FORWARD"); - if (!s) s = ""; - if (!*s) empty = 1; - -#ifdef DEBUG - if (deblog) { - debug(F111,"GOTO command",cmd,cx); - debug(F101,"GOTO cmdlvl","",cmdlvl); - debug(F101,"GOTO maclvl","",maclvl); - debug(F101,"GOTO tlevel","",tlevel); - debug(F111,"GOTO target",s,empty); - } -#endif /* DEBUG */ - debug(F110,cmd,s,0); - ckstrncpy(tmp3+1,s,LBLMAXLEN-1); - s = tmp3+1; - if (*s != ':') { /* Make copy of label */ - tmp3[0] = ':'; /* guaranteed to start with ":" */ - s--; - } - if (!stopflg && !empty) { - if (s[1] == '.' || s[1] == SP || s[1] == NUL) { - printf("?Bad label syntax - '%s'\n",s); - return(success = 0); - } - } - if (cmdlvl == 0) { - printf("?Sorry, %s only works in a command file or macro\n",cmd); - return(success = 0); - } - y = strlen(s); /* y = length of target label */ - debug(F111,cmd,s,y); - - while (cmdlvl > 0) { /* As long as not at top level... */ - if (cmdstk[cmdlvl].src == CMD_MD) { /* GOTO inside macro */ - int i, m, flag; - char *xp, *tp; - - /* GOTO: rewind the macro; FORWARD: start at current position */ - - lp = (cx == XXGOTO) ? macx[maclvl] : macp[maclvl]; - m = (int)strlen(lp) - y + 1; - debug(F010,"GOTO in macro",lp,0); - - flag = 1; /* flag for valid label position */ - for (i = 0; i < m; i++,lp++) { /* search for label in macro body */ - if (*lp == '{') /* But only at this level */ - bc++; /* Anything inside braces is off */ - else if (*lp == '}') /* limits. */ - bc--; - if (stopflg && bc > 0) /* This is good for SWITCH */ - continue; /* but interferes with WHILE, etc. */ - if (*lp == ',') { - flag = 1; - continue; - } - if (flag) { /* If in valid label position */ - if (*lp == SP) /* eat leading spaces */ - continue; - if (*lp != ':') { /* Look for label introducer */ - flag = 0; /* this isn't it */ - continue; /* keep looking */ - } - } - if (!flag) /* We don't have a label */ - continue; /* so keep looking... */ - xp = lp; tp = tmplbl; /* Copy the label from the macro */ - j = 0; /* to make it null-terminated */ - while ((*tp = *xp)) { - if (j++ > LBLMAXLEN) /* j = length of word from macro */ - break; -#ifdef COMMENT - if (*tp < 33 || *tp == ',') /* Look for end of word */ -#else - if (!*tp || *tp == ',') /* Look for end of word */ -#endif /* COMMENT */ - break; - else tp++, xp++; /* Next character */ - } - *tp = NUL; /* In case we stopped early */ - /* Now do caseless string comparison, using longest length */ - debug(F111,"macro GOTO label",s,y); - debug(F111,"macro target label",tmplbl,j); - if (stopflg) { /* Allow variables as SWITCH labels */ - int n = LBLMAXLEN - 1; - char * p = tmp2; - zzstring(tmplbl,&p,&n); - ckstrncpy(tmplbl,tmp2,LBLMAXLEN); - tmp2[49] = NUL; - } - debug(F111,"GOTO s",s,y); - debug(F111,"GOTO tmplbl",tmplbl,j); - debug(F101,"GOTO empty",ckitoa(stopflg),empty); - - if (empty) { /* Empty target */ - z = (!strcmp(s,":") && /* String is empty */ - /* and Label is ":" or ":*"... */ - (!strcmp(tmplbl,":") || !strcmp(tmplbl,":*"))) - ? 0 : 1; - debug(F111,"GOTO","A",z); - } else if (stopflg) { - z = ckmatch(tmplbl,s,inpcas[cmdlvl],1) ? 0 : 1; - debug(F111,"GOTO","B",z); - } else { - z = (stopflg && inpcas[cmdlvl]) ? - strcmp(s,tmplbl) : - ckstrcmp(s,tmplbl,(y > j) ? y : j, 0); - debug(F111,"GOTO","C",z); - } - if (!z) { - break; - } else if (stopflg && - !ckstrcmp(":default",tmplbl,(8 > j) ? 8 : j, 0)) { - debug(F100,"GOTO DEFAULT","",0); - break; - } else { - flag = 0; - } - } - debug(F111,"GOTO macro i",cmd,i); - debug(F111,"GOTO macro m",cmd,m); - if (i >= m) { /* Didn't find the label */ - debug(F101,"GOTO failed cmdlvl","",cmdlvl); -#ifdef COMMENT - /* MOVED TO AFTER POPCLVL ABOUT 20 LINES DOWN 5 AUG 2002 */ - if (stopflg) - return(0); -#endif /* COMMENT */ - if ((maclvl > 0) && - (m_arg[maclvl-1][0]) && - (cmdstk[cmdlvl].src == CMD_MD) && - (!strncmp(m_arg[maclvl-1][0],"_xif",4) || - !strncmp(m_arg[maclvl-1][0],"_for",4) || - !strncmp(m_arg[maclvl-1][0],"_swi",4) || - !strncmp(m_arg[maclvl-1][0],"_whi",4))) { - dogta(XXPTA); /* Restore args */ - debug(F101,"GOTO in XIF/FOR/WHI/SWI popping","",cmdlvl); - popclvl(); /* Pop an extra level */ - } - debug(F101,"GOTO popping","",cmdlvl); - if (!popclvl()) { /* pop up to next higher level */ - printf("?Label '%s' not found\n",s); /* if none */ - return(0); /* Quit */ - } else if (stopflg) { /* SWITCH no case label match */ - return(0); /* and no DEFAULT lable. */ - } else { - continue; /* otherwise look again */ - } - } - debug(F110,"GOTO found macro label",tmplbl,0); - macp[maclvl] = lp; /* set macro buffer pointer */ - return(1); - } else if (cmdstk[cmdlvl].src == CMD_TF) { - x = 0; /* GOTO issued in take file */ - debug(F111,"GOTO in TAKE file",cmd,cx); - if (cx == XXGOTO) { /* If GOTO, but not FORWARD, */ - rewind(tfile[tlevel]); /* search file from beginning */ - tfline[tlevel] = 0; - } - while (! feof(tfile[tlevel])) { -#ifdef COMMENT -/* This is wrong - it lets us jump to labels inside inferior blocks */ - tfline[tlevel]++; - if (fgets(line,LINBUFSIZ,tfile[tlevel]) == NULL) /* Get line */ -#else - if (getnct(line,LINBUFSIZ,tfile[tlevel],0) < 0) -#endif /* COMMENT */ - break; /* If no more, done, label not found */ - lp = line; /* Got line */ - while (*lp == SP || *lp == HT) - lp++; /* Strip leading whitespace */ - if (*lp != ':') continue; /* Check for label introducer */ - while (*(lp+1) == SP) { /* Remove space between : and name */ - *(lp+1) = ':'; - lp++; /* Strip leading whitespace */ - } - tp = lp; /* Get end of word */ - j = 0; - while (*tp) { /* And null-terminate it */ - if (*tp < 33) { - *tp = NUL; - break; - } else tp++, j++; - } - if (!ckstrcmp(lp,s,(y > j) ? y : j,0)) { /* Caseless compare */ - x = 1; /* Got it */ - break; /* done. */ - } else if (stopflg && - !ckstrcmp(":default",tmplbl,(8 > j) ? 8 : j,0)) { - x = 1; - break; - } - } - if (x == 0) { /* If not found, print message */ - debug(F101,"GOTO failed at cmdlvl","",cmdlvl); - if (stopflg) - return(0); - if (!popclvl()) { /* pop up to next higher level */ - printf("?Label '%s' not found\n",s); /* if none */ - return(0); /* quit */ - } else continue; /* otherwise look again */ - } - return(x); /* Send back return code */ - } - } - printf("?Stack problem in GOTO %s\n",s); /* Shouldn't see this */ - return(0); -} -#endif /* NOSPL */ - -/* Finish parsing and do the IF, XIF, and WHILE commands */ - -#ifndef NOSPL - -/* C H K V A R -- Check (if it's a) Variable */ - - -#ifdef OLDCHKVAR -/* - Crude and disgusting, but needed for OS/2, DOS, and Windows, where filenames - have backslashes in them. How do we know if a backslash in a filename is a - directory separator, or if it's a Kermit backslash? This routine does a - rough syntax check of the next few characters and if it looks like it MIGHT - be a variable, then it tries to evaluate it, and if the result is not empty, - we say it's a variable, although sometimes it might not be -- some cases are - truly ambiguous. For example there might a DOS directory called \%a, and - we also have a variable with the same name. This is all for the sake of not - having to tell PC users that they have to double all backslashes in file - and directory names. -*/ -#else -/* - Somewhat less crude & disgusting. The previous method was nondeterministic - and (worse) it interfered with macro argument passing. So now we only - check the syntax of backslash-items to see if they are variables, but we - do NOT check their values. -*/ -#endif /* OLDCHKVAR */ -/* - Call with a string pointer pointing at the backslash of the purported - variable. Returns 1 if it has the syntax of a variable, 0 if not. -*/ -int -chkvar(s) char *s; { - int z = 0; /* Return code - assume failure. */ - if (!s) s = ""; /* Watch our for null pointers. */ - if (!*s) return(0); /* Empty arg so not a variable. */ - if (*s == CMDQ) { /* Object begins with backslash. */ - char c; - c = s[1]; /* Character following backslash. */ - if (c) { - int t = 0; - if (c == CMDQ) /* Quoted backslash */ - return(1); - c = (char) (islower(c) ? toupper(c) : c); /* Otherwise... */ - if (c == '%') { /* Simple variable */ -#ifdef OLDCHKVAR - t = 1; -#else - return(1); -#endif /* OLDCHKVAR */ - } else if (c == '&') { /* Array */ - if (!s[2]) return(0); - if (s[3] == '[') - t = ckindex("]",s,4,0,1); -#ifndef OLDCHKVAR - return((t > 0) ? 1 : 0); -#endif /* OLDCHKVAR */ - } else if (c == '$' || /* Environment variable */ - c == 'V' || /* Built-in variable */ - c == 'M') { /* Macro name */ - t = (s[2] == '('); -#ifndef OLDCHKVAR - return((t > 0) ? 1 : 0); -#endif /* OLDCHKVAR */ - } else if (c == 'F') { /* Function reference */ - /* Don't actually call it - it might have side effects */ - int x; - if ((x = ckindex("(",s,3,0,1))) /* Just check syntax */ - if ((x = ckindex(")",s,x,0,1))) - z = 1; - /* Insert a better syntax check here if necessary */ - } -#ifdef OLDCHKVAR - if (t) { - t = 255; /* This lets us test \v(xxx) */ - lp = line; /* and even \f...(xxx) */ - zzstring(s,&lp,&t); /* Evaluate it, whatever it is. */ - t = strlen(line); /* Get its length. */ - debug(F111,"chkvar",line,t); - z = t > 0; /* If length > 0, it's defined */ - } -#endif /* OLDCHKVAR */ - } - } - return(z); -} - -/* B O O L E X P -- Evaluate a Boolean expression */ - -#define BOOLLEN 1024 -static char boolval[BOOLLEN]; - -int -boolexp(cx) int cx; { - int x, y, z; char *s, *p; - int parens = 0, pcount = 0, ecount = 0; - char *q, *bx; - struct FDB kw, nu; -#ifdef FNFLOAT - struct FDB fl; - CKFLOAT f1 = 0.0, f2 = 0.0; - int f1flag = 0, f2flag = 0; -#endif /* FNFLOAT */ -#ifdef OS2 - extern int keymac; -#endif /* OS2 */ - - not = 0; /* Flag for whether "NOT" was seen */ - z = 0; /* Initial IF condition */ - ifargs = 0; /* Count of IF condition words */ - bx = boolval; /* Initialize boolean value */ - *bx = NUL; - - ifagain: - cmfdbi(&kw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Number, numeric-valued variable, Boolean expression, or keyword", - "", /* default */ - "", /* addtl string data */ - nif, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: 4 = silent */ - xxstring, /* Processing function */ - iftab, /* Keyword table */ - &nu /* Pointer to next FDB */ - ); - cmfdbi(&nu, /* 2nd FDB - An integer */ - _CMNUM, /* fcode */ - "", /* hlpmsg */ - "", /* Default */ - "", /* addtl string data */ - 0, - 0, - xxstring, - NULL, -#ifdef FNFLOAT - &fl -#else - NULL -#endif /* FNFLOAT */ - ); -#ifdef FNFLOAT - cmfdbi(&fl, /* A floating-point number */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); -#endif /* FNFLOAT */ - x = cmfdb(&kw); /* Parse a keyword or a number */ - debug(F111,"boolval cmfdb","",x); - if (x < 0) { - if (x == -3) - x = -2; - return(x); - } - debug(F111,"boolval switch","",cmresult.fcode); - switch (cmresult.fcode) { /* What did we get? */ -#ifdef FNFLOAT - case _CMFLD: /* A "field" */ - if (isfloat(cmresult.sresult,0)) { /* A floating-point number? */ - f1 = floatval; /* Yes, get its value */ - f1flag = 1; /* remember we did this */ - ifc = 9999; /* Set special "if-code" */ - } else - return(-2); -#endif /* FNFLOAT */ - case _CMNUM: /* A number... */ - ifc = 9999; /* Set special "if-code" */ - break; - case _CMKEY: /* A keyword */ - ifc = cmresult.nresult; /* Get if-code */ - break; - default: - return(-2); - } - switch (ifc) { /* set z = 1 for true, 0 for false */ - case 9999: /* Number */ -#ifdef FNFLOAT - if (f1flag) { - z = (f1 == 0.0) ? 0 : 1; - } else -#endif /* FNFLOAT */ - z = (cmresult.nresult == 0) ? 0 : 1; - break; - case XXIFLP: /* Left paren */ - if (pcount == 0 && ifargs > 0) - return(-2); - parens = 1; - pcount++; - ifargs++; - *bx++ = '('; - goto ifagain; - case XXIFRP: /* Right paren */ - if (!parens) - return(-2); - if (--pcount < 0) - return(-2); - ifargs++; - *bx++ = ')'; - *bx = NUL; - if (pcount == 0) - goto ifend; - goto ifagain; - case XXIFAN: /* AND (&&) */ - ifargs++; - if (!ecount) - return(-2); - *bx++ = '&'; - goto ifagain; - case XXIFOR: /* OR (||) */ - ifargs++; - if (!ecount) - return(-2); - *bx++ = '|'; - goto ifagain; - case XXIFNO: /* IF NOT [ NOT [ NOT ... ] ] */ - if (bx > boolval) { /* evala() doesn't like cascaded */ - if (*(bx-1) == '!') { /* unary operators... */ - *(bx-1) = NUL; /* So here, two wrongs make a right. */ - bx--; - } else { - *bx++ = '!'; - } - } else { - *bx++ = '!'; - } - ifargs++; - goto ifagain; - case XXIFTR: /* IF TRUE */ - z = 1; - debug(F101,"if true","",z); - ifargs += 1; - break; - case XXIFNT: /* IF FALSE */ - z = 0; - debug(F101,"if true","",z); - ifargs += 1; - break; - case XXIFSU: /* IF SUCCESS */ - z = ( success != 0 ) ? 1 : 0; - debug(F101,"if success","",z); - ifargs += 1; - break; - case XXIFFA: /* IF FAILURE */ - z = ( success == 0 ) ? 1 : 0; - debug(F101,"if failure","",z); - ifargs += 1; - break; - - case XXIFDE: /* IF DEFINED */ - if ((x = cmfld("Macro or variable name","",&s,NULL)) < 0) - return((x == -3) ? -2 : x); - - if (*s == CMDQ) { - char * lp; - char line[256]; - int t, x; - if (*(s+1) == 'f' || *(s+1) == 'F') { /* Built-in function */ - extern struct keytab fnctab[]; - extern int nfuncs; - ckstrncpy(line,s+2,256); - if (line[0]) { - lp = ckstrchr(line,'('); - if (lp) *lp = NUL; - x = lookup(fnctab,line,nfuncs,&t); - z = x > -1; - } - debug(F111,"if defined function",line,z); - } else if (*(s+1) == 'v' || *(s+1) == 'V') { /* 8.0.200 */ - extern struct keytab vartab[]; - extern int nvars; - z = 0; - if (*(s+2) == '(') { - ckstrncpy(line,s+3,256); - if (line[0]) { - lp = ckstrchr(line,')'); - if (lp) *lp = NUL; - x = lookup(vartab,line,nvars,&t); - z = x > -1; - if (z) { /* 8.0.203 */ - int t; /* It must have a value to succeed */ - t = 255; /* as in C-Kermit 6.0 and 7.0 */ - lp = line; /* (this was broken in 8.0.200-201) */ - zzstring(s,&lp,&t); - t = strlen(line); - z = line[0] ? 1 : 0; - } - } - } - debug(F111,"if defined variable",line,z); - } else { - z = chkvar(s); /* Starts with backslash */ - if (z > 0) { /* Yes... */ - t = 255; /* than buffer so if zzstring fails */ - lp = line; /* check for that -- overflow means */ - line[0] = NUL; /* the quantity is defined. */ - x = zzstring(s,&lp,&t); - if ((x < 0 && t != 255) || !line[0]) - z = 0; - debug(F111,"if defined zzstring",line,z); - debug(F101,"if defined zzstring t","",t); - } - } - } else { - z = (mxlook(mactab,s,nmac) > -1); /* Look for exact match */ - } - debug(F111,"if defined final",s,z); - ifargs += 2; - break; - - case XXIFDC: { /* IF DECLARED */ - char * lp; - char line[32]; - int j, k, t, x; - if ((x = cmfld("Array name","",&s,NULL)) < 0) - return((x == -3) ? -2 : x); - if (*s == CMDQ) { - if (*(s+1) != '&') { - t = 31; - lp = line; - line[0] = NUL; - x = zzstring(s,&lp,&t); - s = line; - } - } - z = 0; - if ((x = arraybounds(s,&j,&k)) > -1) { - if (a_ptr[x]) { - if (j < 1) - z = 1; - else if (j <= a_dim[x]) - z = 1; - if (z == 1 && k > a_dim[x]) - z = 0; - } - } - break; - } - case XXIFBG: /* IF BACKGROUND */ - case XXIFFG: /* IF FOREGROUND */ - bgchk(); /* Check background status */ - if (ifc == XXIFFG) /* Foreground */ - z = pflag ? 1 : 0; - else z = pflag ? 0 : 1; /* Background */ - ifargs += 1; - break; - - case XXIFCO: /* IF COUNT */ - z = ( --count[cmdlvl] > 0 ); - if (cx == XXWHI) count[cmdlvl] += 2; /* Don't ask... */ - debug(F101,"if count","",z); - ifargs += 1; - break; - - case XXIFEX: /* IF EXIST */ -#ifdef CK_TMPDIR - case XXIFDI: /* IF DIRECTORY */ -#endif /* CK_TMPDIR */ - case XXIFAB: /* IF ABSOLUTE */ - if ((x = cmfld( - ((ifc == XXIFDI) ? "Directory name" : "File"), - "",&s, -#ifdef OS2 - NULL /* This allows \'s in filenames */ -#else - xxstring -#endif /* OS2 */ - )) < 0) { - if (x == -3) { - extern int cmflgs; - if (cmflgs == 1) { - printf("?File or directory name required\n"); - return(-9); - } - } else return(x); - } - s = brstrip(s); - if (ifc == XXIFAB) { - z = isabsolute(s); - } else if (ifc == XXIFEX) { - z = (zgetfs(s) > -1L); - debug(F101,"if exist 1","",z); -#ifdef OS2 - if (!z) { /* File not found. */ - int t; /* Try expanding variables */ - t = LINBUFSIZ-1; /* and looking again. */ - lp = line; - zzstring(s,&lp,&t); - s = line; - z = ( zchki(s) > -1L ); - debug(F101,"if exist 2","",z); - } -#endif /* OS2 */ -#ifdef CK_TMPDIR - } else { -#ifdef VMS - z = (zchki(s) == -2) -#else -/* Because this doesn't catch $DISK1:[FOO]BLAH.DIR;1 */ - z = isdir(s) -#ifdef OS2 - || (isalpha(s[0]) && s[1] == ':' && s[2] == NUL) -#endif /* OS2 */ -#endif /* VMS */ - ; - debug(F101,"if directory 1","",z); - - if (!z) { /* File not found. */ - int t; /* Try expanding variables */ - t = LINBUFSIZ-1; /* and looking again. */ - lp = line; - zzstring(s,&lp,&t); - s = line; - z = isdir(s) -#ifdef OS2 - || (isalpha(s[0]) && s[1] == ':' && s[2] == NUL) -#endif /* OS2 */ - ; - debug(F101,"if directory 2","",z); - } -#endif /* CK_TMPDIR */ - } - ifargs += 2; - break; - - case XXIFEQ: /* IF EQUAL (string comparison) */ - case XXIFLL: /* IF Lexically Less Than */ - case XXIFLG: /* If Lexically Greater Than */ - if ((x = cmfld("first word or variable name","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Text required\n"); - return(-9); - } else return(x); - } - s = brstrip(s); /* Strip braces */ - x = (int)strlen(s); - if (x > LINBUFSIZ-1) { - printf("?IF: strings too long\n"); - return(-2); - } - lp = line; /* lp points to first string */ - ckstrncpy(line,s,LINBUFSIZ); - if ((y = cmfld("second word or variable name","",&s,xxstring)) < 0) { - if (y == -3) { - printf("?Text required\n"); - return(-9); - } else return(y); - } - s = brstrip(s); - y = (int)strlen(s); - if (x + y + 2 > LINBUFSIZ) { - printf("?IF: strings too long\n"); - return(-2); - } - tp = lp + x + 2; /* tp points to second string */ - strcpy(tp,s); /* safe (checked) */ - x = ckstrcmp(lp,tp,-1,inpcas[cmdlvl]); /* Use longest length */ - switch (ifc) { - case XXIFEQ: /* IF EQUAL (string comparison) */ - z = (x == 0); - break; - case XXIFLL: /* IF Lexically Less Than */ - z = (x < 0); - break; - case XXIFLG: /* If Lexically Greater Than */ - z = (x > 0); - break; - } - debug(F101,"IF EQ result","",z); - ifargs += 3; - break; - - case XXIFVE: /* IF VERSION */ - case XXIFAE: /* IF (arithmetically) = */ - case XXIFNQ: /* IF != (not arithmetically equal) */ - case XXIFLT: /* IF < */ - case XXIFLE: /* IF <= */ - case XXIFGE: /* IF >= */ - case XXIFGT: { /* IF > */ - - /* Really should use longs here... */ - /* But cmnum parses ints. */ - int xx, n1 = 0, n2 = 0; - if (ifc == XXIFVE) { - n1 = (int) vernum; - } else { - x = cmfld("first number or variable name","",&s,xxstring); - if (x == -3) { - printf("?Quantity required\n"); - return(-9); - } - if (x < 0) return(x); - debug(F101,"xxifgt cmfld","",x); - ckstrncpy(line,s,LINBUFSIZ); - lp = brstrip(line); - debug(F110,"xxifgt exp1",lp,0); - -/* The following bit is for compatibility with old versions of MS-DOS Kermit */ - - if (!ckstrcmp(lp,"count",5,0)) { - n1 = count[cmdlvl]; - } else if (!ckstrcmp(lp,"version",7,0)) { - n1 = (int) vernum; - } else if (!ckstrcmp(lp,"argc",4,0)) { - n1 = (int) macargc[maclvl]; - } else { - -/* End of compatibility bit */ - -#ifdef FNFLOAT - if (isfloat(lp,0) > 1) { /* Allow floating-point comparisons */ - f1 = floatval; - f1flag = 1; - } else -#endif /* FNFLOAT */ - if (chknum(lp)) { - n1 = atoi(lp); - } else { /* Check for arithmetic expression */ - q = evala(lp); /* cmnum() does this but ... */ - if (chknum(q)) /* we're not using cmnum(). */ - n1 = atoi(q); - else - return(-2); - } - } - } - y = cmfld("number or variable name","",&s,xxstring); - if (y == -3) { - printf("?Quantity required\n"); - return(-9); - } - if (y < 0) return(y); - s = brstrip(s); - if (!*s) return(-2); - if (ifc == XXIFVE) { - tp = line; - } else { - x = (int)strlen(lp); - tp = line + x + 2; - } - ckstrncpy(tp,s,LINBUFSIZ-x-2); - debug(F110,"xxifgt exp2",tp,0); - if (!ckstrcmp(tp,"count",5,0)) { - n2 = count[cmdlvl]; - } else if (!ckstrcmp(tp,"version",7,0)) { - n2 = (int) vernum; - } else if (!ckstrcmp(tp,"argc",4,0)) { - n2 = (int) macargc[maclvl]; - } else { -#ifdef FNFLOAT - if (isfloat(tp,0) > 1) { - f2 = floatval; - f2flag = 1; - } else -#endif /* FNFLOAT */ - if (chknum(tp)) { - n2 = atoi(tp); - } else { - q = evala(tp); - if (chknum(q)) - n2 = atoi(q); - else - return(-2); - } - } - xx = (ifc == XXIFVE) ? XXIFGE : ifc; - -#ifdef FNFLOAT - if (f1flag && !f2flag) { - f2 = (CKFLOAT)n2; - f2flag = 1; - } - if (f2flag && !f1flag) - f1 = (CKFLOAT)n1; - if (f1flag) - z = ((f1 < f2 && xx == XXIFLT) - || (f1 != f2 && xx == XXIFNQ) - || (f1 <= f2 && xx == XXIFLE) - || (f1 == f2 && xx == XXIFAE) - || (f1 >= f2 && xx == XXIFGE) - || (f1 > f2 && xx == XXIFGT)); - else -#endif /* FNFLOAT */ - z = ((n1 < n2 && xx == XXIFLT) - || (n1 != n2 && xx == XXIFNQ) - || (n1 <= n2 && xx == XXIFLE) - || (n1 == n2 && xx == XXIFAE) - || (n1 >= n2 && xx == XXIFGE) - || (n1 > n2 && xx == XXIFGT)); - debug(F101,"xxifge z","",z); - if (ifc == XXIFVE) - ifargs += 2; - else - ifargs += 3; - break; - } - - case XXIFNU: /* IF NUMERIC */ - x = cmfld("variable name or constant","",&s,NULL); - if (x == -3) { - extern int cmflgs; - if (cmflgs == 1) { - printf("?Quantity required\n"); - return(-9); - } - } else if (x < 0) - return(x); - x = LINBUFSIZ-1; - lp = line; - zzstring(s,&lp,&x); - lp = line; - debug(F110,"xxifnu quantity",lp,0); - z = chknum(lp); -#ifdef COMMENT -/* - This works, but it's not wise -- IF NUMERIC is mostly used to see if a - string really does contain only numeric characters. If they want to force - evaluation, they can use \feval() on the argument string. -*/ - if (!z) { /* Not a number */ - x_ifnum = 1; /* Avoid "eval" error messages */ - q = evala(lp); /* Maybe it's an expression */ - z = chknum(q); /* that evaluates to a number */ - x_ifnum = 0; /* Put eval messages back to normal */ - if (z) debug(F110,"xxifnu exp",lp,0); - } -#endif /* COMMENT */ - debug(F101,"xxifnu chknum","",z); - ifargs += 2; - break; - -#ifdef ZFCDAT - case XXIFNE: { /* IF NEWER */ - char d1[20], * d2; /* Buffers for 2 dates */ - if ((z = cmifi("First file","",&s,&y,xxstring)) < 0) - return(z); - ckstrncpy(d1,zfcdat(s),20); - if ((z = cmifi("Second file","",&s,&y,xxstring)) < 0) - return(z); - d2 = zfcdat(s); - if ((int)strlen(d1) != 17 || (int)strlen(d2) != 17) { - printf("?Failure to get file date\n"); - return(-9); - } - debug(F110,"xxifnewer d1",d1,0); - debug(F110,"xxifnewer d2",d2,0); - z = (strcmp(d1,d2) > 0) ? 1 : 0; - debug(F101,"xxifnewer","",z); - ifargs += 2; - break; - } -#endif /* ZFCDAT */ - -#ifdef CK_IFRO - case XXIFRO: /* REMOTE-ONLY advisory */ - ifargs++; -#ifdef NOLOCAL - z = 1; -#else - z = remonly; -#endif /* NOLOCAL */ - break; -#endif /* CK_IFRO */ - - case XXIFAL: /* ALARM */ - ifargs++; - debug(F101,"IF ALARM ck_alarm","",ck_alarm); - debug(F110,"IF ALARM alrm_date",alrm_date,0); - debug(F110,"IF ALARM alrm_time",alrm_time,0); - - if (ck_alarm < 1L || alrm_date[0] < '0' || alrm_time[0] < '0') { - z = 0; /* ALARM not SET */ - break; /* so IF ALARM fails */ - } - /* Get current date and time */ - ckstrncpy(tmpbuf,ckcvtdate("",1),TMPBUFSIZ); - s = tmpbuf; - s[8] = NUL; - z = (int) strncmp(tmpbuf,alrm_date,8); /* Compare dates */ - debug(F101,"IF ALARM date z","",z); - if (z == 0) { /* Dates are the same */ - /* Compare times */ - z = (tod2sec(tmpbuf+9) >= atol(alrm_time)) ? 1 : -1; - debug(F101,"IF ALARM time z","",z); - } - tmpbuf[0] = NUL; /* z >= 0 if alarm is passed */ - z = ((z >= 0) ? 1 : 0); /* z < 0 otherwise */ - debug(F101,"IF ALARM final z","",z); - break; - - case XXIFOP: /* IF OPEN */ - if ((x = cmkey(iotab,niot,"file or log","",xxstring)) < 0) - return(x); - if (x == 9999 || x == ZSTDIO) { - bgchk(); /* Check background status */ - z = pflag ? 1 : 0; - } else if (x == 8888) { - z = local ? ttchk() > -1 : 0; -#ifdef CKLOGDIAL - } else if (x == 7777) { - extern int dialog; - z = dialog ? 1 : 0; -#endif /* CKLOGDIAL */ - } else - z = (chkfn(x) > 0) ? 1 : 0; - ifargs += 1; - break; - - case XXIFSD: /* Started-From-Dialer */ -#ifdef OS2 - z = StartedFromDialer; -#else - z = 0; -#endif /* OS2 */ - break; - - case XXIFTM: /* Terminal-Macro */ -#ifdef OS2 - z = cmdstk[cmdlvl].ccflgs & CF_KMAC; -#else - z = 0; -#endif /* OS2 */ - break; - - case XXIFEM: /* Emulation is active */ -#ifdef OS2 - z = 1; -#else - z = 0; -#endif /* OS2 */ - break; - - case XXIFIK: /* Running as IKSD? */ - z = inserver; - break; - - case XXIFTA: /* Connection is TAPI */ - z = 0; -#ifndef NODIAL -#ifdef CK_TAPI - if (local && !network && tttapi) - z = 1; -#endif /* CK_TAPI */ -#endif /* NODIAL */ - break; - - case XXIFMA: /* IF MATCH */ - x = cmfld("String or variable","",&s,xxstring); - if (x == -3) { - extern int cmflgs; - if (cmflgs == 1) { - printf("?String required\n"); - return(-9); - } - } else if (x < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - s = brstrip(line); - debug(F110,"xxifma string",line,0); - x = cmfld("Pattern","",&p,xxstring); - if (x == -3) { - extern int cmflgs; - if (cmflgs == 1) { - printf("?Pattern required\n"); - return(-9); - } - } else if (x < 0) - return(x); - ckstrncpy(tmpbuf,p,TMPBUFSIZ); - p = brstrip(tmpbuf); - debug(F110,"xxifma pattern",tmpbuf,0); - z = ckmatch(p,s,inpcas[cmdlvl],1); - break; - - case XXIFFL: { /* IF FLAG */ - extern int ooflag; - z = ooflag; - break; - } - case XXIFAV: { /* IF AVAILABLE */ - if ((x = cmkey(availtab,availtabn,"","",xxstring)) < 0) - return(x); - switch (x) { - case AV_KRB4: - z = ck_krb4_is_installed(); - break; - case AV_KRB5: - z = ck_krb5_is_installed(); - break; - case AV_SRP: - z = ck_srp_is_installed(); - break; - case AV_SSL: - z = ck_ssleay_is_installed(); - break; - case AV_NTLM: - z = ck_ntlm_is_installed(); - break; - case AV_CRYPTO: - z = ck_crypt_is_installed(); - break; - case AV_SSH: - z = ck_ssh_is_installed(); - break; - default: - z = 0; - } - break; - } - case XXIFAT: /* IF ASKTIMEOUT */ - z = asktimedout; - break; - - case XXIFRD: /* IF READABLE */ - case XXIFWR: /* IF WRITEABLE */ - if ((x = cmfld("File or directory name", - "", - &s, -#ifdef OS2 - NULL /* This allows \'s in filenames */ -#else - xxstring -#endif /* OS2 */ - )) < 0) { - if (x == -3) { - extern int cmflgs; - if (cmflgs == 1) { - printf("?File or directory name required\n"); - return(-9); - } - } else return(x); - } - s = brstrip(s); -/* - zchk[io]() do not do what we want here for directories, so we set - a global flag telling it to behave specially in this case. Othewise - we'd have to change the API and change all ck?fio.c modules accordingly. -*/ - y = 0; /* Try-again control */ -#ifdef OS2 - ifrdagain: -#endif /* OS2 */ - if (ifc == XXIFRD) { /* IF READABLE */ - zchkid = 1; - z = zchki(s) > -1; - zchkid = 0; - } else if (ifc == XXIFWR) { /* IF WRITEABLE */ - zchkod = 1; - z = zchko(s) > -1; - zchkod = 0; - } -#ifdef OS2 - if (!z && !y) { /* File not found. */ - int t; /* Try expanding variables */ - t = LINBUFSIZ-1; /* and looking again. */ - lp = line; - zzstring(s,&lp,&t); - s = line; - z = zchko(s) > -1; - y++; - goto ifrdagain; - } -#endif /* OS2 */ - ifargs += 2; - break; - case XXIFQU: /* IF QUIET */ - z = quiet ? 1 : 0; - debug(F101,"if quiet","",z); - ifargs += 1; - break; - - case XXIFWI: /* WILD */ - if ((x = cmfld("File specification","",&s,xxstring)) < 0) return(x); - z = iswild(s); - break; - - case XXIFCK: /* C-KERMIT */ -#ifdef OS2 - z = 0; -#else - z = 1; -#endif /* OS2 */ - break; - - case XXIFK9: /* K-95 */ -#ifdef OS2 - z = 1; -#else - z = 0; -#endif /* OS2 */ - break; - - case XXIFGU: /* GUI */ -#ifdef KUI - z = 1; -#else - z = 0; -#endif /* KUI */ - break; - - case XXIFMS: /* MS-KERMIT */ - z = 0; - break; - - case XXIFLO: /* IF LOCAL */ - z = local ? 1 : 0; - break; - - case XXIFCM: { /* IF COMMAND */ - extern struct keytab cmdtab[]; - extern int ncmd; - if ((x = cmfld("Word","",&s,xxstring)) < 0) - return(x); - z = lookup(cmdtab,s,ncmd,&y); - z = (z == -2 || z > -1) ? 1 : 0; - break; - } -#ifdef CKFLOAT - case XXIFFP: /* IF FLOAT */ - if ((x = cmfld("Number","",&s,xxstring)) < 0) - if (x != -3) /* e.g. empty variable */ - return(x); - z = isfloat(s,0); - break; -#endif /* CKFLOAT */ - - case XXIFKB: /* KBHIT */ - z = conchk(); - if (z < 0) z = 0; - if (z > 1) z = 1; - break; - - case XXIFKG: { /* KERBANG */ - extern int cfilef; - z = (xcmdsrc == 0) ? 0 : cfilef; - break; - } - - default: /* Shouldn't happen */ - return(-2); - } /* end of switch */ - - if (z) - *bx++ = '1'; - else - *bx++ = '0'; - *bx = NUL; - if (bx > boolval + BOOLLEN - 2) { - printf("?Boolean expression too long"); - return(-9); - } - ecount++; /* Expression counter */ - debug(F101,"boolexp parens","",parens); - debug(F101,"boolexp pcount","",pcount); - if (parens && pcount > 0) - goto ifagain; - - ifend: /* No more - done */ - *bx = NUL; - z = atoi(evalx(boolval)); - debug(F111,"boolexp boolval",boolval,z); - return(z); -} - -/* D O I F -- Do the IF command */ - -int -doif(cx) int cx; { - int x, y, z; char *s, *p; - char *q; -#ifdef OS2 - extern int keymac; -#endif /* OS2 */ - - debug(F101,"doif cx","",cx); - - z = boolexp(cx); /* Evaluate the condition(s) */ - debug(F010,"doif cmdbuf",cmdbuf,0); - debug(F101,"doif boolexp","",z); - if (z < 0) - return(z); - - if (cx == XXIF) { /* Allow IF to have XIF semantics. */ - char * p; - p = cmpeek(); - if (!p) p = ""; - while (*p) { - if (*p == SP || *p == HT) - p++; - else - break; - } - if (*p == '{') - cx = XXIFX; - } - switch (cx) { /* Separate handling for IF and XIF */ - - case XXASSER: /* And ASSERT */ - if ((x = cmcfm()) < 0) - return(x); - return(success = z); - - case XXIF: /* This is IF... */ - ifcmd[cmdlvl] = 1; /* We just completed an IF command */ - debug(F101,"doif condition","",z); - if (z) { /* Condition is true */ - iftest[cmdlvl] = 1; /* Remember that IF succeeded */ - if (maclvl > -1) { /* In macro, */ - pushcmd(NULL); /* save rest of command. */ - } else if (tlevel > -1) { /* In take file, */ - debug(F100, "doif: pushing command", "", 0); - pushcmd(NULL); /* save rest of command. */ - } else { /* If interactive, */ - cmini(ckxech); /* just start a new command */ - printf("\n"); /* (like in MS-DOS Kermit) */ - if (pflag) prompt(xxstring); - } - } else { /* Condition is false */ - iftest[cmdlvl] = 0; /* Remember command failed. */ - if ((y = cmtxt("command to be ignored","",&s,NULL)) < 0) - return(y); /* Gobble up rest of line */ - } - return(0); - - case XXIFX: { /* This is XIF (Extended IF) */ - char *p; - char e[5]; - int i; - if ((y = cmtxt("Object command","",&s,NULL)) < 0) - return(y); /* Get object command. */ - p = s; - lp = line; - debug(F110,"doif THEN part",s,-54); - if (litcmd(&p,&lp,LINBUFSIZ - 1) < 0) { /* Quote THEN-part */ - return(-2); - } - debug(F111,"doif THEN part 2",line,z); - - while (*p == SP) p++; /* Strip trailing spaces */ - ifcmd[cmdlvl] = 0; /* Assume ELSE part in same line */ - iftest[cmdlvl] = z ? 1 : 0; - if (*p) { /* At end? */ - if (!z) { /* No, use ELSE-part, if any */ - for (i = 0; i < 4; i++) e[i] = *p++; - if (ckstrcmp(e,"else",4,0)) /* See if we have an ELSE */ - return(-2); /* Something else - error. */ - debug(F010,"doif ELSE line 1",p,0); - while (*p == SP) p++; /* Skip spaces */ - if (*p != '{') { /* Brace ELSE part if necessary */ - ckmakmsg(tmpbuf,TMPBUFSIZ,"{",p," }",NULL); - p = tmpbuf; - debug(F010,"doif ELSE line 2",p,0); - } - lp = line; /* Write over THEN part... */ - *lp = NUL; /* with ELSE part. */ - if (litcmd(&p,&lp,LINBUFSIZ - 2) < 0) { - return(-2); - } - while (*p == SP) p++; /* Strip trailing spaces */ - if (*p) return(-2); /* Should be nothing here. */ - debug(F010,"doif ELSE line 3",line,0); - } - } else { /* At end, treat like an IF command */ - if (!z) line[0] = NUL; /* Condition not true and no ELSE */ - ifcmd[cmdlvl] = 1; /* Allow ELSE on next line */ - debug(F101,"IF condition","",z); - } - if (line[0]) { - x = mlook(mactab,"_xif",nmac); /* Get index of "_xif" macro. */ - if (x < 0) { /* Not there? */ - addmmac("_xif",xif_def); /* Put it back. */ - if (mlook(mactab,"_xif",nmac) < 0) { /* Look it up again. */ - printf("?XIF macro gone!\n"); - return(success = 0); - } - } - dodo(x,line,cmdstk[cmdlvl].ccflgs | CF_IMAC); - } - return(0); - } - case XXWHI: { /* WHILE Command */ - p = cmdbuf; /* Capture IF condition */ - ifcond[0] = NUL; /* from command buffer */ - while (*p == SP) p++; - while (*p != SP) p++; - ifcp = ifcond; - ifcp += ckstrncpy(ifcp,"{ \\flit(if ( not ",IFCONDLEN); -#ifdef COMMENT -/* - This doesn't work because it breaks on the first left brace, which does - not necessarily start the command list, e.g. "while equal \%a {\35}". -*/ - while (*p != '{' && *p != NUL) *ifcp++ = *p++; - p = " ) goto _..bot) } "; - while (*ifcp++ = *p++) ; -#else -/* - The command parser sets cmbptr to the spot where it left off parsing in - the command buffer. -*/ - { - extern char * cmbptr; - if (cmbptr) { - while (p < cmbptr && *p != NUL) - *ifcp++ = *p++; - p = " ) goto _..bot) } "; - while ((*ifcp++ = *p++)) ; - } else { - printf("?Internal error parsing WHILE condition\n"); - return(-9); - } - } -#endif /* COMMENT */ - - debug(F110,"WHILE cmd",ifcond,0); - - if ((y = cmtxt("Object command","",&s,NULL)) < 0) - return(y); /* Get object command. */ - p = s; - lp = line; - if (litcmd(&p,&lp,LINBUFSIZ - 2) < 0) { /* Quote object command */ - return(-2); - } - debug(F101,"WHILE body",line,-54); - if (line[0]) { - char *p; - x = mlook(mactab,"_while",nmac); /* index of "_while" macro. */ - if (x < 0) { /* Not there? */ - addmmac("_while",whil_def); /* Put it back. */ - if (mlook(mactab,"_while",nmac) < 0) { /* Look it up again */ - printf("?WHILE macro definition gone!\n"); - return(success = 0); - } - } - p = malloc((int)strlen(ifcond) + (int)strlen(line) + 2); - if (p) { - strcpy(p,ifcond); /* safe (prechecked) */ - strcat(p,line); /* safe (prechecked) */ - debug(F010,"WHILE dodo",p,0); - dodo(x,p,cmdstk[cmdlvl].ccflgs | CF_IMAC); - free(p); - p = NULL; - } else { - printf("?Can't allocate storage for WHILE command"); - return(success = 0); - } - } - return(0); - } - default: - return(-2); - } -} -#endif /* NOSPL */ - -/* Set up a TAKE command file */ - -int -dotake(s) char *s; { -#ifndef NOSPL - extern int tra_cmd; -#endif /* NOSPL */ -#ifndef NOLOCAL -#ifdef OS2 - extern int term_io; - int term_io_sav = term_io; -#endif /* OS2 */ -#endif /* NOLOCAL */ - int slen; - - debug(F110,"dotake",s,0); - if (!s) s = ""; - if (!*s) return(success = 0); - slen = strlen(s); - debug(F101,"dotake len","",slen); - - if ((tfile[++tlevel] = fopen(s,"r")) == NULL) { - perror(s); - debug(F110,"dotake fail",s,0); - tlevel--; - return(success = 0); - } else { - tfline[tlevel] = 0; /* Line counter */ -#ifdef VMS - conres(); /* So Ctrl-C will work */ -#endif /* VMS */ -#ifndef NOLOCAL -#ifdef OS2 - term_io = 0; /* Disable Terminal Emulator I/O */ -#endif /* OS2 */ -#endif /* NOLOCAL */ -#ifndef NOSPL - cmdlvl++; /* Entering a new command level */ - debug(F111,"CMD +F",s,cmdlvl); - debug(F101,"dotake cmdlvl","",cmdlvl); - debug(F101,"dotake tlevel","",tlevel); - if (cmdlvl > CMDSTKL) { - debug(F100,"dotake stack overflow","",0); - cmdlvl--; - debug(F111,"CMD*-F",s,cmdlvl); - fclose(tfile[tlevel--]); - printf("?TAKE files and/or DO commands nested too deeply\n"); - return(success = 0); - } - if (tfnam[tlevel]) { /* Copy the filename */ - free(tfnam[tlevel]); - tfnam[tlevel] = NULL; - } - if ((tfnam[tlevel] = malloc(strlen(s) + 1))) { - strcpy(tfnam[tlevel],s); /* safe */ - } else { - printf("?Memory allocation failure\n"); - return(success = 0); - } - ifcmd[cmdlvl] = 0; /* Set variables for this cmd file */ - iftest[cmdlvl] = 0; - count[cmdlvl] = count[cmdlvl-1]; /* Inherit this */ - intime[cmdlvl] = intime[cmdlvl-1]; /* Inherit this */ - inpcas[cmdlvl] = inpcas[cmdlvl-1]; /* Inherit this */ - takerr[cmdlvl] = takerr[cmdlvl-1]; /* Inherit this */ - merror[cmdlvl] = merror[cmdlvl-1]; /* Inherit this */ - xquiet[cmdlvl] = quiet; - xcmdsrc = CMD_TF; - cmdstk[cmdlvl].src = CMD_TF; /* Say we're in a TAKE file */ - cmdstk[cmdlvl].lvl = tlevel; /* nested at this level */ - cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs; -#else - takerr[tlevel] = takerr[tlevel-1]; /* Inherit this */ -#endif /* NOSPL */ - } -#ifndef NOSPL - if (tra_cmd) - printf("[%d] +F: \"%s\"\n",cmdlvl,s); -#endif /* NOSPL */ -#ifndef NOLOCAL -#ifdef OS2 - term_io = term_io_sav; -#endif /* OS2 */ -#endif /* NOLOCAL */ - return(1); -} -#endif /* NOICP */ diff --git a/.pc/030_fix-if-else.patch/ckuusr.c b/.pc/030_fix-if-else.patch/ckuusr.c deleted file mode 100644 index 8545f89..0000000 --- a/.pc/030_fix-if-else.patch/ckuusr.c +++ /dev/null @@ -1,13121 +0,0 @@ -#ifdef SSHTEST -#define SSHBUILTIN -#endif /* SSHTEST */ - -#include "ckcsym.h" -char *userv = "User Interface 8.0.278, 12 Mar 2004"; - -/* C K U U S R -- "User Interface" for C-Kermit (Part 1) */ - -/* - 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. -*/ - -/* - Originally the entire user interface was in one module, ckuusr.c. Over - the years it has been split into many modules: ckuus2.c, ckuus3.c, ..., - ckuus7.c. ckuus2.c contains the HELP command parser and help-text strings; - ckuusy.c contains the UNIX-style command-line interface; ckuusx.c contains - routines needed by both the command-line interface and the interactive - command parser. -*/ - -/* - The ckuus*.c modules depend on the existence of C library features like - fopen, fgets, feof, (f)printf, argv/argc, etc. Other functions that are - likely to vary among different platforms -- like setting terminal modes or - interrupts -- are invoked via calls to functions that are defined in the - system- dependent modules, ck?[ft]io.c. The command line parser processes - any arguments found on the command line, as passed to main() via argv/argc. - The interactive parser uses the facilities of the cmd package (developed for - this program, but usable by any program). Any command parser may be - substituted for this one. The only requirements for the Kermit command - parser are these: - - . Set parameters via global variables like duplex, speed, ttname, etc. See - ckmain.c for the declarations and descriptions of these variables. - - . If a command can be executed without the use of Kermit protocol, then - execute the command directly and set the variable sstate to 0. Examples - include 'set' commands, local directory listings, the 'connect' command. - - . If a command requires the Kermit protocol, set the following variables: - - sstate string data - 'x' (enter server mode) (none) - 'r' (send a 'get' command) cmarg, cmarg2 - 'v' (enter receive mode) cmarg2 - 'g' (send a generic command) cmarg - 's' (send files) nfils, cmarg & cmarg2 OR cmlist - 'c' (send a remote host command) cmarg - - cmlist is an array of pointers to strings. - cmarg, cmarg2 are pointers to strings. - nfils is an integer. - - cmarg can be a filename string (possibly wild), or - a pointer to a prefabricated generic command string, or - a pointer to a host command string. - cmarg2 is an "as-name" - the name to send file(s) under, or - the name under which to store incoming file(s); must not be wild. - A null or empty value means to use the file's own name. - cmlist is a list of filenames, such as passed via argv. - nfils is an integer, interpreted as follows: - -1: filespec (possibly wild) in cmarg, must be expanded internally. - 0: send from stdin (standard input). - >0: number of files to send, from cmlist. - - The screen() function is used to update the screen during file transfer. - The tlog() function writes to a transaction log. - The debug() function writes to a debugging log. - The intmsg() and chkint() functions provide the user i/o for interrupting - file transfers. -*/ - -/* Includes */ - -#ifdef MULTINET -#define MULTINET_OLD_STYLE /* Leave select prototype undefined */ -#endif /* MULTINET */ - -#include "ckcdeb.h" -#include "ckcasc.h" -#include "ckcker.h" -#include "ckcnet.h" /* Network symbols */ -#include "ckuusr.h" -#include "ckcxla.h" - -int g_fncact = -1; /* Needed for NOICP builds */ -int noinit = 0; /* Flag for skipping init file */ -int nscanfile = SCANFILEBUF; - -int rcdactive = 0; /* RCD active */ -int keepallchars = 0; /* See cmfld() */ - -int locus = 1; /* Current LOCUS is LOCAL */ -#ifdef OS2 -int autolocus = 2; /* Automatic LOCUS switching: ASK */ -#else /* OS2 */ -int autolocus = 1; /* Automatic LOCUS switching enabled */ -#endif /* OS2 */ - -#ifndef NOICP -#ifdef CKLEARN -#ifdef VMS -#include /* For CKLEARN */ -#endif /* VMS */ -#endif /* CKLEARN */ -#ifdef OS2 -#ifndef NT -#define INCL_NOPM -#define INCL_VIO /* Needed for ckocon.h */ -#include -#undef COMMENT -#else -#define APIRET ULONG -#include -#include -#include "cknwin.h" -#include "ckntap.h" /* CK_TAPI definition */ -#endif /* NT */ -#include "ckowin.h" -#include "ckocon.h" -extern int tcp_avail; -extern bool viewonly; -extern int k95stdout; -extern int tt_scroll; -#ifndef NOTERM -extern tt_status[VNUM]; -#endif /* NOTERM */ -int display_demo = 1; -#include "ckossh.h" -#ifdef KUI -#include "ikui.h" -#endif /* KUI */ -#endif /* OS2 */ - -int optlines = 0; -int didsetlin = 0; - -#ifdef NEWFTP -extern int ftpget, ftpisopen(), doftpres(); -_PROTOTYP(int doftptyp,(int)); -#endif /* NEWFTP */ - -#ifdef VMS -extern int batch; -#endif /* VMS */ - -#ifdef datageneral -#include -#define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd) -#endif /* datageneral */ - -extern int xcmdsrc, hints, cmflgs, whyclosed; - -char * hlptok = NULL; - -#ifdef CK_TTGWSIZ /* Whether to use more-prompting */ -int xaskmore = 1; /* Momentary setting */ -int saveask = 1; /* Permanent setting */ -#else -int xaskmore = 0; -int saveask = 0; -#endif /* CK_TTGWSIZ */ - -#ifndef NOCSETS -extern int nfilc; -extern struct keytab fcstab[]; -extern int fcharset; -#endif /* NOCSETS */ - -char * g_pswd = NULL; -int g_pcpt = -1; -int g_pflg = -1; - -extern int cmd_rows, cmd_cols; - -#ifdef CKROOT -extern int ckrooterr; -#endif /* CKROOT */ - -extern int inserver, filepeek; - -#ifdef CKLEARN -FILE * learnfp = NULL; -char * learnfile = NULL; -int learning = 0; -#endif /* CKLEARN */ - -#ifndef NOXFER -extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size, - sndsrc, server, displa, fncnv, fnspath, fnrpath, xfermode, urpsiz, - spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact, reliable, - setreliable; - -#ifdef IKSDCONF -extern int iksdcf; -#endif /* IKSDCONF */ - -#ifdef CK_LOGIN -extern int isguest; -#endif /* CK_LOGIN */ - -extern long sendstart; - -extern char *cmarg, *cmarg2, **cmlist, *dftty; - -extern struct keytab fntab[]; extern int nfntab; -extern struct ck_p ptab[NPROTOS]; - -int sndcmd = 0; /* Last command was a SEND-class command. */ - -int g_xfermode = -1; -int g_proto = -1; -int g_urpsiz = -1; -int g_spsizf = -1; -int g_spsiz = -1; -int g_spsizr = -1; -int g_spmax = -1; -int g_wslotr = -1; -int g_prefixing = -1; -int g_fncnv = -1; -int g_fnspath = -1; -int g_fnrpath = -1; -int g_fnact = -1; -int g_displa = -1; -int g_spath = -1; -int g_rpath = -1; -char * g_sfilter = NULL; -char * g_rfilter = NULL; - -extern int patterns; -#ifdef PATTERNS -extern char *txtpatterns[], *binpatterns[]; -int g_patterns = -1; -#endif /* PATTERNS */ -int g_skipbup = -1; - -#ifdef PIPESEND -extern int usepipes, pipesend; -extern char * sndfilter; -#endif /* PIPESEND */ - -#ifndef NOSPL -extern int sndxlo, sndxhi, sndxin; -#endif /* NOSPL */ - -extern char fspec[]; /* Most recent filespec */ -extern int fspeclen; /* Length of fspec[] buffer */ - -#ifndef NOFRILLS -extern int rmailf; /* MAIL command items */ -extern char optbuf[]; -#endif /* NOFRILLS */ - -extern int - en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri, - en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit, - en_mkd, en_rmd, en_asg; - -#ifndef NOMSEND /* Multiple SEND */ -extern char *msfiles[]; -int filesinlist = 0; /* And ADD ... */ -extern struct filelist * filehead; -extern struct filelist * filetail; -extern struct filelist * filenext; -extern int addlist; -#endif /* NOMSEND */ - -static struct keytab addtab[] = { -#ifdef PATTERNS - { "binary-patterns", ADD_BIN, 0 }, -#endif /* PATTERNS */ -#ifndef NOMSEND - { "send-list", ADD_SND, 0 }, -#endif /* NOMSEND */ -#ifdef PATTERNS - { "text-patterns", ADD_TXT, 0 }, -#endif /* PATTERNS */ - { "", 0, 0 } -}; -static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1; - -#ifndef NOCSETS -struct keytab assoctab[] = { - { "file-character-set", ASSOC_FC, 0 }, - { "transfer-character-set", ASSOC_TC, 0 }, - { "xfer-character-set", ASSOC_TC, CM_INV } -}; -static int nassoc = sizeof(assoctab)/sizeof(struct keytab); -extern int afcset[MAXFCSETS+1]; /* Character-set associations */ -extern int axcset[MAXTCSETS+1]; -#endif /* NOCSETS */ - -#ifndef ADDCMD -#ifndef NOMSEND -#define ADDCMD -#endif /* NOMSEND */ -#ifndef ADDCMD -#ifdef PATTERNS -#define ADDCMD -#endif /* PATTERNS */ -#endif /* ADDCMD */ -#endif /* ADDCMD */ -#endif /* NOXFER */ - -/* External Kermit Variables, see ckmain.c for description. */ - -extern xx_strp xxstring; -extern long xvernum; - -extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel, - pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active; -#ifdef TNCODE -extern int debses; -extern char tn_msg[]; -#endif /* TNCODE */ - -int sleepcan = 1; -int g_binary = -1; -int g_recursive = -1; -int g_matchdot = -1; -extern int nolinks; - -extern long vernum; -extern char *versio, *copyright[]; -extern char *ckxsys; -#ifndef NOHELP -extern char *introtxt[]; -extern char *newstxt[]; -#endif /* NOHELP */ - -#ifndef OS2 -#ifndef UNIX -extern char *PWDCMD; -#endif /* UNIX */ -extern char *WHOCMD; -#endif /* OS2 */ - -extern char ttname[]; - -extern CHAR sstate; - -extern int network; /* Have active network connection */ -extern int nettype; /* Type of network */ -extern int ttnproto; /* NET_TCPB protocol */ - -#ifndef NODIAL -extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */ -#endif /* NODIAL */ - -#ifdef CK_APC -extern int apcactive, apcstatus; -#endif /* CK_APC */ - -#ifndef NOPUSH -#ifndef NOFRILLS -extern char editor[]; -extern char editopts[]; -extern char editfile[]; -#endif /* NOFRILLS */ -#endif /* NOPUSH */ - -#ifdef BROWSER -extern char browser[]; /* Web browser application */ -extern char browsopts[]; /* Web browser options */ -extern char browsurl[]; /* Most recent URL */ -#endif /* BROWSER */ -#ifndef NOFTP -char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */ -char ftpopts[128] = { NUL, NUL }; /* ftp command-line options */ -#endif /* NOFTP */ -extern struct keytab onoff[]; /* On/Off keyword table */ - -#ifdef CK_TMPDIR -int f_tmpdir = 0; /* Directory changed temporarily */ -char savdir[TMPDIRLEN]; /* For saving current directory */ -#endif /* CK_TMPDIR */ - -int activecmd = -1; /* Keyword index of active command */ -int doconx = -1; /* CONNECT-class command active */ -int ooflag = 0; /* User-settable on/off flag */ - -int rcflag = 0; /* Pointer to home directory string */ -int repars, /* Reparse needed */ - techo = 0; /* Take echo */ -int secho = 1; /* SCRIPT echo */ - -int xitwarn = /* Warn about open connection on exit */ -#ifdef NOWARN -0 -#else -1 -#endif /* NOWARN */ -; - -struct keytab onoffsw[] = { - { "/off", 0, 0 }, - { "/on", 1, 0 } -}; - -#ifdef CKEXEC -struct keytab redirsw[] = { - { "/redirect", 1, 0 } -}; -#endif /* CKEXEC */ - -#ifndef NOXMIT -/* Variables for TRANSMIT command */ - -int xmitx = 1; /* Whether to echo during TRANSMIT */ -int xmitf = 0; /* Character to fill empty lines */ -int xmitl = 0; /* 0 = Don't send linefeed too */ -int xmitp = LF; /* Host line prompt */ -int xmits = 0; /* Use shift-in/shift-out, 0 = no */ -int xmitw = 0; /* Milliseconds to pause during TRANSMIT */ -int xmitt = 1; /* Seconds to wait for each char to echo */ -int xmita = 1; /* Action upon timeout */ - -#define XMI_BIN 1 -#define XMI_TXT 2 -#define XMI_CMD 3 -#define XMI_TRA 4 -#define XMI_VRB 5 -#define XMI_QUI 6 -#define XMI_NOW 7 -#define XMI_NOE 8 - -static struct keytab xmitsw[] = { /* TRANSMIT command options */ - { "/binary", XMI_BIN, 0 }, -#ifdef PIPESEND - { "/command", XMI_CMD, CM_INV|CM_PSH }, -#endif /* PIPESEND */ - { "/noecho", XMI_NOE, 0 }, - { "/nowait", XMI_NOW, 0 }, -#ifdef PIPESEND - { "/pipe", XMI_CMD, 0 }, -#endif /* PIPESEND */ -#ifdef COMMENT - { "/quiet", XMI_QUI, 0 }, -#endif /* COMMENT */ - { "/text", XMI_TXT, 0 }, - { "/transparent", XMI_TRA, 0 }, -#ifdef COMMENT - { "/verbose", XMI_VRB, 0 }, -#endif /* COMMENT */ - { "", 0, 0 } -}; -#define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1 -static int nxmitsw = NXMITSW; - -#endif /* NOXMIT */ - -/* Declarations from ck?fio.c module */ - -extern char *SPACMD, *SPACM2; /* SPACE commands */ - -/* Command-oriented items */ - -#ifdef DCMDBUF -extern char *cmdbuf; /* Command buffers */ -extern char *atmbuf; -extern char *line; /* Character buffer for anything */ -extern char *tmpbuf; /* Short temporary string buffer */ -extern int *ifcmd; -extern int *intime; -extern int *inpcas; -#else -extern char cmdbuf[]; /* Command buffers */ -extern char atmbuf[]; -extern char line[]; /* Character buffer for anything */ -extern char tmpbuf[]; /* Temporary buffer */ -extern int ifcmd[]; -extern int intime[]; -extern int inpcas[]; -#endif /* DCMDBUF */ - -#ifndef NOSPL -extern char * prstring[]; -#endif /* NOSPL */ - -char *lp; /* Pointer to line buffer */ - -#ifndef NOSPL -int unkmacro = 0; /* Flag for in ON_UNKNOWN_COMMAND */ -int oldeval = 0; -char evalbuf[33]; /* EVALUATE result */ -extern char * inpbuf; /* Buffer for INPUT and REINPUT */ -char *inpbp; /* And pointer to same */ -extern char lblbuf[]; /* Buffer for labels */ -int m_found; /* MINPUT result */ -int i_active = 0; /* INPUT command is active */ -char *ms[MINPMAX]; /* Pointers to MINPUT strings */ -static int mp[MINPMAX]; /* and flags */ -extern int fndiags, fnerror, fnsuccess; /* Function diagnostics */ -#ifndef NOSEXP -char * lastsexp = NULL; /* S-Expressions */ -char * sexpval = NULL; -int sexpecho = SET_AUTO; -#endif /* NOSEXP */ -#endif /* NOSPL */ - -char psave[PROMPTL] = { NUL }; /* For saving & restoring prompt */ - -extern int success; /* Command success/failure flag */ -extern int cmdlvl; /* Current position in command stack */ - -#ifndef NOSPL -int /* SET INPUT parameters. */ -/* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */ - inbufsize = 0, /* INPUT buffer size */ - indef = 1, /* default timeout, seconds */ - inecho = 1, /* 1 = echo on */ - inautodl = 0, /* INPUT autodownload */ - inintr = 1, /* INPUT interrupion allowed */ - innomatch = 0, /* INPUT /NOMATCH */ - insilence = 0; /* 0 = no silence constraint */ - -#ifdef CKFLOAT -CKFLOAT inscale = 1.0; /* Timeout scale factor */ -#endif /* CKFLOAT */ - -#ifdef OS2 -int interm = 1; /* Terminal emulator displays input */ -#endif /* OS2 */ -int maclvl = -1; /* Macro nesting level */ -int mecho = 0; /* Macro echo, 0 = don't */ -char varnam[6]; /* For variable names */ -extern int macargc[]; /* ARGC from macro invocation */ - -extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */ -extern char *mrval[]; - -extern char **a_ptr[]; /* Array pointers */ -extern int a_dim[]; /* Array dimensions */ -extern int a_link[]; - -#ifdef DCMDBUF -extern struct cmdptr *cmdstk; /* The command stack itself */ -#else -extern struct cmdptr cmdstk[]; /* The command stack itself */ -#endif /* DCMDBUF */ - -long ck_alarm = 0; /* SET ALARM value */ -char alrm_date[24] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' }; -char alrm_time[24] = { ' ',' ',' ',' ',' ',' ',' ' }; - -#define INPSW_NOM 1 -struct keytab inputsw[] = { - { "/nomatch", INPSW_NOM, 0 } -}; -static int ninputsw = sizeof(inputsw)/sizeof(struct keytab); - -#endif /* NOSPL */ - -static int x, y, z = 0; /* Local workers */ -static char *s; - -#ifdef CK_MINPUT -static char c1chars[] = { /* C1 control chars escept NUL */ - 001,002,003,004,005,006,007,010,011,012,013,014,015,016,017,020, - 021,022,023,024,025,026,027,030,031,032,033,034,035,036,037 -}; -#endif /* CK_MINPUT */ - -#define xsystem(s) zsyscmd(s) - -/* Top-Level Interactive Command Keyword Table */ -/* Keywords must be in lowercase and in alphabetical order. */ - -struct keytab cmdtab[] = { -#ifndef NOPUSH - { "!", XXSHE, CM_INV|CM_PSH }, /* Shell escape */ -#else - { "!", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOPUSH */ - { "#", XXCOM, CM_INV }, /* Comment */ -#ifndef NOSPL - { "(", XXSEXP,CM_INV }, /* S-Expression */ - { ".", XXDEF, CM_INV }, /* Assignment */ - { ":", XXLBL, CM_INV }, /* Label */ -#endif /* NOSPL */ -#ifdef CK_REDIR -#ifndef NOPUSH - { "<", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */ -#else - { "<", XXNOTAV, CM_INV|CM_PSH }, /* REDIRECT */ -#endif /* NOPUSH */ -#endif /* CK_REDIR */ -#ifndef NOPUSH - { "@", XXSHE, CM_INV|CM_PSH }, /* DCL escape */ -#else - { "@", XXNOTAV, CM_INV|CM_PSH }, /* DCL escape */ -#endif /* NOPUSH */ - -#ifdef CK_RECALL - { "^", XXREDO,CM_INV|CM_NOR }, /* Synonym for REDO */ -#endif /* CK_RECALL */ -#ifndef NOSPL - { "_asg", XXASX, CM_INV }, /* Used internally by FOR, etc */ - { "_assign", XXASX, CM_INV }, /* Used internally by FOR, etc */ - { "_decrement", XX_DECR, CM_INV }, - { "_define", XXDFX, CM_INV }, /* Used internally by FOR, etc */ - { "_evaluate", XX_EVAL, CM_INV }, - { "_forward", XXXFWD, CM_INV }, /* Used internally by SWITCH */ - { "_getargs", XXGTA, CM_INV }, /* Used internally by FOR, etc */ - { "_increment", XX_INCR, CM_INV }, - { "_putargs", XXPTA, CM_INV }, /* Used internally by FOR, etc */ - { "_undefine", XXUNDFX, CM_INV }, -#endif /* NOSPL */ - - { "about", XXVER, CM_INV }, /* Synonym for VERSION */ -#ifndef NOSPL -#ifdef NEWFTP - { "account", XXACCT, CM_INV }, /* (FTP) Account */ -#endif /* NEWFTP */ -#ifdef ADDCMD - { "add", XXADD, 0 }, /* ADD */ -#endif /* ADDCMD */ -#ifndef NODIAL - { "answer", XXANSW, CM_LOC }, /* ANSWER the phone */ -#else - { "answer", XXNOTAV, CM_INV|CM_LOC }, /* ANSWER the phone */ -#endif /* NODIAL */ - { "apc", XXAPC, 0 }, /* Application Program Command */ -#ifndef NOSPL - { "array", XXARRAY, 0 }, /* Array operations */ -#endif /* NOSPL */ - { "ascii", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */ - { "asg", XXASS, CM_INV }, /* Invisible synonym for ASSIGN */ - { "ask", XXASK, 0 }, /* ASK for text, assign to variable */ - { "askq", XXASKQ,0 }, /* ASK quietly (no echo) */ -#ifndef NOSPL - { "ass", XXASS, CM_INV|CM_ABR }, /* ASSIGN */ - { "assert", XXASSER, CM_INV }, /* ASSERT */ - { "assign", XXASS, 0 }, /* ASSIGN */ -#endif /* NOSPL */ -#ifndef NOXFER -#ifndef NOCSETS - { "associate", XXASSOC, 0 }, /* ASSOCIATE */ -#else - { "associate", XXNOTAV, CM_INV }, /* ASSOCIATE */ -#endif /* NOCSETS */ -#endif /* NOXFER */ -#ifdef CK_KERBEROS -#ifdef CK_AUTHENTICATION - { "authenticate",XXAUTH, 0 }, /* Authentication */ -#else - { "authenticate",XXAUTH, CM_INV }, -#endif /* CK_AUTHENTICATION */ -#endif /* CK_KERBEROS */ -#endif /* NOSPL */ -#ifndef NOFRILLS - { "back", XXBACK, 0 }, /* BACK to previous directory */ -#else - { "back", XXNOTAV,CM_INV }, -#endif /* NOFRILLS */ - { "beep", XXBEEP,CM_INV }, /* BEEP */ -#ifndef NOXFER - { "binary", XXBIN, CM_INV }, /* == SET FILE TYPE BINARY */ -#endif /* NOXFER */ -#ifndef NOFRILLS - { "bug", XXBUG, CM_INV }, /* BUG report instructions */ -#else - { "bug", XXNOTAV, CM_INV }, -#endif /* NOFRILLS */ -#ifdef BROWSER - { "browse", XXBROWS, CM_PSH|CM_LOC }, /* BROWSE (start browser) */ -#else - { "browse", XXNOTAV, CM_INV|CM_PSH|CM_LOC }, -#endif /* BROWSER */ -#ifndef NOXFER - { "bye", XXBYE, 0 }, /* BYE to remote server */ -#endif /* NOXFER */ -#ifndef NOLOCAL - { "c", XXCON, CM_INV|CM_ABR|CM_LOC }, /* (CONNECT) */ -#endif /* NOLOCAL */ -#ifndef NOFRILLS - { "cat", XXCAT, CM_INV }, /* Invisible synonym for TYPE */ -#endif /* NOFRILLS */ -#ifndef NOSPL - -#ifndef NOXFER - { "cautious", XXCAU, CM_INV }, -#endif /* NOXFER */ - -#endif /* NOSPL */ - - { "cd", XXCWD, 0 }, /* Change Directory */ - { "cdup", XXCDUP, CM_INV }, /* Change Directory Up */ - -#ifndef NOXFER -#ifdef PIPESEND - { "cget", XXCGET, CM_INV|CM_PSH }, /* CGET */ -#else - { "cget", XXNOTAV, CM_INV|CM_PSH }, /* CGET */ -#endif /* PIPESEND */ -#endif /* NOXFER */ - { "ch", XXCHK, CM_INV|CM_ABR }, - { "check", XXCHK, 0 }, /* CHECK for a feature */ -#ifdef CK_PERMS -#ifdef UNIX - { "chmod", XXCHMOD, 0 }, /* CHMOD */ -#else - { "chmod", XXNOTAV, CM_INV }, -#endif /* UNIX */ -#else - { "chmod", XXNOTAV, CM_INV }, -#endif /* CK_PERMS */ -#ifdef CKROOT - { "chroot", XXCHRT, CM_INV }, /* CHROOT */ -#endif /* CKROOT */ - { "ckermit", XXKERMI, CM_INV }, /* CKERMIT (like KERMIT) */ - { "cl", XXCLO, CM_ABR|CM_INV }, -#ifndef NOFRILLS - { "clear", XXCLE, 0 }, /* CLEAR input and/or device buffer */ -#else - { "clear", XXNOTAV, CM_INV }, -#endif /* NOFRILLS */ - { "close", XXCLO, 0 }, /* CLOSE a log or other file */ - { "cls", XXCLS, CM_INV }, /* Clear Screen (CLS) */ - { "comment", XXCOM, CM_INV }, /* Introduce a comment */ -#ifndef NOLOCAL - { "connect", XXCON, CM_LOC }, /* Begin terminal connection */ -#else - { "connect", XXNOTAV, CM_LOC }, -#endif /* NOLOCAL */ - { "continue", XXCONT, CM_INV }, /* CONTINUE */ -#ifndef NOFRILLS -#ifdef ZCOPY - { "co", XXCPY, CM_INV|CM_ABR }, - { "cop", XXCPY, CM_INV|CM_ABR }, - { "copy", XXCPY, 0 }, /* COPY a file */ -#else - { "copy", XXNOTAV, CM_INV }, -#endif /* ZCOPY */ - { "copyright", XXCPR, CM_INV }, /* COPYRIGHT */ -#ifdef ZCOPY - { "cp", XXCPY, CM_INV }, /* COPY a file */ -#endif /* ZCOPY */ -#ifndef NOLOCAL -#ifndef OS2 - { "cq", XXCQ, CM_INV|CM_LOC }, /* CQ (connect quietly) */ -#endif /* OS2 */ -#endif /* NOLOCAL */ -#ifndef NOXFER -#ifdef PIPESEND - { "creceive", XXCREC,CM_INV|CM_PSH }, /* RECEIVE to a command */ - { "csend", XXCSEN,CM_INV|CM_PSH }, /* SEND from command */ -#else - { "creceive", XXNOTAV,CM_INV|CM_PSH }, - { "csend", XXNOTAV,CM_INV|CM_PSH }, -#endif /* PIPESEND */ -#endif /* NOXFER */ -#endif /* NOFRILLS */ - - { "cwd", XXCWD, CM_INV }, /* Traditional synonym for cd */ - -#ifndef NOSPL - { "date", XXDATE, 0 }, /* DATE */ - { "dcl", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */ - { "debug", XXDEBUG, CM_INV }, - { "declare", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */ - { "decrement", XXDEC, 0 }, /* DECREMENT a numeric variable */ - { "define", XXDEF, 0 }, /* DEFINE a macro or variable */ -#else - { "date", XXNOTAV, CM_INV }, - { "dcl", XXNOTAV, CM_INV }, - { "declare", XXNOTAV, CM_INV }, - { "decrement", XXNOTAV, CM_INV }, - { "define", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOFRILLS - { "delete", XXDEL, 0 }, /* DELETE a file */ -#else - { "delete", XXNOTAV, CM_INV }, -#endif /* NOFRILLS */ - -#ifndef NODIAL - { "dial", XXDIAL, CM_LOC }, /* DIAL a phone number */ -#else - { "dial", XXNOTAV, CM_INV|CM_LOC }, -#endif /* NODIAL */ - -#ifdef NT - { "dialer", XXDIALER, CM_INV }, /* K95 Dialer */ -#endif /* NT */ - - { "directory", XXDIR, 0 }, /* DIRECTORY of files */ - -#ifndef NOFRILLS -#ifndef NOSERVER - { "disable", XXDIS, 0 }, /* DISABLE a server function */ -#else - { "disable", XXNOTAV, CM_INV }, -#endif /* NOSERVER */ -#endif /* NOFRILLS */ - -#ifndef NOSPL - { "do", XXDO, 0 }, /* DO (execute) a macro */ -#else - { "do", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - - { "e", XXEXI, CM_INV|CM_ABR }, - -#ifndef NOFRILLS -#ifndef NOXFER - { "e-packet", XXERR, CM_INV }, /* Send an Error-Packet */ -#endif /* NOXFER */ -#endif /* NOFRILLS */ - - { "echo", XXECH, 0 }, /* ECHO text */ - -#ifndef NOFRILLS -#ifndef NOPUSH - { "edit", XXEDIT, CM_PSH }, /* EDIT */ -#else - { "edit", XXNOTAV, CM_INV|CM_PSH }, /* EDIT */ -#endif /* NOPUSH */ -#endif /* NOFRILLS */ - - { "eightbit", XXEIGHT, CM_INV }, /* EIGHTBIT */ - -#ifndef NOSPL - { "else", XXELS, CM_INV }, /* ELSE part of IF statement */ -#else - { "else", XXNOTAV, CM_INV }, /* ELSE part of IF statement */ -#endif /* NOSPL */ - -#ifndef NOSERVER -#ifndef NOFRILLS - { "enable", XXENA, 0 }, /* ENABLE a server function */ -#else - { "enable", XXNOTAV, CM_INV }, -#endif /* NOFRILLS */ -#endif /* NOSERVER */ - -#ifndef NOSPL - { "end", XXEND, 0 }, /* END command file or macro */ -#else - { "end", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - - { "erase", XXDEL, CM_INV }, /* Synonym for DELETE */ - -#ifndef NOSPL - { "evaluate", XXEVAL, 0 }, /* EVALUATE */ -#else - { "evaluate", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - - { "ex", XXEXI, CM_INV|CM_ABR }, /* Let "ex" still be EXIT */ - -#ifdef CKEXEC - { "exec", XXEXEC, CM_INV|CM_LOC }, /* exec() */ -#else - { "exec", XXNOTAV, CM_INV|CM_LOC }, -#endif /* CKEXEC */ - - { "exit", XXEXI, 0 }, /* EXIT from C-Kermit */ - { "extended-options", XXXOPTS,CM_INV|CM_HLP }, /* Extended-Options */ - -#ifdef OS2 - { "extproc", XXCOM, CM_INV }, /* Dummy command for OS/2 */ -#endif /* OS2 */ - -#ifndef NOXFER - { "f", XXFIN, CM_INV|CM_ABR }, /* Invisible abbrev for FIN */ -#endif /* NOXFER */ - -#ifndef NOSPL - { "fail", XXFAIL, CM_INV }, /* FAIL */ - -#ifndef NOXFER - { "fast", XXFAST, CM_INV }, -#endif /* NOXFER */ - -#ifdef CKCHANNELIO - { "fclose", XXF_CL, CM_INV }, /* FCLOSE */ - { "fcount", XXF_CO, CM_INV }, /* FCOUNT */ - { "fflush", XXF_FL, CM_INV }, /* FFLUSH */ -#endif /* CKCHANNELIO */ - -#ifndef NOXFER - { "fi", XXFIN, CM_INV|CM_ABR }, /* FINISH */ -#endif /* NOXFER */ - -#ifdef CKCHANNELIO - { "file", XXFILE, 0 }, /* FILE */ -#endif /* CKCHANNELIO */ -#endif /* NOSPL */ - -#ifndef NOXFER - { "fin", XXFIN, CM_INV|CM_ABR }, /* FINISH */ -#endif /* NOXFER */ - -#ifndef UNIXOROSK - { "find", XXGREP, 0 }, /* FIND (grep) */ -#else - { "find", XXGREP,CM_INV }, -#endif /* UNIXOROSK */ - -#ifndef NOXFER - { "finish", XXFIN, 0 }, /* FINISH */ -#endif /* NOXFER */ - -#ifdef TCPSOCKET - { "firewall", XXFIREW, CM_INV|CM_HLP }, -#endif /* TCPSOCKET */ - -#ifdef CKCHANNELIO - { "flist", XXF_LI, CM_INV }, /* FLIST */ - { "fopen", XXF_OP, CM_INV }, /* FOPEN */ -#endif /* CKCHANNELIO */ - -#ifndef NOSPL - { "fo", XXFOR, CM_INV|CM_ABR }, /* Invisible abbrev for... */ - { "for", XXFOR, 0 }, /* FOR loop */ - { "forward", XXFWD, CM_INV }, /* FORWARD */ -#endif /* NOSPL */ -#ifndef NOFRILLS - { "fot", XXDIR, CM_INV }, /* "fot" = "dir" (for Chris) */ -#endif /* NOFRILLS */ - -#ifdef CKCHANNELIO - { "fread", XXF_RE, CM_INV }, /* FREAD */ - { "frewind", XXF_RW, CM_INV }, /* FREWIND */ - { "fseek", XXF_SE, CM_INV }, /* FSEEK */ - { "fstatus", XXF_ST, CM_INV }, /* FSTATUS */ -#endif /* CKCHANNELIO */ - -#ifdef TCPSOCKET -#ifndef NOFTP -#ifdef SYSFTP -#ifndef NOPUSH - { "ftp", XXFTP, CM_INV|CM_PSH|CM_LOC }, /* System FTP */ -#else - { "ftp", XXNOTAV, CM_INV|CM_PSH|CM_LOC }, -#endif /* NOPUSH */ -#else /* SYSFTP */ - { "ftp", XXFTP, 0 }, /* Built-in FTP */ -#endif /* SYSFTP */ -#else /* NOFTP */ - { "ftp", XXNOTAV, CM_INV }, /* No FTP */ -#endif /* NOFTP */ -#endif /* TCPSOCKET */ - -#ifndef NOSPL - { "function", XXFUNC, CM_INV|CM_HLP }, /* (for HELP FUNCTION) */ -#endif /* NOSPL */ - -#ifdef CKCHANNELIO - { "fwrite", XXF_WR, CM_INV }, /* FWRITE */ -#endif /* CKCHANNELIO */ - -#ifndef NOXFER - { "g", XXGET, CM_INV|CM_ABR }, /* Invisible abbrev for GET */ -#ifndef NOSPL - { "ge", XXGET, CM_INV|CM_ABR }, /* Ditto */ -#endif /* NOSPL */ - { "get", XXGET, 0 }, /* GET */ -#endif /* NOXFER */ -#ifndef NOSPL - { "getc", XXGETC, 0 }, /* GETC */ -#ifdef OS2 - { "getkeycode", XXGETK, 0 }, /* GETKEYCODE */ -#endif /* OS2 */ -#ifndef NOFRILLS - { "getok", XXGOK, 0 }, /* GETOK (ask for Yes/No/OK) */ -#endif /* NOFRILLS */ -#endif /* NOSPL */ -#ifndef NOSPL - { "goto", XXGOTO,0 }, /* GOTO label in take file or macro */ -#endif /* NOSPL */ -#ifdef UNIXOROSK - { "grep", XXGREP,0 }, /* GREP (find) */ -#else - { "grep", XXGREP,CM_INV }, /* GREP (find) */ -#endif /* UNIXOROSK */ - { "h", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */ - { "he", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */ -#ifndef NOFRILLS - { "head", XXHEAD, 0 }, -#endif /* NOFRILLS */ -#ifndef NOLOCAL - { "hangup", XXHAN, CM_LOC }, /* HANGUP the connection */ -#endif /* NOLOCAL */ - { "HELP", XXHLP, 0 }, /* Display HELP text */ -#ifndef NOHTTP -#ifdef TCPSOCKET - { "http", XXHTTP, 0 }, /* HTTP operations */ -#endif /* TCPSOCKET */ -#endif /* NOHTTP */ -#ifndef NOSPL - { "i", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */ - { "if", XXIF, 0 }, /* IF ( condition ) command */ -#ifdef TCPSOCKET - { "iksd", XXIKSD, CM_INV }, /* Make connection to IKSD */ -#else - { "iksd", XXNOTAV, CM_INV }, -#endif /* TCPSOCKET */ - { "in", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */ - { "increment", XXINC, 0 }, /* Increment a numeric variable */ - { "input", XXINP, 0 }, /* INPUT text from comm device */ -#endif /* NOSPL */ - -#ifndef NOHELP - { "int", XXINT, CM_INV|CM_ABR }, - { "intr", XXINT, CM_INV|CM_ABR }, - { "INTRO", XXINT, 0 }, - { "introduction",XXINT, CM_INV }, /* Print introductory text */ -#else - { "intro", XXNOTAV, CM_INV }, - { "introduction",XXNOTAV, CM_INV }, -#endif /* NOHELP */ - -#ifdef OS2 - { "k95", XXKERMI, CM_INV }, /* Hmmm what's this... */ -#endif /* OS2 */ - -#ifndef NOSPL - { "kcd", XXKCD, 0 }, -#endif /* NOSPL */ - - { "kermit", XXKERMI, CM_INV }, - -#ifdef OS2 -#ifndef NOKVERBS - { "kverb", XXKVRB, CM_INV|CM_HLP }, /* Keyboard verb */ -#endif /* NOKVERBS */ -#endif /* OS2 */ - -#ifndef NOFRILLS - { "l", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */ -#endif /* NOFRILLS */ - - { "lcd", XXLCWD, CM_INV }, - { "lcdup", XXLCDU, CM_INV }, - { "lcwd", XXLCWD, CM_INV }, - { "ldelete", XXLDEL, CM_INV }, - { "ldirectory", XXLDIR, CM_INV }, - -#ifdef CKLEARN - { "learn", XXLEARN, 0 }, /* LEARN - automatic script writing */ -#else - { "learn", XXNOTAV, CM_INV }, -#endif /* CKLEARN */ - - { "li", XXLNOUT, CM_INV|CM_ABR }, - { "LICENSE", XXCPR, 0 }, /* LICENSE */ - -#ifndef NOSPL - { "lineout", XXLNOUT, 0 }, /* LINEOUT = OUTPUT + eol */ -#endif /* NOSPL */ - -#ifdef NT - { "link", XXLINK, 0 }, /* LINK source destination */ -#endif /* NT */ - - { "lmkdir", XXLMKD, CM_INV }, - -#ifndef NOFRILLS - { "lo", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */ -#endif /* NOFRILLS */ - -#ifndef NOSPL - { "local", XXLOCAL, CM_INV }, /* LOCAL variable declaration */ -#else - { "local", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - - { "log", XXLOG, 0 }, /* Open a log file */ - - { "login", XXLOGIN, 0 }, /* (REMOTE) LOGIN to server or IKSD */ - { "logout", XXLOGOUT, 0 }, /* LOGOUT from server or IKSD */ - -#ifndef NOFRILLS -#ifndef NODIAL - { "lookup", XXLOOK, 0 }, /* LOOKUP */ -#else - { "lookup", XXNOTAV, CM_INV }, -#endif /* NODIAL */ - - { "lpwd", XXLPWD, CM_INV }, - { "lrename", XXLREN, CM_INV }, - { "lrmdir", XXLRMD, CM_INV }, - -#ifdef UNIXOROSK - { "ls", XXLS, CM_INV|CM_PSH }, /* UNIX ls command */ -#else - { "ls", XXDIR, CM_INV }, /* Invisible synonym for DIR */ -#endif /* UNIXOROSK */ -#ifndef NOXFER - { "mail", XXMAI, 0 }, /* Send a file as e-mail */ -#endif /* NOXFER */ -#ifndef NOHELP - { "manual", XXMAN, CM_PSH }, /* MAN(UAL) */ -#else - { "manual", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOHELP */ -#endif /* NOFRILLS */ -#ifdef CK_MKDIR - { "md", XXMKDIR, CM_INV }, /* Synonym for MKDIR */ -#endif /* CK_MKDIR */ -#ifdef CK_MINPUT - { "minput", XXMINP, 0 }, /* MINPUT */ -#else - { "minput", XXNOTAV, CM_INV }, -#endif /* CK_MINPUT */ -#ifndef NOMSEND - { "mget", XXMGET, 0 }, /* MGET */ -#else - { "mget", XXNOTAV, CM_INV }, -#endif /* NOMSEND */ -#ifdef CK_MKDIR - { "mkdir", XXMKDIR, 0 }, /* MKDIR */ -#else - { "mkdir", XXNOTAV, CM_INV }, -#endif /* CK_MKDIR */ - -#ifndef NOXFER -#ifndef NOMSEND - { "mmove", XXMMOVE, 0 }, /* MMOVE */ -#else - { "mmove", XXNOTAV, CM_INV }, -#endif /* NOMSEND */ -#endif /* NOXFER */ - -#ifndef NOFRILLS - { "more", XXMORE, CM_INV }, /* MORE */ -#endif /* NOFRILLS */ - -#ifndef NOXFER - { "move", XXMOVE, 0 }, /* MOVE */ -#endif /* NOXFER */ - -#ifndef NOSPL - { "mpause", XXMSL, CM_INV }, /* Millisecond sleep */ -#else - { "mpause", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOXFER -#ifndef NOMSEND - { "mput", XXMSE, CM_INV }, /* MPUT = MSEND */ - { "ms", XXMSE, CM_INV|CM_ABR }, - { "msend", XXMSE, 0 }, /* Multiple SEND */ -#else - { "mput", XXNOTAV, CM_INV }, - { "msend", XXNOTAV, CM_INV }, -#endif /* NOMSEND */ -#endif /* NOXFER */ -#ifndef NOSPL - { "msleep", XXMSL, 0 }, /* Millisecond sleep */ -#else - { "msleep", XXNOTAV, CM_INV }, -#endif /* NOSPL */ -#ifndef NOFRILLS - { "mv", XXREN, CM_INV }, /* Synonym for rename */ -#endif /* NOFRILLS */ -#ifndef NOHELP - { "news", XXNEW, CM_INV }, /* Display NEWS of new features */ -#else - { "news", XXNOTAV, CM_INV }, -#endif /* NOHELP */ - { "nolocal", XXNLCL, CM_INV }, /* Disable SET LINE / SET HOST */ - { "nopush", XXNPSH, CM_INV }, /* Disable PUSH command/features */ -#ifdef OS2 - { "noscroll", XXNSCR, CM_INV }, /* Disable scroll operations */ -#endif /* OS2 */ -#ifndef NOSPL - { "o", XXOUT, CM_INV|CM_ABR }, /* Invisible synonym for OUTPUT */ - { "open", XXOPE, 0 }, /* OPEN file for reading or writing */ -#else - { "open", XXOPE, CM_INV }, /* OPEN */ -#endif /* NOSPL */ -#ifndef NOHELP - { "options", XXOPTS,CM_INV|CM_HLP }, /* Options */ -#endif /* NOHELP */ - { "orientation", XXORIE, 0 }, -#ifndef NOSPL - { "output", XXOUT, 0 }, /* OUTPUT text to comm device */ -#else - { "output", XXNOTAV, CM_INV }, -#endif /* NOSPL */ -#ifdef ANYX25 -#ifndef IBMX25 - { "pad", XXPAD, CM_LOC }, /* X.3 PAD commands */ -#endif /* IBMX25 */ -#endif /* ANYX25 */ - -#ifdef NEWFTP - { "passive", XXPASV, CM_INV }, /* (FTP) PASSIVE */ -#endif /* NEWFTP */ - -#ifndef NOHELP - { "patterns", XXPAT,CM_INV|CM_HLP }, /* Pattern syntax */ -#endif /* NOHELP */ - -#ifndef NOSPL - { "pause", XXPAU, 0 }, /* Sleep for specified interval */ -#else - { "pause", XXNOTAV, CM_INV }, -#endif /* NOSPL */ -#ifndef NODIAL - { "pdial", XXPDIA, CM_LOC }, /* PDIAL (partial dial) */ -#else - { "pdial", XXNOTAV, CM_INV|CM_LOC }, -#endif /* NODIAL */ -#ifdef TCPSOCKET -#ifndef NOPUSH - { "ping", XXPNG, CM_INV|CM_PSH|CM_LOC }, /* PING */ -#else - { "ping", XXNOTAV, CM_INV|CM_PSH|CM_LOC }, -#endif /* NOPUSH */ -#endif /* TCPSOCKET */ -#ifdef NETCMD -#ifndef NOPUSH - { "pipe", XXPIPE, CM_PSH }, /* PIPE */ -#else - { "pipe", XXNOTAV, CM_INV|CM_PSH }, /* PIPE */ -#endif /* NOPUSH */ -#endif /* NETCMD */ - -#ifndef NOSPL - { "pop", XXEND, CM_INV }, /* Invisible synonym for END */ -#endif /* NOSPL */ -#ifndef NOFRILLS - { "print", XXPRI, 0 }, /* PRINT a file locally */ -#endif /* NOFRILLS */ - - { "prompt", XXPROMP, CM_INV }, /* Go interactive (from script) */ - -#ifndef NOXFER -#ifdef CK_RESEND - { "psend", XXPSEN, CM_INV }, /* PSEND */ -#else - { "psend", XXNOTAV, CM_INV }, -#endif /* CK_RESEND */ -#endif /* NOXFER */ - -#ifdef NETPTY - { "pty", XXPTY, CM_PSH }, /* PTY */ -#else - { "pty", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NETPTY */ - -#ifndef NOPUSH - { "pu", XXSHE, CM_INV|CM_ABR|CM_PSH }, /* PU = PUSH */ -#endif /* NOPUSH */ - -#ifdef CKPURGE - { "purge", XXPURGE, 0 }, /* PURGE (real) */ -#else -#ifdef VMS - { "purge", XXPURGE, 0 }, /* PURGE (fake) */ -#else - { "purge", XXNOTAV, CM_INV }, -#endif /* VMS */ -#endif /* CKPURGE */ - -#ifndef NOPUSH - { "push", XXSHE, CM_PSH }, /* PUSH command (like RUN, !) */ -#else - { "push", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOPUSH */ - -#ifndef NOXFER - { "put", XXSEN, CM_INV }, /* PUT = SEND */ -#endif /* NOXFER */ - - { "pwd", XXPWD, 0 }, /* Print Working Directory */ - { "q", XXQUI, CM_INV|CM_ABR }, /* Invisible synonym for QUIT */ - -#ifndef NOXFER - { "query", XXRQUE,CM_INV }, /* (= REMOTE QUERY) */ -#endif /* NOXFER */ - - { "quit", XXQUI, 0 }, /* QUIT from program = EXIT */ - -#ifndef NOXFER - { "r", XXREC, CM_INV|CM_ABR }, /* Inv synonym for RECEIVE */ -#endif /* NOXFER */ - -#ifndef NOXFER - { "rasg", XXRASG, CM_INV }, /* REMOTE ASSIGN */ - { "rassign", XXRASG, CM_INV }, /* ditto */ - { "rcd", XXRCWD, CM_INV }, /* REMOTE CD */ - { "rcdup", XXRCDUP,CM_INV }, /* REMOTE CD */ - { "rcopy", XXRCPY, CM_INV }, /* REMOTE COPY */ - { "rcwd", XXRCWD, CM_INV }, /* REMOTE CWD */ - { "rdelete", XXRDEL, CM_INV }, /* REMOTE DELETE */ - { "rdirectory", XXRDIR, CM_INV }, /* REMODE DIRECTORY */ -#endif /* NOXFER */ - -#ifndef NOSPL - { "read", XXREA, 0 }, /* READ a line from a file */ -#else - { "read", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOXFER - { "receive", XXREC, 0 }, /* RECEIVE files */ -#endif /* NOXFER */ - -#ifndef NODIAL - { "red", XXRED, CM_INV|CM_ABR|CM_LOC }, /* Inv syn for REDIAL */ - { "redi", XXRED, CM_INV|CM_ABR|CM_LOC }, /* ditto */ - { "redial", XXRED, CM_LOC }, /* REDIAL last DIAL number */ -#else - { "red", XXNOTAV, CM_INV|CM_LOC }, - { "redi", XXNOTAV, CM_INV|CM_LOC }, - { "redial", XXNOTAV, CM_INV|CM_LOC }, -#endif /* NODIAL */ - -#ifdef CK_REDIR -#ifdef OS2 -#ifndef NOPUSH - { "redirect", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */ -#else - { "redirect", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOPUSH */ -#else /* OS2 */ -#ifndef NOPUSH - { "redirect", XXFUN, CM_PSH }, /* REDIRECT */ -#else - { "redirect", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOPUSH */ -#endif /* OS2 */ -#endif /* CK_REDIR */ - -#ifdef CK_RECALL - { "redo", XXREDO, CM_NOR }, /* REDO */ -#else - { "redo", XXNOTAV, CM_INV }, -#endif /* CK_RECALL */ - -#ifndef NOXFER -#ifdef CK_RESEND - { "reget", XXREGET, 0 }, /* REGET */ -#else - { "reget", XXNOTAV, CM_INV }, -#endif /* CK_RESEND */ -#endif /* NOXFER */ - -#ifndef NOSPL - { "reinput", XXREI, CM_INV }, /* REINPUT (from INPUT buffer) */ -#else - { "reinput", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOXFER -#ifdef ADDCMD - { "rem", XXREM, CM_INV|CM_ABR }, - { "remo", XXREM, CM_INV|CM_ABR }, -#endif /* ADDCMD */ - { "remote", XXREM, 0 }, /* Send REMOTE command to server */ -#endif /* NOXFER */ - -#ifdef ADDCMD - { "remove", XXREMV,0 }, /* REMOVE (something from a list) */ -#else - { "remove", XXNOTAV, CM_INV }, -#endif /* ADDCMD */ - -#ifndef NOFRILLS -#ifndef NORENAME - { "rename", XXREN, 0 }, /* RENAME a local file */ -#else - { "rename", XXNOTAV, CM_INV }, -#endif /* NORENAME */ - { "replay", XXTYP, CM_INV }, /* REPLAY (for now, just type) */ -#endif /* NOFRILLS */ - -#ifndef NOXFER -#ifdef CK_RESEND - { "res", XXRSEN, CM_INV|CM_ABR }, /* RESEND */ - { "rese", XXRSEN, CM_INV|CM_ABR }, /* RESEND */ - { "resend", XXRSEN, 0 }, /* RESEND */ -#else - { "res", XXNOTAV, CM_INV }, - { "rese", XXNOTAV, CM_INV }, - { "resend", XXNOTAV, CM_INV }, -#endif /* CK_RESEND */ -#endif /* NOXFER */ - - { "reset", XXRESET, CM_INV }, /* RESET */ - -#ifdef CK_RESEND -#ifndef NOSPL - { "ret", XXRET, CM_INV|CM_ABR }, -#endif /* NOSPL */ -#endif /* CK_RESEND */ - -#ifndef NOXFER - { "retrieve", XXRETR, CM_INV }, /* RETRIEVE */ -#endif /* NOXFER */ - -#ifndef NOSPL - { "return", XXRET, 0 }, /* RETURN from a function */ -#else - { "return", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOXFER - { "rexit", XXRXIT, CM_INV }, /* REMOTE EXIT */ -#endif /* NOXFER */ - -#ifdef CK_REXX -#ifndef NOPUSH - { "rexx", XXREXX, CM_PSH }, /* Execute a Rexx command */ -#else - { "rexx", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOPUSH */ -#endif /* CK_REXX */ - -#ifndef NOXFER - { "rhelp", XXRHLP, CM_INV }, /* REMOTE HELP */ - { "rhost", XXRHOS, CM_INV }, /* REMOTE HOST */ - { "rkermit", XXRKER, CM_INV }, /* REMOTE KERMIT */ -#endif /* NOXFER */ - -#ifdef TCPSOCKET - { "rlogin", XXRLOG, CM_LOC }, /* Make an Rlogin connection */ -#else - { "rlogin", XXNOTAV, CM_INV|CM_LOC }, -#endif /* TCPSOCKET */ - -#ifndef NOFRILLS - { "rm", XXDEL, CM_INV }, /* Invisible synonym for delete */ -#endif /* NOFRILLS */ - -#ifdef CK_MKDIR - { "rmdir", XXRMDIR, 0 }, /* RMDIR */ -#else - { "rmdir", XXNOTAV, CM_INV }, -#endif /* CK_MKDIR */ - -#ifndef NOXFER - { "rmkdir", XXRMKD, CM_INV }, /* REMOTE MKDIR */ -#ifndef NOSPL - { "robust", XXROB, CM_INV }, -#else - { "robust", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - { "rprint", XXRPRI, CM_INV }, /* REMOTE PRINT */ - { "rpwd", XXRPWD, CM_INV }, /* REMOTE PWD */ - { "rquery", XXRQUE, CM_INV }, /* REMOTE QUERY */ -#endif /* NOXFER */ - -#ifdef CK_RECALL - { "rr", XXREDO, CM_INV|CM_NOR }, -#endif /* CK_RECALL */ - -#ifndef NOXFER - { "rrename", XXRREN, CM_INV }, /* REMOTE RENAME */ - { "rrmdir", XXRRMD, CM_INV }, /* REMOTE REMDIR */ - { "rset", XXRSET, CM_INV }, /* REMOTE SET */ - { "rspace", XXRSPA, CM_INV }, /* REMOTE SPACE */ - { "rtype", XXRTYP, CM_INV }, /* REMOTE TYPE */ -#endif /* NOXFER */ - -#ifndef NOPUSH - { "run", XXSHE, CM_PSH }, /* RUN a program or command */ -#else - { "run", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOPUSH */ - -#ifndef NOXFER - { "rwho", XXRWHO, CM_INV }, /* REMOTE WHO */ - { "s", XXSEN, CM_INV|CM_ABR }, /* Invisible synonym for send */ -#endif /* NOXFER */ - -#ifndef NOSETKEY -#ifdef OS2 - { "save", XXSAVE, 0 }, /* SAVE something */ -#else - { "save", XXSAVE, CM_INV }, -#endif /* OS2 */ -#else - { "save", XXNOTAV, CM_INV }, -#endif /* NOSETKEY */ - -#ifndef NOSCRIPT - { "sc", XXLOGI, CM_INV|CM_ABR|CM_LOC }, - { "scr", XXLOGI, CM_INV|CM_ABR|CM_LOC }, -#endif /* NOSCRIPT */ - { "screen", XXSCRN, 0 }, /* SCREEN actions */ -#ifndef NOSCRIPT - { "script", XXLOGI, CM_LOC }, /* Expect-Send-style script line */ -#else - { "script", XXNOTAV, CM_INV|CM_LOC }, -#endif /* NOSCRIPT */ - - { "search", XXGREP,CM_INV }, /* Synonym for GREP and FIND */ - -#ifndef NOXFER - { "send", XXSEN, 0 }, /* Send (a) file(s) */ -#ifndef NOSERVER - { "server", XXSER, 0 }, /* Be a SERVER */ -#else - { "server", XXNOTAV, CM_INV }, -#endif /* NOSERVER */ -#endif /* NOXFER */ - - { "set", XXSET, 0 }, /* SET parameters */ - -#ifndef NOSPL -#ifndef NOSEXP - { "sexpression", XXSEXP, CM_INV|CM_HLP }, /* SEXPR */ -#endif /* NOSEXP */ - -#ifdef SFTP_BUILTIN - { "sftp", XXSFTP, 0 }, /* SFTP */ -#endif /* SFTP_BUILTIN */ - -#ifndef NOSHOW - { "sh", XXSHO, CM_INV|CM_ABR }, /* SHOW parameters */ -#endif /* NOSHOW */ - { "shift", XXSHIFT, 0 }, /* SHIFT args */ -#else - { "shift", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOSHOW - { "show", XXSHO, 0 }, /* SHOW parameters */ -#else - { "show", XXNOTAV, CM_INV }, -#endif /* NOSHOW */ - -#ifdef NEWFTP - { "site", XXSITE, CM_INV }, /* (FTP) SITE */ -#endif /* NEWFTP */ - -#ifdef SSHBUILTIN - { "skermit", XXSKRM, 0 }, /* SKERMIT */ -#endif /* SSHBUILTIN */ - -#ifndef NOSPL -#ifndef NOFRILLS - { "sleep", XXPAU, CM_INV }, /* SLEEP for specified interval */ -#endif /* NOFRILLS */ -#endif /* NOSPL */ - -#ifndef NOSPL - { "sort", XXSORT, CM_INV }, /* (see ARRAY) */ -#else - { "sort", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef MAC -#ifndef NOFRILLS - { "sp", XXSPA, CM_INV|CM_ABR }, - { "spa", XXSPA, CM_INV|CM_ABR }, -#endif /* NOFRILLS */ - { "space", XXSPA, 0 }, /* Show available disk SPACE */ -#endif /* MAC */ - -#ifndef NOFRILLS -#ifndef NOPUSH - { "spawn", XXSHE, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */ -#else - { "spawn", XXNOTAV, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */ -#endif /* NOPUSH */ -#endif /* NOFRILLS */ - -#ifdef ANYSSH - { "ssh", XXSSH, 0 }, -#endif /* ANYSSH */ - -#ifndef NOXFER - { "sta", XXSTA, CM_INV|CM_ABR }, - { "stat", XXSTA, CM_INV|CM_ABR }, - { "statistics", XXSTA, 0 }, /* Display file transfer stats */ -#endif /* NOXFER */ - - { "status", XXSTATUS,0 }, /* Show status of previous command */ - -#ifndef NOSPL - { "stop", XXSTO, 0 }, /* STOP all take files and macros */ - { "succeed", XXSUCC, CM_INV }, /* SUCCEED */ -#else - { "stop", XXNOTAV, CM_INV }, - { "succeed", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOFRILLS - { "SUPPORT", XXBUG, 0 }, /* Tech support instructions */ -#else - { "support", XXNOTAV, CM_INV }, -#endif /* NOFRILLS */ - -#ifndef NOJC - { "suspend", XXSUS, CM_PSH }, /* SUSPEND C-Kermit (UNIX only) */ -#else - { "suspend", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOJC */ - -#ifndef NOSPL - { "switch", XXSWIT, 0 }, /* SWITCH */ -#else - { "switch", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifdef CK_TAPI - { "ta", XXTAK, CM_INV|CM_ABR }, /* (because of TAPI) */ -#endif /* CK_TAPI */ - -#ifndef NOFRILLS - { "tail", XXTAIL, 0 }, /* Display end of a local file */ -#endif /* NOFRILLS */ - - { "take", XXTAK, 0 }, /* TAKE commands from a file */ - -#ifdef CK_TAPI - { "tapi", XXTAPI, CM_LOC }, /* Microsoft TAPI commands */ -#else - { "tapi", XXNOTAV, CM_INV|CM_LOC }, -#endif /* CK_TAPI */ - -#ifndef NOFRILLS -#ifdef TCPSOCKET - { "tel", XXTEL, CM_INV|CM_ABR|CM_LOC }, - { "telnet", XXTEL, CM_LOC }, /* TELNET (TCP/IP only) */ - { "telopt", XXTELOP, CM_INV }, /* TELOPT (ditto) */ -#else - { "tel", XXNOTAV, CM_INV|CM_LOC }, - { "telnet", XXNOTAV, CM_INV|CM_LOC }, - { "telopt", XXNOTAV, CM_INV }, -#endif /* TCPSOCKET */ -#ifdef OS2 - { "terminal", XXTERM, CM_INV|CM_LOC }, /* == SET TERMINAL TYPE */ -#else - { "terminal", XXTERM, CM_INV }, -#endif /* OS2 */ -#endif /* NOFRILLS */ -#ifndef NOXFER - { "text", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */ -#endif /* NOXFER */ - -#ifndef NOSPL - { "trace", XXTRACE, 0 }, /* TRACE */ -#else - { "trace", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOCSETS - { "translate", XXXLA, 0 }, /* TRANSLATE local file char sets */ -#else - { "translate", XXNOTAV, CM_INV }, -#endif /* NOCSETS */ - -#ifndef NOXMIT - { "transmit", XXTRA, 0 }, /* Send (upload) a file, no protocol */ -#else - { "transmit", XXNOTAV, CM_INV }, -#endif /* NOXMIT */ - -#ifndef NOFRILLS - { "type", XXTYP, 0 }, /* Display a local file */ -#endif /* NOFRILLS */ - -#ifndef NOSPL - { "undcl", XXUNDCL, CM_INV }, - { "undeclare", XXUNDCL, 0 }, /* UNDECLARE an array */ - { "undefine", XXUNDEF, 0 }, /* UNDEFINE a variable or macro */ -#else - { "undcl", XXNOTAV, CM_INV }, - { "undeclare", XXNOTAV, CM_INV }, - { "undefine", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifdef NEWFTP - { "user", XXUSER, CM_INV }, /* (FTP) USER */ -#endif /* NEWFTP */ - - { "version", XXVER, 0 }, /* VERSION-number display */ - -#ifdef OS2 - { "viewonly", XXVIEW, CM_LOC }, /* VIEWONLY Terminal Mode */ -#endif /* OS2 */ - - { "void", XXVOID, 0 }, /* VOID */ - -#ifndef NOSPL - { "wait", XXWAI, 0 }, /* WAIT */ -#else - { "wait", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - - { "wermit", XXKERMI, CM_INV }, - -#ifndef NOXFER - { "where", XXWHERE, 0 }, /* WHERE (did my file go?) */ -#endif /* NOXFER */ - -#ifndef NOSPL - { "while", XXWHI, 0 }, /* WHILE loop */ -#else - { "while", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef OS2 -#ifndef MAC -#ifndef NOFRILLS - { "who", XXWHO, CM_PSH }, /* WHO's logged in? */ -#endif /* NOFRILLS */ -#endif /* MAC */ -#endif /* OS2 */ - -#ifndef NOHELP - { "wildcards", XXWILD,CM_INV|CM_HLP }, /* Wildcard syntax */ -#endif /* NOHELP */ - -#ifndef NOSPL - { "wr", XXWRI, CM_INV|CM_ABR }, - { "wri", XXWRI, CM_INV|CM_ABR }, - { "writ", XXWRI, CM_INV|CM_ABR }, - { "write", XXWRI, 0 }, /* WRITE characters to a file */ - { "write-line", XXWRL, CM_INV }, /* WRITE a line to a file */ - { "writeln", XXWRL, CM_INV }, /* Pascalisch synonym for write-line */ -#else - { "wr", XXNOTAV, CM_INV }, - { "wri", XXNOTAV, CM_INV }, - { "writ", XXNOTAV, CM_INV }, - { "write", XXNOTAV, CM_INV }, - { "write-line", XXNOTAV, CM_INV }, - { "writeln", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOFRILLS - { "xecho", XXXECH,0 }, /* XECHO */ -#endif /* NOFRILLS */ - -#ifndef NOSPL - { "xif", XXIFX, CM_INV }, /* Extended IF command (obsolete) */ -#else - { "xif", XXNOTAV, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOCSETS - { "xlate", XXXLA, CM_INV }, /* Synonym for TRANSLATE */ -#else - { "xlate", XXNOTAV, CM_INV }, -#endif /* NOCSETS */ - -#ifndef NOXMIT - { "xmit", XXTRA, CM_INV }, /* Synonym for TRANSMIT */ -#else - { "xmit", XXNOTAV, CM_INV }, -#endif /* NOXMIT */ - -#ifndef OS2 -#ifndef NOJC - { "z", XXSUS, CM_INV|CM_PSH }, /* Synonym for SUSPEND */ -#else - { "z", XXNOTAV, CM_INV|CM_PSH }, -#endif /* NOJC */ -#endif /* OS2 */ - -#ifndef NOSPL - { "{", XXMACRO, CM_INV }, /* Immediate macro */ -#endif /* NOSPL */ - { "", 0, 0 } -}; -int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1; - -/* NOTE: Tokens must also be entered above into cmdtab[]. */ - -char toktab[] = { -#ifndef NOPUSH - '!', /* Shell escape */ -#endif /* NOPUSH */ - '#', /* Comment */ -#ifndef NOSPL - '(', /* S-Expression */ - '.', /* Assignment */ -#endif /* NOSPL */ - ';', /* Comment */ -#ifndef NOSPL - ':', /* Label */ -#endif /* NOSPL */ -#ifndef NOPUSH -#ifdef CK_REDIR - '<', /* REDIRECT */ -#endif /* CK_REDIR */ - '@', /* DCL escape */ -#endif /* NOPUSH */ -#ifdef CK_RECALL - '^', /* Command recall */ -#endif /* CK_RECALL */ -#ifndef NOSPL - '{', /* Immediate macro */ -#endif /* NOSPL */ - '\0' /* End of this string */ -}; -int xxdot = 0; /* Used with "." token */ - -struct keytab yesno[] = { /* Yes/No keyword table */ - { "no", 0, 0 }, - { "ok", 1, 0 }, - { "yes", 1, 0 } -}; -int nyesno = (sizeof(yesno) / sizeof(struct keytab)); - -/* Save keyword table */ - -struct keytab savtab[] = { -#ifdef OS2 - { "command", XSCMD, 0 }, -#else -#ifdef CK_RECALL - { "command", XSCMD, 0 }, -#endif /* CK_RECALL */ -#endif /* OS2 */ -#ifndef NOSETKEY - { "keymap", XSKEY, 0 }, -#endif /* NOSETKEY */ -#ifdef OS2 - { "terminal", XSTERM, 0 }, -#endif /* OS2 */ - { "", 0, 0 } -}; -int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1; - -/* Parameter keyword table */ - -struct keytab prmtab[] = { - { "alarm", XYALRM, 0 }, -#ifdef COMMENT /* SET ANSWER not implemented yet */ -#ifndef NODIAL - { "answer", XYANSWER,0 }, -#endif /* NODIAL */ -#endif /* COMMENT */ - { "ask-timer", XYTIMER, 0 }, -#ifndef NOXFER - { "attributes", XYATTR, 0 }, -#endif /* NOXFER */ -#ifdef CK_AUTHENTICATION - { "authentication", XYAUTH, 0 }, -#else /* CK_AUTHENTICATION */ -#ifdef CK_SSL - { "authentication", XYAUTH, 0 }, -#endif /* CK_SSL */ -#endif /* CK_AUTHENTICATION */ - { "b", XYBACK, CM_INV|CM_ABR|CM_PSH }, - { "ba", XYBACK, CM_INV|CM_ABR|CM_PSH }, -#ifdef VMS - { "background", XYBACK, CM_INV|CM_PSH }, - { "batch", XYBACK, CM_PSH }, -#else - { "background", XYBACK, CM_PSH }, - { "batch", XYBACK, CM_INV|CM_PSH }, -#endif /* VMS */ -#ifndef NOLOCAL - { "baud", XYSPEE, CM_INV|CM_LOC }, -#endif /* NOLOCAL */ - { "bell", XYBELL, 0 }, -#ifndef NOXFER - { "block-check", XYCHKT, 0 }, -#endif /* NOXFER */ -#ifdef OS2 -#ifdef BPRINT - { "bprinter", XYBDCP, CM_INV }, -#endif /* BPRINT */ -#endif /* OS2 */ -#ifdef BROWSER - { "browser", XYBROWSE,CM_PSH|CM_LOC }, -#endif /* BROWSER */ -#ifndef NOXFER -#ifdef DYNAMIC - { "buffers", XYBUF, 0 }, -#endif /* DYNAMIC */ -#endif /* NOXFER */ -#ifndef NOLOCAL -#ifndef MAC - { "carrier-watch", XYCARR, CM_LOC }, -#endif /* MAC */ -#endif /* NOLOCAL */ -#ifndef NOSPL - { "case", XYCASE, 0 }, -#endif /* NOSPL */ - { "cd", XYCD, 0 }, -#ifndef NOXFER - { "cl", XYCLEAR, CM_INV|CM_ABR }, - { "cle", XYCLEAR, CM_INV|CM_ABR }, - { "clea", XYCLEAR, CM_INV|CM_ABR }, - { "clear", XYCLEAR, CM_INV|CM_ABR }, - { "clear-channel", XYCLEAR, 0 }, - { "clearchannel", XYCLEAR, CM_INV }, -#endif /* NOXFER */ -#ifndef NOLOCAL - { "close-on-disconnect", XYDISC, CM_INV|CM_LOC }, -#endif /* NOLOCAL */ - { "cmd", XYCMD, CM_INV }, - { "command", XYCMD, 0 }, -#ifdef CK_SPEED - { "con", XYQCTL, CM_INV|CM_ABR }, -#endif /* CK_SPEED */ - { "console", XYCMD, CM_INV }, -#ifdef CK_SPEED - { "control-character",XYQCTL, 0 }, -#endif /* CK_SPEED */ -#ifndef NOSPL - { "count", XYCOUN, 0 }, -#endif /* NOSPL */ -#ifndef NOXFER - { "d", XYDELA, CM_INV|CM_ABR }, - { "de", XYDELA, CM_INV|CM_ABR }, -#endif /* NOXFER */ - { "debug", XYDEBU, 0 }, -#ifdef VMS - { "default", XYDFLT, 0 }, -#else -#ifndef MAC - { "default", XYDFLT, CM_INV }, -#endif /* MAC */ -#endif /* VMS */ -#ifndef NOXFER - { "delay", XYDELA, 0 }, - { "destination", XYDEST, 0 }, -#endif /* NOXFER */ -#ifndef NODIAL - { "di", XYDIAL, CM_INV|CM_ABR|CM_LOC }, - { "dia", XYDIAL, CM_INV|CM_ABR|CM_LOC }, - { "dial", XYDIAL, CM_LOC }, -#endif /* NODIAL */ -#ifdef OS2 - { "dialer", XYDLR, CM_INV }, -#endif /* OS2 */ -#ifndef NOLOCAL - { "disconnect", XYDISC, CM_LOC }, - { "duplex", XYDUPL, CM_LOC }, -#endif /* NOLOCAL */ -#ifndef NOPUSH -#ifndef NOFRILLS - { "editor", XYEDIT, CM_PSH }, -#endif /* NOFRILLS */ -#endif /* NOPUSH */ -#ifdef CK_CTRLZ - { "eof", XYEOF, CM_INV }, -#endif /* CK_CTRLZ */ -#ifndef NOLOCAL - { "escape-character", XYESC, CM_LOC }, -#endif /* NOLOCAL */ -#ifndef NOSPL - { "evaluate", XYEVAL, CM_INV }, -#endif /* NOSPL */ - { "exit", XYEXIT, 0 }, -#ifndef NOXFER - { "f-ack-bug", XYFACKB, CM_INV }, - { "f-ack-path", XYFACKP, CM_INV }, -#endif /* NOXFER */ - { "file", XYFILE, 0 }, - { "fl", XYFLOW, CM_INV|CM_ABR }, -#ifndef NOSPL - { "flag", XYFLAG, 0 }, -#endif /* NOSPL */ -#ifdef TCPSOCKET -#ifndef SYSFTP -#ifndef NOFTP - { "ft", XYFTPX, CM_INV|CM_ABR }, - { "ftp", XYFTPX, 0 }, -#endif /* NOFTP */ -#endif /* SYSFTP */ -#endif /* TCPSOCKET */ -#ifdef BROWSER - { "ftp-client", XYFTP, CM_PSH }, -#endif /* BROWSER */ - { "flow-control", XYFLOW, 0 }, -#ifndef NOSPL - { "function", XYFUNC, 0 }, -#endif /* NOSPL */ -#ifdef NEWFTP - { "get-put-remote", XYGPR, 0 }, -#endif /* NEWFTP */ -#ifdef KUI - { "gui", XYGUI, 0 }, -#endif /* KUI */ - { "handshake", XYHAND, 0 }, - { "hints", XYHINTS, 0 }, -#ifdef NETCONN - { "host", XYHOST, CM_LOC }, -#endif /* NETCONN */ -#ifndef NOSPL - { "i", XYINPU, CM_INV|CM_ABR }, -#endif /* NOSPL */ -#ifdef IKSD - { "iks", XYIKS, 0 }, -#else - { "iks", XYIKS, CM_INV }, -#endif /* IKSD */ -#ifndef NOSPL - { "in", XYINPU, CM_INV|CM_ABR }, -#endif /* NOSPL */ -#ifndef NOXFER - { "incomplete", XYIFD, CM_INV }, -#endif /* NOXFER */ -#ifndef NOSPL - { "input", XYINPU, 0 }, -#endif /* NOSPL */ -#ifndef NOSETKEY - { "key", XYKEY, 0 }, -#endif /* NOSETKEY */ - { "l", XYLINE, CM_INV|CM_ABR }, -#ifndef NOCSETS - { "language", XYLANG, 0 }, -#endif /* NOCSETS */ -#ifndef NOLOCAL - { "line", XYLINE, CM_LOC }, - { "local-echo", XYLCLE, CM_INV|CM_LOC }, -#endif /* NOLOCAL */ -#ifdef LOCUS - { "locus", XYLOCUS, 0 }, -#endif /* LOCUS */ -#ifndef NOSPL - { "login", XYLOGIN, CM_LOC }, -#endif /* NOSPL */ -#ifndef NOSPL - { "macro", XYMACR, 0 }, -#endif /* NOSPL */ - { "match", XYMATCH, 0 }, -#ifdef COMMENT -#ifdef VMS - { "messages", XYMSGS, 0 }, -#endif /* VMS */ -#endif /* COMMENT */ -#ifndef NODIAL - { "modem", XYMODM, CM_LOC }, -#endif /* NODIAL */ -#ifndef NOLOCAL -#ifdef OS2MOUSE - { "mouse", XYMOUSE, 0 }, -#endif /* OS2MOUSE */ -#endif /* NOLOCAL */ -#ifdef OS2 - { "mskermit", XYMSK, 0 }, -#endif /* OS2 */ -#ifdef NETCONN - { "network", XYNET, CM_LOC }, -#endif /* NETCONN */ -#ifndef NOSPL - { "output", XYOUTP, 0 }, -#endif /* NOSPL */ - { "options", XYOPTS, 0 }, - { "pause", XYSLEEP, CM_INV }, -#ifdef ANYX25 -#ifndef IBMX25 - { "pad", XYPAD, CM_LOC }, -#endif /* IBMX25 */ -#endif /* ANYX25 */ - { "parity", XYPARI, 0 }, -#ifndef NOLOCAL -#ifdef OS2 - { "port", XYLINE, CM_LOC }, -#else - { "port", XYLINE, CM_INV|CM_LOC }, -#endif /* OS2 */ -#endif /* NOLOCAL */ -#ifndef NOFRILLS - { "pr", XYPROM, CM_INV|CM_ABR }, - { "printer", XYPRTR, 0 }, -#endif /* NOFRILLS */ -#ifdef OS2 - { "priority", XYPRTY, 0 }, -#endif /* OS2 */ -#ifdef CK_SPEED - { "prefixing", XYPREFIX, 0 }, -#endif /* CK_SPEED */ -#ifndef NOFRILLS - { "prompt", XYPROM, 0 }, -#endif /* NOFRILLS */ -#ifndef NOXFER - { "protocol", XYPROTO, 0 }, -#endif /* NOXFER */ - { "q", XYQUIE, CM_INV|CM_ABR }, -#ifndef NOXFER - { "q8flag", XYQ8FLG, CM_INV }, -#endif /* NOXFER */ -#ifdef QNX - { "qnx-port-lock", XYQNXPL, 0 }, -#else - { "qnx-port-lock", XYQNXPL, CM_INV }, -#endif /* QNX */ - { "quiet", XYQUIE, 0 }, -#ifndef NOXFER - { "rec", XYRECV, CM_INV|CM_ABR }, - { "receive", XYRECV, 0 }, - { "recv", XYRECV, CM_INV }, -#endif /* NOXFER */ - { "reliable", XYRELY, 0 }, -#ifndef NOXFER - { "repeat", XYREPT, 0 }, - { "retry-limit", XYRETR, 0 }, -#endif /* NOXFER */ -#ifdef CKROOT - { "root", XYROOT, 0 }, -#endif /* CKROOT */ -#ifndef NOSCRIPT - { "script", XYSCRI, CM_LOC }, -#endif /* NOSCRIPT */ -#ifndef NOXFER - { "send", XYSEND, 0 }, -#ifndef NOLOCAL -#ifndef NOSERVER - { "ser", XYSERV, CM_INV|CM_ABR }, -#endif /* NOSERVER */ -#endif /* NOXFER */ - { "serial", XYSERIAL,CM_LOC }, -#endif /* NOLOCAL */ -#ifndef NOSERVER - { "server", XYSERV, 0 }, -#endif /* NOSERVER */ -#ifdef SESLIMIT -#ifndef NOLOCAL - { "session-l", XYSESS, CM_INV|CM_ABR }, -#endif /* NOLOCAL */ - { "session-limit", XYLIMIT, CM_INV|CM_LOC }, /* Session Limit */ -#endif /* SESLIMIT */ - -#ifndef NOLOCAL - { "session-log", XYSESS, CM_LOC }, -#endif /* NOLOCAL */ - -#ifndef NOSPL -#ifndef NOSEXP - { "sexpression", XYSEXP, CM_INV }, -#endif /* NOSEXP */ -#endif /* NOSPL */ - - { "sleep", XYSLEEP, 0 }, - -#ifndef NOLOCAL - { "speed", XYSPEE, CM_LOC }, -#endif /* NOLOCAL */ - -#ifdef ANYSSH - { "ssh", XYSSH, 0 }, -#endif /* ANYSSH */ - -#ifndef NOSPL - { "startup-file", XYSTARTUP, CM_INV }, -#endif /* NOSPL */ - -#ifndef NOLOCAL -#ifdef HWPARITY - { "stop-bits", XYSTOP, CM_LOC }, -#else -#ifdef TN_COMPORT - { "stop-bits", XYSTOP, CM_LOC }, -#endif /* TN_COMPORT */ -#endif /* HWPARITY */ -#endif /* NOLOCAL */ - -#ifndef NOXFER -#ifdef STREAMING - { "streaming", XYSTREAM, 0 }, -#endif /* STREAMING */ -#endif /* NOXFER */ - -#ifndef NOJC - { "suspend", XYSUSP, CM_PSH }, -#endif /* NOJC */ -#ifdef CKSYSLOG - { "syslog", XYSYSL, CM_INV }, -#endif /* CKSYSLOG */ - { "take", XYTAKE, 0 }, - -#ifdef CK_TAPI - { "tapi", XYTAPI, CM_LOC }, -#endif /* CK_TAPI */ - -#ifndef NOTCPOPTS -#ifdef TCPSOCKET - { "tcp", XYTCP, CM_LOC }, -#endif /* TCPSOCKET */ -#endif /* NOTCPOPTS */ - -#ifdef TNCODE - { "tel", XYTEL, CM_INV|CM_ABR }, - { "telnet", XYTEL, 0 }, - { "telopt", XYTELOP, 0 }, -#endif /* TNCODE */ - -#ifndef NOSPL - { "temp-directory", XYTMPDIR,0 }, -#endif /* NOSPL */ - -#ifndef NOLOCAL - { "terminal", XYTERM, CM_LOC }, -#endif /* NOLOCAL */ - -#ifdef OS2 - { "title", XYTITLE, CM_LOC }, -#endif /* OS2 */ -#ifdef TLOG - { "transaction-log", XYTLOG, 0 }, -#endif /* TLOG */ -#ifndef NOXFER - { "transfer", XYXFER, 0 }, -#endif /* NOXFER */ -#ifndef NOXMIT - { "transmit", XYXMIT, 0 }, -#endif /* NOXMIT */ -#ifndef NOXFER -#ifndef NOCSETS - { "unknown-char-set", XYUNCS, 0 }, -#endif /* NOCSETS */ -#endif /* NOXFER */ - { "wait", XYSLEEP, CM_INV }, -#ifndef NOPUSH -#ifdef UNIX - { "wildcard-expansion", XYWILD, 0 }, -#endif /* UNIX */ -#endif /* NOPUSH */ -#ifdef NT - { "w", XYWIND, CM_INV|CM_ABR }, - { "wi", XYWIND, CM_INV|CM_ABR }, - { "win", XYWIND, CM_INV|CM_ABR }, -#endif /* NT */ - { "window-size", XYWIND, 0 }, -#ifdef NT - { "win95", XYWIN95, 0 }, -#endif /* NT */ -#ifdef ANYX25 - { "x.25", XYX25, CM_LOC }, - { "x25", XYX25, CM_INV|CM_LOC }, -#endif /* ANYX25 */ - { "xfer", XYXFER, CM_INV }, -#ifndef NOXMIT - { "xmit", XYXMIT, CM_INV }, -#endif /* NOXMIT */ - { "", 0, 0 } -}; -int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */ - -struct keytab scntab[] = { /* Screen commands */ - { "clear", SCN_CLR, 0 }, - { "cleol", SCN_CLE, 0 }, - { "move-to", SCN_MOV, 0 } -}; -int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */ - -#ifdef ANYSSH /* SSH command table */ -#ifdef SSHBUILTIN -int ssh_pf_lcl_n = 0, - ssh_pf_rmt_n = 0; -struct ssh_pf ssh_pf_lcl[32] = { 0, NULL, 0 }; /* SSH Port Forwarding */ -struct ssh_pf ssh_pf_rmt[32] = { 0, NULL, 0 }; /* structs... */ -extern char * ssh_hst, * ssh_cmd, * ssh_prt; -extern int ssh_ver, ssh_xfw; -char * ssh_tmpuid = NULL, *ssh_tmpcmd = NULL, *ssh_tmpport = NULL, - * ssh_tmpstr = NULL; - -int - sshk_type = SSHKT_2D, /* SSH KEY CREATE /TYPE:x */ - sshk_bits = 1024, /* SSH KEY CREATE /BITS:n */ - sshk_din = SKDF_OSSH, /* SSH KEY DISPLAY /IN-FORMAT: */ - sshk_dout = SKDF_OSSH; /* SSH KEY DISPLAY /OUT-FORMAT: */ - -char - * sshk1_comment = NULL, /* SSH V1 COMMENT */ - * sshkp_old = NULL, /* Old key passphrase */ - * sshkp_new = NULL, /* New key passphrase */ - * sshkc_pass = NULL, /* KEY CREATE /PASS:xxx */ - * sshkc_comm = NULL, /* KEY CREATE /V1-RSA-COMMENT:xxx */ - * sshd_file = NULL, /* DISPLAY file */ - * sshk_file = NULL; /* SSH CREATE KEY file */ - -static struct keytab sshclr[] = { - { "local-port-forward", SSHC_LPF, 0 }, - { "remote-port-forward", SSHC_RPF, 0 }, - { "", 0, 0 } -}; -static int nsshclr = (sizeof(sshclr) / sizeof(struct keytab)) - 1; - -struct keytab sshopnsw[] = { - { "/command", SSHSW_CMD, CM_ARG }, - { "/password", SSHSW_PWD, CM_ARG }, - { "/subsystem", SSHSW_SUB, CM_ARG }, - { "/user", SSHSW_USR, CM_ARG }, - { "/version", SSHSW_VER, CM_ARG }, - { "/x11-forwarding", SSHSW_X11, CM_ARG }, - { "", 0, 0 } -}; -int nsshopnsw = (sizeof(sshopnsw) / sizeof(struct keytab)) - 1; - -static struct keytab sshkwtab[] = { - { "add", XSSH_ADD, 0 }, - { "agent", XSSH_AGT, 0 }, - { "clear", XSSH_CLR, 0 }, - { "forward-local-port", XSSH_FLP, CM_INV }, - { "forward-remote-port", XSSH_FRP, CM_INV }, - { "key", XSSH_KEY, 0 }, - { "open", XSSH_OPN, 0 }, - { "v2", XSSH_V2, 0 }, - { "", 0, 0 } -}; -static int nsshcmd = (sizeof(sshkwtab) / sizeof(struct keytab)) - 1; - -static struct keytab ssh2tab[] = { - { "rekey", XSSH2_RKE, 0 }, - { "", 0, 0 } -}; -static int nssh2tab = (sizeof(ssh2tab) / sizeof(struct keytab)); - -static struct keytab addfwd[] = { /* SET SSH ADD command table */ - { "local-port-forward", SSHF_LCL, 0 }, - { "remote-port-forward", SSHF_RMT, 0 }, - { "", 0, 0 } -}; -static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1; - -static struct keytab sshagent[] = { /* SET SSH AGENT command table */ - { "add", SSHA_ADD, 0 }, - { "delete", SSHA_DEL, 0 }, - { "list", SSHA_LST, 0 }, - { "", 0, 0 } -}; -static int nsshagent = (sizeof(sshagent) / sizeof(struct keytab)) - 1; - -static struct keytab sshagtsw[] = { /* SET SSH AGENT LIST switch table */ - { "/fingerprint", SSHASW_FP, 0 }, - { "", 0, 0 } -}; -static int nsshagtsw = (sizeof(sshagtsw) / sizeof(struct keytab)) - 1; - -static struct keytab sshkey[] = { /* SET SSH KEY command table */ - { "change-passphrase", SSHK_PASS, 0 }, - { "create", SSHK_CREA, 0 }, - { "display", SSHK_DISP, 0 }, - { "v1", SSHK_V1, 0 }, - { "", 0, 0 } -}; -static int nsshkey = (sizeof(sshkey) / sizeof(struct keytab)) - 1; - -static struct keytab sshkv1[] = { /* SET SSH KEY V1 command table */ - { "set-comment", 1, 0 } -}; - -static struct keytab sshkpsw[] = { /* SET SSH KEY PASSPHRASE table */ - { "/new-passphrase", 2, CM_ARG }, - { "/old-passphrase", 1, CM_ARG } -}; - -static struct keytab sshkcrea[] = { /* SSH KEY CREATE table */ - { "/bits", SSHKC_BI, CM_ARG }, - { "/passphrase", SSHKC_PP, CM_ARG }, - { "/type", SSHKC_TY, CM_ARG }, - { "/v1-rsa-comment", SSHKC_1R, CM_ARG } -}; -static int nsshkcrea = (sizeof(sshkcrea) / sizeof(struct keytab)); - -static struct keytab sshkcty[] = { /* SSH KEY CREATE /TYPE:xxx */ - { "srp", SSHKT_SRP, 0 }, - { "v1-rsa", SSHKT_1R, 0 }, - { "v2-dsa", SSHKT_2D, 0 }, - { "v2-rsa", SSHKT_2R, 0 } -}; -static int nsshkcty = (sizeof(sshkcty) / sizeof(struct keytab)); - -static struct keytab sshdswi[] = { /* SET SSH KEY DISPLAY /switches */ - { "/format", SSHKD_OUT, CM_ARG } -}; -static int nsshdswi = (sizeof(sshdswi) / sizeof(struct keytab)); - -#ifdef COMMENT -static struct keytab sshdifmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */ - { "openssh", SKDF_OSSH, 0 }, - { "ssh.com", SKDF_SSHC, 0 } -}; -static int nsshdifmt = (sizeof(sshdifmt) / sizeof(struct keytab)); -#endif /* COMMENT */ - -static struct keytab sshdofmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */ - { "fingerprint", SKDF_FING, 0 }, - { "ietf", SKDF_IETF, 0 }, - { "openssh", SKDF_OSSH, 0 }, - { "ssh.com", SKDF_SSHC, 0 } -}; -static int nsshdofmt = (sizeof(sshdofmt) / sizeof(struct keytab)); - -static struct keytab sshkermit[] = { /* SKERMIT */ - { "open", SKRM_OPN, 0 } -}; -static int nsshkermit = (sizeof(sshkermit) / sizeof(struct keytab)); - -struct keytab sshkrmopnsw[] = { - { "/password", SSHSW_PWD, CM_ARG }, - { "/user", SSHSW_USR, CM_ARG }, - { "/version", SSHSW_VER, CM_ARG }, - { "", 0, 0 } -}; -int nsshkrmopnsw = (sizeof(sshkrmopnsw) / sizeof(struct keytab)) - 1; -#endif /* SSHBUILTIN */ - -#ifdef SFTP_BUILTIN -static struct keytab sftpkwtab[] = { /* SFTP */ - { "cd", SFTP_CD, 0 }, - { "chgrp", SFTP_CHGRP, 0 }, - { "chmod", SFTP_CHMOD, 0 }, - { "chown", SFTP_CHOWN, 0 }, - { "delete", SFTP_RM, 0 }, - { "dir", SFTP_DIR, 0 }, - { "get", SFTP_GET, 0 }, - { "mkdir", SFTP_MKDIR, 0 }, - { "open", SFTP_OPN, 0 }, - { "put", SFTP_PUT, 0 }, - { "pwd", SFTP_PWD, 0 }, - { "rename", SFTP_REN, 0 }, - { "rm", SFTP_RM, CM_INV }, - { "rmdir", SFTP_RMDIR, 0 }, - { "symlink", SFTP_LINK, 0 }, - { "version", SFTP_VER, 0 } -}; -static int nsftpkwtab = (sizeof(sftpkwtab) / sizeof(struct keytab)); -#endif /* SFTP_BUILTIN */ -#endif /* ANYSSH */ - -#ifdef NETCONN -struct keytab netkey[] = { /* SET NETWORK table */ - { "directory", XYNET_D, 0 }, - { "type", XYNET_T, 0 } -}; -int nnetkey = (sizeof(netkey) / sizeof(struct keytab)); - -struct keytab netcmd[] = { -/* - These are the network types. -*/ -#ifdef NETCMD - { "command", NET_CMD, CM_INV }, /* Command */ -#endif /* NETCMD */ - -#ifdef DECNET /* DECnet / PATHWORKS */ - { "decnet", NET_DEC, 0 }, -#endif /* DECNET */ - -#ifdef NETDLL - { "dll", NET_DLL, CM_INV }, /* DLL to be loaded */ -#endif /* NETDLL */ - -#ifdef NETFILE - { "file", NET_FILE, CM_INV }, /* FILE (real crude) */ -#endif /* NETFILE */ - -#ifdef NPIPE /* Named Pipes */ - { "named-pipe", NET_PIPE, 0 }, -#endif /* NPIPE */ - -#ifdef CK_NETBIOS - { "netbios", NET_BIOS, 0 }, /* NETBIOS */ -#endif /* CK_NETBIOS */ - -#ifdef DECNET /* DECnet / PATHWORKS (alias) */ - { "pathworks", NET_DEC, CM_INV }, -#endif /* DECNET */ - -#ifdef NETCMD - { "pipe", NET_CMD, 0 }, /* Pipe */ -#endif /* NETCMD */ - -#ifdef NETPTY - { "pseudoterminal",NET_PTY, 0 }, /* Pseudoterminal */ -#endif /* NETPTY */ - -#ifdef NETPTY - { "pty", NET_PTY, CM_INV }, /* Inv syn for pseudoterm */ -#endif /* NETPTY */ - -#ifdef SSHBUILTIN - { "ssh", NET_SSH, 0 }, -#endif /* SSHBUILTIN */ - -#ifdef SUPERLAT - { "superlat", NET_SLAT, 0 }, /* Meridian Technologies' SuperLAT */ -#endif /* SUPERLAT */ - -#ifdef TCPSOCKET /* TCP/IP sockets library */ - { "tcp/ip", NET_TCPB, 0 }, -#endif /* TCPSOCKET */ -#ifdef SUPERLAT - { "tes32", NET_SLAT, 0 }, /* Emulux TES32 */ -#endif /* SUPERLAT */ -#ifdef ANYX25 /* X.25 */ -#ifdef SUNX25 - { "x", NET_SX25, CM_INV|CM_ABR }, - { "x.25", NET_SX25, 0 }, - { "x25", NET_SX25, CM_INV }, -#else -#ifdef STRATUSX25 - { "x", NET_VX25, CM_INV|CM_ABR }, - { "x.25", NET_VX25, 0 }, - { "x25", NET_VX25, CM_INV }, -#endif /* STRATUSX25 */ -#endif /* SUNX25 */ -#ifdef IBMX25 - { "x", NET_IX25, CM_INV|CM_ABR }, - { "x.25", NET_IX25, CM_INV }, - { "x25", NET_IX25, CM_INV }, -#endif /* IBMX25 */ -#ifdef HPX25 - { "x", NET_IX25, CM_INV|CM_ABR }, - { "x.25", NET_IX25, 0 }, - { "x25", NET_IX25, CM_INV }, -#endif /* HPX25 */ -#endif /* ANYX25 */ - { "", 0, 0 } -}; -int nnets = (sizeof(netcmd) / sizeof(struct keytab)); - -#ifndef NOTCPOPTS -#ifdef TCPSOCKET - -/* TCP options */ - -struct keytab tcpopt[] = { - { "address", XYTCP_ADDRESS, 0 }, -#ifdef CK_DNS_SRV - { "dns-service-records", XYTCP_DNS_SRV, 0 }, -#endif /* CK_DNS_SRV */ -#ifdef SO_DONTROUTE - { "dontroute", XYTCP_DONTROUTE, 0 }, -#endif /* SO_DONTROUTE */ -#ifndef NOHTTP - { "http-proxy", XYTCP_HTTP_PROXY, 0 }, -#endif /* NOHTTP */ -#ifdef SO_KEEPALIVE - { "keepalive", XYTCP_KEEPALIVE, 0 }, -#endif /* SO_KEEPALIVE */ -#ifdef SO_LINGER - { "linger", XYTCP_LINGER, 0 }, -#endif /* SO_LINGER */ -#ifdef TCP_NODELAY - { "nagle", XYTCP_NAGLE, CM_INV }, - { "nodelay", XYTCP_NODELAY, 0 }, -#endif /* TCP_NODELAY */ - { "reverse-dns-lookup", XYTCP_RDNS, 0 }, -#ifdef SO_RCVBUF - { "recvbuf", XYTCP_RECVBUF, 0 }, -#endif /* SO_RCVBUF */ -#ifdef SO_SNDBUF - { "sendbuf", XYTCP_SENDBUF, 0 }, -#endif /* SO_SNDBUF */ -#ifdef NT -#ifdef CK_SOCKS - { "socks-server", XYTCP_SOCKS_SVR, 0 }, -#endif /* CK_SOCKS */ -#endif /* NT */ -#ifdef VMS -#ifdef DEC_TCPIP - { "ucx-port-bug", XYTCP_UCX, 0 }, -#endif /* DEC_TCPIP */ -#endif /* VMS */ - { "",0,0 } -}; -int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab)); -#endif /* TCPSOCKET */ -#endif /* NOTCPOPTS */ -#endif /* NETCONN */ - -#ifdef OS2 -/* K95 Manual Chapter Table -- Keep these two tables in sync! */ - -static char * linktbl[] = { /* Internal links in k95.htm */ - "#top", /* 00 */ - "#what", /* 01 */ - "#install", /* 02 */ - "#start", /* 03 */ - "#dialer", /* 04 */ - "#entries", /* 05 */ - "#command", /* 06 */ - "#terminal", /* 07 */ - "#transfer", /* 08 */ - "#hostmode" /* 09 */ -}; - -static struct keytab chaptbl[] = { - { "Command-Screen", 6, 0 }, - { "Contents", 0, 0 }, - { "Dialer-Entries", 5, 0 }, - { "File-Transfer", 8, 0 }, - { "Getting-Started", 3, 0 }, - { "Host-Mode", 9, 0 }, - { "Installation", 2, 0 }, - { "Terminal-Emulation", 7, 0 }, - { "Using-The-Dialer", 4, 0 }, - { "What-Is-K95", 1, 0 }, - { "", 0, 0 } -}; -static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab) - 1); -#endif /* OS2 */ - -#ifndef NOXFER -/* Remote Command Table */ - -struct keytab remcmd[] = { -#ifndef NOSPL - { "as", XZASG, CM_INV|CM_ABR }, - { "asg", XZASG, CM_INV }, - { "assign", XZASG, 0 }, -#endif /* NOSPL */ - { "cd", XZCWD, 0 }, - { "cdup", XZCDU, CM_INV }, - { "copy", XZCPY, 0 }, - { "cwd", XZCWD, CM_INV }, - { "delete", XZDEL, 0 }, - { "directory", XZDIR, 0 }, - { "e", XZXIT, CM_ABR|CM_INV }, - { "erase", XZDEL, CM_INV }, - { "exit", XZXIT, 0 }, - { "help", XZHLP, 0 }, -#ifndef NOPUSH - { "host", XZHOS, 0 }, -#endif /* NOPUSH */ -#ifndef NOFRILLS - { "kermit", XZKER, 0 }, - { "l", XZLGI, CM_ABR|CM_INV }, - { "lo", XZLGI, CM_ABR|CM_INV }, - { "log", XZLGI, CM_ABR|CM_INV }, - { "login", XZLGI, 0 }, - { "logout", XZLGO, 0 }, - { "mkdir", XZMKD, 0 }, - { "print", XZPRI, 0 }, -#endif /* NOFRILLS */ - { "pwd", XZPWD, 0 }, -#ifndef NOSPL - { "query", XZQUE, 0 }, -#endif /* NOSPL */ - { "rename", XZREN, 0 }, - { "rmdir", XZRMD, 0 }, - { "set", XZSET, 0 }, - { "space", XZSPA, 0 }, -#ifndef NOFRILLS - { "type", XZTYP, 0 }, - { "who", XZWHO, 0 }, -#endif /* NOFRILLS */ - { "", 0, 0} -}; -int nrmt = (sizeof(remcmd) / sizeof(struct keytab)) - 1; -#endif /* NOXFER */ - -struct keytab logtab[] = { -#ifdef CKLOGDIAL - { "connections", LOGM, CM_INV }, - { "cx", LOGM, 0 }, -#endif /* CKLOGDIAL */ -#ifdef DEBUG - { "debugging", LOGD, 0 }, -#endif /* DEBUG */ - { "packets", LOGP, 0 }, -#ifndef NOLOCAL - { "session", LOGS, 0 }, -#endif /* NOLOCAL */ -#ifdef TLOG - { "transactions", LOGT, 0 }, -#endif /* TLOG */ - { "", 0, 0 } -}; -int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1; - -struct keytab writab[] = { -#ifndef NOSPL - { "append-file", LOGW, CM_INV }, -#endif /* NOSPL */ - { "debug-log", LOGD, 0 }, - { "error", LOGE, 0 }, -#ifndef NOSPL - { "file", LOGW, 0 }, -#endif /* NOSPL */ - { "packet-log", LOGP, 0 }, - { "screen", LOGX, 0 }, -#ifndef NOLOCAL - { "session-log", LOGS, 0 }, -#endif /* NOLOCAL */ - { "sys$output", LOGX, CM_INV }, - { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */ - { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */ - { "tra", LOGT, CM_ABR|CM_INV }, - { "tran", LOGT, CM_ABR|CM_INV }, - { "trans", LOGT, CM_ABR|CM_INV }, - { "transa", LOGT, CM_ABR|CM_INV }, - { "transac", LOGT, CM_ABR|CM_INV }, - { "transact", LOGT, CM_ABR|CM_INV }, - { "transacti", LOGT, CM_ABR|CM_INV }, - { "transactio", LOGT, CM_ABR|CM_INV }, - { "transaction", LOGT, CM_ABR|CM_INV }, - { "transaction-log", LOGT, 0 }, - { "transactions", LOGT, CM_INV } -}; -int nwri = (sizeof(writab) / sizeof(struct keytab)); - -#ifdef COMMENT /* INPUT switches not used yet... */ -static struct keytab inswtab[] = { -#ifdef COMMENT - { "/assign", IN_ASG, CM_ARG }, -#endif /* COMMENT */ - { "/autodownload", IN_ADL, CM_ARG }, - { "/case", IN_CAS, CM_ARG }, - { "/echo", IN_ECH, CM_ARG }, - { "/interrupts", IN_NOI, CM_ARG }, - { "/silence", IN_SIL, CM_ARG }, -#ifdef COMMENT - { "/pattern", IN_PAT, CM_ARG }, -#endif /* COMMENT */ - { "", 0, 0 } -}; -static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1; -#endif /* COMMENT */ - -static struct keytab clrtab[] = { /* Keywords for CLEAR command */ -#ifndef NOSPL - { "alarm", CLR_ALR, 0 }, -#ifdef CK_APC - { "apc", CLR_APC, 0 }, -#endif /* CK_APC */ -#ifdef PATTERNS - { "binary-patterns", CLR_BIN, 0 }, -#endif /* PATTERNS */ - { "both", CLR_DEV|CLR_INP, CM_INV }, -#endif /* NOSPL */ -#ifdef OS2 - { "command-screen", CLR_CMD, 0 }, -#endif /* OS2 */ -#ifndef NOSPL - { "device", CLR_DEV, CM_INV|CM_ABR }, - { "device-and-input", CLR_DEV|CLR_INP, 0 }, -#endif /* NOSPL */ - { "device-buffer", CLR_DEV, 0 }, -#ifndef NODIAL - { "dial-status", CLR_DIA, 0 }, -#endif /* NODIAL */ -#ifndef NOSPL - { "input-buffer", CLR_INP, 0 }, -#endif /* NOSPL */ - { "keyboard-buffer", CLR_KBD, 0 }, - { "send-list", CLR_SFL, 0 }, -#ifdef OS2 - { "scr", CLR_SCL, CM_INV|CM_ABR }, -#endif /* OS2 */ - { "screen", CLR_SCR, 0 }, -#ifdef OS2 - { "scrollback", CLR_SCL, CM_INV }, - { "terminal-screen", CLR_TRM, 0 }, -#endif /* OS2 */ -#ifdef PATTERNS - { "text-patterns", CLR_TXT, 0 }, -#endif /* PATTERNS */ - { "", 0, 0 } -}; -int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1; - -struct keytab clstab[] = { /* Keywords for CLOSE command */ -#ifndef NOSPL - { "!read", LOGR, CM_INV }, - { "!write", LOGW, CM_INV }, -#ifndef NOPUSH -#endif /* NOPUSH */ -#endif /* NOSPL */ -#ifndef NOSPL - { "append-file", LOGW, CM_INV }, -#endif /* NOSPL */ -#ifndef NOLOCAL - { "connection", 9999, 0 }, -#endif /* NOLOCAL */ -#ifdef CKLOGDIAL - { "cx-log", LOGM, 0 }, -#endif /* CKLOGDIAL */ -#ifdef DEBUG - { "debug-log", LOGD, 0 }, -#endif /* DEBUG */ - { "host", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */ - { "line", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */ - { "p", LOGP, CM_INV|CM_ABR }, - { "packet-log", LOGP, 0 }, - { "port", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */ -#ifndef NOSPL - { "read-file", LOGR, 0 }, -#endif /* NOSPL */ -#ifndef NOLOCAL - { "session-log", LOGS, 0 }, -#endif /* NOLOCAL */ -#ifdef TLOG - { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */ - { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */ - { "tra", LOGT, CM_ABR|CM_INV }, - { "tran", LOGT, CM_ABR|CM_INV }, - { "trans", LOGT, CM_ABR|CM_INV }, - { "transa", LOGT, CM_ABR|CM_INV }, - { "transac", LOGT, CM_ABR|CM_INV }, - { "transact", LOGT, CM_ABR|CM_INV }, - { "transacti", LOGT, CM_ABR|CM_INV }, - { "transactio", LOGT, CM_ABR|CM_INV }, - { "transaction", LOGT, CM_ABR|CM_INV }, - { "transaction-log", LOGT, 0 }, - { "transactions", LOGT, CM_INV }, -#endif /* TLOG */ -#ifndef NOSPL - { "write-file", LOGW, 0 }, -#endif /* NOSPL */ - { "", 0, 0 } -}; -int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1; - -/* SHOW command arguments */ - -#ifndef NOSHOW -struct keytab shotab[] = { -#ifndef NOSPL - { "alarm", SHALRM, 0 }, - { "arg", SHARG, CM_INV|CM_ABR }, - { "arguments", SHARG, 0 }, - { "args", SHARG, CM_INV }, - { "arrays", SHARR, 0 }, -#endif /* NOSPL */ - -#ifndef NOCSETS - { "associations", SHASSOC, 0 }, -#endif /* NOCSETS */ - -#ifndef NOXFER - { "attributes", SHATT, 0 }, -#endif /* NOXFER */ - -#ifdef CK_AUTHENTICATION - { "authentication", SHOAUTH, CM_INV }, -#endif /* CK_AUTHENTICATION */ - -#ifndef NOPUSH -#ifdef BROWSER - { "browser", SHBROWSE, CM_PSH|CM_LOC }, -#endif /* BROWSER */ -#endif /* NOPUSH */ - { "cd", SHCD, 0 }, - { "character-sets", SHCSE, 0 }, - { "cmd", SHCMD, CM_INV }, -#ifndef NOLOCAL - { "com", SHCOM, CM_INV|CM_ABR }, - { "comm", SHCOM, CM_INV|CM_ABR }, - { "communications", SHCOM, 0 }, -#endif /* NOLOCAL */ - { "command", SHCMD, 0 }, - { "connection", SHCONNX, 0 }, -#ifdef CK_SPEED - { "control-prefixing", SHCTL, 0 }, -#endif /* CK_SPEED */ -#ifdef CKLOGDIAL - { "cx", SHCONNX, CM_INV }, -#endif /* CKLOGDIAL */ -#ifndef NOSPL - { "count", SHCOU, 0 }, -#endif /* NOSPL */ - { "d", SHDIA, CM_INV|CM_ABR }, -#ifdef VMS - { "default", SHDFLT, 0 }, -#else - { "default", SHDFLT, CM_INV }, -#endif /* VMS */ -#ifndef NODIAL - { "dial", SHDIA, CM_LOC }, -#endif /* NODIAL */ - { "double/ignore",SHDBL, 0 }, -#ifndef NOPUSH -#ifndef NOFRILLS - { "editor", SHEDIT, CM_PSH }, -#endif /* NOFRILLS */ -#endif /* NOPUSH */ -#ifndef NOLOCAL - { "escape", SHESC, CM_LOC }, -#endif /* NOLOCAL */ - { "exit", SHEXI, 0 }, - { "extended-options", SHXOPT, CM_INV }, - { "features", SHFEA, 0 }, - { "file", SHFIL, 0 }, -#ifndef NOLOCAL - { "flow-control", SHOFLO, 0 }, -#endif /* NOLOCAL */ -#ifdef BROWSER - { "ftp", SHOFTP, CM_PSH|CM_LOC }, -#else -#ifndef NOFTP -#ifndef SYSFTP -#ifdef TCPSOCKET - { "ftp", SHOFTP, 0 }, /* (built-in ftp) */ -#endif /* TCPSOCKET */ -#endif /* SYSFTP */ -#endif /* NOFTP */ -#endif /* BROWSER */ -#ifndef NOSPL - { "functions", SHFUN, 0 }, - { "globals", SHVAR, 0 }, -#endif /* NOSPL */ -#ifdef KUI - { "gui", SHOGUI, 0 }, -#endif /* KUI */ -#ifdef CK_RECALL - { "history", SHHISTORY, 0 }, -#endif /* CK_RECALL */ - { "ignore/double",SHDBL, CM_INV }, - { "iksd", SHOIKS, CM_INV }, -#ifndef NOSPL - { "input", SHINP, 0 }, -#endif /* NOSPL */ -#ifndef NOSETKEY - { "k", SHKEY, CM_INV|CM_ABR }, - { "key", SHKEY, 0 }, -#ifndef NOKVERBS - { "kverbs", SHKVB, 0 }, -#endif /* NOKVERBS */ -#endif /* NOSETKEY */ -#ifdef CK_LABELED - { "labeled-file-info", SHLBL, 0 }, -#endif /* CK_LABELED */ -#ifndef NOCSETS - { "languages", SHLNG, 0 }, -#endif /* NOCSETS */ - { "logs", SHLOG, 0 }, -#ifndef NOSPL - { "macros", SHMAC, 0 }, -#endif /* NOSPL */ -#ifndef NODIAL - { "modem", SHMOD, CM_LOC }, -#else - { "modem-signals",SHCOM, CM_INV|CM_LOC }, -#endif /* NODIAL */ -#ifndef NOLOCAL -#ifdef OS2MOUSE - { "mouse", SHMOU, CM_LOC }, -#endif /* OS2MOUSE */ -#endif /* NOLOCAL */ -#ifdef NETCONN - { "network", SHNET, CM_LOC }, -#else - { "network", SHNET, CM_INV|CM_LOC }, -#endif /* NETCONN */ - { "options", SHOPTS, 0 }, -#ifndef NOSPL - { "output", SHOUTP, CM_INV }, -#endif /* NOSPL */ -#ifdef ANYX25 -#ifndef IBMX25 - { "pad", SHPAD, CM_LOC }, -#endif /* IBMX25 */ -#endif /* ANYX25 */ - { "parameters", SHPAR, CM_INV }, -#ifdef PATTERNS - { "patterns", SHOPAT, 0 }, -#endif /* PATTERNS */ - { "printer", SHPRT, 0 }, -#ifdef CK_SPEED - { "prefixing", SHCTL, CM_INV }, -#endif /* CK_SPEED */ -#ifndef NOXFER - { "protocol", SHPRO, 0 }, -#endif /* NOXFER */ -#ifndef NOSPL - { "scripts", SHSCR, CM_LOC }, -#endif /* NOSPL */ - { "send-list", SHSFL, 0 }, -#ifndef NOSERVER - { "server", SHSER, 0 }, -#endif /* NOSERVER */ -#ifndef NOSEXP - { "sexpression", SHSEXP, 0 }, -#endif /* NOSEXP */ -#ifdef ANYSSH - { "ssh", SHOSSH, 0 }, -#endif /* ANYSSH */ - { "stack", SHSTK, 0 }, - { "status", SHSTA, 0 }, -#ifdef STREAMING - { "streaming", SHOSTR, 0 }, -#endif /* STREAMING */ -#ifndef NOLOCAL -#ifdef OS2 - { "tabs", SHTAB, CM_INV|CM_LOC }, -#endif /* OS2 */ -#ifdef CK_TAPI - { "tapi", SHTAPI, CM_LOC }, - { "tapi-comm", SHTAPI_C, CM_INV|CM_LOC }, - { "tapi-location", SHTAPI_L, CM_INV|CM_LOC }, - { "tapi-modem", SHTAPI_M, CM_INV|CM_LOC }, -#endif /* CK_TAPI */ - { "tcp", SHTCP, CM_LOC }, -#ifdef TNCODE - { "tel", SHTEL, CM_INV|CM_ABR }, - { "telnet", SHTEL, 0 }, - { "telopt", SHTOPT, 0 }, -#endif /* TNCODE */ - { "terminal", SHTER, CM_LOC }, -#endif /* NOLOCAL */ -#ifndef NOXMIT - { "tr", SHXMI, CM_INV|CM_ABR }, - { "tra", SHXMI, CM_INV|CM_ABR }, - { "tran", SHXMI, CM_INV|CM_ABR }, - { "trans", SHXMI, CM_INV|CM_ABR }, -#endif /* NOXMIT */ -#ifndef NOXFER - { "transfer", SHOXFER, 0 }, -#endif /* NOXFER */ -#ifndef NOXMIT - { "transmit", SHXMI, 0 }, -#endif /* NOXMIT */ -#ifdef CK_TRIGGER - { "trigger", SHTRIG, CM_LOC }, -#endif /* CK_TRIGGER */ -#ifndef NOSETKEY -#ifndef NOKVERBS -#ifdef OS2 - { "udk", SHUDK, CM_LOC }, -#endif /* OS2 */ -#endif /* NOKVERBS */ -#endif /* NOSETKEY */ -#ifndef NOSPL - { "variables", SHBUI, 0 }, -#endif /* NOSPL */ -#ifndef NOFRILLS - { "versions", SHVER, 0 }, -#endif /* NOFRILLS */ -#ifdef OS2 - { "vscrn", SHVSCRN, CM_INV|CM_LOC }, -#endif /* OS2 */ - { "xfer", SHOXFER, CM_INV }, -#ifndef NOXMIT - { "xmit", SHXMI, CM_INV }, -#endif /* NOXMIT */ - { "", 0, 0 } -}; -int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1; -#endif /* NOSHOW */ - -#ifdef ANYX25 -#ifndef IBMX25 -struct keytab padtab[] = { /* PAD commands */ - { "clear", XYPADL, 0 }, - { "interrupt", XYPADI, 0 }, - { "reset", XYPADR, 0 }, - { "status", XYPADS, 0 } -}; -int npadc = (sizeof(padtab) / sizeof(struct keytab)); -#endif /* IBMX25 */ -#endif /* ANYX25 */ - -#ifndef NOSERVER -static struct keytab kmstab[] = { - { "both", 3, 0 }, - { "local", 1, 0 }, - { "remote", 2, 0 } -}; - -static struct keytab enatab[] = { /* ENABLE commands */ - { "all", EN_ALL, 0 }, -#ifndef NOSPL - { "as", EN_ASG, CM_INV|CM_ABR }, - { "asg", EN_ASG, CM_INV }, - { "assign", EN_ASG, 0 }, -#endif /* NOSPL */ -#ifndef datageneral - { "bye", EN_BYE, 0 }, -#endif /* datageneral */ - { "cd", EN_CWD, 0 }, -#ifdef ZCOPY - { "copy", EN_CPY, 0 }, -#endif /* ZCOPY */ - { "cwd", EN_CWD, CM_INV }, - { "delete", EN_DEL, 0 }, - { "directory", EN_DIR, 0 }, - { "enable", EN_ENA, CM_INV }, - { "exit", EN_XIT, 0 }, - { "finish", EN_FIN, 0 }, - { "get", EN_GET, 0 }, - { "host", EN_HOS, 0 }, - { "mail", EN_MAI, 0 }, - { "mkdir", EN_MKD, 0 }, - { "print", EN_PRI, 0 }, -#ifndef NOSPL - { "query", EN_QUE, 0 }, -#endif /* NOSPL */ - { "rename", EN_REN, 0 }, - { "retrieve", EN_RET, CM_INV }, - { "rmdir", EN_RMD, 0 }, - { "send", EN_SEN, 0 }, - { "set", EN_SET, 0 }, - { "space", EN_SPA, 0 }, - { "type", EN_TYP, 0 }, - { "who", EN_WHO, 0 } -}; -static int nena = (sizeof(enatab) / sizeof(struct keytab)); -#endif /* NOSERVER */ - -struct keytab txtbin[] = { - { "all", 2, 0 }, - { "binary", 1, 0 }, - { "text", 0, 0 } -}; - -#ifndef NOXFER -static struct keytab sndtab[] = { /* SEND command options */ - { "/after", SND_AFT, CM_ARG }, -#ifndef NOSPL - { "/array", SND_ARR, CM_ARG }, -#endif /* NOSPL */ - { "/as-name", SND_ASN, CM_ARG }, - { "/b", SND_BIN, CM_INV|CM_ABR }, - { "/before", SND_BEF, CM_ARG }, - { "/binary", SND_BIN, 0 }, -#ifdef CALIBRATE - { "/c", SND_CMD, CM_INV|CM_ABR }, - { "/calibrate", SND_CAL, CM_INV|CM_ARG }, -#endif /* CALIBRATE */ - { "/command", SND_CMD, CM_PSH }, - { "/delete", SND_DEL, 0 }, -#ifdef UNIXOROSK - { "/dotfiles", SND_DOT, 0 }, -#endif /* UNIXOROSK */ - { "/except", SND_EXC, CM_ARG }, -#ifdef PIPESEND - { "/filter", SND_FLT, CM_ARG|CM_PSH }, -#endif /* PIPESEND */ - { "/filenames", SND_NAM, CM_ARG }, -#ifdef CKSYMLINK - { "/followlinks", SND_LNK, 0 }, -#endif /* CKSYMLINK */ -#ifdef VMS - { "/image", SND_IMG, 0 }, -#else - { "/image", SND_BIN, CM_INV }, -#endif /* VMS */ -#ifdef CK_LABELED - { "/labeled", SND_LBL, 0 }, -#endif /* CK_LABELED */ - { "/larger-than", SND_LAR, CM_ARG }, - { "/listfile", SND_FIL, CM_ARG }, -#ifndef NOFRILLS - { "/mail", SND_MAI, CM_ARG }, -#endif /* NOFRILLS */ -#ifdef CK_TMPDIR - { "/move-to", SND_MOV, CM_ARG }, -#endif /* CK_TMPDIR */ - { "/nobackupfiles", SND_NOB, 0 }, -#ifdef UNIXOROSK - { "/nodotfiles", SND_NOD, 0 }, -#endif /* UNIXOROSK */ -#ifdef CKSYMLINK - { "/nofollowlinks", SND_NLK, 0 }, -#endif /* CKSYMLINK */ - { "/not-after", SND_NAF, CM_ARG }, - { "/not-before", SND_NBE, CM_ARG }, - { "/pathnames", SND_PTH, CM_ARG }, - { "/print", SND_PRI, CM_ARG }, -#ifdef CK_XYZ - { "/protocol", SND_PRO, CM_ARG }, -#else - { "/protocol", SND_PRO, CM_ARG|CM_INV }, -#endif /* CK_XYZ */ - { "/quiet", SND_SHH, 0 }, - { "/recover", SND_RES, 0 }, -#ifdef RECURSIVE -/* Systems where we do recursion */ - { "/recursive", SND_REC, 0 }, -#else -#ifdef VMS -/* Systems that do recursion themselves without our assistance */ -/* if we give them the right kind of wildcard */ - { "/recursive", SND_REC, 0 }, -#else -#ifdef datageneral - { "/recursive", SND_REC, 0 }, -#else - { "/recursive", SND_REC, CM_INV }, -#endif /* datageneral */ -#endif /* VMS */ -#endif /* RECURSIVE */ - { "/rename-to", SND_REN, CM_ARG }, - { "/since", SND_AFT, CM_INV|CM_ARG }, - { "/smaller-than", SND_SMA, CM_ARG }, - { "/starting-at", SND_STA, CM_ARG }, -#ifndef NOFRILLS - { "/su", SND_ASN, CM_ARG|CM_INV|CM_ABR }, - { "/sub", SND_ASN, CM_ARG|CM_INV|CM_ABR }, - { "/subject", SND_ASN, CM_ARG }, -#endif /* NOFRILLS */ -#ifdef RECURSIVE - { "/subdirectories", SND_REC, CM_INV }, -#endif /* RECURSIVE */ - { "/text", SND_TXT, 0 }, - { "/transparent", SND_XPA, 0 }, - { "/type", SND_TYP, CM_ARG } -}; -#define NSNDTAB sizeof(sndtab)/sizeof(struct keytab) -static int nsndtab = NSNDTAB; - -#ifndef NOMSEND -static struct keytab msndtab[] = { /* MSEND options */ - { "/after", SND_AFT, CM_ARG }, - { "/before", SND_BEF, CM_ARG }, - { "/binary", SND_BIN, 0 }, - { "/delete", SND_DEL, 0 }, - { "/except", SND_EXC, CM_ARG }, - { "/filenames", SND_NAM, CM_ARG }, -#ifdef CKSYMLINK - { "/followlinks", SND_LNK, 0 }, -#endif /* CKSYMLINK */ -#ifdef VMS - { "/image", SND_IMG, 0 }, -#else - { "/image", SND_BIN, CM_INV }, -#endif /* VMS */ -#ifdef CK_LABELED - { "/labeled", SND_LBL, 0 }, -#endif /* CK_LABELED */ - { "/larger-than", SND_LAR, CM_ARG }, - { "/list", SND_FIL, CM_ARG }, -#ifndef NOFRILLS - { "/mail", SND_MAI, CM_ARG }, -#endif /* NOFRILLS */ -#ifdef CK_TMPDIR - { "/move-to", SND_MOV, CM_ARG }, -#endif /* CK_TMPDIR */ -#ifdef CKSYMLINK - { "/nofollowlinks", SND_NLK, 0 }, -#endif /* CKSYMLINK */ - { "/not-after", SND_NAF, CM_ARG }, - { "/not-before", SND_NBE, CM_ARG }, - { "/pathnames", SND_PTH, CM_ARG }, - { "/print", SND_PRI, CM_ARG }, -#ifdef CK_XYZ - { "/protocol", SND_PRO, CM_ARG }, -#endif /* CK_XYZ */ - { "/quiet", SND_SHH, 0 }, - { "/recover", SND_RES, 0 }, - { "/rename-to", SND_REN, CM_ARG }, - { "/since", SND_AFT, CM_INV|CM_ARG }, - { "/smaller-than", SND_SMA, CM_ARG }, - { "/starting-at", SND_STA, CM_ARG }, -#ifndef NOFRILLS - { "/subject", SND_ASN, CM_ARG }, -#endif /* NOFRILLS */ - { "/text", SND_TXT, 0 }, - { "/transparent", SND_XPA, 0 }, - { "/type", SND_TYP, CM_ARG } -}; -#define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab) -static int nmsndtab = NMSNDTAB; -#endif /* NOMSEND */ -#endif /* NOXFER */ - -/* CONNECT command switches */ - -#define CONN_II 0 /* Idle interval */ -#define CONN_IS 1 /* Idle string */ -#define CONN_IL 2 /* Idle limit */ -#define CONN_NV 3 /* Non-Verbose */ -#define CONN_TL 4 /* Time limit */ -#define CONN_TS 5 /* Trigger string */ -#define CONN_AS 6 /* Asynchronous */ -#define CONN_SY 7 /* Synchronous */ -#define CONN_MAX 7 /* Number of CONNECT switches */ - -#ifndef NOLOCAL -static struct keytab conntab[] = { -#ifdef OS2 - { "/asynchronous", CONN_AS, CM_INV }, -#endif /* OS2 */ -#ifdef XLIMITS - { "/idle-interval", CONN_II, CM_ARG }, - { "/idle-limit", CONN_IL, CM_ARG }, - { "/idle-string", CONN_IS, CM_ARG }, - { "/quietly", CONN_NV, CM_INV }, -#else - { "/quietly", CONN_NV, 0 }, -#endif /* XLIMITS */ -#ifdef OS2 - { "/synchronous", CONN_SY, CM_INV }, -#endif /* OS2 */ -#ifdef XLIMITS - { "/time-limit", CONN_TL, CM_ARG }, -#endif /* XLIMITS */ -#ifdef CK_TRIGGER - { "/trigger", CONN_TS, CM_ARG }, -#endif /* CK_TRIGGER */ - { "",0,0 } -}; -#define NCONNTAB sizeof(conntab)/sizeof(struct keytab) -static int nconntab = NCONNTAB; -#endif /* NOLOCAL */ - -#ifndef NOXFER -static struct keytab stattab[] = { /* STATISTICS command switches */ - { "/brief", 1, 0 }, - { "/verbose", 0, 0 } -}; -#endif /* NOXFER */ - -#ifndef NOSPL -#ifdef COMMENT -struct mtab mactab[MAC_MAX] = { /* Preinitialized macro table */ - { NULL, NULL, 0 } -}; -#else -struct mtab *mactab; /* Dynamically allocated macro table */ -#endif /* COMMENT */ -int nmac = 0; - -struct keytab mackey[MAC_MAX]; /* Macro names as command keywords */ -#endif /* NOSPL */ - -#ifndef NOSPL -#ifdef OS2 -struct keytab beeptab[] = { /* Beep options */ - { "error", BP_FAIL, 0 }, - { "information", BP_NOTE, 0 }, - { "warning", BP_WARN, 0 } -}; -int nbeeptab = sizeof(beeptab)/sizeof(struct keytab); - -/* CLEAR COMMMAND-SCREEN options */ - -#define CLR_C_ALL 0 -#define CLR_C_BOL 1 -#define CLR_C_BOS 2 -#define CLR_C_EOL 3 -#define CLR_C_EOS 4 -#define CLR_C_LIN 5 -#define CLR_C_SCR 6 - -struct keytab clrcmdtab[] = { - { "all", CLR_C_ALL, 0 }, - { "bol", CLR_C_BOL, 0 }, - { "bos", CLR_C_BOS, 0 }, - { "eol", CLR_C_EOL, 0 }, - { "eos", CLR_C_EOS, 0 }, - { "line", CLR_C_LIN, 0 }, - { "scrollback", CLR_C_SCR, 0 } -}; -int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab); -#endif /* OS2 */ -#endif /* NOSPL */ - -#ifdef COMMENT -/* Not used at present */ -static struct keytab pagetab[] = { - { "/more", 1, CM_INV }, - { "/nopage", 0, 0 }, - { "/page", 1, 0 } -}; -int npagetab = sizeof(pagetab)/sizeof(struct keytab); -#endif /* COMMENT */ - -#define TYP_NOP 0 /* /NOPAGE */ -#define TYP_PAG 1 /* /PAGE */ -#define TYP_HEA 2 /* /HEAD:n */ -#define TYP_TAI 3 /* /TAIL:n */ -#define TYP_PAT 4 /* /MATCH:pattern */ -#define TYP_WID 5 /* /WIDTH:cols */ -#define TYP_COU 6 /* /COUNT */ -#define TYP_OUT 7 /* /OUTPUT:file */ -#define TYP_PFX 8 /* /PREFIX:string */ -#ifdef UNICODE -#define TYP_XIN 9 /* /TRANSLATE-FROM:charset */ -#define TYP_XUT 10 /* /TRANSLATE-TO:charset */ -#define TYP_XPA 11 /* /TRANSPARENT */ -#endif /* UNICODE */ -#ifdef KUI -#define TYP_GUI 12 /* /GUI:title */ -#define TYP_HIG 13 /* /HEIGHT:rows */ -#endif /* KUI */ -#define TYP_NUM 14 /* /NUMBER */ - -static struct keytab typetab[] = { /* TYPE command switches */ - { "/count", TYP_COU, 0 }, -#ifdef UNICODE - { "/character-set", TYP_XIN, CM_ARG }, -#endif /* UNICODE */ -#ifdef KUI - { "/gui", TYP_GUI, CM_ARG }, -#endif /* KUI */ - { "/head", TYP_HEA, CM_ARG }, -#ifdef KUI - { "/height", TYP_HIG, CM_ARG }, -#endif /* KUI */ - { "/match", TYP_PAT, CM_ARG }, -#ifdef CK_TTGWSIZ - { "/more", TYP_PAG, CM_INV }, - { "/nopage", TYP_NOP, 0 }, - { "/number", TYP_NUM, 0 }, - { "/output", TYP_OUT, CM_ARG }, - { "/page", TYP_PAG, 0 }, -#endif /* CK_TTGWSIZ */ - { "/prefix", TYP_PFX, CM_ARG }, - { "/tail", TYP_TAI, CM_ARG }, -#ifdef UNICODE - { "/translate-to", TYP_XUT, CM_ARG }, - { "/transparent", TYP_XPA, 0 }, -#endif /* UNICODE */ - { "/width", TYP_WID, CM_ARG }, -#ifdef UNICODE - { "/xlate-to", TYP_XUT, CM_INV|CM_ARG }, -#endif /* UNICODE */ - { "", 0, 0 } -}; -int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1; - -int typ_page = -1; /* TYPE /[NO]PAGE default */ -int typ_wid = -1; - -#ifndef NOSPL -#define TRA_ALL 999 /* TRACE command */ -#define TRA_ASG 0 -#define TRA_CMD 1 - -int tra_asg = 0; -int tra_cmd = 0; - -static struct keytab tracetab[] = { /* TRACE options */ - { "all", TRA_ALL, 0 }, - { "assignments", TRA_ASG, 0 }, - { "command-level", TRA_CMD, 0 } -}; -static int ntracetab = sizeof(tracetab)/sizeof(struct keytab); -#endif /* NOSPL */ - -#ifndef NOSHOW -VOID -showtypopts() { - printf(" TYPE "); - if (typ_page > -1) { - prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE"); - } else - prtopt(&optlines,"(no options set)"); - if (typ_wid > -1) { - ckmakmsg(tmpbuf,TMPBUFSIZ,"/WIDTH:",ckitoa(typ_wid),NULL,NULL); - prtopt(&optlines,tmpbuf); - } - prtopt(&optlines,""); -} -#endif /* NOSHOW */ - -#ifdef LOCUS -/* isauto == 1 if locus is being switched automatically */ - -VOID -setlocus(x, isauto) int x, isauto; { - extern int quitting; - if (x) x = 1; - if (x && locus) return; - if (!x && !locus) return; - /* Get here if it actually needs to be changed */ -#ifdef OS2 - if (isauto && /* Automatically switching */ - !quitting && /* not exiting */ - autolocus == 2) { /* and AUTOLOCUS is set to ASK */ - char locmsg[300]; - ckmakmsg(locmsg,300, - "Switching Locus to ", - x ? "LOCAL" : "REMOTE", - " for file management commands\n" - "such as CD, DIRECTORY, DELETE, RENAME. Type HELP SET\n" - "LOCUS at the K-95> prompt for further info. Use the\n" -#ifdef KUI - "Actions menu or SET LOCUS command to disable automatic\n" - "Locus switching or to disable these queries.", -#else /* KUI */ - "SET LOCUS command to disable automatic locus switching\n" - "or to disable these queries.", -#endif /* KUI */ - NULL); - if (uq_ok(locmsg,"OK to switch Locus?",3,NULL,1)) { - locus = x; -#ifdef KUI - KuiSetProperty(KUI_LOCUS,x,0); -#endif /* KUI */ - return; - } - } else { -#endif /* OS2 */ - if (isauto && msgflg && !quitting) - printf("Switching LOCUS for file-management commands to %s.\n", - x ? "LOCAL" : "REMOTE" - ); - locus = x; -#ifdef OS2 -#ifdef KUI - KuiSetProperty(KUI_LOCUS,x,0); -#endif /* KUI */ - } -#endif /* OS2 */ -} - -VOID -setautolocus(x) int x; { - autolocus = x; -#ifdef KUI - KuiSetProperty(KUI_AUTO_LOCUS,x,0); -#endif /* KUI */ -} -#endif /* LOCUS */ - -int -settypopts() { /* Set TYPE option defaults */ - int xp = -1; - int c, getval; - while (1) { - if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) { - if (y == -3) - break; - else - return(y); - } - c = cmgbrk(); - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - switch (y) { - case TYP_NOP: xp = 0; break; - case TYP_PAG: xp = 1; break; - case TYP_WID: - if (getval) - if ((x = cmnum("Column at which to truncate", - ckitoa(cmd_cols),10,&y,xxstring)) < 0) - return(x); - typ_wid = y; - break; - - default: - printf("?Sorry, this option can not be set\n"); - return(-9); - } - } - if ((x = cmcfm()) < 0) /* Get confirmation */ - return(x); - if (xp > -1) typ_page = xp; /* Confirmed, save defaults */ - return(success = 1); -} - -/* Forward declarations of functions local to this module */ - -#ifdef UNIX -_PROTOTYP (int douchmod, ( void ) ); -#endif /* UNIX */ -#ifdef CKPURGE -_PROTOTYP (int dopurge, ( void ) ); -#endif /* CKPURGE */ -#ifndef NOSPL -_PROTOTYP (int doundef, ( int ) ); -_PROTOTYP (int doask, ( int ) ); -_PROTOTYP (int dodef, ( int ) ); -_PROTOTYP (int doelse, ( void ) ); -_PROTOTYP (int dofor, ( void ) ); -_PROTOTYP (int doincr, ( int ) ); -#endif /* NOSPL */ -#ifndef NODIAL -_PROTOTYP (int dodial, ( int ) ); -#endif /* NODIAL */ -_PROTOTYP (int dodel, ( void ) ); -_PROTOTYP (int dopaus, ( int ) ); -#ifndef NOPUSH -#ifdef TCPSOCKET -_PROTOTYP (int doping, ( void ) ); -_PROTOTYP (int doftp, ( void ) ); -#endif /* TCPSOCKET */ -#endif /* NOPUSH */ -#ifndef NORENAME -#ifndef NOFRILLS -_PROTOTYP (int dorenam, ( void ) ); -#endif /* NOFRILLS */ -#endif /* NORENAME */ -#ifdef ZCOPY -_PROTOTYP (int docopy, ( void ) ); -#endif /* ZCOPY */ -#ifdef NT -_PROTOTYP (int dolink, ( void )); -#endif /* NT */ -#ifdef CK_REXX -_PROTOTYP (int dorexx, ( void ) ); -#endif /* CK_REXX */ - -#ifdef TNCODE -static struct keytab telcmd[] = { - { "abort", TN_ABORT, CM_INV }, /* Emotionally toned - don't show */ - { "ao", TN_AO, 0 }, - { "ayt", TN_AYT, 0 }, - { "break", BREAK, 0 }, - { "cancel",TN_ABORT, 0 }, - { "dmark", TN_DM, 0 }, - { "do", DO, 0 }, - { "dont", DONT, 0 }, - { "ec", TN_EC, 0 }, - { "el", TN_EL, 0 }, - { "eof", TN_EOF, 0 }, - { "eor", TN_EOR, 0 }, -#ifdef CK_KERBEROS -#ifdef KRB5 -#define TN_FWD 1 - { "forward", TN_FWD, CM_INV }, -#endif /* KRB5 */ -#endif /* CK_KERBEROS */ - { "ga", TN_GA, 0 }, - { "ip", TN_IP, 0 }, - { "nop", TN_NOP, 0 }, - { "sak", TN_SAK, CM_INV }, - { "sb", SB, 0 }, - { "se", SE, 0 }, - { "susp", TN_SUSP, 0 }, - { "will", WILL, 0 }, - { "wont", WONT, 0 } -}; -static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab)); - -static struct keytab tnopts[] = { -#ifdef CK_AUTHENTICATION - { "auth", TELOPT_AUTHENTICATION, 0 }, -#else - { "auth", TELOPT_AUTHENTICATION, CM_INV }, -#endif /* CK_AUTHENTICATION */ - { "binary", TELOPT_BINARY, 0 }, -#ifdef TN_COMPORT - { "c", TELOPT_COMPORT, CM_INV|CM_ABR}, - { "co", TELOPT_COMPORT, CM_INV|CM_ABR}, - { "com", TELOPT_COMPORT, CM_INV|CM_ABR}, - { "com-port-control", TELOPT_COMPORT, 0 }, - { "comport-control", TELOPT_COMPORT, CM_INV}, -#else /* TN_COMPORT */ - { "com-port-control", TELOPT_COMPORT, CM_INV }, - { "comport-control", TELOPT_COMPORT, CM_INV}, -#endif /* TN_COMPORT */ - { "echo", TELOPT_ECHO, 0 }, -#ifdef CK_ENCRYPTION - { "encrypt", TELOPT_ENCRYPTION, 0 }, -#else - { "encrypt", TELOPT_ENCRYPTION, CM_INV }, -#endif /* CK_ENCRYPTION */ -#ifdef CK_FORWARD_X - { "forward-x", TELOPT_FORWARD_X, 0 }, -#else - { "forward-x", TELOPT_FORWARD_X, CM_INV }, -#endif /* CK_FORWARD_X */ -#ifdef IKS_OPTION - { "kermit", TELOPT_KERMIT, 0 }, -#else - { "kermit", TELOPT_KERMIT, CM_INV }, -#endif /* IKS_OPTION */ - { "lflow", TELOPT_LFLOW, CM_INV }, - { "logout", TELOPT_LOGOUT, CM_INV }, -#ifdef CK_NAWS - { "naws", TELOPT_NAWS, 0 }, -#else - { "naws", TELOPT_NAWS, CM_INV }, -#endif /* CK_NAWS */ -#ifdef CK_ENVIRONMENT - { "new-environment", TELOPT_NEWENVIRON, 0 }, -#else - { "new-environment", TELOPT_NEWENVIRON, CM_INV }, -#endif /* CK_ENVIRONMENT */ - { "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT, CM_INV }, - { "pragma-logon", TELOPT_PRAGMA_LOGON, CM_INV }, - { "pragma-sspi", TELOPT_SSPI_LOGON, CM_INV }, - { "sak", TELOPT_IBM_SAK, CM_INV }, -#ifdef CK_SNDLOC - { "send-location", TELOPT_SNDLOC, 0 }, -#else - { "send-location", TELOPT_SNDLOC, CM_INV }, -#endif /* CK_SNDLOC */ - { "sga", TELOPT_SGA, 0 }, -#ifdef CK_SSL - { "start-tls", TELOPT_START_TLS, 0 }, -#else - { "start-tls", TELOPT_START_TLS, CM_INV }, -#endif /* CK_SSL */ - { "ttype", TELOPT_TTYPE, 0 }, -#ifdef CK_ENVIRONMENT - { "xdisplay-location", TELOPT_XDISPLOC, 0 }, -#else - { "xdisplay-location", TELOPT_XDISPLOC, CM_INV }, -#endif /* CK_ENVIRONMENT */ - { "", 0, 0 } -}; -static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1; - -static struct keytab tnsbopts[] = { -#ifdef CK_NAWS - { "naws", TELOPT_NAWS, 0 }, -#endif /* CK_NAWS */ - { "", 0, 0 } -}; -static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1; -#endif /* TNCODE */ - -#ifdef TCPSOCKET -#ifndef NOPUSH -#ifdef SYSFTP -int -doftp() { /* (External) FTP command */ - char *p, *f; /* (See doxftp() for internal one) */ - int x; - - if (network) /* If we have a current connection */ - ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */ - else *line = '\0'; /* as default host */ - for (p = line; *p; p++) /* Remove ":service" from end. */ - if (*p == ':') { *p = '\0'; break; } - if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0) - return(x); - if (nopush) { - printf("?Sorry, FTP command disabled\n"); - return(success = 0); - } -/* Construct FTP command */ -#ifdef VMS -#ifdef MULTINET /* TGV MultiNet */ - ckmakmsg(line,LINBUFSIZ,"multinet ftp ",s,NULL,NULL); -#else - ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL); -#endif /* MULTINET */ -#else /* Not VMS */ -#ifdef OS2ORUNIX -#ifndef NOFTP - f = ftpapp; - if (!f) f = ""; - if (!f[0]) f = "ftp"; - ckmakmsg(line,LINBUFSIZ,f," ",s,NULL); -#ifdef OS2 - p = line + strlen(ftpapp); - while (p != line) { - if (*p == '/') *p = '\\'; - p--; - } -#endif /* OS2 */ -#else /* NOFTP */ - ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL); -#endif /* NOFTP */ -#else /* OS2ORUNIX */ - ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL); -#endif /* OS2ORUNIX */ -#endif /* VMS */ - conres(); /* Make console normal */ -#ifdef DEC_TCPIP - printf("\n"); /* Prevent prompt-stomping */ -#endif /* DEC_TCPIP */ - x = zshcmd(line); - concb((char)escape); - return(success = x); -} -#endif /* SYSFTP */ - -int -doping() { /* PING command */ - char *p; /* just runs ping program */ - int x; - - if (network) /* If we have a current connection */ - ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */ - else *line = '\0'; /* as default host to be pinged. */ - for (p = line; *p; p++) /* Remove ":service" from end. */ - if (*p == ':') { *p = '\0'; break; } - if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0) - return(x); - if (nopush) { - printf("?Sorry, PING command disabled\n"); - return(success = 0); - } - - /* Construct PING command */ -#ifdef VMS -#ifdef MULTINET /* TGV MultiNet */ - ckmakmsg(line,LINBUFSIZ,"multinet ping ",s," /num=1",NULL); -#else - ckmakmsg(line,LINBUFSIZ,"ping ",s," 56 1",NULL); /* Other VMS TCP/IP's */ -#endif /* MULTINET */ -#else /* Not VMS */ - ckmakmsg(line,LINBUFSIZ,"ping ",s,NULL,NULL); -#endif /* VMS */ - conres(); /* Make console normal */ -#ifdef DEC_TCPIP - printf("\n"); /* Prevent prompt-stomping */ -#endif /* DEC_TCPIP */ - x = zshcmd(line); - concb((char)escape); - return(success = x); -} -#endif /* NOPUSH */ -#endif /* TCPSOCKET */ - -static VOID -doend(x) int x; { -#ifndef NOSPL - /* Pop from all FOR/WHILE/XIF/SWITCH's */ - debug(F101,"doend maclvl 1","",maclvl); - while ((maclvl > 0) && - (m_arg[maclvl-1][0]) && - (cmdstk[cmdlvl].src == CMD_MD) && - (!strncmp(m_arg[maclvl-1][0],"_xif",4) || - !strncmp(m_arg[maclvl-1][0],"_for",4) || - !strncmp(m_arg[maclvl-1][0],"_whi",4) || - !strncmp(m_arg[maclvl-1][0],"_swi",4))) { - debug(F110,"END popping",m_arg[maclvl-1][0],0); - dogta(XXPTA); /* Put args back */ - popclvl(); /* Pop up two levels */ - popclvl(); - debug(F101,"doend maclvl 2","",maclvl); - } - if (maclvl > -1) { - if (mrval[maclvl]) /* Free previous retval if any */ - free(mrval[maclvl]); - mrval[maclvl] = malloc(16); /* Room for up to 15 digits */ - if (mrval[maclvl]) /* Record current retval */ - ckmakmsg(mrval[maclvl],16,ckitoa(x),NULL,NULL,NULL); - } -#endif /* NOSPL */ - popclvl(); /* Now pop out of macro or TAKE file */ -#ifndef NOSPL -#ifdef DEBUG - if (deblog) { - debug(F101,"END maclvl 3","",maclvl); - debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl); - debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1); - } -#endif /* DEBUG */ -#endif /* NOSPL */ -} - -#ifdef CKROOT -int -dochroot() { - if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Directory name required\n"); - return(-9); - } - return(x); - } - ckstrncpy(line,s,LINBUFSIZ); - s = line; - if ((x = cmcfm()) < 0) return(x); - s = brstrip(s); - x = zsetroot(s); - if (x < 0) { - char * m = NULL; - switch (x) { - case -1: - case -2: m = "Not a directory"; break; - case -3: m = "Internal error"; break; - case -4: m = "Access denied"; break; - case -5: m = "Off limits"; break; - } - if (m) printf("%s: \"%s\"\n", m, s); - return(m ? -9 : -2); - } else { - nopush = 1; - return(success = 1); - } -} -#endif /* CKROOT */ - -#ifndef NOXFER -static char * asnbuf = NULL; /* As-name buffer pointer */ - -char sndxnam[] = { "_array_x_" }; /* (with replaceable x!) */ - -/* - The new SEND command, replacing BSEND, CSEND, PSEND, etc etc. - Call with cx = top-level keyword value. Returns: - < 0 On parse error. - 0 On other type of failure (e.g. requested operation not allowed). - 1 On success with sstate set to 's' so protocol will begin. -*/ - -/* D O X S E N D -- Parse SEND and related commands with switches */ - -int -doxsend(cx) int cx; { - int c, i, n, wild, confirmed = 0; /* Workers */ - int x, y; /* of the world... */ - int getval = 0; /* Whether to get switch value */ - extern char * snd_move; /* Directory to move sent files to */ - extern char * snd_rename; /* What to rename sent files to */ - extern char * filefile; /* File containing filenames to send */ - extern int xfiletype; /* Send only text (or binary) files */ - extern struct keytab pathtab[]; /* PATHNAMES option keywords */ - extern int npathtab; /* How many of them */ - extern int recursive; /* Recursive directory traversal */ - extern int rprintf; /* REMOTE PRINT flag */ - extern int fdispla; /* TRANSFER DISPLAY setting */ - extern int skipbup; /* Skip backup files when sending */ - struct stringint { /* Temporary array for switch values */ - char * sval; - int ival; - } pv[SND_MAX+1]; - struct FDB sf, sw, fl, cm; /* FDBs for each parse function */ - int mlist = 0; /* Flag for MSEND or MMOVE */ - char * m; /* For making help messages */ - extern struct keytab protos[]; /* File transfer protocols */ - extern int xfrxla, g_xfrxla, nprotos; - extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */ - extern char sndnbefore[], sndnafter[]; - extern long sndsmaller, sndlarger, calibrate; -#ifndef NOSPL - int range[2]; /* Array range */ - char ** ap = NULL; /* Array pointer */ - int arrayx = -1; /* Array index */ -#endif /* NOSPL */ - -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) { - if (cx == XXMAI) { - printf("?Sorry, No MAIL with FTP\n"); - return(-9); - } - return(doftpput(cx,0)); - } -#endif /* NEWFTP */ - - for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */ - pv[i].sval = NULL; /* to null pointers */ - pv[i].ival = -1; /* and -1 int values */ - } -#ifndef NOSPL - range[0] = -1; - range[1] = -1; - sndxin = -1; /* Array index */ -#endif /* NOSPL */ - sndarray = NULL; /* Array pointer */ - -#ifdef UNIXOROSK - g_matchdot = matchdot; /* Match dot files */ -#endif /* UNIXOROSK */ - g_recursive = recursive; /* Recursive sending */ - recursive = 0; /* Save global value, set local */ - debug(F101,"xsend entry fncnv","",fncnv); - - /* Preset switch values based on top-level command that called us */ - - switch (cx) { - case XXMSE: /* MSEND */ - mlist = 1; break; - case XXCSEN: /* CSEND */ - pv[SND_CMD].ival = 1; break; - case XXMMOVE: /* MMOVE */ - mlist = 1; - case XXMOVE: /* MOVE */ - pv[SND_DEL].ival = 1; break; - case XXRSEN: /* RESEND */ - pv[SND_BIN].ival = 1; /* Implies /BINARY */ - pv[SND_RES].ival = 1; break; - case XXMAI: /* MAIL */ - pv[SND_MAI].ival = 1; break; - } - - /* Set up chained parse functions... */ - - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Filename, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ -#ifdef NOMSEND - nsndtab, /* addtl numeric data 1: tbl size */ -#else - mlist ? nmsndtab : nsndtab, /* addtl numeric data 1: tbl size */ -#endif /* NOMSEND */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ -#ifdef NOMSEND - sndtab, /* Keyword table */ -#else - mlist ? msndtab : sndtab, -#endif /* NOMSEND */ - &sf /* Pointer to next FDB */ - ); - cmfdbi(&sf, /* 2nd FDB - file to send */ - _CMIFI, /* fcode */ - "File(s) to send", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nolinks, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - mlist ? &cm : &fl - ); - cmfdbi(&fl, /* 3rd FDB - command to send from */ - _CMFLD, /* fcode */ - "Command", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - &cm - ); - cmfdbi(&cm, /* 4th FDB - Confirmation */ - _CMCFM, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - NULL, - NULL, - NULL - ); - - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - debug(F101,"xsend cmfdb","",x); - if (x < 0) /* Error */ - goto xsendx; /* or reparse needed */ - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; -/* - They gave a switch, but let's see how they terminated it. - If they ended it with : or =, then we must parse a value. - If they ended it with anything else, then we must NOT parse a value. -*/ - c = cmgbrk(); /* Get break character */ - getval = (c == ':' || c == '='); /* to see how they ended the switch */ - if (getval && !(cmresult.kflags & CM_ARG)) { - printf("?This switch does not take arguments\n"); - x = -9; - goto xsendx; - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - x = -9; - goto xsendx; - } - n = cmresult.nresult; /* Numeric result = switch value */ - debug(F101,"xsend switch","",n); - - switch (n) { /* Process the switch */ - case SND_CMD: /* These take no args */ - if (nopush) { - printf("?Sorry, system command access is disabled\n"); - x = -9; - goto xsendx; - } -#ifdef PIPESEND - else if (sndfilter) { - printf( -"?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n"); - x = -9; - goto xsendx; - } -#endif /* PIPESEND */ - sw.hlpmsg = "Command, or switch"; /* Change help message */ - pv[n].ival = 1; /* Just set the flag */ - pv[SND_ARR].ival = 0; - break; - - case SND_REC: /* /RECURSIVE */ - recursive = 2; /* Set the real variable */ - pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */ - pv[n].ival = 1; /* Just set the flag */ - break; - - case SND_RES: /* /RECOVER (resend) */ - pv[SND_ARR].ival = 0; - pv[SND_BIN].ival = 1; /* Implies /BINARY */ - case SND_NOB: /* /NOBACKUP */ - case SND_DEL: /* /DELETE */ - case SND_SHH: /* /QUIET */ - pv[n].ival = 1; /* Just set the flag */ - break; - -#ifdef UNIXOROSK -/* Like recursive, these are set immediately because they affect cmifi() */ - case SND_DOT: /* /DOTFILES */ - matchdot = 1; - break; - case SND_NOD: /* /NODOTFILES */ - matchdot = 0; - break; -#endif /* UNIXOROSK */ - - /* File transfer modes - each undoes the others */ - - case SND_BIN: /* Binary */ - case SND_TXT: /* Text */ - case SND_IMG: /* Image */ - case SND_LBL: /* Labeled */ - pv[SND_BIN].ival = 0; - pv[SND_TXT].ival = 0; - pv[SND_IMG].ival = 0; - pv[SND_LBL].ival = 0; - pv[n].ival = 1; - break; - -#ifdef CKSYMLINK - case SND_LNK: - case SND_NLK: - nolinks = (n == SND_NLK) ? 2 : 0; - cmfdbi(&sf, /* Redo cmifi() */ - _CMIFI, /* fcode */ - "File(s) to send", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nolinks, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - mlist ? &cm : &fl - ); - break; -#endif /* CKSYMLINK */ - - case SND_EXC: /* Excludes */ - if (!getval) break; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Pattern required\n"); - x = -9; - } - goto xsendx; - } - if (pv[n].sval) free(pv[n].sval); - y = strlen(s); - if (y > 256) { - printf("?Pattern too long - 256 max\n"); - x = -9; - goto xsendx; - } - pv[n].sval = malloc(y+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - break; - - case SND_MOV: /* MOVE after */ - case SND_REN: /* RENAME after */ - if (!getval) break; - if ((x = cmfld(n == SND_MOV ? - "device and/or directory for source file after sending" : - "new name for source file after sending", - "", - &s, - n == SND_MOV ? xxstring : NULL - )) < 0) { - if (x == -3) { - printf("%s\n", n == SND_MOV ? - "?Destination required" : - "?New name required" - ); - x = -9; - } - goto xsendx; - } - if (pv[n].sval) free(pv[n].sval); - s = brstrip(s); - y = strlen(s); - if (y > 0) { - pv[n].sval = malloc(y+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - } - break; - - case SND_SMA: /* Smaller / larger than */ - case SND_LAR: - if (!getval) break; - if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0) - goto xsendx; - pv[n].ival = y; - break; - - case SND_AFT: /* Send /AFTER:date-time */ - case SND_BEF: /* Send /BEFORE:date-time */ - case SND_NAF: /* Send /NOT-AFTER:date-time */ - case SND_NBE: /* Send /NOT-BEFORE:date-time */ - if (!getval) break; - if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) { - if (x == -3) { - printf("?Date-time required\n"); - x = -9; - } - goto xsendx; - } - if (pv[n].sval) free(pv[n].sval); - pv[n].sval = malloc((int)strlen(s)+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - break; - - case SND_MAI: /* Send as mail (= MAIL) */ -#ifdef IKSD - if (inserver && !ENABLED(en_mai)) { - printf("?Sorry, sending files as mail is disabled\n"); - return(-9); - } -#endif /* IKSD */ - pv[n].ival = 1; - if (!getval) break; - if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?address required\n"); - x = -9; - } - goto xsendx; - } - s = brstrip(s); - if (pv[n].sval) free(pv[n].sval); - pv[n].sval = malloc((int)strlen(s)+1); - if (pv[n].sval) - strcpy(pv[n].sval,s); /* safe */ - break; - - case SND_PRI: /* Send to be printed (REMOTE PRINT) */ -#ifdef IKSD - if (inserver && !ENABLED(en_mai)) { - printf("?Sorry, sending files for printing is disabled\n"); - return(-9); - } -#endif /* IKSD */ - pv[n].ival = 1; - if (!getval) break; - if ((x = cmfld("Print options","",&s,xxstring)) < 0) - if (x != -3) goto xsendx; - s = brstrip(s); - if (pv[n].sval) free(pv[n].sval); - pv[n].sval = malloc((int)strlen(s)+1); - if (pv[n].sval) - strcpy(pv[n].sval,s); /* safe */ - break; - - case SND_ASN: /* As-name */ - debug(F101,"xsend /as-name getval","",getval); - if (!getval) break; - if ((x = cmfld("Name to send under","",&s,NULL)) < 0) { - if (x == -3) { - printf("?name required\n"); - x = -9; - } - goto xsendx; - } - s = brstrip(s); - if ((y = strlen(s)) > 0) { - if (pv[n].sval) free(pv[n].sval); - pv[n].sval = malloc(y+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - } - break; - - case SND_STA: /* Starting position (= PSEND) */ - if (!getval) break; - if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0) - goto xsendx; - pv[n].ival = y; - break; - - case SND_PRO: /* Protocol to use */ - if (!getval) break; - if ((x = cmkey(protos,nprotos,"File-transfer protocol","", - xxstring)) < 0) { - if (x == -3) { - printf("?name of protocol required\n"); - x = -9; - } - goto xsendx; - } - pv[n].ival = x; - break; - -#ifdef PIPESEND - case SND_FLT: /* Filter */ - debug(F101,"xsend /filter getval","",getval); - if (!getval) break; - if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) { - if (x == -3) - s = ""; - else - goto xsendx; - } - if (*s) s = brstrip(s); - y = strlen(s); - for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */ - if (s[x] != '\\') continue; - if (s[x+1] == 'v') break; - } - if (x == y) { - printf( - "?Filter must contain a replacement variable for filename.\n" - ); - x = -9; - goto xsendx; - } - pv[n].ival = 1; - if (pv[n].sval) { - free(pv[n].sval); - pv[n].sval = NULL; - } - if ((y = strlen(s)) > 0) { - if ((pv[n].sval = malloc(y+1))) - strcpy(pv[n].sval,s); /* safe */ - } - break; -#endif /* PIPESEND */ - - case SND_PTH: /* Pathnames */ - if (!getval) { - pv[n].ival = PATH_REL; - break; - } - if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0) - goto xsendx; - pv[n].ival = x; - break; - - case SND_NAM: /* Filenames */ - if (!getval) break; - if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0) - goto xsendx; - debug(F101,"xsend /filenames","",x); - pv[n].ival = x; - break; - -#ifdef CALIBRATE - case SND_CAL: /* /CALIBRATE */ - if (getval) { - if ((x = cmnum("number of Kbytes to send", - "1024",10,&y,xxstring)) < 0) - goto xsendx; - } else - y = 1024; - pv[n].ival = y; - pv[SND_ARR].ival = 0; - break; -#endif /* CALIBRATE */ - - case SND_FIL: /* Name of file containing filnames */ - if (!getval) break; - if ((x = cmifi("Name of file containing list of filenames", - "",&s,&y,xxstring)) < 0) { - if (x == -3) { - printf("?Filename required\n"); - x = -9; - } - goto xsendx; - } else if (y) { - printf("?Wildcards not allowed\n"); - x = -9; - goto xsendx; - } - if (pv[n].sval) - free(pv[n].sval); - if (s) if (*s) { - if ((pv[n].sval = malloc((int)strlen(s)+1))) { - strcpy(pv[n].sval,s); - pv[n].ival = 1; - pv[SND_ARR].ival = 0; - } - } - break; - -#ifndef NOSPL - case SND_ARR: /* SEND /ARRAY: */ - if (!getval) break; - ap = NULL; - if ((x = cmfld("Array name (a single letter will do)", - "", - &s, - NULL - )) < 0) { - if (x == -3) - break; - else - return(x); - } - if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) { - printf("?Bad array: %s\n",s); - return(-9); - } - if (!(ap = a_ptr[x])) { - printf("?No such array: %s\n",s); - return(-9); - } - pv[n].ival = 1; - pv[SND_CMD].ival = 0; /* Undo any conflicting ones... */ - pv[SND_RES].ival = 0; - pv[SND_CAL].ival = 0; - pv[SND_FIL].ival = 0; - arrayx = x; - break; -#endif /* NOSPL */ - - case SND_XPA: /* /TRANSPARENT */ - pv[n].ival = 1; - break; - - case SND_TYP: /* Only files of given type */ - if (!getval) break; - if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0) - goto xsendx; - pv[n].ival = (x == 2) ? -1 : x; - break; - - default: - printf("?Unexpected switch value - %d\n",cmresult.nresult); - x = -9; - goto xsendx; - } - } - debug(F101,"xsend cmresult fcode","",cmresult.fcode); - -#ifdef COMMENT - /* List switch parsing results in debug log */ - for (i = 0; i <= SND_MAX; i++) { - ckmakmsg(line,LINBUFSIZ,"xsend switch ",ckitoa(i),NULL,NULL); - debug(F111,line, pv[i].sval, pv[i].ival); - } -#endif /* COMMENT */ - -/* Now we have all switches, plus maybe a filename or command, or nothing */ - -#ifdef PIPESEND - if (protocol != PROTO_K && pv[SND_CMD].ival > 0) { - printf("?Sorry, %s works only with Kermit protocol\n", - (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND"); - x = -9; - goto xsendx; - } - if (pv[SND_RES].ival > 0 || /* /RECOVER */ - pv[SND_STA].ival > 0) { /* or /STARTING */ - if (sndfilter || pv[SND_FLT].ival > 0) { - printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n"); - x = -9; - goto xsendx; - } - } -#endif /* PIPESEND */ - - cmarg = ""; - cmarg2 = ""; - line[0] = NUL; - s = line; - wild = 0; - - switch (cmresult.fcode) { /* How did we get out of switch loop */ - case _CMIFI: /* Input filename */ - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */ - if (pv[SND_ARR].ival > 0) - cmarg2 = line; - else - wild = cmresult.nresult; /* Wild flag */ - if (!recursive && !wild) - nolinks = 0; - break; - case _CMFLD: /* Field */ - /* Only allowed with /COMMAND and /ARRAY */ - if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) { -#ifdef CKROOT - if (ckrooterr) - printf("?Off limits: %s\n",cmresult.sresult); - else -#endif /* CKROOT */ - printf("?%s - \"%s\"\n", - iswild(cmresult.sresult) ? - "No files match" : "File not found", - cmresult.sresult - ); - x = -9; - goto xsendx; - } - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - if (pv[SND_ARR].ival > 0) - cmarg2 = line; - break; - case _CMCFM: /* Confirmation */ - /* s = ""; */ - confirmed = 1; - break; - default: - printf("?Unexpected function code: %d\n",cmresult.fcode); - x = -9; - goto xsendx; - } - debug(F110,"xsend string",s,0); - debug(F101,"xsend confirmed","",confirmed); - - /* Save and change protocol and transfer mode */ - /* Global values are restored in main parse loop */ - - g_proto = protocol; /* Save current global protocol */ - g_urpsiz = urpsiz; - g_spsizf = spsizf; - g_spsiz = spsiz; - g_spsizr = spsizr; - g_spmax = spmax; - g_wslotr = wslotr; - g_prefixing = prefixing; - g_fncact = fncact; - g_fncnv = fncnv; - g_fnspath = fnspath; - g_fnrpath = fnrpath; - g_xfrxla = xfrxla; - - if (pv[SND_PRO].ival > -1) { /* Change according to switch */ - protocol = pv[SND_PRO].ival; - if (ptab[protocol].rpktlen > -1) /* copied from initproto() */ - urpsiz = ptab[protocol].rpktlen; - if (ptab[protocol].spktflg > -1) - spsizf = ptab[protocol].spktflg; - if (ptab[protocol].spktlen > -1) { - spsiz = ptab[protocol].spktlen; - if (spsizf) - spsizr = spmax = spsiz; - } - if (ptab[protocol].winsize > -1) - wslotr = ptab[protocol].winsize; - if (ptab[protocol].prefix > -1) - prefixing = ptab[protocol].prefix; - if (ptab[protocol].fnca > -1) - fncact = ptab[protocol].fnca; - if (ptab[protocol].fncn > -1) - fncnv = ptab[protocol].fncn; - if (ptab[protocol].fnsp > -1) - fnspath = ptab[protocol].fnsp; - if (ptab[protocol].fnrp > -1) - fnrpath = ptab[protocol].fnrp; - } - debug(F101,"xsend protocol","",protocol); - - if (pv[SND_NOB].ival > -1) { /* /NOBACKUP (skip backup file) */ - g_skipbup = skipbup; - skipbup = 1; - } - if (pv[SND_REC].ival > 0) /* /RECURSIVE */ - recursive = 2; - - if (pv[SND_TYP].ival > -1) { /* /TYPE */ - xfiletype = pv[SND_TYP].ival; - if (xfiletype == 2) - xfiletype = -1; - } - g_binary = binary; /* Save global transfer mode */ -#ifdef PATTERNS - g_patterns = patterns; /* Save FILE PATTERNS setting */ -#endif /* PATTERNS */ - if (pv[SND_BIN].ival > 0) { /* Change according to switch */ - /* If they said /BINARY they mean /BINARY */ - patterns = 0; /* So no pattern-based switching */ - g_xfermode = xfermode; /* or automatic transfer mode */ - xfermode = XMODE_M; - binary = XYFT_B; - debug(F101,"doxsend /BINARY xfermode","",xfermode); - } else if (pv[SND_TXT].ival > 0) { /* Ditto for /TEXT */ - patterns = 0; - g_xfermode = xfermode; - xfermode = XMODE_M; - binary = XYFT_T; - debug(F101,"doxsend /TEXT xfermode","",xfermode); - } else if (pv[SND_IMG].ival > 0) { -#ifdef VMS - binary = XYFT_I; -#else - binary = XYFT_B; -#endif /* VMS */ - } -#ifdef CK_LABELED - else if (pv[SND_LBL].ival > 0) { - binary = XYFT_L; - } -#endif /* CK_LABELED */ - debug(F101,"xsend binary","",binary); - - if (pv[SND_XPA].ival > 0) /* /TRANSPARENT */ - xfrxla = 0; /* Don't translate character sets */ - - /* Check for legal combinations of switches, filenames, etc */ - -#ifdef PIPESEND - if (pv[SND_CMD].ival > 0) { /* COMMAND - strip any braces */ - debug(F110,"SEND /COMMAND before stripping",s,0); - s = brstrip(s); - debug(F110,"SEND /COMMAND after stripping",s,0); - if (!*s) { - printf("?Sorry, a command to send from is required\n"); - x = -9; - goto xsendx; - } - cmarg = s; - } -#endif /* PIPESEND */ - -/* Set up /MOVE and /RENAME */ - - if (pv[SND_DEL].ival > 0 && - (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) { - printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n"); - x = -9; - goto xsendx; - } -#ifdef CK_TMPDIR - if (pv[SND_MOV].ival > 0) { - int len; - char * p = pv[SND_MOV].sval; -#ifdef CK_LOGIN - if (isguest) { - printf("?Sorry, /MOVE-TO not available to guests\n"); - x = -9; - goto xsendx; - } -#endif /* CK_LOGIN */ - len = strlen(p); - if (!isdir(p)) { /* Check directory */ -#ifdef CK_MKDIR - char * s = NULL; - s = (char *)malloc(len + 4); - if (s) { - strcpy(s,p); /* safe */ -#ifdef datageneral - if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; } -#else - if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; } -#endif /* datageneral */ - s[len++] = 'X'; - s[len] = NUL; - x = zmkdir(s); - free(s); - if (x < 0) { - printf("?Can't create \"%s\"\n",p); - x = -9; - goto xsendx; - } - } -#else - printf("?Directory \"%s\" not found\n",p); - x = -9; - goto xsendx; -#endif /* CK_MKDIR */ - } - zfnqfp(p,LINBUFSIZ,tmpbuf); - makestr(&snd_move,tmpbuf); - } -#endif /* CK_TMPDIR */ - - if (pv[SND_REN].ival > 0) { /* /RENAME */ - char * p = pv[SND_REN].sval; -#ifdef CK_LOGIN - if (isguest) { - printf("?Sorry, /RENAME-TO not available to guests\n"); - x = -9; - goto xsendx; - } -#endif /* CK_LOGIN */ - if (!p) p = ""; - if (!*p) { - printf("?New name required for /RENAME\n"); - x = -9; - goto xsendx; - } - p = brstrip(p); -#ifndef NOSPL - /* If name given is wild, rename string must contain variables */ - if (wild) { - char * s = tmpbuf; - x = TMPBUFSIZ; - zzstring(p,&s,&x); - if (!strcmp(tmpbuf,p)) { - printf( - "?/RENAME for file group must contain variables such as \\v(filename)\n" - ); - x = -9; - goto xsendx; - } - } -#endif /* NOSPL */ - makestr(&snd_rename,p); - } - -/* Handle /RECOVER and /START */ - -#ifdef CK_RESEND - if (pv[SND_RES].ival > 0 && binary != XYFT_B && !filepeek -#ifdef PATTERNS - && !patterns -#else -#ifdef VMS -/* VMS sets text/binary automatically later when it opens the file */ - && 0 -#endif /* VMS */ -#endif /* PATTERNS */ - ) { - printf("?Sorry, /BINARY required\n"); - x = -9; - goto xsendx; - } - if (pv[SND_STA].ival > 0) { /* /START */ - if (wild) { - printf("?Sorry, wildcards not permitted with /START\n"); - x = -9; - goto xsendx; - } - if (sizeof(int) < 4) { - printf("?Sorry, this command needs 32-bit integers\n"); - x = -9; - goto xsendx; - } -#ifdef CK_XYZ - if (protocol != PROTO_K) { - printf("?Sorry, SEND /START works only with Kermit protocol\n"); - x = -9; - goto xsendx; - } -#endif /* CK_XYZ */ - } -#ifdef CK_XYZ - if (pv[SND_RES].ival > 0) { - if (protocol != PROTO_K && protocol != PROTO_Z) { - printf( - "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n" - ); - x = -9; - goto xsendx; - } - } -#endif /* CK_XYZ */ -#endif /* CK_RESEND */ - - if (protocol == PROTO_K) { - if ((pv[SND_MAI].ival > 0 || /* MAIL */ - pv[SND_PRI].ival > 0 || /* PRINT */ - pv[SND_RES].ival > 0 /* RESEND */ - ) && - (!atdiso || !atcapr)) { /* Disposition attribute off? */ - printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n"); - x = -9; - goto xsendx; - } - } - -#ifdef CK_XYZ - if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) { - printf( -"Sorry, you can only send one file at a time with XMODEM protocol\n" - ); - x = -9; - goto xsendx; - } -#endif /* CK_XYZ */ - - if (!confirmed) { /* CR not typed yet, get more fields */ - char *m; - if (mlist) { /* MSEND or MMOVE */ - nfils = 0; /* We already have the first one */ -#ifndef NOMSEND - msfiles[nfils++] = line; /* Store pointer */ - lp = line + (int)strlen(line) + 1; /* Point past it */ - debug(F111,"xsend msend",msfiles[nfils-1],nfils-1); - while (1) { /* Get more filenames */ - char *p; - if ((x = cmifi("Names of files to send, separated by spaces", - "", &s,&y,xxstring)) < 0) { - if (x != -3) - goto xsendx; - if ((x = cmcfm()) < 0) - goto xsendx; - break; - } - msfiles[nfils++] = lp; /* Got one, count it, point to it, */ - p = lp; /* remember pointer, */ - while ((*lp++ = *s++)) /* and copy it into buffer */ - if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */ - printf("?MSEND list too long\n"); - line[0] = NUL; - x = -9; - goto xsendx; - } - debug(F111,"xsend msend",msfiles[nfils-1],nfils-1); - if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */ -#ifdef ZFNQFP - zfnqfp(p,TMPBUFSIZ,tmpbuf); - p = tmpbuf; -#endif /* ZFNQFP */ - if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) { - strcat(fspec,p); /* safe */ - strcat(fspec," "); /* safe */ - } else -#ifdef COMMENT - printf("WARNING - \\v(filespec) buffer overflow\n"); -#else - debug(F101,"doxsend filespec buffer overflow","",0); -#endif /* COMMENT */ - } -#endif /* NOMSEND */ - } else { /* Regular SEND */ - char *p; int y; - nfils = -1; - if (pv[SND_MAI].ival > 0) - m = (pv[SND_MAI].sval) ? - "e-mail address (optional)" : - "e-mail address (required)"; - else if (pv[SND_PRI].ival > 0) - m = "printer options (optional)"; - else if (wild) - m = -"\nOptional as-name template containing replacement variables \ -like \\v(filename)"; - else - m = "Optional name to send it with"; - if ((x = cmtxt(m,"",&p,NULL)) < 0) - goto xsendx; - if (!p) p = ""; - if (*p) { /* If some text was given... */ - p = brstrip(p); /* Replace /AS-NAME: value if any */ - if ((y = strlen(p)) > 0) { - if (pv[SND_MAI].ival > 0) { - makestr(&pv[SND_MAI].sval, p); - } else { - if (pv[SND_ASN].sval) free(pv[SND_ASN].sval); - pv[SND_ASN].sval = malloc(y+1); - if (pv[SND_ASN].sval) { - strcpy(pv[SND_ASN].sval,p); /* safe */ - pv[SND_ASN].ival = 1; - } - } - } - } - } - } - /* Set cmarg2 from as-name, however we got it. */ - - if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) { - int x; - x = strlen(line); - ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1); - cmarg2 = line+x+2; - debug(F110,"doxsend cmarg2",cmarg2,0); - } - -#ifndef NOFRILLS - if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) { - printf("Sorry, /MAIL and /PRINT are conflicting options\n"); - x = -9; - goto xsendx; - } - n = 0; /* /MAIL or /PRINT? */ - if (pv[SND_MAI].ival > 0) - n = SND_MAI; - else if (pv[SND_PRI].ival > 0) - n = SND_PRI; - if (n) { /* Yes... */ -#ifdef DEBUG - char * p; - if (n == SND_MAI) - p = "/MAIL"; - else - p = "/PRINT"; - debug(F111,"xsend",p,n); -#endif /* DEBUG */ -#ifdef CK_XYZ - if (protocol != PROTO_K) { - printf("Sorry, %s available only with Kermit protocol\n", - (n == SND_MAI) ? "/MAIL" : "/PRINT" - ); - x = -9; - goto xsendx; - } -#endif /* CK_XYZ */ - debug(F101,"xsend print/mail wild","",wild); - *optbuf = NUL; /* Wipe out any old options */ - s = pv[n].sval; /* mail address or print switch val */ - if (!s) s = ""; - debug(F110,"doxsend mail address or printer options",s,0); - if (n == SND_MAI && !*s) { - printf("?E-mail address required\n"); - x = -9; - goto xsendx; - } else if ((int)strlen(s) > 94) { /* Ensure legal size */ - printf("?%s too long\n", - (n == SND_MAI) ? - "E-mail address" : - "Print option string" - ); - x = -9; - goto xsendx; - } - ckstrncpy(optbuf,s,OPTBUFLEN); /* OK, copy to option buffer */ - cmarg = line; /* File to send */ - if (n == SND_MAI) { - debug(F110,"xsend mailing",cmarg,0); - debug(F110,"xsend address:",optbuf,0); - rmailf = 1; - } else { - debug(F110,"xsend printing",cmarg,0); - debug(F110,"xsend options",optbuf,0); - rprintf = 1; - } - } -#endif /* NOFRILLS */ - -#ifdef CALIBRATE - if (pv[SND_CAL].ival > 0) { /* Handle /CALIBRATE */ - if (confirmed) { - calibrate = pv[SND_CAL].ival * 1024L; - sndsrc = -9; - nfils = 1; - wild = 0; -#ifndef NOMSEND - addlist = 0; -#endif /* NOMSEND */ - ckstrncpy(line,"CALIBRATION",LINBUFSIZ); - s = cmarg = line; - if (!cmarg2) cmarg2 = ""; - debug(F110,"doxsend cmarg2 calibrate",cmarg2,0); - } else if (line[0]) { - calibrate = 0L; - pv[SND_CAL].ival = 0L; - } - } -#endif /* CALIBRATE */ - - if (pv[SND_FIL].ival > 0) { - if (confirmed && !calibrate) { - if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) { - debug(F110,"xsend can't open",pv[SND_FIL].sval,0); - printf("?Failure to open %s\n",filefile); - x = -9; - goto xsendx; - } - makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */ - debug(F110,"xsend opened",filefile,0); - wild = 1; - } - } - - /* SEND alone... */ - -#ifndef NOSPL - if (confirmed && pv[SND_ARR].ival > 0) { - if (!*cmarg2) { - sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE); - cmarg2 = sndxnam; - } - cmarg = ""; - goto sendend; - } -#endif /* NOSPL */ - - if (confirmed && !line[0] && !filefile && !calibrate) { -#ifndef NOMSEND - if (filehead) { /* OK if we have a SEND-LIST */ - nfils = filesinlist; - sndsrc = nfils; /* Like MSEND */ - addlist = 1; /* But using a different list... */ - filenext = filehead; - goto sendend; - } -#endif /* NOMSEND */ - printf("?Filename required but not given\n"); - x = -9; - goto xsendx; - } - - /* Not send-list or array */ - -#ifndef NOMSEND - addlist = 0; /* Don't use SEND-LIST. */ - filenext = NULL; -#endif /* NOMSEND */ - - if (mlist) { /* MSEND or MMOVE */ -#ifndef NOMSEND - cmlist = msfiles; /* List of files to send */ - sndsrc = nfils; - cmarg2 = ""; - sendstart = 0L; -#endif /* NOMSEND */ -#ifdef PIPESEND - pipesend = 0; -#endif /* PIPESEND */ - } else if (filefile) { /* File contains list of filenames */ - s = ""; - cmarg = ""; - cmarg2 = ""; - line[0] = NUL; - nfils = 1; - sndsrc = 1; - - } else if (!calibrate && pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) { - - nfils = sndsrc = -1; /* Not MSEND, MMOVE, /LIST, or /ARRAY */ - if ( /* or /COMMAND */ - -#ifndef NOFRILLS - !rmailf && !rprintf /* Not MAIL or PRINT */ -#else - 1 -#endif /* NOFRILLS */ - ) { - int y = 1; - if (!wild) - y = zchki(s); - if (y < 0) { - printf("?Read access denied - \"%s\"\n", s); - x = -9; - goto xsendx; - } - if (s != line) /* We might already have done this. */ - ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */ - else - debug(F110,"doxsend line=s",line,0); - cmarg = line; /* File to send */ - } - zfnqfp(cmarg,fspeclen,fspec); - } - if (!mlist) { /* For all but MSEND... */ -#ifdef PIPESEND - if (pv[SND_CMD].ival > 0) /* /COMMAND sets pipesend flag */ - pipesend = 1; - debug(F101,"xsend /COMMAND pipesend","",pipesend); - if (pipesend && filefile) { - printf("?Invalid switch combination\n"); - x = -9; - goto xsendx; - } -#endif /* PIPESEND */ - -#ifndef NOSPL - /* If as-name given and filespec is wild, as-name must contain variables */ - debug(F111,"doxsend cmarg2 wild",cmarg2,wild); - if (wild && *cmarg2) { - char * s = tmpbuf; - x = TMPBUFSIZ; - zzstring(cmarg2,&s,&x); - if (!strcmp(tmpbuf,cmarg2)) { - printf( - "?As-name for file group must contain variables such as \\v(filename)\n" - ); - x = -9; - goto xsendx; - } - } -#endif /* NOSPL */ - - /* Strip braces from as-name */ - debug(F110,"xsend cmarg2 before stripping",cmarg2,0); - cmarg2 = brstrip(cmarg2); - debug(F110,"xsend filename",cmarg,0); - debug(F110,"xsend as-name",cmarg2,0); - - /* Copy as-name to a safe place */ - - if (asnbuf) { - free(asnbuf); - asnbuf = NULL; - } - if ((y = strlen(cmarg2)) > 0) { - asnbuf = (char *) malloc(y + 1); - if (asnbuf) { - strcpy(asnbuf,cmarg2); /* safe */ - cmarg2 = asnbuf; - } else cmarg2 = ""; - } - -#ifdef CK_RESEND - debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival); - if (pv[SND_STA].ival > -1) { /* /START position */ - if (wild) { - printf("?/STARTING-AT may not be used with multiple files.\n"); - x = -9; - goto xsendx; - } else - sendstart = pv[SND_STA].ival; - } else - sendstart = 0L; - debug(F101,"xsend /STARTING","",sendstart); -#endif /* CK_RESEND */ - } - -sendend: /* Common successful exit */ - moving = 0; - if (pv[SND_SHH].ival > 0) { /* SEND /QUIET... */ - g_displa = fdispla; - fdispla = 0; - debug(F101,"xsend display","",fdispla); - } - -#ifndef NOSPL /* SEND /ARRAY... */ - if (pv[SND_ARR].ival > 0) { - if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */ - if (range[0] == -1) /* If low end of range not specified */ - range[0] = 1; /* default to 1 */ - if (range[1] == -1) /* If high not specified */ - range[1] = a_dim[arrayx]; /* default to size of array */ - if ((range[0] < 0) || /* Check range */ - (range[0] > a_dim[arrayx]) || - (range[1] < range[0]) || - (range[1] > a_dim[arrayx])) { - printf("?Bad array range - [%d:%d]\n",range[0],range[1]); - x = -9; - goto xsendx; - } - sndarray = ap; /* Array pointer */ - sndxin = arrayx; /* Array index */ - sndxlo = range[0]; /* Array range */ - sndxhi = range[1]; - sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE); - -#ifdef COMMENT - printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */ - (sndxin == 1) ? 64 : sndxin + ARRAYBASE); - printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi); - printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2); - while ((x = agnbyte()) > -1) { - putchar((char)x); - } - return(1); -#endif /* COMMENT */ - } -#endif /* NOSPL */ - - if (pv[SND_ARR].ival < 1) { /* File selection & disposition... */ - - if (pv[SND_DEL].ival > 0) /* /DELETE was specified */ - moving = 1; - debug(F101,"xsend /DELETE","",moving); - if (pv[SND_AFT].ival > 0) /* Copy SEND criteria */ - ckstrncpy(sndafter,pv[SND_AFT].sval,19); - if (pv[SND_BEF].ival > 0) - ckstrncpy(sndbefore,pv[SND_BEF].sval,19); - if (pv[SND_NAF].ival > 0) - ckstrncpy(sndnafter,pv[SND_NAF].sval,19); - if (pv[SND_NBE].ival > 0) - ckstrncpy(sndnbefore,pv[SND_NBE].sval,19); - if (pv[SND_EXC].ival > 0) - makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT); - if (pv[SND_SMA].ival > -1) - sndsmaller = pv[SND_SMA].ival; - if (pv[SND_LAR].ival > -1) - sndlarger = pv[SND_LAR].ival; - if (pv[SND_NAM].ival > -1) { - g_fncnv = fncnv; /* Save global value */ - fncnv = pv[SND_NAM].ival; - debug(F101,"xsend fncnv","",fncnv); - } - if (pv[SND_PTH].ival > -1) { - g_spath = fnspath; /* Save global values */ - fnspath = pv[SND_PTH].ival; -#ifndef NZLTOR - if (fnspath != PATH_OFF) { - g_fncnv = fncnv; /* Bad bad... */ - fncnv = XYFN_C; - } -#endif /* NZLTOR */ - debug(F101,"xsend fnspath","",fnspath); - debug(F101,"xsend fncnv","",fncnv); - } - } - -#ifdef PIPESEND - if (pv[SND_FLT].ival > 0) { - makestr(&sndfilter,pv[SND_FLT].sval); - debug(F110,"xsend /FILTER", sndfilter, 0); - } -#endif /* PIPESEND */ - -#ifdef CK_APC -/* MOVE not allowed in APCs */ - if (moving && - (apcactive == APC_LOCAL || apcactive == APC_REMOTE) - && !(apcstatus & APC_UNCH)) - return(success = 0); -#endif /* CK_APC */ -#ifdef IKS_OPTION - if ( -#ifdef CK_XYZ - protocol == PROTO_K && -#endif /* CK_XYZ */ - !iks_wait(KERMIT_REQ_START,1)) { - printf("?A Kermit Server is not available to process this command.\n"); - printf("?Start a RECEIVE command to complement this command.\n"); - } -#endif /* IKS_OPTION */ - -#ifdef IKSD -#ifdef CK_LOGIN - if (moving && inserver && isguest) { - printf("?File deletion not allowed for guests.\n"); - return(-9); - } -#endif /* CK_LOGIN */ -#endif /* IKSD */ - - sstate = 's'; /* Set start state to SEND */ - sndcmd = 1; -#ifdef CK_RESEND - if (pv[SND_RES].ival > 0) /* Send sendmode appropriately */ - sendmode = SM_RESEND; - else if (pv[SND_STA].ival > 0) - sendmode = SM_PSEND; - else -#endif /* CK_RESEND */ - if (mlist) - sendmode = SM_MSEND; - else - sendmode = SM_SEND; -#ifdef MAC - what = W_SEND; - scrcreate(); -#endif /* MAC */ - if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */ - displa = 1; /* turn on file transfer display */ - } - x = 0; - - xsendx: /* Common exit, including failure */ - debug(F101,"doxsend sndsrc","",sndsrc); - for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */ - if (pv[i].sval) - free(pv[i].sval); - } - return(x); -} -#endif /* NOXFER */ - -#ifndef NOLOCAL -/* D O X C O N N -- CONNECT command parsing with switches */ - -#ifdef XLIMITS -#define XLIMORTRIGGER -#else -#ifdef CK_TRIGGER -#define XLIMORTRIGGER -#endif /* CK_TRIGGER */ -#endif /* XLIMITS */ - -#ifdef CKTIDLE -int tt_idlelimit = 0; /* Terminal idle limit */ -int tt_idleact = IDLE_RET; /* Terminal idle action */ -#endif /* CKTIDLE */ - -#ifdef OS2 /* K95 only: */ -extern int - tt_idlesnd_tmo; /* Idle interval */ -int tt_timelimit = 0; /* Time limit, 0 = none */ -extern char * /* Parse results - strings: */ - tt_idlesnd_str; /* Idle string */ -#endif /* OS2 */ - -#ifdef CK_TRIGGER -extern char *tt_trigger[]; -extern CHAR *tt_trmatch[]; -extern char *triggerval; -static char *g_tt_trigger[TRIGGERS]; -#endif /* CK_TRIGGER */ - -#ifdef OS2 -static int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */ -static int g_tt_idlelimit, g_tt_saved = 0; -static char * g_tt_idlesnd_str; /* global settings */ -#endif /* OS2 */ - -static struct stringint { /* Temporary array for switch values */ - char * sval; - int ival; -} pv[CONN_MAX+1]; - -VOID -resconn() { - int i; - -#ifdef OS2 - if ( g_tt_saved ) { - tt_idlelimit = g_tt_idlelimit; - tt_idlesnd_tmo = g_tt_idlesnd_tmo; - tt_timelimit = g_tt_timelimit; - tt_idlesnd_str = g_tt_idlesnd_str; - g_tt_saved = 0; - } -#endif /* OS2 */ - -#ifdef CK_TRIGGER - for (i = 0; i < TRIGGERS; i++) - tt_trigger[i] = g_tt_trigger[i]; -#endif /* CK_TRIGGER */ - - for (i = 0; i <= CONN_MAX; i++) { /* Free malloc'd memory */ - if (pv[i].sval) - free(pv[i].sval); - pv[i].sval = NULL; - } -} - -int -doxconn(cx) int cx; { - int c, i, n; /* Workers */ - int x, y; - int getval = 0; /* Whether to get switch value */ - int async = 0; /* Make an async connect */ - struct FDB sw, cm; /* FDBs for each parse function */ - extern FILE * tfile[]; - extern char * macp[]; - -#ifdef OS2 - g_tt_idlesnd_tmo = tt_idlesnd_tmo; /* Save global settings */ - g_tt_timelimit = tt_timelimit; - g_tt_idlelimit = tt_idlelimit; - g_tt_idlesnd_str = tt_idlesnd_str; - g_tt_saved = 1; -#endif /* OS2 */ - -#ifdef CK_TRIGGER - if (!tt_trigger[0]) { /* First initialization */ - for (i = 1; i < TRIGGERS; i++) - tt_trigger[i] = NULL; - } - for (i = 0; i < TRIGGERS; i++) - g_tt_trigger[i] = tt_trigger[i]; - if (triggerval) { - free(triggerval); - triggerval = NULL; - } -#endif /* CK_TRIGGER */ - - for (i = 0; i <= CONN_MAX; i++) { /* Initialize switch values */ - pv[i].sval = NULL; /* to null pointers */ - pv[i].ival = -1; /* and -1 int values */ - } - if (cx == XXCQ) /* CQ == CONNECT /QUIETLY */ - pv[CONN_NV].ival = 1; - - /* Set up chained parse functions... */ - - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nconntab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - conntab, /* Keyword table */ - &cm /* Pointer to next FDB */ - ); - cmfdbi(&cm, /* 2nd FDB - Confirmation */ - _CMCFM, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - NULL, - NULL, - NULL - ); - - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse switch or confirmation */ - debug(F101,"doxconn cmfdb","",x); - if (x < 0) { /* Error */ - if (x == -9 || x == -2) - printf("?No switches match - \"%s\"\n",atmbuf); - goto xconnx; /* or reparse needed */ - } - if (cmresult.fcode != _CMKEY) /* Break out if not a switch */ - break; - c = cmgbrk(); /* Get break character */ - getval = (c == ':' || c == '='); /* to see how they ended the switch */ - if (getval && !(cmresult.kflags & CM_ARG)) { - printf("?This switch does not take arguments\n"); - x = -9; - goto xconnx; - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - n = cmresult.nresult; /* Numeric result = switch value */ - debug(F101,"doxconn switch","",n); - - switch (n) { /* Process the switch */ -#ifdef OS2 - case CONN_AS: /* Asynchronous */ - pv[CONN_AS].ival = 1; - pv[CONN_SY].ival = 0; - break; - case CONN_SY: /* Synchronous */ - pv[CONN_SY].ival = 1; - pv[CONN_AS].ival = 0; - break; -#endif /* OS2 */ - case CONN_NV: /* Non-verbal */ - pv[n].ival = 1; - break; -#ifdef XLIMITS - case CONN_II: /* Idle-interval */ - case CONN_IL: /* Idle-limit */ - case CONN_TL: /* Time-limit */ - if (!getval) break; - if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0) - goto xconnx; - pv[n].ival = y; - break; - case CONN_IS: /* Idle-string */ -#endif /* XLIMITS */ -#ifdef CK_TRIGGER - case CONN_TS: /* Trigger-string */ -#endif /* CK_TRIGGER */ -#ifdef XLIMORTRIGGER - if (!getval) break; - if ((x = cmfld("String (enclose in braces if it contains spaces)", - "",&s,xxstring)) < 0) { - if (x == -3) { - printf("?String required\n"); - x = -9; - } - goto xconnx; - } - if (n != CONN_TS) - s = brstrip(s); - if ((y = strlen(s)) > 0) { - if (pv[n].sval) free(pv[n].sval); - pv[n].sval = malloc(y+1); - if (pv[n].sval) { - strcpy(pv[n].sval,s); /* safe */ - pv[n].ival = 1; - } - } - break; -#endif /* XLIMORTRIGGER */ - default: - printf("?Unexpected switch value - %d\n",cmresult.nresult); - x = -9; - goto xconnx; - } - } - debug(F101,"doxconn cmresult.fcode","",cmresult.fcode); - if (cmresult.fcode != _CMCFM) { - printf("?Unexpected function code: %d\n",cmresult.fcode); - x = -9; - goto xconnx; - } - - /* Command was confirmed so we can pre-pop command level. */ - /* This is so CONNECT module won't think we're executing a script */ - /* if CONNECT was the final command in the script. */ - - if (cmdlvl > 0) - prepop(); - -#ifdef OS2 /* Make results available globally */ - if (pv[CONN_IL].ival > -1) /* Idle limit */ - tt_idlelimit = pv[CONN_IL].ival; - if (pv[CONN_II].ival > -1) /* Idle limit */ - tt_idlesnd_tmo = pv[CONN_II].ival; - if (pv[CONN_IS].sval) /* Idle string */ - if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1)) - strcpy(tt_idlesnd_str,pv[CONN_IS].sval); /* safe */ - if (pv[CONN_TL].ival > -1) /* Session limit */ - tt_timelimit = pv[CONN_TL].ival; - async = (pv[CONN_AS].ival > 0 || - pv[CONN_SY].ival <= 0 && cmdlvl == 0) ? 1 : 0; -#endif /* OS2 */ - -#ifdef CK_TRIGGER - if (pv[CONN_TS].sval) /* Trigger strings */ - makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS); - for (i = 0; i < TRIGGERS; i++) /* Trigger match pointers */ - tt_trmatch[i] = NULL; - if (triggerval) { /* Reset trigger value */ - free(triggerval); - triggerval = NULL; - } -#endif /* CK_TRIGGER */ - - x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0, async); - { - int xx; - debug(F101,"doxconn doconect returns","",x); - if ((xx = ttchk()) < 0) dologend(); - debug(F101,"doxconn ttchk returns","",xx); - } - -#ifdef CK_TRIGGER - debug(F111,"doxconn doconect triggerval",triggerval,x); -#endif /* CK_TRIGGER */ - - xconnx: - /* Back from CONNECT -- Restore global settings */ - - if (!async) - resconn(); - - success = (x > 0) ? 1 : 0; - return(x); -} -#endif /* NOLOCAL */ - -#ifdef ADDCMD -/* cx == XXADD or XXREMV */ -/* fc == ADD_BIN or ADD_TXT */ -static int -doadd(cx,fc) int cx, fc; { -#ifdef PATTERNS - char * tmp[FTPATTERNS]; - char **p = NULL; - int i, j, k, n = 0, x = 0, last; - -#endif /* PATTERNS */ - if (cx != XXADD && cx != XXREMV) { - printf("?Unexpected function code: %d\n",cx); - return(-9); - } -#ifdef PATTERNS - while (n < FTPATTERNS) { /* Collect new patterns */ - tmp[n] = NULL; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) - break; - ckstrncpy(line,s,LINBUFSIZ); - s = brstrip(line); - makestr(&(tmp[n++]),s); - } - if (x == -3) - x = cmcfm(); - if (x < 0) - goto xdoadd; - p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */ - last = 0; - for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */ - if (!p[i]) { - last = i; - break; - } - } - if (cx == XXADD) { /* Adding */ - if (last + n > FTPATTERNS) { /* Check if too many */ - printf("?Too many patterns - %d is the maximum\n", FTPATTERNS); - goto xdoadd; - } - for (i = 0; i < n; i++) { /* Copy in the new ones. */ - for (j = 0, x = 0; x == 0 && j < last ; j++ ) - x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */ - if (x == 0) - makestr(&(p[last++]),tmp[i]); - } - makestr(&(p[last]),NULL); /* Null-terminate the list */ - x = 1; - goto xdoadd; /* Done */ - } else if (cx == XXREMV) { /* Remove something(s) */ - int j, k; - if (last == 0) /* List is empty */ - goto xdoadd; /* Nothing to remove */ - for (i = 0; i < n; i++) { /* i = Patterns they typed */ - for (j = 0; j < last; j++) { /* j = Patterns in list */ - /* Change this to ckstrcmp()... */ - if (filecase) - x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */ - else - x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */ - if (x) { /* This one matches */ - makestr(&(p[j]),NULL); /* Free it */ - for (k = j; k < last; k++) /* Move the rest up */ - p[k] = p[k+1]; - p[k] = NULL; /* Erase last one */ - if (!p[k]) - break; - } - } - } - } - xdoadd: /* Common exit */ - for (i = 0; i < n; i++) - if (tmp[i]) - free(tmp[i]); - return(x); -#endif /* PATTERNS */ -} - -/* ADD SEND-LIST */ - -static int -addsend(cx) int cx; { -#ifndef NOMSEND - extern struct keytab fttab[]; - extern int nfttyp; - struct filelist * flp; - char * fmode = ""; - int xmode = 0; - int xbinary = 0; -#endif /* NOMSEND */ - -#ifdef NOMSEND - printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n"); - return(-9); -#endif /* NOMSEND */ - if (cx == XXREMV) { - printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n"); - return(-9); - } -#ifndef NOMSEND -#ifndef XYZ_INTERNAL - if (protocol != PROTO_K) { - printf("?Sorry, ADD SEND-LIST does not work with external protocols\n"); - return(-9); - } -#endif /* XYZ_INTERNAL */ - - x = cmifi("File specification to add","", &s,&y,xxstring); - if (x < 0) { - if (x == -3) { - printf("?A file specification is required\n"); - return(-9); - } else - return(x); - } - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - s = tmpbuf; - if (filesinlist == 0) /* Take care of \v(filespec) */ - fspec[0] = NUL; - zfnqfp(s,LINBUFSIZ,line); - s = line; - if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) { - strcat(fspec,s); /* safe */ - strcat(fspec," "); /* safe */ - } else - printf("WARNING - \\v(filespec) buffer overflow\n"); - - - xbinary = binary; - if ((patterns || filepeek) /* FILE PATTERNS or SCAN is ON */ -#ifdef CK_LABELED - && binary != XYFT_L /* And not if FILE TYPE LABELED */ -#endif /* CK_LABELED */ -#ifdef VMS - && binary != XYFT_I /* or FILE TYPE IMAGE */ -#endif /* VMS */ - ) { - int k, x; - x = -1; - k = scanfile(line,&x,nscanfile); - if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T; - } - fmode = gfmode(xbinary,0); - if ((x = cmkey(fttab,nfttyp, - "type of file transfer", fmode, xxstring)) < 0) - return(x); - xmode = x; - - cmarg2 = ""; - if ((x = cmfld(y ? - "\nAs-name template containing replacement variables such as \\v(filename)" : - "Name to send it with", "",&s,NULL)) < 0) - if (x != -3) - return(x); -#ifndef NOSPL - if (y && *s) { - char * p = tmpbuf; - x = TMPBUFSIZ; - zzstring(s,&p,&x); - if (!strcmp(tmpbuf,s)) { - printf( - "?As-name for file group must contain variables such as \\v(filename)\n" - ); - return(-9); - } - } -#endif /* NOSPL */ - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - cmarg2 = tmpbuf; - - if ((x = cmcfm()) < 0) - return(x); - flp = (struct filelist *) malloc(sizeof(struct filelist)); - if (flp) { - if (filetail) - filetail->fl_next = flp; - filetail = flp; - if (!filehead) - filehead = flp; - x = (int) strlen(line); /* Length of filename */ - s = (char *) malloc(x + 1); - if (s) { - strcpy(s,line); /* safe */ - flp->fl_name = s; - flp->fl_mode = xmode; - x = (int) strlen(cmarg2); /* Length of as-name */ - if (x < 1) { - flp->fl_alias = NULL; - } else { - s = (char *) malloc(x + 1); - if (s) { - strcpy(s,cmarg2); /* safe */ - flp->fl_alias = s; - } else { - printf("Sorry, can't allocate space for as-name"); - return(-9); - } - } - flp->fl_next = NULL; - filesinlist++; /* Count this node */ - return(success = 1); /* Finished adding this node */ - } else { - printf("Sorry, can't allocate space for name"); - return(-9); - } - } else { - printf("Sorry, can't allocate file list node"); - return(-9); - } -#endif /* NOMSEND */ -} -#endif /* ADDCMD */ - -#ifndef NOHTTP /* HTTP ops... */ -#ifdef TCPSOCKET -#define HTTP_GET 0 /* GET */ -#define HTTP_PUT 1 /* PUT */ -#define HTTP_POS 2 /* POST */ -#define HTTP_IDX 3 /* INDEX */ -#define HTTP_HED 4 /* HEAD */ -#define HTTP_DEL 5 /* DELETE */ -#define HTTP_CON 6 /* CONNECT */ -#define HTTP_OPN 7 /* OPEN */ -#define HTTP_CLS 8 /* CLOSE */ - -static struct keytab httptab[] = { - { "close", HTTP_CLS, 0 }, - { "connect", HTTP_CON, 0 }, - { "delete", HTTP_DEL, 0 }, - { "get", HTTP_GET, 0 }, - { "head", HTTP_HED, 0 }, - { "index", HTTP_IDX, 0 }, - { "open", HTTP_OPN, 0 }, - { "put", HTTP_PUT, 0 }, - { "post", HTTP_POS, 0 } -}; -static int nhttptab = sizeof(httptab)/sizeof(struct keytab); - -/* HTTP switches */ -#define HT_SW_AG 0 /* /AGENT */ -#define HT_SW_HD 1 /* /HEADER */ -#define HT_SW_US 2 /* /USER */ -#define HT_SW_PW 3 /* /PASSWORD */ -#define HT_SW_AR 4 /* /ARRAY */ -#define HT_SW_TP 5 /* /TOSCREEN */ - -static struct keytab httpswtab[] = { - { "/agent", HT_SW_AG, CM_ARG }, -#ifndef NOSPL - { "/array", HT_SW_AR, CM_ARG }, -#endif /* NOSPL */ - { "/header", HT_SW_HD, CM_ARG }, - { "/password", HT_SW_PW, CM_ARG }, - { "/toscreen", HT_SW_TP, 0 }, - { "/user", HT_SW_US, CM_ARG }, - { "", 0, 0 } -}; -static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1; - -/* HTTP PUT/POST switches */ -#define HT_PP_MT 0 /* /MIME-TYPE */ - -static struct keytab httpptab[] = { - { "/mime-type", HT_PP_MT, CM_ARG }, - { "", 0, 0 } -}; -static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1; - -#define HTTP_MAXHDR 8 - -static int -xdohttp(action, lfile, rf, dfile, agent, hdr, user, pass, mime, array, type) - int action; - char *lfile, *rf, *dfile, *agent, *hdr, *user, *pass, *mime, array; - int type; -/* xdohttp */ { - int i, rc = 0; - char * hdrlist[HTTP_MAXHDR]; - char rfile[CKMAXPATH+1]; - extern int httpfd; - - /* Check for a valid state to execute the command */ - if (inserver) { - printf("?The HTTP command may not be used from the IKS\r\n"); - } else if (httpfd == -1) { - if (http_reopen() < 0) - printf("?No connection\n"); - else - rc = 1; - } else { - rc = 1; - } - - /* If the command is not valid, exit with failure */ - if (rc == 0) - return(success = 0); - - if (action != HTTP_CON && rf[0] != '/') { - rfile[0] = '/'; - ckstrncpy(&rfile[1],rf,CKMAXPATH); - } else { - ckstrncpy(rfile,rf,CKMAXPATH); - } - for (i = 0; i < HTTP_MAXHDR; i++) /* Initialize header list */ - hdrlist[i] = NULL; - makelist(hdr,hdrlist,HTTP_MAXHDR); /* Make header list */ - -#ifdef BETADEBUG - for (i = 0; i < nhttptab; i++) /* Find action keyword */ - if (httptab[i].kwval == action) - break; - if (i == nhttptab) { /* Shouldn't happen... */ - printf("?Invalid action - %d\n",action); - return(0); /* Failure */ - } - - printf("HTTP action: %s\n",httptab[i].kwd); - printf(" Agent: %s\n",agent ? agent : "(null)"); - - if (hdrlist[1]) { - printf(" Header list: 1. %s\n",hdrlist[0]); - for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++) - printf("%15d. %s\n",i+1,hdrlist[i]); - } else - printf(" Header: %s\n",hdrlist[0] ? hdrlist[0] : "(null)"); - - printf(" User: %s\n",user ? user : "(null)"); -#ifdef COMMENT - printf(" Password: %s\n",pass ? pass : "(null)"); -#endif /* COMMENT */ - -#ifndef NOSPL - if (array) - printf(" Array: \\%%%c[]\n", array); - else - printf(" Array: (none)\n"); -#endif /* NOSPL */ - - if (action == HTTP_PUT || action == HTTP_POS) - printf(" Mime-type: %s\n",mime ? mime : "(null)"); - - printf(" Local file: %s\n",lfile ? lfile : "(null)"); - printf(" Remote file: %s\n",rfile ? rfile : "(null)"); - printf(" Destination file: %s\n",dfile ? dfile : "(null)"); -#endif /* BETADEBUG */ - - /* The http_xxxx() functions return 0 on success, -1 on failure */ - switch (action) { - case HTTP_CON: { - extern int ttyfd; - rc = http_connect(httpfd,agent,hdrlist,user,pass,array,rfile); - break; - } - case HTTP_DEL: - rc = http_delete(agent,hdrlist,user,pass,array,rfile); - break; - case HTTP_GET: - rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile,type); - break; - case HTTP_HED: - rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile,type); - break; - case HTTP_PUT: - rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile, - type); - break; - case HTTP_POS: - rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile, - type); - break; - case HTTP_IDX: - rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile,type); - break; - default: - rc = -1; - } - return(rc == 0 ? 1 : 0); /* Success is set by caller */ -} -#endif /* TCPSOCKET */ -#endif /* NOHTTP */ - -#ifndef NOSPL /* ARRAY ops... */ -static struct keytab arraytab[] = { - { "clear", ARR_CLR, 0 }, - { "copy", ARR_CPY, 0 }, - { "dcl", ARR_DCL, CM_INV }, - { "declare", ARR_DCL, 0 }, - { "destroy", ARR_DST, CM_INV }, - { "equate", ARR_EQU, CM_INV }, - { "link", ARR_EQU, 0 }, - { "resize", ARR_RSZ, 0 }, - { "set", ARR_SET, 0 }, -#ifndef NOSHOW - { "show", ARR_SHO, 0 }, -#endif /* NOSHOW */ - { "sort", ARR_SRT, 0 }, - { "undeclare", ARR_DST, 0 }, - { "", 0, 0 } -}; -static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1; - -#ifdef CKLEARN -static struct keytab learnswi[] = { - { "/close", 2, 0 }, - { "/off", 0, 0 }, - { "/on", 1, 0 } -}; -#endif /* CKLEARN */ - -int -arrayitoa(x) int x; { /* Array index to array letter */ - if (x == 1) - return(64); - else if (x < 0 || x > (122 - ARRAYBASE)) - return(-1); - else - return(x + ARRAYBASE); -} - -int -arrayatoi(c) int c; { /* Array letter to array index */ - if (c == 64) - c = 96; - if (c > 63 && c < 91) - c += 32; - if (c < ARRAYBASE || c > 122) - return(-1); - return(c - ARRAYBASE); -} - -static int /* Declare an array */ -dodcl(cx) int cx; { - int i, n, v, lo, hi, rc = 0; - int isdynamic = 0; - char tmpbuf[64]; - char ** p = NULL; - char tmp[64]; /* Local temporary string buffer */ - if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */ - if (y == -3) { - printf("?Array name required\n"); - return(-9); - } else return(y); - } - ckstrncpy(line,s,LINBUFSIZ); - s = line; - x = arraybounds(s,&lo,&hi); /* Check syntax and get bounds */ - debug(F111,"dodcl arraybounds",s,x); - if (x < 0) { /* Error - Maybe it's a variable */ - char * p; /* whose value is an array name */ - int n; - p = tmpbuf; - n = 63; - p[0] = NUL; - if (s[0] == CMDQ && s[1] == '&') - s++; - if (zzstring(s,&p,&n) > -1) { - s = tmpbuf; - x = arraybounds(s,&lo,&hi); - debug(F111,"dodcl arraybounds 2",s,x); - } - if (x < 0) { - printf("?Bad array name - \"%s\"\n",s); - return(-9); - } - } - debug(F101,"dodcl hi","",hi); - debug(F101,"dodcl lo","",lo); - debug(F101,"dodcl lo+1","",lo+1); - - if (lo == -1 && hi == -1) { /* Have good array name and bounds */ - isdynamic = 1; - n = CMDBL / 5; - } else if (hi > -1) { - printf("?Segment notation not allowed in array declarations\n"); - return(-9); - } else if ((lo+1) < 0) { - debug(F101,"dodcl underflow","",lo+1); - printf("?Dimension underflow\n"); - return(-9); - } else - n = lo; - x = arrayitoa(x); - if (cx == XXUNDCL) { - n = 0; - v = 0; - if ((y = cmcfm()) < 0) - return(y); - } else { - p = (char **)malloc(sizeof(char **)*(n+1)); - if (!p) { - printf("?Memory allocation error\n"); - return(-9); - } - v = 0; /* Highest initialized member */ - p[0] = NULL; /* Element 0 */ - keepallchars = 1; - while (n > 0 && v < n) { /* Parse initializers */ - p[v+1] = NULL; - ckmakxmsg(tmp, - 64, - "Initial value for \\&", - ckctoa((char)x), - "[", - ckitoa(v+1), - "]", - NULL,NULL,NULL,NULL,NULL,NULL,NULL - ); - if ((rc = cmfld((char *)tmp,"",&s,xxstring)) < 0) { /* Get field */ - if (rc == -3) /* If answer is empty, we're done */ - break; - else /* Parse error, free temp pointers */ - goto dclx; - } - rc = 1; - if (v == 0 && !strcmp(s,"=")) /* Skip the = sign. */ - continue; - s = brstrip(s); /* Strip any braces */ - makestr(&(p[++v]),s); - } - keepallchars = 0; - if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0) - return(y); - if (isdynamic) - n = v; - } - if (dclarray((char)x,n) < 0) { /* Declare the array */ - printf("?Declare failed\n"); - goto dclx; - } - for (i = 1; i <= v; i++) { /* Add any initial values */ - tmp[0] = '&'; - ckmakmsg(&tmp[1],63,ckctoa((char)x),"[",ckitoa(i),"]"); - if (addmac(tmp,p[i]) < 0) { - printf("Array initialization error: %s %s\n",tmp,p[i]); - rc = -9; - goto dclx; - } - } - dclx: - if (p) { - for (i = 1; i <= v; i++) - if (p[i]) free(p[i]); - free((char *)p); - } - debug(F101,"DCL rc","",rc); - return(success = rc); -} - -static int -rszarray() { - int i, x, y, n, lo, hi, islink = -1; - char c, * s, ** ap = NULL; - if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */ - if (x == -3) { - printf("?Array name required\n"); - return(-9); - } else return(x); - } - ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */ - s = line; - x = arraybounds(s,&lo,&hi); - if (x < 0) { /* Parse the name, get index */ - printf("?Bad array reference - \"%s\"\n", s); - return(-9); - } - if (lo < 0 && hi < 0) { - y = cmnum("New size","",10,&lo,xxstring); - if (y < 0) { - if (y == -3) - printf("?New size required\n"); - return(y); - } - } - if ((y = cmcfm()) < 0) - return(y); - if (a_link[x] > -1) { /* Link? */ - islink = x; /* Yes follow it */ - x = a_link[x]; /* and remember */ - } - if (!a_ptr[x]) { - printf("?Array not declared - \"%s\"\n", s); - return(-9); - } - if (lo < 0) { - printf("?New size required\n"); - return(-9); - } - if (hi > -1) { - printf("?Array segments not allowed for this operation\n"); - return(-9); - } - c = arrayitoa(x); /* Get array letter */ - if (c == '@') { /* Argument vector array off limits */ - printf("?Sorry, \\&@[] is read-only\n"); - return(-9); - } - if (lo == 0) { /* If new size is 0... */ - dclarray(c,0); /* Undeclare the array */ - return(success = 1); - } - n = a_dim[x]; /* Current size */ - ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */ - y = (n < lo) ? n : lo; - for (i = 0; i <= y; i++) /* Copy the part that fits */ - ap[i] = a_ptr[x][i]; - if (n < lo) { /* If original array smaller */ - for (; i <= lo; i++) /* initialize extra elements in */ - ap[i] = NULL; /* new array to NULL. */ - } else if (n > lo) { /* If new array smaller */ - for (; i <= lo; i++) /* deallocate leftover elements */ - makestr(&(a_ptr[x][i]),NULL); /* from original array. */ - } - free((char *)a_ptr[x]); /* Free original array list */ - a_ptr[x] = ap; /* Replace with new one */ - a_dim[x] = lo; /* Record the new dimension */ - if (islink > -1) { /* Was this a link? */ - a_ptr[islink] = ap; /* If so point to the resized array */ - a_dim[islink] = lo; - } else { /* If not are there links to here? */ - for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */ - if (i != x && a_link[i] == x) { /* Find and update them */ - a_ptr[i] = ap; - a_dim[i] = lo; - } - } - } - return(success = 1); -} - -static int -copyarray() { - int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0; - char c1, c2, * a1, * a2; - if ((y = cmfld("Name of source array","",&s,NULL)) < 0) - return(y); - ckstrncpy(line,s,LINBUFSIZ); - a1 = line; - if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) { - printf("?Bad array reference - \"%s\"\n", a1); - return(-9); - } else if (!a_ptr[x1]) { - printf("?Array not declared - \"%s\"\n", a1); - return(-9); - } - c1 = arrayitoa(x1); - - if ((y = cmfld("Name of destination array","",&s,NULL)) < 0) - return(y); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - a2 = tmpbuf; - if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) { - printf("?Bad array reference - \"%s\"\n", a2); - return(-9); - } - c2 = arrayitoa(x2); - - if ((x = cmcfm()) < 0) - return(x); - - if (c2 == '@') { /* Argument vector array off limits */ - printf("?Sorry, \\&@[] is read-only\n"); - return(-9); - } - if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */ - whole = 1; /* whole array... */ - - if (lo1 < 0) lo1 = whole ? 0 : 1; /* Supply lower bound of source */ - if (hi1 < 0) hi1 = a_dim[x1]; /* Supply upper bound of source */ - if (lo2 < 0) lo2 = whole ? 0 : 1; /* Lower bound of target */ - if (hi2 < 0) hi2 = lo2 + hi1 - lo1; /* Upper bound of target */ - if (a_ptr[x2]) { /* Target array is already declared? */ - if (hi2 > a_dim[x2]) /* If upper bound out of range */ - hi2 = a_dim[x2]; /* shrink to fit */ - } else { /* Otherwise... */ - x2 = dclarray(c2, hi2); /* declare the target array */ - } - for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */ - makestr(&(a_ptr[x2][j]),a_ptr[x1][i]); - } - return(success = 1); -} - -static int /* Undeclare an array */ -unarray() { - int x, y, n, rc = 0; - char c, * s; - - if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */ - if (y == -3) { - printf("?Array name required\n"); - return(-9); - } else return(y); - } - ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */ - s = line; - if ((y = cmcfm()) < 0) - return(y); - if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */ - printf("?Bad array reference - \"%s\"\n", s); - return(-9); - } - if (y > 0 || n > 0) { - printf("?Partial arrays can not be destroyed\n"); - return(-9); - } - c = arrayitoa(x); /* Get array letter */ - if (a_ptr[x]) { /* If array is declared */ - if (c == '@') { /* Argument vector array off limits */ - printf("?Sorry, \\&@[] is read-only\n"); - return(-9); - } - rc = dclarray(c,0); /* Undeclare the array */ - } else /* It wasn't declared */ - rc = 1; - if (rc > -1) { /* Set return code and success */ - success = 1; - rc = 1; - } else { - success = 0; - printf("?Failed - destroy \"\\&%c[]\"\n", c); - rc = -9; - } - return(rc); -} - -static int -clrarray(cx) int cx; { - int i, x, lo, hi; - char c, * s, * val = NULL; - - if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */ - if (x == -3) { - printf("?Array name required\n"); - return(-9); - } else return(x); - } - ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */ - s = line; - if (cx == ARR_SET) { /* SET */ - if ((x = cmtxt("Value","",&val,xxstring)) < 0) - return(x); - ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */ - val = tmpbuf; - if (!*val) val = NULL; - } else if ((x = cmcfm()) < 0) /* CLEAR */ - return(x); - - if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */ - printf("?Bad array reference - \"%s\"\n", s); - return(-9); - } - c = arrayitoa(x); /* Get array letter */ - if (!a_ptr[x]) { /* If array is declared */ - printf("?Array %s is not declared\n", s); - return(-9); - } else if (c == '@') { /* Argument vector array off limits */ - printf("?Sorry, \\&@[] is read-only\n"); - return(-9); - } - if (lo < 0) lo = 0; - if (hi < 0) hi = a_dim[x]; - for (i = lo; i <= hi; i++) /* Clear/Set selected range */ - makestr(&(a_ptr[x][i]),val); - - return(success = 1); -} - -extern char **aa_ptr[CMDSTKL][28]; -extern int aa_dim[CMDSTKL][28]; - -static int /* Create symbolic link to an array */ -linkarray() { - int i = 0, x, y, lo, hi, flag = 0; - char c, * s, * p; - - if ((x = cmfld("Array name not currently in use","",&s,NULL)) < 0) { - if (x == -3) { - printf("?Array name required\n"); - return(-9); - } else return(x); - } - ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of link name */ - s = line; - if ((x = cmfld("Name of existing array","",&p,xxstring)) < 0) { - if (x == -3) { - printf("?Array name required\n"); - return(-9); - } else return(x); - } - ckstrncpy(tmpbuf,p,TMPBUFSIZ); /* Make safe copy of array name */ - p = tmpbuf; - if ((x = cmcfm()) < 0) - return(x); - - if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the link name */ - printf("?Bad array reference - \"%s\"\n", s); - return(-9); - } - if (a_ptr[x]) { /* Must not already exist */ - c = arrayitoa(x); - printf("?Array already exists: \\&%c[]\n", c); - return(-9); - } - if (lo > -1 || hi > -1) { - printf("?Sorry, whole arrays only: %s\n",s); - return(-9); - } - if ((y = arraybounds(p,&lo,&hi)) < 0) { /* Parse the array name */ - printf("?Bad array reference - \"%s\"\n", s); - return(-9); - } - if (lo > -1 || hi > -1) { - printf("?Sorry, whole arrays only: %s\n",p); - return(-9); - } - if (x == y) { - for (i = cmdlvl; i >= 0; i--) - if (aa_ptr[i][x]) { - flag++; - break; - } - } - if (flag) { - a_ptr[x] = aa_ptr[i][y]; /* Link to saved copy */ - a_dim[x] = aa_dim[i][y]; - } else { /* Otherwise... */ - c = arrayitoa(y); /* Check if it's declared */ - if (!a_ptr[y]) { - printf("?Array is not declared: \\&%c[]\n", c); - return(-9); - } - if (a_link[y] > -1) { /* And if it's a link itself */ - printf("?Links to links not allowed: \\&%c[]\n", c); - return(-9); - } - a_ptr[x] = a_ptr[y]; /* All OK, make the link */ - a_dim[x] = a_dim[y]; - } - a_link[x] = y; - return(success = 1); -} -#endif /* NOSPL */ - -#ifndef NOCSETS -static char * dcsetname = NULL; - -/* Get Display Character-Set Name */ - -char * -getdcset() { - char * s; - int y; -#ifdef PCFONTS - extern int tt_font, ntermfont; - extern struct keytab term_font[]; -#endif /* PCFONTS */ - - s = ""; -#ifdef OS2 - y = os2getcp(); /* Default is current code page */ - switch (y) { - case 437: s = "cp437"; break; - case 850: s = "cp850"; break; - case 852: s = "cp852"; break; - case 857: s = "cp857"; break; - case 858: s = "cp858"; break; - case 862: s = "cp862"; break; - case 866: s = "cp866"; break; - case 869: s = "cp869"; break; - case 1250: s = "cp1250"; break; - case 1251: s = "cp1251"; break; - case 1252: s = "cp1252"; break; - case 1253: s = "cp1253"; break; - case 1254: s = "cp1254"; break; - case 1255: s = "cp1255"; break; - case 1256: s = "cp1256"; break; - case 1257: s = "cp1257"; break; - case 1258: s = "cp1258"; break; - } -#ifdef PCFONTS -/* - If the user has loaded a font with SET TERMINAL FONT then we want - to change the default code page to the font that was loaded. -*/ - if (tt_font != TTF_ROM) { - for (y = 0; y < ntermfont; y++ ) { - if (term_font[y].kwval == tt_font) { - s = term_font[y].kwd; - break; - } - } - } -#endif /* PCFONTS */ -#else /* OS2 */ -#ifdef COMMENT - /* Hack not needed as of C-Kermit 7.1 */ - if (fcharset == FC_1LATIN) { - s = "latin1-iso"; /* Hack to avoid reporting "cp1252" */ - } else { /* Report current file character set */ -#endif /* COMMENT */ - for (y = 0; y <= nfilc; y++) - if (fcstab[y].kwval == fcharset) { - s = fcstab[y].kwd; - break; - } -#ifdef COMMENT - } -#endif /* COMMENT */ -#endif /* OS2 */ - makestr(&dcsetname,s); /* Return stable pointer */ - return((char *)dcsetname); -} -#endif /* NOCSETS */ - -#ifndef NOFRILLS -static int -doclear() { - if ((x = cmkey(clrtab,nclear,"item to clear", -#ifdef NOSPL - "device-buffer" -#else - "device-and-input" -#endif /* NOSPL */ - ,xxstring)) < 0) return(x); -#ifndef NOSPL -#ifdef OS2 - if (x == CLR_CMD || x == CLR_TRM) { - if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n", - "all",xxstring)) < 0) - return(z); - } -#endif /* OS2 */ -#endif /* NOSPL */ - if ((y = cmcfm()) < 0) - return(y); - - /* Clear device input buffer if requested */ - y = (x & CLR_DEV) ? ttflui() : 0; - - if (x & CLR_SCR) /* CLEAR SCREEN */ - y = ck_cls(); /* (= SCREEN CLEAR = CLS) */ - - if (x & CLR_KBD) { /* CLEAR KEYBOARD */ - int n; - n = conchk(); - y = 0; - while (n-- > 0 && (y = coninc(0) > -1)) - ; - y = (y > -1) ? 0 : -1; - } - -#ifndef NOSPL - /* Clear INPUT command buffer if requested */ - if (x & CLR_INP) { - for (z = 0; z < inbufsize; z++) - inpbuf[z] = NUL; - inpbp = inpbuf; - y = 0; - } -#ifdef CK_APC - if (x & CLR_APC) { - debug(F101,"Executing CLEAR APC","",apcactive); - apcactive = 0; - y = 0; - } -#endif /* CK_APC */ - if (x & CLR_ALR) { - setalarm(0L); - y = 0; - } -#endif /* NOSPL */ - -#ifdef PATTERNS - if (x & (CLR_TXT|CLR_BIN)) { - int i; - for (i = 0; i < FTPATTERNS; i++) { - if (x & CLR_TXT) - makestr(&txtpatterns[i],NULL); - if (x & CLR_BIN) - makestr(&binpatterns[i],NULL); - } - y = 0; - } -#endif /* PATTERNS */ - -#ifndef NODIAL - if (x & CLR_DIA) { - dialsta = DIA_UNK; - y = 0; - } -#endif /* NODIAL */ - -#ifndef NOMSEND - if (x & CLR_SFL) { /* CLEAR SEND-LIST */ - if (filehead) { - struct filelist * flp, * next; - flp = filehead; - while (flp) { - if (flp->fl_name) - free(flp->fl_name); - if (flp->fl_alias) - free(flp->fl_alias); - next = flp->fl_next; - free((char *)flp); - flp = next; - } - } - filesinlist = 0; - filehead = NULL; - filetail = NULL; - addlist = 0; - y = 0; - } -#endif /* NOMSEND */ - -#ifdef OS2 -#ifndef NOLOCAL - switch (x) { - case CLR_SCL: - clearscrollback(VTERM); - break; - case CLR_CMD: - switch ( z ) { - case CLR_C_ALL: - clear(); - break; - case CLR_C_BOS: - clrboscr_escape(VCMD,SP); - break; - case CLR_C_BOL: - clrbol_escape(VCMD,SP); - break; - case CLR_C_EOL: - clrtoeoln(VCMD,SP); - break; - case CLR_C_EOS: - clreoscr_escape(VCMD,SP); - break; - case CLR_C_LIN: - clrline_escape(VCMD,SP); - break; - case CLR_C_SCR: - clearscrollback(VCMD); - break; - default: - printf("Not implemented yet, sorry.\n"); - break; - } - break; - -#ifndef NOTERM - case CLR_TRM: - switch ( z ) { - case CLR_C_ALL: - if (VscrnGetBufferSize(VTERM) > 0 ) { - VscrnScroll(VTERM, UPWARD, 0, - VscrnGetHeight(VTERM)-(tt_status[VTERM]?2:1), - VscrnGetHeight(VTERM) - - (tt_status[VTERM]?1:0), TRUE, SP - ); - cleartermscreen(VTERM); - } - break; - case CLR_C_BOS: - clrboscr_escape(VTERM,SP); - break; - case CLR_C_BOL: - clrbol_escape(VTERM,SP); - break; - case CLR_C_EOL: - clrtoeoln(VTERM,SP); - break; - case CLR_C_EOS: - clreoscr_escape(VTERM,SP); - break; - case CLR_C_LIN: - clrline_escape(VTERM,SP); - break; - case CLR_C_SCR: - clearscrollback(VTERM); - break; - default: - printf("Not implemented yet, sorry.\n"); - break; - } - break; -#endif /* NOTERM */ - } - y = 0; -#endif /* NOLOCAL */ -#endif /* OS2 */ - return(success = (y == 0)); -} -#endif /* NOFRILLS */ - -#ifndef NOSPL -static int -doeval(cx) int cx; { - char *p; - char vnambuf[VNAML], * vnp = NULL; /* These must be on the stack */ - if (!oldeval) { - if ((y = cmfld("Variable name","",&s, - ((cx == XX_EVAL) ? xxstring : NULL))) < 0) { - if (y == -3) { - printf("?Variable name required\n"); - return(-9); - } else return(y); - } - ckstrncpy(vnambuf,s,VNAML); /* Make a copy. */ - vnp = vnambuf; - if (vnambuf[0] == CMDQ && - (vnambuf[1] == '%' || vnambuf[1] == '&')) - vnp++; - y = 0; - if (*vnp == '%' || *vnp == '&') { - if ((y = parsevar(vnp,&x,&z)) < 0) - return(y); - } - } - if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0) - return(x); - p = evala(s); - if (!p) p = ""; - if (oldeval && *p) - printf("%s\n", p); - ckstrncpy(evalbuf,p,32); - if (!oldeval) - return(success = addmac(vnambuf,p)); - else - return(success = *p ? 1 : 0); -} -#endif /* NOSPL */ - -#ifdef TNCODE -static int -dotelopt() { - if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 ) - return(x); - switch (x) { - case WILL: - case WONT: - case DO: - case DONT: - if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0) - return(y); - if ((z = cmcfm()) < 0) return(z); - - switch (x) { - case WILL: - if (TELOPT_UNANSWERED_WILL(y)) - return(success = 0); - break; - case WONT: - if (TELOPT_UNANSWERED_WONT(y)) - return(success = 0); - break; - case DO: - if (TELOPT_UNANSWERED_DO(y)) - return(success = 0); - break; - case DONT: - if (TELOPT_UNANSWERED_DONT(y)) - return(success = 0); - break; - } - if (local) { - success = ((tn_sopt(x,y) > -1) ? 1 : 0); - } else { - printf("ff%02x%02x\n",x,y); - success = 1; - } - if (success) { - switch (x) { - case WILL: - TELOPT_UNANSWERED_WILL(y) = 1; - break; - case WONT: - if ( TELOPT_ME(y) ) - TELOPT_UNANSWERED_WONT(y) = 1; - break; - case DO: - TELOPT_UNANSWERED_DO(y) = 1; - break; - case DONT: - if ( TELOPT_ME(y) ) - TELOPT_UNANSWERED_DONT(y) = 1; - break; - } - if (tn_wait("XXTELOP") < 0) { - tn_push(); - success = 0; - } - } - return(success); - case SB: - if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0) - return(y); - switch (y) { - case TELOPT_NAWS: - /* Some compilers require switch() to have at least 1 case */ -#ifdef CK_NAWS - TELOPT_SB(TELOPT_NAWS).naws.x = 0; - TELOPT_SB(TELOPT_NAWS).naws.y = 0; - if (local) - return(success = ((tn_snaws() > -1) ? 1 : 0)); - else - return(success = 0); -#else - return(success = 0); -#endif /* CK_NAWS */ - } - return(success = 0); - -#ifdef CK_KERBEROS -#ifdef KRB5 - case TN_FWD: - success = (kerberos5_forward() == AUTH_SUCCESS); - return(success); -#endif /* KRB5 */ -#endif /* CK_KERBEROS */ - - default: - if ((z = cmcfm()) < 0) return(z); -#ifndef NOLOCAL - if (local) { - CHAR temp[3]; - if (network && IS_TELNET()) { /* TELNET */ - temp[0] = (CHAR) IAC; - temp[1] = x; - temp[2] = NUL; - success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0); - if (tn_deb || debses || deblog) { - /* TN_MSG_LEN is in ckctel.h */ - ckmakmsg(tn_msg,256,"TELNET SENT ",TELCMD(x),NULL,NULL); - debug(F101,tn_msg,"",x); - if (debses || tn_deb) tn_debug(tn_msg); - } - return(success); - } - return(success = 0); - } else { -#endif /* NOLOCAL */ - printf("ff%02x\n",x); - return(success = 1); -#ifndef NOLOCAL - } -#endif /* NOLOCAL */ - } -} -#endif /* TNCODE */ - - -#ifndef NOPUSH -#ifndef NOFRILLS -static int -doedit() { -#ifdef OS2 - char * p = NULL; -#endif /* OS2 */ - if (!editor[0]) { - s = getenv("EDITOR"); - if (s) ckstrncpy(editor,s,CKMAXPATH); - editor[CKMAXPATH] = NUL; - if (!editor[0]) { - printf("?Editor not defined - use SET EDITOR to define\n"); - return(-9); - } - } - ckstrncpy(tmpbuf,editfile,TMPBUFSIZ); -/* - cmiofi() lets us parse the name of an existing file, or the name of - a nonexistent file to be created. -*/ - x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring); - if (x < 0) { - if (x == -9) { - if (zchko(s) < 0) { - printf("Can't create \"%s\"\n",s); - return(x); - } - } else if (x != -3) - return(x); - } - if (x == -3) - tmpbuf[0] = NUL; - else { - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - if (iswild((char *)tmpbuf)) { - printf("?A single file please\n"); - return(-9); - } - } - if ((z = cmcfm()) < 0) return(z); - if (nopush) { - printf("?Sorry, editing not allowed\n"); - return(success = 0); - } - if (tmpbuf[0]) { - /* Get full path in case we change directories between EDIT commands */ - zfnqfp(tmpbuf, CKMAXPATH, editfile); - editfile[CKMAXPATH] = NUL; -#ifdef OS2 - p = editfile; /* Flip the stupid slashes */ - while (*p) { - if (*p == '/') *p = '\\'; - p++; - } -#endif /* OS2 */ - } else - editfile[0] = NUL; - x = 0; - if (editopts[0]) { -#ifdef OS2 - x = ckindex("%1",(char *)editopts,0,0,1); - if (x > 0) - editopts[x] = 's'; - else -#endif /* OS2 */ - x = ckindex("%s",(char *)editopts,0,0,1); - } - if (((int)strlen(editopts) + (int)strlen(editfile) + 1) < TMPBUFSIZ) { - if (x) - sprintf(tmpbuf,editopts,editfile); - else - sprintf(tmpbuf,"%s %s",editopts,editfile); - } - s = line; - ckmakmsg(s,LINBUFSIZ,editor," ",tmpbuf,NULL); -#ifdef OS2 - p = s + strlen(editor); /* And again with the slashes */ - while (p != s) { - if (*p == '/') *p = '\\'; - p--; - } -#endif /* OS2 */ - conres(); - x = zshcmd(s); - concb((char)escape); - return(x); -} -#endif /* NOFRILLS */ -#endif /* NOPUSH */ - -#ifdef BROWSER -static int -dobrowse() { -#ifdef OS2 - char * p = NULL; -#endif /* OS2 */ - if (nopush) { - printf("?Sorry, browsing not allowed\n"); - return(success = 0); - } -#ifndef NT - /* Windows lets the Shell Execute the URL if no Browser is defined */ - if (!browser[0]) { - s = getenv("BROWSER"); - if (s) ckstrncpy(browser,s,CKMAXPATH); - browser[CKMAXPATH] = NUL; - if (!browser[0]) { - printf("?Browser not defined - use SET BROWSER to define\n"); - return(-9); - } - } -#endif /* NT */ - ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ); - if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0) - return(x); - ckstrncpy(browsurl,s,4096); - x = 0; - if (browsopts[0]) { -#ifdef OS2 - x = ckindex("%1",(char *)browsopts,0,0,1); - if (x > 0) - browsopts[x] = 's'; - else -#endif /* OS2 */ - x = ckindex("%s",(char *)browsopts,0,0,1); - } - if (((int)strlen(browsopts) + (int)strlen(browsurl) + 1) < TMPBUFSIZ) { - if (x) - sprintf(tmpbuf,browsopts,browsurl); - else - sprintf(tmpbuf,"%s %s",browsopts,browsurl); - } -#ifdef NT - if (!browser[0]) - return(success = Win32ShellExecute(browsurl)); -#endif /* NT */ - s = line; - ckmakmsg(s,LINBUFSIZ,browser," ",tmpbuf,NULL); -#ifdef OS2 - p = line + strlen(browser); /* Flip slashes */ - while (p != line) { - if (*p == '/') *p = '\\'; - p--; - } -#endif /* OS2 */ - conres(); - x = zshcmd(s); - concb((char)escape); - return(x); -} -#endif /* BROWSER */ - -#ifdef CK_RECALL -static int -doredo() { /* Find a previous cmd and redo it */ - extern int on_recall, in_recall; - int x; - char * p; - - if ((x = cmtxt( -"pattern, or first few characters of a previous command", - "*",&s,xxstring)) < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - x = strlen(s); - s = line; - if (*s == '{') { /* Braces disable adding * to end */ - if (s[x-1] == '}') { - s[x-1] = NUL; - s++; - x--; - } - } else { /* No braces, add * to end. */ - s[x] = '*'; - s[x+1] = NUL; - } - - while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL; - - if (!on_recall || !in_recall) { - printf("?Sorry, command recall can't be used now.\n"); - return(-9); - } - if ((p = cmgetcmd(s))) { /* Look for it history buffer */ - ckmakmsg(cmdbuf,CMDBL,p,"\r",NULL,NULL); /* Copy to command buffer */ - if (!quiet) /* Echo it */ - printf("%s\n",cmdbuf); - cmaddnext(); /* Force re-add to history buffer */ - return(cmflgs = -1); /* Force reparse */ - } else { - printf("?Sorry - \"%s\" not found\n", s); - return(-9); - } -} -#endif /* CK_RECALL */ - -#ifndef NOXFER -#ifndef NOCSETS -static int -doassoc() { /* ASSOCIATE */ - extern struct keytab tcstab[]; - extern int ntcs; - if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 ) - return(x); - - switch (x) { /* Associate what? */ - - case ASSOC_TC: /* Transfer character-set... */ - if ((x = cmkey(tcstab, ntcs, - "transfer character-set name","",xxstring)) < 0) - return(x); - if ((y = cmkey(fcstab, nfilc, - "with file character-set","", xxstring)) < 0) - if (y != -3) - return(y); - if ((z = cmcfm()) < 0) - return(z); - axcset[x] = y; - return(success = 1); - - case ASSOC_FC: /* File character-set... */ - if ((x = cmkey(fcstab, nfilc, - "file character-set name","",xxstring)) < 0) - return(x); - if ((y = cmkey(tcstab, ntcs, - "with transfer character-set","", xxstring)) < 0) - if (y != -3) - return(y); - if ((z = cmcfm()) < 0) - return(z); - afcset[x] = y; - return(success = 1); - - default: - return(-2); - } -} -#endif /* NOCSETS */ -#endif /* NOXFER */ - -#ifndef NOHELP -static int -domanual() { -#ifdef OS2 - if ((x = cmcfm()) < 0) - return(x); - if (nopush) { - printf("?Sorry, access to system commands is disabled.\n"); - return(-9); - } - y = mxlook(mactab,"manual",nmac); - if (y > -1) { - z = maclvl; /* Save the current maclvl */ - dodo(y,NULL,cmdstk[cmdlvl].ccflgs); /* Run the macro */ - while (maclvl > z) { - debug(F101,"XXMAN loop maclvl 1","",maclvl); - sstate = (CHAR) parser(1); - debug(F101,"XXMAN loop maclvl 2","",maclvl); - if (sstate) proto(); - } - debug(F101,"XXMAN loop exit maclvl","",maclvl); - return(success); - } - return(success = 0); -#else - if ((x = cmtxt( -#ifdef UNIX - "Carriage return to confirm the command, or manual topic", -#else - "Carriage return to confirm the command, or help topic", -#endif /* UNIX */ - "kermit", - &s, - xxstring - ) - ) < 0) - return(x); -#endif /* OS2 */ - -#ifdef UNIX - ckmakmsg(tmpbuf,TMPBUFSIZ,"man ",s,NULL,NULL); -#else - ckmakmsg(tmpbuf,TMPBUFSIZ,"help ",s,NULL,NULL); -#endif /* UNIX */ - debug(F110,"MANUAL",tmpbuf,0); - if (nopush) { - printf("?Sorry, access to system commands is disabled.\n"); - return(-9); - } else { - conres(); /* Restore the console */ - success = zshcmd(tmpbuf); - concb((char)escape); /* Restore CBREAK mode */ - return(success); - } -} -#endif /* NOHELP */ - -#ifndef NOHTTP -#ifdef TCPSOCKET -static struct keytab sslswtab[] = { - { "/ssl", 1, 0 }, - { "/tls", 1, 0 } -}; - -#ifndef NOURL -struct urldata http_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL}; -#endif /* NOURL */ - -static int -dohttp() { /* HTTP */ - struct FDB sw, kw, fi; - int n, getval, allinone = 0; - char c, * p; - char rdns[128]; - - char * http_agent = NULL; /* Parse results */ - char * http_hdr = NULL; - char * http_user = NULL; - char * http_pass = NULL; - char * http_mime = NULL; - char * http_lfile = NULL; - char * http_rfile = NULL; - char * http_dfile = NULL; - char http_array = NUL; - int http_action = -1; - - char * http_host = NULL; - char * http_srv = NULL; - int http_ssl = 0; - - static char * http_d_agent = NULL; - static char * http_d_user = NULL; - static char * http_d_pass = NULL; - - static int http_d_type = 0; - int http_type = http_d_type; - -#ifdef OS2 - p = "Kermit 95"; /* Default user agent */ -#else - p = "C-Kermit"; -#endif /* OS2 */ - makestr(&http_agent,p); - makestr(&http_mime,"text/HTML"); /* MIME type default */ - rdns[0] = '\0'; - - cmfdbi(&sw, /* 1st FDB - general switches */ - _CMKEY, /* fcode */ - "OPEN, CLOSE, GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nhttpswtab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - httpswtab, /* Keyword table */ - &kw /* Pointer to next FDB */ - ); - cmfdbi(&kw, /* 2nd FDB - commands */ - _CMKEY, /* fcode */ - "Command", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nhttptab, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: 0 = keyword */ - xxstring, /* Processing function */ - httptab, /* Keyword table */ - NULL /* Pointer to next FDB */ - ); - - while (1) { - x = cmfdb(&sw); /* Parse something */ - if (x < 0) /* Error */ - goto xhttp; - n = cmresult.nresult; - if (cmresult.fdbaddr == &kw) /* Command - exit this loop */ - break; - c = cmgbrk(); /* Switch... */ - getval = (c == ':' || c == '='); - x = -9; - if (getval && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - goto xhttp; - } - switch (cmresult.nresult) { /* Handle each switch */ - case HT_SW_TP: /* /TOSCREEN */ - http_type = 1; - break; - case HT_SW_AG: /* /AGENT */ - if (getval) { - if ((x = cmfld("User agent",p,&s,xxstring)) < 0) - goto xhttp; - } else { - s = p; - } - makestr(&http_agent,s); - break; - case HT_SW_HD: /* /HEADER */ - s = NULL; - if (getval) { - if ((x = cmfld("Header line","",&s,xxstring)) < 0) { - if (x == -3) - s = NULL; - else - goto xhttp; - } - } - makestr(&http_hdr,s); - break; - case HT_SW_US: /* /USER */ - s = NULL; - if (getval) { - if ((x = cmfld("User ID","",&s,xxstring)) < 0) { - if (x == -3) - s = ""; - else - goto xhttp; - } - } - makestr(&http_user,s); - break; - case HT_SW_PW: /* /PASSWORD */ - debok = 0; - s = NULL; - if (getval) { - if ((x = cmfld("Password","",&s,xxstring)) < 0) - goto xhttp; - } - makestr(&http_pass,s); - break; -#ifndef NOSPL - case HT_SW_AR: { /* /ARRAY: */ - char * s2, array = NUL; - if (!getval) { - printf("?This switch requires an argument\n"); - x = -9; - goto xhttp; - } - if ((x = cmfld("Array name (a single letter will do)", - "", - &s, - NULL - )) < 0) { - if (x == -3) { - printf("?Array name required\n"); - x = -9; - goto xhttp; - } else - goto xhttp; - } - if (!*s) { - printf("?Array name required\n"); - x = -9; - goto xhttp; - } - s2 = s; - if (*s == CMDQ) s++; - if (*s == '&') s++; - if (!isalpha(*s)) { - printf("?Bad array name - \"%s\"\n",s2); - x = -9; - goto xhttp; - } - array = *s++; - if (isupper(array)) - array = tolower(array); - if (*s && (*s != '[' || *(s+1) != ']')) { - printf("?Bad array name - \"%s\"\n",s2); - http_array = NUL; - x = -9; - goto xhttp; - } - http_array = array; - break; - } -#endif /* NOSPL */ - default: - x = -2; - goto xhttp; - } - } - http_action = n; /* Save the action */ - if (http_action == HTTP_PUT || http_action == HTTP_POS) { - cmfdbi(&sw, /* 1st FDB - switch */ - _CMKEY, /* fcode */ - "Local filename\n Or switch", /* help */ - "", /* default */ - "", /* addtl string data */ - nhttpptab, /* keyword table size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - httpptab, /* Keyword table */ - &fi /* Pointer to next FDB */ - ); - cmfdbi(&fi, /* 2nd FDB - filename */ - _CMIFI, /* fcode */ - "Local filename", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - while (1) { - x = cmfdb(&sw); - if (x < 0) - goto xhttp; /* Free any malloc'd temp strings */ - n = cmresult.nresult; - if (cmresult.fcode != _CMKEY) - break; - c = cmgbrk(); /* Switch... */ - getval = (c == ':' || c == '='); - if (getval && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - x = -9; - goto xhttp; - } - switch (n) { - case HT_PP_MT: - s = "text/HTML"; - if (getval) { - if ((x = cmfld("MIME type", - "text/HTML",&s,xxstring)) < 0) - goto xhttp; - } - makestr(&http_mime,s); - break; - default: - x = -2; - goto xhttp; - } - } - makestr(&http_lfile,cmresult.sresult); - n = ckindex("/",http_lfile,-1,1,0); - if (n) - p = &http_lfile[n]; - else - p = http_lfile; - if ((x = cmfld("URL or remote filename",p,&s,xxstring)) < 0) { - if (x == -3) { - printf("?%s what?\n",(http_action == HTTP_PUT) ? "Put" : "Post"); - x = -9; - } - goto xhttp; - } - if (!*s) s = NULL; - makestr(&http_rfile,s); - - if ((x = cmtxt("Response filename","",&s,xxstring)) < 0) { - if (x != -3) - goto xhttp; - } - if (*s) - makestr(&http_dfile,s); - } - switch (http_action) { - case HTTP_DEL: /* DELETE */ - if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Delete what?\n"); - x = -9; - } - goto xhttp; - } - makestr(&http_rfile,s); - break; - case HTTP_CON: /* CONNECT */ - if ((x = cmfld("Remote host[:port]","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Remote host[:port] is required\n"); - x = -9; - } - goto xhttp; - } - makestr(&http_rfile,s); - break; - case HTTP_HED: { /* HEAD */ - char buf[CKMAXPATH+1]; - if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Head of what?\n"); - x = -9; - } - goto xhttp; - } - makestr(&http_rfile,s); - - if (http_array || http_type) { /* Default result filename */ - p = ""; /* None if /ARRAY or /TOSCREEN */ - } else { - n = ckindex("/",http_rfile,-1,1,0); /* Otherwise strip path */ - if (n) /* and add ".head" */ - p = &http_rfile[n]; - else - p = http_rfile; - ckmakmsg(buf,CKMAXPATH,p,".head",NULL,NULL); - p = buf; - } - if ((x = cmofi("Local filename",p,&s,xxstring)) < 0) { - if (x != -3) - goto xhttp; - } - makestr(&http_lfile,s); - break; - } - case HTTP_GET: /* GET */ - case HTTP_IDX: { /* INDEX */ - char * lfile = ""; - if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Get what?\n"); - x = -9; - } - goto xhttp; - } - makestr(&http_rfile,s); - if (http_action == HTTP_GET && !http_type) - zstrip(http_rfile,&lfile); - if ((x = cmofi("Local filename",lfile,&s,xxstring)) < 0) - if (x != -3) - goto xhttp; - makestr(&http_lfile,s); - break; - } - case HTTP_OPN: { - int sslswitch = 0; -#ifdef CK_SSL - struct FDB sw, fl; - cmfdbi(&sw, - _CMKEY, /* fcode */ - "IP host name or address, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 2, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - sslswtab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* 2nd FDB - host */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - x = cmfdb(&sw); /* Parse switch or host */ - if (x < 0) /* Error */ - goto xhttp; - if (cmresult.fcode == _CMFLD) { /* Host */ - s = cmresult.sresult; /* Set up expected pointer */ - goto havehost; /* Go parse rest of command */ - } - sslswitch = 1; /* /SSL or /TLS switch - set flag */ -#endif /* CK_SSL */ - - /* Parse host */ - - if ((x = cmfld("URL, hostname, or ip-address","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Open what?\n"); - x = -9; - } - goto xhttp; - } - - havehost: /* Come here with s -> host */ -#ifdef CK_URL - x = urlparse(s,&http_url); /* Was a URL given? */ - if (x < 1) { /* Not a URL */ -#endif /* CK_URL */ - makestr(&http_host,s); - if ((x = - cmfld("Service name or port number", - sslswitch ? "https" : "http",&s,xxstring)) < 0) - goto xhttp; - else - makestr(&http_srv,s); -#ifdef CK_URL - } else if (ckstrcmp(http_url.svc,"http",-1,0) && /* Non-HTTP URL */ - ckstrcmp(http_url.svc,"https",-1,0)) { - printf("?Non-HTTP URL\n"); - x = -9; - goto xhttp; - } else { /* Have HTTP URL */ - makestr(&http_srv, http_url.svc); - makestr(&http_user,http_url.usr); - makestr(&http_pass,http_url.psw); - makestr(&http_host,http_url.hos); - if (http_url.por) - makestr(&http_srv,http_url.por); - makestr(&http_rfile,http_url.pth); - } - if (http_rfile) { /* Open, GET, and Close */ - printf("?Directory/file path not allowed in HTTP OPEN URL\n"); - x = -9; - goto xhttp; - } - if (!ckstrcmp("https",http_srv,-1,0) || sslswitch || - !ckstrcmp("443",http_srv,-1,0)) - http_ssl = 1; -#endif /* CK_URL */ - break; - } - case HTTP_CLS: - break; - } - if ((x = cmcfm()) < 0) - goto xhttp; - - if (http_action == HTTP_OPN) { - x = (http_open(http_host,http_srv,http_ssl,rdns,128,http_agent) == 0); - if (x) { - if (!quiet) { - if (rdns[0]) - printf("Connected to %s [%s]\r\n",http_host,rdns); - else - printf("Connected to %s\r\n",http_host); - } - if (http_agent) { - if (http_d_agent) - free(http_d_agent); - http_d_agent = http_agent; - http_agent = NULL; - } - if (http_user) { - if (http_d_user) - free(http_d_user); - http_d_user = http_user; - http_user = NULL; - } - if (http_pass) { - if (http_d_pass) { - memset(http_d_pass,0,strlen(http_d_pass)); - free(http_d_pass); - } - http_d_pass = http_pass; - http_pass = NULL; - } - http_d_type = http_type; - } else { - if (!quiet) - printf("?HTTP Connection failed.\r\n"); - } - } else if (http_action == HTTP_CLS) { - if (http_d_agent) { - free(http_d_agent); - http_d_agent = NULL; - } - if (http_d_user) { - free(http_d_user); - http_d_user = NULL; - } - if (http_d_pass) { - memset(http_d_pass,0,strlen(http_d_pass)); - free(http_d_pass); - http_d_pass = NULL; - } - http_d_type = 0; - x = (http_close() == 0); - } - if ((http_action != HTTP_CLS) && - (http_action != HTTP_CON) && http_rfile) { /* Remote file is URL? */ - - /* All-in-one actions when a URL is given... */ - -#ifdef CK_URL - if (urlparse(http_rfile,&http_url) > 0) { /* Have URL? */ - if (ckstrcmp(http_url.svc,"http",-1,0) && /* It's an HTTP URL? */ - ckstrcmp(http_url.svc,"https",-1,0)) { - printf("?Non-HTTP URL\n"); - x = -9; - goto xhttp; - } else { /* Yes, collect the pieces */ - makestr(&http_srv, http_url.svc); - makestr(&http_user,http_url.usr); - makestr(&http_pass,http_url.psw); - makestr(&http_host,http_url.hos); - if (http_url.por) - makestr(&http_srv,http_url.por); - makestr(&http_rfile,http_url.pth); - } - if (!http_rfile) { /* Still have a path? */ - makestr(&http_rfile,"/"); - } - if (!ckstrcmp("https",http_srv,-1,0) || /* Check for SSL/TLS */ - !ckstrcmp("443",http_srv,-1,0)) - http_ssl = 1; - if (http_isconnected()) /* Close any open HTTP connection */ - http_close(); - if (http_pass == NULL && http_d_pass != NULL) - makestr(&http_pass,http_d_pass); - x = (http_open(http_host, - http_srv,http_ssl,rdns,128,http_d_agent) == 0); - if (x < 0) { - x = 0; - goto xhttp; - } - allinone = 1; - } -#endif /* CK_URL */ - if (http_pass == NULL && http_d_pass != NULL) - makestr(&http_pass,http_d_pass); - - if (http_action == HTTP_OPN && allinone) { - http_action = HTTP_GET; - } - x = xdohttp(http_action, - http_lfile, - http_rfile, - http_dfile, - http_agent ? http_agent : http_d_agent, - http_hdr, - http_user ? http_user : http_d_user, - http_pass ? http_pass : http_d_pass, - http_mime, - http_array, - http_type - ); - if (allinone) - x = (http_close() == 0); - } - - xhttp: - if (http_agent) free(http_agent); - if (http_hdr) free(http_hdr); - if (http_user) free(http_user); - if (http_pass) { - memset(http_pass,0,strlen(http_pass)); - free(http_pass); - } - if (http_mime) free(http_mime); - if (http_lfile) free(http_lfile); - if (http_rfile) free(http_rfile); - if (http_dfile) free(http_dfile); - if (http_host) free(http_host); - if (http_srv) free(http_srv); - - if (x > -1) - success = x; - return(x); -} -#endif /* TCPSOCKET */ -#endif /* NOHTTP */ - - -#ifndef NOSPL -static int -dotrace() { - int on = 1; - struct FDB sw, kw; - cmfdbi(&sw, /* 1st FDB - switch */ - _CMKEY, /* fcode */ - "Trace object;\n Or switch", /* help */ - "", /* default */ - "", /* addtl string data */ - 2, /* keyword table size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - onoffsw, /* Keyword table */ - &kw /* Pointer to next FDB */ - ); - cmfdbi(&kw, /* 2nd FDB - Trace object */ - _CMKEY, /* fcode */ - "Trace object", /* help */ - "all", /* default */ - "", /* addtl string data */ - ntracetab, /* keyword table size */ - 0, /* addtl numeric data 2: 0 = keyword */ - xxstring, /* Processing function */ - tracetab, /* Keyword table */ - NULL /* Pointer to next FDB */ - ); - if ((x = cmfdb(&sw)) < 0) - return(x); - if (cmresult.fdbaddr == &sw) { - on = cmresult.nresult; - if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0) - return(x); - } else { - x = cmresult.nresult; - } - if ((y = cmcfm()) < 0) - return(y); - - switch (x) { - case TRA_ASG: - tra_asg = on; - break; - case TRA_CMD: - tra_cmd = on; - break; - case TRA_ALL: - tra_asg = on; - tra_cmd = on; - break; - default: - return(-2); - } - printf("TRACE %s\n", on ? "ON" : "OFF"); - return(success = 1); -} -#endif /* NOSPL */ - - -static int -doprompt() { - extern int xcmdsrc; - if ((x = cmtxt("Optional message","",&s,xxstring)) < 0) - return(x); -#ifdef NOSPL - printf("?Sorry, PROMPT requires script programming language\n"); - return(-9); -#else - debug(F101,"Prompt cmdlvl","",cmdlvl); - cmdlvl++; - if (cmdlvl > CMDSTKL) { - printf("?Command stack overflow: %d\n",cmdlvl); - cmdlvl--; - return(-9); - } - xcmdsrc = CMD_KB; - cmdstk[cmdlvl].src = CMD_KB; /* Say we're at the prompt */ - cmdstk[cmdlvl].lvl = 0; - cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs; - if (tra_cmd) - printf("[%d] +P: \"(prompt)\"\n",cmdlvl); - concb((char)escape); - if (!quiet) - printf( -"(Recursive command prompt: Resume script with CONTINUE, STOP to stop...)\n" - ); - if (*s) { /* If prompt given */ - makestr(&(prstring[cmdlvl-1]),cmgetp()); /* Save current prompt */ - cmsetp(s); /* Set new one */ - } - return(success = 1); -#endif /* NOSPL */ -} - -#ifdef CKLEARN -VOID -learncmd(s) char *s; { /* Record commands in learned script */ - char buf[64]; - int i, k; - if (learnfp && learning) { /* Only if open and on */ - k = ckstrncpy(buf,s,64); - for (i = 0; i < k; i++) { /* Get top-level command keyword */ - if (buf[i] <= SP) { - buf[i] = NUL; - break; - } - } - k = lookup(cmdtab,buf,ncmd,NULL); /* Look it up */ - if (k == XXCON || k == XXLEARN) /* Don't record CONNECT or LEARN */ - return; - if (k == XXTEL) { - fputs("SET HOST /NETWORK:TCP",learnfp); - fputs(&s[i],learnfp); - fputs(" TELNET /TELNET",learnfp); - fputs("\nIF FAIL STOP 1 Connection failed\n",learnfp); - } else { - fputs(s,learnfp); - fputs("\n",learnfp); - } - } -} -#endif /* CKLEARN */ - - -/* D O C M D -- Do a command */ - -/* - Returns: - -2: user typed an illegal command - -1: reparse needed - 0: parse was successful (even tho command may have failed). -*/ -#ifdef DEBUG -int cmdstats[256] = { -1, -1 }; -#endif /* DEBUG */ - -int -docmd(cx) int cx; { - extern int nolocal, cmkwflgs; - - debug(F101,"docmd entry, cx","",cx); - activecmd = cx; - doconx = ((activecmd == XXCON) || (activecmd == XXTEL) || - (activecmd == XXRLOG) || (activecmd == XXPIPE) || - (activecmd == XXIKSD) || (activecmd == XXPTY)); -/* - Originally all commands were handled with a big switch() statement, - but eventually this started blowing up compilers. Now we have a series - of separate if statements and small switches, with the commands that are - most commonly executed in scipts and loops coming first, to speed up - compute-bound scripts. - */ - -#ifdef DEBUG - if (cmdstats[0] == -1) { /* Count commands */ - int i; /* for tuning... */ - for (i = 0; i < 256; i++) - cmdstats[i] = 0; - } -#endif /* DEBUG */ - - switch (cx) { - case -4: /* EOF */ -#ifdef OSK - if (msgflg) printf("\n"); -#else - if (msgflg) printf("\r\n"); -#endif /* OSK */ - doexit(GOOD_EXIT,xitsta); - case -3: /* Null command */ - return(0); - case -9: /* Like -2, but errmsg already done */ - case -1: /* Reparse needed */ - return(cx); - case -6: /* Special */ - case -2: /* Error, maybe */ - -#ifndef NOSPL -/* - Maybe they typed a macro name. Let's look it up and see. -*/ - if (cx == -6) /* If they typed CR */ - ckstrncat(cmdbuf,"\015",CMDBL); /* add it back to command buffer. */ - if (ifcmd[cmdlvl] == 2) /* Watch out for IF commands. */ - ifcmd[cmdlvl]--; - repars = 1; /* Force reparse */ - cmres(); - cx = XXDO; /* Try DO command */ -#else - return(cx); -#endif /* NOSPL */ - default: - if (cx < 0) - return(cx); - break; - } -#ifdef DEBUG - if (cx < 256) - cmdstats[cx]++; -#endif /* DEBUG */ - - if ((cmkwflgs & CM_PSH) -#ifndef NOPUSH - && nopush -#endif /* NOPUSH */ - ) { - printf("?Access to system disabled\n"); - return(-9); - } - if ((cmkwflgs & CM_LOC) -#ifndef NOLOCAL - && nolocal -#endif /* NOLOCAL */ - ) { - printf("?Connections disabled\n"); - return(-9); - } - -#ifndef NOSPL - /* Used in FOR loops */ - - if (cx == XX_INCR || cx == XXINC || /* _INCREMENT, INCREMENT */ - cx == XX_DECR || cx == XXDEC) /* _DECREMENT, DECREMENT */ - return(doincr(cx)); - - /* Define (or change the definition of) a macro or variable */ - - if (cx == XXUNDEF || cx == XXUNDFX) { -#ifdef IKSD - if (inserver && !ENABLED(en_asg)) { - printf("?Sorry, DEFINE/ASSIGN disabled\n"); - return(-9); - } -#endif /* IKSD */ - return(doundef(cx)); /* [_]UNDEFINE */ - } - if (cx == XXDEF || cx == XXASS || - cx == XXDFX || cx == XXASX) { -#ifdef IKSD - if (inserver && !ENABLED(en_asg)) { - printf("?Sorry, DEFINE/ASSIGN disabled\n"); - return(-9); - } -#endif /* IKSD */ - if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */ - xxdot = 1; /* i.e. with space after it... */ - return(dodef(cx)); /* DEFINE, ASSIGN, etc... */ - } - - /* IF, WHILE, and friends */ - - if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) { - return(doif(cx)); - } - if (cx == XXSWIT) { /* SWITCH */ - return(doswitch()); - } - - /* GOTO, FORWARD, and _FORWARD (used internally by FOR, WHILE, etc) */ - - if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */ - /* Note, here we don't set SUCCESS/FAILURE flag */ -#ifdef COMMENT - if ((y = cmfld("label","",&s,xxstring)) < 0) { - if (y == -3) { - if (cx != XXXFWD) { - printf("?Label name required\n"); - return(-9); - } - } else - return(y); - } - ckstrncpy(lblbuf,s,LBLSIZ); - if ((x = cmcfm()) < 0) return(x); -#else - if ((y = cmtxt("label","",&s,xxstring)) < 0) { - if (y == -3) { - if (cx != XXXFWD) { - printf("?GOTO: Label name required: \"%s\" \"%s\"\n", - atmbuf, - cmdbuf); - return(-9); - } - } else - return(y); - } - ckstrncpy(lblbuf,brstrip(s),LBLSIZ); -#endif /* COMMENT */ - s = lblbuf; - debug(F111,"GOTO target",s,cx); - return(dogoto(s,cx)); - } - if (cx == XXDO || cx == XXMACRO) { /* DO (a macro) */ - char mnamebuf[16]; /* (buffer for controlled temp name) */ - struct FDB kw, fl; - int mx; /* Macro index (on stack!) */ - - debug(F101,"XXMACRO 0",line,cx); - if (cx == XXDO) { - if (nmac == 0) { - printf("\n?No macros defined\n"); - return(-9); - } - for (y = 0; y < nmac; y++) { /* copy the macro table into a */ - mackey[y].kwd = mactab[y].kwd; /* regular keyword table */ - mackey[y].kwval = y; /* with value = pointer to macro tbl */ - mackey[y].flgs = mactab[y].flgs; - } - cmfdbi(&kw, /* First FDB - macro name */ - _CMKEY, /* fcode */ - "Macro", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nmac, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: 0 = cmkey */ - xxstring, /* Processing function */ - mackey, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* 2nd FDB - for "{" */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - x = cmfdb(&kw); /* Parse something */ - if (x < 0) { /* Error */ - if (x == -3) { - printf("?Macro name required\n"); - return(-9); - } else - return(x); - } - if (cmresult.fcode == _CMKEY) { - extern int mtchanged; - char * macroname = NULL; - - /* In case args include an \fexec() that changes the macro table */ - - mx = x; /* Save macro index on stack */ - mtchanged = 0; /* Mark state of macro table */ - makestr(¯oname,mactab[mx].kwd); /* Save name */ - - if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0) - return(y); /* Get macro args */ - - if (mtchanged) { /* Macro table changed? */ - mx = mlook(mactab,macroname,nmac); /* Look up name again */ - } - if (macroname) - free(macroname); - - return(dodo(mx,s,cmdstk[cmdlvl].ccflgs) < 1 ? - (success = 0) : 1); - } - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* _CMFLD */ - if (atmbuf[0] == '{') { - if ((y = cmcfm()) < 0) - return(y); - } - } else { /* XXMACRO ("immediate macro") */ - int k = 0; - line[k++] = '{'; - line[k++] = SP; - line[k] = NUL; - debug(F111,"XXMACRO A",line,k); - /* Defer evaluation of variables until the commands are exec'd */ - if ((y = cmtxt("Braced list of commands","",&s,NULL)) < 0) - return(y); - k = ckstrncpy(line+k,s,LINBUFSIZ-k); - debug(F111,"XXMACRO B",line,k); - } - x = strlen(line); - if ((line[0] == '{' && line[x-1] != '}') || line[0] == '}') - return(-2); - if (line[0] != '{' && line[x-1] != '}') { - /* Unknown command. If ON_UNKNOWN_COMMAND macro is defined, */ - /* parse args and then execute it, but only if it is not */ - /* already active. */ - int k = -1; - if (!unkmacro) { - k = mxlook(mactab,"on_unknown_command",nmac); - } - if (k > -1) { - ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ); - z = maclvl; /* Save the current maclvl */ - if ((y = cmtxt("text","",&s,xxstring)) < 0) - return(y); - ckstrncat(tmpbuf," ",TMPBUFSIZ); - ckstrncat(tmpbuf,s,TMPBUFSIZ); - unkmacro = 1; - debug(F110,"ON_UNKNOWN_COMMAND",s,0); - dodo(k,tmpbuf,cmdstk[cmdlvl].ccflgs); /* Run the macro */ - while (maclvl > z) { - sstate = (CHAR) parser(1); - if (sstate) proto(); - } - debug(F101,"UNKMAC loop exit maclvl","",maclvl); - unkmacro = 0; - return(success); - } - if (x > 0) - printf("?Not a command or macro name: \"%s\"\n",line); - else - printf("?Not a command or macro name.\n"); - return(-9); - } - s = brstrip(line); - sprintf(mnamebuf," ..tmp:%03d",cmdlvl); /* safe (16) */ - x = addmac(mnamebuf,s); - return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1); - } - - if (cx == XXLBL) { /* LABEL */ - if ((x = cmfld("label","",&s,xxstring)) < 0) { - if (x == -3) { -#ifdef COMMENT - printf("?LABEL: Label name required: \"%s\"\n", cmdbuf); - return(-9); -#else - s = ""; -#endif /* COMMENT */ - } else return(x); - - } - debug(F111,"LABEL",s,x); - if ((x = cmcfm()) < 0) return(x); - return(0); - } - - if (cx == XXEVAL || cx == XX_EVAL) /* _EVALUATE, EVALUATE */ - return(doeval(cx)); - -#ifndef NOSEXP - if (cx == XXSEXP) { /* Lisp-like S-Expression */ - struct stringarray * q; - char /* *p, *r, */ *tmp, *m; - int i, k, n, quote = 0, contd = 0, size = 0, len = 0; - extern int sexprc, sexppv; - - tmp = tmpbuf; /* Buffer to collect SEXP */ - tmpbuf[0] = NUL; /* Clear it */ - size = TMPBUFSIZ; /* Capacity of buffer */ - sexprc = -1; /* Assume bad input */ - n = 0; /* Paren balance counter */ - - while (1) { /* Allow SEXP on multiple lines */ - m = contd ? - "Continuation of S-Expression" : - "S-Expression (\"help sexp\" for details)"; - x = cmtxt(m,"",&s,xxstring); - if (x < 0) - return(x); - if (!*s) /* Needed for (=) and (:) */ - s = atmbuf; - k = ckmakmsg(tmp, size, contd ? " " : "(", s, NULL, NULL); - if (k < 1) { - printf("?SEXP too long - %d max\n",TMPBUFSIZ); - return(-9); - } - debug(F111,contd ? "sexp contd" : "sexp",s,k); - - for (i = len; i < len+k; i++) { /* Check balance */ - if (!quote && tmpbuf[i] == CMDQ) { - quote = 1; - continue; - } - if (quote) { - quote = 0; - continue; - } - if (tmpbuf[i] == '(') - n++; - else if (tmpbuf[i] == ')') - n--; - } - if (n == 0) { /* Break when balanced */ - break; - } - if (n < 0) { /* Too many right parens */ - printf("?Unbalanced S-Expression: \"%s\"\n",tmpbuf); - return(-9); - } - contd++; /* Need more right parens */ - cmini(ckxech); /* so keep parsing */ - tmp += k; /* adjust buffer pointer */ - size -= k; /* and capacity */ - len += k; /* and length so far */ - } - s = tmpbuf; - makestr(&lastsexp,s); - q = cksplit(1,SEXPMAX,s,NULL,NULL,8,0,0); /* Precheck for > 1 SEXP */ - debug(F101,"sexp split","",q->a_size); - - if (q->a_size == 1) { /* We should get exactly one back */ - char * result, * dosexp(); - sexprc = 0; /* Reset out-of-band return code */ - result = dosexp(s); /* Get result */ - debug(F111,"sexp result",result,sexprc); - if (sexprc == 0) { /* Success */ - /* Echo the result if desired */ - if ((!xcmdsrc && sexpecho != SET_OFF) || sexpecho == SET_ON) - printf(" %s\n",result ? result : ""); - makestr(&sexpval,result); - success = sexppv > -1 ? sexppv : 1; - return(success); - } - } - if (sexprc < 0) - printf("?Invalid S-Expression: \"%s\"\n",lastsexp); - return(-9); - } -#endif /* NOSEXP */ - -#endif /* NOSPL */ - - if (cx == XXECH || cx == XXXECH || cx == XXVOID -#ifndef NOSPL - || cx == XXAPC -#endif /* NOSPL */ - ) { /* ECHO or APC */ - if ((x = cmtxt((cx == XXECH || cx == XXXECH) ? - "Text to be echoed" : - ((cx == XXVOID) ? "Text" : - "Application Program Command text"), - "", - &s, - xxstring - ) - ) < 0) - return(x); - if (!s) s = ""; -#ifdef COMMENT -/* This is to preserver the pre-8.0 behavior but it's too confusing */ - x = strlen(s); - x = (x > 1) ? ((s[0] == '"' && s[x-1] == '"') ? 1 : 0) : 0; -#endif /* COMMENT */ - s = brstrip(s); /* Strip braces and doublequotes */ - if (cx == XXECH) { /* ECHO */ -#ifndef NOSPL - if (!fndiags || fnsuccess) { -#endif /* NOSPL */ -#ifdef COMMENT - /* The "if (x)" business preserves previous behavior */ - /* by putting back the doublequotes if they were included. */ - if (x) - printf("\"%s\"\n",s); - else -#endif /* COMMENT */ - printf("%s\n",s); -#ifndef NOSPL - } -#endif /* NOSPL */ - } else if (cx == XXXECH) { /* XECHO */ - if (x) - printf("\"%s\"",s); - else - printf("%s",s); -#ifdef UNIX - fflush(stdout); -#endif /* UNIX */ - } else if (cx == XXAPC) { /* APC */ -#ifdef CK_APC - if (apcactive == APC_LOCAL || - (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))) - return(success = 0); -#endif /* CK_APC */ - if (!local) { - printf("%c_%s%c\\",ESC,s,ESC); -#ifdef UNIX - fflush(stdout); -#endif /* UNIX */ - - } else { /* Local mode - have connection */ -#ifndef NOSPL - if (ckmakxmsg(tmpbuf, /* Form APC string in buffer */ - TMPBUFSIZ, - ckctoa((char)ESC), - ckctoa('_'), - s, - ckctoa((char)ESC), - ckctoa('\\'), - NULL,NULL,NULL,NULL,NULL,NULL,NULL - ) > 0) - return(success = dooutput(tmpbuf, XXOUT)); - printf("?Too long\n"); - return(-9); -#else - printf("%c_%s%c\\",ESC,s,ESC); -#endif /* NOSPL */ - } - } - return(success = 1); - } - -#ifndef NOSPL -/* Copy macro args from/to two levels up, used internally by _floop et al. */ - if (cx == XXGTA || cx == XXPTA) { /* _GETARGS, _PUTARGS */ - int x; - debug(F101,"docmd XXGTA","",XXGTA); - debug(F101,"docmd cx","",cx); - debug(F101,"docmd XXGTA maclvl","",maclvl); - x = dogta(cx); - debug(F101,"docmd dogta returns","",x); - debug(F101,"docmd dogta maclvl","",maclvl); - return(x); - } -#endif /* NOSPL */ - -#ifndef NOSPL -#ifdef CKCHANNELIO - if (cx == XXFILE) - return(dofile(cx)); - else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP || - cx == XXF_CL || cx == XXF_SE || cx == XXF_RW || - cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO) - return(dofile(cx)); -#endif /* CKCHANNELIO */ - -/* ASK, ASKQ, READ */ - if (cx == XXASK || cx == XXASKQ || cx == XXREA || - cx == XXRDBL || cx == XXGETC || cx == XXGETK) { - return(doask(cx)); - } -#endif /* NOSPL */ - -#ifndef NOFRILLS - if (cx == XXBUG) { /* BUG */ - if ((x = cmcfm()) < 0) return(x); - return(dobug()); - } -#endif /* NOFRILLS */ - -#ifndef NOXFER - if (cx == XXBYE) { /* BYE */ - extern int ftp_cmdlin; - if ((x = cmcfm()) < 0) return(x); - -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) { - extern int stayflg, ftp_fai; - success = ftpbye(); - if (ftp_cmdlin && !stayflg && !local) - doexit(ftp_fai ? BAD_EXIT : GOOD_EXIT,-1); - else - return(success); - } -#endif /* NEWFTP */ - - if (!local) { - printf("?No connection - use EXIT to quit.\n"); - return(-9); - } - -#ifdef CK_XYZ - if (protocol != PROTO_K) { - printf("?Sorry, BYE only works with Kermit protocol\n"); - return(-9); - } -#endif /* CK_XYZ */ - -#ifdef IKS_OPTION - if ( -#ifdef CK_XYZ - protocol == PROTO_K && -#endif /* CK_XYZ */ - !iks_wait(KERMIT_REQ_START,1)) { - printf( - "?A Kermit Server is not available to process this command\n"); - return(-9); /* Correct the return code */ - } -#endif /* IKS_OPTION */ - - bye_active = 1; - sstate = setgen('L',"","",""); - if (local) ttflui(); /* If local, flush tty input buffer */ - return(0); - } -#endif /* NOXFER */ - - if (cx == XXBEEP) { /* BEEP */ - int x; -#ifdef OS2 - int y; - if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information", - xxstring)) < 0 ) - return (y); - if ((x = cmcfm()) < 0) return(x); - bleep((short)y); /* y is one of the BP_ values */ -#else /* OS2 */ - if ((x = cmcfm()) < 0) return(x); -#ifndef NOSPL - bleep(BP_NOTE); -#else - putchar('\07'); -#endif /* NOSPL */ -#endif /* OS2 */ - return(0); - } - -#ifndef NOFRILLS - if (cx == XXCLE) /* CLEAR */ - return(success = doclear()); -#endif /* NOFRILLS */ - - if (cx == XXCOM) { /* COMMENT */ - if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0) - return(x); - /* Don't change SUCCESS flag for this one */ - return(0); - } - -#ifndef NOLOCAL - if (cx == XXCON || cx == XXCQ) /* CONNECT or CONNECT /QUIETLY */ - return(doxconn(cx)); -#endif /* NOLOCAL */ - -#ifndef NOFRILLS -#ifdef ZCOPY - if (cx == XXCPY) { /* COPY a file */ -#ifdef IKSD - if (inserver && !ENABLED(en_cpy)) { - printf("?Sorry, COPY is disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef CK_APC - if (apcactive == APC_LOCAL || - (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)) - ) - return(success = 0); -#endif /* CK_APC */ - return(docopy()); - } -#endif /* ZCOPY */ -#ifdef NT - if ( cx == XXLINK ) { -#ifdef IKSD - if (inserver && !ENABLED(en_cpy)) { - printf("?Sorry, LINK (COPY) is disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef CK_APC - if (apcactive == APC_LOCAL || - (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)) - ) - return(success = 0); -#endif /* CK_APC */ - return(dolink()); - } -#endif /* NT */ -#endif /* NOFRILLS */ - - /* CD and friends */ - if (cx == XXCWD || cx == XXCDUP || cx == XXBACK || - cx == XXLCWD || cx == XXLCDU || cx == XXKCD) { -#ifdef LOCUS - if (!locus) { - if (cx == XXCWD) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZCWD)); -#endif /* NOXFER */ - } else if (cx == XXCDUP) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZCDU)); -#endif /* NOXFER */ - } - } -#endif /* LOCUS */ -#ifdef IKSD - if (inserver && !ENABLED(en_cwd)) { - printf("?Sorry, changing directories is disabled\n"); - return(-9); - } -#endif /* IKSD */ - return(success = docd(cx)); - } - - if (cx == XXCHK) /* CHECK */ - return(success = dochk()); - - if (cx == XXCLO) { /* CLOSE */ - x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close", - "connection",xxstring); - if (x == -3) { - printf("?You must say which file or log\n"); - return(-9); - } - if (x < 0) return(x); - if ((y = cmcfm()) < 0) return(y); -#ifndef NOLOCAL - if (x == 9999) { /* CLOSE CONNECTION */ - x = clsconnx(0); - switch (x) { - case 0: - if (msgflg) printf("?Connection was not open\n"); - case -1: - return(0); - case 1: - whyclosed = WC_CLOS; - return(1); - } - return(0); - } -#endif /* NOLOCAL */ - y = doclslog(x); - success = (y == 1); - return(success); - } - -#ifndef NOSPL - if (cx == XXDCL || cx == XXUNDCL) { /* DECLARE an array */ - return(dodcl(cx)); - } -#endif /* NOSPL */ - -#ifndef NODIAL - if (cx == XXRED || cx == XXDIAL || cx == XXPDIA || - cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */ -#ifdef VMS - extern int batch; -#else -#ifdef UNIXOROSK - extern int backgrd; -#endif /* UNIXOROSK */ -#endif /* VMS */ - x = dodial(cx); - debug(F101,"dodial returns","",x); - if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) && - (x > 0) && /* If DIAL or REDIAL succeeded */ - (dialsta != DIA_PART) && /* and it wasn't partial */ - (dialcon > 0)) { - if ((dialcon == 1 || /* And DIAL CONNECT is ON, */ - ((dialcon == 2) && /* or DIAL CONNECT is AUTO */ - !xcmdsrc /* and we're at top level... */ -#ifdef VMS - && !batch /* Not if running from batch */ -#else -#ifdef UNIXOROSK - && !backgrd /* Not if running in background */ -#endif /* UNIXOROSK */ -#endif /* VMS */ - ))) /* Or AUTO */ - x = doconect(dialcq, /* Then also CONNECT */ - cmdlvl == 0 ? 1 : 0 - ); - if (ttchk() < 0) - dologend(); - } - return(success = x); - } -#endif /* NODIAL */ - -#ifndef NOPUSH -#ifdef CK_REXX - if (cx == XXREXX) { /* REXX */ - extern int nopush; - if ( nopush ) - return(success=0); - return(dorexx()); - } -#endif /* CK_REXX */ -#endif /* NOPUSH */ - -#ifndef NOFRILLS - if (cx == XXDEL || cx == XXLDEL) { /* DELETE */ -#ifdef LOCUS - if (!locus && cx != XXLDEL) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZDEL)); -#endif /* NOXFER */ - } -#endif /* LOCUS */ -#ifdef IKSD - if (inserver && (!ENABLED(en_del) -#ifdef CK_LOGIN - || isguest -#endif /* CK_LOGIN */ - )) { - printf("?Sorry, DELETE is disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ - return(dodel()); - } -#endif /* NOFRILLS */ - - if (cx == XXDIR || cx == XXLS || cx == XXLDIR) { /* DIRECTORY or LS */ -#ifdef LOCUS - if (!locus && cx != XXLDIR) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZDIR)); -#endif /* NOXFER */ - } -#endif /* LOCUS */ -#ifdef IKSD - if (inserver && !ENABLED(en_dir)) { - printf("?Sorry, DIRECTORY is disabled\n"); - return(-9); - } -#endif /* IKSD */ - return(dodir(cx)); - } - -#ifndef NOSPL - if (cx == XXELS) /* ELSE */ - return(doelse()); -#endif /* NOSPL */ - -#ifndef NOSERVER -#ifndef NOFRILLS - if (cx == XXENA || cx == XXDIS) { /* ENABLE, DISABLE */ - s = (cx == XXENA) ? - "Server function to enable" : - "Server function to disable"; - - if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) { - if (x == -3) { - printf("?Name of server function required\n"); - return(-9); - } else return(x); - } - if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) { - if (y == -3) { - printf("?Please specify remote, local, or both\n"); - return(-9); - } else return(y); - } - if (cx == XXDIS) /* Disabling, not enabling */ - y = 3 - y; - if ((z = cmcfm()) < 0) return(z); -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ -#ifdef IKSD - /* This may seem like it duplicates the work in doenable() */ - /* but this code returns failure whereas doenable() returns */ - /* success. */ - if (inserver && -#ifdef IKSDCONF - iksdcf && -#endif /* IKSDCONF */ - (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO || - isguest)) - return(success = 0); -#endif /* IKSD */ - return(doenable(y,x)); - } -#endif /* NOFRILLS */ -#endif /* NOSERVER */ - -#ifndef NOSPL - if (cx == XXRET) { /* RETURN */ - if ((x = cmtxt("Optional return value","",&s,NULL)) < 0) - return(x); - s = brstrip(s); /* Strip braces */ - if (cmdlvl == 0) /* At top level, nothing happens... */ - return(success = 1); - switch (cmdstk[cmdlvl].src) { /* Action depends on command source */ - case CMD_TF: /* Command file */ - popclvl(); /* Pop command level */ - return(success = 1); /* always succeeds */ - case CMD_MD: /* Macro */ - case CMD_KB: /* Prompt */ - return(doreturn(s)); /* Trailing text is return value. */ - default: /* Shouldn't happen */ - return(-2); - } - } -#endif /* NOSPL */ - -#ifndef NOSPL - if (cx == XXOPE) /* OPEN */ - return(doopen()); -#endif /* NOSPL */ - -#ifndef NOSPL - if (cx == XXOUT || cx == XXLNOUT) { /* OUTPUT or LINEOUT */ - if ((x = cmtxt("Text to be output","",&s,NULL)) < 0) - return(x); -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ - debug(F110,"OUTPUT 1",s,0); - s = brstrip(s); /* Strip enclosing braces, */ - debug(F110,"OUTPUT 2",s,0); -/* - I don't think I could ever fully explain this in a million years... - We have read the user's string without calling the variable-expander - function. Now, before we call it, we have to double backslashes that - appear before \N, \B, \L, and \ itself, so the expander function will - reduce them back to single backslashes, so when we call dooutput()... - But it's more complicated than that. -*/ - if (cmdgquo()) { /* Only if COMMAND QUOTING ON ... */ - for (x = 0, y = 0; s[x]; x++, y++) { - if (s[x] == CMDQ) { - char c = s[x+1]; - if (c == 'n' || c == 'N' || - c == 'b' || c == 'B' || - c == 'l' || c == 'L' || - c == CMDQ) - line[y++] = CMDQ; - } - line[y] = s[x]; - } - line[y++] = '\0'; /* Now expand variables, etc. */ - debug(F110,"OUTPUT 3",line,0); - s = line+y+1; - x = LINBUFSIZ - (int) strlen(line) - 1; - debug(F101,"OUTPUT size","",x); - if (zzstring(line,&s,&x) < 0) - return(success = 0); - s = line+y+1; - debug(F110,"OUTPUT 4",s,0); - } - success = dooutput(s,cx); - return(success); - } -#endif /* NOSPL */ - -#ifdef ANYX25 -#ifndef IBMX25 - if (cx == XXPAD) { /* PAD commands */ - x = cmkey(padtab,npadc,"PAD command","",xxstring); - if (x == -3) { - printf("?You must specify a PAD command to execute\n"); - return(-9); - } - if (x < 0) return(x); - - switch (x) { - case XYPADL: - if (x25stat() < 0) - printf("Sorry, you must 'set network' & 'set host' first\r\n"); - else { - x25clear(); - initpad(); - } - break; - case XYPADS: - if (x25stat() < 0) - printf("Not connected\r\n"); - else { - extern int linkid, lcn; - conol("Connected thru "); - conol(ttname); - printf(", Link id %d, Logical channel number %d\r\n", - linkid,lcn); - } - break; - case XYPADR: - if (x25stat() < 0) - printf("Sorry, you must 'set network' & 'set host' first\r\n"); - else - x25reset(0,0); - break; - case XYPADI: - if (x25stat() < 0) - printf("Sorry, you must 'set network' & 'set host' first\r\n"); - else - x25intr(0); - } - return(0); - } -#endif /* IBMX25 */ -#endif /* ANYX25 */ - -#ifndef NOSPL - if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */ - return(dopaus(cx)); -#endif /* NOSPL */ - -#ifndef NOFRILLS - if (cx == XXPRI) { -#ifdef IKSD -#ifdef CK_LOGIN - if (inserver && (isguest || !ENABLED(en_pri))) { - printf("?Sorry, printing is disabled\n"); - return(-9); - } -#endif /* CK_LOGIN */ -#endif /* IKSD */ - if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) { - if (x == -3) { - printf("?A file specification is required\n"); - return(-9); - } else return(x); - } - if (y != 0) { - printf("?Wildcards not allowed\n"); - return(-9); - } - ckstrncpy(line,s,LINBUFSIZ); - s = ""; -#ifndef NT - if ((x = cmtxt("Local print command options, or carriage return","",&s, - xxstring)) < 0) - return(x); -#endif /* NT */ - if ((x = cmcfm()) < 0) - return(x); - return(success = (zprint(s,line) == 0) ? 1 : 0); - } -#endif /* NOFRILLS */ - -#ifdef TCPSOCKET -#ifndef NOPUSH - if (cx == XXPNG) /* PING an IP host */ - return(doping()); -#endif /* NOPUSH */ - -#ifndef NOFTP - if (cx == XXFTP) /* FTP */ -#ifdef SYSFTP -#ifndef NOPUSH - return(doftp()); /* Just runs system's ftp program */ -#else - return(-2); -#endif /* NOPUSH */ -#else - return(doxftp()); -#endif /* SYSFTP */ -#endif /* NOFTP */ -#endif /* TCPSOCKET */ - - if (cx == XXPWD || cx == XXLPWD) { /* PWD */ -#ifdef OS2 - char *pwp; -#endif /* OS2 */ - if ((x = cmcfm()) < 0) - return(x); -#ifdef LOCUS - if (!locus && cx != XXLPWD) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZPWD)); -#endif /* NOXFER */ - } -#endif /* LOCUS */ - -#ifndef MAC -#ifndef OS2 -#ifdef UNIX - printf("%s\n",zgtdir()); -#else - xsystem(PWDCMD); -#endif /* UNIX */ - return(success = 1); /* Blind faith */ -#else /* OS2 */ - if (pwp = zgtdir()) { - if (*pwp) { -#ifdef NT - line[0] = NUL; - ckGetLongPathName(pwp,line,LINBUFSIZ); - line[LINBUFSIZ-1] = NUL; - tmpbuf[0] = NUL; - GetShortPathName(pwp,tmpbuf,TMPBUFSIZ); - tmpbuf[TMPBUFSIZ-1] = NUL; - pwp = line; - if (!strcmp(line,tmpbuf)) { -#endif /* NT */ - printf("%s\n",pwp); -#ifdef NT - } else { - printf(" Long name: %s\n",line); - printf(" Short name: %s\n",tmpbuf); - } -#endif /* NT */ - } - return(success = ((int)strlen(pwp) > 0)); - } else return(success = 0); -#endif /* OS2 */ -#else /* MAC */ - if (pwp = zgtdir()) { - printf("%s\n",pwp); - return(success = ((int)strlen(pwp) > 0)); - } else return(success = 0); -#endif /* MAC */ - } - - if (cx == XXQUI || cx == XXEXI) { /* EXIT, QUIT */ - extern int quitting; - - if ((y = cmnum("exit status code",ckitoa(xitsta),10,&x,xxstring)) < 0) - return(y); - if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0) - return(y); - s = brstrip(s); - ckstrncpy(line,s,LINBUFSIZ); - - if (!hupok(0)) /* Check if connection still open */ - return(success = 0); - - if (line[0]) /* Print EXIT message if given */ - printf("%s\n",(char *)line); - - quitting = 1; /* Flag that we are quitting. */ - -#ifdef VMS - doexit(GOOD_EXIT,x); -#else -#ifdef OSK -/* Returning any codes here makes the OS-9 shell print an error message. */ - doexit(GOOD_EXIT,-1); -#else -#ifdef datageneral - doexit(GOOD_EXIT,x); -#else - doexit(x,-1); -#endif /* datageneral */ -#endif /* OSK */ -#endif /* VMS */ - } - -#ifndef NOXFER -#ifndef NOFRILLS - if (cx == XXERR) { /* ERROR */ -#ifdef CK_XYZ - if (protocol != PROTO_K) { - printf("Sorry, E-PACKET only works with Kermit protocol\n"); - return(-9); - } -#endif /* CK_XYZ */ - if ((x = cmcfm()) < 0) return(x); - ttflui(); - epktflg = 1; - sstate = 'a'; - return(0); - } -#endif /* NOFRILLS */ - - if (cx == XXFIN) { /* FINISH */ -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) - return(ftpbye()); -#endif /* NEWFTP */ -#ifdef CK_XYZ - if (protocol != PROTO_K) { - printf("Sorry, FINISH only works with Kermit protocol\n"); - return(-9); - } -#endif /* CK_XYZ */ - if ((x = cmcfm()) < 0) return(x); - -#ifdef IKS_OPTION - if ( -#ifdef CK_XYZ - protocol == PROTO_K && -#endif /* CK_XYZ */ - !iks_wait(KERMIT_REQ_START,1)) { - printf( - "?A Kermit Server is not available to process this command\n"); - return(-9); /* Correct the return code */ - } -#endif /* IKS_OPTION */ - - sstate = setgen('F',"","",""); - if (local) ttflui(); /* If local, flush tty input buffer */ - return(0); - } -#endif /* NOXFER */ - -#ifndef NOSPL - if (cx == XXFOR) /* FOR loop */ - return(dofor()); -#endif /* NOSPL */ - -#ifndef NOXFER - /* GET MGET REGET RETRIEVE etc */ - if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) { -#ifdef IKSD - if (inserver && !ENABLED(en_sen)) { - printf("?Sorry, reception of files is disabled\n"); - return(-9); - } -#endif /* IKSD */ - return(doxget(cx)); - } -#endif /* NOXFER */ - -#ifndef NOSPL -#ifndef NOFRILLS - if (cx == XXGOK) { /* GETOK */ - return(success = doask(cx)); - } -#endif /* NOFRILLS */ -#endif /* NOSPL */ - - if (cx == XXHLP) { /* HELP */ -#ifdef NOHELP - return(dohlp(XXHLP)); -#else - x = cmkey2(cmdtab,ncmd,"\nCommand or topic","help",toktab,xxstring,3); - debug(F101,"HELP command x","",x); - if (x == -5) { - y = chktok(toktab); - debug(F101,"HELP cmkey token","",y); - /* ungword(); */ - switch (y) { -#ifndef NOPUSH - case '!': x = XXSHE; break; -#endif /* NOPUSH */ - case '#': x = XXCOM; break; - case ';': x = XXCOM; break; -#ifndef NOSPL - case '.': x = XXDEF; break; - case ':': x = XXLBL; break; -#ifndef NOSEXP - case '(': x = XXSEXP; break; -#endif /* NOSEXP */ -#endif /* NOSPL */ - case '&': x = XXECH; break; - default: - printf("\n?Invalid - %s\n",cmdbuf); - x = -2; - } - } - makestr(&hlptok,atmbuf); - debug(F111,"HELP token",hlptok,x); - return(dohlp(x)); -#endif /* NOHELP */ - } - -#ifndef NOHELP - if (cx == XXINT) /* INTRO */ - return(hmsga(introtxt)); - if (cx == XXNEW) { /* NEWS */ - int x; - extern char * k_info_dir; - x = hmsga(newstxt); - return(x); - } - -#ifdef OS2ONLY - if (cx == XXUPD) { /* View UPDATE file */ - extern char exedir[]; - char * pTopic; - char updstr[2048]; - if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0) - return x; -#ifdef COMMENT - sprintf(updstr, - "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\ -%s\\docs\\dialing.inf+%s\\docs\\modems.inf %s", - exedir,exedir,exedir,exedir,pTopic - ); -#else - if (ckmakxmsg(updstr, - 2048, - "start view ", - exedir, - "\\docs\\k2.inf+", - exedir, - "\\docs\\using_ck.inf+", - exedir, - "\\docs\\dialing.inf+", - exedir, - "\\docs\\modems.inf ", - pTopic, - NULL, - NULL - ) > 0) -#endif /* COMMENT */ - system(updstr); - return(success = 1); - } -#endif /* OS2ONLY */ -#endif /* NOHELP */ - -#ifndef NOLOCAL - if (cx == XXHAN) { /* HANGUP */ - if ((x = cmcfm()) < 0) return(x); -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen())) - return(success = ftpbye()); -#endif /* NEWFTP */ -#ifndef NODIAL - if ((x = mdmhup()) < 1) { - debug(F101,"HANGUP mdmup","",x); -#endif /* NODIAL */ - x = tthang(); - debug(F101,"HANGUP tthang","",x); - x = (x > -1); -#ifndef NODIAL - } - dialsta = DIA_UNK; -#endif /* NODIAL */ - whyclosed = WC_CLOS; - ttchk(); /* In case of CLOSE-ON-DISCONNECT */ - dologend(); -#ifdef OS2 - if (x) - DialerSend(OPT_KERMIT_HANGUP, 0); -#endif /* OS2 */ - if (x) haveline = 0; - return(success = x); - } -#endif /* NOLOCAL */ - -#ifndef NOSPL - /* INPUT, REINPUT, and MINPUT */ - - if (cx == XXINP || cx == XXREI || cx == XXMINP) { - long zz; - extern int ispattern, isjoin; - - struct FDB sw, nu, fl; - int fc, havetime = 0; - char * m; - - if (cx == XXREI) { - m = "Timeout in seconds (ignored)"; - } else { - m = "Seconds to wait for input,\n or time of day hh:mm:ss, \ - or switch"; - } - innomatch = 0; /* Initialize switch value(s) */ - - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - m, /* helpmsg */ - ckitoa(indef), /* default */ - "", /* addtl string data */ - ninputsw, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - inputsw, /* Keyword table */ - &nu /* Pointer to next FDB */ - ); - cmfdbi(&nu, - _CMNUM, /* Number */ - m, /* Help message */ - ckitoa(indef), /* default */ - "", /* N/A */ - 10, /* Radix = 10 */ - 0, /* N/A */ - xxstring, /* Processing function */ - NULL, /* N/A */ - &fl /* Next */ - ); - cmfdbi(&fl, /* Time of day hh:mm:ss */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - fc = (cx == XXREI) ? cmfdb(&nu) : cmfdb(&sw); /* Parse something */ - - while (!havetime) { - if (fc < 0) { /* Error */ - if (fc == -3) { - printf("?Syntax error in INPUT-class command\n"); - return(-9); - } else - return(fc); - } - switch (cmresult.fcode) { - case _CMKEY: /* Switch */ - if (cmresult.nresult == INPSW_NOM) /* /NOMATCH */ - innomatch = 1; - m = "Seconds to wait for input,\n or time of day hh:mm:ss"; - cmfdbi(&nu,_CMNUM,m,"","",10,0,xxstring,NULL,&fl); - cmfdbi(&fl,_CMFLD,"","","",0,0,xxstring,NULL,NULL); - fc = cmfdb(&nu); /* Parse something */ - continue; - - case _CMNUM: /* Seconds to time out */ - x = cmresult.nresult; -#ifdef CKFLOAT - if (inscale != 1.0) /* Scale */ - x *= inscale; -#endif /* CKFLOAT */ - havetime++; - break; - - case _CMFLD: - zz = tod2sec(atmbuf); /* Convert to secs since midnight */ - if (zz < 0L) { - printf("?Number, expression, or time of day required\n"); - return(-9); - } else { - char now[32]; /* Current time */ - char *p; - long tnow; - p = now; - ztime(&p); - tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17); - if (zz < tnow) /* User's time before now */ - zz += 86400L; /* So make it tomorrow */ - zz -= tnow; /* Seconds from now. */ - if (zz > -1L) { - x = zz; - if (zz != (long) x) { - printf( -"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n" -); - return(-9); - } - } - havetime++; - } - break; - default: - printf("?Internal error\n"); - return(-9); - } - } - /* Now parse the search text */ - -#ifdef CK_MINPUT - for (y = 0; y < MINPMAX; y++) { /* Initialize strings */ - mp[y] = 0; /* Assume it's not a pattern */ - if (ms[y]) { - free(ms[y]); /* Free old strings, if any */ - ms[y] = NULL; - } - } - if (cx == XXMINP) { /* MINPUT */ - int i, k = 0, n = 0; - struct stringarray * q; - keepallchars = 1; - while (k < MINPMAX) { - if ((y = cmfld("String or pattern","",&s,xxstring)) < 0) { - if (y == -3) { - if ((y = cmcfm()) < 0) - return(y); - break; - } else { - return(y); - } - } - debug(F111,"MINPUT field",s,k); - if (isjoin) { - if ((q = cksplit(1,0,s," ",(char *)c1chars,3,0,0))) { - char ** ap = q->a_head; - n = q->a_size; - debug(F101,"minput cksplit size","",n); - for (i = 1; i <= n && k < MINPMAX; i++) { - if (!ap[i]) /* Add non-empty elements */ - continue; - if (!*(ap[i])) - continue; - makestr(&(ms[k]),ap[i]); - debug(F111,"MINPUT JOIN",ms[k],k); - k++; - } - } - } else { - if (s) if (*s) { - makestr(&(ms[k]),brstrip(s)); - if (ispattern) mp[k] = 1; - debug(F111,"MINPUT",ms[k],ispattern); - k++; - } - } - } - keepallchars = 0; - } else { -#endif /* CK_MINPUT */ - - /* INPUT or REINPUT */ - - if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0) - return(y); - mp[0] = ispattern ? 1 : 0; - makestr(&(ms[0]),brstrip(s)); - ms[1] = NULL; - -#ifdef CK_MINPUT - } -#endif /* CK_MINPUT */ - -#ifdef COMMENT - printf("/NOMATCH=%d\n",innomatch); - printf("Timeout=%d\n",x); - return(1); -#endif /* COMMENT */ - - if (cx == XXINP || cx == XXMINP) { /* Not REINPUT... */ - i_active = 1; - /* Go try to input the search string */ - success = doinput(x,ms,mp,innomatch); - i_active = 0; - } else { /* REINPUT */ - success = doreinp(x,ms[0],ispattern); - } - if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */ - popclvl(); /* If so, pop command level. */ - if (pflag && cmdlvl == 0) { - if (cx == XXINP) printf("?INPUT timed out\n"); - if (cx == XXMINP) printf("?MINPUT timed out\n"); - if (cx == XXREI) printf("?REINPUT failed\n"); - } - } - return(success); /* Return do(re)input's return code */ - } - -#endif /* NOSPL */ - - if (cx == XXLOG) { /* LOG */ - x = cmkey(logtab,nlog,"What to log","",xxstring); - if (x == -3) { - printf("?Type of log required\n"); - return(-9); - } - if (x < 0) return(x); - x = dolog(x); - if (x < 0) - return(x); - else - return(success = x); - } - - if (cx == XXLOGIN) { /* (REMOTE) LOGIN */ -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) - return(success = doftpusr()); -#endif /* NEWFTP */ -#ifdef IKSD - if (inserver) { - printf("?Already logged in\n"); - return(-9); - } else -#endif /* IKSD */ - { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZLGI)); -#endif /* NOXFER */ - } - } - if (cx == XXLOGOUT) { /* (REMOTE) LOGOUT */ -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) - return(success = doftpres()); -#endif /* NEWFTP */ - -#ifdef IKSD - if (inserver) { - if ((x = cmcfm()) < 0) - return(x); - doexit(GOOD_EXIT,xitsta); - } else -#endif /* IKSD */ - if (!local || (network && ttchk() < 0)) { - printf("?No connection.\n"); - return(-9); - } else { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZLGO)); -#endif /* NOXFER */ - } - } - -#ifndef NOSCRIPT - if (cx == XXLOGI) { /* UUCP-style script */ - if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0) - return(x); -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ -#ifdef VMS - conres(); /* For Ctrl-C to work... */ -#endif /* VMS */ - return(success = dologin(s)); /* Return 1=completed, 0=failed */ - } -#endif /* NOSCRIPT */ - -#ifndef NOXFER -#ifdef PIPESEND - if (cx == XXCREC) { /* CRECEIVE */ - if (protocol != PROTO_K) { - printf("?Sorry, CRECEIVE works only with Kermit protocol\n"); - return(-9); - } else - return(doxget(cx)); - } - if (cx == XXCGET) { /* CGET */ - return(doxget(cx)); - } -#endif /* PIPESEND */ - - if (cx == XXREC) /* RECEIVE */ - return(doxget(cx)); -#endif /* NOXFER */ - -#ifndef NOXFER - if (cx == XXREM) { /* REMOTE */ -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) - return(doftprmt(0,0)); -#endif /* NEWFTP */ -#ifdef CK_XYZ - if (protocol != PROTO_K) { - printf("Sorry, REMOTE commands only work with Kermit protocol\n"); - return(-9); - } -#endif /* CK_XYZ */ - x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring); - if (x == -3) { - printf("?You must specify a command for the remote server\n"); - return(-9); - } - return(dormt(x)); - } -#endif /* NOXFER */ - -#ifndef NORENAME -#ifndef NOFRILLS - if (cx == XXREN || cx == XXLREN) { /* RENAME */ -#ifdef LOCUS - if (!locus && cx != XXLREN) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZREN)); -#endif /* NOXFER */ - } -#endif /* LOCUS */ -#ifdef IKSD - if (inserver && (!ENABLED(en_ren) -#ifdef CK_LOGIN - || isguest -#endif /* CK_LOGIN */ - )) { - printf("?Sorry, renaming of files is disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ - return(dorenam()); - } -#endif /* NOFRILLS */ -#endif /* NORENAME */ - - if (cx == XXEIGHT) { /* EIGHTBIT */ - extern int parity, cmask, cmdmsk; - if ((x = cmcfm()) < 0) - return(x); - parity = 0; - cmask = 0xff; - cmdmsk = 0xff; - return(success = 1); - } - -#ifndef NOXFER -/* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */ - - if (cx == XXSEN /* SEND */ -#ifdef PIPESEND - || cx == XXCSEN /* CSEND */ -#endif /* PIPESEND */ - || cx == XXMOVE /* MOVE */ - || cx == XXMAI /* MAIL */ -#ifdef CK_RESEND - || cx == XXRSEN /* RESEND */ -#endif /* CK_RESEND */ - ) { -#ifdef IKSD - if (inserver && !ENABLED(en_get)) { - printf("?Sorry, sending files is disabled\n"); - return(-9); - } -#endif /* IKSD */ - return(doxsend(cx)); - } - -/* PSEND, ADD, and REMOVE use special parsing */ - -#ifdef ADDCMD - /* ADD and REMOVE */ - if (cx == XXADD || cx == XXREMV) { - char * m; - m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?"; - x = cmkey(addtab,naddtab,m,"",xxstring); - if (x < 0) - return(x); -#ifndef NOMSEND - if (x == ADD_SND) - return(addsend(cx)); - else -#endif /* NOMSEND */ - return(doadd(cx,x)); - } -#endif /* ADDCMD */ - -#ifdef CK_RESEND - if (cx == XXPSEN) { /* PSEND */ - int seekto = 0; - - cmarg = cmarg2 = ""; - x = cmifi("File to partially send", "", &s, &y, xxstring); - if (x < 0) { - if (x == -3) { - printf("?A file specification is required\n"); - return(-9); - } else return(x); - } - nfils = -1; /* Files come from internal list. */ -#ifndef NOMSEND - addlist = 0; /* Don't use SEND-LIST. */ - filenext = NULL; -#endif /* NOMSEND */ - ckstrncpy(line,s,LINBUFSIZ); /* Save copy of string just parsed. */ - debug(F110,"PSEND line",line,0); - if (y != 0) { - printf("?Sorry, wildcards not permitted in this command\n"); - return(-9); - } - if (sizeof(int) < 4) { - printf("?Sorry, this command needs 32-bit integers\n"); - return(-9); - } - x = cmnum("starting position (byte number)", - "",10,&seekto,xxstring); - if (x < 0) - return(x); - zfnqfp(s,fspeclen,fspec); /* Get full path */ - if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0) - return(x); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - -#ifdef IKSD - if (inserver && !ENABLED(en_get)) { - printf("?Sorry, sending files is disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef PIPESEND - if (sndfilter) { - printf("?Sorry, no PSEND while SEND FILTER selected\n"); - return(-9); - } -#endif /* PIPESEND */ -#ifdef CK_XYZ - if ((protocol == PROTO_X || protocol == PROTO_XC)) { - printf("Sorry, PSEND works only with Kermit protocol\n"); - return(-9); - } -#endif /* CK_XYZ */ - - cmarg2 = brstrip(tmpbuf); /* Strip braces */ - cmarg = line; /* File to send */ - debug(F110,"PSEND filename",cmarg,0); - debug(F110,"PSEND as-name",cmarg2,0); - sendstart = seekto; - sstate = 's'; /* Set start state to SEND */ -#ifndef NOMSEND - addlist = 0; - filenext = NULL; -#endif /* NOMSEND */ - sendmode = SM_PSEND; -#ifdef MAC - what = W_SEND; - scrcreate(); -#endif /* MAC */ - if (local) { /* If in local mode, */ - displa = 1; /* enable file transfer display */ - } - return(0); - } -#endif /* CK_RESEND */ -#endif /* NOXFER */ - -#ifndef NOXFER -#ifndef NOMSEND - if (cx == XXMSE || cx == XXMMOVE) { -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) - return(doftpput(cx,0)); -#endif /* NEWFTP */ -#ifdef CK_XYZ - if (protocol == PROTO_X || protocol == PROTO_XC) { - printf( -"Sorry, you can only send one file at a time with XMODEM protocol\n" - ); - return(-9); - } -#endif /* CK_XYZ */ - return(doxsend(cx)); - } - -#ifdef COMMENT /* (moved to doxsend) */ - if (cx == XXMSE || cx == XXMMOVE) { /* MSEND and MMOVE commands */ - nfils = 0; /* Like getting a list of */ - lp = line; /* files on the command line */ - addlist = 0; /* Do not use SEND-LIST */ - filenext = NULL; /* Ditto ! */ - - while (1) { - char *p; - if ((x = cmifi("Names of files to send, separated by spaces","", - &s,&y,xxstring)) < 0) { - if (x == -3) { - if (nfils <= 0) { - printf("?A file specification is required\n"); - return(-9); - } else break; - } - return(x); - } - msfiles[nfils++] = lp; /* Got one, count it, point to it, */ - p = lp; /* remember pointer, */ - while (*lp++ = *s++) /* and copy it into buffer */ - if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */ - printf("?MSEND list too long\n"); - line[0] = NUL; - return(-9); - } - debug(F111,"msfiles",msfiles[nfils-1],nfils-1); - if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */ -#ifdef ZFNQFP - zfnqfp(p,TMPBUFSIZ,tmpbuf); - p = tmpbuf; -#endif /* ZFNQFP */ - if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) { - strcat(fspec,p); /* safe */ - strcat(fspec," "); /* safe */ - } else printf("WARNING - \\v(filespec) buffer overflow\n"); - } - cmlist = msfiles; /* Point cmlist to pointer array */ - cmarg2 = ""; /* No internal expansion list (yet) */ - sndsrc = nfils; /* Filenames come from cmlist */ - sendmode = SM_MSEND; /* Remember this kind of SENDing */ - sstate = 's'; /* Set start state for SEND */ - if (cx == XXMMOVE) /* If MMOVE'ing, */ - moving = 1; /* set this flag. */ -#ifdef MAC - what = W_SEND; - scrcreate(); -#endif /* MAC */ - if (local) { /* If in local mode, */ - displa = 1; /* turn on file transfer display */ - ttflui(); /* and flush tty input buffer. */ - } - return(0); - } -#endif /* COMMENT */ -#endif /* NOMSEND */ -#endif /* NOXFER */ - -#ifndef NOSERVER - if (cx == XXSER) { /* SERVER */ -#ifdef CK_XYZ - if (protocol != PROTO_K) { - printf("Sorry, SERVER only works with Kermit protocol\n"); - return(-9); - } -#endif /* CK_XYZ */ -#ifdef COMMENT -/* - Parse for time limit, but since we don't use it yet, - the parsing is commented out. -*/ - x_ifnum = 1; /* Turn off internal complaints */ - y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss", - "0", 10, &x, xxstring - ); - x_ifnum = 0; - if (y < 0) { - if (y == -2) { /* Invalid number or expression */ - zz = tod2sec(atmbuf); /* Convert to secs since midnight */ - if (zz < 0L) { - printf("?Number, expression, or time of day required\n"); - return(-9); - } else { - char now[32]; /* Current time */ - char *p; - long tnow; - p = now; - ztime(&p); - tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17); - if (zz < tnow) /* User's time before now */ - zz += 86400L; /* So make it tomorrow */ - zz -= tnow; /* Seconds from now. */ - } - } else - return(y); - } - if (zz > -1L) { - x = zz; - if (zz != (long) x) { - printf( -"Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n" - ); - return(-9); - } - } - if (x < 0) - x = 0; -#endif /* COMMENT */ - - if ((x = cmcfm()) < 0) return(x); - sstate = 'x'; -#ifdef MAC - what = W_RECV; - scrcreate(); -#endif /* MAC */ - if (local) displa = 1; -#ifdef AMIGA - reqoff(); /* No DOS requestors while server */ -#endif /* AMIGA */ - return(0); - } -#endif /* NOSERVER */ - - if (cx == XXSAVE) { /* SAVE command */ - x = cmkey(savtab,nsav,"option","keymap",xxstring); - if (x == -3) { - printf("?You must specify an option to save\n"); - return(-9); - } - if (x < 0) return(x); - /* have to set success separately for each item in doprm()... */ - /* actually not really, could have just had doprm return 0 or 1 */ - /* and set success here... */ - y = dosave(x); - if (y == -3) { - printf("?More fields required\n"); - return(-9); - } else return(y); - } - - if (cx == XXSET) { /* SET command */ - x = cmkey(prmtab,nprm,"Parameter","",xxstring); - if (x == -3) { - printf("?You must specify a parameter to set\n"); - return(-9); - } - if (x < 0) return(x); - /* have to set success separately for each item in doprm()... */ - /* actually not really, could have just had doprm return 0 or 1 */ - /* and set success here... */ - y = doprm(x,0); - if (y == -3) { - printf("?More fields required\n"); - return(-9); - } else return(y); - } - -#ifndef NOPUSH - if (cx == XXSHE /* SHELL (system) command */ - || cx == XXEXEC /* exec() */ - ) { - int rx = 0; - char * p = NULL; - int i /* ,n */ ; -#ifdef UNIXOROSK - char * args[256]; -#endif /* UNIXOROSK */ - -#ifdef IKSD - if (inserver && (nopush || !ENABLED(en_hos))) { - printf("?Sorry, host command access is disabled\n"); - return(-9); - } -#endif /* IKSD */ - -#ifdef CKEXEC - if (cx == XXEXEC) { /* EXEC (overlay ourselves) */ - struct FDB sw, fl; - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Command to overlay C-Kermit\n or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 1, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - redirsw, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* 2nd FDB - command to exec */ - _CMFLD, /* fcode */ - "Command to overlay C-Kermit", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL /* No more after this */ - ); - while (1) { - x = cmfdb(&sw); /* Parse something */ - debug(F101,"exec cmfdb","",x); - if (x < 0) - return(x); - /* Generalize this if we add more switches */ - if (cmresult.fcode == _CMKEY) { - rx = 1; - continue; - } - if (cmresult.fcode == _CMFLD) - break; - return(-2); - } - ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ); - if (!tmpbuf[0]) { - printf("?Command required\n"); - return(-9); - } - p = brstrip(tmpbuf); - args[0] = NULL; /* Set argv[0] to it */ - makestr(&args[0],p); - for (i = 1; i < 255; i++) { /* Get arguments for command */ - if ((x = cmfld("Argument","",&s,xxstring)) < 0) { - if (x == -3) { - if ((x = cmcfm()) < 0) - return(x); - break; - } else - return(x); - } - args[i] = NULL; - s = brstrip(s); - makestr(&args[i],s); - } - args[i] = NULL; - } else { -#endif /* CKEXEC */ - if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0) - return(x); -#ifdef CKEXEC - } -#endif /* CKEXEC */ - if (nopush) - return(success = 0); -#ifdef CK_APC - if (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)) - return(success = 0); -#endif /* CK_APC */ - conres(); /* Make console normal */ -#ifdef OS2 - if (!(s && *s)) { - os2push(); - return(success = 1); - } else -#endif /* OS2 */ - if (cx == XXSHE) { - x = zshcmd(s); - debug(F101,"RUN zshcmd code","",x); - concb((char)escape); - return(success = x); -#ifdef CKEXEC - } else { -#ifdef DEBUG - if (deblog) { - debug(F111,"EXEC cmd",p,0); - for (i = 0; i < 256 && args[i]; i++) - debug(F111,"EXEC arg",args[i],i); - } -#endif /* DEBUG */ - if (p) { - z_exec(p,args,rx); /* Overlay ourself */ - debug(F100,"EXEC fails","",0); - concb((char)escape); /* In case it returns */ - } - return(success = 0); -#endif /* CKEXEC */ - } - } - -#ifdef CK_REDIR - if (cx == XXFUN) { /* REDIRECT */ -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ - ckmakmsg(tmpbuf, - TMPBUFSIZ, - "Local command to run,\n", - "with its standard input/output redirected to ", - local ? ttname : "the communications connection", - "\n" - ); - if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0) - return(x); - if (nopush) { - printf("?REDIRECT disabled\n"); - return(success=0); - } - if (!local) { - printf("?SET LINE or SET HOST required first\n"); - return(-9); - } - if (!*s) { - printf("?REDIRECT requires a command to redirect\n"); - return(-9); - } - return(success = ttruncmd(s)); - } -#endif /* CK_REDIR */ -#endif /* NOPUSH */ - -#ifndef NOSHOW - if (cx == XXSHO) { /* SHOW */ - x = cmkey(shotab,nsho,"","parameters",xxstring); - if (x < 0) return(x); - return(doshow(x)); - } -#endif /* NOSHOW */ - -#ifndef MAC - if (cx == XXSPA) { /* SPACE */ -#ifdef IKSD - if (inserver && !ENABLED(en_spa)) { - printf("?Sorry, SPACE command disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef datageneral - /* AOS/VS can take an argument after its "space" command. */ - if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0) - return(x); - if (nopush) { - printf("?Sorry, SPACE command disabled\n"); - return(-9); - } else if (*s == NUL) { - xsystem(SPACMD); - } else { - ckmakmsg(line,LINBUFSIZ,"space ",s,NULL,NULL); - xsystem(line); - } -#else -#ifdef OS2 - if ((x = cmtxt("Press Enter for current disk,\n\ - or specify a disk letter like A:","",&s,xxstring)) < 0) - return(x); - if (*s == NUL) { /* Current disk */ - unsigned long space = zdskspace(0); - if (space > 0 && space < 1024) - printf(" Free space: unknown\n"); - else - printf(" Free space: %ldK\n", space/1024L); - } else { - int drive = toupper(*s); - unsigned long space = zdskspace(drive - 'A' + 1); - if (space > 0 && space < 1024) - printf(" Drive %c: unknown free\n"); - else - printf(" Drive %c: %ldK free\n", drive,space / 1024L); - } -#else -#ifdef UNIXOROSK - x = cmdir("Confirm for current disk,\n\ - or specify a disk device or directory","",&s,xxstring); - if (x == -3) - s = ""; - else if (x < 0) - return(x); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - s = tmpbuf; - if ((x = cmcfm()) < 0) return(x); - if (nopush) { - printf("?Sorry, SPACE command disabled\n"); - return(-9); - } - if (!*s) { /* Current disk */ - xsystem(SPACMD); - } else { /* Specified disk */ - ckmakmsg(line,LINBUFSIZ,SPACM2," ",s,NULL); - xsystem(line); - } -#else - if ((x = cmcfm()) < 0) return(x); - if (nopush) { - printf("?Sorry, SPACE command disabled\n"); - return(-9); - } - xsystem(SPACMD); -#endif /* UNIXOROSK */ -#endif /* OS2 */ -#endif /* datageneral */ - return(success = 1); /* Pretend it worked */ - } -#endif /* MAC */ - -#ifndef NOXFER - if (cx == XXSTA) { /* STATISTICS */ - if ((x = cmkey(stattab,2,"Carriage return, or option", - "/brief",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) return(y); - return(success = dostat(x)); - } -#endif /* NOXFER */ - - if (cx == XXSTO || cx == XXEND) { /* STOP, END, or POP */ - if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0) - return(y); - if ((y = cmtxt("Message to print","",&s,xxstring)) < 0) - return(y); - s = brstrip(s); - if (*s) printf("%s\n",s); - if (cx == XXSTO) { - dostop(); - } else { - doend(x); - } - return(success = (x == 0)); - } - if (cx == XXSUS) { /* SUSPEND */ - if ((y = cmcfm()) < 0) return(y); -#ifdef NOJC - printf("Sorry, this version of Kermit cannot be suspended\n"); -#else -#ifdef IKSD - if (inserver) { - printf("?Sorry, IKSD can not be suspended\n"); - return(-9); - } else -#endif /* IKSD */ - if (nopush) { - printf("?Sorry, access to system is disabled\n"); - return(-9); - } - stptrap(0); -#endif /* NOJC */ - return(0); - } - - if (cx == XXTAK) { /* TAKE */ - char * scriptenv = NULL; -#ifdef OS2 - char * GetAppData(int); - extern char startupdir[],exedir[],inidir[]; - char * keymapenv = NULL; - char * appdata0 = NULL, *appdata1 = NULL; - int xx; -#define TAKEPATHLEN 4096 -#else /* OS2 */ -#define TAKEPATHLEN 1024 -#endif /* OS2 */ - char takepath[TAKEPATHLEN]; - - if (tlevel >= MAXTAKE-1) { - printf("?Take files nested too deeply\n"); - return(-9); - } -#ifdef OS2 -#ifdef NT - scriptenv = getenv("K95SCRIPTS"); - keymapenv = getenv("K95KEYMAPS"); - makestr(&appdata0,(char *)GetAppData(0)); - makestr(&appdata1,(char *)GetAppData(1)); -#else /* NT */ - scriptenv = getenv("K2SCRIPTS"); - keymapenv = getenv("K2KEYMAPS"); -#endif /* NT */ -#endif /* OS2 */ - - if (!scriptenv) /* Let this work for Unix etc too */ - scriptenv = getenv("CK_SCRIPTS"); /* Use this if defined */ -#ifndef OS2 - if (!scriptenv) /* Otherwise use home directory */ - scriptenv = homepath(); -#endif /* OS2 */ - if (!scriptenv) - scriptenv = ""; - ckstrncpy(takepath,scriptenv,TAKEPATHLEN); - debug(F110,"TAKE initial takepath",takepath,0); - -#ifdef OS2 - if (!keymapenv) - keymapenv = getenv("CK_KEYMAPS"); - if (!keymapenv) - keymapenv = ""; - - ckstrncat(takepath, - (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";", - TAKEPATHLEN - ); - ckstrncat(takepath,keymapenv?keymapenv:"",TAKEPATHLEN); - ckstrncat(takepath, - (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";", - TAKEPATHLEN - ); - ckstrncat(takepath,startupdir,TAKEPATHLEN); - ckstrncat(takepath,";",TAKEPATHLEN); - ckstrncat(takepath,startupdir,TAKEPATHLEN); - ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN); - ckstrncat(takepath,startupdir,TAKEPATHLEN); - ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN); - - ckstrncat(takepath,appdata1,TAKEPATHLEN); - ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN); - ckstrncat(takepath,appdata1,TAKEPATHLEN); - ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN); - ckstrncat(takepath,appdata1,TAKEPATHLEN); - ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN); - - ckstrncat(takepath,appdata0,TAKEPATHLEN); - ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN); - ckstrncat(takepath,appdata0,TAKEPATHLEN); - ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN); - ckstrncat(takepath,appdata0,TAKEPATHLEN); - ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN); - - ckstrncat(takepath,inidir,TAKEPATHLEN); - ckstrncat(takepath,";",TAKEPATHLEN); - ckstrncat(takepath,inidir,TAKEPATHLEN); - ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN); - ckstrncat(takepath,inidir,TAKEPATHLEN); - ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN); - - ckstrncat(takepath,zhome(),TAKEPATHLEN); - ckstrncat(takepath,";",TAKEPATHLEN); - ckstrncat(takepath,zhome(),TAKEPATHLEN); - ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN); - ckstrncat(takepath,zhome(),TAKEPATHLEN); - ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN); - - ckstrncat(takepath,exedir,TAKEPATHLEN); - ckstrncat(takepath,";",TAKEPATHLEN); - ckstrncat(takepath,exedir,TAKEPATHLEN); - ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN); - ckstrncat(takepath,exedir,TAKEPATHLEN); - ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN); -#endif /* OS2 */ - debug(F110,"TAKE final takepath",takepath,0); - - if ((y = cmifip("Commands from file", - "",&s,&x,0,takepath,xxstring)) < 0) { - if (y == -3) { - printf("?A file name is required\n"); - return(-9); - } else - return(y); - } - if (x != 0) { - printf("?Wildcards not allowed in command file name\n"); - return(-9); - } - ckstrncpy(line,s,LINBUFSIZ); - debug(F110,"TAKE file",s,0); - if (isdir(s)) { - printf("?Can't execute a directory - \"%s\"\n", s); - return(-9); - } -#ifndef NOTAKEARGS - { - char * p; - x = strlen(line); - debug(F111,"TAKE args",line,x); - p = line + x + 1; - if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0) - return(y); - if (*s) { /* Args given? */ - ckstrncpy(p,s,LINBUFSIZ-x-1); -#ifdef ZFNQFP - zfnqfp(line,TMPBUFSIZ,tmpbuf); - s = tmpbuf; -#else - s = line; -#endif /* ZFNQFP */ - debug(F110,"TAKE filename",s,0); - x = strlen(s); - debug(F101,"TAKE new len",s,x); - -#ifdef COMMENT -/* - This was added in C-Kermit 7.0 to allow args to be passed from the TAKE - command to the command file. But it overwrites the current argument vector, - which is at best surprising, and at worst unsafe. -*/ - addmac("%0",s); /* Define %0 = name of file */ - varnam[0] = '%'; - varnam[2] = '\0'; - debug(F110,"take arg 0",s,0); - debug(F110,"take args",p,0); - for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */ - varnam[1] = (char) (y + '0'); - delmac(varnam,0); - } - xwords(p,MAXARGLIST,NULL,0); /* Assign new args */ - debug(F110,"take args",p,0); -#else -/* - This method is used in 8.0. If the TAKE command includes arguments, we - insert an intermediate temporary macro between the current level; we pass - the arguments to the macro and then the macro TAKEs the command file. - If the user Ctrl-C's out of the TAKE file, some temporary macro definitions - and other small malloc'd bits might be left behind. -*/ - { - char * q = NULL; - char * r = NULL; - int k, m; - m = maclvl; - q = (char *)malloc(x+24); - if (q) { - r = (char *)malloc(x+24); - if (r) { - sprintf(q,"_file[%s](%d)",s,cmdlvl); /* safe */ - sprintf(r,"take %s",s); /* safe */ - k = addmac(q,r); - if (k > -1) { - dodo(k,p,0); - while (maclvl > m) { - sstate = (CHAR) parser(1); - if (sstate) proto(); - } - } - k = delmac(q,0); - free(q); - free(r); - return(success); - } - } - } - return(success = 0); -#endif /* COMMENT */ - } - } -#else - if ((y = cmcfm()) < 0) return(y); -#endif /* NOTAKEARGS */ - return(success = dotake(line)); - } - -#ifndef NOLOCAL -#ifdef OS2 - if (cx == XXVIEW) { /* VIEW Only Terminal mode */ - viewonly = TRUE; - success = doconect(0, 0); - viewonly = FALSE; - return success; - } -#endif /* OS2 */ - -#ifdef NETCONN - if (cx == XXTEL || cx == XXIKSD) { /* TELNET */ - int x,z; -#ifdef OS2 - if (!tcp_avail) { - printf("?Sorry, either TCP/IP is not available on this system or\n\ -necessary DLLs did not load. Use SHOW NETWORK to check network status.\n"); - success = 0; - return(-9); - } else -#endif /* OS2 */ - { - x = nettype; /* Save net type in case of failure */ - z = ttnproto; /* Save protocol in case of failure */ - nettype = NET_TCPB; - ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT; - if ((y = setlin(XYHOST,0,1)) <= 0) { - nettype = x; /* Failed, restore net type. */ - ttnproto = z; /* and protocol */ - success = 0; - } - didsetlin++; - } - return(y); - } - -#ifndef PTYORPIPE -#ifdef NETCMD -#define PTYORPIPE -#else -#ifdef NETPTY -#define PTYORPIPE -#endif /* NETPTY */ -#endif /* NETCMD */ -#endif /* PTYORPIPE */ - -#ifdef PTYORPIPE - if (cx == XXPIPE || cx == XXPTY) { /* PIPE or PTY */ - int x; - extern int netsave; - x = nettype; /* Save net type in case of failure */ - nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY; - if ((y = setlin(XYHOST,0,1)) < 0) { - nettype = x; /* Failed, restore net type. */ - ttnproto = z; /* and protocol */ - success = 0; - } - didsetlin++; - netsave = x; - return(y); - } -#endif /* PTYORPIPE */ - -#ifdef ANYSSH - if (cx == XXSSH) { /* SSH (Secure Shell) */ - extern int netsave; -#ifdef SSHBUILTIN - int k, x, havehost = 0, trips = 0; - int tmpver = -1, tmpxfw = -1; -#ifndef SSHTEST - extern int sl_ssh_xfw, sl_ssh_xfw_saved; - extern int sl_ssh_ver, sl_ssh_ver_saved; -#endif /* SSHTEST */ - extern int mdmtyp, mdmsav, cxtype, sl_uid_saved; - extern char * slmsg; - extern char uidbuf[], sl_uidbuf[]; - extern char pwbuf[], * g_pswd; - extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal; - struct FDB sw, kw, fl; - - if (ssh_tmpstr) - memset(ssh_tmpstr,0,strlen(ssh_tmpstr)); - makestr(&ssh_tmpstr,NULL); - makestr(&ssh_tmpuid,NULL); - makestr(&ssh_tmpcmd,NULL); - makestr(&ssh_tmpport,NULL); - - cmfdbi(&kw, /* 1st FDB - commands */ - _CMKEY, /* fcode */ - "host [ port ],\n or action", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nsshcmd, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: 0 = keyword */ - xxstring, /* Processing function */ - sshkwtab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Host */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - x = cmfdb(&kw); - if (x == -3) { - printf("?ssh what?\n"); - return(-9); - } - if (x < 0) - return(x); - havehost = 0; - if (cmresult.fcode == _CMFLD) { - havehost = 1; - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */ - cmresult.nresult = XSSH_OPN; - } - switch (cmresult.nresult) { /* SSH keyword */ - case XSSH_OPN: /* SSH OPEN */ - if (!havehost) { - if ((x = cmfld("Host","",&s,xxstring)) < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - } - /* Parse [ port ] [ switches ] */ - cmfdbi(&kw, /* Switches */ - _CMKEY, - "Port number or service name,\nor switch", - "", - "", - nsshopnsw, - 4, - xxstring, - sshopnsw, - &fl - ); - cmfdbi(&fl, /* Port number or service name */ - _CMFLD, - "", - "", - "", - 0, - 0, - xxstring, - NULL, - NULL - ); - trips = 0; /* Explained below */ - while (1) { /* Parse port and switches */ - x = cmfdb(&kw); /* Get a field */ - if (x == -3) /* User typed CR so quit from loop */ - break; - if (x < 0) /* Other parse error, pass it back */ - return(x); - switch (cmresult.fcode) { /* Field or Keyword? */ - case _CMFLD: /* Field */ - makestr(&ssh_tmpport,cmresult.sresult); - break; - case _CMKEY: /* Keyword */ - switch (cmresult.nresult) { /* Which one? */ - case SSHSW_USR: /* /USER: */ - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((y = cmfld("Username","",&s,xxstring)) < 0) - return(y); - s = brstrip(s); - makestr(&ssh_tmpuid,s); - break; - case SSHSW_PWD: - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - debok = 0; - if ((x = cmfld("Password","",&s,xxstring)) < 0) { - if (x == -3) { - makestr(&ssh_tmpstr,""); - } else { - return(x); - } - } else { - s = brstrip(s); - if ((x = (int)strlen(s)) > PWBUFL) { - makestr(&slmsg,"Internal error"); - printf("?Sorry, too long - max = %d\n",PWBUFL); - return(-9); - } - makestr(&ssh_tmpstr,s); - } - break; - - case SSHSW_VER: - if ((x = cmnum("Number","",10,&z,xxstring)) < 0) - return(x); - if (z < 1 || z > 2) { - printf("?Out of range: %d\n",z); - return(-9); - } - tmpver = z; - break; - case SSHSW_CMD: - case SSHSW_SUB: - if ((x = cmfld("Text","",&s,xxstring)) < 0) - return(x); - makestr(&ssh_tmpcmd,s); - ssh_cas = (cmresult.nresult == SSHSW_SUB); - break; - case SSHSW_X11: - if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) - return(x); - tmpxfw = x; - break; - default: - return(-2); - } - } - if (trips++ == 0) { /* After first time through */ - cmfdbi(&kw, /* only parse switches, not port. */ - _CMKEY, - "Switch", - "", - "", - nsshopnsw, - 4, - xxstring, - sshopnsw, - NULL - ); - } - } - if ((x = cmcfm()) < 0) /* Get confirmation */ - return(x); - if (clskconnx(1) < 0) { /* Close current Kermit connection */ - if ( ssh_tmpstr ) { - memset(ssh_tmpstr,0,strlen(ssh_tmpstr)); - makestr(&ssh_tmpstr,NULL); - } - return(success = 0); - } - makestr(&ssh_hst,line); /* Stash everything */ - if (ssh_tmpuid) { - if (!sl_uid_saved) { - ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN); - sl_uid_saved = 1; - } - ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN); - makestr(&ssh_tmpuid,NULL); - } - if (ssh_tmpport) { - makestr(&ssh_prt,ssh_tmpport); - makestr(&ssh_tmpport,NULL); - } else - makestr(&ssh_prt,NULL); - - if (ssh_tmpcmd) { - makestr(&ssh_cmd,brstrip(ssh_tmpcmd)); - makestr(&ssh_tmpcmd,NULL); - } else - makestr(&ssh_cmd,NULL); - - if (tmpver > -1) { -#ifndef SSHTEST - if (!sl_ssh_ver_saved) { - sl_ssh_ver = ssh_ver; - sl_ssh_ver_saved = 1; - } -#endif /* SSHTEST */ - ssh_ver = tmpver; - } - if (tmpxfw > -1) { -#ifndef SSHTEST - if (!sl_ssh_xfw_saved) { - sl_ssh_xfw = ssh_xfw; - sl_ssh_xfw_saved = 1; - } -#endif /* SSHTEST */ - ssh_xfw = tmpxfw; - } - if (ssh_tmpstr) { - if (ssh_tmpstr[0]) { - ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1); - pwflg = 1; - pwcrypt = 0; - } else - pwflg = 0; - makestr(&ssh_tmpstr,NULL); - } - nettype = NET_SSH; - if (mdmsav < 0) - mdmsav = mdmtyp; - mdmtyp = -nettype; - x = 1; - -#ifndef NOSPL - makestr(&g_pswd,pwbuf); /* Save global pwbuf */ - g_pflg = pwflg; /* and flag */ - g_pcpt = pwcrypt; -#endif /* NOSPL */ - - /* Line parameter to ttopen() is ignored */ - k = ttopen(line,&x,mdmtyp, 0); - if (k < 0) { - printf("?Unable to connect to %s\n",ssh_hst); - mdmtyp = mdmsav; - slrestor(); - return(success = 0); - } - duplex = 0; /* Remote echo */ - ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */ - debug(F110,"ssh ttname",ttname,0); - makestr(&slmsg,NULL); /* No SET LINE error message */ - cxtype = CXT_SSH; -#ifndef NODIAL - dialsta = DIA_UNK; -#endif /* NODIAL */ - success = 1; /* SET LINE succeeded */ - network = 1; /* Network connection (not serial) */ - local = 1; /* Local mode (not remote) */ - if ((reliable != SET_OFF || !setreliable)) - reliable = SET_ON; /* Transport is reliable end to end */ -#ifdef OS2 - DialerSend(OPT_KERMIT_CONNECT, 0); -#endif /* OS2 */ - setflow(); /* Set appropriate flow control */ - - haveline = 1; -#ifdef CKLOGDIAL -#ifdef NETCONN - dolognet(); -#endif /* NETCONN */ -#endif /* CKLOGDIAL */ - -#ifndef NOSPL - if (local) { - if (nmac) { /* Any macros defined? */ - int k; /* Yes */ - k = mlook(mactab,"on_open",nmac); /* Look this up */ - if (k >= 0) { /* If found, */ - if (dodo(k,ssh_hst,0) > -1) /* set it up, */ - parser(1); /* and execute it */ - } - } - } -#endif /* NOSPL */ -#ifdef LOCUS - if (autolocus) - setlocus(1,1); -#endif /* LOCUS */ - - /* Command was confirmed so we can pre-pop command level. */ - /* This is so CONNECT module won't think we're executing a */ - /* script if CONNECT was the final command in the script. */ - if (cmdlvl > 0) - prepop(); - success = doconect(0,cmdlvl == 0 ? 1 : 0); - if (ttchk() < 0) - dologend(); - return(success); - - case XSSH_CLR: - if ((y = cmkey(sshclr,nsshclr,"","", xxstring)) < 0) { - if (y == -3) { - printf("?clear what?\n"); - return(-9); - } - return(y); - } - if ((x = cmcfm()) < 0) - return(x); - switch (y) { - case SSHC_LPF: - ssh_pf_lcl_n = 0; - break; - case SSHC_RPF: - ssh_pf_rmt_n = 0; - break; - default: - return(-2); - } - return(success = 1); /* or whatever */ - - case XSSH_AGT: { /* SSH AGENT */ - int doeach = 0; - if ((y = cmkey(sshagent,nsshagent,"","",xxstring)) < 0) - return(y); - switch (y) { - case SSHA_ADD: /* SSH AGENT ADD ... */ - if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) { -#ifndef SSHTEST - if (x == -3) /* No name given */ - doeach = 1; /* so do them all */ - else -#endif /* SSHTEST */ - return(x); - } - ckstrncpy(line,s,LINBUFSIZ); - if ((x = cmcfm()) < 0) - return(x); -#ifdef SSHTEST - x = 0; -#else - if (doeach) { - int i; - x = 0; - for (i = 0; i < ssh_idf_n; i++) - x += ssh_agent_add_file(ssh_idf[i]); - } else - x = ssh_agent_add_file(line); -#endif /* SSHTEST */ - return(success = (x == 0)); - - case SSHA_DEL: { /* SSH AGENT DELETE ... */ - int doall = 0; - if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) { -#ifndef SSHTEST - if (x == -3) /* No name given */ - doall = 1; /* so do them all */ - else -#endif /* SSHTEST */ - return(x); - } - ckstrncpy(line,s,LINBUFSIZ); - if ((x = cmcfm()) < 0) - return(x); -#ifdef SSHTEST - x = 0; -#else - if (doall) - x = ssh_agent_delete_all(); - else - x = ssh_agent_delete_file(line); -#endif /* SSHTEST */ - return(success = (x == 0)); - } - case SSHA_LST: { - int fingerprint = 0; - if ((y = cmswi(sshagtsw,nsshagtsw,"","",xxstring)) < 0) { - if (y != -3) - return(y); - } else if (cmgbrk() > SP) { - printf("?This switch does not take an argument\n"); - return(-9); - } else if (y == SSHASW_FP) { - fingerprint = 1; - } - if ((x = cmcfm()) < 0) - return(x); -#ifdef SSHTEST - return(success = 1); -#else - return(success = - (ssh_agent_list_identities(fingerprint) == 0)); -#endif /* SSHTEST */ - } - default: - return(-2); - } - } - case XSSH_ADD: { /* SSH ADD */ - /* ssh add { local, remote } port host port */ - int cx, i, j, k; - char * h; - if ((cx = cmkey(addfwd,naddfwd,"","", xxstring)) < 0) - return(cx); - if ((x = cmnum((cx == SSHF_LCL) ? - "Local port number" : "Remote port number", - "",10,&j,xxstring)) < 0) - return(x); - if ((x = cmfld("Host","",&s,xxstring)) < 0) - return(x); - makestr(&h,s); - if ((x = cmnum("Port","",10,&k,xxstring)) < 0) - return(x); - if ((x = cmcfm()) < 0) - return(x); - - switch(cx) { - case SSHF_LCL: - if (ssh_pf_lcl_n == 32) { - printf( -"?Maximum number of local port forwardings already specified\n" - ); - free(h); - return(success = 0); - } - ssh_pf_lcl[ssh_pf_lcl_n].p1 = j; - makestr(&(ssh_pf_lcl[ssh_pf_lcl_n].host),h); - makestr(&h,NULL); - ssh_pf_lcl[ssh_pf_lcl_n].p2 = k; - ssh_pf_lcl_n++; - break; - case SSHF_RMT: - if (ssh_pf_rmt_n == 32) { - printf( -"?Maximum number of remote port forwardings already specified\n" - ); - free(h); - return(success = 0); - } - ssh_pf_rmt[ssh_pf_rmt_n].p1 = j; - makestr(&(ssh_pf_rmt[ssh_pf_rmt_n].host),h); - makestr(&h,NULL); - ssh_pf_rmt[ssh_pf_rmt_n].p2 = k; - ssh_pf_rmt_n++; - } - return(success = 1); - } - /* Not supporting arbitrary forwarding yet */ - case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */ - case XSSH_FRP: { /* SSH FORWARD-REMOTE-PORT */ - int li_port = 0; - int to_port = 0; - char * fw_host = NULL; - int n; - if ((x = cmnum(cmresult.nresult == XSSH_FLP ? - "local-port":"remote-port", - "",10,&li_port,xxstring)) < 0) - return(x); - if (li_port < 1 || li_port > 65535) { - printf("?Out range - min: 1, max: 65535\n"); - return(-9); - } - if ((x = cmfld("host",ssh_hst?ssh_hst:"",&s,xxstring)) < 0) - return(x); - n = ckstrncpy(tmpbuf,s,TMPBUFSIZ); - fw_host = tmpbuf; - if ((x = cmnum("host-port",ckuitoa(li_port),10, - &to_port,xxstring)) < 0) - return(x); - if (to_port < 1 || to_port > 65535) { - printf("?Out range - min: 1, max: 65535\n"); - return(-9); - } - if ((x = cmcfm()) < 0) - return(x); - switch (cmresult.nresult) { - case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */ -#ifndef SSHTEST - ssh_fwd_local_port(li_port,fw_host,to_port); -#endif /* SSHTEST */ - return(success = 1); - case XSSH_FRP: /* SSH FORWARD-REMOTE-PORT */ -#ifndef SSHTEST - ssh_fwd_remote_port(li_port,fw_host,to_port); -#endif /* SSHTEST */ - return(success = 1); - } - return(success = 1); - } - case XSSH_V2: /* SSH V2 */ - if ((cx = cmkey(ssh2tab,nssh2tab,"","", xxstring)) < 0) - return(cx); - switch (cx) { - case XSSH2_RKE: - if ((x = cmcfm()) < 0) - return(x); -#ifndef SSHTEST - ssh_v2_rekey(); -#endif /* SSHTEST */ - return(success = 1); - default: - return(-2); - } - case XSSH_KEY: - if ((cx = cmkey(sshkey,nsshkey,"","", xxstring)) < 0) - return(cx); - switch (cx) { - case SSHK_PASS: { /* Change passphrase */ - char * oldp = NULL, * newp = NULL; - struct FDB df, sw; - cmfdbi(&sw, - _CMKEY, /* fcode */ - "Filename, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 2, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - sshkpsw, /* Keyword table */ - &df /* Pointer to next FDB */ - ); - cmfdbi(&df, /* 2nd FDB - file for display */ - _CMIFI, /* output file */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - line[0] = NUL; - - while (1) { - x = cmfdb(&sw); - if (x == -3) break; - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) - break; - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((y = cmfld("Passphrase","",&s,xxstring)) < 0) - return(y); - switch (cmresult.nresult) { - case 1: /* Old */ - makestr(&oldp,s); - break; - case 2: /* New */ - makestr(&newp,s); - } - } - if (cmresult.fcode == _CMIFI) { /* Filename */ - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - if (zfnqfp(line,TMPBUFSIZ,tmpbuf)) - ckstrncpy(line,tmpbuf,LINBUFSIZ); - } - if ((x = cmcfm()) < 0) return(x); - -#ifndef SSHTEST - x = sshkey_change_passphrase(line[0] ? line : NULL, - oldp, newp); -#endif /* SSHTEST */ - makestr(&oldp,NULL); - makestr(&newp,NULL); - success = (x == 0); - return(success); - } - case SSHK_CREA: { /* SSH KEY CREATE /switches... */ - int bits = 1024, keytype = SSHKT_2R; - char * pass = NULL, * comment = NULL; - struct FDB df, sw; - - /* - * char * sshkey_default_file(int keytype) - * will provide the default filename for a given keytype - * is it possible to have the default value for the 2nd - * FDB set and changed when a /TYPE switch is provided? - * Would this allow for tab completion of the filename? - */ - cmfdbi(&sw, - _CMKEY, /* fcode */ - "Filename, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nsshkcrea, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - sshkcrea, /* Keyword table */ - &df /* Pointer to next FDB */ - ); - cmfdbi(&df, /* 2nd FDB - file for display */ - _CMOFI, /* output file */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - line[0] = NUL; - - while (1) { - x = cmfdb(&sw); - if (x == -3) break; - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) - break; - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (cmresult.nresult) { - case SSHKC_BI: /* /BITS:n */ - if ((y = cmnum("","1024",10,&z,xxstring)) < 0) - return(y); - if (z < 512 || z > 4096) { - printf("?Out range - min: 512, max: 4096\n"); - return(-9); - } - bits = z; - break; - case SSHKC_PP: /* /PASSPHRASE:blah */ - if ((y = cmfld("Passphrase","",&s,xxstring)) < 0) - return(y); - makestr(&pass,s); - break; - case SSHKC_TY: /* /TYPE:keyword */ - if ((y = cmkey(sshkcty,nsshkcty,"", - "v2-rsa",xxstring)) < 0) - return(y); - keytype = y; - break; - case SSHKC_1R: /* /COMMENT */ - if ((y = cmfld("Text","",&s,xxstring)) < 0) - return(y); - makestr(&comment,s); - break; - } - } - if (cmresult.fcode == _CMOFI) { /* Filename */ - if (cmresult.sresult) { - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - if (zfnqfp(line,TMPBUFSIZ,tmpbuf)) - ckstrncpy(line,tmpbuf,LINBUFSIZ); - } - } - if ((y = cmcfm()) < 0) /* Confirm */ - return(y); -#ifndef SSHTEST - x = sshkey_create(line[0] ? line : NULL, - bits, pass, keytype, comment); - if (pass) - memset(pass,0,strlen(pass)); -#endif /* SSHTEST */ - makestr(&pass,NULL); - makestr(&comment,NULL); - return(success = (x == 0)); - } - case SSHK_DISP: { /* SSH KEY DISPLAY /switches... */ - char c; - int infmt = 0, outfmt = 0; - struct FDB df, sw; - cmfdbi(&sw, - _CMKEY, /* fcode */ - "Filename, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nsshdswi, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - sshdswi, /* Keyword table */ - &df /* Pointer to next FDB */ - ); - cmfdbi(&df, /* 2nd FDB - file for display */ - _CMIFI, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - line[0] = NUL; - - while (1) { - x = cmfdb(&sw); - if (x == -3) break; - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) - break; - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - switch (cmresult.nresult) { -#ifdef COMMENT - case SSHKD_IN: /* /IN-FORMAT: */ - if ((y = cmkey(sshdifmt,nsshdifmt, - "","",xxstring)) < 0) - return(y); - infmt = y; - break; -#endif /* COMMENT */ - case SSHKD_OUT: /* /FORMAT: */ - if ((y = cmkey(sshdofmt,nsshdofmt, - "","",xxstring)) < 0) - return(y); - outfmt = y; - break; - } - } - if (cmresult.fcode == _CMIFI) { /* Filename */ - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - if (zfnqfp(line,TMPBUFSIZ,tmpbuf)) - ckstrncpy(line,tmpbuf,LINBUFSIZ); - } -#ifdef COMMENT - if (!line[0]) { - printf("?Key filename required\n"); - return(-9); - } -#endif /* COMMENT */ - if ((y = cmcfm()) < 0) /* Confirm */ - return(y); -#ifndef SSHTEST - switch (outfmt) { - case SKDF_OSSH: - /* 2nd param is optional passphrase */ - x = sshkey_display_public(line[0] ? line : NULL, NULL); - break; - case SKDF_SSHC: - /* 2nd param is optional passphrase */ - x = sshkey_display_public_as_ssh2(line[0] ? line : NULL, - NULL); - break; - case SKDF_IETF: - x = sshkey_display_fingerprint(line[0] ? line : NULL, 1); - break; - case SKDF_FING: - x = sshkey_display_fingerprint(line[0] ? line : NULL, 0); - break; - } -#endif /* SSHTEST */ - return(success = (x == 0)); - } - case SSHK_V1: /* SSH KEY V1 SET-COMMENT */ - if ((x = cmkey(sshkv1,1,"","set-comment", xxstring)) < 0) - return(x); - if (x != 1) return(-2); - if ((x = cmifi("Key file name","",&s,&y,xxstring)) < 0) { - if (x == -3) { - printf("?Name of key file required\n"); - return(-9); - } - } - ckstrncpy(line,s,LINBUFSIZ); - if ((x = cmtxt("Comment text","",&s,xxstring)) < 0) - return(x); -#ifndef SSHTEST - x = sshkey_v1_change_comment(line, /* filename */ - s, /* new comment */ - NULL /* passphrase */ - ); -#endif /* SSHTEST */ - success = (x == 0); - return(success); - } - default: - return(-2); - } -#else /* SSHBUILTIN */ -#ifdef SSHCMD - x = nettype; - if ((y = setlin(XXSSH,0,1)) < 0) { - if (errno) - printf("?%s\n",ck_errstr()); - else -#ifdef COMMENT - /* This isn't right either because it catches command editing */ - printf("?Sorry, pseudoterminal open failed\n"); - if (hints) - printf("Hint: Try \"ssh -t %s\"\n",line); -#else - return(y); -#endif /* COMMENT */ - nettype = x; /* Failed, restore net type. */ - ttnproto = z; /* and protocol */ - success = 0; - } - didsetlin++; - netsave = x; - return(y); -#endif /* SSHCMD */ -#endif /* SSHBUILTIN */ - } -#endif /* ANYSSH */ - -#ifdef SSHBUILTIN - if (cx == XXSKRM) { /* SKERMIT (Secure Shell Kermit) */ - extern int netsave; - int k, x, havehost = 0, trips = 0; - int tmpver = -1, tmpxfw = -1; -#ifndef SSHTEST - extern int sl_ssh_xfw, sl_ssh_xfw_saved; - extern int sl_ssh_ver, sl_ssh_ver_saved; -#endif /* SSHTEST */ - extern int mdmtyp, mdmsav, cxtype, sl_uid_saved; - extern char * slmsg; - extern char uidbuf[], sl_uidbuf[]; - extern char pwbuf[], * g_pswd; - extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal; - struct FDB sw, kw, fl; - - if (ssh_tmpstr) - memset(ssh_tmpstr,0,strlen(ssh_tmpstr)); - makestr(&ssh_tmpstr,NULL); - makestr(&ssh_tmpuid,NULL); - makestr(&ssh_tmpcmd,NULL); - makestr(&ssh_tmpport,NULL); - - cmfdbi(&kw, /* 1st FDB - commands */ - _CMKEY, /* fcode */ - "host [ port ],\n or action", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nsshkermit, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: 0 = keyword */ - xxstring, /* Processing function */ - sshkermit, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Host */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - x = cmfdb(&kw); - if (x == -3) { - printf("?skermit what?\n"); - return(-9); - } - if (x < 0) - return(x); - havehost = 0; - if (cmresult.fcode == _CMFLD) { - havehost = 1; - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */ - cmresult.nresult = SKRM_OPN; - } - switch (cmresult.nresult) { /* SSH keyword */ - case SKRM_OPN: /* SSH OPEN */ - if (!havehost) { - if ((x = cmfld("Host","",&s,xxstring)) < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - } - /* Parse [ port ] [ switches ] */ - cmfdbi(&kw, /* Switches */ - _CMKEY, - "Port number or service name,\nor switch", - "", - "", - nsshkrmopnsw, - 4, - xxstring, - sshkrmopnsw, - &fl - ); - cmfdbi(&fl, /* Port number or service name */ - _CMFLD, - "", - "", - "", - 0, - 0, - xxstring, - NULL, - NULL - ); - trips = 0; /* Explained below */ - while (1) { /* Parse port and switches */ - x = cmfdb(&kw); /* Get a field */ - if (x == -3) /* User typed CR so quit from loop */ - break; - if (x < 0) /* Other parse error, pass it back */ - return(x); - switch (cmresult.fcode) { /* Field or Keyword? */ - case _CMFLD: /* Field */ - makestr(&ssh_tmpport,cmresult.sresult); - break; - case _CMKEY: /* Keyword */ - switch (cmresult.nresult) { /* Which one? */ - case SSHSW_USR: /* /USER: */ - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((y = cmfld("Username","",&s,xxstring)) < 0) - return(y); - s = brstrip(s); - makestr(&ssh_tmpuid,s); - break; - case SSHSW_PWD: - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - debok = 0; - if ((x = cmfld("Password","",&s,xxstring)) < 0) { - if (x == -3) { - makestr(&ssh_tmpstr,""); - } else { - return(x); - } - } else { - s = brstrip(s); - if ((x = (int)strlen(s)) > PWBUFL) { - makestr(&slmsg,"Internal error"); - printf("?Sorry, too long - max = %d\n",PWBUFL); - return(-9); - } - makestr(&ssh_tmpstr,s); - } - break; - - case SSHSW_VER: - if ((x = cmnum("Number","",10,&z,xxstring)) < 0) - return(x); - if (z < 1 || z > 2) { - printf("?Out of range: %d\n",z); - return(-9); - } - tmpver = z; - break; - default: - return(-2); - } - } - if (trips++ == 0) { /* After first time through */ - cmfdbi(&kw, /* only parse switches, not port. */ - _CMKEY, - "Switch", - "", - "", - nsshkrmopnsw, - 4, - xxstring, - sshkrmopnsw, - NULL - ); - } - } - if ((x = cmcfm()) < 0) /* Get confirmation */ - return(x); - if (clskconnx(1) < 0) { /* Close current Kermit connection */ - if ( ssh_tmpstr ) { - memset(ssh_tmpstr,0,strlen(ssh_tmpstr)); - makestr(&ssh_tmpstr,NULL); - } - return(success = 0); - } - makestr(&ssh_hst,line); /* Stash everything */ - if (ssh_tmpuid) { - if (!sl_uid_saved) { - ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN); - sl_uid_saved = 1; - } - ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN); - makestr(&ssh_tmpuid,NULL); - } - if (ssh_tmpport) { - makestr(&ssh_prt,ssh_tmpport); - makestr(&ssh_tmpport,NULL); - } else - makestr(&ssh_prt,NULL); - - /* Set the Subsystem to Kermit */ - ssh_cas = 1; - makestr(&ssh_cmd,"kermit"); - - if (tmpver > -1) { -#ifndef SSHTEST - if (!sl_ssh_ver_saved) { - sl_ssh_ver = ssh_ver; - sl_ssh_ver_saved = 1; - } -#endif /* SSHTEST */ - ssh_ver = tmpver; - } - /* Disable X11 Forwarding */ -#ifndef SSHTEST - if (!sl_ssh_xfw_saved) { - sl_ssh_xfw = ssh_xfw; - sl_ssh_xfw_saved = 1; - } -#endif /* SSHTEST */ - ssh_xfw = 0; - - if (ssh_tmpstr) { - if (ssh_tmpstr[0]) { - ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1); - pwflg = 1; - pwcrypt = 0; - } else - pwflg = 0; - makestr(&ssh_tmpstr,NULL); - } - nettype = NET_SSH; - if (mdmsav < 0) - mdmsav = mdmtyp; - mdmtyp = -nettype; - x = 1; - -#ifndef NOSPL - makestr(&g_pswd,pwbuf); /* Save global pwbuf */ - g_pflg = pwflg; /* and flag */ - g_pcpt = pwcrypt; -#endif /* NOSPL */ - - /* Line parameter to ttopen() is ignored */ - k = ttopen(line,&x,mdmtyp, 0); - if (k < 0) { - printf("?Unable to connect to %s\n",ssh_hst); - mdmtyp = mdmsav; - slrestor(); - return(success = 0); - } - duplex = 0; /* Remote echo */ - ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */ - debug(F110,"ssh ttname",ttname,0); - makestr(&slmsg,NULL); /* No SET LINE error message */ - cxtype = CXT_SSH; -#ifndef NODIAL - dialsta = DIA_UNK; -#endif /* NODIAL */ - success = 1; /* SET LINE succeeded */ - network = 1; /* Network connection (not serial) */ - local = 1; /* Local mode (not remote) */ - if ((reliable != SET_OFF || !setreliable)) - reliable = SET_ON; /* Transport is reliable end to end */ -#ifdef OS2 - DialerSend(OPT_KERMIT_CONNECT, 0); -#endif /* OS2 */ - setflow(); /* Set appropriate flow control */ - - haveline = 1; -#ifdef CKLOGDIAL -#ifdef NETCONN - dolognet(); -#endif /* NETCONN */ -#endif /* CKLOGDIAL */ - -#ifndef NOSPL - if (local) { - if (nmac) { /* Any macros defined? */ - int k; /* Yes */ - k = mlook(mactab,"on_open",nmac); /* Look this up */ - if (k >= 0) { /* If found, */ - if (dodo(k,ssh_hst,0) > -1) /* set it up, */ - parser(1); /* and execute it */ - } - } - } -#endif /* NOSPL */ -#ifdef LOCUS - if (autolocus) - setlocus(1,1); -#endif /* LOCUS */ - - /* Command was confirmed so we can pre-pop command level. */ - /* This is so CONNECT module won't think we're executing a */ - /* script if CONNECT was the final command in the script. */ - if (cmdlvl > 0) - prepop(); - return(success = 1); - - default: - return(-2); - } - } -#endif /* SSHBUILTIN */ - -#ifdef SFTP_BUILTIN - if (cx == XXSFTP) { /* SFTP (Secure Shell File Transfer) */ - extern int netsave; - int k, x, havehost = 0, trips = 0; - int tmpver = -1, tmpxfw = -1; -#ifndef SSHTEST - extern int sl_ssh_xfw, sl_ssh_xfw_saved; - extern int sl_ssh_ver, sl_ssh_ver_saved; -#endif /* SSHTEST */ - extern int mdmtyp, mdmsav, cxtype, sl_uid_saved; - extern char * slmsg; - extern char uidbuf[], sl_uidbuf[]; - extern char pwbuf[], * g_pswd; - extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal; - struct FDB sw, kw, fl; - - if (ssh_tmpstr) - memset(ssh_tmpstr,0,strlen(ssh_tmpstr)); - makestr(&ssh_tmpstr,NULL); - makestr(&ssh_tmpuid,NULL); - makestr(&ssh_tmpcmd,NULL); - makestr(&ssh_tmpport,NULL); - - cmfdbi(&kw, /* 1st FDB - commands */ - _CMKEY, /* fcode */ - "host [ port ],\n or action", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nsftpkwtab, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: 0 = keyword */ - xxstring, /* Processing function */ - sftpkwtab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* Host */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - x = cmfdb(&kw); - if (x == -3) { - printf("?sftp what?\n"); - return(-9); - } - if (x < 0) - return(x); - havehost = 0; - if (cmresult.fcode == _CMFLD) { - havehost = 1; - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */ - cmresult.nresult = SFTP_OPN; - } - switch (cmresult.nresult) { /* SFTP keyword */ - case SFTP_OPN: /* SFTP OPEN */ - if (!havehost) { - if ((x = cmfld("Host","",&s,xxstring)) < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - } - /* Parse [ port ] [ switches ] */ - cmfdbi(&kw, /* Switches */ - _CMKEY, - "Port number or service name,\nor switch", - "", - "", - nsshkrmopnsw, - 4, - xxstring, - sshkrmopnsw, - &fl - ); - cmfdbi(&fl, /* Port number or service name */ - _CMFLD, - "", - "", - "", - 0, - 0, - xxstring, - NULL, - NULL - ); - trips = 0; /* Explained below */ - while (1) { /* Parse port and switches */ - x = cmfdb(&kw); /* Get a field */ - if (x == -3) /* User typed CR so quit from loop */ - break; - if (x < 0) /* Other parse error, pass it back */ - return(x); - switch (cmresult.fcode) { /* Field or Keyword? */ - case _CMFLD: /* Field */ - makestr(&ssh_tmpport,cmresult.sresult); - break; - case _CMKEY: /* Keyword */ - switch (cmresult.nresult) { /* Which one? */ - case SSHSW_USR: /* /USER: */ - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((y = cmfld("Username","",&s,xxstring)) < 0) - return(y); - s = brstrip(s); - makestr(&ssh_tmpuid,s); - break; - case SSHSW_PWD: - if (!cmgbrk()) { - printf("?This switch requires an argument\n"); - return(-9); - } - debok = 0; - if ((x = cmfld("Password","",&s,xxstring)) < 0) { - if (x == -3) { - makestr(&ssh_tmpstr,""); - } else { - return(x); - } - } else { - s = brstrip(s); - if ((x = (int)strlen(s)) > PWBUFL) { - makestr(&slmsg,"Internal error"); - printf("?Sorry, too long - max = %d\n",PWBUFL); - return(-9); - } - makestr(&ssh_tmpstr,s); - } - break; - - case SSHSW_VER: - if ((x = cmnum("Number","",10,&z,xxstring)) < 0) - return(x); - if (z < 1 || z > 2) { - printf("?Out of range: %d\n",z); - return(-9); - } - tmpver = z; - break; - default: - return(-2); - } - } - if (trips++ == 0) { /* After first time through */ - cmfdbi(&kw, /* only parse switches, not port. */ - _CMKEY, - "Switch", - "", - "", - nsshkrmopnsw, - 4, - xxstring, - sshkrmopnsw, - NULL - ); - } - } - if ((x = cmcfm()) < 0) /* Get confirmation */ - return(x); - if (clskconnx(1) < 0) { /* Close current Kermit connection */ - if ( ssh_tmpstr ) { - memset(ssh_tmpstr,0,strlen(ssh_tmpstr)); - makestr(&ssh_tmpstr,NULL); - } - return(success = 0); - } - makestr(&ssh_hst,line); /* Stash everything */ - if (ssh_tmpuid) { - if (!sl_uid_saved) { - ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN); - sl_uid_saved = 1; - } - ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN); - makestr(&ssh_tmpuid,NULL); - } - if (ssh_tmpport) { - makestr(&ssh_prt,ssh_tmpport); - makestr(&ssh_tmpport,NULL); - } else - makestr(&ssh_prt,NULL); - - /* Set the Subsystem to Kermit */ - ssh_cas = 1; - makestr(&ssh_cmd,"sftp"); - - if (tmpver > -1) { -#ifndef SSHTEST - if (!sl_ssh_ver_saved) { - sl_ssh_ver = ssh_ver; - sl_ssh_ver_saved = 1; - } -#endif /* SSHTEST */ - ssh_ver = tmpver; - } - /* Disable X11 Forwarding */ -#ifndef SSHTEST - if (!sl_ssh_xfw_saved) { - sl_ssh_xfw = ssh_xfw; - sl_ssh_xfw_saved = 1; - } -#endif /* SSHTEST */ - ssh_xfw = 0; - - if (ssh_tmpstr) { - if (ssh_tmpstr[0]) { - ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1); - pwflg = 1; - pwcrypt = 0; - } else - pwflg = 0; - makestr(&ssh_tmpstr,NULL); - } - nettype = NET_SSH; - if (mdmsav < 0) - mdmsav = mdmtyp; - mdmtyp = -nettype; - x = 1; - -#ifndef NOSPL - makestr(&g_pswd,pwbuf); /* Save global pwbuf */ - g_pflg = pwflg; /* and flag */ - g_pcpt = pwcrypt; -#endif /* NOSPL */ - - /* Line parameter to ttopen() is ignored */ - k = ttopen(line,&x,mdmtyp, 0); - if (k < 0) { - printf("?Unable to connect to %s\n",ssh_hst); - mdmtyp = mdmsav; - slrestor(); - return(success = 0); - } - duplex = 0; /* Remote echo */ - ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */ - debug(F110,"ssh ttname",ttname,0); - makestr(&slmsg,NULL); /* No SET LINE error message */ - cxtype = CXT_SSH; -#ifndef NODIAL - dialsta = DIA_UNK; -#endif /* NODIAL */ - success = 1; /* SET LINE succeeded */ - network = 1; /* Network connection (not serial) */ - local = 1; /* Local mode (not remote) */ - if ((reliable != SET_OFF || !setreliable)) - reliable = SET_ON; /* Transport is reliable end to end */ -#ifdef OS2 - DialerSend(OPT_KERMIT_CONNECT, 0); -#endif /* OS2 */ - setflow(); /* Set appropriate flow control */ - - haveline = 1; -#ifdef CKLOGDIAL -#ifdef NETCONN - dolognet(); -#endif /* NETCONN */ -#endif /* CKLOGDIAL */ - -#ifndef NOSPL - if (local) { - if (nmac) { /* Any macros defined? */ - int k; /* Yes */ - k = mlook(mactab,"on_open",nmac); /* Look this up */ - if (k >= 0) { /* If found, */ - if (dodo(k,ssh_hst,0) > -1) /* set it up, */ - parser(1); /* and execute it */ - } - } - } -#endif /* NOSPL */ -#ifdef LOCUS - if (autolocus) - setlocus(1,1); -#endif /* LOCUS */ - - /* Command was confirmed so we can pre-pop command level. */ - /* This is so CONNECT module won't think we're executing a */ - /* script if CONNECT was the final command in the script. */ - if (cmdlvl > 0) - prepop(); - - success = sftp_do_init(); - return(success = 1); - - case SFTP_CD: - case SFTP_CHGRP: - case SFTP_CHMOD: - case SFTP_CHOWN: - case SFTP_RM: - case SFTP_DIR: - case SFTP_GET: - case SFTP_MKDIR: - case SFTP_PUT: - case SFTP_PWD: - case SFTP_REN: - case SFTP_RMDIR: - case SFTP_LINK: - case SFTP_VER: - if ((y = cmtxt("command parameters","",&s,xxstring)) < 0) - return(y); - if (ssh_tchk() < 0 || !ssh_cas || strcmp(ssh_cmd,"sftp")) { - printf("?Not connected to SFTP Service\n"); - return(success = 0); - } - success = sftp_do_cmd(cmresult.nresult,s); - return(success); - default: - return(-2); - } - } -#endif /* SFTP_BUILTIN */ - - if (cx == XXRLOG) { /* RLOGIN */ -#ifdef RLOGCODE - int x,z; -#ifdef OS2 - if (!tcp_avail) { - printf("?Sorry, either TCP/IP is not available on this system or\n\ -necessary DLLs did not load. Use SHOW NETWORK to check network status.\n" - ); - success = 0; - return(-9); - } else { -#endif /* OS2 */ - x = nettype; /* Save net type in case of failure */ - z = ttnproto; /* Save protocol in case of failure */ - nettype = NET_TCPB; - ttnproto = NP_RLOGIN; - if ((y = setlin(XYHOST,0,1)) <= 0) { - nettype = x; /* Failed, restore net type. */ - ttnproto = z; /* and protocol */ - success = 0; - } - didsetlin++; -#ifdef OS2 - } -#endif /* OS2 */ - return(y); -#else - printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n"); - return(-9); -#endif /* RLOGCODE */ - } -#endif /* NETCONN */ -#endif /* NOLOCAL */ - -#ifndef NOXMIT - if (cx == XXTRA) { /* TRANSMIT */ - extern int xfrxla; - int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval; - int xxecho = 0; - int scan = 1; - char c; - struct FDB sf, sw, tx; /* FDBs for parse functions */ -#ifndef NOCSETS - extern int tcs_transp; /* Term charset is transparent */ -#else - int tcs_transp = 1; -#endif /* NOCSETS */ - -#ifdef COMMENT - xbinary = binary; /* Default text/binary mode */ -#else - xbinary = 0; /* Default is text */ -#endif /* COMMENT */ - xxecho = xmitx; - - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Filename, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nxmitsw, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - xmitsw, /* Keyword table */ - &sf /* Pointer to next FDB */ - ); - cmfdbi(&sf, /* 2nd FDB - file to send */ - _CMIFI, /* fcode */ - "File to transmit", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, -#ifdef PIPESEND - &tx -#else - NULL -#endif /* PIPESEND */ - ); -#ifdef PIPESEND - cmfdbi(&tx, - _CMTXT, /* fcode */ - "Command", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); -#endif /* PIPESEND */ - - while (1) { - x = cmfdb(&sw); - if (x < 0) - return(x); - if (cmresult.fcode != _CMKEY) - break; - c = cmgbrk(); /* Have switch, get break character */ - if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - n = cmresult.nresult; /* Numeric result = switch ID */ - switch (n) { /* Process the switch */ -#ifdef PIPESEND - case XMI_CMD: /* Transmit from a command */ - if (nopush) { - printf("?Sorry, system command access is disabled\n"); - return(-9); - } - sw.hlpmsg = "Command, or switch"; /* Change help message */ - xpipe = 1; /* (No way to undo this one) */ - break; -#endif /* PIPESEND */ - - case XMI_BIN: /* Binary */ - xbinary = 1; - xxlate = 0; /* Don't translate charsets */ - scan = 0; - break; - - case XMI_TXT: /* Text */ - xbinary = 0; - xxlate = !tcs_transp; /* Translate if TERM CHAR not TRANSP */ - scan = 0; - break; - - case XMI_TRA: /* Transparent text */ - xbinary = 0; - xxlate = 0; /* But don't translate charsets */ - scan = 0; - break; - -#ifdef COMMENT - case XMI_VRB: /* /VERBOSE */ - case XMI_QUI: /* /QUIET */ - break; /* (not implemented yet) */ -#endif /* COMMENT */ - - case XMI_NOW: /* /NOWAIT */ - xxnowait = 1; - break; - - case XMI_NOE: /* /NOWAIT */ - xxecho = 0; - break; - - default: - return(-2); - } - - } - if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT) - return(-2); - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */ - if (zfnqfp(line,TMPBUFSIZ,tmpbuf)) - ckstrncpy(line,tmpbuf,LINBUFSIZ); - s = line; - if ((y = cmcfm()) < 0) /* Confirm */ - return(y); -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ - if (cmresult.nresult != 0) { - printf("?Only a single file may be transmitted\n"); - return(-9); - } -#ifdef PIPESEND - if (xpipe) { - s = brstrip(s); - if (!*s) { - printf("?Sorry, a command to send from is required\n"); - return(-9); - } - pipesend = 1; - } -#endif /* PIPESEND */ - - if (scan && (filepeek -#ifndef NOXFER - || patterns -#endif /* NOXFER */ - )) { /* If user didn't specify type */ - int k, x; /* scan the file to see */ - x = -1; - k = scanfile(s,&x,nscanfile); - if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T; - } - if (!xfrxla) xxlate = 0; - success = transmit(s, - (char) (xxnowait ? '\0' : (char)xmitp), - xxlate, - xbinary, - xxecho - ); - return(success); - } -#endif /* NOXMIT */ - -#ifndef NOFRILLS - if (cx == XXTYP || cx == XXCAT || cx == XXMORE || - cx == XXHEAD || cx == XXTAIL) { - int paging = 0, havename = 0, head = 0, width = 0; - int height = 0, count = 0; - char pfxbuf[64], * prefix = NULL; - char outfile[CKMAXPATH+1]; - struct FDB sf, sw; - char * pat = NULL; - int incs = 0, outcs = 0, cset = -1, number = 0; -#ifdef UNICODE - char * tocs = ""; - extern int fileorder; -#ifdef OS2 -#ifdef NT - char guibuf[128], * gui_title = NULL; - int gui = 0; -#endif /* NT */ -#ifndef NOCSETS - extern int tcsr, tcsl; -#endif /* NOCSETS */ -#endif /* OS2 */ -#endif /* UNICODE */ - - outfile[0] = NUL; - - if (cx == XXMORE) - paging = 1; - else if (cx == XXCAT) - paging = 0; - else - paging = (typ_page < 0) ? xaskmore : typ_page; - if (paging < 0) - paging = saveask; - - if (cx == XXHEAD) { - head = 10; - cx = XXTYP; - } else if (cx == XXTAIL) { - head = -10; - cx = XXTYP; - } - -#ifdef IKSD - if (inserver && !ENABLED(en_typ)) { - printf("?Sorry, TYPE command disabled\n"); - return(-9); - } -#endif /* IKSD */ - - cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */ - _CMKEY, /* fcode */ - "Filename or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - ntypetab, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - typetab, /* Keyword table */ - &sf /* Pointer to next FDB */ - ); - cmfdbi(&sf, /* 1st FDB - file to type */ - _CMIFI, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - while (!havename) { - x = cmfdb(&sw); /* Parse something */ - debug(F101,"type cmfdb","",x); - debug(F101,"type cmresult.fcode","",cmresult.fcode); - debug(F101,"type cmresult.nresult","",cmresult.nresult); - if (x < 0) { /* Error */ - if (x == -3) { - x = -9; - printf("?Filename required\n"); - } - return(x); - } else if (cmresult.fcode == _CMKEY) { - char c; int getval; - c = cmgbrk(); - getval = (c == ':' || c == '='); - if (getval && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } -#ifdef COMMENT - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - /* Not if it has a default! */ - return(-9); - } -#endif /* COMMENT */ - switch (cmresult.nresult) { -#ifdef CK_TTGWSIZ - case TYP_PAG: - paging = 1; - break; - - case TYP_NOP: - paging = 0; - break; -#endif /* CK_TTGWSIZ */ - - case TYP_COU: - paging = 0; - count = 1; - break; - - case TYP_HEA: - case TYP_TAI: - y = 10; - if (getval) - if ((x = cmnum("Number of lines", - "10",10,&y,xxstring)) < 0) - return(x); - head = (cmresult.nresult == TYP_TAI) ? -y : y; - break; - - case TYP_WID: - y = typ_wid > -1 ? typ_wid : cmd_cols; - if (getval) - if ((x = cmnum("Column at which to truncate", - ckitoa(y),10,&y,xxstring)) < 0) - return(x); - width = y; - break; - -#ifdef KUI - case TYP_HIG: - if (getval) - if ((x = cmnum("Height of GUI dialog", - ckitoa(y),10,&y,xxstring)) < 0) - return(x); - height = y; - break; -#endif /* KUI */ - - case TYP_PAT: - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((x = cmfld("pattern","",&s,xxstring)) < 0) - return(x); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - pat = tmpbuf; - break; - - case TYP_PFX: - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0) - return(x); - if ((int)strlen(s) > 63) { - printf("?Too long - 63 max\n"); - return(-9); - } - ckstrncpy(pfxbuf,s,64); - prefix = brstrip(pfxbuf); - number = 0; - break; - -#ifdef KUI - case TYP_GUI: - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((x = cmfld("Dialog box title","",&s,xxstring)) < 0) { - if (x != -3) - return(x); - } else { - if ((int)strlen(s) > 127) { - printf("?Too long - 127 max\n"); - return(-9); - } - ckstrncpy(guibuf,s,128); - gui_title = brstrip(guibuf); - } - gui = 1; - break; -#endif /* KUI */ - - case TYP_NUM: /* /NUMBER */ - number = 1; - prefix = NULL; - break; - -#ifdef UNICODE - case TYP_XPA: /* /TRANSPARENT */ - incs = 0; - cset = 0; - outcs = -1; - break; - - case TYP_XIN: /* /CHARACTER-SET: */ - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } - if ((incs = cmkey(fcstab,nfilc, - "character-set name","",xxstring)) < 0) { - if (incs == -3) /* Note: No default */ - incs = -2; - return(incs); - } - cset = incs; - break; - - case TYP_XUT: /* /TRANSLATE-TO: */ - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - return(-9); - } -#ifdef OS2 - if (!inserver && !k95stdout) { - tocs = "ucs2"; - } else { -#ifdef CKOUNI - tocs = rlookup(txrtab,ntxrtab,tcsl); -#else /* CKOUNI */ - extern struct keytab ttcstab[]; - extern int ntxrtab; - tocs = rlookup(ttcstab,ntermc,tocs); - if (!tocs) - tocs = getdcset(); -#endif /* CKOUNI */ - } -#else /* OS2 */ - tocs = getdcset(); -#endif /* OS2 */ - if ((outcs = cmkey(fcstab,nfilc, - "character-set",tocs,xxstring)) < 0) - return(outcs); - break; -#endif /* UNICODE */ - case TYP_OUT: - if ((x = cmofi("File for result lines","", - &s,xxstring)) < 0) - return(x); - ckstrncpy(outfile,s,CKMAXPATH); - break; - } - } else if (cmresult.fcode == _CMIFI) - havename = 1; - else - return(-2); - } - if (havename) { - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - y = cmresult.nresult; - } else { - if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) { - if (x == -3) { - printf("?Name of an existing file required\n"); - return(-9); - } else return(x); - } - ckstrncpy(line,s,LINBUFSIZ); - } - if (y != 0) { - printf("?A single file please\n"); - return(-9); - } -#ifdef KUI - if ( outfile[0] && gui ) { - printf("?/GUI and /OUTPUT are incompatible\n"); - return(-9); - } -#endif /* KUI */ - - if ((y = cmcfm()) < 0) /* Confirm the command */ - return(y); - -#ifdef UNICODE - fileorder = -1; - if (cset < 0 && filepeek) { /* If no charset switches given */ - int k, x = -1; - k = scanfile(line,&x,nscanfile); /* Call file analyzer */ - debug(F111,"type scanfile",line,k); - debug(F101,"type scanfile flag","",x); - switch(k) { - case FT_UTF8: /* which can detect UTF-8... */ - cset = 0; - incs = FC_UTF8; - break; - case FT_UCS2: /* and UCS-2... */ - cset = 0; - incs = FC_UCS2; - fileorder = x; /* even if there is no BOM. */ - debug(F101,"type fileorder","",fileorder); - break; - } - } -#ifdef OS2 - if (cset < 0) { /* If input charset still not known */ -#ifdef CKOUNI - tocs = rlookup(txrtab,ntxrtab,tcsl); -#else /* CKOUNI */ - extern struct keytab ttcstab[]; - extern int ntxrtab; - tocs = rlookup(ttcstab,ntermc,incs); - if (!tocs) - tocs = getdcset(); -#endif /* CKOUNI */ - incs = lookup(fcstab,tocs,nfilc,&x); - } -#endif /* OS2 */ - - if (outcs == 0 && incs != 0) { /* Supply default target charset */ - int x = 0; /* if switch not given. */ - tocs = getdcset(); - outcs = lookup(fcstab,tocs,nfilc,&x); - } -#else /* !UNICODE */ - if (cset < 0) incs = outcs = 0; -#endif /* UNICODE */ - - if (outfile[0] && paging) /* This combination makes no sense */ - paging = 0; /* so turn off paging */ - -#ifdef KUI - /* No paging when dialog is used */ - if ( gui && paging ) - paging = 0; - - if ( !gui && height ) { - printf("?The /HEIGHT switch is not supported without /GUI\n"); - return(-9); - } -#endif /* KUI */ - - if (count) paging = -1; - debug(F111,"type",line,paging); -#ifdef KUI - if ( gui ) { - s = (char *)1; /* ok, its an ugly hack */ - if (gui_text_popup_create(gui_title ? - gui_title : line, height,width) < 0) { - printf("?/GUI not supported on this system\n"); - gui = 0; - return(-9); - } - width = 0; - } else -#endif /* KUI */ - s = outfile; - success = - dotype(line,paging,0,head,pat,width,prefix,incs,outcs,s,number); - return(success); - } -#endif /* NOFRILLS */ - -#ifndef NOCSETS - if (cx == XXXLA) { /* TRANSLATE file's charset */ - _PROTOTYP (int doxlate, ( void ) ); - return(doxlate()); - } -#endif /* NOCSETS */ - - if (cx == XXVER) { /* VERSION */ - int n = 0; - extern char * ck_patch, * ck_s_test; -#ifdef COMMENT - extern int hmtopline; -#endif /* COMMENT */ - if ((y = cmcfm()) < 0) - return(y); - - printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum); - printf("\n\n"); - printf("Authors:\n"); - printf(" Frank da Cruz, Columbia University\n"); - printf(" Jeffrey Eric Altman, Secure Endpoints, Inc. %s\n", - "" - ); - printf(" Contributions from many others.\n"); - n = 7; - if (*ck_s_test) { - printf("\nTHIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n"); - n += 2; - } - if (*ck_patch) { - printf(" Patches: %s\n", ck_patch); - n++; - } - printf(" Type COPYRIGHT for copyright and license.\n\n"); -#ifdef OS2 - shoreg(); -#else -#ifdef COMMENT - hmtopline = n+1; - hmsga(copyright); - hmtopline = 0; -#endif /* COMMENT */ -#endif /* OS2 */ - return(success = 1); - } - - if (cx == XXCPR) { /* COPYRIGHT or LICENSE */ - if ((y = cmcfm()) < 0) - return(y); -#ifdef OS2 - if (inserver) { /* Free WIKSD */ - extern char * wiksdcpr[]; - hmsga(wiksdcpr); - } else -#endif /* OS2 */ - hmsga(copyright); - return(success = 1); - } - -#ifndef MAC /* Only for multiuser systems */ -#ifndef OS2 -#ifndef NOFRILLS - if (cx == XXWHO) { /* WHO */ - char *wc; -#ifdef IKSD - if (inserver && !ENABLED(en_who)) { - printf("?Sorry, WHO command disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef datageneral - if ((z = cmcfm()) < 0) return(z); - if (nopush) { - printf("?Sorry, who not allowed\n"); - return(success = 0); - } - xsystem(WHOCMD); -#else - if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y); - if (nopush) { - printf("?Sorry, WHO command disabled\n"); - return(success = 0); - } - if (!(wc = getenv("CK_WHO"))) wc = WHOCMD; - if (wc) - if ((int) strlen(wc) > 0) { - ckmakmsg(line,LINBUFSIZ,wc," ",s,NULL); - xsystem(line); - } -#endif /* datageneral */ - return(success = 1); - } -#endif /* NOFRILLS */ -#endif /* OS2 */ -#endif /* MAC */ - -#ifndef NOFRILLS - if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */ - int x,y; /* On stack in case of \fexec() */ - if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) { - if (x == -3) printf("?Write to what?\n"); - return(x); - } - if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y); - s = brstrip(s); - switch (x) { - case LOGD: y = ZDFILE; break; - case LOGP: y = ZPFILE; break; -#ifndef NOLOCAL - case LOGS: y = ZSFILE; break; -#endif /* NOLOCAL */ - case LOGT: y = ZTFILE; break; -#ifndef NOSPL - case LOGW: y = ZWFILE; break; -#endif /* NOSPL */ - case LOGX: /* SCREEN (stdout) */ - case LOGE: /* ERROR (stderr) */ - if (x == LOGE) { - debug(F110, - (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0); - fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : ""); - } else { - debug(F110, - (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0); - printf("%s%s",s,(cx == XXWRL) ? "\n" : ""); - } - return(success = 1); - default: return(-2); - } - if (chkfn(y) > 0) { - x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s); - if (x < 0) printf("?Write error\n"); - } else { - x = -1; - printf("?File or log not open\n"); - } - return(success = (x == 0) ? 1 : 0); - } -#endif /* NOFRILLS */ - -#ifndef NOXFER - if (cx == XXASC || cx == XXBIN) { - if ((x = cmcfm()) < 0) return(x); -#ifdef NEWFTP - if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) - return(success = doftptyp((cx == XXASC) ? 0 : 1)); -#endif /* NEWFTP */ - binary = (cx == XXASC) ? XYFT_T : XYFT_B; - return(success = 1); - } -#endif /* NOXFER */ - - if (cx == XXCLS) { - if ((x = cmcfm()) < 0) return(x); - y = ck_cls(); - return(success = (y > -1) ? 1 : 0); - } - -#ifdef CK_MKDIR - if (cx == XXMKDIR || cx == XXLMKD) { - char *p; -#ifdef LOCUS - if (!locus && cx != XXLMKD) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZMKD)); -#endif /* NOXFER */ - } -#endif /* LOCUS */ -#ifdef IKSD - if (inserver && !ENABLED(en_mkd)) { - printf("?Sorry, directory creation is disabled\n"); - return(-9); - } -#endif /* IKSD */ - if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) { - if (x != -3) { - return(x); - } else { - printf("?Directory name required\n"); - return(-9); - } - } - ckstrncpy(line,s,LINBUFSIZ); - s = line; - if ((x = cmcfm()) < 0) return(x); - s = brstrip(s); - bgchk(); /* Set msgflg */ - x = ckmkdir(0,s,&p,msgflg,0); -#ifdef COMMENT - if (msgflg && x == 0) - printf("?Directory already exists\n"); -#endif /* COMMENT */ - return(success = (x < 0) ? 0 : 1); - } - if (cx == XXRMDIR || cx == XXLRMD) { /* RMDIR */ - char *p; -#ifdef LOCUS - if (!locus && cx != XXLRMD) { -#ifdef NOXFER - return(-2); -#else - return(dormt(XZRMD)); -#endif /* NOXFER */ - } -#endif /* LOCUS */ -#ifdef IKSD - if (inserver && !ENABLED(en_rmd)) { - printf("?Sorry, directory removal is disabled\n"); - return(-9); - } -#endif /* IKSD */ - if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - s = line; - if ((x = cmcfm()) < 0) return(x); - s = brstrip(s); - x = ckmkdir(1,s,&p,msgflg,0); - return(success = (x < 0) ? 0 : 1); - } -#endif /* CK_MKDIR */ - -#ifdef TNCODE - if (cx == XXTELOP) - return(dotelopt()); -#endif /* TNCODE */ - -#ifndef NOPUSH - if (cx == XXNPSH) { - if ((z = cmcfm()) < 0) return(z); - nopush = 1; -#ifndef NOSERVER - en_hos = 0; -#endif /* NOSERVER */ -#ifdef PIPESEND - usepipes = 0; -#endif /* PIPESEND */ - return(success = 1); - } -#endif /* NOPUSH */ - -#ifdef OS2 - if (cx == XXNSCR) { - if ((z = cmcfm()) < 0) return(z); - tt_scroll = 0; - return(success = 1); - } -#endif /* OS2 */ - -#ifndef NOSPL - if (cx == XXLOCAL) /* LOCAL variable declarations */ - return(success = dolocal()); -#endif /* NOSPL */ - - if (cx == XXKERMI) { /* The KERMIT command */ - char * list[65]; - extern char **xargv; - extern int xargc; - int i; - if ((y = cmtxt("kermit command-line arguments, -h for help", - "",&s,xxstring)) < 0) - return(y); - ckstrncpy(line,"kermit ",LINBUFSIZ); - ckstrncat(line,s,LINBUFSIZ-8); - xwords(line,64,list,0); - for (i = 1; i < 64; i++) { - if (!list[i]) - break; - } - i--; - xargc = i; - xargv = list; - xargv++; - sstate = cmdlin(); - if (sstate) { - extern int justone; - debug(F000,"KERMIT sstate","",sstate); - justone = 1; /* Force return to command mode */ - proto(); /* after protocol */ - return(success); - } else { - debug(F101,"KERMIT sstate","",sstate); - return(success = 1); /* Not exactly right, but... */ - } - } - if (cx == XXDATE) { /* DATE command */ - extern char cmdatebuf[], * cmdatemsg; - -#ifndef COMMENT - char * dp; - if ((y = cmtxt("date and/or time, or carriage return for current", - "",&s,xxstring)) < 0) - return(y); - s = brstrip(s); - dp = cmcvtdate(s,1); - if (!dp) { - printf("?%s\n",cmdatemsg ? cmdatemsg : "Date conversion error"); - success = 0; - } else { - printf("%s\n",dp); - success = 1; - } -#else - /* This works fine but messes up my "dates" torture-test script */ - - if ((x = cmdate("Date and/or time, or carriage return for current", - "",&s,0,xxstring)) < 0) { - return(x); - } else { - printf("%s\n",cmdatebuf); - success = 1; - } -#endif /* COMMENT */ - return(success); - } -#ifndef NOPUSH -#ifndef NOFRILLS - if (cx == XXEDIT) - return(doedit()); -#endif /* NOFRILLS */ -#endif /* NOPUSH */ - -#ifdef BROWSER /* Defined only ifndef NOPUSH */ - if (cx == XXBROWS) - return(dobrowse()); -#endif /* BROWSER */ - -#ifdef CK_TAPI - if (cx == XXTAPI) { /* Microsoft TAPI */ - return (success = dotapi()); - } -#endif /* CK_TAPI */ - -#ifndef NOXFER - if (cx == XXWHERE) { - extern char * rfspec, * sfspec, * srfspec, * rrfspec; - if ((x = cmcfm()) < 0) return(x); - printf("\nFile most recently...\n\n"); - printf(" Sent: %s\n", sfspec ? sfspec : "(none)"); - if (sfspec && srfspec) { - printf(" Stored as: %s\n", srfspec); - printf("\n"); - } - printf(" Received: %s\n", rrfspec ? rrfspec : "(none)"); - if (rfspec && rrfspec) - printf(" Stored as: %s\n", rfspec); - printf( -"\nIf the full path is not shown, then the file is probably in your current\n" - ); - printf( -"directory or your download directory (if any - SHOW FILE to find out).\n\n" - ); - return(success = 1); - } -#endif /* NOXFER */ - -#ifdef CK_RECALL - if (cx == XXREDO) - return(doredo()); -#endif /* CK_RECALL */ - -#ifdef CKROOT - if (cx == XXCHRT) /* Change Kermit's root directory */ - return(dochroot()); -#endif /* CKROOT */ - -#ifdef CK_KERBEROS - if (cx == XXAUTH) { /* KERBEROS */ - x = cp_auth(); /* Parse it */ -#ifdef IKSD - if (inserver) { - printf("?Command disabled in IKSD.\r\n"); - return(success = 0); - } -#endif /* IKSD */ - if (x < 0) /* Pass parse errors back */ - return(x); - return(success = doauth(cx)); - } -#endif /* CK_KERBEROS */ - -#ifndef NOLOCAL - if (cx == XXTERM) { - return(settrmtyp()); - } -#endif /* NOLOCAL */ - - if (cx == XXSTATUS) { - if ((x = cmcfm()) < 0) return(x); - printf( " %s\n", success ? "SUCCESS" : "FAILURE" ); - return(0); /* Don't change it */ - } - - if (cx == XXFAIL) { - if ((x = cmcfm()) < 0) return(x); - return(success = 0); - } - - if (cx == XXSUCC) { - if ((x = cmcfm()) < 0) return(x); - return(success = 1); - } - - if (cx == XXNLCL) { - extern int nolocal; - if ((x = cmcfm()) < 0) return(x); - nolocal = 1; - return(success = 1); - } - -#ifndef NOXFER - if (cx == XXRASG) /* Shortcuts for REMOTE commands */ - return(dormt(XZASG)); - if (cx == XXRCWD) - return(dormt(XZCWD)); - if (cx == XXRCPY) - return(dormt(XZCPY)); - if (cx == XXRDEL) - return(dormt(XZDEL)); - if (cx == XXRDIR) - return(dormt(XZDIR)); - if (cx == XXRXIT) - return(dormt(XZXIT)); - if (cx == XXRHLP) - return(dormt(XZHLP)); - if (cx == XXRHOS) - return(dormt(XZHOS)); - if (cx == XXRKER) - return(dormt(XZKER)); - if (cx == XXRPWD) - return(dormt(XZPWD)); - if (cx == XXRQUE) - return(dormt(XZQUE)); - if (cx == XXRREN) - return(dormt(XZREN)); - if (cx == XXRMKD) - return(dormt(XZMKD)); - if (cx == XXRRMD) - return(dormt(XZRMD)); - if (cx == XXRSET) - return(dormt(XZSET)); - if (cx == XXRSPA) - return(dormt(XZSPA)); - if (cx == XXRTYP) - return(dormt(XZTYP)); - if (cx == XXRWHO) - return(dormt(XZWHO)); - if (cx == XXRCDUP) - return(dormt(XZCDU)); - if (cx == XXRPRI) - return(dormt(XZPRI)); -#endif /* NOXFER */ - - if (cx == XXRESET) { /* RESET */ - if ((x = cmcfm()) < 0) - return(x); - doclean(0); /* Close all files */ - return(success = 1); - } - -#ifndef NOXFER -#ifndef NOCSETS - if (cx == XXASSOC) /* ASSOCIATE */ - return(doassoc()); -#endif /* NOCSETS */ -#endif /* NOXFER */ - -#ifndef NOSPL - if (cx == XXSHIFT) { /* SHIFT */ - if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0) - return(y); - if ((z = cmcfm()) < 0) - return(z); - return(success = doshift(x)); - } -#endif /* NOSPL */ - -#ifndef NOHELP - if (cx == XXMAN) - return(domanual()); -#endif /* NOHELP */ - -#ifndef NOSPL - if (cx == XXSORT) /* SORT an array */ - return(dosort()); -#endif /* NOSPL */ - - if (cx == XXPURGE) { -#ifdef IKSD - if (inserver && (!ENABLED(en_del) -#ifdef CK_LOGIN - || isguest -#endif /* CK_LOGIN */ - )) { - printf("?Sorry, DELETE is disabled\n"); - return(-9); - } -#endif /* IKSD */ -#ifdef CK_APC - if ((apcactive == APC_LOCAL) || - ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH)))) - return(success = 0); -#endif /* CK_APC */ -#ifdef CKPURGE - return(dopurge()); -#else -#ifdef VMS - if ((x = cmtxt("optional switches followed by filespec", - "",&s,xxstring)) < 0) - return(x); - if (nopush) { - printf("?Sorry, DCL access is disabled\n"); - return(-9); - } - ckstrncpy(line,s,LINBUFSIZ); - s = line; - x = mlook(mactab,"purge",nmac); - return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs)); -#else - return(-2); -#endif /* VMS */ -#endif /* CKPURGE */ - } - -#ifndef NOSPL - if (cx == XXFAST) { - if ((x = cmcfm()) < 0) return(x); - x = mlook(mactab,"fast",nmac); - return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs)); - } - if (cx == XXCAU) { - if ((x = cmcfm()) < 0) return(x); - x = mlook(mactab,"cautious",nmac); - return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs)); - } - if (cx == XXROB) { - if ((x = cmcfm()) < 0) return(x); - x = mlook(mactab,"robust",nmac); - return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs)); - } -#endif /* NOSPL */ - - if (cx == XXSCRN) { /* SCREEN */ - int row, col; - if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0) - return(x); - switch (x) { /* MOVE-TO (cursor position) */ - case SCN_MOV: - if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0) - return(y); - row = z; - y = cmnum("Column (1-based)","1",10,&z,xxstring); - if (y < 0) - return(y); - col = z; - if ((y = cmcfm()) < 0) - return(y); - if (row < 0 || col < 0) { - printf("?Row and Column must be 1 or greater\n"); - return(-9); - } - if (cmd_rows > 0 && row > cmd_rows) - row = cmd_rows; - if (cmd_cols > 0 && col > cmd_cols) - col = cmd_cols; - y = ck_curpos(row,col); - return(success = (y > -1) ? 1 : 0); - - case SCN_CLR: /* CLEAR */ - if ((y = cmcfm()) < 0) - return(y); - debug(F100,"screen calling ck_cls()","",0); - y = ck_cls(); - return(success = (y > -1) ? 1 : 0); - - case SCN_CLE: /* CLEOL */ - if ((y = cmcfm()) < 0) - return(y); - y = ck_cleol(); - return(success = (y > -1) ? 1 : 0); - } - } - -#ifndef NOHTTP -#ifdef TCPSOCKET - if (cx == XXHTTP) - return(dohttp()); -#endif /* TCPSOCKET */ -#endif /* NOHTTP */ - -#ifndef NOSPL - if (cx == XXARRAY) { /* ARRAY */ -#ifndef NOSHOW - extern int showarray(); -#endif /* NOSHOW */ - if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0) - return(x); - switch (x) { - case ARR_DCL: - return(dodcl(XXDCL)); - case ARR_SRT: - return(dosort()); -#ifndef NOSHOW - case ARR_SHO: - return(showarray()); -#endif /* NOSHOW */ - case ARR_CPY: - return(copyarray()); - case ARR_SET: - case ARR_CLR: - return(clrarray(x)); - case ARR_DST: - return(unarray()); - case ARR_RSZ: - return(rszarray()); - case ARR_EQU: - return(linkarray()); - - default: - printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf); - return(-9); - } - } - if (cx == XXTRACE) - return(dotrace()); -#endif /* NOSPL */ - -#ifdef CK_PERMS -#ifdef UNIX - if (cx == XXCHMOD) - return(douchmod()); /* Do Unix chmod */ -#endif /* UNIX */ -#endif /* CK_PERMS */ - - if (cx == XXPROMP) - return(doprompt()); - - if (cx == XXGREP) - return(dogrep()); - - if (cx == XXDEBUG) { /* DEBUG */ -#ifndef DEBUG - int dummy = 0; - return(seton(&dummy)); -#else - return(seton(&deblog)); -#endif /* DEBUG */ - } - -#ifdef CKLEARN - if (cx == XXLEARN) { /* LEARN */ - struct FDB of, sw, cm; - int closing = 0, off = 0, on = 0, confirmed = 0; - char c; - - cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */ - _CMKEY, /* fcode */ - "Script file name, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 3, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - learnswi, /* Keyword table */ - &of /* Pointer to next FDB */ - ); - cmfdbi(&of,_CMOFI,"","","",0,0,xxstring,NULL,&cm); - cmfdbi(&cm,_CMCFM,"","","",0,0,NULL,NULL,NULL); - line[0] = NUL; - - while (!confirmed) { - x = cmfdb(&sw); /* Parse something */ - if (x < 0) - return(x); - switch (cmresult.fcode) { /* What was it? */ - case _CMOFI: /* Output file name */ - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - break; - case _CMKEY: /* Switch */ - c = cmgbrk(); - if ((c == ':' || c == '=') && !(cmgkwflgs() & CM_ARG)) { - printf("?This switch does not take an argument\n"); - return(-9); - } - switch (cmresult.nresult) { - case 2: /* /CLOSE */ - closing = 1; /* Fall thru on purpose */ - case 0: /* /OFF */ - off = 1; - on = 0; - break; - case 1: /* /ON */ - on = 1; - off = 0; - break; - } - break; - case _CMCFM: /* Confirmation */ - confirmed++; - break; - } - } - if (closing) { - if (learnfp) { - fclose(learnfp); - learnfp = NULL; - } - makestr(&learnfile,NULL); - } - if (line[0]) { - if (!on && !off) - on = 1; - if (learnfp) { - fclose(learnfp); - learnfp = NULL; - } - makestr(&learnfile,line); - if (learnfile) { - char * modes = "w"; - learnfp = fopen(learnfile,modes); - if (!learnfp) { - debug(F110,"LEARN file open error",learnfile,0); - perror(learnfile); - return(-9); - } else { -#ifdef ZFNQFP - if (zfnqfp(learnfile,TMPBUFSIZ,tmpbuf)) - makestr(&learnfile,tmpbuf); -#endif /* ZFNQFP */ - debug(F110,"LEARN file open ok",learnfile,0); - if (!quiet) { - printf("Recording to %s...\n\n",learnfile); - printf( -" WARNING: If you type your password during script recording, it will appear\n\ - in the file. Be sure to edit it or take other appropriate precautions.\n\n" - ); - } - fputs( "; Scriptfile: ",learnfp); - fputs(learnfile,learnfp); - fputs("\n; Directory: ",learnfp); - fputs(zgtdir(),learnfp); - fputs("\n; Recorded: ",learnfp); - fputs(ckdate(),learnfp); - fputs("\n",learnfp); - } - } - } - if (on) { - learning = 1; - } else if (off) { - learning = 0; - } - debug(F101,"LEARN learning","",learning); - return(success = 1); - } -#endif /* CKLEARN */ - -#ifdef NEWFTP - if (cx == XXUSER || cx == XXACCT) { - if (!ftpisopen()) { - printf("?FTP connection is not open\n"); - return(-9); - } - return(success = (cx == XXUSER) ? doftpusr() : doftpacct()); - } - if (cx == XXSITE || cx == XXPASV) { - if (!ftpisopen()) { - printf("?FTP connection is not open\n"); - return(-9); - } - return(success = (cx == XXSITE) ? doftpsite() : dosetftppsv()); - } -#endif /* NEWFTP */ - - if (cx == XXORIE) { /* ORIENTATION */ - extern char * myname; - int i, y, n = 0; - char * s, *p, vbuf[32]; - char * vars[16]; char * legend[16]; - - if ((y = cmcfm()) < 0) - return(y); - - printf("\nProgram name:\n %s\n\n",myname); - n += 4; - -#ifdef NT - vars[0] = "home"; legend[0] = "Your home directory"; - vars[1] = "directory"; legend[1] = "K95's current directory"; - vars[2] = "exedir"; legend[2] = "K95 Program directory"; - vars[3] = "inidir"; legend[3] = "K95 Initialization file directory"; - vars[4] = "startup"; legend[4] = "Current directory when started"; - - vars[5] = "common"; - legend[5] = "K95 data for all users and K95SITE.INI file"; - - vars[6] = "personal"; legend[6] = "Your personal data directory tree"; - vars[7] = "desktop"; legend[7] = "Your deskop directory tree"; - - vars[8] = "appdata"; - legend[8] = "Your personal K95 data tree and K95CUSTOM.INI file"; - - vars[9] = "download"; legend[9] = "Your K95 download directory"; - vars[10] = "tmpdir"; legend[10] = "Your TEMP directory"; - vars[11] = NULL; legend[11] = NULL; - - for (i = 0; i < 16 && vars[i]; i++) { - printf("%s:\n",legend[i]); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL); - printf(" Variable: %s\n",vbuf); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - y = TMPBUFSIZ; - s = tmpbuf; - zzstring(vbuf,&s,&y); - line[0] = NUL; - ckGetLongPathName(tmpbuf,line,LINBUFSIZ); - printf(" Long name: %s\n",line); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - line[0] = NUL; - GetShortPathName(tmpbuf,line,LINBUFSIZ); - printf(" Short name: %s\n",line); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf("\n"); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - } -#else /* NT */ - - vars[0] = "home"; legend[0] = "Your home directory"; - vars[1] = "directory"; legend[1] = "Kermit's current directory"; - vars[2] = "exedir"; legend[2] = "Kermit's program directory"; - vars[3] = "inidir"; legend[3] = "Initialization file directory"; - vars[4] = "startup"; legend[4] = "Current directory when started"; - vars[5] = "download"; legend[5] = "Kermit download directory"; - vars[6] = NULL; legend[6] = NULL; - - for (i = 0; i < 16 && vars[i]; i++) { - printf("%s:\n",legend[i]); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL); - printf(" Variable: %s\n",vbuf); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - y = TMPBUFSIZ; - s = tmpbuf; - zzstring(vbuf,&s,&y); - printf(" Value: %s\n",tmpbuf); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - printf("\n"); - if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0; - } -#endif /* NT */ - return(success = 1); - } - -#ifdef NT - if (cx == XXDIALER) { - StartDialer(); - return(success = 1); - } -#endif /* NT */ - - if (cx == XXCONT) { /* CONTINUE */ - if ((x = cmcfm()) < 0) - return(x); - if (!xcmdsrc) { /* At prompt: continue script */ - if (cmdlvl > 0) - popclvl(); /* Pop command level */ - return(success = 1); /* always succeeds */ -#ifndef NOSPL - } else { /* In script: whatever... */ - x = mlook(mactab,"continue",nmac); - /* Don't set success */ - return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs)); -#endif /* NOSPL */ - } - } - if (cx == XXNOTAV) { /* Command in table not available */ - ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ); - if ((x = cmtxt("Rest of command","",&s,NULL)) < 0) - return(x); - printf("Sorry, \"%s\" not configured in this version of Kermit.\n", - tmpbuf - ); - return(success = 0); - } - return(-2); /* None of the above */ - -} /* end of docmd() */ - -#endif /* NOICP */ diff --git a/.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/050_ck_patch.patch/.timestamp b/.pc/050_ck_patch.patch/.timestamp deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/050_ck_patch.patch/ckcmai.c b/.pc/050_ck_patch.patch/ckcmai.c deleted file mode 100644 index 33504dc..0000000 --- a/.pc/050_ck_patch.patch/ckcmai.c +++ /dev/null @@ -1,3592 +0,0 @@ -#define EDITDATE "10 Apr 2004" /* Update these with each edit */ -#define EDITNDATE "20040410" /* Keep them in sync */ -/* Sat Apr 10 12:05:49 2004 */ - -/* - ckcsym.h is used for for defining symbols that normally would be defined - using -D or -d on the cc command line, for use with compilers that don't - support this feature. Must be before any tests for preprocessor symbols. -*/ -#include "ckcsym.h" -/* - Consolidated program version information (for UNIX also see ckuver.h). - See makever() below for how they are used. -*/ -/* #ifdef COMMENT */ /* Uncomment this for test version */ -#ifndef OS2 -#ifndef BETATEST -#define BETATEST -#endif /* BETATEST */ -#endif /* OS2 */ -/* #endif */ /* COMMENT */ - -#ifdef BETATEST -#ifdef OS2 -#ifdef __DATE__ -#define BETADATE -#endif /* __DATE__ */ -#endif /* OS2 */ -#endif /* BETATEST */ - -#ifndef MAC -/* - Note: initialize ck_s_test to "" if this is not a test version. - Use (*ck_s_test != '\0') to decide whether to print test-related messages. -*/ -#ifndef BETATEST -#ifndef OS2 /* UNIX, VMS, etc... (i.e. C-Kermit) */ -char *ck_s_test = ""; /* "Dev","Alpha","Beta","RC", or "" */ -char *ck_s_tver = ""; /* Test version number or "" */ -#else /* OS2 */ -char *ck_s_test = ""; /* (i.e. K95) */ -char *ck_s_tver = ""; -#endif /* OS2 */ -#else -char *ck_s_test = ""; /* Development */ -char *ck_s_tver = ""; -#endif /* BETATEST */ -#else /* MAC */ -char *ck_s_test = "Pre-Alpha"; /* Mac Kermit is always a test... */ -char *ck_s_tver = ""; -#endif /* MAC */ - -#ifdef BETADATE /* Date of this version or edit */ -char *ck_s_date = __DATE__; /* Compilation date */ -#else -char *ck_s_date = EDITDATE; /* See top */ - -#endif /* BETADATE */ -char *buildid = EDITNDATE; /* See top */ - -#ifdef UNIX -static char sccsid[] = "@(#)C-Kermit 8.0.211"; -#endif /* UNIX */ - -char *ck_s_ver = "8.0.211"; /* C-Kermit version string */ -long ck_l_ver = 800211L; /* C-Kermit version number */ - -#ifdef OS2 -char *ck_s_xver = "2.2.0"; /* Product-specific version string */ -long ck_l_xver = 2200L; /* Product-specific version number */ -#else -#ifdef MAC -char *ck_s_xver = "0.995"; /* Product-specific version string */ -long ck_l_xver = 995L; /* Product-specific version number */ -#else -char *ck_s_xver = ""; /* Don't touch these... */ -long ck_l_xver = 0L; /* they are computed at runtime */ -#endif /* MAC */ -#endif /* OS2 */ - -#ifdef OS2 -#ifdef IKSDONLY -#ifdef NT -char *ck_s_name = "IKS-NT"; -#else /* NT */ -char *ck_s_name = "IKS-OS/2"; -#endif /* NT */ -#else /* IKSDONLY */ -char *ck_s_name = "Kermit 95"; /* Program name */ -#endif /* IKSDONLY */ -#else -#ifdef MAC -char *ck_s_name = "Mac Kermit"; -#else -char *ck_s_name = "C-Kermit"; -#endif /* MAC */ -#endif /* OS2 */ - -char *ck_s_who = ""; /* Where customized, "" = not. */ -char *ck_patch = ""; /* Patch info, if any. */ - -#define CKVERLEN 128 -char versiox[CKVERLEN]; /* Version string buffer */ -char *versio = versiox; /* These are filled in at */ -long vernum, xvernum; /* runtime from above. */ - -#define CKCMAI - -#include "ckcasc.h" /* ASCII character symbols */ -#include "ckcdeb.h" /* Debug & other symbols */ - -char * myname = NULL; /* The name I am called by */ -#ifndef OS2 -char * exedir = NULL; /* Directory I was executed from */ -#endif /* OS2 */ -char * myhome = NULL; /* Home directory override */ - -/* C K C M A I -- C-Kermit Main program */ - -/* - Author: Frank da Cruz (fdc@columbia.edu), - Columbia University Academic Information Systems, New York City. - -COPYRIGHT NOTICE: -*/ - -#ifdef OS2 -char *wiksdcpr[] = { -"Windows Internet Kermit Service Daemon (WIKSD):", -"Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New", -"York. All rights reserved.", -" ", -"PERMISSIONS:", -" ", -" The WIKSD software may be obtained directly, in binary form only, from", -" the Kermit Project at Columbia University by any individual for his or", -" her OWN USE, and by any company or other organization for its own", -" INTERNAL DISTRIBUTION and use, including installation on servers that", -" are accessed by customers or clients, WITHOUT EXPLICIT LICENSE. All", -" other forms of redistribution must be licensed from the Kermit Project", -" at Columbia University. These permissions apply only to the nonsecure", -" version of WIKSD.", -" ", -"DISCLAIMER:", -" ", -" THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE", -" TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK AS TO ITS", -" FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE TRUSTEES OF", -" COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK OF ANY KIND, EITHER", -" EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED", -" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.", -" THE TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK SHALL NOT", -" BE LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL,", -" OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OR IN", -" CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS", -" HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. YOU SHALL", -" INDEMNIFY AND HOLD HARMLESS THE TRUSTEES OF COLUMBIA UNIVERSITY IN", -" THE CITY OF NEW YORK, ITS EMPLOYEES AND AGENTS FROM AND AGAINST ANY", -" AND ALL CLAIMS, DEMANDS, LOSS, DAMAGE OR EXPENSE (INCLUDING", -" ATTORNEYS' FEES) ARISING OUT OF YOUR USE OF THIS SOFTWARE.", -" ", -"The above copyright notice, permissions notice, and disclaimer may not be", -"removed, altered, or obscured and shall be included in all copies of the", -"WIKSD software. The Trustees of Columbia University in the City of", -"New York reserve the right to revoke this permission if any of the terms", -"of use set forth above are breached.", -" ", -"For further information, contact the Kermit Project, Columbia University,", -"612 West 115th Street, New York NY 10025-7799, USA; Phone +1 (212) 854 3703,", -"Fax +1 (212) 662 6442, kermit@columbia.edu, http://www.columbia.edu/kermit/", -"" -}; -#endif /* OS2 */ - -char *copyright[] = { - -#ifdef pdp11 -"Copyright (C) 1985, 2004, Trustees of Columbia University, NYC.", -"All rights reserved.", -" ", -#else -#ifdef OS2 -"Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New", -"York. All rights reserved. This software is furnished under license", -"and may not be reproduced without license to do so. This copyright notice", -"must not be removed, altered, or obscured.", -" ", -" THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE", -" TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK AS TO ITS", -" FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE TRUSTEES OF", -" COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK OF ANY KIND, EITHER", -" EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED", -" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.", -" THE TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK SHALL NOT", -" BE LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL,", -" OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OR IN", -" CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS", -" HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. YOU SHALL", -" INDEMNIFY AND HOLD HARMLESS THE TRUSTEES OF COLUMBIA UNIVERSITY IN", -" THE CITY OF NEW YORK, ITS EMPLOYEES AND AGENTS FROM AND AGAINST ANY", -" AND ALL CLAIMS, DEMANDS, LOSS, DAMAGE OR EXPENSE (INCLUDING", -" ATTORNEYS' FEES) ARISING OUT OF YOUR USE OF THIS SOFTWARE.", -" ", -#else -"Copyright (C) 1985, 2004,", -" The Trustees of Columbia University in the City of New York.", -" All rights reserved.", -" ", -"PERMISSIONS:", -" ", -"The C-Kermit software may be obtained directly from the Kermit Project at", -"Columbia University (or from any source explicitly licensed by the Kermit", -"Project or implicitly licensed by Clause (A) below) by any individual for", -"his or her OWN USE, and by any company or other organization for its own", -"INTERNAL DISTRIBUTION and use, including installation on servers that are", -"accessed by customers or clients, WITHOUT EXPLICIT LICENSE.", -" ", -"Conditions for REDISTRIBUTION are as follows:", -" ", -"(A) The C-Kermit software, in source and/or binary form, may be", -" included WITHOUT EXPLICIT LICENSE in distributions of OPERATING", -" SYSTEMS that have OSI (Open Source Initiative, www.opensource.org)", -" approved licenses, even if non-Open-Source applications (but not", -" operating systems) are included in the same distribution. Such", -" distributions include, but are not limited to, CD-ROM, FTP site,", -" Web site, or preinstalled software on a new GENERAL-PURPOSE", -" computer, as long as the primary character of the distribution is", -" an Open Source operating system with accompanying utilities. The", -" C-Kermit source code may not be changed without the consent of the", -" Kermit Project, which will not be unreasonably withheld (this is", -" simply a matter of keeping a consistent and supportable code base).", -" ", -"(B) Inclusion of C-Kermit software in whole or in part, in any form, in", -" or with any product not covered by Clause (A), or its distribution", -" by any commercial enterprise to its actual or potential customers", -" or clients except as in Clause (A), requires a license from the", -" Kermit Project, Columbia University; contact kermit@columbia.edu.", -" ", -"The name of Columbia University may not be used to endorse or promote", -"products derived from or including the C-Kermit software without specific", -"prior written permission.", -" ", -"DISCLAIMER:", -" ", -" THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE", -" TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK AS TO ITS", -" FITNESS FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE TRUSTEES OF", -" COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK OF ANY KIND, EITHER", -" EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED", -" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.", -" THE TRUSTEES OF COLUMBIA UNIVERSITY IN THE CITY OF NEW YORK SHALL NOT", -" BE LIABLE FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL,", -" OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT OF OR", -" IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN IF IT HAS BEEN OR IS", -" HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. YOU SHALL", -" INDEMNIFY AND HOLD HARMLESS THE TRUSTEES OF COLUMBIA UNIVERSITY IN", -" THE CITY OF NEW YORK, ITS EMPLOYEES AND AGENTS FROM AND AGAINST ANY", -" AND ALL CLAIMS, DEMANDS, LOSS, DAMAGE OR EXPENSE (INCLUDING", -" ATTORNEYS' FEES) ARISING OUT OF YOUR USE OF THIS SOFTWARE.", -" ", -"The above copyright notice, permissions notice, and disclaimer may not be", -"removed, altered, or obscured and shall be included in all copies of the", -"C-Kermit software. The Trustees of Columbia University in the City of", -"New York reserve the right to revoke this permission if any of the terms", -"of use set forth above are breached.", -#endif /* OS2 */ -#endif /* pdp11 */ - -#ifdef OS2 -"Portions Copyright (C) 1995, Oy Online Solutions Ltd., Jyvaskyla, Finland.", -#endif /* OS2 */ - -#ifdef CK_AUTHENTICATION -"Portions Copyright (C) 1990, Massachusetts Institute of Technology.", -#ifdef CK_ENCRYPTION -"Portions Copyright (C) 1991, 1993 Regents of the University of California.", -"Portions Copyright (C) 1991, 1992, 1993, 1994, 1995 by AT&T.", -"Portions Copyright (C) 1995, 1997, Eric Young .", -#endif /* CK_ENCRYPTION */ -#ifdef CK_SRP -"Portions Copyright (C) 1997, Stanford University.", -#endif /* CK_SRP */ -#endif /* CK_AUTHENTICATION */ - -#ifndef pdp11 -" ", -"For further information, contact the Kermit Project, Columbia University,", -"612 West 115th Street, New York NY 10025-7799, USA; phone +1 (212) 854 3703,", -"fax +1 (212) 663 8202 or +1 (212) 662 6442, email kermit@columbia.edu,", -"Web http://www.columbia.edu/kermit/ or http://www.kermit-project.org/.", -#endif /* pdp11 */ -""}; - -/* -DOCUMENTATION: - - "Using C-Kermit" by Frank da Cruz and Christine M. Gianone, - Digital Press / Butterworth-Heinemann, Woburn MA, USA. - Second edition (1997), ISBN 1-55558-164-1. - Order from Digital Press: +1 (800) 366-2665 - Or from Columbia University: +1 (212) 854-3703 - -For Kermit 95, also: - - "Kermit 95" by Christine M. Gianone and Frank da Cruz, - Manning Publications, Greenwich CT, USA (1998) - Online. - -ACKNOWLEDGMENTS: - - The Kermit file transfer protocol was developed at the Columbia University - Center for Computing Activities (CUCCA), which was since renamed to Columbia - University Academic Information Systems (AcIS). Kermit is named after - Kermit the Frog, star of the television series THE MUPPET SHOW; the name is - used by permission of Henson Associates, Inc. - - Thanks to at least the following people for their contributions to this - program over the years, and apologies to anyone who was inadvertantly - omitted: - - Chris Adie, Edinburgh U, Scotland (OS/2) - Robert Adsett, University of Waterloo, Canada - Larry Afrin, Clemson U - Russ Allbery, Stanford U - Jeffrey Altman, Columbia University - Greg Andrews, Telebit Corp - Barry Archer, U of Missouri - Robert Andersson, International Systems A/S, Oslo, Norway - Chris Armstrong, Brookhaven National Lab (OS/2) - William Bader, Software Consulting Services, Nazareth, PA - Fuat Baran, Columbia U - Stan Barber, Rice U - Jim Barbour, U of Colorado - Donn Baumgartner, Dell - Nelson Beebe, U of Utah - Gerry Belanger, Cognitronics - Karl Berry, UMB - Mark Berryman, SAIC - Dean W Bettinger, SUNY - Gary Bilkus - Peter Binderup, Denmark - David Bolen, Advanced Networks and Services, Inc. - Marc Boucher, U of Montreal - Charles Brooks, EDN - Bob Brown - Mike Brown, Purdue U - Jack Bryans, California State U at Long Beach - Mark Buda, DEC (VMS) - Fernando Cabral, Padrao iX, Brasilia - Bjorn Carlsson, Stockholm University Computer Centre QZ, Sweden - Bill Catchings, (formerly of) Columbia U - Bob Cattani, Columbia U CS Dept - Davide Cervone, Rochester U - Seth Chaiklin, Denmark - John Chandler, Harvard U / Smithsonian Astronomical Observatory - Bernard Chen, UCLA - Andrew A Chernov, RELCOM Team, Moscow - John L Chmielewski, AT&T, Lisle, IL - Howard Chu, U of Michigan - Bill Coalson, McDonnell Douglas - Bertie Coopersmith, London - Chet Creider, U of Western Ontario - Alan Crosswell, Columbia U - Jeff Damens, (formerly of) Columbia U - Mark Davies, Bath U, UK - Sin-itirou Dezawa, Fujifilm, Japan - Joe R. Doupnik, Utah State U - Frank Dreano, Honeywell - John Dunlap, U of Washington - Alex Dupuy, SMART.COM - David Dyck, John Fluke Mfg Co. - Stefaan A. Eeckels, Eurokom, Luxembourg - Nick Efthymiou - Paul Eggert, Twin Sun, Inc., El Segundo, CA - Bernie Eiben, DEC - Peter Eichhorn, Assyst International - Kristoffer Eriksson, Peridot Konsult AB, Oerebro, Sweden - John R. Evans, IRS, Kansas City - Glenn Everhart, RCA Labs - Charlie Finan, Cray Research - Herm Fischer, Encino, CA (extensive contributions to version 4.0) - Carl Fongheiser, CWRU - Mike Freeman, Bonneville Power Authority - Marcello Frutig, Catholic University, Sao Paulo, Brazil (X.25 support) - Hirofumi Fujii, Japan Nat'l Lab for High Energy Physics, Tokyo (Kanji) - Chuck Fuller, Westinghouse Corporate Computer Services - Andy Fyfe, Caltech - Christine M. Gianone, Columbia U - John Gilmore, UC Berkeley - Madhusudan Giyyarpuram, HP - Rainer Glaschick, Siemens AG, Paderborn - William H. Glass - German Goldszmidt, IBM - Chuck Goodhart, NASA - Alistair Gorman, New Zealand - Richard Gration, ADFA, Australia - Chris Green, Essex U, UK - Alan Grieg, Dundee Tech, Scotland - Yekta Gursel, MIT - Jim Guyton, Rand Corp - Michael Haertel - Bruno Haible - Bob Hain, UMN - Marion Hakanson, ORST - Richard Hamilton - John Hamilston, Iowa State U - Simon Hania, Netherlands - Stan Hanks, Rice U. - Ken Harrenstein, SRI - Eugenia Harris, Data General (AOS/VS) - David Harrison, Kingston Warren Corp - Lucas Hart, Oregon State University - James Harvey, Indiana/Purdue U (VMS) - Rob Healey - Chuck Hedrick, Rutgers U - Ron Heiby, Technical Systems Division, Motorola Computer Group - Steve Hemminger, Tektronix - Christian Hemsing, RWTH Aachen, Germany (OS-9) - Randolph Herber, US DOE, - Andrew Herbert, Monash Univ, Australia - Marcus Herbert, Germany - Mike Hickey, ITI - Dan Hildebrand, QNX Software Systems Inc, Kanata, ON (QNX) - R E Hill - Stephan Hoffman-Emden - Sven Holmstrom, ABB Utilities AB, Sweden - Bill Homer, Cray Research - Ray Hunter, The Wollongong Group - Randy Huntziger, National Library of Medicine - Larry Jacobs, Transarc - Steve Jenkins, Lancaster University, UK - Dave Johnson, Gradient Technologies - Mark B Johnson, Apple Computer - Jyke Jokinen, Tampere University of Technology, Finland (QNX) - Eric F Jones, AT&T - Luke Jones, AT&T - Peter Jones, U of Quebec Montreal - Phil Julian, SAS Institute - Peter Kabal, U of Quebec - Mic Kaczmarczik, U of Texas at Austin - Sergey Kartashoff, Inst. of Precise Mechanics & Computer Equipment, Moscow - Howie Kaye, Columbia U - Rob Kedoin, Linotype Co, Hauppauge, NY (OS/2) - Phil Keegstra - Mark Kennedy, IBM - Terry Kennedy, St Peter's College, Jersey City, NJ (VMS and more) - "Carlo Kid", Technical University of Delft, Netherlands - Tim Kientzle - Paul Kimoto, Cornell U - Douglas Kingston, morgan.com - Lawrence Kirby, Wiltshire, UK - Tom Kloos, Sequent Computer Systems - Jim Knutson, U of Texas at Austin - John T. Kohl (BSDI) - Scott Kramer, SRI International, Menlo Park, CA - John Kraynack, US Postal Service - David Kricker, Encore Computer - Thomas Krueger, UWM - Bo Kullmar, ABC Klubben, Stockholm, and Central Bank of Sweden, Kista - R. Brad Kummer, AT&T Bell Labs, Atlanta, GA - John Kunze, UC Berkeley - David Lane, BSSI / BellSouth (Stratus VOS, X.25) - Bob Larson, USC (OS-9) - Bert Laverman, Groningen U, Netherlands - Steve Layton - David Lawyer, UC Irvine - David LeVine, National Semiconductor Corporation - Daniel S. Lewart, UIUC - S.O. Lidie, Lehigh U - Tor Lillqvist, Helsinki U, Finland - David-Michael Lincke, U of St Gallen, Switzerland - Robert Lipe (for SCO makefile entries & advice) - Dean Long - Mike Long, Analog Devices, Norwood MA - Kevin Lowey, U of Saskatchewan (OS/2) - Andy Lowry, Columbia U - James Lummel, Caprica Telecomputing Resources (QNX) - David MacKenzie, Environmental Defense Fund, U of Maryland - John Mackin, University of Sidney, Australia - Martin Maclaren, Bath U, UK - Chris Maio, Columbia U CS Dept - Montserrat Mane, HP, Grenoble, France - Fulvio Marino, Olivetti, Ivrea, Italy - Arthur Marsh, dircsa.org.au - Peter Mauzey, Lucent Technologies - Tye McQueen, Utah State U - Ted Medin - Hellmuth Michaelis, Hanseatischer Computerservice GmbH, Hamburg, Germany - Leslie Mikesell, American Farm Bureau - Todd Miller, Courtesan Consulting - Martin Minow, DEC (VMS) - Pawan Misra, Bellcore - Ken Mizialko, IBM, Manassas, VA - Wolfgang Moeller, DECUS Germany - Ray Moody, Purdue U - Bruce J Moore, Allen-Bradley Co, Highland Heights, OH (Atari ST) - Steve Morley, Convex - Peter Mossel, Columbia U - Tony Movshon, NYU - Lou Muccioli, Swanson Analysis Systems - Dan Murphy - Neal P. Murphy, Harsof Systems, Wonder Lake IL - Gary Mussar - John Nall, FSU - Jack Nelson, U of Pittsburgh - Jim Noble, Planning Research Corporation (Macintosh) - Ian O'Brien, Bath U, UK - Melissa O'Neill, SFU - John Owens - Thomas Pinkl, Health Business Systems Inc. - Michael Pins, Iowa Computer Aided Engineering Network - Andre' Pirard, University of Liege, Belgium - Paul Placeway, Ohio State U - Piet W. Plomp, ICCE, Groningen University, Netherlands - Ken Poulton, HP Labs - Manfred Prange, Oakland U - Christopher Pratt, APV Baker, UK - Frank Prindle, NADC - Tony Querubin, U of Hawaii - Jean-Pierre Radley - Anton Rang - Scott Ribe - Alan Robiette, Oxford University, UK - Michel Robitaille, U of Montreal (Mac) - Huw Rogers, Schweizerische Kreditanstalt, Zuerich - Nigel Roles, Cambridge, England - Kai Uwe Rommel, Technische Universitaet Muenchen (OS/2) - Larry Rosenman (Amiga) - Jay Rouman, U of Michigan - Jack Rouse, SAS Institute (Data General and/or Apollo) - Stew Rubenstein, Harvard U (VMS) - Gerhard Rueckle, FH Darmstadt, Fb. E/Automatisierungstechnik - John Santos, EG&H - Bill Schilit, Columbia U - Ulli Schlueter, RWTH Aachen, Germany (OS-9, etc) - Michael Schmidt, U of Paderborn, Germany - Eric Schnoebelen, Convex - Benn Schreiber, DEC - Dan Schullman, DEC (modems, DIAL command, etc) - John Schultz, 3M - Steven Schultz, Contel (PDP-11) - APPP Scorer, Leeds Polytechnic, UK - Gordon Scott, Micro Focus, Newbury UK - Gisbert W. Selke, WIdO, Bonn, Germany - David Singer, IBM Almaden Research Labs - David Sizeland, U of London Medical School - Fridrik Skulason, Iceland - Rick Sladkey (Linux) - Dave Slate - Bradley Smith, UCLA - Fred Smith, Merk / Computrition - Richard S Smith, Cal State - Ryan Stanisfer, UNT - Bertil Stenstroem, Stockholm University Computer Centre (QZ), Sweden - James Sturdevant, CAP GEMENI AMERICA, Minneapolis - Peter Svanberg, Royal Techn. HS, Sweden - James R. Swenson, Accu-Weather, Inc. - Ted T'so, MIT (Linux) - Andy Tanenbaum, Vrije U, Amsterdam, Netherlands - Glen Thobe - Markku Toijala, Helsinki U of Technology - Teemu Torma, Helsinki U of Technology - Linus Torvalds, Helsinki - Rick Troxel, NIH - Warren Tucker, Tridom Corp, Mountain Park, GA - Dave Tweten, AMES-NAS - G Uddeborg, Sweden - Walter Underwood, Ford Aerospace - Pieter Van Der Linden, Centre Mondial, Paris - Ge van Geldorp, Netherlands - Fred van Kempen, MINIX User Group, Voorhout, Netherlands - Wayne Van Pelt, GE/CRD - Mark Vasoll, Oklahoma State U (V7 UNIX) - Konstantin Vinogradov, ICSTI, Moscow - Paul Vixie, DEC - Bernie Volz, Process Software - Eduard Vopicka, Prague University of Economics, Czech Republic - Dimitri Vulis, CUNY - Roger Wallace, Raytheon - Stephen Walton, Calif State U, Northridge (Amiga) - Jamie Watson, Adasoft, Switzerland (AIX) - Rick Watson, U of Texas (Macintosh) - Scott Weikart (Association for Progressive Communications) - Robert Weiner, Programming Plus, New York City - Lauren Weinstein, Vortex Technlogy - David Wexelblat, AT&T - Clark Wierda, Illuminati Online - Joachim Wiesel, U of Karlsruhe - Lon Willett, U of Utah - Michael Williams, UCLA - Nate Williams, U of Montana - David Wilson - Joellen Windsor, U of Arizona - Patrick Wolfe, Kuck & Associates, Inc. - Gregg Wonderly, Oklahoma State U (V7 UNIX) - Farrell Woods, Concurrent (formerly Masscomp) - Dave Woolley, CAP Communication Systems, London - Jack Woolley, SCT Corp - Frank Wortner - Ken Yap, formerly of U of Rochester - John Zeeff, Ann Arbor, MI -*/ - -#include "ckcker.h" /* Kermit symbols */ -#include "ckcnet.h" /* Network symbols */ - -#ifdef CK_SSL -#include "ck_ssl.h" -#endif /* CK_SSL */ - -#ifndef NOSPL -#include "ckuusr.h" -#endif /* NOSPL */ - -#ifdef OS2ONLY -#define INCL_VIO /* Needed for ckocon.h */ -#include -#undef COMMENT -#endif /* OS2ONLY */ - -#ifdef NT -#include -#include -#include "ckntap.h" -#endif /* NT */ - -#ifndef NOSERVER -/* Text message definitions.. each should be 256 chars long, or less. */ -#ifdef MINIX -char *srvtxt = "\r\n\ -Entering server mode.\r\n\0"; -#else -#ifdef OLDMSG -/* - It seems there was a large installation that was using C-Kermit 5A(165) - or thereabouts, which had deployed thousands of MS-DOS Kermit scripts in - scattered locations that looked for strings in the old server message, - which changed in 5A(183), August 1992. -*/ -char *srvtxt = "\r\n\ -C-Kermit server starting. Return to your local machine by typing\r\n\ -its escape sequence for closing the connection, and issue further\r\n\ -commands from there. To shut down the C-Kermit server, issue the\r\n\ -FINISH or BYE command and then reconnect.\n\ -\r\n\0"; -#else -#ifdef OSK -char *srvtxt = "\r\012\ -Entering server mode. If your local Kermit software is menu driven, use\r\012\ -the menus to send commands to the server. Otherwise, enter the escape\r\012\ -sequence to return to your local Kermit prompt and issue commands from\r\012\ -there. Use SEND and GET for file transfer. Use REMOTE HELP for a list of\r\012\ -other available services. Use BYE or FINISH to end server mode.\r\012\0"; -#else /* UNIX, VMS, AOS/VS, and all others */ -char *srvtxt = "\r\n\ -Entering server mode. If your local Kermit software is menu driven, use\r\n\ -the menus to send commands to the server. Otherwise, enter the escape\r\n\ -sequence to return to your local Kermit prompt and issue commands from\r\n\ -there. Use SEND and GET for file transfer. Use REMOTE HELP for a list of\r\n\ -other available services. Use BYE or FINISH to end server mode.\r\n\0"; -#endif /* OSK */ -#endif /* OLDMSG */ -#endif /* MINIX */ -#else /* server mode disabled */ -char *srvtxt = ""; -#endif /* NOSERVER */ - -int initflg = 0; /* sysinit() has executed... */ -int howcalled = I_AM_KERMIT; /* How I was called */ -int hmtopline = 0; -int quitting = 0; /* I'm in the act of quitting */ - -#ifdef IKSDCONF -char * iksdconf = IKSDCONF; /* IKSD configuration file */ -int iksdcf = 0; /* Has IKSD c.f. been processed? */ -#endif /* IKSDCONF */ - -int srvcdmsg = 0; /* [Server] CD message */ -char * cdmsgfile[8] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; -char * cdmsgstr = NULL; -char * ckcdpath = NULL; - -#ifdef NLCHAR /* Text-file line terminator */ -CHAR feol = NLCHAR; -#else -CHAR feol = 0; -#endif /* NLCHAR */ - -int fblksiz = DBLKSIZ; /* File blocksize */ -int frecl = DLRECL; /* File record length */ -int frecfm = XYFF_S; /* File record format (default = stream) */ -int forg = XYFO_S; /* File organization (sequential) */ -int fcctrl = XYFP_N; /* File carriage control (ctrl chars) */ -int filecase = FILECASE; /* Case matters in filenames */ -int stathack = 1; /* Fast directory lookups by default */ - -char uidbuf[UIDBUFLEN] = { NUL, NUL }; /* User ID buffer */ -int cfilef = 0; /* Application ("kerbang") file flag */ -char cmdfil[CKMAXPATH + 1] = { NUL, NUL }; /* Application file name */ -int haveurl = 0; /* URL given on command line */ - -#ifndef NOXFER -/* Multi-protocol support */ - -struct ck_p ptab[NPROTOS] = { /* Initialize the Kermit part ... */ - { "Kermit", - DRPSIZ, /* Receive packet size */ - DSPSIZ, /* Send packet size */ - 0, /* Send-packet-size-set flag */ - DFWSIZ, /* Window size */ - -#ifdef NEWDEFAULTS - PX_CAU, /* Control char unprefixing... */ -#else - PX_ALL, -#endif /* NEWDEFAULTS */ - -#ifdef VMS /* Default filename collision action */ - XYFX_X, /* REPLACE for VAX/VMS */ -#else - XYFX_B, /* BACKUP for everybody else */ -#endif /* VMS */ - -#ifdef OS2 /* Flag for file name conversion */ - XYFN_L, /* Literal for OS2 */ -#else - XYFN_C, /* Converted for others */ -#endif /* OS2 */ - - PATH_OFF, /* Send pathnames OFF */ - PATH_AUTO, /* Receive pathnames AUTO */ - NULL, /* Host receive initiation string (binary) */ - NULL, /* Host receive initiation string (text) */ - NULL, /* Host server string */ - NULL, /* External protocol send command (binary) */ - NULL, /* External protocol send command (text) */ - NULL, /* External protocol receive command (bin) */ - NULL } /* External protocol receive command (txt) */ -#ifdef CK_XYZ -, -{"XMODEM", 128,128,-1,-1, 1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, -{"XMODEM-CRC",128,128,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, -{"YMODEM", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, -{"YMODEM-g", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, -{"ZMODEM", -1, -1,-1,-1,PX_WIL,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL}, -{"Other", -1, -1,-1,-1, -1,-1,-1,0,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL} -#endif /* CK_XYZ */ -}; - -/* Declarations for Send-Init Parameters */ - -int spsiz = DSPSIZ, /* Current packet size to send */ - spmax = DSPSIZ, /* Biggest packet size we can send */ - lastspmax = DSPSIZ, /* Send-packet size last used */ - spsizr = DSPSIZ, /* Send-packet size requested */ - spsizf = 0, /* Flag to override size negotiation */ - rpsiz = DRPSIZ, /* Biggest we want to receive */ - urpsiz = DRPSIZ, /* User-requested receive pkt size */ - maxrps = MAXRP, /* Maximum incoming long packet size */ - maxsps = MAXSP, /* Maximum outbound l.p. size */ - maxtry = MAXTRY, /* Maximum retries per packet */ - wslots = 1, /* Window size currently in use */ - wslotr = DFWSIZ, /* Window size from SET WINDOW */ - wslotn = 1, /* Window size negotiated in S-pkt */ - timeouts = 0, /* For statistics reporting */ - spackets = 0, /* ... */ - rpackets = 0, /* ... */ - retrans = 0, /* ... */ - crunched = 0, /* ... */ - wmax = 0, /* ... */ - wcur = 0, /* ... */ - srvidl = 0, /* Server idle timeout */ - srvdis = 1, /* Server file xfer display */ - srvtim = DSRVTIM, /* Server command wait timeout */ - srvping = 1, /* Server keepalive */ -/* - timint is the timeout interval I use when waiting for a packet. - pkttim is the SET RECEIVE TIMEOUT value, sent to the other Kermit. - rtimo is the SET SEND TIMEOUT value. rtimo is the initial value of - timint. timint is changed by the value in the incoming negotiation - packet unless a SET SEND TIMEOUT command was given. -*/ - timint = DMYTIM, /* Timeout interval I use */ - pkttim = URTIME, /* Timeout I want you to use */ - rtimo = DMYTIM, /* Normal packet wait timeout */ - timef = 0, /* Flag to override what you ask */ -#ifdef CK_TIMERS - rttflg = 1, /* Use dynamic round-trip timers */ -#else - rttflg = 0, /* Use fixed timer */ -#endif /* CK_TIMERS */ - mintime = 1, /* Minimum timeout */ - maxtime = 0, /* Maximum timeout */ - - npad = MYPADN, /* How much padding to send */ - mypadn = MYPADN, /* How much padding to ask for */ - bctr = DFBCT, /* Block check type requested */ - bctu = 1, /* Block check type used */ - bctl = 1, /* Block check length */ - c_save = -1, /* Block check saving and restoring */ - ss_save = -1, /* Slow-start saving and restoring */ - ebq = MYEBQ, /* 8th bit prefix */ - ebqflg = 0, /* 8th-bit quoting flag */ - rqf = -1, /* Flag used in 8bq negotiation */ - rq = 0, /* Received 8bq bid */ - sq = 'Y', /* Sent 8bq bid */ - rpt = 0, /* Repeat count */ - rptq = MYRPTQ, /* Repeat prefix */ - rptflg = 0, /* Repeat processing flag */ - rptena = 1, /* Repeat processing enabled */ - xfrcan = 1, /* Transfer cancellation enabled */ - xfrint = 1, /* Transfer interruption enabled */ - xfrchr = 3, /* Transfer cancel char = Ctrl-C */ - xfrnum = 3, /* Need three of them by default */ - g_xfrxla = -1; - char * xfrmsg = NULL; /* Message for f.t. display screen */ -#endif /* NOXFER */ - -#ifdef NOCSETS -int xfrxla = 0; /* Character-set translation */ -#else -int xfrxla = 1; /* enabled or disabled */ -#endif /* NOCSETS */ - -#ifndef NOXFER -int epktflg = 0; /* E-PACKET command active */ - -int capas = 9, /* Position of Capabilities */ - lpcapb = 2, /* Long Packet capability */ - lpcapr = 1, /* requested */ - lpcapu = 0, /* used */ - swcapb = 4, /* Sliding Window capability */ - swcapr = 1, /* requested (allowed) */ - swcapu = 0, /* used */ - atcapb = 8, /* Attribute capability */ - atcapr = 1, /* requested */ - atcapu = 0, /* used */ - rscapb = 16, /* RESEND capability */ - rscapr = 1, /* requested by default */ - rscapu = 0, /* used */ - lscapb = 32, /* Locking Shift capability */ - lscapr = 1, /* requested by default */ - lscapu = 0; /* used */ - -/* Flags for whether to use particular attributes */ - -int atenci = 1, /* Encoding in */ - atenco = 1, /* Encoding out */ - atdati = 1, /* Date in */ - atdato = 1, /* Date out */ - atdisi = 1, /* Disposition in/out */ - atdiso = 1, - atleni = 1, /* Length in/out (both kinds) */ - atleno = 1, - atblki = 1, /* Blocksize in/out */ - atblko = 1, - attypi = 1, /* File type in/out */ - attypo = 1, - atsidi = 1, /* System ID in/out */ - atsido = 1, - atsysi = 1, /* System-dependent parameters in/out */ - atsyso = 1; - -int dispos = 0; /* Disposition */ - -#ifdef CK_PERMS -int atlpri = 1, - atlpro = 1, - atgpri = 1, - atgpro = 1; -#endif /* CK_PERMS */ - -int atfrmi = 1, /* Record Format in/out */ - atfrmo = 1; - -#ifdef STRATUS -int atcrei = 1, /* Creator ID in/out */ - atcreo = 1, - atacti = 1, /* Account in/out */ - atacto = 1; -#endif /* STRATUS */ - -int sprmlen = -1; /* Send/Receive protocol parameter */ -int rprmlen = -1; /* string length limits */ -int sendipkts = 1; /* Send I packets */ - -CHAR padch = MYPADC, /* Padding character to send */ - mypadc = MYPADC, /* Padding character to ask for */ - seol = MYEOL, /* End-Of-Line character to send */ - eol = MYEOL, /* End-Of-Line character to look for */ - ctlq = CTLQ, /* Control prefix in incoming data */ - myctlq = CTLQ, /* Outbound control character prefix */ - myrptq = MYRPTQ; /* Repeat prefix I want to use */ - -int rptmin = 3; /* Repeat-count minimum */ - -int usepipes = 0, /* Used for xfer to/from pipes */ - g_usepipes = -1; - -char * filefile = NULL; /* File containing list of filenames */ -/* CD message filename list */ - -char whoareu[16] = { NUL, NUL }; /* System ID of other Kermit */ -int sysindex = -1; /* and index to its system ID struct */ -int myindex = -1; -int wearealike = 0; /* 2 Kermits have compatible sysids */ -char * cksysid = /* My system ID */ -#ifdef UNIX - "U1" -#else -#ifdef VMS - "D7" -#else -#ifdef OSK - "UD" -#else -#ifdef AMIGA - "L3" -#else -#ifdef MAC - "A3" -#else -#ifdef OS2 -#ifdef NT - "UN" -#else /* NT */ - "UO" -#endif /* NT */ -#else /* OS2 */ -#ifdef datageneral - "F3" -#else -#ifdef GEMDOS - "K2" -#else -#ifdef STRATUS - "MV" -#else - "" -#endif /* STRATUS */ -#endif /* GEMDOS */ -#endif /* datageneral */ -#endif /* OS2 */ -#endif /* MAC */ -#endif /* AMIGA */ -#endif /* OSK */ -#endif /* VMS */ -#endif /* UNIX */ - ; - -int oopts = -1; /* O-Packet Options */ -int omode = -1; /* O-Packet Transfer Mode */ -int oname = -1; /* O-Packet Filename Options */ -int opath = -1; /* O-Packet Pathname Options */ - -struct zattr iattr; /* Incoming file attributes */ - -#ifdef VMS -/* VMS labeled file default options - name only. */ -int lf_opts = LBL_NAM; -#else -#ifdef OS2 -/* OS/2 labeled file default options, all attributes but archived. */ -unsigned long int lf_opts = LBL_EXT|LBL_HID|LBL_RO|LBL_SYS; -#else -int lf_opts = 0; -#endif /* OS2 */ -#endif /* VMS */ - -/* Packet-related variables */ - -int pktnum = 0, /* Current packet number */ - sndtyp = 0, /* Type of packet just sent */ - rcvtyp = 0, /* Type of packet just received */ - rsn, /* Received packet sequence number */ - rln, /* Received packet length */ - size, /* Current size of output pkt data */ - osize, /* Previous output packet data size */ - maxsize, /* Max size for building data field */ - spktl = 0, /* Length packet being sent */ - rpktl = 0, /* Length of packet just received */ - pktpaus = 0, /* Interpacket pause interval, msec */ - rprintf, /* REMOTE PRINT flag */ - rmailf, /* MAIL flag */ - xferstat = -1, /* Status of last transaction */ - filestatus = 0; /* Status of last file transfer */ - -CHAR pktmsgbuf[PKTMSGLEN+1]; -CHAR *epktmsg = pktmsgbuf; - -#ifdef pdp11 -int srvcmdlen = MAXRP; /* srvcmd buffer length */ -#else -#ifdef DYNAMIC -int srvcmdlen = MAXRP; -#else -int srvcmdlen = 0; -#endif /* DYNAMIC */ -#endif /* pdp11 */ - -CHAR -#ifdef pdp11 - srvcmdbuf[MAXRP+4], - *srvcmd = srvcmdbuf, -#else -#ifdef DYNAMIC - *srvcmd = (CHAR *)0, /* Where to decode server command */ -#else - srvcmdbuf[MAXRP+4], - *srvcmd = srvcmdbuf, -#endif /* DYNAMIC */ -#endif /* pdp11 */ - padbuf[96], /* Buffer for send-padding */ - *recpkt, - *rdatap, /* Pointer to received packet data */ - *data = (CHAR *)0, /* Pointer to send-packet data */ - *srvptr, /* Pointer to srvcmd */ - mystch = SOH, /* Outbound packet-start character */ - stchr = SOH; /* Incoming packet-start character */ - -/* File-related variables */ - -#ifndef NOMSEND /* Multiple SEND */ -struct filelist * filehead = NULL; /* SEND list */ -struct filelist * filetail = NULL; -struct filelist * filenext = NULL; -int addlist = 0; -#endif /* NOMSEND */ - -char filnam[CKMAXPATH + 1]; /* Name of current file. */ -char ofilnam[CKMAXPATH + 1]; /* Original name. */ - -int pipesend = 0; /* Nonzero if sending from pipe */ -#ifdef PIPESEND -char * sndfilter = NULL; /* Send and receive filters */ -char * rcvfilter = NULL; -#endif /* PIPESEND */ - -char ** sndarray = NULL; /* SEND /ARRAY pointer and range */ -#ifndef NOSPL -int sndxlo = -1, sndxhi = -1, sndxin = -1; -#endif /* NOSPL */ -#endif /* NOXFER */ - -#ifndef NOSERVER -int ngetpath = 0; /* GET search path */ -int fromgetpath = 0; -char * getpath[MAXGETPATH]; -char * x_user = NULL; /* Server login information */ -char * x_passwd = NULL; -char * x_acct = NULL; -#endif /* NOSERVER */ - -int x_login = 0; /* Login required */ -int x_logged = 0; /* User is logged in */ - -extern int timelimit; - -#ifdef CK_LOGIN -int logintimo = 300; /* Login timeout */ -char * userfile = NULL; /* Forbidden user file */ -#endif /* CK_LOGIN */ -#ifdef IKSD -char * anonfile = NULL; /* Anonymous login init file */ -char * anonroot = NULL; /* Anonymous file-system root */ -int iks_timo = 300; /* 5 minutes idle timo */ -int iks_retry = 3; /* 3 attempts at login */ -#endif /* IKSD */ - -#ifdef CKSYSLOG -extern VOID zsyslog(); -extern int ckxlogging, ckxsyslog; -#endif /* CKSYSLOG */ - -int nzxopts = 0; /* Options for nzxpand() */ -int nfils = 0; /* Number of files in file group */ -long fsize = 0L; /* Size of current file */ -#ifdef UNIX -int wildxpand = 0; /* Who expands wildcards */ -#else /* UNIX */ -#ifdef STRATUS -int wildxpand = 1; -#endif /* STRATUS */ -#endif /* UNIX */ -#ifdef UNIXOROSK -int matchdot = 0; /* Whether to match dot files */ -#else -int matchdot = 1; -#endif /* UNIXOROSK */ -int matchfifo = 0; /* Whether to match FIFO "files" */ -int clfils = 0; /* Flag for command-line files */ -int stayflg = 0; /* Flag for "stay", i.e. "-S" */ -int xfinish = 0; /* Flag for FINISH = EXIT */ -long ztusec = -1L; /* Used with ztime() */ -long ztmsec = -1L; /* Ditto */ - -/* Communication device / connection variables */ - -char ttname[TTNAMLEN+1]; /* Name of communication device */ - -#ifdef MAC -int connected = 0; /* True if connected */ -int startconnected; /* initial state of connected */ -#endif /* MAC */ - -long speed = -1L; /* Communication device speed */ -int wasclosed = 0; /* Connection was just closed */ -int whyclosed = WC_REMO; /* why it was closed */ -int qnxportlock = 0; /* QNX port locking on/off */ - -#ifndef CLSONDISC -#define CLSONDISC 0 -#endif /* CLSONDISC */ - -int cxflow[CXT_MAX+1]; /* See initflow() */ - -#ifndef NOSHOW -char * floname[] = { /* Flow control names */ - "none", "xon/xoff", "rts/cts", "dtr/cd", "etx/ack", "string", - "xxx1", "xxx2", "dtr/cts", "keep", "auto" -}; -int nfloname = (sizeof(floname) / sizeof(char *)); - -char * cxname[] = { /* Connection type names */ - "remote", "direct-serial", "modem", "tcp/ip", "x.25", "decnet", - "lat", "netbios", "named-pipe", "ssh", "pipe" -}; -int ncxname = (sizeof(cxname) / sizeof(char *)); -#endif /* NOSHOW */ - -int parity = DEFPAR, /* Parity specified, 0,'e','o',etc */ - hwparity = 0, /* Hardware parity for serial port */ - stopbits = -1, /* Stop bits for serial port */ - clsondisc = CLSONDISC, /* Serial port close on disconnect */ - autopar = 0, /* Automatic parity change flag */ - sosi = 0, /* Shift-In/Out flag */ - flow = 0, /* Flow control (see initflow()) */ - autoflow = 1, /* Automatic flow control */ - turn = 0, /* Line turnaround handshake flag */ - turnch = XON, /* Line turnaround character */ - duplex = 0, /* Duplex, full by default */ - escape = DFESC, /* Escape character for connect */ - ckdelay = DDELAY, /* Initial delay before sending */ - tnlm = 0; /* Terminal newline mode */ - -/* Networks for SET HOST */ - -#ifdef BIGBUFOK -#define MYHOSTL 1024 -#else -#define MYHOSTL 100 -#endif /* BIGBUFOK */ - -char myhost[MYHOSTL]; /* Local host name */ -int network = 0; /* Network vs serial connection */ -int inserver = 0; /* Running as an Internet server */ -int isguest = 0; /* User is anonymous */ -char * clienthost = NULL; /* Peer host name or address */ -int tcp_incoming = 0; /* Incoming TCP connection? */ - -#ifdef NETCONN -#ifdef TCPSOCKET -int nettype = NET_TCPB; /* Default network type */ -#else -#ifdef SUNX25 -int nettype = NET_SX25; -#else -#ifdef IBMX25 -int nettype = NET_IX25; -#else -#ifdef HPX25 -int nettype = NET_HX25; -#else -#ifdef STRATUSX25 -int nettype = NET_VX25; -#else -#ifdef DECNET -int nettype = NET_DEC; -#else -#ifdef SUPERLAT -int nettype = NET_SLAT; -#else -int nettype = NET_NONE; -#endif /* SUPERLAT */ -#endif /* DECNET */ -#endif /* STRATUSX25 */ -#endif /* HPX25 */ -#endif /* IBMX25 */ -#endif /* SUNX25 */ -#endif /* TCPSOCKET */ -#else /* NETCONN */ -int nettype = NET_NONE; -#endif /* NETCONN */ - -#ifdef ANYX25 -int revcall = 0; /* X.25 reverse call not selected */ -int closgr = -1; /* X.25 closed user group */ -int cudata = 0; /* X.25 call user data not specified */ -char udata[MAXCUDATA]; /* X.25 call user data */ - -#ifdef IBMX25 -/* - I was unable to find any pre-defined MAX values for x25 addresses - the - addresses that I've seen have been around 10-12 characters 32 is probably - enough, 64 is hopefully safe for everyone. -*/ - x25addr_t local_nua = {'\0'}; /* local x.25 address */ - x25addr_t remote_nua = {'\0'}; /* remote x.25 address */ - char x25name[32] = {'\0'}; /* x25 device name, sx25a0 or sx25a1 */ - char x25dev[64] = "/dev/x25pkt"; /* x25 device in /dev */ - int x25port = 0; /* port used for X.25 - AIX only */ -#endif /* IBMX25 */ - -#ifndef IBMX25 -/* - This condition is unrelated to the above IBMX25 condition. - IBM X.25 doesn't have PAD support. -*/ - CHAR padparms[MAXPADPARMS+1]; /* X.3 parameters */ -#endif /* IBMX25 */ -#endif /* ANYX25 */ - -/* Other items */ - -int isinterrupted = 0; /* Used in exception handling */ -int what = W_INIT; /* What I am doing */ -int lastxfer = 0; /* Last transfer (send or receive) */ - -extern int mdmtyp; /* Modem (/network) type */ - -#ifdef NT -extern int StartedFromDialer; -#ifdef NTSIG -extern int TlsIndex; -#endif /* NTSIG */ -#ifdef NTASM -unsigned long ESPToRestore; /* Ditto */ -#endif /* NTASM */ -#endif /* NT */ - -#ifdef OS2PM -int os2pm = 0; /* OS/2 Presentation Manager flag */ -#endif /* OS2PM */ - -/* Terminal screen size, if known, -1 means unknown. */ - -#ifdef OS2 -#include "ckocon.h" -#ifdef KUI -int tt_rows[VNUM] = {24,24,25,1}; /* Rows (height) */ -int tt_cols[VNUM] = {80,80,80,80}; /* Columns (width) */ -int cmd_rows = 24, cmd_cols = 80; /* Command/console screen dimensions */ -#else /* KUI */ -int tt_rows[VNUM] = {-1,24,25,1}; /* Rows (height) */ -int tt_cols[VNUM] = {-1,80,80,80}; /* Columns (width) */ -int cmd_rows = -1, cmd_cols = -1; /* Command/console screen dimensions */ -#endif /* KUI */ -int k95stdio = 0; /* Stdio threads */ -int tt_bell = XYB_AUD | XYB_SYS; /* BELL AUDIBLE (system sounds) */ -#else /* OS2 */ -int tt_rows = -1; /* Rows (height) */ -int tt_cols = -1; /* Columns (width) */ -int cmd_rows = 24, cmd_cols = 80; /* Command/console screen dimensions */ -int tt_bell = XYB_AUD; /* BELL ON */ -#endif /* OS2 */ - -int tt_print = 0; /* Transparent print disabled */ -int tt_escape = 1; /* Escaping back is enabled */ -int tt_scroll = 1; /* Scrolling operations are enabled */ - -int tn_exit = 0; /* Exit on disconnect */ - -int exitonclose = 0; /* Exit on close */ -int exithangup = 1; /* Hangup on exit */ -int haveline = 0; /* SET LINE or SET HOST in effect */ -int tlevel = -1; /* Take-file command level */ -int hints = 1; /* Whether to give hints */ - -#ifdef NOLOCAL -int remonly = 1; /* Remote-mode-only advisory (-R) */ -int nolocal = 1; /* Remote-only strictly enforced */ -#else -int remonly = 0; -int nolocal = 0; -int cx_status = 0; /* CONNECT return status */ -#endif /* NOLOCAL */ - -#ifndef NOSPL -extern int cmdlvl; /* Command level */ -extern int maclvl; /* Macro invocation level */ -#endif /* NOSPL */ - -int protocol = PROTO_K; /* File transfer protocol = Kermit */ - -#ifdef NEWDEFAULTS -int prefixing = PX_CAU; -#else -int prefixing = PX_ALL; -#endif /* NEWDEFAULTS */ - -extern short ctlp[]; /* Control-prefix table */ - -int carrier = CAR_AUT; /* Pay attention to carrier signal */ -int cdtimo = 0; /* Carrier wait timeout */ -int xitsta = GOOD_EXIT; /* Program exit status */ - -#ifdef VMS /* Default filename collision action */ -int fncact = XYFX_X; /* REPLACE for VMS */ -#else -int fncact = XYFX_B; /* BACKUP for everybody else */ -#endif /* VMS */ - -int fncsav = -1; /* For saving & restoring the above */ -int bgset = -1; /* BACKGROUND mode set explicitly */ - -int cmdint = 1; /* Interrupts are allowed */ -#ifdef UNIX -int xsuspend = DFSUSP; /* Whether SUSPEND command, etc, */ -#else /* is to be allowed. */ -int xsuspend = 0; -#endif /* UNIX */ - -/* Statistics variables */ - -long filcnt, /* Number of files in transaction */ - filrej, /* Number of files rejected in transaction */ - flci, /* Characters from line, current file */ - flco, /* Chars to line, current file */ - tlci, /* Chars from line in transaction */ - tlco, /* Chars to line in transaction */ - ffc, /* Chars to/from current file */ - tfc, /* Chars to/from files in transaction */ - cps = 0L, /* Chars/sec last transfer */ - peakcps = 0L, /* Peak chars/sec last transfer */ - ccu, /* Control chars unprefixed in transaction */ - ccp, /* Control chars prefixed in transaction */ - rptn; /* Repeated characters compressed */ - -int tsecs = 0; /* Seconds for transaction */ -int fsecs = 0; /* Per-file timer */ - -#ifdef GFTIMER -CKFLOAT - fpfsecs = 0.0, /* Floating point per-file timer */ - fptsecs = 0.0; /* and per-transaction timer */ -#endif /* GFTIMER */ - -/* Flags */ - -int deblog = 0, /* Debug log is open */ - debok = 1, /* Debug log is not disabled */ - debxlen = 54, /* Default length for debug strings */ - debses = 0, /* Flag for DEBUG SESSION */ - debtim = 0, /* Include timestamp in debug log */ - pktlog = 0, /* Flag for packet logging */ - seslog = 0, /* Session logging */ - dialog = 0, /* DIAL logging */ - tralog = 0, /* Transaction logging */ - tlogfmt = 1, /* Transaction log format (verbose) */ - tlogsep = (int)',', /* Transaction log field separator */ - displa = 0, /* File transfer display on/off */ - stdouf = 0, /* Flag for output to stdout */ - stdinf = 0, /* Flag for input from stdin */ - xflg = 0, /* Flag for X instead of F packet */ - hcflg = 0, /* Doing Host command */ - dest = DEST_D, /* Destination for packet data */ - zchkod = 0, /* zchko() should work for dirs too? */ - zchkid = 0, /* zchki() should work for dirs too? */ - -/* If you change this, also see struct ptab above... */ - -#ifdef OS2 /* Flag for file name conversion */ - fncnv = XYFN_L, /* Default is Literal in OS/2, */ - f_save = XYFN_L, /* (saved copy of same) */ -#else - fncnv = XYFN_C, /* elsewhere Convert them */ - f_save = XYFN_C, /* (ditto) */ -#endif /* OS2 */ - - fnspath = PATH_OFF, /* Send file path */ - fnrpath = PATH_AUTO, /* Receive file path */ - fackpath = 1, /* Send back path in ACK to F */ - binary = XYFT_B, /* Default file transfer mode */ - b_save = XYFT_B, /* Saved file mode */ - eofmethod = 0, /* EOF detection method (length) */ - -#ifdef OS2 - cursor_save = -1, /* Cursor state */ -#endif /* OS2 */ - - xfermode = XMODE_A, /* Transfer mode, manual or auto */ - xfiletype = -1, /* Transfer only text (or binary) */ - recursive = 0, /* Recursive directory traversal */ - nolinks = 2, /* Don't follow symbolic links */ - skipbup = 0, /* Skip backup files when sending */ - sendmode = SM_SEND, /* Which type of SEND operation */ - slostart = 1, /* Slow start (grow packet lengths) */ - cmask = 0377, /* CONNECT (terminal) byte mask */ - fmask = 0377, /* File byte mask */ - ckwarn = 0, /* Flag for file warning */ - quiet = 0, /* Be quiet during file transfer */ - local = 0, /* 1 = local mode, 0 = remote mode */ - cxtype = CXT_REMOTE, /* Connection type */ - server = 0, /* Flag for I Am Server */ - query = 0, /* Flag for Query active */ - justone = 0, /* Server should do Just One command */ - urserver = 0, /* Flag for You Are Server */ - bye_active = 0, /* Flag for BYE command active */ - diractive = 0, /* Flag for DIRECTORY command active */ - cdactive = 0, /* Flag for CD command active */ - cflg = 0, /* Connect before transaction */ - cnflg = 0, /* Connect after transaction */ - cxseen = 0, /* Flag for cancelling a file */ - czseen = 0, /* Flag for cancelling file group */ - fatalio = 0, /* Flag for fatal i/o error */ - discard = 0, /* Flag for file to be discarded */ - keep = SET_AUTO, /* Keep incomplete files = AUTO */ - unkcs = 1, /* Keep file w/unknown character set */ -#ifdef VMS - filepeek = 0, /* Inspection of files */ -#else -#ifdef datgeneral - filepeek = 0, -#else - filepeek = 1, -#endif /* datageneral */ -#endif /* VMS */ - nakstate = 0, /* In a state where we can send NAKs */ - dblchar = -1, /* Character to double when sending */ - moving = 0, /* MOVE = send, then delete */ - reliable = SET_AUTO, /* Nonzero if transport is reliable */ - xreliable = -1, - setreliable = 0, - urclear = 0, /* Nonzero for clear channel to you */ - clearrq = SET_AUTO, /* SET CLEARCHANEL value */ - cleared = 0, - streaming = 0, /* Nonzero if streaming is active */ - streamok = 0, /* Nonzero if streaming negotiated */ - streamrq = SET_AUTO, /* SET STREAMING value */ - streamed = -1; /* Whether we streamed last time */ - -char * snd_move = NULL; /* Move file after sending it */ -char * snd_rename = NULL; /* Rename file after sending it */ -char * rcv_move = NULL; /* Move file after receiving it */ -char * rcv_rename = NULL; /* Rename file after receiving it */ - -char * g_snd_move = NULL; -char * g_snd_rename = NULL; -char * g_rcv_move = NULL; -char * g_rcv_rename = NULL; - -long sendstart = 0L; /* SEND start position */ -long calibrate = 0L; /* Nonzero if calibration run */ - -#ifdef CK_TRIGGER -char *tt_trigger[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; -CHAR *tt_trmatch[TRIGGERS] = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; -char *triggerval = NULL; -#endif /* CK_TRIGGER */ - -int ckxlogging = 0; /* Flag for syslogging active */ -int ikdbopen = 0; /* Flag for IKSD database active */ -int dbinited = 0; /* Flag for IKSDB record init'd */ -#ifndef CKSYSLOG -int ckxsyslog = 0; /* Logging level 0 */ -#else -#ifdef SYSLOGLEVEL -int ckxsyslog = SYSLOGLEVEL; /* Logging level specified */ -#else -int ckxsyslog = SYSLG_DF; /* Default logging level */ -#endif /* SYSLOGLEVEL */ -#endif /* CKSYSLOG */ - -#ifndef NOHELP -#ifndef NOCMDL -_PROTOTYP( VOID iniopthlp, (void) ); /* Command-line help initializer */ -#endif /* NOCMDL */ -#endif /* NOHELP */ - -_PROTOTYP( VOID getexedir, (void) ); -_PROTOTYP( int putnothing, (char) ); - -#ifdef IKSD -_PROTOTYP( VOID doiksdinit, (void) ); -_PROTOTYP( VOID iksdinit, (void) ); -_PROTOTYP( VOID doiklog, (void) ); -_PROTOTYP( int dbinit, (void) ); -#endif /* IKSD */ - -/* Variables passed from command parser to protocol module */ - -#ifndef NOSPL -#ifndef NOICP -#ifdef CK_APC -_PROTOTYP( VOID apconect, (void) ); -#endif /* CK_APC */ -#ifdef OS2 -extern int initvik; -#endif /* OS2 */ -#endif /* NOICP */ -#endif /* NOSPL */ -char *clcmds = NULL; /* Pointer to command-line commands */ - -#ifndef NOSETKEY -extern KEY *keymap; -extern MACRO *macrotab; -#endif /* NOSETKEY */ - -#ifndef NOPUSH -int nopush = 0; /* PUSH enabled */ -#else -int nopush = 1; /* PUSH disabled */ -#endif /* NOPUSH */ - -CHAR sstate = (CHAR) 0; /* Starting state for automaton */ -CHAR zstate = (CHAR) 0; /* For remembering sstate */ -char * printername = NULL; /* NULL if printer not redirected */ -int printpipe = 0; /* For SET PRINTER */ -int noprinter = 0; - -#ifndef NOXFER -char *cmarg = ""; /* Pointer to command data */ -char *cmarg2 = ""; /* Pointer to 2nd command data */ -char **cmlist; /* Pointer to file list in argv */ - -#ifdef CK_AUTODL /* Autodownload */ -int autodl = 1; /* Enabled by default */ -#else -int autodl = 0; /* (or if not implemented). */ -#endif /* CK_AUTODL */ -int adl_err = 1; /* 1 = stop on error */ -#ifdef KUI -int adl_ask = 1; /* 1 = file dialog on autodownload */ -#else -int adl_ask = 0; /* 0 = no file dialog */ -#endif /* KUI */ -#ifdef OS2 /* AUTODOWNLOAD parameters */ -int adl_kmode = ADL_PACK, /* Match Packet to signal download */ - adl_zmode = ADL_PACK; -char * adl_kstr = NULL; /* KERMIT Download String */ -char * adl_zstr = NULL; /* ZMODEM Download String */ -#endif /* OS2 */ - -int remfile = 0, rempipe = 0, remappd = 0; /* REMOTE output redirection */ -char * remdest = NULL; - -#ifndef NOSERVER -/* - Server services: - 0 = disabled - 1 = enabled in local mode - 2 = enabled in remote mode - 3 = enabled in both local and remote modes - only as initial (default) values. -*/ -int en_xit = 2; /* EXIT */ -int en_cwd = 3; /* CD/CWD */ -int en_cpy = 3; /* COPY */ -int en_del = 2; /* DELETE */ -int en_mkd = 3; /* MKDIR */ -int en_rmd = 2; /* RMDIR */ -int en_dir = 3; /* DIRECTORY */ -int en_fin = 3; /* FINISH */ -int en_get = 3; /* GET */ -#ifndef NOPUSH -int en_hos = 2; /* HOST enabled */ -#else -int en_hos = 0; /* HOST disabled */ -#endif /* NOPUSH */ -int en_ren = 3; /* RENAME */ -int en_sen = 3; /* SEND */ -int en_set = 3; /* SET */ -int en_spa = 3; /* SPACE */ -int en_typ = 3; /* TYPE */ -int en_who = 3; /* WHO */ -#ifdef datageneral -/* Data General AOS/VS can't do this */ -int en_bye = 0; /* BYE */ -#else -int en_bye = 2; /* PCs in local mode... */ -#endif /* datageneral */ -int en_asg = 3; /* ASSIGN */ -int en_que = 3; /* QUERY */ -int en_ret = 2; /* RETRIEVE */ -int en_mai = 3; /* MAIL */ -int en_pri = 3; /* PRINT */ -int en_ena = 3; /* ENABLE */ -#else -int en_xit = 0, en_cwd = 0, en_cpy = 0, en_del = 0, en_mkd = 0, en_rmd = 0, - en_dir = 0, en_fin = 0, en_get = 0, en_hos = 0, en_ren = 0, en_sen = 0, - en_set = 0, en_spa = 0, en_typ = 0, en_who = 0, en_bye = 0, en_asg = 0, - en_que = 0, en_ret = 0, en_mai = 0, en_pri = 0, en_ena = 0; -#endif /* NOSERVER */ -#endif /* NOXFER */ - -/* Miscellaneous */ - -char **xargv; /* Global copies of argv */ -int xargc; /* and argc */ -int xargs; /* an immutable copy of argc */ -char *xarg0; /* and of argv[0] */ -char *pipedata; /* Pointer to -P (pipe) data */ - -extern char *dftty; /* Default tty name from ck?tio.c */ -extern int dfloc; /* Default location: remote/local */ -extern int dfprty; /* Default parity */ -extern int dfflow; /* Default flow control */ - -#ifdef TNCODE -extern int tn_deb; -#endif /* TNCODE */ -/* - Buffered file input and output buffers. See getpkt() in ckcfns.c - and zoutdump() in the system-dependent file i/o module (usually ck?fio.c). -*/ -#ifndef DYNAMIC -/* Now we allocate them dynamically, see getiobs() below. */ -char zinbuffer[INBUFSIZE], zoutbuffer[OBUFSIZE]; -#endif /* DYNAMIC */ -char *zinptr, *zoutptr; -int zincnt, zoutcnt; -int zobufsize = OBUFSIZE; -int zofbuffer = 1; -int zofblock = 1; - -#ifdef SESLIMIT -int seslimit = 0; -#endif /* SESLIMIT */ - -#ifdef CK_AUTHENTICATION -#include "ckuath.h" -#endif /* CK_AUTHENTICATION */ - -_PROTOTYP( int getiobs, (VOID) ); - -/* M A I N -- C-Kermit main program */ - -#include - -#ifndef NOCCTRAP -#include -#include "ckcsig.h" -ckjmpbuf cmjbuf; -#ifdef GEMDOS /* Special for Atari ST */ -cc_clean(); /* This can't be right? */ -#endif /* GEMDOS */ -#endif /* NOCCTRAP */ - -#ifndef NOXFER -/* Info associated with a system ID */ - -struct sysdata sysidlist[] = { /* Add others as needed... */ - { "0", "anonymous", 0, NUL, 0, 0, 0 }, - { "A1", "Apple II", 0, NUL, 0, 0, 3 }, /* fix this */ - { "A3", "Macintosh", 1, ':', 0, 2, 1 }, - { "D7", "VMS", 0, ']', 1, 0, 0 }, - { "DA", "RSTS/E", 0, ']', 1, 0, 3 }, /* (i think...) */ - { "DB", "RT11", 0, NUL, 1, 0, 3 }, /* (maybe...) */ - { "F3", "AOS/VS", 1, ':', 0, 0, 2 }, - { "I1", "VM/CMS", 0, NUL, 0, 0, 0 }, - { "I2", "MVS/TSO", 0, NUL, 0, 0, 0 }, - { "I4", "MUSIC", 0, NUL, 0, 0, 0 }, - { "I7", "CICS", 0, NUL, 0, 0, 0 }, - { "I9", "MVS/ROSCOE", 0, NUL, 0, 0, 0 }, - { "K2", "Atari ST", 1, '\\', 1, 0, 3 }, - { "L3", "Amiga", 1, '/', 1, 0, 2 }, - { "MV", "Stratus VOS", 1, '>', 0, 1, 0 }, - { "N3", "Apollo Aegis", 1, '/', 0, 3, 2 }, - { "U1", "UNIX", 1, '/', 0, 3, 2 }, - { "U8", "MS-DOS", 1, '\\', 1, 0, 3 }, - { "UD", "OS-9", 1, '/', 0, 3, 2 }, - { "UN", "Windows-32", 1, '\\', 1, 2, 3 }, - { "UO", "OS/2", 1, '\\', 1, 2, 3 } -}; -static int nxxsysids = (sizeof(sysidlist) / sizeof(struct sysdata)); - -/* Given a Kermit system ID code, return the associated name string */ -/* and some properties of the filenames... */ - -char * -getsysid(s) char * s; { /* Get system-type name */ - int i; - if (!s) return(""); - for (i = 0; i < nxxsysids; i++) - if (!strcmp(sysidlist[i].sid_code,s)) - return(sysidlist[i].sid_name); - return(s); -} - -int -getsysix(s) char *s; { /* Get system-type index */ - int i; - if (!s) return(-1); - for (i = 0; i < nxxsysids; i++) - if (!strcmp(sysidlist[i].sid_code,s)) - return(i); - return(-1); -} -#endif /* NOXFER */ - -/* Tell if a pathname is absolute (versus relative) */ -/* This should be parceled out to each of the ck*fio.c modules... */ -int -isabsolute(path) char * path; { - int rc = 0; - int x; - if (!path) - return(0); - if (!*path) - return(0); - x = (int) strlen(path); - debug(F111,"isabsolute",path,x); -#ifdef VMS - rc = 0; - x = ckindex("[",path,0,0,0); /* 1-based */ - if (!x) - x = ckindex("<",path,0,0,0); - debug(F111,"isabsolute left bracket",path,x); - if (!x) { - x = ckindex(":",path,-1,1,1); - if (x) - debug(F111,"isabsolute logical",path,x); - } - if (x > 0) - if (path[x] != '.') /* 0-based */ - rc = 1; -#else -#ifdef UNIX - if (*path == '/' -#ifdef DTILDE - || *path == '~' -#endif /* DTILDE */ - ) - rc = 1; -#else -#ifdef OS2 - if (*path == '/' || *path == '\\') - rc = 1; - else if (isalpha(*path) && x > 2) - if (*(path+1) == ':' && (*(path +2) == '/' || *(path+2) == '\\')) - rc = 1; -#else -#ifdef AMIGA - if (*path == '/' -#ifdef DTILDE - || *path == '~' -#endif /* DTILDE */ - ) - rc = 1; -#else -#ifdef OSK - if (*path == '/' -#ifdef DTILDE - || *path == '~' -#endif /* DTILDE */ - ) - rc = 1; -#else -#ifdef datageneral - if (*path == ':') - rc = 1; -#else -#ifdef MAC - rc = 0; /* Fill in later... */ -#else -#ifdef STRATUS - rc = 0; /* Fill in later... */ -#else -#ifdef GEMDOS - if (*path == '/' || *path == '\\') - rc = 1; - else if (isalpha(*path) && x > 1) - if (*(path+1) == ':') - rc = 1; -#endif /* GEMDOS */ -#endif /* STRATUS */ -#endif /* MAC */ -#endif /* datageneral */ -#endif /* OSK */ -#endif /* AMIGA */ -#endif /* OS2 */ -#endif /* UNIX */ -#endif /* VMS */ - debug(F101,"isabsolute rc","",rc); - return(rc); -} - -/* See if I have direct access to the keyboard */ - -int -is_a_tty(n) int n; { -#ifdef UNIX - extern int ttfdflg; - if (ttfdflg > 0) - return(1); -#endif /* UNIX */ -#ifdef KUI - return 1; -#else /* KUI */ -#ifdef NT - if (isWin95()) - return(1); - else - return(_isatty(n)); -#else -#ifdef IKSD - if (inserver) - return(1); - else -#endif /* IKSD */ - return(isatty(n)); -#endif /* NT */ -#endif /* KUI */ -} - -#ifndef NOXFER -VOID -initxlist() { - extern char * sndexcept[], * rcvexcept[]; - int i; - for (i = 0; i < NSNDEXCEPT; i++) { - sndexcept[i] = NULL; - rcvexcept[i] = NULL; - } -} -#endif /* NOXFER */ - -/* Initialize flow control table */ - -VOID -initflow() { /* Default values for flow control */ -#ifdef VMS /* for each kind of connection. */ - /* The VMS telnet terminal driver treats "none" as request to lose chars */ - cxflow[CXT_REMOTE] = FLO_XONX; /* Remote mode... */ -#else -#ifdef HPUX - /* Ditto for HP-UX */ - cxflow[CXT_REMOTE] = FLO_XONX; /* Remote mode... */ -#else - /* The temptation is to make this one FLO_KEEP but don't!!! */ - /* It totally wrecks binary-file transfer when coming in via Telnet. */ - /* In UNIX at least... */ - cxflow[CXT_REMOTE] = FLO_NONE; -#endif /* HPUX */ -#endif /* VMS */ - -#ifdef VMS - cxflow[CXT_DIRECT] = FLO_XONX; /* Direct serial connections... */ -#else - cxflow[CXT_DIRECT] = FLO_NONE; -#endif /* VMS */ - -#ifdef CK_RTSCTS - cxflow[CXT_MODEM] = FLO_RTSC; /* Modem connections... */ -#else -#ifdef VMS - cxflow[CXT_MODEM] = FLO_XONX; -#else - cxflow[CXT_MODEM] = FLO_NONE; -#endif /* VMS */ -#endif /* CK_RTSCTS */ - -#ifdef VMS - cxflow[CXT_TCPIP] = FLO_XONX; /* TCP/IP connections... */ -#else - cxflow[CXT_TCPIP] = FLO_NONE; -#endif /* VMS */ - - cxflow[CXT_SSH] = FLO_NONE; - cxflow[CXT_X25] = FLO_NONE; /* Other kinds of networks... */ - cxflow[CXT_DECNET] = FLO_XONX; - cxflow[CXT_LAT] = FLO_XONX; - cxflow[CXT_NETBIOS] = FLO_NONE; - cxflow[CXT_NPIPE] = FLO_NONE; - cxflow[CXT_PIPE] = FLO_NONE; - flow = cxflow[cxtype]; /* Initial flow setting. */ - debug(F101,"initflow","",flow); -} - -#ifndef NOXFER -/* Initialize file transfer protocols */ - -VOID -initproto(y, upbstr, uptstr, srvstr, sndbstr, sndtstr, rcvbstr, rcvtstr) - int y; - char * upbstr, * uptstr, * srvstr, * sndbstr, * sndtstr, * rcvbstr, - * rcvtstr; -/* initproto */ { - - if (upbstr) /* Convert null strings */ - if (!*upbstr) /* to null pointers */ - upbstr = NULL; - - if (uptstr) /* Convert null strings */ - if (!*uptstr) /* to null pointers */ - uptstr = NULL; - - if (sndbstr) - if (!*sndbstr) - sndbstr = NULL; - - if (sndtstr) - if (!*sndtstr) - sndtstr = NULL; - - if (rcvbstr) - if (!*rcvbstr) - rcvbstr = NULL; - - if (rcvtstr) - if (!*rcvtstr) - rcvtstr = NULL; - - if (srvstr) - if (!*srvstr) - srvstr = NULL; - - protocol = y; /* Set protocol */ - - if (ptab[protocol].rpktlen > -1) - urpsiz = ptab[protocol].rpktlen; - if (ptab[protocol].spktflg > -1) - spsizf = ptab[protocol].spktflg; - if (ptab[protocol].spktlen > -1) { - spsiz = ptab[protocol].spktlen; - debug(F101,"initproto spsiz","",spsiz); - if (spsizf) { - spsizr = spmax = spsiz; - debug(F101,"initproto spsizr","",spsizr); - } - } - if (ptab[protocol].winsize > -1) - wslotr = ptab[protocol].winsize; - if (ptab[protocol].prefix > -1) - prefixing = ptab[protocol].prefix; - if (ptab[protocol].fnca > -1) - fncact = ptab[protocol].fnca; - if (ptab[protocol].fncn > -1) - fncnv = ptab[protocol].fncn; - if (ptab[protocol].fnsp > -1) - fnspath = ptab[protocol].fnsp; - if (ptab[protocol].fnrp > -1) - fnrpath = ptab[protocol].fnrp; - - makestr(&(ptab[protocol].h_b_init),upbstr); - makestr(&(ptab[protocol].h_t_init),uptstr); - makestr(&(ptab[protocol].h_x_init),srvstr); - makestr(&(ptab[protocol].p_b_scmd),sndbstr); - makestr(&(ptab[protocol].p_t_scmd),sndtstr); - makestr(&(ptab[protocol].p_b_rcmd),rcvbstr); - makestr(&(ptab[protocol].p_t_rcmd),rcvtstr); -} -#endif /* NOXFER */ - -#ifndef NOCMDL -VOID -#ifdef CK_ANSIC -docmdline(void * threadinfo) -#else /* CK_ANSIC */ -docmdline(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ -#ifdef NTSIG - setint(); - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug( F100, "docmdline called with threadinfo block", "", 0 ); - } else - debug( F100, "docmdline threadinfo is NULL","",0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef NT -#ifdef IKSD - if (inserver) - setntcreds(); -#endif /* IKSD */ -#endif /* NT */ -#endif /* CK_LOGIN */ - proto(); /* Take any requested action, then */ - if (!quiet) /* put cursor back at left margin, */ - conoll(""); -#ifndef NOLOCAL - if (cnflg) { /* Re-connect if requested */ - cnflg = 0; - doconect(0,0); - if (ttchk() < 0) - dologend(); - } -#endif /* NOLOCAL */ - -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; -} - -void -ikslogin() { - if (sstelnet -#ifdef IKSD - || inserver /* Internet server */ -#endif /* IKSD */ - ) { - char *s; - extern int fdispla; /* File-transfer display format */ - extern char * ikprompt; /* IKSD prompt */ - -#ifdef IKSD -#ifdef CK_LOGIN - if (inserver) { - x_login = 1; /* Login required */ - x_logged = 0; /* Not logged in yet */ - cmsetp(ikprompt); /* Set up IKSD's prompt */ -#ifndef NOSERVER - en_mai = 0; /* MAIL is disabled */ - en_who = 0; /* REMOTE WHO is disabled */ - en_hos = 0; /* REMOTE HOST is disabled */ - en_pri = 0; /* PRINT is disabled */ -#endif /* NOSERVER */ - } else { - x_login = 0; /* Login not required */ - x_logged = 1; /* Already logged in */ - } -#endif /* CK_LOGIN */ -#endif /* IKSD */ - nolocal = 1; /* SET LINE/HOST not allowed */ - fdispla = XYFD_N; /* No file-transfer display */ -#ifdef NETCONN - clienthost = ckgetpeer(); /* Get client's hostname */ - debug(F110,"ikslogin clienthost",clienthost,0); -#endif /* NETCONN */ - ztime(&s); /* Get current date and time */ - -#ifdef CK_LOGIN -#ifdef CK_AUTHENTICATION - if (x_login) { - x_logged = ck_tn_auth_valid(); /* Did Telnet Auth succeed? */ - debug(F111,"ikslogin","x_logged",x_logged); - -#ifdef NT - /* On Windows 9x, we do not have the ability in */ - /* zvuser() at present to determine if the name */ - /* approved in a Kerberos principal is really a */ - /* an account in the Windows Access Control List */ - if (isWin95() && x_logged == AUTH_VALID - && (ck_tn_authenticated() != AUTHTYPE_NTLM) -#ifdef CK_SRP - && (ck_tn_authenticated() != AUTHTYPE_SRP) -#endif /* CK_SRP */ - ) { - auth_finished(AUTH_USER); - x_logged = AUTH_USER; - printf("WARNING:\r\n"); - printf( -" The Telnet authentication method used cannot provide for automated\r\n"); - printf( -" login to Windows 95 or Windows 98. A password must be entered\r\n"); - printf( -" locally to validate your userid. Telnet authentication (and encryption)\r\n" - ); - printf( -" can be used to validate the host (and protect the privacy of your password.)\ -\r\n" - ); - } -#endif /* NT */ - - if (x_logged == AUTH_VALID) { -#ifdef CK_SSL - if ((ssl_active_flag || tls_active_flag) && - (!TELOPT_U(TELOPT_AUTHENTICATION) || - ck_tn_authenticated() == AUTHTYPE_NULL || - ck_tn_authenticated() == AUTHTYPE_AUTO) - ) { -#ifdef SSL_KRB5 - if (tls_is_krb5(0)) { - printf("Authenticated using Kerberos 5\r\n"); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_LI && ckxlogging) { - extern char szUserNameAuthenticated[]; - cksyslog(SYSLG_LI, 1, "AUTH_VALID", - "Kerberos 5", - szUserNameAuthenticated - ); - } -#endif /* CKSYSLOG */ - } else -#endif /* SSL_KRB5 */ - { - printf("Authenticated using X.509 certificate\r\n"); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_LI && ckxlogging) { - extern char szUserNameAuthenticated[]; - cksyslog(SYSLG_LI, 1, "AUTH_VALID", - "X.509 certificate", - szUserNameAuthenticated - ); - } -#endif /* CKSYSLOG */ - } - } else -#endif /* CK_SSL */ - { - printf("Authenticated using %s\r\n", - AUTHTYPE_NAME(ck_tn_authenticated())); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_LI && ckxlogging) { - extern char szUserNameAuthenticated[]; - cksyslog(SYSLG_LI, 1, "AUTH_VALID", - AUTHTYPE_NAME(ck_tn_authenticated()), - szUserNameAuthenticated - ); - } -#endif /* CKSYSLOG */ - } - zvuser(uidbuf); - if (zvpass("") == 0) - x_logged = 0; - } else if (x_logged == AUTH_USER && !strcmp(uidbuf,"anonymous")) { - extern char szUserNameAuthenticated[]; - zvuser(uidbuf); - debug(F110,"szUserNameAuthenticated", - szUserNameAuthenticated,0); - if (zvpass(szUserNameAuthenticated) == 0) { - /* Anonymous login failed. Force a username prompt. */ - x_logged = 0; - uidbuf[0] = '\0'; - } else { -#ifdef CK_SSL - if ((ssl_active_flag || tls_active_flag) && - (!TELOPT_U(TELOPT_AUTHENTICATION) || - ck_tn_authenticated() == AUTHTYPE_NULL || - ck_tn_authenticated() == AUTHTYPE_AUTO)) { - printf("Authenticated using X.509 certificate\r\n"); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_LI && ckxlogging) { - extern char szUserNameAuthenticated[]; - cksyslog(SYSLG_LI, 1, "AUTH_USER", - "X.509 certificate", - szUserNameAuthenticated - ); - } -#endif /* CKSYSLOG */ - } else -#endif /* CK_SSL */ - { - printf("Authenticated using %s\r\n", - AUTHTYPE_NAME(ck_tn_authenticated()) - ); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_LI && ckxlogging) { - cksyslog(SYSLG_LI, 1, "AUTH_USER", - AUTHTYPE_NAME(ck_tn_authenticated()), - szUserNameAuthenticated - ); - } -#endif /* CKSYSLOG */ - } - } - } else { -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_LI && ckxlogging && - x_logged == AUTH_USER) { - extern char szUserNameAuthenticated[]; - cksyslog(SYSLG_LI, 1, "AUTH_USER", - AUTHTYPE_NAME(ck_tn_authenticated()), - szUserNameAuthenticated - ); - } -#endif /* CKSYSLOG */ - x_logged = 0; - if (!strcmp("(unknown)",uidbuf) -#ifdef NT - || !stricmp("administrator",uidbuf) -#ifdef UNIX - || !strcmp("root",uidbuf) -#else -#ifdef Plan9 - || !strcmp("root",uidbuf) -#else -#ifdef OSK - || !strcmp("root",uidbuf) -#endif /* OSK */ -#endif /* Plan9 */ -#endif /* UNIX */ -#endif /* NT */ - ) - uidbuf[0] = '\0'; - } - } -#endif /* CK_AUTHENTICATION */ -#endif /* CK_LOGIN */ - -#ifdef IKSD - if (inserver) - printf("\r\nInternet Kermit Service ready at %s%s\r\n",s,versio); - else -#endif /* IKSD */ - printf("\r\nC-Kermit ready at %s%s\r\n",s,versio); - if (*myhost) - printf("%s\r\n", myhost); - printf("\r\n"); - } -#ifdef CK_LOGIN -#ifdef IKSD - if (inserver) { - int i; - extern int arg_x; /* Flag for '-x' on command line */ -#ifndef NOSPL - extern struct mtab *mactab; /* For ON_LOGIN macro. */ - extern int nmac; -#endif /* NOSPL */ - - debug(F110,"MAIN clienthost",clienthost,0); - srvidl = timelimit = logintimo; /* For interactive login */ - rtimer(); /* Reset timer */ - for (i = 0; i < iks_retry && !x_logged; i++) { /* Count retries */ - if (gtimer() > logintimo) - break; -#ifdef TNCODE - tn_wait("login loop"); - tn_push(); -#endif /* TNCODE */ - debug(F101,"MAIN LOGIN try","",i); - what = W_NOTHING; /* Because proto() changes this */ - -#ifdef IKS_OPTION - debug(F111,"MAIN LOGIN", - "TELOPT_SB(TELOPT_KERMIT).kermit.me_start", - TELOPT_SB(TELOPT_KERMIT).kermit.me_start - ); - /* Kermit server negotiated */ - if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { - debug(F101,"IKSD starting in server mode","",0); - arg_x = 1; /* Enter server mode */ - sstate = 'x'; -#ifdef IKSDPOPBACK - justone = 1; /* Execute one command at a time. */ -#endif /* IKSDPOPBACK */ - proto(); /* Enter protocol if requested. */ -#ifdef NTSIG - ck_ih(); -#endif /* NTSIG */ - if (x_logged) /* Logged in */ - break; - } else { /* Not in client/server mode */ -#endif /* IKS_OPTION */ - debug(F101,"IKSD starting with Username prompt","",0); - x_logged = ckxlogin((CHAR *)uidbuf,NULL,NULL,1); - if (sstate) { /* Received a packet at prompt */ -#ifdef IKSDPOPBACK - justone = 1; /* Go handle it */ -#endif /* IKSDPOPBACK */ - proto(); - } - if (!x_logged) { /* In case we are at the prompt... */ - printf("Access denied.\n"); - uidbuf[0] = '\0'; /* Forget the name if we have one */ - } -#ifdef IKS_OPTION - } -#endif /* IKS_OPTION */ - } - srvidl = timelimit = iks_timo; /* Reset command timelimit */ - debug(F101,"MAIN LOGIN","",x_logged); - if (!x_logged) { /* Logins failed. */ - if (TELOPT_SB(TELOPT_KERMIT).kermit.me_start) - errpkt((CHAR *)"Login Timeout"); - msleep(500); - doexit(BAD_EXIT,0); - } - what = W_NOTHING; /* Stay in known state */ -#ifndef NOSERVER - if (isguest) { - en_pri = 0; /* No printing for anonymous users */ - en_mai = 0; /* No email for anonymous users */ - en_mkd = 0; /* Or directory creation */ - en_rmd = 0; /* Or directory removal */ - en_ena = 0; /* Or ENABLing DISABLEd items */ - } -#endif /* NOSERVER */ - -#ifndef NOSPL -/* - If a macro named "on_login" is defined, execute it. Also remove it from the - macro table so the user cannot see what it does. Execute it as part of the - iksd.conf file. -*/ - if (nmac) { /* Any macros defined? */ - int k; /* Yes */ - char * cmd = "on_login"; /* MSVC 2.x compiler error */ - k = mlook(mactab,cmd,nmac); /* Look up "on_exit" */ - if (k >= 0) { /* If found, */ -#ifdef IKSDCONF - int saved = iksdcf; - iksdcf = 0; -#endif /* IKSDCONF */ - if (dodo(k,"",0) > -1) /* set it up, */ - parser(1); /* execute it */ -#ifdef IKSDCONF - iksdcf = saved; -#endif /* IKSDCONF */ - delmac(cmd,1); /* and delete it */ - } - } -#endif /* NOSPL */ - } /* if (inserver) */ -#else /* CK_LOGIN */ - if (inserver) - srvidl = timelimit = iks_timo; /* Set idle limits for IKS */ -#endif /* CK_LOGIN */ -#endif /* IKSD */ -} - -VOID -#ifdef CK_ANSIC -failcmdline(void * foo) -#else /* CK_ANSIC */ -failcmdline(foo) VOID * foo; -#endif /* CK_ANSIC */ -{ -#ifdef GEMDOS - cc_clean(); -#endif /* GEMDOS */ -#ifndef NOLOCAL - if (cnflg) doconect(0,0); /* connect again if requested. */ - if (ttchk() < 0) - dologend(); -#endif /* NOLOCAL */ -} -#endif /* NOCMDL */ - -#ifndef NOICP -VOID -#ifdef CK_ANSIC -dotakeini(void * threadinfo) /* Execute init file. */ -#else /* CK_ANSIC */ -dotakeini(threadinfo) VOID * threadinfo; /* Execute init file. */ -#endif /* CK_ANSIC */ -/* dotakeini */ { -#ifdef NTSIG - setint(); - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "dotakeini called with threadinfo block","", 0); - } else - debug(F100, "dotakeini - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef NT -#ifdef IKSD - if (inserver) - setntcreds(); -#endif /* IKSD */ -#endif /* NT */ -#endif /* CK_LOGIN */ - cmdini(); /* Sets tlevel */ - - debug(F111,"dotakeini","inserver",inserver); - debug(F111,"dotakeini","sstelnet",sstelnet); - -#ifdef COMMENT -/* Wrong place for this... */ -#ifndef NOXFER -#ifdef CK_FAST - dofast(); /* By now FAST defaults should be OK */ -#endif /* CK_FAST */ -#endif /* NOXFER */ -#endif /* COMMENT */ - - doinit(); /* Now do the initialization file */ - debug(F101,"main executing init file","",tlevel); - while (tlevel > -1) { - sstate = (CHAR) parser(1); /* Execute one command at a time. */ - if (sstate) proto(); /* Enter protocol if requested. */ -#ifdef NTSIG - ck_ih(); -#endif /* NTSIG */ - } - debug(F101,"main exits init file","",tlevel); - -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; -} - -VOID -#ifdef CK_ANSIC -failtakeini(void * threadinfo) -#else /* CK_ANSIC */ -failtakeini(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -/* failtakeini */ { -#ifdef GEMDOS - cc_clean(); /* Atari: Clean up after ^C-trap. */ -#endif /* GEMDOS */ - if (!cfilef) { - conoll("Interrupt during initialization or command-line processing."); - conoll("C-Kermit quitting..."); - } - doexit(BAD_EXIT,-1); /* Exit with bad status. */ -} - -VOID -#ifdef CK_ANSIC -doicp(void * threadinfo) -#else /* CK_ANSIC */ -doicp(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -/* doicp */ { -#ifdef NTSIG - setint(); - if (threadinfo) { /* Thread local storage... */ - if (!TlsSetValue(TlsIndex,threadinfo)) - debug(F101,"doicp TlsSetValue failed","",GetLastError()); - debug(F101, "doicp a threadinfo block - TlsIndex", "", TlsIndex); - } else { - debug(F100, "doicp received a null threadinfo", "", 0); - } -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef NT -#ifdef IKSD - if (inserver) - setntcreds(); -#endif /* IKSD */ -#endif /* NT */ -#endif /* CK_LOGIN */ -#ifdef MAC - while (1) { - extern char *lfiles; /* Fake pointer cast */ - - if (connected) { - debug(F100, "doicp: calling macparser", "", 0); - sstate = newparser(1, 1, 0L); - - /* ignore null command state */ - if (sstate == 'n') - sstate = '\0'; - - if (sstate) - proto(); - } else { - /* - * process take files the finder gave us. - */ - if ((tlevel == -1) && lfiles) - startlfile(); - - debug(F100, "doicp: calling parser", "", 0); - sstate = (CHAR) parser(0); - if (sstate == 'c') /* if MAC connect */ - sstate = 0; - if (sstate) - proto(); - } - } -#else /* Not MAC */ - -#ifndef NOSPL -/* - If interactive commands were given on the command line (using the - -C "command, command, ..." option), assign them to a macro called - "cl_commands", then execute the macro and leave it defined for - subsequent re-execution if desired. -*/ - if (clcmds) { /* Check for -C commands */ - int x; - x = addmac("cl_commands",clcmds); /* Put macro in table */ - if (x > -1) { /* If successful, */ - dodo(x,NULL,CF_CMDL); /* set up for macro execution */ - while (maclvl > -1) { /* Loop getting macro commands. */ - sstate = (CHAR) parser(1); - if (sstate) proto(); /* Enter protocol if requested. */ -#ifdef NTSIG - ck_ih(); -#endif /* NTSIG */ - } - } - debug(F100,"doicp calling herald","",0); - herald(); - } -#endif /* NOSPL */ - while(1) { /* Loop getting commands. */ - sstate = (CHAR) parser(0); - if (sstate) proto(); /* Enter protocol if requested. */ -#ifdef NTSIG - ck_ih(); -#endif /* NTSIG */ - } -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ -#endif /* MAC */ -} - -VOID -#ifdef CK_ANSIC -failicp(void * threadinfo) -#else /* CK_ANSIC */ -failicp(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ -#ifdef GEMDOS - cc_clean(); -#endif /* GEMDOS */ - fixcmd(); /* Pop command stacks, etc. */ - clcmds = NULL; - debug(F100,"ckcmai got interrupt","",0); -} -#endif /* NOICP */ - -#ifndef NOICP -VOID -#ifdef CK_ANSIC -docmdfile(void * threadinfo) /* Execute application file */ -#else /* CK_ANSIC */ -docmdfile(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -/* docmdfile */ { -#ifdef NTSIG - concb((char)escape); - setint(); - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "docmdfile called with threadinfo block","", 0); - } else debug(F100, "docmdfile - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - debug(F110,"main cmdfil",cmdfil,0); -#ifndef NOSPL - addmac("\\%0",cmdfil); -#endif /* NOSPL */ - dotake(cmdfil); /* execute it */ - while (tlevel > -1) { /* until it runs out. */ - sstate = parser(1); /* Loop getting commands. */ - if (sstate) proto(); /* Enter protocol if requested. */ -#ifdef NTSIG - ck_ih(); -#endif /* NTSIG */ - } - cfilef = 1; /* Remember we did this */ - -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; -} - -VOID -#ifdef CK_ANSIC -failcmdfile(void * threadinfo) -#else /* CK_ANSIC */ -failcmdfile(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -/* failcmdfile */ { -#ifdef GEMDOS - cc_clean(); /* Atari: Clean up after ^C-trap. */ -#endif /* GEMDOS */ - if (!cfilef) { - conoll("Interrupt during initialization or command-line processing."); - conoll("C-Kermit quitting..."); - } - doexit(BAD_EXIT,-1); /* Exit with bad status. */ -} -#endif /* NOICP */ - -#ifndef NOXFER -VOID -setprefix(z) int z; { /* Initial control-char prefixing */ -#ifdef CK_SPEED - int i, val; - - prefixing = z; - ptab[protocol].prefix = prefixing; - debug(F101,"setprefix","",prefixing); - switch (z) { - case PX_ALL: /* All */ -#ifdef COMMENT - /* Don't let Clear-Channel be dependent on prefixing */ - clearrq = 0; /* Turn off clearchannel, fall thru */ -#endif /* COMMENT */ - case PX_NON: /* None */ - val = (z == PX_ALL) ? 1 : 0; - for (i = -#ifdef UNPREFIXZERO - 0 -#else - 1 -#endif /* UNPREFIXZERO */ - ; i < 32; i++) - ctlp[i] = val; - for (i = 127; i < 160; i++) ctlp[i] = val; - ctlp[(unsigned)255] = val; - if (z == PX_NON) { /* These are never safe */ - if (network) { /* Assume network = telnet or rlogin */ - ctlp[CR] = 1; /* Prefix CR because of NVT rules */ - ctlp[XON] = ctlp[XOFF] = 1; /* Because of Telnet server */ - ctlp[127] = ctlp[255] = 1; /* Telnet IAC */ - ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit packet start */ - } else { - ctlp[CR] = ctlp[255] = ctlp[mystch] = ctlp[mystch+128] = 1; - if (flow == FLO_XONX) /* Xon/Xoff forces prefixing */ - ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1; - } - } - break; - - case PX_CAU: /* Cautious or Minimal */ -#ifdef COMMENT - /* Don't let CLEAR-CHANNEL be dependent on Prefixing */ - clearrq = 0; /* Turn off clearchannel */ -#endif /* COMMENT */ - case PX_WIL: /* Minimal ("wild") */ - ctlp[0] = 1; /* Does not include 0 */ - for (i = 1; i < 32; i++) - ctlp[i] = 0; - for (i = 127; i < 160; i++) - ctlp[i] = 0; - ctlp[mystch] = ctlp[mystch+128] = 1; /* Kermit start of packet */ - if (seol != 13) - ctlp[seol] = ctlp[seol+128] = 1; /* Kermit end */ - ctlp[13] = ctlp[141] = 1; /* In case of TELNET (NVT rules) */ - ctlp[(unsigned)255] = 1; /* Ditto */ - - /* ^D, ^J, ^M, or ^U followed by tilde trigger Rlogin escape */ - - ctlp[4] = ctlp[4+128] = 1; /* In case of RLOGIN */ - ctlp[10] = ctlp[10+128] = 1; /* In case of RLOGIN */ - ctlp[21] = ctlp[21+128] = 1; /* In case of RLOGIN */ - - if (flow == FLO_XONX || /* Xon/Xoff forces prefixing these */ - prefixing == PX_CAU || /* So does CAUTIOUS */ - network) /* Networks too... */ - ctlp[XON] = ctlp[XOFF] = ctlp[XON+128] = ctlp[XOFF+128] = 1; - if (prefixing == PX_CAU) { /* Cautious - add some more */ -#ifdef UNPREFIXZERO - ctlp[0] = 1; -#endif /* UNPREFIXZERO */ - ctlp[3] = ctlp[16] = 1; /* ^C, DLE */ - ctlp[14] = ctlp[15] = 1; /* SO/SI */ - ctlp[24] = ctlp[25] = 1; /* VMS might need these */ - ctlp[26] = ctlp[26+128] = 1; /* UNIX suspend */ - ctlp[28] = ctlp[29] = ctlp[30] = 1; /* Assorted esc chars */ - ctlp[131] = ctlp[141] = ctlp[144] = 1; /* and 8-bit versions */ - ctlp[(unsigned)255] = ctlp[156] = ctlp[157] = ctlp[158] = 1; - } - break; - } -#endif /* CK_SPEED */ -} -#endif /* NOXFER */ - -VOID -makever() { /* Make version string from pieces */ - int x, y; -#ifndef OS2 -#ifndef MAC - ck_s_xver = ck_s_ver; /* Fill in C-Kermit version number */ - ck_l_xver = ck_l_ver; /* for UNIX, VMS, etc. */ -#endif /* MAC */ -#endif /* OS2 */ - x = strlen(ck_s_name); - y = strlen(ck_s_xver); - if (y + x + 1 < CKVERLEN) { - ckmakmsg(versio,CKVERLEN,ck_s_name," ",ck_s_xver,NULL); - } else { - ckstrncpy(versio,"C-Kermit",CKVERLEN); - return; - } - x += y + 1; - if (*ck_s_who) { - y = strlen(ck_s_who); - if (CKVERLEN < x + y + 1) - return; - ckstrncat(versio,"-",CKVERLEN); - ckstrncat(versio,ck_s_who,CKVERLEN); - } - x += y + 1; - y = strlen(ck_s_test); - if (y > 0 && y + x + 1 < CKVERLEN) { - ckstrncat(versio," ",CKVERLEN); - ckstrncat(versio,ck_s_test,CKVERLEN); - x += y + 1; - y = strlen(ck_s_tver); - if (y > 0 && y + x + 1 < CKVERLEN) { - ckstrncat(versio,".",CKVERLEN); - ckstrncat(versio,ck_s_tver,CKVERLEN); - x += y + 1; - } - } - y = strlen(ck_s_date); - if (y > 0 && y + x + 2 < CKVERLEN) { - ckstrncat(versio,", ",CKVERLEN); - ckstrncat(versio,ck_s_date,CKVERLEN); - } - vernum = ck_l_ver; - xvernum = ck_l_xver; - debug(F110,"Kermit version",versio,0); -} - -union ck_short shortbytes; /* For determining byte order */ -int byteorder = 0; /* 0 = Big Endian; 1 = Little Endian */ -int bigendian = 1; -/* NOTE: MUST BE 0 or 1 - nothing else */ - -#ifndef NOSPL -#define SCRIPTLEN 10240 -#endif /* NOSPL */ - -#ifdef NETCONN -#ifndef NOCMDL -#ifndef NOURL -VOID -dourl() { - int rc = 0; - char * port = NULL; - extern int ttnproto; - extern struct urldata g_url; - -#ifdef COMMENT - /* NOTE: debug() doesn't work yet - must use printf's */ - printf("URL: %s\n",g_url.sav ? g_url.sav : "(none)"); - printf("Type: %s\n",g_url.svc ? g_url.svc : "(none)"); - printf("User: %s\n",g_url.usr ? g_url.usr : "(none)"); - printf("Pass: %s\n",g_url.psw ? g_url.psw : "(none)"); - printf("Host: %s\n",g_url.hos ? g_url.hos : "(none)"); -/* printf("Port: %s\n",g_url.por ? g_url.por : "(none)"); */ - printf("Path: %s\n",g_url.pth ? g_url.pth : "(none)"); -#endif /* COMMENT */ - - if (!ckstrcmp(g_url.svc,"iksd",-1,0) || - !ckstrcmp(g_url.svc,"kermit",-1,0)) { - extern char pwbuf[]; - extern int pwflg; -#ifdef OS2 - extern int pwcrypt; -#endif /* OS2 */ - - if (!g_url.hos) { - printf("?Incomplete IKSD URL\n"); - doexit(BAD_EXIT,1); - } - if (!g_url.usr) - makestr(&g_url.usr,"anonymous"); - if (!g_url.psw) { - char * tmpbuf = NULL; - if (!(tmpbuf = (char *)malloc(1024))) - fatal("dourl: out of memory"); - if (!ckstrcmp(g_url.usr,"anonymous",-1,0)) { - ckmakmsg(tmpbuf,1024,uidbuf,"@",myhost,NULL); - makestr(&g_url.psw,tmpbuf); - } else { - readpass(" Password:",tmpbuf,1024); - makestr(&g_url.psw,tmpbuf); - } - free(tmpbuf); - } - port = "kermit"; - ttnproto = NP_TELNET; - nettype = NET_TCPB; - mdmtyp = -nettype; - local = -1; - ckstrncpy(uidbuf,g_url.usr,UIDBUFLEN); - if (g_url.psw) { - ckstrncpy(pwbuf,g_url.psw,PWBUFL); - pwflg = 1; -#ifdef OS2 - pwcrypt = 0; -#endif /* OS2 */ - } - ckmakmsg(ttname, - TTNAMLEN, - g_url.hos, - ":", - g_url.por ? g_url.por : port, - NULL - ); - rc = ttopen(ttname,&local,mdmtyp,0); - if (rc > -1) { - network = 1; - exitonclose = 1; -#ifdef CKLOGDIAL - dolognet(); -#endif /* CKLOGDIAL */ - } else { - printf("?Connection failed: %s\n",g_url.sav); - doexit(BAD_EXIT,1); - } - /* Also need to check here for secure authentication already done */ - -#ifdef NOSPL - cflg = 1; -#else - { - char * script = NULL; - if (!(script = (char *)malloc(SCRIPTLEN))) - fatal("dourl: out of memory"); - if (!g_url.pth) { /* Write the appropriate script */ - cflg = 1; - ckmakxmsg(script,SCRIPTLEN, - "if not eq {\\v(authstate)} {user} ", - "if not eq {\\v(authstate)} {valid} { ", - "remote login ", /* No path */ - g_url.usr, /* Just log in and CONNECT */ - " ", - g_url.psw, - ", if fail exit 1 {IKSD login failed} }", - ", connect", - NULL,NULL,NULL,NULL); - /* printf("CLCMDS 1: %s\n",script); */ - } else { - /* does the path specify a file or a directory? */ - int len = strlen(g_url.pth); - if (ISDIRSEP(g_url.pth[len-1])) { - ckmakxmsg(script,SCRIPTLEN, /* Directory name given */ - "if not eq {\\v(authstate)} {user} \ -if not eq {\\v(authstate)} {valid} { remote login ", - g_url.usr, - " ", - g_url.psw, - ", if fail exit 1 {IKSD login failed} }", - ", set macro error on", - ", set xfer displ brief", - ", set xfer bell off", - ", remote cd ", - g_url.pth, - ", lineout directory", - ", connect" - ); - /* printf("CLCMDS 2: %s\n",script); */ - } else { - ckmakxmsg(script,SCRIPTLEN, /* Path given, try to GET */ - "if not eq {\\v(authstate)} {user} \ -if not eq {\\v(authstate)} {valid} { remote login ", - g_url.usr, - " ", - g_url.psw, - ", if fail exit 1 {IKSD login failed} }", - ", set xfer displ brief", - ", set xfer bell off", - ", get ", - g_url.pth, - ", .rc := \\v(status)", - ", if open connection bye", - ", exit \\m(rc)" - ); - /* printf("CLCMDS 2: %s\n",script); */ - } - } - clcmds = script; /* Make this our -C cmdline macro */ - /* printf("HAVEURL=%d\n",haveurl); */ - } -#endif /* NOSPL */ - } else { - if (ckstrcmp(g_url.svc,"telnet",-1,0) && -#ifdef SSHBUILTIN - ckstrcmp(g_url.svc,"ssh",-1,0) && -#endif /* SSHBUILTIN */ - ckstrcmp(g_url.svc,"ftp",-1,0)) { - printf("?Sorry, %s URLs not supported\n", - g_url.svc ? g_url.svc : ""); - doexit(BAD_EXIT,1); - } - } -} -#endif /* NOCMDL */ -#endif /* NETCONN */ -#endif /* NOURL */ - -/* - main()... - - If you get complaints about "main: return type is not blah", - define MAINTYPE on the CC command line, e.g. "CFLAGS=-DMAINTYPE=blah" - (where "blah" is int, long, or whatever). - - If the complaint is "Attempt to return a value from a function of type void" - then add -DMAINISVOID. -*/ -#ifndef MAINTYPE -#ifndef MAINISVOID -#define MAINTYPE int -#endif /* MAINISVOID */ -#endif /* MAINTYPE */ - -#ifdef MAINISVOID -#ifndef MAINTYPE -#define MAINTYPE void -#endif /* MAINTYPE */ -#endif /* MAINISVOID */ - -#ifdef aegis -/* On the Apollo, intercept main to insert a cleanup handler */ -int -ckcmai(argc,argv) int argc; char **argv; -#else -#ifdef MAC /* Macintosh */ -int -main (void) -#else -#ifdef __GNUC__ /* GCC compiler */ -int -main(argc,argv) int argc; char **argv; -#else -#ifdef __DECC /* DEC Alpha with DEC C compiler */ -#ifdef __ALPHA -int -main(argc,argv) int argc; char **argv; -#else /* DEC C compiler, not Alpha */ -#define MAINISVOID -VOID -main(argc,argv) int argc; char **argv; -#endif /* __ALPHA */ -#else -#ifdef STRATUS /* Stratus VOS */ -int -main(argc,argv) int argc; char **argv; -#else /* K-95 */ -#ifdef OS2 -#ifdef KUI -#define MAINISVOID -void -Main( int argc, char ** argv ) -#else /* KUI */ -#define MAINISVOID -VOID -main(argc,argv) int argc; char **argv; -#endif /* KUI */ -#else /* Not K95 */ -MAINTYPE /* All others... */ -main(argc,argv) int argc; char **argv; -#endif /* OS2 */ -#endif /* STRATUS */ -#endif /* __DECC */ -#endif /* __GNUC__ */ -#endif /* MAC */ -#endif /* aegis */ - -/* main */ { - - char *p; - -#ifndef NOSETKEY - int i; -#endif /* NOSETKEY */ - -#ifdef datageneral - short *pfha = 016000000036; /* Get around LANG_RT problem */ - *pfha = (short) 0; /* No user protection fault handler */ -#endif /* datageneral */ - -/* Do some initialization */ - -#ifndef MAC - xargc = xargs = argc; /* Make global copies of argc */ - xargv = argv; /* ...and argv. */ - xarg0 = argv[0]; -#ifdef NT - setOSVer(); -#endif /* NT */ - zstrip(argv[0],&p); /* Get name we were invoked with */ - makestr(&myname,p); - if (!ckstrcmp(myname,"telnet",-1,0)) howcalled = I_AM_TELNET; -#ifdef CK_KERBEROS - else if (!ckstrcmp(myname,"ktelnet",-1,0)) howcalled = I_AM_TELNET; -#endif /* CK_KERBEROS */ - else if (!ckstrcmp(myname,"rlogin",-1,0)) howcalled = I_AM_RLOGIN; - else if (!ckstrcmp(myname,"iksd",-1,0)) howcalled = I_AM_IKSD; -#ifdef NEWFTP - else if (!ckstrcmp(myname,"ftp",-1,0)) howcalled = I_AM_FTP; -#endif /* NEWFTP */ -#ifndef NOHTTP - else if (!ckstrcmp(myname,"http",-1,0)) howcalled = I_AM_HTTP; -#endif /* NOHTTP */ -#ifdef OS2 - else if (!ckstrcmp(myname,"telnet.exe",-1,0)) howcalled = I_AM_TELNET; -#ifdef SSHBUILTIN - else if (!ckstrcmp(myname,"ssh",-1,0)) howcalled = I_AM_SSH; - else if (!ckstrcmp(myname,"ssh.exe",-1,0)) howcalled = I_AM_SSH; -#endif /* SSHBUILTIN */ -#ifdef CK_KERBEROS - else if (!ckstrcmp(myname,"ktelnet.exe",-1,0)) howcalled = I_AM_TELNET; -#endif /* CK_KERBEROS */ - else if (!ckstrcmp(myname,"rlogin.exe",-1,0)) howcalled = I_AM_RLOGIN; -#ifdef NT - else if (!ckstrcmp(myname,"iksdnt",-1,0)) howcalled = I_AM_IKSD; - else if (!ckstrcmp(myname,"iksdnt.exe",-1,0)) howcalled = I_AM_IKSD; -#endif /* NT */ -#ifdef NEWFTP - else if (!ckstrcmp(myname,"ftp.exe",-1,0)) howcalled = I_AM_FTP; -#endif /* NEWFTP */ -#ifndef NOHTTP - else if (!ckstrcmp(myname,"http.exe",-1,0)) howcalled = I_AM_HTTP; -#endif /* NOHTTP */ -#endif /* OS2 */ - else if (!ckstrcmp(myname,"kermit-sshsub",-1,0)) howcalled = I_AM_SSHSUB; - -#ifndef NOICP - cmdini(); /* Must come before prescan */ - debug(F100,"main cmdini() done","",0); -#endif /* NOICP */ - prescan(0); /* Pre-Check for debugging, etc */ -#endif /* MAC */ - debug(F101,"MAIN feol","",feol); - makever(); /* Put together version strings */ -#ifndef NOSETKEY /* Allocate & initialize the keymap */ - /* This code has been moved to before sysinit() for K95G */ - if (!(keymap = (KEY *) malloc(sizeof(KEY)*KMSIZE))) - fatal("main: no memory for keymap"); - if (!(macrotab = (MACRO *) malloc(sizeof(MACRO)*KMSIZE))) - fatal("main: no memory for macrotab"); - for (i = 0; i < KMSIZE; i++) { - keymap[i] = (KEY) i; - macrotab[i] = NULL; - } -#endif /* NOSETKEY */ - - shortbytes.x_short = 0xABCD; /* Get Endianness */ - if (shortbytes.x_char[0] == 0xCD) { /* 0 = Big Endian */ - byteorder = 1; /* 1 = Little Endian */ - bigendian = 0; /* (for clarity in programming) */ - } else { - byteorder = 0; /* Big Endian */ - bigendian = 1; - } - if (sysinit() < 0) /* System-dependent initialization. */ - fatal("Can't initialize!"); - else - initflg = 1; /* Remember we did. */ - debug(F111,"ckcmai myname",myname,howcalled); - -#ifdef UNIX - getexedir(); /* Compute exedir variable */ -#endif /* UNIX */ - -#ifdef CKSYSLOG -#ifdef SYSLOGLEVEL -/* - If built with -DSYSLOGLEVEL on cc command line, this means we always - do syslogging at the indicated level. -*/ - zsyslog(); /* Open syslog */ -#else /* SYSLOGLEVEL */ -#ifdef IKSD - if (inserver) - zsyslog(); /* Open syslog */ -#endif /* IKSD */ -#endif /* SYSLOGLEVEL */ -#endif /* CKSYSLOG */ - -#ifdef CK_KERBEROS - ini_kerb(); /* Initialize Kerberos data */ -#endif /* CK_KERBEROS */ -#ifdef CK_SSL - ssl_once_init(); -#endif /* CK_SSL */ -#ifdef TNCODE - tn_set_modes(); /* Init Telnet Option tables */ -#endif /* TNCODE */ - -#ifdef CK_TTGWSIZ /* Initialize screen dimensions */ -#ifdef OS2 - ttgcwsz(); -#else /* OS2 */ - if (ttgwsiz() > 0) { - if (tt_rows > 0 && tt_cols > 0) { - cmd_rows = tt_rows; - cmd_cols = tt_cols; - } - } -#endif /* OS2 */ -#endif /* CK_TTGWSIZ */ - -#ifndef OS2 -#ifdef TCPSOCKET -#ifdef CK_SOCKS - SOCKSinit(argv[0]); /* Internet relay package... */ -#endif /* CK_SOCKS */ -#endif /* TCPSOCKET */ -#endif /* OS2 */ - - initflow(); /* Initialize flow-control table */ - -#ifndef NOICP -#ifdef CKFLOAT - initfloat(); /* Deduce floating-point precision */ -#endif /* CKFLOAT */ -#endif /* NOICP */ - -#ifndef NOXFER - initxlist(); /* Init exception lists */ - -#ifdef CK_XYZ /* Initialize protocols... */ - -#ifdef XYZ_INTERNAL /* XYZMODEM are internal ... */ - -#ifdef COMMENT - /* Can't do this for XMODEM because if filename contains a "C" etc... */ - initproto(PROTO_X, "rx %s","rx %s", NULL, NULL, NULL, NULL, NULL); - initproto(PROTO_XC,"rc %s","rc %s", NULL, NULL, NULL, NULL, NULL); -#else /* COMMENT */ - initproto(PROTO_X, NULL, NULL, NULL, NULL, NULL, NULL, NULL); - initproto(PROTO_XC,NULL, NULL, NULL, NULL, NULL, NULL, NULL); -#endif /* COMMENT */ - initproto(PROTO_Y, "rb","rb", NULL, NULL, NULL, NULL, NULL); - initproto(PROTO_G, "rb","rb", NULL, NULL, NULL, NULL, NULL); - initproto(PROTO_Z, "rz","rz", NULL, NULL, NULL, NULL, NULL); - initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL); - /* Kermit Must be last */ - -#else /* XYZMODEM are external protocols ... */ - - /* s1 s2 s3 s4 s5 s6 s7 */ - initproto(PROTO_X, "rx %s","rx %s",NULL,"sx %s","sx -a %s","rx %s", "rx %s"); - initproto(PROTO_XC,"rc %s","rc %s",NULL,"sx %s","sx -a %s","rc %s", "rc %s"); - initproto(PROTO_Y, "rb", "rb", NULL,"sb %s","sb -a %s","rb", "rb" ); - initproto(PROTO_G, "rb", "rb", NULL,"sb %s","sb -a %s","rb", "rb" ); - initproto(PROTO_Z, "rz", "rz", NULL,"sz %s","sz -a %s","rz", "rz" ); - initproto(PROTO_K, "kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL); - /* Kermit must be last */ - -#endif /* XYZ_INTERNAL */ - -#else /* No XYZMODEM support */ - - initproto(PROTO_K,"kermit -ir","kermit -r","kermit -x",NULL,NULL,NULL,NULL); - -#endif /* CK_XYZ */ -#endif /* NOXFER */ - - connoi(); /* Console interrupts off */ - -#ifndef NOXFER -#ifdef OS2 - /* Initialize Kermit and Zmodem Auto-Download Strings */ - adl_kstr = strdup("KERMIT READY TO SEND..."); - adl_zstr = strdup("rz\r"); -#endif /* OS2 */ - -#ifdef PATTERNS - initpat(); /* Initialize filename patterns */ -#endif /* PATTERNS */ -#endif /* NOXFER */ - -#ifndef NOCSETS - initcsets(); /* Initialize character sets */ -#endif /* NOCSETS */ - -#ifndef NOICP -#ifdef DFCDMSG - makestr(&cdmsgstr,DFCDMSG); - makelist(cdmsgstr,cdmsgfile,8); /* Initialize CD message filenames */ -#endif /* DFCDMSG */ -#endif /* NOICP */ - - sstate = 0; /* No default start state. */ -#ifdef DYNAMIC - if (getiobs() < 0) - fatal("Can't allocate i/o buffers!"); -#endif /* DYNAMIC */ - -#ifndef NOSPL -#ifndef NORANDOM - { - char stackdata[256]; - unsigned int c = 1234, n; - /* try to make a random unsigned int to feed srand() */ -#ifndef VMS - /* time.h and MultiNet do not get along */ - c = time(NULL); -#endif /* VMS */ - c *= getpid(); - /* Referenced before set... DELIBERATELY */ - for (n = 0; n < sizeof(stackdata); n++) /* IGNORE WARNING */ - c += stackdata[n]; /* DELIBERATELY USED BEFORE SET */ - srand((unsigned int)c); - } -#endif /* NORANDOM */ -#endif /* NOSPL */ - - ckhost(myhost,MYHOSTL); /* Name of local host */ - debug(F110,"main ckhost",myhost,0); -#ifdef IKSD - if (!inserver) { -#endif /* IKSD */ - ckstrncpy(ttname,dftty,TTNAMLEN); /* Set up default tty name. */ - local = nolocal ? 0 : dfloc; /* And whether it's local or remote. */ - parity = dfprty; /* Set initial parity, */ -#ifndef NOXFER - myindex = getsysix(cksysid); /* System index */ -#endif /* NOXFER */ - if (local) if (ttopen(ttname,&local,0,0) < 0) { -#ifndef OS2 - conol("Can't open device: "); - conoll(ttname); -#endif /* OS2 */ - local = 0; - ckstrncpy(ttname,CTTNAM,TTNAMLEN); - } - setflow(); /* Set appropriate flow control */ - speed = ttgspd(); /* Get transmission speed. */ -#ifdef IKSD - } -#endif /* IKSD */ - -#ifdef ANYX25 /* All X.25 implementations */ -#ifndef IBMX25 /* except IBM have PAD support */ - initpad(); /* Initialize X.25 PAD */ -#endif /* IBMX25 */ -#endif /* ANYX25 */ - -#ifndef NOXFER - if (inibufs(SBSIZ,RBSIZ) < 0) /* Allocate packet buffers */ - fatal("Can't allocate packet buffers!"); -#ifndef NOCKSPEED - setprefix(prefixing); /* Set up control char prefixing */ -#endif /* NOCKSPEED */ -#endif /* NOXFER */ - -#ifndef NOICP - if (sstelnet -#ifdef IKSD - || inserver -#endif /* IKSD */ - ) { - int on = 1, x = 0; - extern int ckxech, ttnet, ttnproto, cmdmsk; -#ifdef SO_SNDBUF - extern int tcp_sendbuf; -#endif -#ifdef SO_RCVBUF - extern int tcp_recvbuf; -#endif -#ifdef SO_KEEPALIVE - extern int tcp_keepalive; -#endif -#ifdef SO_LINGER - extern int tcp_linger, tcp_linger_tmo; -#endif /* SO_LINGER */ -#ifdef SO_DONTROUTE - extern int tcp_dontroute; -#endif /* SO_DONTROUTE */ -#ifdef TCP_NODELAY - extern int tcp_nodelay; -#endif /* TCP_NODELAY */ -#ifdef IKSD - extern int iklogopen; -#endif /* IKSD */ - extern int ttmdm; - -#ifdef UNIX - if (isatty(0)) - fatal("Internet Kermit Service cannot be started at a terminal."); -#endif /* UNIX */ - - reliable = xreliable = SET_ON; /* IKSD has reliable connection */ -#ifndef VMS - flow = 0; /* No flow control needed */ -#endif /* VMS */ - bgset = 0; /* Not in background */ - nopush = 1; /* No external processes */ - parity = 0; /* 8 bits ... */ - cmdmsk = 0xff; /* all the way */ - cmask = 0xff; - -#ifdef IKSD - if (inserver) { /* If IKSD */ - doiksdinit(); /* Execute IKSD configuration file */ - while (tlevel > -1) - parser(1); /* (Ignore any file-xfer commands) */ - iksdcf = 1; /* IKSD c.f. has been processed */ - } - if (!iklogopen) (VOID) doiklog(); /* Open Kermit-specific log */ -#endif /* IKSD */ - -#ifdef UNIX - setbuf(stdout,NULL); /* Don't buffer the output */ - ckstrncpy(ttname,"0",TTNAMLEN); /* not "/dev/tty"... */ -#endif /* UNIX */ - local = 0; /* We are in remote mode */ - ckxech = 1; /* We will echo */ -#ifdef OS2 - nettype = NET_TCPB; /* So ttopen() treats the connection */ - mdmtyp = -nettype; /* as a network */ -#endif /* OS2 */ - debug(F100,"main about to call ttopen() inserver","",0); - if (ttopen(ttname,&local,mdmtyp,0) < 0) { /* Open comm channel */ - fatal("can't initialize i/o"); - } -#ifdef OS2 - local = 0; - network = 1; /* Does use networking code */ -#else /* OS2 */ - network = 0; /* Does not use networking code */ -#endif /* OS2 */ - ttmdm = -1; /* Does not use a modem */ - sstelnet = 1; /* Do server-side Telnet negotations */ - debug(F111,"MAIN","sstelnet",sstelnet); - ttnet = NET_TCPB; /* Network type is TCP sockets */ - ttnproto = NP_TELNET; /* Netword protocol is Telnet */ -#ifdef IKSDB - dbinit(); /* Initialize database record */ -#endif /* IKSDB */ -#ifndef OS2 -#ifdef CK_AUTHENTICATION - /* Before initializating Telnet/Rlogin negotiations, init Kerberos */ - ck_auth_init(ckgetpeer(),"","",0); -#endif /* CK_AUTHENTICATION */ - -#ifdef NON_BLOCK_IO - on = 1; - x = socket_ioctl(0,FIONBIO,&on); - debug(F101,"main FIONBIO","",x); -#endif /* NON_BLOCK_IO */ -#ifdef SO_OOBINLINE - on = 1; - x = setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)); - debug(F101,"main SO_OOBINLINE","",x); -#endif /* SO_OOBINLINE */ - -#ifndef NOTCPOPTS -#ifndef datageneral -#ifdef SOL_SOCKET -#ifdef TCP_NODELAY - no_delay(0,tcp_nodelay); -#endif /* TCP_NODELAY */ -#ifdef SO_KEEPALIVE - keepalive(0,tcp_keepalive); -#endif /* SO_KEEPALIVE */ -#ifdef SO_LINGER - ck_linger(0,tcp_linger, tcp_linger_tmo); -#endif /* SO_LINGER */ -#ifdef SO_DONTROUTE - dontroute(0,tcp_dontroute); -#endif /* SO_DONTROUTE */ -#ifdef SO_SNDBUF - sendbuf(0,tcp_sendbuf); -#endif /* SO_SNDBUF */ -#ifdef SO_RCVBUF - recvbuf(0,tcp_recvbuf); -#endif /* SO_RCVBUF */ -#endif /* SOL_SOCKET */ -#endif /* datageneral */ -#endif /* NOTCPOPTS */ - -#ifdef CK_SSL - if (ck_ssleay_is_installed()) { - if (!ssl_tn_init(SSL_SERVER)) { - if (bio_err != NULL) { - BIO_printf(bio_err,"do_ssleay_init() failed\r\n"); - ERR_print_errors(bio_err); - } else { - fflush(stderr); - fprintf(stderr,"do_ssleay_init() failed\r\n"); - ERR_print_errors_fp(stderr); - } - switch (ttnproto) { - case NP_SSL: - case NP_TLS: - case NP_SSL_TELNET: - case NP_TLS_TELNET: - doexit(BAD_EXIT,1); - } - /* otherwise we will continue to accept the connection */ - /* without SSL or TLS support unless required. */ - if ( TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) != TN_NG_MU ) - TELOPT_DEF_S_ME_MODE(TELOPT_START_TLS) = TN_NG_RF; - if ( TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) != TN_NG_MU ) - TELOPT_DEF_S_U_MODE(TELOPT_START_TLS) = TN_NG_RF; - if ( TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) != TN_NG_MU ) - TELOPT_DEF_C_ME_MODE(TELOPT_START_TLS) = TN_NG_RF; - if ( TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) != TN_NG_MU ) - TELOPT_DEF_C_U_MODE(TELOPT_START_TLS) = TN_NG_RF; - } else { - if ( ck_ssl_incoming(0) < 0 ) { - doexit(BAD_EXIT,1); - } - } - } -#endif /* CK_SSL */ - -#ifdef TNCODE - tn_ini(); /* Start Telnet negotiation now */ -#endif /* TNCODE */ -#endif /* OS2 */ - } - debug(F101,"main argc after prescan()","",argc); - - /* Now process any relevant environment variables */ - -#ifndef NODIAL - getdialenv(); /* Dialing */ -#ifdef NETCONN - ndinit(); /* Initialize network directory info */ - getnetenv(); /* Network directories */ -#endif /* NETCONN */ -#endif /* NODIAL */ - -#ifndef NOXFER -#ifdef CK_FAST - dofast(); /* By now FAST defaults should be OK */ -#endif /* CK_FAST */ -#endif /* NOXFER */ - -#ifndef NOCMDL - ikslogin(); /* IKSD Login and other stuff */ -#ifdef IKSD -#ifdef NT - if ( inserver ) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* NOCMDL */ - - if (howcalled == I_AM_SSHSUB) { - reliable = 1; /* We say the connection is reliable */ - xreliable = 1; /* And that we said it was */ - setreliable = 1; /* And pretend the "user" did too */ - xfinish = 1; /* For REMOTE HELP response */ - mdmtyp = 0; /* For ttopen() */ - ckstrncpy(ttname,"0",TTNAMLEN+1); /* Use file descriptor 0 */ - local = 0; /* And force remote mode */ - ttopen(ttname,&local,mdmtyp,0); /* Open the "connection" */ - sstate = 'x'; /* Initial state is Server */ - proto(); /* Enter protocol */ - doexit(GOOD_EXIT,xitsta); /* Exit when done */ - } - debug(F111,"howcalled",myname,howcalled); - -#ifdef NOCCTRAP - dotakeini(0); -#else /* NOCCTRAP */ - debug(F100,"main about to cc_execute","",0); - setint(); - cc_execute( ckjaddr(cmjbuf), dotakeini, failtakeini ); -#endif /* NOCCTRAP */ - - debug(F111,"main 2 cfilef",cmdfil,cfilef); - if (cmdfil[0]) { /* If we got one (see prescan())... */ -#ifdef NOCCTRAP - docmdfile(0); /* execute it. */ -#else /* NOCCTRAP */ - setint(); - cc_execute( ckjaddr(cmjbuf), docmdfile, failcmdfile ); -#endif /* NOCCTRAP */ - } -#ifndef OS2 /* Preserve name so we can delete it */ - *cmdfil = '\0'; /* Done, nullify the file name */ -#endif /* OS2 */ -#endif /* NOICP */ - -#ifndef NOCMDL -/* Look for a UNIX-style command line... */ - - what = W_NOTHING; - - debug(F101,"main argc","",argc); -#ifndef NOHELP - iniopthlp(); /* Initialize cmdline arg help */ -#endif /* NOHELP */ - if ( -#ifdef COMMENT - !cfilef && -#endif /* COMMENT */ - argc > 1) { /* Command line arguments? */ - sstate = (CHAR) cmdlin(); /* Yes, parse. */ -#ifdef NETCONN -#ifndef NOURL - if (haveurl) { /* Was a URL given? */ - dourl(); /* if so, do it. */ - } -#endif /* NOURL */ -#endif /* NETCONN */ -#ifndef NOXFER - zstate = sstate; /* Remember sstate around protocol */ - debug(F101,"main zstate","",zstate); -#endif /* NOXFER */ - -#ifndef NOLOCAL - if (cflg) { /* Connect first if requested */ - doconect(0,0); - if (ttchk() < 0) - dologend(); - cflg = 0; - } -#endif /* NOLOCAL */ - -#ifndef NOXFER - if (sstate) { -#ifndef NOLOCAL - if (displa) concb((char)escape); /* (for console "interrupts") */ -#endif /* NOLOCAL */ -#ifdef NOCCTRAP - docmdline(1); -#else /* NOCCTRAP */ - setint(); - cc_execute( ckjaddr(cmjbuf), docmdline, failcmdline ); -#endif /* NOCCTRAP */ - } -#endif /* NOXFER */ - -#ifndef NOICP -/* - If a command-line action argument was given and -S ("stay") was not given, - exit now. -*/ - if ((cflg || cnflg || zstate) && !stayflg) -#endif /* NOICP */ - doexit(GOOD_EXIT,xitsta); /* Exit with good status */ - -#ifndef NOLOCAL -#ifndef NOICP - if (local) { -#ifdef NETCONN - if ((cflg || cnflg) && tn_exit && ttchk() < 0) - doexit(GOOD_EXIT,xitsta); /* Exit with good status */ -#endif /* NETCONN */ - if (exitonclose && !network && - (carrier != CAR_OFF && (ttgmdm() & BM_DCD) == 0)) - doexit(GOOD_EXIT,xitsta); /* Exit with good status */ - if (exitonclose && network && ttchk() < 0) - doexit(GOOD_EXIT,xitsta); /* Exit with good status */ - } -#endif /* NOICP */ -#endif /* NOLOCAL */ - } -#endif /* NOCMDL */ - -#ifdef NOICP /* No interactive command parser */ -#ifndef NOCMDL - else { - - /* Command-line-only version */ - fatal("?No command-line options given - type 'kermit -h' for help"); - } -#else /* Neither one! */ - sstate = 'x'; - justone = 0; - proto(); /* So go into server mode */ - doexit(GOOD_EXIT,xitsta); /* exit with good status */ - -#endif /* NOCMDL */ -#else /* not NOICP */ -/* - If no action requested on command line, or if -S ("stay") was included, - enter the interactive command parser. -*/ - if (!clcmds) - herald(); /* Display program herald. */ - -#ifdef NOCCTRAP - debug(F100,"main NOCCTRAP setting interrupt trap","",0); - setint(); /* Set up command interrupt traps */ - doicp(NULL); -#else /* NOCCTRAP */ - while (1) { - debug(F100,"main setting interrupt trap","",0); - setint(); /* Set up command interrupt traps */ - if (!cc_execute(ckjaddr(cmjbuf), doicp, failicp)) - break; - } -#endif /* NOCCTRAP */ -#endif /* NOICP */ -#ifndef MAINISVOID - return(1); -#endif /* MAINISVOID */ -} - -#ifdef DYNAMIC -/* Allocate file i/o buffers */ - -char *zinbuffer = NULL, *zoutbuffer = NULL; - -int -getiobs() { - zinbuffer = (char *)malloc(INBUFSIZE); - if (!zinbuffer) return(-1); - zoutbuffer = (char *)malloc(zobufsize); - debug(F101,"zoutbuffer malloc","",zobufsize); - if (!zoutbuffer) return(-1); - debug(F100,"getiobs ok","",0); - return(0); -} -#endif /* DYNAMIC */ diff --git a/.pc/060_speeling.patch/.timestamp b/.pc/060_speeling.patch/.timestamp deleted file mode 100644 index e69de29..0000000 diff --git a/.pc/060_speeling.patch/ckcftp.c b/.pc/060_speeling.patch/ckcftp.c deleted file mode 100644 index d8d9ddd..0000000 --- a/.pc/060_speeling.patch/ckcftp.c +++ /dev/null @@ -1,17126 +0,0 @@ -/* C K C F T P -- FTP Client for C-Kermit */ - -char *ckftpv = "FTP Client, 8.0.226, 7 Jan 2004"; - -/* - Authors: - Jeffrey E Altman - Secure Endpoints Inc., New York City - Frank da Cruz , - The Kermit Project, Columbia University. - - Copyright (C) 2000, 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. - - Portions of conditionally included code Copyright Regents of the - University of California and The Stanford SRP Authentication Project; - see notices below. -*/ - -/* - Pending... - - . Implement recursive NLST downloads by trying to CD to each filename. - If it works, it's a directory; if not, it's a file -- GET it. But - that won't work with servers like wu-ftpd that don't send directory - names. Recursion with MLSD is done. - - . Make syslog entries for session? Files? - - . Messages are printed to stdout and stderr in random fashion. We should - either print everything to stdout, or else be systematic about when - to use stderr. - - . Implement mail (MAIL, MLFL, MSOM, etc) if any servers support it. - - . Adapt to VMS. Big job because of its record-oriented file system. - RMS programmer required. There are probably also some VMS TCP/IP - product-specific wrinkles, e.g. attribute preservation in VMS-to-VMS - transfers using special options for Multinet or other FTP servers - (find out about STRU VMS). -*/ - -/* - Quick FTP command reference: - - RFC765 (1980) and earlier: - MODE S(tream), B(lock), C(ompressed) - STRU F(ILE), R(ECORD), P(AGE) - TYPE A(SCII) , E(BCDIC) , I(MAGE), L(OCAL) - PORT - Port - PASV - Passive mode - USER - User - PASS - Password - ACCT - Account - CWD - Change Working Directory - REIN - Logout but not disconnect - QUIT - Bye - RETR - Retreive - STOR - Store - APPE - Append - ALLO - Allocate - REST - Restart - RNFR - Rename from - RNTO - Rename to - ABOR - Cancel - DELE - Delete - LIST - Directory - NLST - Name List - SITE - Site parameters or commands - STAT - Status - HELP - Help - NOOP - Noop - - RFC959 (1985): - CDUP - Change to Parent Directory - SMNT - Structure Mount - STOU - Store Unique - RMD - Remove Directory - MKD - Make Directory - PWD - Print Directory - SYST - System - - RFC2389 (1998): - FEAT - List Features (done) - OPTS - Send options (done) - - RFC2640 (1999): - LANG - Specify language for messages (not done) - - Pending (Internet Drafts): - SIZE - File size (done) - MDTM - File modification date-time (done) - MLST - File name and attribute list (single file) (not done) - MLSD - File list with attributes (multiple files) (done) - MAIL, MLFL, MSOM - mail delivery (not done) - - Alphabetical syntax list: - ABOR - ACCT - ALLO [ R ] - APPE - CDUP - CWD - DELE - FEAT - HELP [ ] - LANG [ ] - LIST [ ] - MKD - MLSD [ ] - MLST [ ] - MODE - NLST [ ] - NOOP - OPTS [ ] - PASS - PASV - PORT - PWD - QUIT - REIN - REST - RETR - RMD - RNFR - RNTO - SITE - SIZE - SMNT - STAT [ ] - STOR - STOU - STRU - SYST - TYPE - USER -*/ -#include "ckcsym.h" /* Standard includes */ -#include "ckcdeb.h" - -#ifndef NOFTP /* NOFTP = no FTP */ -#ifndef SYSFTP /* SYSFTP = use external ftp client */ -#ifdef TCPSOCKET /* Build only if TCP/IP included */ -#define CKCFTP_C - -/* Note: much of the following duplicates what was done in ckcdeb.h */ -/* but let's not mess with it unless it causes trouble. */ - -#ifdef CK_ANSIC -#include -#else /* CK_ANSIC */ -#include -#endif /* CK_ANSIC */ -#include -#ifdef OS2 -#ifdef OS2ONLY -#include -#endif /* OS2ONLY */ -#include "ckowin.h" -#include "ckocon.h" -#endif /* OS2 */ -#ifndef ZILOG -#ifdef NT -#include -#ifdef NTSIG -extern int TlsIndex; -#endif /* NTSIG */ -#else /* NT */ -#include -#endif /* NT */ -#else -#include -#endif /* ZILOG */ -#include "ckcsig.h" -#include -#include -#include -#ifndef NOTIMEH -#include -#endif /* NOTIMEH */ -#ifndef EPIPE -#define EPIPE 32 /* Broken pipe error */ -#endif /* EPIPE */ - -/* Kermit includes */ - -#include "ckcasc.h" -#include "ckcker.h" -#include "ckucmd.h" -#include "ckuusr.h" -#include "ckcnet.h" /* Includes ckctel.h */ -#include "ckctel.h" /* (then why include it again?) */ -#include "ckcxla.h" - -/* - How to get the struct timeval definition so we can call select(). The - xxTIMEH symbols are defined in ckcdeb.h, overridden in various makefile - targets. The problem is: maybe we have already included some header file - that defined struct timeval, and maybe we didn't. If we did, we don't want - to include another header file that defines it again or the compilation will - fail. If we didn't, we have to include the header file where it's defined. - But in some cases even that won't work because of strict POSIX constraints - or somesuch, or because this introduces other conflicts (e.g. struct tm - multiply defined), in which case we have to define it ourselves, but this - can work only if we didn't already encounter a definition. -*/ -#ifndef DCLTIMEVAL -#ifdef SV68R3V6 -#define DCLTIMEVAL -#else -#ifdef SCO234 -#define DCLTIMEVAL -#endif /* SCO234 */ -#endif /* SV68R3V6 */ -#endif /* DCLTIMEVAL */ - -#ifdef DCLTIMEVAL -/* Also maybe in some places the elements must be unsigned... */ -struct timeval { - long tv_sec; - long tv_usec; -}; -#ifdef COMMENT -/* Currently we don't use this... */ -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; -#endif /* COMMENT */ -#else /* !DCLTIMEVAL */ -#ifndef NOSYSTIMEH -#ifdef SYSTIMEH -#include -#endif /* SYSTIMEH */ -#endif /* NOSYSTIMEH */ -#ifndef NOSYSTIMEBH -#ifdef SYSTIMEBH -#include -#endif /* SYSTIMEBH */ -#endif /* NOSYSTIMEBH */ -#endif /* DCLTIMEVAL */ - -#include -#include -#include -#ifdef HAVE_STDLIB_H -#include -#endif /* HAVE_STDLIB_H */ - -#ifndef NOSETTIME -#ifdef COMMENT -/* This section moved to ckcdeb.h */ -#ifdef POSIX -#define UTIMEH -#else -#ifdef HPUX9 -#define UTIMEH -#else -#ifdef OS2 -#define SYSUTIMEH -#endif /* OS2 */ -#endif /* HPUX9 */ -#endif /* POSIX */ -#endif /* COMMENT */ - -#ifdef SYSUTIMEH -#include -#else -#ifdef UTIMEH -#include -#define SYSUTIMEH -#endif /* UTIMEH */ -#endif /* SYSUTIMEH */ -#endif /* NOSETTIME */ - -#ifndef SCO_OSR504 -#ifdef SELECT_H -#include -#endif /* SELECT_H */ -#endif /* SCO_OSR504 */ - -/* select() dialects... */ - -#ifdef UNIX -#define BSDSELECT /* BSD select() syntax/semantics */ -#else -#ifdef OS2 /* OS/2 or Win32 */ -#ifdef NT -#define BSDSELECT -#else /* NT */ -#define IBMSELECT -#endif /* NT */ -#endif /* OS2 */ -#endif /* UNIX */ - -/* Other select() peculiarities */ - -#ifdef HPUX -#ifndef HPUX10 /* HP-UX 9.xx and earlier */ -#ifndef HPUX1100 -/* The three interior args to select() are (int *) rather than (fd_set *) */ -#ifndef INTSELECT -#define INTSELECT -#endif /* INTSELECT */ -#endif /* HPUX1100 */ -#endif /* HPUX10 */ -#endif /* HPUX */ - -#ifdef CK_SOCKS /* SOCKS Internet relay package */ -#ifdef CK_SOCKS5 /* SOCKS 5 */ -#define accept SOCKSaccept -#define bind SOCKSbind -#define connect SOCKSconnect -#define getsockname SOCKSgetsockname -#define listen SOCKSlisten -#else /* Not SOCKS 5 */ -#define accept Raccept -#define bind Rbind -#define connect Rconnect -#define getsockname Rgetsockname -#define listen Rlisten -#endif /* CK_SOCKS5 */ -#endif /* CK_SOCKS */ - -#ifndef NOHTTP -extern char * tcp_http_proxy; /* Name[:port] of http proxy server */ -extern int tcp_http_proxy_errno; -extern char * tcp_http_proxy_user; -extern char * tcp_http_proxy_pwd; -extern char * tcp_http_proxy_agent; -#define HTTPCPYL 1024 -static char proxyhost[HTTPCPYL]; -#endif /* NOHTTP */ -int ssl_ftp_proxy = 0; /* FTP over SSL/TLS Proxy Server */ - -/* Feature selection */ - -#ifndef USE_SHUTDOWN -/* - We don't use shutdown() because (a) we always call it just before close() - so it's redundant and unnecessary, and (b) it introduces a long pause on - some platforms like SV/68 R3. -*/ -/* #define USE_SHUTDOWN */ -#endif /* USE_SHUTDOWN */ - -#ifndef NORESEND -#ifndef NORESTART /* Restart / recover */ -#ifndef FTP_RESTART -#define FTP_RESTART -#endif /* FTP_RESTART */ -#endif /* NORESTART */ -#endif /* NORESEND */ - -#ifndef NOUPDATE /* Update mode */ -#ifndef DOUPDATE -#define DOUPDATE -#endif /* DOUPDATE */ -#endif /* NOUPDATE */ - -#ifndef UNICODE /* Unicode required */ -#ifndef NOCSETS /* for charset translation */ -#define NOCSETS -#endif /* NOCSETS */ -#endif /* UNICODE */ - -#ifndef OS2 -#ifndef HAVE_MSECS /* Millisecond timer */ -#ifdef UNIX -#ifdef GFTIMER -#define HAVE_MSECS -#endif /* GFTIMER */ -#endif /* UNIX */ -#endif /* HAVE_MSECS */ -#endif /* OS2 */ - -#ifdef PIPESEND /* PUT from pipe */ -#ifndef PUTPIPE -#define PUTPIPE -#endif /* PUTPIPE */ -#endif /* PIPESEND */ - -#ifndef NOSPL /* PUT from array */ -#ifndef PUTARRAY -#define PUTARRAY -#endif /* PUTARRAY */ -#endif /* NOSPL */ - -/* Security... */ - -#ifdef CK_SRP -#define FTP_SRP -#endif /* CK_SRP */ - -#ifdef CK_KERBEROS -#ifdef KRB4 -/* - There is a conflict between the Key Schedule formats used internally - within the standalone MIT KRB4 library and that used by Eric Young - in OpenSSL and his standalone DES library. Therefore, KRB4 FTP AUTH - cannot be supported when either of those two packages are used. -*/ -#ifdef KRB524 -#define FTP_KRB4 -#else /* KRB524 */ -#ifndef CK_SSL -#ifndef LIBDES -#define FTP_KRB4 -#endif /* LIBDES */ -#endif /* CK_SSL */ -#endif /* KRB524 */ -#endif /* KRB4 */ -#ifdef KRB5 -#ifndef HEIMDAL -#define FTP_GSSAPI -#endif /* HEIMDAL */ -#endif /* KRB5 */ -#endif /* CK_KERBEROS */ - -/* FTP_SECURITY is defined if any of the above is selected */ -#ifndef FTP_SECURITY -#ifdef FTP_GSSAPI -#define FTP_SECURITY -#else -#ifdef FTP_KRB4 -#define FTP_SECURITY -#else -#ifdef FTP_SRP -#define FTP_SECURITY -#else -#ifdef CK_SSL -#define FTP_SECURITY -#endif /* CK_SSL */ -#endif /* FTP_SRP */ -#endif /* FTP_KRB4 */ -#endif /* FTP_GSSAPI */ -#endif /* FTP_SECURITY */ - -#ifdef CK_DES -#ifdef CK_SSL -#ifndef LIBDES -#define LIBDES -#endif /* LIBDES */ -#endif /* CK_SSL */ -#endif /* CK_DES */ - -#ifdef CRYPT_DLL -#ifndef LIBDES -#define LIBDES -#endif /* LIBDES */ -#endif /* CRYPT_DLL */ - -#ifdef FTP_KRB4 -#define des_cblock Block -#define des_key_schedule Schedule -#ifdef KRB524 -#ifdef NT -#define _WINDOWS -#endif /* NT */ -#include "kerberosIV/krb.h" -#else /* KRB524 */ -#ifdef SOLARIS -#ifndef sun -/* For some reason lost in history the Makefile Solaris targets have -Usun */ -#define sun -#endif /* sun */ -#endif /* SOLARIS */ -#include "krb.h" -#define krb_get_err_text_entry krb_get_err_text -#endif /* KRB524 */ -#endif /* FTP_KRB4 */ - -#ifdef CK_SSL -#ifdef FTP_KRB4 -#ifndef HEADER_DES_H -#define HEADER_DES_H -#endif /* HEADER_DES_H */ -#endif /* FTP_KRB4 */ -#include "ck_ssl.h" -#endif /* CK_SSL */ - -#ifdef FTP_SRP -#ifdef HAVE_PWD_H -#include "pwd.h" -#endif /* HAVE_PWD_H */ -#include "t_pwd.h" -#include "t_client.h" -#include "krypto.h" -#endif /* FTP_SRP */ - -#ifdef FTP_GSSAPI -#include -/* - Need to include the krb5 file, because we're doing manual fallback - from the v2 mech to the v1 mech. Once there's real negotiation, - we can be generic again. -*/ -#include -#include -static gss_ctx_id_t gcontext; -#endif /* FTP_GSSAPI */ - -#ifdef OS2 -#ifdef FTP_SRP -#define MAP_KRYPTO -#ifdef SRPDLL -#define MAP_SRP -#endif /* SRPDLL */ -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 -#define MAP_KRB4 -#ifdef CK_ENCRYPTION -#define MAP_DES -#endif /* CK_ENCRYPTION */ -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI -#define MAP_GSSAPI -#define GSS_OIDS -#endif /* FTP_GSSAPI */ -#include "ckoath.h" - -extern int k95stdout, wherex[], wherey[]; -extern unsigned char colorcmd; -#endif /* OS2 */ - -#ifdef FTP_KRB4 -static char ftp_realm[REALM_SZ + 1]; -static KTEXT_ST ftp_tkt; -#ifdef OS2 -static LEASH_CREDENTIALS ftp_cred; -#else /* OS2 */ -static CREDENTIALS ftp_cred; -#endif /* OS2 */ -static MSG_DAT ftp_msg_data; -static des_key_schedule ftp_sched; -static int foo[4] = {99,99,99,99}; -#endif /* FTP_KRB4 */ - -/* getreply() function codes */ - -#define GRF_AUTH 1 /* Reply to AUTH command */ -#define GRF_FEAT 2 /* Reply to FEAT command */ - -/* Operational definitions */ - -#define DEF_VBM 0 /* Default verbose mode */ -/* #define SETVBM */ /* (see getreply) */ - -#define URL_ONEFILE /* GET, not MGET, for FTP URL */ - -#define FTP_BUFSIZ 10240 /* Max size for FTP cmds & replies */ -#define SRVNAMLEN 32 /* Max length for server type name */ -#define PWDSIZ 256 -#define PASSBUFSIZ 256 -#define PROMPTSIZ 256 - -#ifndef MGETMAX /* Max operands for MGET command */ -#define MGETMAX 1000 -#endif /* MGETMAX */ - -#ifdef FTP_SRP -#define FUDGE_FACTOR 100 -#endif /* FTP_SRP */ - -/* - Amount of growth from cleartext to ciphertext. krb_mk_priv adds this - number bytes. Must be defined for each auth type. - GSSAPI appears to add 52 bytes, but I'm not sure it is a constant--hartmans - 3DES requires 56 bytes. Lets use 96 just to be sure. -*/ -#ifdef FTP_GSSAPI -#ifndef FUDGE_FACTOR -#define FUDGE_FACTOR 96 -#endif /* FUDGE_FACTOR */ -#endif /* FTP_GSSAPI */ - -#ifdef FTP_KRB4 -#ifndef FUDGE_FACTOR -#define FUDGE_FACTOR 32 -#endif /* FUDGE_FACTOR */ -#endif /* FTP_KRB4 */ - -#ifndef FUDGE_FACTOR /* In case no auth types define it */ -#define FUDGE_FACTOR 0 -#endif /* FUDGE_FACTOR */ - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif /* MAXHOSTNAMELEN */ -#define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1) - -/* Fascist compiler toadying */ - -#ifndef SENDARG2TYPE -#ifdef COMMENT /* Might be needed here and there */ -#define SENDARG2TYPE const char * -#else -#define SENDARG2TYPE char * -#endif /* COMMENT */ -#endif /* SENDARG2TYPE */ - -/* Common text messages */ - -static char *nocx = "?No FTP control connection\n"; - -static char *fncnam[] = { - "rename", "overwrite", "backup", "append", "discard", "ask", "update", - "dates-differ", "" -}; - -/* Macro definitions */ - -/* Used to speed up text-mode PUTs */ -#define zzout(fd,c) \ -((fd<0)?(-1):((nout>=ucbufsiz)?(zzsend(fd,c)):(ucbuf[nout++]=c))) - -#define CHECKCONN() if(!connected){printf(nocx);return(-9);} - -/* Externals */ - -#ifdef CK_URL -extern struct urldata g_url; -#endif /* CK_URL */ - -#ifdef DYNAMIC -extern char *zinbuffer, *zoutbuffer; /* Regular Kermit file i/o */ -#else -extern char zinbuffer[], zoutbuffer[]; -#endif /* DYNAMIC */ -extern char *zinptr, *zoutptr; -extern int zincnt, zoutcnt, zobufsize, fncact; - -#ifdef CK_TMPDIR -extern int f_tmpdir; /* Directory changed temporarily */ -extern char savdir[]; /* For saving current directory */ -extern char * dldir; -#endif /* CK_TMPDIR */ - -extern char * rfspec, * sfspec, * srfspec, * rrfspec; /* For WHERE command */ - -extern xx_strp xxstring; -extern struct keytab onoff[], txtbin[], rpathtab[]; -extern int nrpathtab, xfiletype, patterns, gnferror, moving, what, pktnum; -extern int success, nfils, sndsrc, quiet, nopush, recursive, inserver, binary; -extern int filepeek, nscanfile, fsecs, xferstat, xfermode, lastxfer, tsecs; -extern int backgrd, spackets, rpackets, spktl, rpktl, xaskmore, cmd_rows; -extern int nolinks, msgflg, keep; -extern long fsize, ffc, tfc, filcnt, xfsecs, tfcps, cps, oldcps; -#ifdef GFTIMER -extern CKFLOAT fptsecs, fpfsecs, fpxfsecs; -#else -extern long xfsecs; -#endif /* GFTIMER */ - -extern char filnam[], * filefile, myhost[]; -extern char * snd_move, * rcv_move, * snd_rename, * rcv_rename; -extern int g_skipbup, skipbup, sendmode; -extern int g_displa, fdispla, displa; - -#ifdef LOCUS -extern int locus, autolocus; -#endif /* LOCUS */ - -#ifndef NOCSETS -extern int nfilc, dcset7, dcset8, fileorder; -extern struct csinfo fcsinfo[]; -extern struct keytab fcstab[]; -extern int fcharset; -#endif /* NOCSETS */ - -extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */ -extern char sndnbefore[], sndnafter[], *rcvexcept[]; -extern CHAR feol; -extern long sendstart, sndsmaller, sndlarger, rs_len; - -extern char * remdest; -extern int remfile, remappd, rempipe; - -#ifndef NOSPL -extern int cmd_quoting; -#ifdef PUTARRAY -extern int sndxlo, sndxhi, sndxin; -extern char sndxnam[]; -extern char **a_ptr[]; /* Array pointers */ -extern int a_dim[]; /* Array dimensions */ -#endif /* PUTARRAY */ -#endif /* NOSPL */ - -#ifndef NOMSEND /* MPUT and ADD SEND-LIST lists */ -extern char *msfiles[]; -extern int filesinlist; -extern struct filelist * filehead; -extern struct filelist * filetail; -extern struct filelist * filenext; -extern int addlist; -extern char fspec[]; /* Most recent filespec */ -extern int fspeclen; /* Length of fspec[] buffer */ -#endif /* NOMSEND */ - -extern int pipesend; -#ifdef PIPESEND -extern char * sndfilter, * rcvfilter; -#endif /* PIPESEND */ - -#ifdef CKROOT -extern int ckrooterr; -#endif /* CKROOT */ - -#ifdef KRB4 -extern int krb4_autoget; -_PROTOTYP(char * ck_krb4_realmofhost,(char *)); -#endif /* KRB4 */ - -#ifdef KRB5 -extern int krb5_autoget; -extern int krb5_d_no_addresses; -_PROTOTYP(char * ck_krb5_realmofhost,(char *)); -#endif /* KRB5 */ - -#ifdef DCMDBUF -extern char *atmbuf; /* Atom buffer (malloc'd) */ -extern char *cmdbuf; /* Command buffer (malloc'd) */ -extern char *line; /* Big string buffer #1 */ -extern char *tmpbuf; /* Big string buffer #2 */ -#else -extern char atmbuf[]; /* The same, but static */ -extern char cmdbuf[]; -extern char line[]; -extern char tmpbuf[]; -#endif /* DCMDBUF */ - -extern char * cmarg, * cmarg2, ** cmlist; /* For setting up file lists */ - -/* Public variables declared here */ - -#ifdef NOXFER -int ftpget = 1; /* GET/PUT/REMOTE orientation FTP */ -#else -int ftpget = 2; /* GET/PUT/REMOTE orientation AUTO */ -#endif /* NOXFER */ -int ftpcode = -1; /* Last FTP response code */ -int ftp_cmdlin = 0; /* FTP invoked from command line */ -int ftp_fai = 0; /* FTP failure count */ -int ftp_deb = 0; /* FTP debugging */ -int ftp_dis = -1; /* FTP display style */ -int ftp_log = 1; /* FTP Auto-login */ -int sav_log = -1; -int ftp_action = 0; /* FTP action from command line */ -int ftp_dates = 1; /* Set file dates from server */ - -char ftp_reply_str[FTP_BUFSIZ] = ""; /* Last line of previous reply */ -char ftp_srvtyp[SRVNAMLEN] = { NUL, NUL }; /* Server's system type */ -char ftp_user_host[MAX_DNS_NAMELEN]= ""; /* FTP hostname specified by user */ -char * ftp_host = NULL; /* FTP hostname */ -char * ftp_logname = NULL; /* FTP username */ -char * ftp_rdir = NULL; /* Remote directory from cmdline */ -char * ftp_apw = NULL; /* Anonymous password */ - -/* Definitions and typedefs needed for prototypes */ - -#define sig_t my_sig_t -#define sigtype SIGTYP -typedef sigtype (*sig_t)(); - -/* Static global variables */ - -static char ftpsndbuf[FTP_BUFSIZ+64]; - -static char * fts_sto = NULL; - -static int ftpsndret = 0; -static struct _ftpsnd { - sig_t oldintr, oldintp; - int reply; - int incs, - outcs; - char * cmd, * local, * remote; - int bytes; - int restart; - int xlate; - char * lmode; -} ftpsnd; - -/* - This is just a first stab -- these strings should match how the - corresponding FTP servers identify themselves. -*/ -#ifdef UNIX -static char * myostype = "UNIX"; -#else -#ifdef VMS -/* not yet... */ -static char * myostype = "VMS"; -#else -#ifdef OS2 -#ifdef NT -static char * myostype = "WIN32"; -#else -static char * myostype = "OS/2"; -#endif /* NT */ -#else -static char * myostype = "UNSUPPORTED"; -#endif /* OS2 */ -#endif /* VMS */ -#endif /* UNIX */ - -static int noinit = 0; /* Don't send REST, STRU, MODE */ -static int alike = 0; /* Client/server like platforms */ -static int local = 1; /* Shadows Kermit global 'local' */ -static int dout = -1; /* Data connection file descriptor */ -static int dpyactive = 0; /* Data transfer is active */ -static int globaldin = -1; /* Data connection f.d. */ -static int out2screen = 0; /* GET output is to screen */ -static int forcetype = 0; /* Force text or binary mode */ -static int cancelfile = 0; /* File canceled */ -static int cancelgroup = 0; /* Group canceled */ -static int anonymous = 0; /* Logging in as anonymous */ -static int loggedin = 0; /* Logged in (or not) */ -static int puterror = 0; /* What to do on PUT error */ -static int geterror = 0; /* What to do on GET error */ -static int rfrc = 0; /* remote_files() return code */ -static int okrestart = 0; /* Server understands REST */ -static int printlines = 0; /* getreply()should print data lines */ -static int haveurl = 0; /* Invoked by command-line FTP URL */ -static int mdtmok = 1; /* Server supports MDTM */ -static int sizeok = 1; -static int featok = 1; -static int mlstok = 1; -static int stouarg = 1; -static int typesent = 0; -static int havesigint = 0; -static long havetype = 0; -static long havesize = -1L; -static char * havemdtm = NULL; -static int mgetmethod = 0; /* NLST or MLSD */ -static int mgetforced = 0; - -static int i, /* j, k, */ x, y, z; /* Volatile temporaries */ -static int c0, c1; /* Temp variables for characters */ - -static char putpath[CKMAXPATH+1] = { NUL, NUL }; -static char asnambuf[CKMAXPATH+1] = { NUL, NUL }; - -#define RFNBUFSIZ 4096 /* Remote filename buffer size */ - -static unsigned int maxbuf = 0, actualbuf = 0; -static CHAR *ucbuf = NULL; -static int ucbufsiz = 0; -static unsigned int nout = 0; /* Number of chars in ucbuf */ - -static jmp_buf recvcancel; -static jmp_buf sendcancel; -static jmp_buf ptcancel; -static jmp_buf jcancel; -static int ptabflg = 0; - -/* Protection level symbols */ - -#define FPL_CLR 1 /* Clear */ -#define FPL_SAF 2 /* Safe */ -#define FPL_PRV 3 /* Private */ -#define FPL_CON 4 /* Confidential */ - -/* Symbols for file types returned by MLST/MLSD */ - -#define FTYP_FILE 1 /* Regular file */ -#define FTYP_DIR 2 /* Directory */ -#define FTYP_CDIR 3 /* Current directory */ -#define FTYP_PDIR 4 /* Parent directory */ - -/* File type symbols keyed to the file-type symbols from ckcker.h */ - -#define FTT_ASC XYFT_T /* ASCII (text) */ -#define FTT_BIN XYFT_B /* Binary (image) */ -#define FTT_TEN XYFT_X /* TENEX (TOPS-20) */ - -/* Server feature table - sfttab[0] > 0 means server supports FEAT and OPTS */ - -static int sfttab[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; - -#define SFT_AUTH 1 /* FTP server feature codes */ -#define SFT_LANG 2 -#define SFT_MDTM 3 -#define SFT_MLST 4 -#define SFT_PBSZ 5 -#define SFT_PROT 6 -#define SFT_REST 7 -#define SFT_SIZE 8 -#define SFT_TVFS 9 -#define SFT_UTF8 10 - -#define CNV_AUTO 2 /* FTP filename conversion */ -#define CNV_CNV 1 -#define CNV_LIT 0 - -/* SET FTP values */ - -static int /* SET FTP values... */ - ftp_aut = 1, /* Auto-authentication */ -#ifdef FTP_SECURITY - ftp_cry = 1, /* Auto-encryption */ - ftp_cfw = 0, /* Credential forwarding */ -#endif /* FTP_SECURITY */ - ftp_cpl = FPL_CLR, /* Command protection level */ - ftp_dpl = FPL_CLR, /* Data protection level */ -#ifdef FTP_PROXY - ftp_prx = 0, /* Use proxy */ -#endif /* FTP_PROXY */ - sav_psv = -1, /* For saving passive mode */ - ftp_psv = 1, /* Passive mode */ - ftp_spc = 1, /* Send port commands */ - ftp_typ = FTT_ASC, /* Type */ - get_auto = 1, /* Automatic type switching for GET */ - tenex = 0, /* Type is Tenex */ - ftp_usn = 0, /* Unique server names */ - ftp_prm = 0, /* Permissions */ - ftp_cnv = CNV_AUTO, /* Filename conversion (2 = auto) */ - ftp_vbm = DEF_VBM, /* Verbose mode */ - ftp_vbx = DEF_VBM, /* Sticky version of same */ - ftp_err = 0, /* Error action */ - ftp_fnc = -1; /* Filename collision action */ - -#ifdef CK_SSL -static int ftp_bug_use_ssl_v2 = 0; /* use SSLv2 for AUTH SSL */ -#endif /* CK_SSL */ - -static int -#ifdef NOCSETS - ftp_csr = -1, /* Remote (server) character set */ -#else - ftp_csr = FC_UTF8, -#endif /* NOCSETS */ - ftp_xla = 0; /* Character-set translation on/off */ -int - ftp_csx = -1, /* Remote charset currently in use */ - ftp_csl = -1; /* Local charset currently in use */ - -static int g_ftp_typ = FTT_ASC; /* For saving and restoring ftp_typ */ - -char * ftp_nml = NULL; /* /NAMELIST */ -char * ftp_tmp = NULL; /* Temporary string */ -static char * ftp_acc = NULL; /* Account string */ -static char * auth_type = NULL; /* Authentication type */ -static char * srv_renam = NULL; /* Server-rename string */ -FILE * fp_nml = NULL; /* Namelist file pointer */ - -static int csocket = -1; /* Control socket */ -static int connected = 0; /* Connected to FTP server */ -static short ftp_port = 0; /* FTP port */ -#ifdef FTPHOST -static int hostcmd = 0; /* Has HOST command been sent */ -#endif /* FTPHOST */ -static int form, mode, stru, bytesize, curtype = FTT_ASC; -static char bytename[8]; - -/* For parsing replies to FTP server command */ -static char *reply_parse, reply_buf[FTP_BUFSIZ], *reply_ptr; - -#ifdef FTP_PROXY -static int proxy, unix_proxy -#endif /* FTP_PROXY */ - -static char pasv[64]; /* Passive-mode port */ -static int passivemode = 0; -static int sendport = 0; -static int servertype = 0; /* FTP server's OS type */ - -static int testing = 0; -static char ftpcmdbuf[FTP_BUFSIZ]; - -/* Macro definitions */ - -#define UC(b) ckitoa(((int)b)&0xff) -#define nz(x) ((x) == 0 ? 1 : (x)) - -/* Command tables and definitions */ - -#define FTP_ACC 1 /* FTP command keyword codes */ -#define FTP_APP 2 -#define FTP_CWD 3 -#define FTP_CHM 4 -#define FTP_CLS 5 -#define FTP_DEL 6 -#define FTP_DIR 7 -#define FTP_GET 8 -#define FTP_IDL 9 -#define FTP_MDE 10 -#define FTP_MDI 11 -#define FTP_MGE 12 -#define FTP_MKD 13 -#define FTP_MOD 14 -#define FTP_MPU 15 -#define FTP_OPN 16 -#define FTP_PUT 17 -#define FTP_PWD 18 -#define FTP_RGE 19 -#define FTP_REN 20 -#define FTP_RES 21 -#define FTP_HLP 22 -#define FTP_RMD 23 -#define FTP_STA 24 -#define FTP_SIT 25 -#define FTP_SIZ 26 -#define FTP_SYS 27 -#define FTP_UMA 28 -#define FTP_GUP 29 -#define FTP_USR 30 -#define FTP_QUO 31 -#define FTP_TYP 32 -#define FTP_FEA 33 -#define FTP_OPT 34 -#define FTP_CHK 35 -#define FTP_VDI 36 -#define FTP_ENA 37 -#define FTP_DIS 38 - -struct keytab gprtab[] = { /* GET-PUT-REMOTE keywords */ - { "auto", 2, 0 }, - { "ftp", 1, 0 }, - { "kermit", 0, 0 } -}; - -static struct keytab qorp[] = { /* QUIT or PROCEED keywords */ - { "proceed", 0, 0 }, /* 0 = proceed */ - { "quit", 1, 0 } /* 1 = quit */ -}; - -static struct keytab ftpcmdtab[] = { /* FTP command table */ - { "account", FTP_ACC, 0 }, - { "append", FTP_APP, 0 }, - { "bye", FTP_CLS, 0 }, - { "cd", FTP_CWD, 0 }, - { "cdup", FTP_GUP, 0 }, - { "check", FTP_CHK, 0 }, - { "chmod", FTP_CHM, 0 }, - { "close", FTP_CLS, 0 }, - { "cwd", FTP_CWD, CM_INV }, - { "delete", FTP_MDE, 0 }, - { "directory", FTP_DIR, 0 }, - { "disable", FTP_DIS, 0 }, - { "enable", FTP_ENA, 0 }, - { "features", FTP_FEA, 0 }, - { "get", FTP_GET, 0 }, - { "help", FTP_HLP, 0 }, - { "idle", FTP_IDL, 0 }, - { "login", FTP_USR, CM_INV }, - { "mdelete", FTP_MDE, CM_INV }, - { "mget", FTP_MGE, 0 }, - { "mkdir", FTP_MKD, 0 }, - { "modtime", FTP_MOD, 0 }, - { "mput", FTP_MPU, 0 }, - { "open", FTP_OPN, 0 }, - { "opt", FTP_OPT, CM_INV|CM_ABR }, - { "opts", FTP_OPT, CM_INV }, - { "options", FTP_OPT, 0 }, - { "put", FTP_PUT, 0 }, - { "pwd", FTP_PWD, 0 }, - { "quit", FTP_CLS, CM_INV }, - { "quote", FTP_QUO, 0 }, - { "reget", FTP_RGE, 0 }, - { "rename", FTP_REN, 0 }, - { "reset", FTP_RES, 0 }, - { "rmdir", FTP_RMD, 0 }, - { "send", FTP_PUT, CM_INV }, - { "site", FTP_SIT, 0 }, - { "size", FTP_SIZ, 0 }, - { "status", FTP_STA, 0 }, - { "system", FTP_SYS, 0 }, - { "type", FTP_TYP, 0 }, - { "umask", FTP_UMA, 0 }, - { "up", FTP_GUP, CM_INV }, - { "user", FTP_USR, 0 }, - { "vdirectory",FTP_VDI, 0 }, - { "", 0, 0 } -}; -static int nftpcmd = (sizeof(ftpcmdtab) / sizeof(struct keytab)) - 1; - -#define OPN_ANO 1 /* FTP OPEN switch codes */ -#define OPN_PSW 2 -#define OPN_USR 3 -#define OPN_ACC 4 -#define OPN_ACT 5 -#define OPN_PSV 6 -#define OPN_TLS 7 -#define OPN_NIN 8 -#define OPN_NOL 9 - -#ifdef FTP_SECURITY -#ifdef CK_SSL -#define USETLSTAB -static struct keytab tlstab[] = { /* FTP SSL/TLS switches */ - { "/ssl", OPN_TLS, 0 }, - { "/tls", OPN_TLS, 0 }, - { "", 0, 0 } -}; -static int ntlstab = (sizeof(tlstab) / sizeof(struct keytab)) - 1; -#endif /* CK_SSL */ -#endif /* FTP_SECURITY */ - -static struct keytab ftpswitab[] = { /* FTP command switches */ - { "/account", OPN_ACC, CM_ARG }, - { "/active", OPN_ACT, 0 }, - { "/anonymous", OPN_ANO, 0 }, - { "/noinit", OPN_NIN, 0 }, - { "/nologin", OPN_NOL, 0 }, - { "/passive", OPN_PSV, 0 }, - { "/password", OPN_PSW, CM_ARG }, - { "/user", OPN_USR, CM_ARG }, - { "", 0, 0 } -}; -static int nftpswi = (sizeof(ftpswitab) / sizeof(struct keytab)) - 1; - -/* FTP { ENABLE, DISABLE } items */ - -#define ENA_FEAT 1 -#define ENA_MDTM 2 -#define ENA_MLST 3 -#define ENA_SIZE 4 -#define ENA_AUTH 5 - -static struct keytab ftpenatab[] = { - { "AUTH", ENA_AUTH, 0 }, - { "FEAT", ENA_FEAT, 0 }, - { "MDTM", ENA_MDTM, 0 }, - { "ML", ENA_MLST, CM_INV|CM_ABR }, - { "MLS", ENA_MLST, CM_INV|CM_ABR }, - { "MLSD", ENA_MLST, CM_INV }, - { "MLST", ENA_MLST, 0 }, - { "SIZE", ENA_SIZE, 0 }, - { "", 0, 0 } -}; -static int nftpena = (sizeof(ftpenatab) / sizeof(struct keytab)) - 1; - -/* SET FTP command keyword indices */ - -#define FTS_AUT 1 /* Autoauthentication */ -#define FTS_CRY 2 /* Encryption */ -#define FTS_LOG 3 /* Autologin */ -#define FTS_CPL 4 /* Command protection level */ -#define FTS_CFW 5 /* Credentials forwarding */ -#define FTS_DPL 6 /* Data protection level */ -#define FTS_DBG 7 /* Debugging */ -#define FTS_PSV 8 /* Passive mode */ -#define FTS_SPC 9 /* Send port commands */ -#define FTS_TYP 10 /* (file) Type */ -#define FTS_USN 11 /* Unique server names (for files) */ -#define FTS_VBM 12 /* Verbose mode */ -#define FTS_ATP 13 /* Authentication type */ -#define FTS_CNV 14 /* Filename conversion */ -#define FTS_TST 15 /* Test (progress) messages */ -#define FTS_PRM 16 /* (file) Permissions */ -#define FTS_XLA 17 /* Charset translation */ -#define FTS_CSR 18 /* Server charset */ -#define FTS_ERR 19 /* Error action */ -#define FTS_FNC 20 /* Collision */ -#define FTS_SRP 21 /* SRP options */ -#define FTS_GFT 22 /* GET automatic file-type switching */ -#define FTS_DAT 23 /* Set file dates */ -#define FTS_STO 24 /* Server time offset */ -#define FTS_APW 25 /* Anonymous password */ -#define FTS_DIS 26 /* File-transfer display style */ -#define FTS_BUG 27 /* Bug(s) */ - -/* FTP BUGS */ - -#define FTB_SV2 1 /* use SSLv2 */ - -static struct keytab ftpbugtab[] = { - { "use-ssl-v2", FTB_SV2, 0 } -}; -static int nftpbug = (sizeof(ftpbugtab) / sizeof(struct keytab)); - -/* FTP PUT options (mutually exclusive, not a bitmask) */ - -#define PUT_UPD 1 /* Update */ -#define PUT_RES 2 /* Restart */ -#define PUT_SIM 4 /* Simulation */ -#define PUT_DIF 8 /* Dates Differ */ - -static struct keytab ftpcolxtab[] = { /* SET FTP COLLISION options */ -#ifndef MAC - { "append", XYFX_A, 0 }, /* append to old file */ -#endif /* MAC */ -#ifdef COMMENT - { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */ -#endif - { "backup", XYFX_B, 0 }, /* rename old file */ -#ifndef MAC - { "dates-differ", XYFX_M, 0 }, /* accept if dates differ */ - { "discard", XYFX_D, 0 }, /* don't accept new file */ - { "no-supersede", XYFX_D, CM_INV }, /* ditto (MSK compatibility) */ -#endif /* MAC */ - { "overwrite", XYFX_X, 0 }, /* overwrite the old file */ - { "rename", XYFX_R, 0 }, /* rename the incoming file */ -#ifndef MAC /* This crashes Mac Kermit. */ - { "update", XYFX_U, 0 }, /* replace if newer */ -#endif /* MAC */ - { "", 0, 0 } -}; -static int nftpcolx = (sizeof(ftpcolxtab) / sizeof(struct keytab)) - 1; - - -#ifdef FTP_SECURITY -/* FTP authentication options */ - -#define FTA_AUTO 0 /* Auto */ -#define FTA_SRP 1 /* SRP */ -#define FTA_GK5 2 /* Kerberos 5 */ -#define FTA_K4 3 /* Kerberos 4 */ -#define FTA_SSL 4 /* SSL */ -#define FTA_TLS 5 /* TLS */ - -/* FTP authentication types */ - -#define FTPATYPS 8 -static int ftp_auth_type[FTPATYPS] = { -#ifdef FTP_GSSAPI - FTA_GK5, /* GSSAPI Kerberos 5 */ -#endif /* FTP_GK5 */ -#ifdef FTP_SRP - FTA_SRP, /* SRP */ -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 - FTA_K4, /* Kerberos 4 */ -#endif /* FTP_KRB4 */ -#ifdef CK_SSL - FTA_TLS, /* TLS */ - FTA_SSL, /* SSL */ -#endif /* CK_SSL */ - 0 -}; - -static struct keytab ftpauth[] = { /* SET FTP AUTHTYPE cmd table */ - { "automatic", FTA_AUTO, CM_INV }, -#ifdef FTP_GSSAPI - { "gssapi-krb5", FTA_GK5, 0 }, -#endif /* FTP_GSSAPI */ -#ifdef FTP_KRB4 - { "k4", FTA_K4, CM_INV }, -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - { "k5", FTA_GK5, CM_INV }, -#endif /* FTP_GSSAPI */ -#ifdef FTP_KRB4 - { "kerberos4", FTA_K4, 0 }, -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - { "kerberos5", FTA_GK5, CM_INV }, -#endif /* FTP_GSSAPI */ -#ifdef FTP_KRB4 - { "kerberos_iv",FTA_K4, CM_INV }, -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - { "kerberos_v", FTA_GK5, CM_INV }, -#endif /* FTP_GSSAPI */ -#ifdef FTP_KRB4 - { "krb4", FTA_K4, CM_INV }, -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - { "krb5", FTA_GK5, CM_INV }, -#endif /* FTP_GSSAPI */ -#ifdef FTP_SRP - { "srp", FTA_SRP, 0 }, -#endif /* FTP_SRP */ -#ifdef CK_SSL - { "ssl", FTA_SSL, 0 }, - { "tls", FTA_TLS, 0 }, -#endif /* CK_SSL */ - { "", 0, 0 } -}; -static int nftpauth = (sizeof(ftpauth) / sizeof(struct keytab)) - 1; - -#ifdef FTP_SRP -#define SRP_CIPHER 1 -#define SRP_HASH 2 -static struct keytab ftpsrp[] = { /* SET FTP SRP command table */ - { "cipher", SRP_CIPHER, 0 }, - { "hash", SRP_HASH, 0 }, - { "", 0, 0 } -}; -static int nftpsrp = (sizeof(ftpsrp) / sizeof(struct keytab)) - 1; -#endif /* FTP_SRP */ -#endif /* FTP_SECURITY */ - -static struct keytab ftpset[] = { /* SET FTP commmand table */ - { "anonymous-password", FTS_APW, 0 }, -#ifdef FTP_SECURITY - { "authtype", FTS_ATP, 0 }, - { "autoauthentication", FTS_AUT, 0 }, - { "autoencryption", FTS_CRY, 0 }, -#endif /* FTP_SECURITY */ - { "autologin", FTS_LOG, 0 }, - { "bug", FTS_BUG, 0 }, -#ifndef NOCSETS - { "character-set-translation",FTS_XLA, 0 }, -#endif /* NOCSETS */ - { "collision", FTS_FNC, 0 }, -#ifdef FTP_SECURITY - { "command-protection-level", FTS_CPL, 0 }, - { "cpl", FTS_CPL, CM_INV }, - { "credential-forwarding", FTS_CFW, 0 }, - { "da", FTS_DAT, CM_INV|CM_ABR }, - { "data-protection-level", FTS_DPL, 0 }, -#endif /* FTP_SECURITY */ - { "dates", FTS_DAT, 0 }, - { "debug", FTS_DBG, 0 }, - { "display", FTS_DIS, 0 }, -#ifdef FTP_SECURITY - { "dpl", FTS_DPL, CM_INV }, -#endif /* FTP_SECURITY */ - { "error-action", FTS_ERR, 0 }, - { "filenames", FTS_CNV, 0 }, - { "get-filetype-switching", FTS_GFT, 0 }, - { "passive-mode", FTS_PSV, 0 }, - { "pasv", FTS_PSV, CM_INV }, - { "permissions", FTS_PRM, 0 }, - { "progress-messages", FTS_TST, 0 }, - { "send-port-commands", FTS_SPC, 0 }, -#ifndef NOCSETS - { "server-character-set", FTS_CSR, 0 }, -#endif /* NOCSETS */ - { "server-time-offset", FTS_STO, 0 }, -#ifdef FTP_SRP - { "srp", FTS_SRP, 0 }, -#else - { "srp", FTS_SRP, CM_INV }, -#endif /* FTP_SRP */ - { "type", FTS_TYP, 0 }, - { "unique-server-names", FTS_USN, 0 }, - { "verbose-mode", FTS_VBM, 0 }, - { "", 0, 0 } -}; -static int nftpset = (sizeof(ftpset) / sizeof(struct keytab)) - 1; - -/* - GET and PUT switches are approximately the same as Kermit GET and SEND, - and use the same SND_xxx definitions, but hijack a couple for FTP use. - Don't just make up new ones, since the number of SND_xxx options must be - known in advance for the switch-parsing arrays. -*/ -#define SND_USN SND_PRO /* /UNIQUE instead of /PROTOCOL */ -#define SND_PRM SND_PIP /* /PERMISSIONS instead of /PIPES */ -#define SND_TEN SND_CAL /* /TENEX instead of /CALIBRATE */ - -static struct keytab putswi[] = { /* FTP PUT switch table */ - { "/after", SND_AFT, CM_ARG }, -#ifdef PUTARRAY - { "/array", SND_ARR, CM_ARG }, -#endif /* PUTARRAY */ - { "/as", SND_ASN, CM_ARG|CM_INV|CM_ABR }, - { "/as-name", SND_ASN, CM_ARG }, - { "/ascii", SND_TXT, CM_INV }, - { "/b", SND_BIN, CM_INV|CM_ABR }, - { "/before", SND_BEF, CM_ARG }, - { "/binary", SND_BIN, 0 }, -#ifdef PUTPIPE - { "/command", SND_CMD, CM_PSH }, -#endif /* PUTPIPE */ -#ifdef COMMENT -/* This works but it's dangerous */ -#ifdef DOUPDATE - { "/dates-differ", SND_DIF, CM_INV }, -#endif /* DOUPDATE */ -#endif /* COMMENT */ - { "/delete", SND_DEL, 0 }, -#ifdef UNIXOROSK - { "/dotfiles", SND_DOT, 0 }, -#endif /* UNIXOROSK */ - { "/error-action", SND_ERR, CM_ARG }, - { "/except", SND_EXC, CM_ARG }, - { "/filenames", SND_NAM, CM_ARG }, -#ifdef PIPESEND -#ifndef NOSPL - { "/filter", SND_FLT, CM_ARG|CM_PSH }, -#endif /* NOSPL */ -#endif /* PIPESEND */ -#ifdef CKSYMLINK - { "/followlinks", SND_LNK, 0 }, -#endif /* CKSYMLINK */ -#ifdef VMS - { "/image", SND_IMG, 0 }, -#else - { "/image", SND_BIN, CM_INV }, -#endif /* VMS */ - { "/larger-than", SND_LAR, CM_ARG }, - { "/listfile", SND_FIL, CM_ARG }, -#ifndef NOCSETS - { "/local-character-set", SND_CSL, CM_ARG }, -#endif /* NOCSETS */ -#ifdef CK_TMPDIR - { "/move-to", SND_MOV, CM_ARG }, -#endif /* CK_TMPDIR */ - { "/nobackupfiles", SND_NOB, 0 }, -#ifdef UNIXOROSK - { "/nodotfiles", SND_NOD, 0 }, -#endif /* UNIXOROSK */ -#ifdef CKSYMLINK - { "/nofollowlinks", SND_NLK, 0 }, -#endif /* CKSYMLINK */ - - { "/not-after", SND_NAF, CM_ARG }, - { "/not-before", SND_NBE, CM_ARG }, -#ifdef UNIX - { "/permissions", SND_PRM, CM_ARG }, -#else - { "/permissions", SND_PRM, CM_ARG|CM_INV }, -#endif /* UNIX */ - { "/quiet", SND_SHH, 0 }, -#ifdef FTP_RESTART - { "/recover", SND_RES, 0 }, -#endif /* FTP_RESTART */ -#ifdef RECURSIVE - { "/recursive", SND_REC, 0 }, -#endif /* RECURSIVE */ - { "/rename-to", SND_REN, CM_ARG }, -#ifdef FTP_RESTART - { "/restart", SND_RES, CM_INV }, -#endif /* FTP_RESTART */ -#ifndef NOCSETS - { "/server-character-set", SND_CSR, CM_ARG }, -#endif /* NOCSETS */ - { "/server-rename-to", SND_SRN, CM_ARG }, - { "/simulate", SND_SIM, 0 }, - { "/since", SND_AFT, CM_INV|CM_ARG }, - { "/smaller-than", SND_SMA, CM_ARG }, -#ifdef COMMENT - { "/starting-at", SND_STA, CM_ARG }, -#endif /* COMMENT */ -#ifdef RECURSIVE - { "/subdirectories", SND_REC, CM_INV }, -#endif /* RECURSIVE */ - { "/tenex", SND_TEN, 0 }, - { "/text", SND_TXT, 0 }, -#ifndef NOCSETS - { "/transparent", SND_XPA, 0 }, -#endif /* NOCSETS */ - { "/type", SND_TYP, CM_ARG }, -#ifdef DOUPDATE - { "/update", SND_UPD, 0 }, -#endif /* DOUPDATE */ - { "/unique-server-names", SND_USN, 0 }, - { "", 0, 0 } -}; -static int nputswi = (sizeof(putswi) / sizeof(struct keytab)) - 1; - -static struct keytab getswi[] = { /* FTP [M]GET switch table */ - { "/after", SND_AFT, CM_INV }, - { "/as", SND_ASN, CM_ARG|CM_INV|CM_ABR }, - { "/as-name", SND_ASN, CM_ARG }, - { "/ascii", SND_TXT, CM_INV }, - { "/before", SND_BEF, CM_INV }, - { "/binary", SND_BIN, 0 }, - { "/collision", SND_COL, CM_ARG }, -#ifdef PUTPIPE - { "/command", SND_CMD, CM_PSH }, -#endif /* PUTPIPE */ - { "/delete", SND_DEL, 0 }, - { "/error-action", SND_ERR, CM_ARG }, - { "/except", SND_EXC, CM_ARG }, - { "/filenames", SND_NAM, CM_ARG }, -#ifdef PIPESEND -#ifndef NOSPL - { "/filter", SND_FLT, CM_ARG|CM_PSH }, -#endif /* NOSPL */ -#endif /* PIPESEND */ -#ifdef VMS - { "/image", SND_IMG, 0 }, -#else - { "/image", SND_BIN, CM_INV }, -#endif /* VMS */ - { "/larger-than", SND_LAR, CM_ARG }, - { "/listfile", SND_FIL, CM_ARG }, -#ifndef NOCSETS - { "/local-character-set", SND_CSL, CM_ARG }, -#endif /* NOCSETS */ - { "/match", SND_PAT, CM_ARG }, - { "/ml", SND_MLS, CM_INV|CM_ABR }, - { "/mls", SND_MLS, CM_INV|CM_ABR }, - { "/mlsd", SND_MLS, 0 }, - { "/mlst", SND_MLS, CM_INV }, -#ifdef CK_TMPDIR - { "/move-to", SND_MOV, CM_ARG }, -#endif /* CK_TMPDIR */ - { "/namelist", SND_NML, CM_ARG }, - { "/nlst", SND_NLS, 0 }, - { "/nobackupfiles", SND_NOB, 0 }, - { "/nodotfiles", SND_NOD, 0 }, -#ifdef DOUPDATE - { "/dates-differ", SND_DIF, CM_INV }, -#endif /* DOUPDATE */ - { "/not-after", SND_NAF, CM_INV }, - { "/not-before", SND_NBE, CM_INV }, - { "/permissions", SND_PRM, CM_INV }, - { "/quiet", SND_SHH, 0 }, -#ifdef FTP_RESTART - { "/recover", SND_RES, 0 }, -#endif /* FTP_RESTART */ -#ifdef RECURSIVE - { "/recursive", SND_REC, 0 }, -#endif /* RECURSIVE */ - { "/rename-to", SND_REN, CM_ARG }, -#ifdef FTP_RESTART - { "/restart", SND_RES, CM_INV }, -#endif /* FTP_RESTART */ -#ifndef NOCSETS - { "/server-character-set", SND_CSR, CM_ARG }, -#endif /* NOCSETS */ - { "/server-rename-to", SND_SRN, CM_ARG }, - { "/smaller-than", SND_SMA, CM_ARG }, -#ifdef RECURSIVE - { "/subdirectories", SND_REC, CM_INV }, -#endif /* RECURSIVE */ - { "/text", SND_TXT, 0 }, - { "/tenex", SND_TEN, 0 }, -#ifndef NOCSETS - { "/transparent", SND_XPA, 0 }, -#endif /* NOCSETS */ - { "/to-screen", SND_MAI, 0 }, -#ifdef DOUPDATE - { "/update", SND_UPD, CM_INV }, -#endif /* DOUPDATE */ - { "", 0, 0 } -}; -static int ngetswi = (sizeof(getswi) / sizeof(struct keytab)) - 1; - -static struct keytab delswi[] = { /* FTP [M]DELETE switch table */ - { "/error-action", SND_ERR, CM_ARG }, - { "/except", SND_EXC, CM_ARG }, - { "/filenames", SND_NAM, CM_ARG }, - { "/larger-than", SND_LAR, CM_ARG }, - { "/nobackupfiles", SND_NOB, 0 }, -#ifdef UNIXOROSK - { "/nodotfiles", SND_NOD, 0 }, -#endif /* UNIXOROSK */ - { "/quiet", SND_SHH, 0 }, -#ifdef RECURSIVE - { "/recursive", SND_REC, 0 }, -#endif /* RECURSIVE */ - { "/smaller-than", SND_SMA, CM_ARG }, -#ifdef RECURSIVE - { "/subdirectories", SND_REC, CM_INV }, -#endif /* RECURSIVE */ - { "", 0, 0 } -}; -static int ndelswi = (sizeof(delswi) / sizeof(struct keytab)) - 1; - -static struct keytab fntab[] = { /* Filename conversion keyword table */ - { "automatic", 2, CNV_AUTO }, - { "converted", 1, CNV_CNV }, - { "literal", 0, CNV_LIT } -}; -static int nfntab = (sizeof(fntab) / sizeof(struct keytab)); - -static struct keytab ftptyp[] = { /* SET FTP TYPE table */ - { "ascii", FTT_ASC, 0 }, - { "binary", FTT_BIN, 0 }, - { "tenex", FTT_TEN, 0 }, - { "text", FTT_ASC, CM_INV }, - { "", 0, 0 } -}; -static int nftptyp = (sizeof(ftptyp) / sizeof(struct keytab)) - 1; - -#ifdef FTP_SECURITY -static struct keytab ftppro[] = { /* SET FTP PROTECTION-LEVEL table */ - { "clear", FPL_CLR, 0 }, - { "confidential", FPL_CON, 0 }, - { "private", FPL_PRV, 0 }, - { "safe", FPL_SAF, 0 }, - { "", 0, 0 } -}; -static int nftppro = (sizeof(ftppro) / sizeof(struct keytab)) - 1; -#endif /* FTP_SECURITY */ - -/* Definitions for FTP from RFC765. */ - -/* Reply codes */ - -#define REPLY_PRELIM 1 /* Positive preliminary */ -#define REPLY_COMPLETE 2 /* Positive completion */ -#define REPLY_CONTINUE 3 /* Positive intermediate */ -#define REPLY_TRANSIENT 4 /* Transient negative completion */ -#define REPLY_ERROR 5 /* Permanent negative completion */ -#define REPLY_SECURE 6 /* Security encoded message */ - -/* Form codes and names */ - -#define FORM_N 1 /* Non-print */ -#define FORM_T 2 /* Telnet format effectors */ -#define FORM_C 3 /* Carriage control (ASA) */ - -/* Structure codes and names */ - -#define STRU_F 1 /* File (no record structure) */ -#define STRU_R 2 /* Record structure */ -#define STRU_P 3 /* Page structure */ - -/* Mode types and names */ - -#define MODE_S 1 /* Stream */ -#define MODE_B 2 /* Block */ -#define MODE_C 3 /* Compressed */ - -/* Protection levels and names */ - -#define PROT_C 1 /* Clear */ -#define PROT_S 2 /* Safe */ -#define PROT_P 3 /* Private */ -#define PROT_E 4 /* Confidential */ - -#ifdef COMMENT /* Not used */ -#ifdef FTP_NAMES -char *strunames[] = {"0", "File", "Record", "Page" }; -char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" }; -char *modenames[] = {"0", "Stream", "Block", "Compressed" }; -char *levelnames[] = {"0", "Clear", "Safe", "Private", "Confidential" }; -#endif /* FTP_NAMES */ - -/* Record Tokens */ - -#define REC_ESC '\377' /* Record-mode Escape */ -#define REC_EOR '\001' /* Record-mode End-of-Record */ -#define REC_EOF '\002' /* Record-mode End-of-File */ - -/* Block Header */ - -#define BLK_EOR 0x80 /* Block is End-of-Record */ -#define BLK_EOF 0x40 /* Block is End-of-File */ -#define BLK_REPLY_ERRORS 0x20 /* Block might have errors */ -#define BLK_RESTART 0x10 /* Block is Restart Marker */ -#define BLK_BYTECOUNT 2 /* Bytes in this block */ -#endif /* COMMENT */ - -#define RADIX_ENCODE 0 /* radix_encode() function codes */ -#define RADIX_DECODE 1 - -/* - The default setpbsz() value in the Unix FTP client is 1<<20 (1MB). This - results in a serious performance degradation due to the increased number - of page faults and the inability to overlap encrypt/decrypt, file i/o, and - network i/o. So instead we set the value to 1<<13 (8K), about half the size - of the typical TCP window. Maybe we should add a command to allow the value - to be changed. -*/ -#define DEFAULT_PBSZ 1<<13 - -/* Prototypes */ - -_PROTOTYP(int remtxt, (char **) ); -_PROTOTYP(char * gskreason, (int) ); -_PROTOTYP(static int ftpclose,(void)); -_PROTOTYP(static int zzsend, (int, CHAR)); -_PROTOTYP(static int getreply,(int,int,int,int,int)); -_PROTOTYP(static int radix_encode,(CHAR[], CHAR[], int, int *, int)); -_PROTOTYP(static int setpbsz,(unsigned int)); -_PROTOTYP(static int recvrequest,(char *,char *,char *,char *, - int,int,char *,int,int,int)); -_PROTOTYP(static int ftpcmd,(char *,char *,int,int,int)); -_PROTOTYP(static int fts_cpl,(int)); -_PROTOTYP(static int fts_dpl,(int)); -#ifdef FTP_SECURITY -_PROTOTYP(static int ftp_auth, (void)); -#endif /* FTP_SECURITY */ -_PROTOTYP(static int ftp_user, (char *, char *, char *)); -_PROTOTYP(static int ftp_login, (char *)); -_PROTOTYP(static int ftp_reset, (void)); -_PROTOTYP(static int ftp_rename, (char *, char *)); -_PROTOTYP(static int ftp_umask, (char *)); -_PROTOTYP(static int secure_flush, (int)); -#ifdef COMMENT -_PROTOTYP(static int secure_putc, (char, int)); -#endif /* COMMENT */ -_PROTOTYP(static int secure_write, (int, CHAR *, unsigned int)); -_PROTOTYP(static int scommand, (char *)); -_PROTOTYP(static int secure_putbuf, (int, CHAR *, unsigned int)); -_PROTOTYP(static int secure_getc, (int, int)); -_PROTOTYP(static int secure_getbyte, (int, int)); -_PROTOTYP(static int secure_read, (int, char *, int)); -_PROTOTYP(static int initconn, (void)); -_PROTOTYP(static int dataconn, (char *)); -_PROTOTYP(static int setprotbuf,(unsigned int)); -_PROTOTYP(static int sendrequest, (char *, char *, char *, int,int,int,int)); - -_PROTOTYP(static char * radix_error,(int)); -_PROTOTYP(static char * ftp_hookup,(char *, int, int)); -_PROTOTYP(static CHAR * remote_files, (int, CHAR *, CHAR *, int)); - -_PROTOTYP(static VOID mlsreset, (void)); -_PROTOTYP(static VOID secure_error, (char *fmt, ...)); -_PROTOTYP(static VOID lostpeer, (void)); -_PROTOTYP(static VOID cancel_remote, (int)); -_PROTOTYP(static VOID changetype, (int, int)); - -_PROTOTYP(static sigtype cmdcancel, (int)); - -#ifdef FTP_SRP -_PROTOTYP(static int srp_reset, ()); -_PROTOTYP(static int srp_ftp_auth, (char *,char *,char *)); -_PROTOTYP(static int srp_put, (CHAR *, CHAR **, int, int *)); -_PROTOTYP(static int srp_get, (CHAR **, CHAR **, int *, int *)); -_PROTOTYP(static int srp_encode, (int, CHAR *, CHAR *, unsigned int)); -_PROTOTYP(static int srp_decode, (int, CHAR *, CHAR *, unsigned int)); -_PROTOTYP(static int srp_selcipher, (char *)); -_PROTOTYP(static int srp_selhash, (char *)); -#endif /* FTP_SRP */ - -#ifdef FTP_GSSAPI -_PROTOTYP(static void user_gss_error,(OM_uint32, OM_uint32,char *)); -#endif /* FTP_GSSAPI */ - -/* D O F T P A R G -- Do an FTP command-line argument. */ - -#ifdef FTP_SECURITY -#ifndef NOICP -#define FT_NOGSS 1 -#define FT_NOK4 2 -#define FT_NOSRP 3 -#define FT_NOSSL 4 -#define FT_NOTLS 5 -#define FT_CERTFI 6 -#define FT_OKCERT 7 -#define FT_DEBUG 8 -#define FT_KEY 9 -#define FT_SECURE 10 -#define FT_VERIFY 11 - -static struct keytab ftpztab[] = { - { "!gss", FT_NOGSS, 0 }, - { "!krb4", FT_NOK4, 0 }, - { "!srp", FT_NOSRP, 0 }, - { "!ssl", FT_NOSSL, 0 }, - { "!tls", FT_NOTLS, 0 }, - { "cert", FT_CERTFI, CM_ARG }, - { "certsok", FT_OKCERT, 0 }, - { "debug", FT_DEBUG, 0 }, - { "key", FT_KEY, CM_ARG }, - { "nogss", FT_NOGSS, 0 }, - { "nokrb4", FT_NOK4, 0 }, - { "nosrp", FT_NOSRP, 0 }, - { "nossl", FT_NOSSL, 0 }, - { "notls", FT_NOTLS, 0 }, -#ifdef COMMENT - { "secure", FT_SECURE, 0 }, -#endif /* COMMENT */ - { "verify", FT_VERIFY, CM_ARG }, - { "", 0, 0 } -}; -static int nftpztab = sizeof(ftpztab) / sizeof(struct keytab) - 1; - -/* - The following cipher and hash tables should be replaced with - dynamicly created versions based upon the linked library. -*/ -#define SRP_BLOWFISH_ECB 1 -#define SRP_BLOWFISH_CBC 2 -#define SRP_BLOWFISH_CFB64 3 -#define SRP_BLOWFISH_OFB64 4 -#define SRP_CAST5_ECB 5 -#define SRP_CAST5_CBC 6 -#define SRP_CAST5_CFB64 7 -#define SRP_CAST5_OFB64 8 -#define SRP_DES_ECB 9 -#define SRP_DES_CBC 10 -#define SRP_DES_CFB64 11 -#define SRP_DES_OFB64 12 -#define SRP_DES3_ECB 13 -#define SRP_DES3_CBC 14 -#define SRP_DES3_CFB64 15 -#define SRP_DES3_OFB64 16 - -static struct keytab ciphertab[] = { - { "blowfish_ecb", SRP_BLOWFISH_ECB, 0 }, - { "blowfish_cbc", SRP_BLOWFISH_CBC, 0 }, - { "blowfish_cfb64", SRP_BLOWFISH_CFB64, 0 }, - { "blowfish_ofb64", SRP_BLOWFISH_OFB64, 0 }, - { "cast5_ecb", SRP_CAST5_ECB, 0 }, - { "cast5_cbc", SRP_CAST5_CBC, 0 }, - { "cast5_cfb64", SRP_CAST5_CFB64, 0 }, - { "cast5_ofb64", SRP_CAST5_OFB64, 0 }, - { "des_ecb", SRP_DES_ECB, 0 }, - { "des_cbc", SRP_DES_CBC, 0 }, - { "des_cfb64", SRP_DES_CFB64, 0 }, - { "des_ofb64", SRP_DES_OFB64, 0 }, - { "des3_ecb", SRP_DES3_ECB, 0 }, - { "des3_cbc", SRP_DES3_CBC, 0 }, - { "des3_cfb64", SRP_DES3_CFB64, 0 }, - { "des3_ofb64", SRP_DES3_OFB64, 0 }, - { "none", 0, 0 }, - { "", 0, 0 } -}; -static int nciphertab = sizeof(ciphertab) / sizeof(struct keytab) - 1; - -#define SRP_MD5 1 -#define SRP_SHA 2 -static struct keytab hashtab[] = { - { "md5", SRP_MD5, 0 }, - { "none", 0, 0 }, - { "sha", SRP_SHA, 0 }, - { "", 0, 0 } -}; -static int nhashtab = sizeof(hashtab) / sizeof(struct keytab) - 1; -#endif /* NOICP */ -#endif /* FTP_SECURITY */ - -static char * -strval(s1,s2) char * s1, * s2; { - if (!s1) s1 = ""; - if (!s2) s2 = ""; - return(*s1 ? s1 : (*s2 ? s2 : "(none)")); -} - -#ifndef NOCSETS -static char * rfnptr = NULL; -static int rfnlen = 0; -static char rfnbuf[RFNBUFSIZ]; /* Remote filename translate buffer */ -static char * xgnbp = NULL; - -static int -strgetc() { /* Helper function for xgnbyte() */ - int c; - if (!xgnbp) - return(-1); - if (!*xgnbp) - return(-1); - c = (unsigned) *xgnbp++; - return(((unsigned) c) & 0xff); -} - -static int /* Helper function for xpnbyte() */ -#ifdef CK_ANSIC -strputc(char c) -#else -strputc(c) char c; -#endif /* CK_ANSIC */ -{ - rfnlen = rfnptr - rfnbuf; - if (rfnlen >= (RFNBUFSIZ - 1)) - return(-1); - *rfnptr++ = c; - *rfnptr = NUL; - return(0); -} - -static int -#ifdef CK_ANSIC -xprintc(char c) -#else -xprintc(c) char c; -#endif /* CK_ANSIC */ -{ - printf("%c",c); - return(0); -} - -static VOID -bytswap(c0,c1) int * c0, * c1; { - int t; - t = *c0; - *c0 = *c1; - *c1 = t; -} -#endif /* NOCSETS */ - -#ifdef CKLOGDIAL -char ftplogbuf[CXLOGBUFL] = { NUL, NUL }; /* Connection Log */ -int ftplogactive = 0; -long ftplogprev = 0L; - -VOID -ftplogend() { - extern int dialog; - extern char diafil[]; - long d1, d2, t1, t2; - char buf[32], * p; - - debug(F111,"ftp cx log active",ckitoa(dialog),ftplogactive); - debug(F110,"ftp cx log buf",ftplogbuf,0); - - if (!ftplogactive || !ftplogbuf[0]) /* No active record */ - return; - - ftplogactive = 0; /* Record is not active */ - - d1 = mjd((char *)ftplogbuf); /* Get start date of this session */ - ckstrncpy(buf,ckdate(),31); /* Get current date */ - d2 = mjd(buf); /* Convert them to mjds */ - p = ftplogbuf; /* Get start time */ - p[11] = NUL; - p[14] = NUL; /* Convert to seconds */ - t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15); - p[11] = ':'; - p[14] = ':'; - p = buf; /* Get end time */ - p[11] = NUL; - p[14] = NUL; - t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15); - t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Compute elapsed time */ - if (t2 > -1L) { - ftplogprev = t2; - p = hhmmss(t2); - strncat(ftplogbuf,"E=",CXLOGBUFL); /* Append to log record */ - strncat(ftplogbuf,p,CXLOGBUFL); - } else - ftplogprev = 0L; - debug(F101,"ftp cx log dialog","",dialog); - if (dialog) { /* If logging */ - int x; - x = diaopn(diafil,1,1); /* Open log in append mode */ - if (x > 0) { - debug(F101,"ftp cx log open","",x); - x = zsoutl(ZDIFIL,ftplogbuf); /* Write the record */ - debug(F101,"ftp cx log write","",x); - x = zclose(ZDIFIL); /* Close the log */ - debug(F101,"ftp cx log close","",x); - } - } -} - -VOID -dologftp() { - ftplogend(); /* Previous session not closed out? */ - ftplogprev = 0L; - ftplogactive = 1; /* Record is active */ - - ckmakxmsg(ftplogbuf,CXLOGBUFL, - ckdate()," ",strval(ftp_logname,NULL)," ",ckgetpid(), - " T=FTP N=", strval(ftp_host,NULL)," H=",myhost," ",NULL,NULL); - debug(F110,"ftp cx log begin",ftplogbuf,0); -} -#endif /* CKLOGDIAL */ - -static char * dummy[2] = { NULL, NULL }; - -static struct keytab modetab[] = { - { "active", 0, 0 }, - { "passive", 1, 0 } -}; - -#ifndef NOCMDL -int /* Called from ckuusy.c */ -#ifdef CK_ANSIC -doftparg(char c) -#else -doftparg(c) char c; -#endif /* CK_ANSIC */ -/* doftparg */ { - int x, z; - char *xp; - extern char **xargv, *xarg0; - extern int xargc, stayflg, haveftpuid; - extern char uidbuf[]; - - xp = *xargv+1; /* Pointer for bundled args */ - while (c) { - if (ckstrchr("MuDPkcHzm",c)) { /* Options that take arguments */ - if (*(xp+1)) { - fatal("?Invalid argument bundling"); - } - xargv++, xargc--; - if ((xargc < 1) || (**xargv == '-')) { - fatal("?Required argument missing"); - } - } - switch (c) { /* Big switch on arg */ - case 'h': /* help */ - printf("C-Kermit's FTP client command-line personality. Usage:\n"); - printf(" %s [ options ] host [ port ] [-pg files ]\n\n",xarg0); - printf("Options:\n"); - printf(" -h = help (this message)\n"); - printf(" -m mode = \"passive\" (default) or \"active\"\n"); - printf(" -u name = username for autologin (or -M)\n"); - printf(" -P password = password for autologin (RISKY)\n"); - printf(" -A = autologin anonymously\n"); - printf(" -D directory = cd after autologin\n"); - printf(" -b = force binary mode\n"); - printf(" -a = force text (\"ascii\") mode (or -T)\n"); - printf(" -d = debug (double to add timestamps)\n"); - printf(" -n = no autologin\n"); - printf(" -v = verbose (default)\n"); - printf(" -q = quiet\n"); - printf(" -S = Stay (issue command prompt when done)\n"); - printf(" -Y = do not execute Kermit init file\n"); - printf(" -p files = files to put after autologin (or -s)\n"); - printf(" -g files = files to get after autologin\n"); - printf(" -R = recursive (for use with -p)\n"); - -#ifdef FTP_SECURITY - printf("\nSecurity options:\n"); - printf(" -k realm = Kerberos 4 realm\n"); - printf(" -f = Kerboros 5 credentials forwarding\n"); - printf(" -x = autoencryption mode\n"); - printf(" -c cipher = SRP cipher type\n"); - printf(" -H hash = SRP encryption hash\n"); - printf(" -z option = Security options\n"); -#endif /* FTP_SECURITY */ - - printf("\n-p or -g, if given, should be last. Example:\n"); - printf(" ftp -A kermit.columbia.edu -D kermit -ag TESTFILE\n"); - - doexit(GOOD_EXIT,-1); - break; - - case 'R': /* Recursive */ - recursive = 1; - break; - - case 'd': /* Debug */ -#ifdef DEBUG - if (deblog) { - extern int debtim; - debtim = 1; - } else { - deblog = debopn("debug.log",0); - debok = 1; - } -#endif /* DEBUG */ - /* fall thru on purpose */ - - case 't': /* Trace */ - ftp_deb++; - break; - - case 'n': /* No autologin */ - ftp_log = 0; - break; - - case 'i': /* No prompt */ - case 'v': /* Verbose */ - break; /* (ignored) */ - - case 'q': /* Quiet */ - quiet = 1; - break; - - case 'S': /* Stay */ - stayflg = 1; - break; - - case 'M': - case 'u': /* My User Name */ - if ((int)strlen(*xargv) > 63) { - fatal("username too long"); - } - ckstrncpy(uidbuf,*xargv,UIDBUFLEN); - haveftpuid = 1; - break; - - case 'A': - ckstrncpy(uidbuf,"anonymous",UIDBUFLEN); - haveftpuid = 1; - break; - - case 'T': /* Text */ - case 'a': /* "ascii" */ - case 'b': /* Binary */ - binary = (c == 'b') ? FTT_BIN : FTT_ASC; - xfermode = XMODE_M; - filepeek = 0; - patterns = 0; - break; - - case 'g': /* Get */ - case 'p': /* Put */ - case 's': { /* Send (= Put) */ - int havefiles, rc; - if (ftp_action) { - fatal("Only one FTP action at a time please"); - } - if (*(xp+1)) { - fatal("invalid argument bundling after -s"); - } - nfils = 0; /* Initialize file counter */ - havefiles = 0; /* Assume nothing to send */ - cmlist = xargv + 1; /* Remember this pointer */ - - while (++xargv, --xargc > 0) { /* Traverse the list */ - if (c == 'g') { - havefiles++; - nfils++; - continue; - } -#ifdef RECURSIVE - if (!strcmp(*xargv,".")) { - havefiles = 1; - nfils++; - recursive = 1; - } else -#endif /* RECURSIVE */ - if ((rc = zchki(*xargv)) > -1 || (rc == -2)) { - if (rc != -2) - havefiles = 1; - nfils++; - } else if (iswild(*xargv) && nzxpand(*xargv,0) > 0) { - havefiles = 1; - nfils++; - } - } - xargc++, xargv--; /* Adjust argv/argc */ - if (!havefiles) { - if (c == 'g') { - fatal("No files to put"); - } else { - fatal("No files to get"); - } - } - ftp_action = c; - break; - } - case 'D': /* Directory */ - makestr(&ftp_rdir,*xargv); - break; - - case 'm': /* Mode (Active/Passive */ - ftp_psv = lookup(modetab,*xargv,2,NULL); - if (ftp_psv < 0) fatal("Invalid mode"); - break; - - case 'P': - makestr(&ftp_tmp,*xargv); /* You-Know-What */ - break; - - case 'Y': /* No initialization file */ - break; /* (already done in prescan) */ - -#ifdef CK_URL - case 'U': { /* URL */ - /* These are set by urlparse() - any not set are NULL */ - if (g_url.hos) { -/* - Kermit has accepted host:port notation since many years before URLs were - invented. Unfortunately, URLs conflict with this notation. Thus "ftp - host:449" looks like a URL and results in service = host and host = 449. - Here we try to catch this situation transparently to the user. -*/ - if (ckstrcmp(g_url.svc,"ftp",-1,0) -#ifdef CK_SSL - && ckstrcmp(g_url.svc,"ftps",-1,0) -#endif /* CK_SSL */ - ) { - if (!g_url.usr && - !g_url.psw && - !g_url.por && - !g_url.pth) { - g_url.por = g_url.hos; - g_url.hos = g_url.svc; - g_url.svc = "ftp"; - } else { - ckmakmsg(tmpbuf,TMPBUFSIZ,"Non-FTP URL: service=", - g_url.svc," host=",g_url.hos); - fatal(tmpbuf); - } - } - makestr(&ftp_host,g_url.hos); - if (g_url.usr) { - haveftpuid = 1; - ckstrncpy(uidbuf,g_url.usr,UIDBUFLEN); - makestr(&ftp_logname,uidbuf); - } - if (g_url.psw) { - makestr(&ftp_tmp,g_url.psw); - } - if (g_url.pth) { - if (!g_url.usr) { - haveftpuid = 1; - ckstrncpy(uidbuf,"anonymous",UIDBUFLEN); - makestr(&ftp_logname,uidbuf); - } - if (ftp_action) { - fatal("Only one FTP action at a time please"); - } - if (!stayflg) - quiet = 1; - nfils = 1; - dummy[0] = g_url.pth; - cmlist = dummy; - ftp_action = 'g'; - } - xp = NULL; - haveurl = 1; - } - break; - } -#endif /* CK_URL */ - -#ifdef FTP_SECURITY - case 'k': { /* K4 Realm */ -#ifdef FTP_KRB4 - ckstrncpy(ftp_realm,*xargv, REALM_SZ); -#endif /* FTP_KRB4 */ - if (ftp_deb) printf("K4 Realm = [%s]\n",*xargv); - break; - } - case 'f': { -#ifdef FTP_GSSAPI - ftp_cfw = 1; - if (ftp_deb) printf("K5 Credentials Forwarding\n"); -#else /* FTP_GSSAPI */ - printf("K5 Credentials Forwarding not supported\n"); -#endif /* FTP_GSSAPI */ - break; - } - case 'x': { - ftp_cry = 1; - if (ftp_deb) printf("Autoencryption\n"); - break; - } - case 'c': { /* Cipher */ -#ifdef FTP_SRP - if (!srp_selcipher(*xargv)) { - if (ftp_deb) printf("SRP cipher type: \"%s\"\n",*xargv); - } else - printf("?Invalid SRP cipher type: \"%s\"\n",*xargv); -#else /* FTP_SRP */ - printf("?SRP not supported\n"); -#endif /* FTP_SRP */ - break; - } - case 'H': { -#ifdef FTP_SRP - if (!srp_selhash(*xargv)) { - if (ftp_deb) printf("SRP hash type: \"%s\"\n",*xargv); - } else - printf("?Invalid SRP hash type: \"%s\"\n",*xargv); -#else /* FTP_SRP */ - printf("?SRP not supported\n"); -#endif /* FTP_SRP */ - break; - } - case 'z': { - /* *xargv contains a value of the form tag=value */ - /* we need to lookup the tag and save the value */ - char * p = NULL, * q = NULL; - makestr(&p,*xargv); - y = ckindex("=",p,0,0,1); - if (y > 0) - p[y-1] = '\0'; - x = lookup(ftpztab,p,nftpztab,&z); - if (x < 0) { - printf("?Invalid security option: \"%s\"\n",p); - } else { - if (ftp_deb) - printf("Security option: \"%s",p); - if (ftpztab[z].flgs & CM_ARG) { - if (y <= 0) - fatal("?Missing required value"); - q = &p[y]; - if (!*q) - fatal("?Missing required value"); - if (ftp_deb) - printf("=%s\"",q); - } - switch (ftpztab[z].kwval) { /* -z options w/args */ - case FT_NOGSS: -#ifdef FTP_GSSAPI - for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) { - if (ftp_auth_type[z] == FTA_GK5) { - for (y = z; - y < (FTPATYPS-1) && ftp_auth_type[y]; - y++ - ) - ftp_auth_type[y] = ftp_auth_type[y+1]; - ftp_auth_type[FTPATYPS-1] = 0; - break; - } - } -#endif /* FTP_GSSAPI */ - break; - case FT_NOK4: -#ifdef FTP_KRB4 - for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) { - if (ftp_auth_type[z] == FTA_K4) { - for (y = z; - y < (FTPATYPS-1) && ftp_auth_type[y]; - y++ - ) - ftp_auth_type[y] = ftp_auth_type[y+1]; - ftp_auth_type[FTPATYPS-1] = 0; - break; - } - } -#endif /* FTP_KRB4 */ - break; - case FT_NOSRP: -#ifdef FTP_SRP - for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) { - if (ftp_auth_type[z] == FTA_SRP) { - for (y = z; - y < (FTPATYPS-1) && ftp_auth_type[y]; - y++ - ) - ftp_auth_type[y] = ftp_auth_type[y+1]; - ftp_auth_type[FTPATYPS-1] = 0; - break; - } - } -#endif /* FTP_SRP */ - break; - case FT_NOSSL: -#ifdef CK_SSL - for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) { - if (ftp_auth_type[z] == FTA_SSL) { - for (y = z; - y < (FTPATYPS-1) && ftp_auth_type[y]; - y++ - ) - ftp_auth_type[y] = ftp_auth_type[y+1]; - ftp_auth_type[FTPATYPS-1] = 0; - break; - } - } -#endif /* CK_SSL */ - break; - case FT_NOTLS: -#ifdef CK_SSL - for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) { - if (ftp_auth_type[z] == FTA_TLS) { - for (y = z; - y < (FTPATYPS-1) && ftp_auth_type[y]; - y++ - ) - ftp_auth_type[y] = ftp_auth_type[y+1]; - ftp_auth_type[FTPATYPS-1] = 0; - break; - } - } -#endif /* CK_SSL */ - break; - case FT_CERTFI: -#ifdef CK_SSL - makestr(&ssl_rsa_cert_file,q); -#endif /* CK_SSL */ - break; - case FT_OKCERT: -#ifdef CK_SSL - ssl_certsok_flag = 1; -#endif /* CK_SSL */ - break; - case FT_DEBUG: -#ifdef DEBUG - if (deblog) { - extern int debtim; - debtim = 1; - } else { - deblog = debopn("debug.log",0); - } -#endif /* DEBUG */ - break; - case FT_KEY: -#ifdef CK_SSL - makestr(&ssl_rsa_key_file,q); -#endif /* CK_SSL */ - break; - case FT_SECURE: - /* no equivalent */ - break; - case FT_VERIFY: -#ifdef CK_SSL - if (!rdigits(q)) - printf("?Bad number: %s\n",q); - ssl_verify_flag = atoi(q); -#endif /* CK_SSL */ - break; - } - } - if (ftp_deb) printf("\"\n"); - free(p); - break; - } -#endif /* FTP_SECURITY */ - - default: - fatal2(*xargv, - "unknown command-line option, type \"ftp -h\" for help" - ); - } - if (!xp) break; - c = *++xp; /* See if options are bundled */ - } - return(0); -} -#endif /* NOCMDL */ - -int -ftpisconnected() { - return(connected); -} - -int -ftpisloggedin() { - return(connected ? loggedin : 0); -} - -int -ftpissecure() { - return((ftp_dpl == FPL_CLR && !ssl_ftp_proxy) ? 0 : 1); -} - -static VOID -ftscreen(n, c, z, s) int n; char c; long z; char * s; { - if (displa && fdispla && !backgrd && !quiet && !out2screen) { - if (!dpyactive) { - ckscreen(SCR_PT,'S',0L,""); - dpyactive = 1; - } - ckscreen(n,c,z,s); - } -} - -#ifndef OS2 -/* g m s t i m e r -- Millisecond timer */ - -long -gmstimer() { -#ifdef HAVE_MSECS - /* For those versions of ztime() that also set global ztmsec. */ - char *p = NULL; - long z; - ztime(&p); - if (!p) return(0L); - if (!*p) return(0L); - z = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17); - return(z * 1000 + ztmsec); -#else - return((long)time(NULL) * 1000L); -#endif /* HAVE_MSECS */ -} -#endif /* OS2 */ - -/* d o s e t f t p -- The SET FTP command */ - -int -dosetftp() { - int cx; - if ((cx = cmkey(ftpset,nftpset,"","",xxstring)) < 0) /* Set what? */ - return(cx); - switch (cx) { - - case FTS_FNC: /* Filename collision action */ - if ((x = cmkey(ftpcolxtab,nftpcolx,"","",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) - return(y); - ftp_fnc = x; - return(1); - - case FTS_CNV: /* Filename conversion */ - if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) - return(y); - ftp_cnv = x; - return(1); - - case FTS_DBG: /* Debug messages */ - return(seton(&ftp_deb)); - - case FTS_LOG: /* Auto-login */ - return(seton(&ftp_log)); - - case FTS_PSV: /* Passive mode */ - return(dosetftppsv()); - - case FTS_SPC: /* Send port commands */ - x = seton(&ftp_spc); - if (x > 0) sendport = ftp_spc; - return(x); - - case FTS_TYP: /* Type */ - if ((x = cmkey(ftptyp,nftptyp,"","",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) return(y); - ftp_typ = x; - g_ftp_typ = x; - tenex = (ftp_typ == FTT_TEN); - return(1); - - case FTS_USN: /* Unique server names */ - return(seton(&ftp_usn)); - - case FTS_VBM: /* Verbose mode */ - if ((x = seton(&ftp_vbm)) < 0) /* Per-command copy */ - return(x); - ftp_vbx = ftp_vbm; /* Global sticky copy */ - return(x); - - case FTS_TST: /* "if (testing)" messages */ - return(seton(&testing)); - - case FTS_PRM: /* Send permissions */ - return(setonaut(&ftp_prm)); - - case FTS_AUT: /* Auto-authentication */ - return(seton(&ftp_aut)); - - case FTS_ERR: /* Error action */ - if ((x = cmkey(qorp,2,"","",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) - return(y); - ftp_err = x; - return(success = 1); - -#ifndef NOCSETS - case FTS_XLA: /* Translation */ - return(seton(&ftp_xla)); - - case FTS_CSR: /* Server charset */ - if ((x = cmkey(fcstab,nfilc,"character-set","utf8",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) - return(y); - ftp_csr = x; - ftp_xla = 1; /* Also enable translation */ - return(success = 1); -#endif /* NOCSETS */ - - case FTS_GFT: - return(seton(&get_auto)); /* GET-filetype-switching */ - - case FTS_DAT: - return(seton(&ftp_dates)); /* Set file dates */ - - case FTS_STO: { /* Server time offset */ - char * s, * p = NULL; - int k; - if ((x = cmfld("[+-]hh[:mm[:ss]]","+0",&s,xxstring)) < 0) - return(x); - if (!strcmp(s,"+0")) { - s = NULL; - } else if ((x = delta2sec(s,&k)) < 0) { /* Check format */ - printf("?Invalid time offset\n"); - return(-9); - } - makestr(&p,s); /* Make a safe copy the string */ - if ((x = cmcfm()) < 0) { /* Get confirmation */ - if (p) - makestr(&p,NULL); - return(x); - } - fts_sto = p; /* Confirmed - set the string. */ - return(success = 1); - } - case FTS_APW: { - char * s; - if ((x = cmtxt("Text", "", &s, xxstring)) < 0) - return(x); - makestr(&ftp_apw, *s ? s : NULL); - return(success = 1); - } - - case FTS_BUG: { - if ((x = cmkey(ftpbugtab,nftpbug,"","",xxstring)) < 0) - return(x); - switch (x) { -#ifdef CK_SSL - case FTB_SV2: - return seton(&ftp_bug_use_ssl_v2); -#endif /* CK_SSL */ - default: - return(-2); - } - } - -#ifdef FTP_SECURITY - case FTS_CRY: /* Auto-encryption */ - return(seton(&ftp_cry)); - - case FTS_CFW: /* Credential-forwarding */ - return(seton(&ftp_cfw)); - - case FTS_CPL: /* Command protection level */ - if ((x = cmkey(ftppro,nftppro,"","",xxstring)) < 0) return(x); - if ((y = cmcfm()) < 0) return(y); - success = fts_cpl(x); - return(success); - - case FTS_DPL: /* Data protection level */ - if ((x = cmkey(ftppro,nftppro,"","",xxstring)) < 0) return(x); - if ((y = cmcfm()) < 0) return(y); - success = fts_dpl(x); - return(success); - - case FTS_ATP: { /* FTP Auth Type */ - int i, j, atypes[8]; - - for (i = 0; i < 8; i++) { - if ((y = cmkey(ftpauth,nftpauth,"", - (i == 0) ? "automatic" : "", - xxstring)) < 0) { - if (y == -3) - break; - return(y); - } - if (i > 0 && (y == FTA_AUTO)) { - printf("?Choice may only be used in first position.\r\n"); - return(-9); - } - for (j = 0; j < i; j++) { - if (atypes[j] == y) { - printf("\r\n?Choice has already been used.\r\n"); - return(-9); - } - } - atypes[i] = y; - if (y == FTA_AUTO) { - i++; - break; - } - } - if (i < 8) - atypes[i] = 0; - if ((z = cmcfm()) < 0) - return(z); - if (atypes[0] == FTA_AUTO) { - i = 0; -#ifdef FTP_GSSAPI - ftp_auth_type[i++] = FTA_GK5; -#endif /* FTP_GSSAPI */ -#ifdef FTP_SRP - ftp_auth_type[i++] = FTA_SRP; -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 - ftp_auth_type[i++] = FTA_K4; -#endif /* FTP_KRB4 */ -#ifdef CK_SSL - ftp_auth_type[i++] = FTA_TLS; - ftp_auth_type[i++] = FTA_SSL; -#endif /* CK_SSL */ - ftp_auth_type[i] = 0; - } else { - for (i = 0; i < 8; i++) - ftp_auth_type[i] = atypes[i]; - } - return(success = 1); - } - - case FTS_SRP: -#ifdef FTP_SRP - if ((x = cmkey(ftpsrp,nftpsrp,"","",xxstring)) < 0) - return(x); - switch (x) { - case SRP_CIPHER: - if ((x = cmkey(ciphertab,nciphertab,"","",xxstring)) < 0) - return(x); - if ((z = cmcfm()) < 0) - return(z); - success = !srp_selcipher(ciphertab[x].kwd); - return(success); - case SRP_HASH: - if ((x = cmkey(hashtab,nhashtab,"","",xxstring)) < 0) - return(x); - if ((z = cmcfm()) < 0) - return(z); - success = !srp_selhash(hashtab[x].kwd); - return(success = 1); - default: - if ((z = cmcfm()) < 0) - return(z); - return(-2); - } -#else /* FTP_SRP */ - if ((z = cmcfm()) < 0) - return(z); - return(-2); -#endif /* FTP_SRP */ -#endif /* FTP_SECURITY */ - - case FTS_DIS: - doxdis(2); /* 2 == ftp */ - return(success = 1); - - default: - return(-2); - } -} - -int -ftpbye() { - int x; - if (!connected) - return(1); - if (testing) - printf(" ftp closing %s...\n",ftp_host); - x = ftpclose(); - return((x > -1) ? 1 : 0); -} - -/* o p e n f t p -- Parse FTP hostname & port and open */ - -static int -openftp(s,opn_tls) char * s; int opn_tls; { - char c, * p, * hostname = NULL, *hostsave = NULL, * service = NULL; - int i, n, havehost = 0, getval = 0, rc = -9, opn_psv = -1, nologin = 0; - int haveuser = 0; - struct FDB sw, fl, cm; - extern int nnetdir; /* Network services directory */ - extern int nhcount; /* Lookup result */ - extern char *nh_p[]; /* Network directory entry pointers */ - extern char *nh_p2[]; /* Network directory entry nettype */ - - if (!s) return(-2); - if (!*s) return(-2); - - makestr(&hostname,s); - hostsave = hostname; - makestr(&ftp_logname,NULL); - anonymous = 0; - noinit = 0; - - debug(F110,"ftp open",hostname,0); - - if (sav_psv > -1) { /* Restore prevailing active/passive */ - ftp_psv = sav_psv; /* selection in case it was */ - sav_psv = -1; /* temporarily overriden by a switch */ - } - if (sav_log > -1) { /* Ditto for autologin */ - ftp_log = sav_log; - sav_log = -1; - } - cmfdbi(&sw, /* Switches */ - _CMKEY, - "Service name or port;\n or switch", - "", /* default */ - "", /* addtl string data */ - nftpswi, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: none */ - xxstring, /* Processing function */ - ftpswitab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* A host name or address */ - _CMFLD, /* fcode */ - "", /* help */ - "xYzBoo", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - &cm - ); - cmfdbi(&cm, /* Command confirmation */ - _CMCFM, - "", - "", - "", - 0, - 0, - NULL, - NULL, - NULL - ); - - for (n = 0;; n++) { - rc = cmfdb(&sw); /* Parse a service name or a switch */ - if (rc < 0) - goto xopenftp; - - if (cmresult.fcode == _CMCFM) { /* Done? */ - break; - } else if (cmresult.fcode == _CMFLD) { /* Port */ - if (ckstrcmp("xYzBoo",cmresult.sresult,-1,1)) - makestr(&service,cmresult.sresult); - else - makestr(&service,opn_tls?"ftps":"ftp"); - } else if (cmresult.fcode == _CMKEY) { /* Have a switch */ - c = cmgbrk(); /* get break character */ - getval = (c == ':' || c == '='); - rc = -9; - if (getval && !(cmresult.kflags & CM_ARG)) { - printf("?This switch does not take arguments\n"); - goto xopenftp; - } - if (!getval && (cmresult.kflags & CM_ARG)) { - printf("?This switch requires an argument\n"); - goto xopenftp; - } - switch (cmresult.nresult) { /* Switch */ - case OPN_ANO: /* /ANONYMOUS */ - anonymous++; - nologin = 0; - break; - case OPN_NIN: /* /NOINIT */ - noinit++; - break; - case OPN_NOL: /* /NOLOGIN */ - nologin++; - anonymous = 0; - makestr(&ftp_logname,NULL); - break; - case OPN_PSW: /* /PASSWORD */ - if (!anonymous) /* Don't log real passwords */ - debok = 0; - rc = cmfld("Password for FTP server","",&p,xxstring); - if (rc == -3) { - makestr(&ftp_tmp,NULL); - } else if (rc < 0) { - goto xopenftp; - } else { - makestr(&ftp_tmp,brstrip(p)); - nologin = 0; - } - break; - case OPN_USR: /* /USER */ - rc = cmfld("Username for FTP server","",&p,xxstring); - if (rc == -3) { - makestr(&ftp_logname,NULL); - } else if (rc < 0) { - goto xopenftp; - } else { - nologin = 0; - anonymous = 0; - haveuser = 1; - makestr(&ftp_logname,brstrip(p)); - } - break; - case OPN_ACC: - rc = cmfld("Account for FTP server","",&p,xxstring); - if (rc == -3) { - makestr(&ftp_acc,NULL); - } else if (rc < 0) { - goto xopenftp; - } else { - makestr(&ftp_acc,brstrip(p)); - } - break; - case OPN_ACT: - opn_psv = 0; - break; - case OPN_PSV: - opn_psv = 1; - break; - case OPN_TLS: - opn_tls = 1; - break; - default: - break; - } - } - if (n == 0) { /* After first time through */ - cmfdbi(&sw, /* accept only switches */ - _CMKEY, - "\nCarriage return to confirm to command, or switch", - "", - "", - nftpswi, - 4, - xxstring, - ftpswitab, - &cm - ); - } - } -#ifdef COMMENT - debug(F100,"ftp openftp while exit","",0); - rc = cmcfm(); - debug(F101,"ftp openftp cmcfm rc","",rc); - if (rc < 0) - goto xopenftp; -#endif /* COMMENT */ - - if (opn_psv > -1) { /* /PASSIVE or /ACTIVE switch given */ - sav_psv = ftp_psv; - ftp_psv = opn_psv; - } - if (nologin || haveuser) { /* /NOLOGIN or /USER switch given */ - sav_log = ftp_log; - ftp_log = haveuser ? 1 : 0; - } - if (*hostname == '=') { /* Bypass directory lookup */ - hostname++; /* if hostname starts with '=' */ - havehost++; - } else if (isdigit(*hostname)) { /* or if it starts with a digit */ - havehost++; - } - if (!service) - makestr(&service,opn_tls?"ftps":"ftp"); - -#ifndef NODIAL - if (!havehost && nnetdir > 0) { /* If there is a networks directory */ - lunet(hostname); /* Look up the name */ - debug(F111,"ftp openftp lunet",hostname,nhcount); - if (nhcount == 0) { - if (testing) - printf(" ftp open trying \"%s %s\"...\n",hostname,service); - success = ftpopen(hostname,service,opn_tls); - debug(F101,"ftp openftp A ftpopen success","",success); - rc = success; - } else { - int found = 0; - for (i = 0; i < nhcount; i++) { - if (nh_p2[i]) /* If network type specified */ - if (ckstrcmp(nh_p2[i],"tcp/ip",strlen(nh_p2[i]),0)) - continue; - found++; - makestr(&hostname,nh_p[i]); - debug(F111,"ftpopen lunet substitution",hostname,i); - if (testing) - printf(" ftp open trying \"%s %s\"...\n",hostname,service); - success = ftpopen(hostname,service,opn_tls); - debug(F101,"ftp openftp B ftpopen success","",success); - rc = success; - if (success) - break; - } - if (!found) { /* E.g. if no network types match */ - if (testing) - printf(" ftp open trying \"%s %s\"...\n",hostname,service); - success = ftpopen(hostname,service,opn_tls); - debug(F101,"ftp openftp C ftpopen success","",success); - rc = success; - } - } - } else { -#endif /* NODIAL */ - if (testing) - printf(" ftp open trying \"%s %s\"...\n",hostname,service); - success = ftpopen(hostname,service,opn_tls); - debug(F111,"ftp openftp D ftpopen success",hostname,success); - debug(F111,"ftp openftp D ftpopen connected",hostname,connected); - rc = success; -#ifndef NODIAL - } -#endif /* NODIAL */ - - xopenftp: - debug(F101,"ftp openftp xopenftp rc","",rc); - if (hostsave) free(hostsave); - if (service) free(service); - if (rc < 0 && ftp_logname) { - free(ftp_logname); - ftp_logname = NULL; - } - if (ftp_tmp) { - free(ftp_tmp); - ftp_tmp = NULL; - } - return(rc); -} - -int -doftpacct() { - int x; - char * s; - if ((x = cmtxt("Remote account", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - makestr(&ftp_acc,brstrip(s)); - if (testing) - printf(" ftp account: \"%s\"\n",ftp_acc); - success = (ftpcmd("ACCT",ftp_acc,-1,-1,ftp_vbm) == REPLY_COMPLETE); - return(success); -} - -int -doftpusr() { /* Log in as USER */ - int x; - char *s, * acct = ""; - - debok = 0; /* Don't log */ - if ((x = cmfld("Remote username or ID","",&s,xxstring)) < 0) - return(x); - ckstrncpy(line,brstrip(s),LINBUFSIZ); /* brstrip: 15 Jan 2003 */ - if ((x = cmfld("Remote password","",&s,xxstring)) < 0) - if (x != -3) - return(x); - ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ); - if ((x = cmtxt("Remote account\n or Enter or CR to confirm the command", - "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - if (*s) { - x = strlen(tmpbuf); - if (x > 0) { - acct = &tmpbuf[x+2]; - ckstrncpy(acct,brstrip(s),TMPBUFSIZ - x - 2); - } - } - if (testing) - printf(" ftp user \"%s\" password \"%s\"...\n",line,tmpbuf); - success = ftp_user(line,tmpbuf,acct); -#ifdef CKLOGDIAL - dologftp(); -#endif /* CKLOGDIAL */ - return(success); -} - -/* DO (various FTP commands)... */ - -int -doftptyp(type) int type; { /* TYPE */ - CHECKCONN(); - ftp_typ = type; - changetype(ftp_typ,ftp_vbm); - return(1); -} - -static int -doftpxmkd(s,vbm) char * s; int vbm; { /* MKDIR action */ - int lcs = -1, rcs = -1; -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - debug(F110,"ftp doftpmkd",s,0); - if (ftpcmd("MKD",s,lcs,rcs,vbm) == REPLY_COMPLETE) - return(success = 1); - if (ftpcode == 500 || ftpcode == 502) { - if (!quiet) - printf("MKD command not recognized, trying XMKD\n"); - if (ftpcmd("XMKD",s,lcs,rcs,vbm) == REPLY_COMPLETE) - return(success = 1); - } - return(success = 0); -} - -static int -doftpmkd() { /* MKDIR parse */ - int x; - char * s; - if ((x = cmtxt("Remote directory name", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) - printf(" ftp mkdir \"%s\"...\n",line); - return(success = doftpxmkd(line,-1)); -} - -static int -doftprmd() { /* RMDIR */ - int x, lcs = -1, rcs = -1; - char * s; - if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) - printf(" ftp rmdir \"%s\"...\n",line); -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - if (ftpcmd("RMD",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE) - return(success = 1); - if (ftpcode == 500 || ftpcode == 502) { - if (!quiet) - printf("RMD command not recognized, trying XMKD\n"); - success = (ftpcmd("XRMD",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE); - } else - success = 0; - return(success); -} - -static int -doftpren() { /* RENAME */ - int x; - char * s; - if ((x = cmfld("Remote filename","",&s,xxstring)) < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - if ((x = cmfld("New name for remote file","",&s,xxstring)) < 0) - return(x); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - if ((x = cmcfm()) < 0) - return(x); - CHECKCONN(); - if (testing) - printf(" ftp rename \"%s\" (to) \"%s\"...\n",line,tmpbuf); - success = ftp_rename(line,tmpbuf); - return(success); -} - -int -doftpres() { /* RESET (log out without close) */ - int x; - if ((x = cmcfm()) < 0) - return(x); - CHECKCONN(); - if (testing) - printf(" ftp reset...\n"); - return(success = ftp_reset()); -} - -static int -doftpxhlp() { /* HELP */ - int x; - char * s; - if ((x = cmtxt("Command name", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) - printf(" ftp help \"%s\"...\n",line); - /* No need to translate -- all FTP commands are ASCII */ - return(success = (ftpcmd("HELP",line,0,0,1) == REPLY_COMPLETE)); -} - -static int -doftpdir(cx) int cx; { /* [V]DIRECTORY */ - int x, lcs = 0, rcs = 0, xlate = 0; - char * p, * s, * m = ""; - if (cx == FTP_VDI) { - switch (servertype) { - case SYS_VMS: - case SYS_DOS: - case SYS_TOPS10: - case SYS_TOPS20: - m = "*.*"; - break; - default: - m = "*"; - } - } - if ((x = cmtxt("Remote filespec",m,&s,xxstring)) < 0) - return(x); - if ((x = remtxt(&s)) < 0) - return(x); -#ifdef NOCSETS - xlate = 0; -#else - xlate = ftp_xla; -#endif /* NOCSETS */ - line[0] = NUL; - ckstrncpy(line,s,LINBUFSIZ); - s = line; - CHECKCONN(); - -#ifndef NOCSETS - if (xlate) { /* SET FTP CHARACTER-SET-TRANSLATION */ - lcs = ftp_csl; /* Local charset */ - if (lcs < 0) lcs = fcharset; - if (lcs < 0) xlate = 0; - } - if (xlate) { /* Still ON? */ - rcs = ftp_csx; /* Remote (Server) charset */ - if (rcs < 0) rcs = ftp_csr; - if (rcs < 0) xlate = 0; - } -#endif /* NOCSETS */ - - if (testing) { - p = s; - if (!p) p = ""; - if (*p) - printf("Directory of files %s at %s:\n", line, ftp_host); - else - printf("Directory of files at %s:\n", ftp_host); - } - debug(F111,"doftpdir",s,cx); - - if (cx == FTP_DIR) { - /* Translation of line[] is done inside recvrequest() */ - /* when it calls ftpcmd(). */ - return(success = - (recvrequest("LIST","-",s,"wb",0,0,NULL,xlate,lcs,rcs) == 0)); - } - success = 1; /* VDIR - one file at a time... */ - p = (char *)remote_files(1,(CHAR *)s,NULL,0); /* Get the file list */ - cancelgroup = 0; - if (!ftp_vbm && !quiet) - printlines = 1; - while (p && !cancelfile && !cancelgroup) { /* STAT one file */ - if (ftpcmd("STAT",p,lcs,rcs,ftp_vbm) < 0) { - success = 0; - break; - } - p = (char *)remote_files(0,NULL,NULL,0); /* Get next file */ - debug(F110,"ftp vdir file",s,0); - } - return(success); -} - -static int -doftppwd() { /* PWD */ - int x, lcs = -1, rcs = -1; -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - if ((x = cmcfm()) < 0) - return(x); - CHECKCONN(); - if (ftpcmd("PWD",NULL,lcs,rcs,1) == REPLY_COMPLETE) { - success = 1; - } else if (ftpcode == 500 || ftpcode == 502) { - if (ftp_deb) - printf("PWD command not recognized, trying XPWD\n"); - success = (ftpcmd("XPWD",NULL,lcs,rcs,1) == REPLY_COMPLETE); - } - return(success); -} - -static int -doftpcwd(s,vbm) char * s; int vbm; { /* CD (CWD) */ - int lcs = -1, rcs = -1; -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - - debug(F110,"ftp doftpcwd",s,0); - if (ftpcmd("CWD",s,lcs,rcs,vbm) == REPLY_COMPLETE) - return(success = 1); - if (ftpcode == 500 || ftpcode == 502) { - if (!quiet) - printf("CWD command not recognized, trying XCWD\n"); - if (ftpcmd("XCWD",s,lcs,rcs,vbm) == REPLY_COMPLETE) - return(success = 1); - } - return(success = 0); -} - -static int -doftpcdup() { /* CDUP */ - debug(F100,"ftp doftpcdup","",0); - if (ftpcmd("CDUP",NULL,0,0,1) == REPLY_COMPLETE) - return(success = 1); - if (ftpcode == 500 || ftpcode == 502) { - if (!quiet) - printf("CDUP command not recognized, trying XCUP\n"); - if (ftpcmd("XCUP",NULL,0,0,1) == REPLY_COMPLETE) - return(success = 1); - } - return(success = 0); -} - -/* s y n c d i r -- Synchronizes client & server directories */ - -/* Used with recursive PUTs; Returns 0 on failure, 1 on success */ - -static int cdlevel = 0, cdsimlvl = 0; - -static int -syncdir(local,sim) char * local; int sim; { - char buf[CKMAXPATH+1]; - char tmp[CKMAXPATH+1]; - char msgbuf[CKMAXPATH+64]; - char c, * p = local, * s = buf, * q = buf; - int i, k = 0, done = 0, itsadir = 0, saveq; - - debug(F110,"ftp syncdir local (new)",local,0); - debug(F110,"ftp syncdir putpath (old)",putpath,0); - - itsadir = isdir(local); - saveq = quiet; - - while ((*s = *p)) { /* Copy the argument filename */ - if (++k == CKMAXPATH) /* so we can poke it. */ - return(-1); - if (*s == '/') /* Pointer to rightmost dirsep */ - q = s; - s++; - p++; - } - if (!itsadir) - *q = NUL; /* Keep just the path part */ - - debug(F110,"ftp syncdir buf",buf,0); - if (!strcmp(buf,putpath)) { /* Same as for previous file? */ - if (itsadir) { /* It's a directory? */ - if (doftpcwd(local,0)) { /* Try to CD to it */ - doftpcdup(); /* Worked - CD back up */ - } else if (sim) { /* Simulating... */ - if (fdispla == XYFD_B) { - printf("WOULD CREATE DIRECTORY %s\n",local); - } else if (fdispla) { - ckmakmsg(msgbuf,CKMAXPATH, - "WOULD CREATE DIRECTORY",local,NULL,NULL); - ftscreen(SCR_ST,ST_MSG,0l,msgbuf); - } - /* See note above */ - return(0); - } else if (!doftpxmkd(local,0)) { /* Can't CD - try to create */ - return(0); - } else { - if (fdispla == XYFD_B) { - printf("CREATED DIRECTORY %s\n",local); - } else if (fdispla) { - ckmakmsg(msgbuf,CKMAXPATH+64, - "CREATED DIRECTORY ",local,NULL,NULL); - ftscreen(SCR_ST,ST_MSG,0l,msgbuf); - } - } - } - debug(F110,"ftp syncdir no change",buf,0); - return(1); /* Yes, done. */ - } - ckstrncpy(tmp,buf,CKMAXPATH+1); /* Make a safe (pre-poked) copy */ - debug(F110,"ftp syncdir new path",buf,0); /* for later (see end) */ - - p = buf; /* New */ - s = putpath; /* Old */ - - debug(F110,"ftp syncdir A p",p,0); - debug(F110,"ftp syncdir A s",s,0); - - while (*p != NUL && *s != NUL && *p == *s) p++,s++; - - if (*s == '/' && !*p) s++; /* Don't count initial slash */ - - debug(F110,"ftp syncdir B p",p,0); - debug(F110,"ftp syncdir B s",s,0); - - /* p and s now point to the leftmost spot where they differ */ - - if (*s) { /* We have to back up */ - k = 1; /* How many levels */ - while ((c = *s++)) { /* Count dirseps */ - if (c == '/' && *s) - k++; - } - for (i = 0; i < k; i++) { /* Do that many CDUPs */ - debug(F111,"ftp syncdir up",p,i+1); - if (sim && cdsimlvl) { - cdsimlvl--; - } else { - if (!doftpcdup()) { - quiet = saveq; - return(0); - } - } - cdlevel--; - } - if (!*p) /* If we don't have to go down */ - goto xcwd; /* we're done. */ - } - while (p > buf && *p && *p != '/') /* If in middle of segment */ - p--; /* back up to beginning */ - if (*p == '/') /* and terminate there */ - p++; - - s = p; /* Point to start of new down path. */ - while (1) { /* Loop through characters. */ - if (*s == '/' || !*s) { /* Have a segment. */ - if (!*s) /* If end of string, */ - done++; /* after this segment we're done. */ - else - *s = NUL; /* NUL out the separator. */ - if (*p) { /* If segment is not empty */ - debug(F110,"ftp syncdir down segment",p,0); - if (!doftpcwd(p,0)) { /* Try to CD to it */ - if (sim) { - if (fdispla == XYFD_B) { - printf("WOULD CREATE DIRECTORY %s\n",local); - } else if (fdispla) { - ckmakmsg(msgbuf,CKMAXPATH,"WOULD CREATE DIRECTORY", - local,NULL,NULL); - ftscreen(SCR_ST,ST_MSG,0l,msgbuf); - } - cdsimlvl++; - } else { - if (!doftpxmkd(p,0)) { /* Can't CD - try to create */ -/* - Suppose we are executing SEND /RECURSIVE. Locally we have a directory - FOO but the remote has a regular file with the same name. We can't CD - to it, can't MKDIR it either. There's no way out but to fail and let - the user handle the problem. -*/ - quiet = saveq; - return(0); - } - if (fdispla == XYFD_B) { - printf("CREATED DIRECTORY %s\n",p); - } else if (fdispla) { - ckmakmsg(msgbuf,CKMAXPATH, - "CREATED DIRECTORY ",p,NULL,NULL); - ftscreen(SCR_ST,ST_MSG,0l,msgbuf); - } - if (!doftpcwd(p,0)) { /* Try again to CD */ - quiet = saveq; - return(0); - } - } - } - cdlevel++; - } - if (done) /* Quit if no next segment */ - break; - p = s+1; /* Point to next segment */ - } - s++; /* Point to next source char */ - } - - xcwd: - ckstrncpy(putpath,tmp,CKMAXPATH+1); /* All OK - make this the new path */ - quiet = saveq; - return(1); -} - -#ifdef DOUPDATE -#ifdef DEBUG -static VOID -dbtime(s,xx) char * s; struct tm * xx; { /* Write struct tm to debug log */ - if (deblog) { - debug(F111,"ftp year ",s,xx->tm_year); - debug(F111,"ftp month",s,xx->tm_mon); - debug(F111,"ftp day ",s,xx->tm_mday); - debug(F111,"ftp hour ",s,xx->tm_hour); - debug(F111,"ftp min ",s,xx->tm_min); - debug(F111,"ftp sec ",s,xx->tm_sec); - } -} -#endif /* DEBUG */ - -/* t m c o m p a r e -- Compare two struct tm's */ - -/* Like strcmp() but for struct tm's */ -/* Returns -1 if xx < yy, 0 if they are equal, 1 if xx > yy */ - -static int -tmcompare(xx,yy) struct tm * xx, * yy; { - - if (xx->tm_year < yy->tm_year) /* First year less than second */ - return(-1); - if (xx->tm_year > yy->tm_year) /* First year greater than second */ - return(1); - - /* Years are equal so compare months */ - - if (xx->tm_mon < yy->tm_mon) /* And so on... */ - return(-1); - if (xx->tm_mon > yy->tm_mon) - return(1); - - if (xx->tm_mday < yy->tm_mday) - return(-1); - if (xx->tm_mday > yy->tm_mday) - return(1); - - if (xx->tm_hour < yy->tm_hour) - return(-1); - if (xx->tm_hour > yy->tm_hour) - return(1); - - if (xx->tm_min < yy->tm_min) - return(-1); - if (xx->tm_min > yy->tm_min) - return(1); - - if (xx->tm_sec < yy->tm_sec) - return(-1); - if (xx->tm_sec > yy->tm_sec) - return(1); - - return(0); -} -#endif /* DOUPDATE */ - -#ifndef HAVE_TIMEGM /* For platforms that do not have timegm() */ -static CONST int MONTHDAYS[] = { /* Number of days in each month. */ - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -/* Macro for whether a given year is a leap year. */ -#define ISLEAP(year) \ -(((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0)) -#endif /* HAVE_TIMEGM */ - -/* m k u t i m e -- Like mktime() but argument is already UTC */ - -static time_t -#ifdef CK_ANSIC -mkutime(struct tm * tm) -#else -mkutime(tm) struct tm * tm; -#endif /* CK_ANSIC */ -/* mkutime */ { -#ifdef HAVE_TIMEGM - return(timegm(tm)); /* Have system service, use it. */ -#else -/* - Contributed by Russ Allbery (rra@stanford.edu), used by permission. - Given a struct tm representing a calendar time in UTC, convert it to - seconds since epoch. Returns (time_t) -1 if the time is not - convertable. Note that this function does not canonicalize the provided - struct tm, nor does it allow out-of-range values or years before 1970. - Result should be identical with timegm(). -*/ - time_t result = 0; - int i; - /* - We do allow some ill-formed dates, but we don't do anything special - with them and our callers really shouldn't pass them to us. Do - explicitly disallow the ones that would cause invalid array accesses - or other algorithm problems. - */ -#ifdef DEBUG - if (deblog) { - debug(F101,"mkutime tm_mon","",tm->tm_mon); - debug(F101,"mkutime tm_year","",tm->tm_year); - } -#endif /* DEBUG */ - if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 70) - return((time_t) -1); - - /* Convert to time_t. */ - for (i = 1970; i < tm->tm_year + 1900; i++) - result += 365 + ISLEAP(i); - for (i = 0; i < tm->tm_mon; i++) - result += MONTHDAYS[i]; - if (tm->tm_mon > 1 && ISLEAP(tm->tm_year + 1900)) - result++; - result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour; - result = 60 * result + tm->tm_min; - result = 60 * result + tm->tm_sec; - debug(F101,"mkutime result","",result); - return(result); -#endif /* HAVE_TIMEGM */ -} - - -/* - s e t m o d t i m e -- Set file modification time. - - f = char * filename; - t = time_t date/time to set (Secs since 19700101 0:00:00 UTC, NOT local) - - UNIX-specific; isolates mainline code from hideous #ifdefs. - Returns: - 0 on success, - -1 on error. - -*/ -static int -#ifdef CK_ANSIC -setmodtime(char * f, time_t t) -#else -setmodtime(f,t) char * f; time_t t; -#endif /* CK_ANSIC */ -/* setmodtime */ { -#ifdef NT - struct _stat sb; -#else /* NT */ - struct stat sb; -#endif /* NT */ - int x, rc = 0; -#ifdef BSD44 - struct timeval tp[2]; -#else -#ifdef V7 - struct utimbuf { - time_t timep[2]; - } tp; -#else -#ifdef SYSUTIMEH -#ifdef NT - struct _utimbuf tp; -#else /* NT */ - struct utimbuf tp; -#endif /* NT */ -#else - struct utimbuf { - time_t atime; - time_t mtime; - } tp; -#endif /* SYSUTIMEH */ -#endif /* V7 */ -#endif /* BSD44 */ - - if (stat(f,&sb) < 0) { - debug(F111,"setmodtime stat failure",f,errno); - return(-1); - } -#ifdef BSD44 - tp[0].tv_sec = sb.st_atime; /* Access time first */ - tp[1].tv_sec = t; /* Update time second */ - debug(F111,"setmodtime BSD44",f,t); -#else -#ifdef V7 - tp.timep[0] = t; /* Set modif. time to creation date */ - tp.timep[1] = sb.st_atime; /* Don't change the access time */ - debug(F111,"setmodtime V7",f,t); -#else -#ifdef SYSUTIMEH - tp.modtime = t; /* Set modif. time to creation date */ - tp.actime = sb.st_atime; /* Don't change the access time */ - debug(F111,"setmodtime SYSUTIMEH",f,t); -#else - tp.mtime = t; /* Set modif. time to creation date */ - tp.atime = sb.st_atime; /* Don't change the access time */ - debug(F111,"setmodtime (other)",f,t); -#endif /* SYSUTIMEH */ -#endif /* V7 */ -#endif /* BSD44 */ - - /* Try to set the file date */ - -#ifdef BSD44 - x = utimes(f,tp); - debug(F111,"setmodtime utimes()","BSD44",x); -#else -#ifdef IRIX65 - { - /* - The following produces the nonsensical warning: - Argument of type "const struct utimbuf *" is incompatible with - parameter of type "const struct utimbuf *". If you can make it - go away, be my guest. - */ - const struct utimbuf * t2 = &tp; - x = utime(f,t2); - } -#else - x = utime(f,&tp); - debug(F111,"setmodtime utime()","other",x); -#endif /* IRIX65 */ -#endif /* BSD44 */ - if (x) - rc = -1; - - debug(F101,"setmodtime result","",rc); - return(rc); -} - - -/* - c h k m o d t i m e -- Check/Set file modification time. - - fc = function code: - 0 = Check; returns: - -1 on error, - 0 if local older than remote, - 1 if modtimes are equal, - 2 if local newer than remote. - 1 = Set (local file's modtime from remote's); returns: - -1 on error, - 0 on success. -*/ -static int -chkmodtime(local,remote,fc) char * local, * remote; int fc; { -#ifdef NT - struct _stat statbuf; -#else /* NT */ - struct stat statbuf; -#endif /* NT */ - struct tm * tmlocal = NULL; - struct tm tmremote; - int rc = 0, havedate = 0, lcs = -1, rcs = -1, flag = 0; - char * s, timebuf[64]; - - debug(F111,"chkmodtime",local,mdtmok); - if (!mdtmok) /* Server supports MDTM? */ - return(-1); /* No don't bother. */ - -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - - if (fc == 0) { - rc = stat(local,&statbuf); - if (rc == 0) { /* Get local file's mod time */ - tmlocal = gmtime(&statbuf.st_mtime); /* Convert to struct tm */ -#ifdef DEBUG - if (tmlocal) { - dbtime(local,tmlocal); - } -#endif /* DEBUG */ - } - } - /* Get remote file's mod time as yyyymmddhhmmss */ - - if (havemdtm) { /* Already got it from MLSD? */ - s = havemdtm; - flag++; - } else if (ftpcmd("MDTM",remote,lcs,rcs,0) == REPLY_COMPLETE) { - char c; - bzero((char *)&tmremote, sizeof(struct tm)); - s = ftp_reply_str; - while ((c = *s++)) { /* Skip past response code */ - if (c == SP) { - flag++; - break; - } - } - } - if (flag) { - debug(F111,"ftp chkmodtime string",s,flag); - if (fts_sto) { /* User gave server time offset? */ - char * p; - debug(F110,"ftp chkmodtime offset",fts_sto,0); - ckmakmsg(timebuf,64,s," ",fts_sto,NULL); /* Build delta time */ - if ((p = cmcvtdate(timebuf,1))) { /* Apply delta time */ - ckstrncpy(timebuf,p,64); /* Convert to MDTM format */ - timebuf[8] = timebuf[9]; /* h */ - timebuf[9] = timebuf[10]; /* h */ - timebuf[10] = timebuf[12]; /* m */ - timebuf[11] = timebuf[13]; /* m */ - timebuf[12] = timebuf[12]; /* s */ - timebuf[13] = timebuf[13]; /* s */ - timebuf[14] = NUL; - s = timebuf; - debug(F110,"ftp chkmodtime adjust",s,0); - } - } - if (flag) { /* Convert to struct tm */ - char * pat; - int y2kbug = 0; /* Seen in Kerberos 4 FTP servers */ - if (!ckstrcmp(s,"191",3,0)) { - pat = "%05d%02d%02d%02d%02d%02d"; - y2kbug++; - debug(F110,"ftp chkmodtime Y2K BUG detected",s,0); - } else { - pat = "%04d%02d%02d%02d%02d%02d"; - } - if (sscanf(s, /* Parse into struct tm */ - pat, - &(tmremote.tm_year), - &(tmremote.tm_mon), - &(tmremote.tm_mday), - &(tmremote.tm_hour), - &(tmremote.tm_min), - &(tmremote.tm_sec) - ) == 6) { - tmremote.tm_year -= (y2kbug ? 19000 : 1900); - debug(F101,"ftp chkmodtime year","",tmremote.tm_year); - tmremote.tm_mon--; - -#ifdef DEBUG - debug(F100,"SERVER TIME FOLLOWS:","",0); - dbtime(remote,&tmremote); -#endif /* DEBUG */ - - if (havedate > -1) - havedate = 1; - } - } - } else { /* Failed */ - debug(F101,"ftp chkmodtime ftpcode","",ftpcode); - if (ftpcode == 500 || /* Command unrecognized */ - ftpcode == 502 || /* Command not implemented */ - ftpcode == 202) /* Command superfluous */ - mdtmok = 0; /* Don't ask this server again */ - return(-1); - } - if (fc == 0) { /* Compare */ - if (havedate == 1) { /* Only if we have both file dates */ - /* - Compare with local file's time. We don't use - clock time (time_t) here in case of signed/unsigned - confusion, etc. - */ - int xx; -#ifdef COMMENT -#ifdef DEBUG - if (deblog) { - dbtime("LOCAL",tmlocal); - dbtime("REMOT",&tmremote); - } -#endif /* DEBUG */ -#endif /* COMMENT */ - xx = tmcompare(tmlocal,&tmremote); - debug(F101,"chkmodtime tmcompare","",xx); - return(xx + 1); - } - } else if (ftp_dates) { /* Set */ - /* - Here we must convert struct tm to time_t - without applying timezone conversion, for which - there is no portable API. The method is hidden - in mkutime(), defined above. - */ - time_t utc; - utc = mkutime(&tmremote); - debug(F111,"ftp chkmodtime mkutime",remote,utc); - if (utc != (time_t)-1) - return(setmodtime(local,utc)); - } - return(-1); -} - -/* getfile() returns: -1 on error, 0 if file received, 1 if file skipped */ - -static int -getfile(remote,local,recover,append,pipename,xlate,fcs,rcs) - char * local, * remote, * pipename; int recover, append, xlate, fcs, rcs; -/* getfile */ { - int rc = -1; - ULONG t0, t1; - -#ifdef GFTIMER - CKFLOAT sec; -#else - int sec = 0; -#endif /* GFTIMER */ - char fullname[CKMAXPATH+1]; - - debug(F110,"ftp getfile remote A",remote,0); - debug(F110,"ftp getfile local A",local,0); - debug(F110,"ftp getfile pipename",pipename,0); - if (!remote) remote = ""; - -#ifdef PATTERNS - /* Automatic type switching? */ - if (xfermode == XMODE_A && patterns && get_auto && !forcetype) { - int x; - x = matchname(remote,0,servertype); - debug(F111,"ftp getfile matchname",remote,x); - switch (x) { - case 0: ftp_typ = FTT_ASC; break; - case 1: ftp_typ = tenex ? FTT_TEN : FTT_BIN; break; - default: if (g_ftp_typ > -1) ftp_typ = g_ftp_typ; - } - changetype(ftp_typ,ftp_vbm); - binary = ftp_typ; /* For file-transfer display */ - } -#endif /* PATTERNS */ - -#ifndef NOCSETS - ftp_csx = -1; /* For file-transfer display */ - ftp_csl = -1; /* ... */ - - if (rcs > -1) /* -1 means no translation */ - if (ftp_typ == FTT_ASC) /* File type is "ascii"? */ - if (fcs < 0) /* File charset not forced? */ - fcs = fcharset; /* use prevailing FILE CHARACTER-SET */ - if (fcs > -1 && rcs > -1) { /* Set up translation functions */ - debug(F110,"ftp getfile","initxlate",0); - initxlate(rcs,fcs); /* NB: opposite order of PUT */ - ftp_csx = rcs; - ftp_csl = fcs; - } else - xlate = 0; -#endif /* NOCSETS */ - - if (!pipename && (!local || !local[0])) - local = remote; - - out2screen = !strcmp(local,"-"); - - fullname[0] = NUL; - if (pipename) { - ckstrncpy(fullname,pipename,CKMAXPATH+1); - } else { - zfnqfp(local,CKMAXPATH,fullname); - if (!fullname[0]) - ckstrncpy(fullname,local,CKMAXPATH+1); - } - if (!out2screen && displa && fdispla) { /* Screen */ - ftscreen(SCR_FN,'F',(long)pktnum,remote); - ftscreen(SCR_AN,0,0L,fullname); - ftscreen(SCR_FS,0,fsize,""); - } - tlog(F110,ftp_typ ? "ftp get BINARY:" : "ftp get TEXT:", remote, 0); - tlog(F110," as",fullname,0); - debug(F111,"ftp getfile size",remote,fsize); - debug(F111,"ftp getfile local",local,out2screen); - - ckstrncpy(filnam, pipename ? remote : local, CKMAXPATH); - - t0 = gmstimer(); /* Start time */ - debug(F111,"ftp getfile t0",remote,t0); /* ^^^ */ - rc = recvrequest("RETR", - local, - remote, - append ? "ab" : "wb", - 0, - recover, - pipename, - xlate, - fcs, - rcs - ); - t1 = gmstimer(); /* End time */ - debug(F111,"ftp getfile t1",remote,t1); - debug(F111,"ftp getfile sec",remote,(t1-t0)/1000); -#ifdef GFTIMER - sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */ - fpxfsecs = sec; /* (for doxlog()) */ -#else - sec = (t1 - t0) / 1000; - xfsecs = (int)sec; -#endif /* GFTIMER */ - debug(F111,"ftp recvrequest rc",remote,rc); - if (cancelfile || cancelgroup) { - debug(F111,"ftp get canceled",ckitoa(cancelfile),cancelgroup); - ftscreen(SCR_ST,ST_INT,0l,""); - } else if (rc > 0) { - debug(F111,"ftp get skipped",ckitoa(cancelfile),cancelgroup); - ftscreen(SCR_ST,ST_SKIP,0l,cmarg); - } else if (rc < 0) { - switch (ftpcode) { - case -4: /* Network error */ - case -2: /* File error */ - ftscreen(SCR_ST,ST_MSG,0l,ck_errstr()); - break; - case -3: - ftscreen(SCR_ST,ST_MSG,0l,"Failure to make data connection"); - break; - case -1: - ftscreen(SCR_ST,ST_INT,0l,""); /* (should be covered above) */ - break; - default: - ftscreen(SCR_ST,ST_MSG,0l,&ftp_reply_str[4]); - } - } else { /* Tudo bem */ - ftscreen(SCR_PT,'Z',0L,""); - if (rc == 0) { - ftscreen(SCR_ST,ST_OK,0L,""); /* For screen */ - makestr(&rrfspec,remote); /* For WHERE command */ - makestr(&rfspec,fullname); - } - } - if (ftp_dates) /* If FTP DATES ON... */ - if (!pipename && !out2screen) /* and it's a real file */ - if (rc < 1 && rc != -3) /* and it wasn't skipped */ - if (connected) /* and we still have a connection */ - if (zchki(local) > -1) { /* and the file wasn't discarded */ - chkmodtime(local,remote,1); /* set local file date */ - debug(F110,"ftp get set date",local,0); - } - filcnt++; /* Used by \v(filenum) */ -#ifdef TLOG - if (tralog) { - if (rc > 0) { - tlog(F100," recovery skipped","",0); - } else if (rc == 0) { - tlog(F101," complete, size", "", fsize); - } else if (cancelfile) { - tlog(F100," canceled by user","",0); - } else { - tlog(F110," failed:",ftp_reply_str,0); - } - if (!tlogfmt) - doxlog(what,local,fsize,ftp_typ,rc,""); - } -#endif /* TLOG */ - return(rc); -} - -/* putfile() returns: -1 on error, >0 if file not selected, 0 on success. */ -/* Positive return value is Skip Reason, SKP_xxx, from ckcker.h. */ - -static int -putfile(cx, - local,remote,force,moving,mvto,rnto,srvrn,x_cnv,x_usn,xft,prm,fcs,rcs,flg) - char * local, * remote, * mvto, *rnto, *srvrn; - int cx, force, moving, x_cnv, x_usn, xft, fcs, rcs, flg; - -/* putfile */ { - - char asname[CKMAXPATH+1]; - char fullname[CKMAXPATH+1]; - int k = -1, x = 0, y = 0, o = -1, rc = 0, nc = 0; - int xlate = 0, restart = 0, mt = -1; - char * s = NULL, * cmd = NULL; - ULONG t0 = 0, t1 = 0; /* Times for stats */ - int ofcs = 0, orcs = 0; - -#ifdef GFTIMER - CKFLOAT sec = 0.0; -#else - int sec = 0; -#endif /* GFTIMER */ - debug(F111,"ftp putfile flg",local,flg); - debug(F110,"ftp putfile srv_renam",srvrn,0); - debug(F101,"ftp putfile fcs","",fcs); - debug(F101,"ftp putfile rcs","",rcs); - - ofcs = fcs; /* Save charset args */ - orcs = rcs; - - sendstart = 0L; - restart = flg & PUT_RES; - if (!remote) - remote = ""; - - /* FTP protocol command to send to server */ - cmd = (cx == FTP_APP) ? "APPE" : (x_usn ? "STOU" : "STOR"); - - if (x_cnv == SET_AUTO) { /* Name conversion is auto */ - if (alike) { /* If server & client are alike */ - nc = 0; /* no conversion */ - } else { /* If they are different */ - if (servertype == SYS_UNIX || servertype == SYS_WIN32) - nc = -1; /* only minimal conversions needed */ - else /* otherwise */ - nc = 1; /* full conversion */ - } - } else /* Not auto - do what user said */ - nc = x_cnv; - - /* If Transfer Mode is Automatic, determine file type */ - if (xfermode == XMODE_A && filepeek && !pipesend) { - if (isdir(local)) { /* If it's a directory */ - k = FT_BIN; /* skip the file scan */ - } else { - debug(F110,"FTP PUT calling scanfile",local,0); - k = scanfile(local,&o,nscanfile); /* Scan the file */ - } - debug(F111,"FTP PUT scanfile",local,k); - if (k > -1 && !forcetype) { - ftp_typ = (k == FT_BIN) ? 1 : 0; - if (xft > -1 && ftp_typ != xft) { - if (flg & PUT_SIM) - tlog(F110,"ftp put SKIP (Type):", local, 0); - return(SKP_TYP); - } - if (ftp_typ == 1 && tenex) /* User said TENEX? */ - ftp_typ = FTT_TEN; - } - } -#ifndef NOCSETS - ftp_csx = -1; /* For file-transfer display */ - ftp_csl = -1; /* ... */ - - if (rcs > -1) { /* -1 means no translation */ - if (ftp_typ == 0) { /* File type is "ascii"? */ - if (fcs < 0) { /* File charset not forced? */ - if (k < 0) { /* If we didn't scan */ - fcs = fcharset; /* use prevailing FILE CHARACTER-SET */ - } else { /* If we did scan, use scan result */ - switch (k) { - case FT_TEXT: /* Unknown text */ - fcs = fcharset; - break; - case FT_7BIT: /* 7-bit text */ - fcs = dcset7; - break; - case FT_8BIT: /* 8-bit text */ - fcs = dcset8; - break; - case FT_UTF8: /* UTF-8 */ - fcs = FC_UTF8; - break; - case FT_UCS2: /* UCS-2 */ - fcs = FC_UCS2; - if (o > -1) /* Input file byte order */ - fileorder = o; - break; - default: - rcs = -1; - } - } - } - } - } - if (fcs > -1 && rcs > -1) { /* Set up translation functions */ - debug(F110,"ftp putfile","initxlate",0); - initxlate(fcs,rcs); - debug(F111,"ftp putfile rcs",fcsinfo[rcs].keyword,rcs); - xlate = 1; - ftp_csx = rcs; - ftp_csl = fcs; - } -#endif /* NOCSETS */ - - binary = ftp_typ; /* For file-transfer display */ - asname[0] = NUL; - - if (recursive) { /* If sending recursively, */ - if (!syncdir(local,flg & PUT_SIM)) /* synchronize directories. */ - return(-1); /* Don't PUT if it fails. */ - else if (isdir(local)) /* It's a directory */ - return(0); /* Don't send it! */ - } - if (*remote) { /* If an as-name template was given */ -#ifndef NOSPL - if (cmd_quoting) { /* and COMMAND QUOTING is ON */ - y = CKMAXPATH; /* evaluate it for this file */ - s = asname; - zzstring(remote,&s,&y); - } else -#endif /* NOSPL */ - ckstrncpy(asname,remote,CKMAXPATH); /* (or take it literally) */ - } else { /* No as-name */ - nzltor(local,asname,nc,0,CKMAXPATH); /* use local name strip path */ - debug(F110,"FTP PUT nzltor",asname,0); - } - /* Preliminary messages and log entries */ - - fullname[0] = NUL; - zfnqfp(local,CKMAXPATH,fullname); - if (!fullname[0]) ckstrncpy(fullname,local,CKMAXPATH+1); - fullname[CKMAXPATH] = NUL; - - if (displa && fdispla) { /* Screen */ - ftscreen(SCR_FN,'F',(long)pktnum,local); - ftscreen(SCR_AN,0,0L,asname); - ftscreen(SCR_FS,0,fsize,""); - } -#ifdef DOUPDATE - if (flg & (PUT_UPD|PUT_DIF)) { /* Date-checking modes... */ - mt = chkmodtime(fullname,asname,0); - debug(F111,"ftp putfile chkmodtime",asname,mt); - if (mt == 0 && ((flg & PUT_DIF) == 0)) { /* Local is older */ - tlog(F110,"ftp put /update SKIP (Older modtime): ",fullname,0); - ftscreen(SCR_ST,ST_SKIP,SKP_DAT,fullname); /* Skip this one */ - filcnt++; - return(SKP_DAT); - } else if (mt == 1) { /* Times are equal */ - tlog(F110,"ftp put /update SKIP (Equal modtime): ",fullname,0); - ftscreen(SCR_ST,ST_SKIP,SKP_EQU,fullname); /* Skip it */ - filcnt++; - return(SKP_DAT); - } - /* Local file is newer */ - tlog(F110,ftp_typ ? "ftp put /update BINARY:" : - "ftp put /update TEXT:", fullname, 0); - } else if (flg & PUT_RES) { - tlog(F110,ftp_typ ? "ftp put /recover BINARY:" : - "ftp put /recover TEXT:", fullname, 0); - } else { - tlog(F110,ftp_typ ? "ftp put BINARY:" : "ftp put TEXT:", fullname, 0); - } -#else - tlog(F110,ftp_typ ? "ftp put BINARY:" : "ftp put TEXT:", fullname, 0); -#endif /* DOUPDATE */ - tlog(F110," as",asname,0); - -#ifndef NOCSETS - if (xlate) { - debug(F111,"ftp putfile fcs",fcsinfo[fcs].keyword,fcs); - tlog(F110," file character set:",fcsinfo[fcs].keyword,0); - tlog(F110," server character set:",fcsinfo[rcs].keyword,0); - } else if (!ftp_typ) { - tlog(F110," character sets:","no conversion",0); - fcs = ofcs; /* Binary file but we still must */ - rcs = orcs; /* translate its name */ - } -#endif /* NOCSETS */ - - /* PUT THE FILE */ - - t0 = gmstimer(); /* Start time */ - if (flg & PUT_SIM) { /* rc > 0 is a skip reason code */ - if (flg & (PUT_UPD|PUT_DIF)) { /* (see SKP_xxx in ckcker.h) */ - rc = (mt < 0) ? /* Update mode... */ - SKP_XNX : /* Remote file doesn't exist */ - SKP_XUP; /* Remote file is older */ - } else { - rc = SKP_SIM; /* "Would be sent", period. */ - } - } else { - rc = sendrequest(cmd,local,asname,xlate,fcs,rcs,restart); - } - t1 = gmstimer(); /* End time */ - filcnt++; /* File number */ - -#ifdef GFTIMER - sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */ - fpxfsecs = sec; /* (for doxlog()) */ -#else - sec = (t1 - t0) / 1000; - xfsecs = (int)sec; -#endif /* GFTIMER */ - - debug(F111,"ftp sendrequest rc",local,rc); - - if (cancelfile || cancelgroup) { - debug(F111,"ftp put canceled",ckitoa(cancelfile),cancelgroup); - ftscreen(SCR_ST,ST_INT,0l,""); - } else if (rc > 0) { - debug(F101,"ftp put skipped",local,rc); - ftscreen(SCR_ST,ST_SKIP,rc,fullname); - } else if (rc < 0) { - debug(F111,"ftp put error",local,ftpcode); - ftscreen(SCR_ST,ST_MSG,0L,&ftp_reply_str[4]); - } else { - debug(F111,"ftp put not canceled",ckitoa(displa),fdispla); - ftscreen(SCR_PT,'Z',0L,""); - debug(F111,"ftp put ST_OK",local,rc); - ftscreen(SCR_ST,ST_OK,0L,""); - debug(F110,"ftp put old sfspec",sfspec,0); - makestr(&sfspec,fullname); /* For WHERE command */ - debug(F110,"ftp put new sfspec",sfspec,0); - debug(F110,"ftp put old srfspec",srfspec,0); - makestr(&srfspec,asname); - debug(F110,"ftp put new srfspec",srfspec,0); - } - - /* Final log entries */ - -#ifdef TLOG - if (tralog) { - if (rc > 0) { - if (rc == SKP_XNX) - tlog(F100," /simulate: WOULD BE SENT:","no remote file",0); - else if (rc == SKP_XUP) - tlog(F100," /simulate: WOULD BE SENT:","remote file older",0); - else if (rc == SKP_SIM) - tlog(F100," /simulate: WOULD BE SENT","",0); - else - tlog(F110," skipped:",gskreason(rc),0); - } else if (rc == 0) { - tlog(F101," complete, size", "", fsize); - } else if (cancelfile) { - tlog(F100," canceled by user","",0); - } else { - tlog(F110," failed:",ftp_reply_str,0); - } - if (!tlogfmt) - doxlog(what,local,fsize,ftp_typ,rc,""); - } -#endif /* TLOG */ - - if (rc < 0) /* PUT did not succeed */ - return(-1); /* so done. */ - - if (flg & PUT_SIM) /* Simulating, skip the rest. */ - return(SKP_SIM); - -#ifdef UNIX - /* Set permissions too? */ - - if (prm) { /* Change permissions? */ - s = zgperm(local); /* Get perms of local file */ - if (!s) s = ""; - x = strlen(s); - if (x > 3) s += (x - 3); - if (rdigits(s)) { - ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,s," ",asname,NULL); - x = - ftpcmd("SITE CHMOD",ftpcmdbuf,fcs,rcs,ftp_vbm) == REPLY_COMPLETE; - tlog(F110, x ? " chmod" : " chmod failed", - s, - 0 - ); - if (!x) - return(-1); - } - } -#endif /* UNIX */ - - /* Disposition of source file */ - - if (moving) { - x = zdelet(local); - tlog(F110, (x > -1) ? - " deleted" : " failed to delete", - local, - 0 - ); - if (x < 0) - return(-1); - } else if (mvto) { - x = zrename(local,mvto); - tlog(F110, (x > -1) ? - " moved source to" : " failed to move source to", - mvto, - 0 - ); - if (x < 0) - return(-1); - /* ftscreen(SCR_ST,ST_MSG,0L,mvto); */ - - } else if (rnto) { - char * s = rnto; -#ifndef NOSPL - int y; /* Pass it thru the evaluator */ - extern int cmd_quoting; /* for \v(filename) */ - if (cmd_quoting) { /* But only if cmd_quoting is on */ - y = CKMAXPATH; - s = (char *)asname; - zzstring(rnto,&s,&y); - s = (char *)asname; - } -#endif /* NOSPL */ - if (s) if (*s) { - int x; - x = zrename(local,s); - tlog(F110, (x > -1) ? - " renamed source file to" : - " failed to rename source file to", - s, - 0 - ); - if (x < 0) - return(-1); - /* ftscreen(SCR_ST,ST_MSG,0L,s); */ - } - } - - /* Disposition of destination file */ - - if (srvrn) { /* /SERVER-RENAME: */ - char * s = srvrn; -#ifndef NOSPL - int y; /* Pass it thru the evaluator */ - extern int cmd_quoting; /* for \v(filename) */ - debug(F111,"ftp putfile srvrn",s,1); - - if (cmd_quoting) { /* But only if cmd_quoting is on */ - y = CKMAXPATH; - s = (char *)fullname; /* We can recycle this buffer now */ - zzstring(srvrn,&s,&y); - s = (char *)fullname; - } -#endif /* NOSPL */ - debug(F111,"ftp putfile srvrn",s,2); - if (s) if (*s) { - int x; - x = ftp_rename(asname,s); - debug(F111,"ftp putfile ftp_rename",asname,x); - tlog(F110, (x > 0) ? - " renamed destination file to" : - " failed to rename destination file to", - s, - 0 - ); - if (x < 1) - return(-1); - } - } - return(0); -} - -/* xxout must only be used for ASCII transfers */ -static int -#ifdef CK_ANSIC -xxout(char c) -#else -xxout(c) char c; -#endif /* CK_ANSIC */ -{ -#ifndef OS2 -#ifndef VMS -#ifndef MAC -#ifndef OSK - /* For Unix, DG, Stratus, Amiga, Gemdos, other */ - if (c == '\012') { - if (zzout(dout,(CHAR)'\015') < 0) - return(-1); - ftpsnd.bytes++; - } -#else /* OSK */ - if (c == '\015') { - c = '\012'; - if (zzout(dout,(CHAR)'\015') < 0) - return(-1); - ftpsnd.bytes++; - } -#endif /* OSK */ -#else /* MAC */ - if (c == '\015') { - c = '\012'; - if (zzout(dout,(CHAR)'\015') < 0) - return(-1); - ftpsnd.bytes++; - } -#endif /* MAC */ -#endif /* VMS */ -#endif /* OS2 */ - if (zzout(dout,(CHAR)c) < 0) - return(-1); - ftpsnd.bytes++; - return(0); -} - -static int -#ifdef CK_ANSIC -scrnout(char c) -#else -scrnout(c) char c; -#endif /* CK_ANSIC */ -{ - return(putchar(c)); -} - -static int -#ifdef CK_ANSIC -pipeout(char c) -#else -pipeout(c) char c; -#endif /* CK_ANSIC */ -{ - return(zmchout(c)); -} - -static int -ispathsep(c) int c; { - switch (servertype) { - case SYS_VMS: - case SYS_TOPS10: - case SYS_TOPS20: - return(((c == ']') || (c == '>') || (c == ':')) ? 1 : 0); - case SYS_OS2: - case SYS_WIN32: - case SYS_DOS: - return(((c == '\\') || (c == '/') || (c == ':')) ? 1 : 0); - case SYS_VOS: - return((c == '>') ? 1 : 0); - default: - return((c == '/') ? 1 : 0); - } -} - -static int -iscanceled() { -#ifdef CK_CURSES - extern int ck_repaint(); -#endif /* CK_CURSES */ - int x, rc = 0; - char c = 0; - if (cancelfile) - return(1); - x = conchk(); /* Any chars waiting at console? */ - if (x-- > 0) { /* Yes... */ - c = coninc(5); /* Get one */ - switch (c) { - case 032: /* Ctrl-X or X */ - case 'z': - case 'Z': cancelgroup++; /* fall thru on purpose */ - case 030: /* Ctrl-Z or Z */ - case 'x': - case 'X': cancelfile++; rc++; break; -#ifdef CK_CURSES - case 'L': - case 'l': - case 014: /* Ctrl-L or L or Ctrl-W */ - case 027: - ck_repaint(); /* Refresh screen */ -#endif /* CK_CURSES */ - } - } - while (x-- > 0) /* Soak up any rest */ - c = coninc(1); - return(rc); -} - -/* zzsend - used by buffered output macros. */ - -static int -#ifdef CK_ANSIC -zzsend(int fd, CHAR c) -#else -zzsend(fd,c) int fd; CHAR c; -#endif /* CK_ANSIC */ -{ - int rc; - - debug(F101,"zzsend ucbufsiz","",ucbufsiz); - debug(F101,"zzsend nout","",nout); - debug(F111,"zzsend","secure?",ftpissecure()); - - if (iscanceled()) /* Check for cancellation */ - return(-9); - rc = (!ftpissecure()) ? - send(fd, (SENDARG2TYPE)ucbuf, nout, 0) : - secure_putbuf(fd, ucbuf, nout); - ucbuf[nout] = NUL; - nout = 0; - ucbuf[nout++] = c; - spackets++; - pktnum++; - if (rc > -1 && fdispla != XYFD_B) { - spktl = nout; - ftscreen(SCR_PT,'D',spackets,NULL); - } - return(rc); -} - -/* c m d l i n p u t -- Command-line PUT */ - -int -cmdlinput(stay) int stay; { - int x, rc = 0, done = 0, good = 0, status = 0; - ULONG t0, t1; /* Times for stats */ -#ifdef GFTIMER - CKFLOAT sec; -#else - int sec = 0; -#endif /* GFTIMER */ - - if (quiet) { /* -q really means quiet */ - displa = 0; - fdispla = 0; - } else { - displa = 1; - fdispla = XYFD_B; - } - testing = 0; - out2screen = 0; - dpyactive = 0; - what = W_FTP|W_SEND; - -#ifndef NOSPL - cmd_quoting = 0; -#endif /* NOSPL */ - sndsrc = nfils; - - t0 = gmstimer(); /* Record starting time */ - - while (!done && !cancelgroup) { /* Loop for all files */ - - cancelfile = 0; - x = gnfile(); /* Get next file from list(s) */ - if (x == 0) /* (see gnfile() comments...) */ - x = gnferror; - - switch (x) { - case 1: /* File to send */ - rc = putfile(FTP_PUT, /* Function (PUT, APPEND) */ - filnam, /* Local file to send */ - filnam, /* Remote name for file */ - forcetype, /* Text/binary mode forced */ - 0, /* Not moving */ - NULL, /* No move-to */ - NULL, /* No rename-to */ - NULL, /* No server-rename */ - ftp_cnv, /* Filename conversion */ - 0, /* Unique-server-names */ - -1, /* All file types */ - 0, /* No permissions */ - -1, /* No character sets */ - -1, /* No character sets */ - 0 /* No update or restart */ - ); - if (rc > -1) { - good++; - status = 1; - } - if (cancelfile) { - continue; /* Or break? */ - } - if (rc < 0) { - ftp_fai++; - } - continue; /* Or break? */ - - case 0: /* No more files, done */ - done++; - continue; - - case -2: - case -1: - printf("?%s: file not found - \"%s\"\n", - puterror ? "Fatal" : "Warning", - filnam - ); - continue; /* or break? */ - case -3: - printf("?Warning access denied - \"%s\"\n", filnam); - continue; /* or break? */ - case -5: - printf("?Too many files match\n"); - done++; - break; - case -6: - if (good < 1) - printf("?No files selected\n"); - done++; - break; - default: - printf("?getnextfile() - unknown failure\n"); - done++; - } - } - if (status > 0) { - if (cancelgroup) - status = 0; - else if (cancelfile && good < 1) - status = 0; - } - success = status; - x = success; - if (x > -1) { - lastxfer = W_FTP|W_SEND; - xferstat = success; - } - t1 = gmstimer(); /* End time */ -#ifdef GFTIMER - sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */ - if (!sec) sec = 0.001; - fptsecs = sec; -#else - sec = (t1 - t0) / 1000; - if (!sec) sec = 1; -#endif /* GFTIMER */ - tfcps = (long) (tfc / sec); - tsecs = (int)sec; - lastxfer = W_FTP|W_SEND; - xferstat = success; - if (dpyactive) - ftscreen(SCR_TC,0,0L,""); - - if (!stay) - doexit(success ? GOOD_EXIT : BAD_EXIT, -1); - return(success); -} - - -/* d o f t p p u t -- Parse and execute PUT, MPUT, and APPEND */ - -int -#ifdef CK_ANSIC -doftpput(int cx, int who) /* who == 1 for ftp, 0 for kermit */ -#else -doftpput(cx,who) int cx, who; -#endif /* CK_ANSIC */ -{ - struct FDB sf, fl, sw, cm; - int n, rc, confirmed = 0, wild = 0, getval = 0, mput = 0, done = 0; - int x_cnv = 0, x_usn = 0, x_prm = 0, putflags = 0, status = 0, good = 0; - char * s, * s2; - - int x_csl, x_csr = -1; /* Local and remote charsets */ - int x_xla = 0; - int x_recurse = 0; - char c, * p; /* Workers */ -#ifdef PUTARRAY - int range[2]; /* Array range */ - char ** ap = NULL; /* Array pointer */ - int arrayx = -1; /* Array index */ -#endif /* PUTARRAY */ - ULONG t0 = 0L, t1 = 0L; /* Times for stats */ -#ifdef GFTIMER - CKFLOAT sec; -#else - int sec = 0; -#endif /* GFTIMER */ - - struct stringint { /* Temporary array for switch values */ - char * sval; - int ival; - } pv[SND_MAX+1]; - - success = 0; /* Assume failure */ - forcetype = 0; /* No /TEXT or /BINARY given yet */ - out2screen = 0; /* Not outputting file to screen */ - putflags = 0; /* PUT options */ - x_cnv = ftp_cnv; /* Filename conversion */ - x_usn = ftp_usn; /* Unique server names */ - x_prm = ftp_prm; /* Permissions */ - if (x_prm == SET_AUTO) /* Permissions AUTO */ - x_prm = alike; - -#ifndef NOCSETS - x_csr = ftp_csr; /* Inherit global server charset */ - x_csl = ftp_csl; - if (x_csl < 0) - x_csl = fcharset; - x_xla = ftp_xla; -#endif /* NOCSETS */ - - makestr(&filefile,NULL); /* No filename list file yet. */ - makestr(&srv_renam,NULL); /* Clear /SERVER-RENAME: */ - makestr(&snd_rename,NULL); /* PUT /RENAME */ - makestr(&snd_move,NULL); /* PUT /MOVE */ - putpath[0] = NUL; /* Initialize for syncdir(). */ - puterror = ftp_err; /* Inherit global error action. */ - what = W_SEND|W_FTP; /* What we're doing (sending w/FTP) */ - asnambuf[0] = NUL; /* Clear as-name buffer */ - - if (g_ftp_typ > -1) { /* Restore TYPE if saved */ - ftp_typ = g_ftp_typ; - /* g_ftp_typ = -1; */ - } - for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */ - pv[i].sval = NULL; /* to null pointers */ - pv[i].ival = -1; /* and -1 int values */ - } - if (who == 0) { /* Called with unprefixed command */ - switch (cx) { - case XXRSEN: pv[SND_RES].ival = 1; break; - case XXCSEN: pv[SND_CMD].ival = 1; break; - case XXMOVE: pv[SND_DEL].ival = 1; break; - case XXMMOVE: pv[SND_DEL].ival = 1; /* fall thru */ - case XXMSE: mput++; break; - } - } else { - if (cx == FTP_MPU) - mput++; - } - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Filename, or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nputswi, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - putswi, /* Keyword table */ - &sf /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* 3rd FDB - local filespec */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - &cm - ); - cmfdbi(&cm, /* 4th FDB - Confirmation */ - _CMCFM, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - NULL, - NULL, - NULL - ); - - again: - cmfdbi(&sf, /* 2nd FDB - file to send */ - _CMIFI, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - /* 0 = parse files, 1 = parse files or dirs, 2 = skip symlinks */ - nolinks | x_recurse, /* addtl numeric data 1 */ - 0, /* dirflg 0 means "not dirs only" */ - xxstring, - NULL, -#ifdef COMMENT - mput ? &cm : &fl -#else - &fl -#endif /* COMMENT */ - ); - - while (1) { /* Parse zero or more switches */ - x = cmfdb(&sw); /* Parse something */ - debug(F101,"ftp put cmfdb A","",x); - debug(F101,"ftp put fcode A","",cmresult.fcode); - if (x < 0) /* Error */ - goto xputx; /* or reparse needed */ - if (cmresult.fcode != _CMKEY) /* Break out of loop if not a switch */ - break; - c = cmgbrk(); /* Get break character */ - getval = (c == ':' || c == '='); /* to see how they ended the switch */ - if (getval && !(cmresult.kflags & CM_ARG)) { - printf("?This switch does not take arguments\n"); - x = -9; - goto xputx; - } - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - x = -9; - goto xputx; - } - n = cmresult.nresult; /* Numeric result = switch value */ - debug(F101,"ftp put switch","",n); - - switch (n) { /* Process the switch */ - case SND_AFT: /* Send /AFTER:date-time */ - case SND_BEF: /* Send /BEFORE:date-time */ - case SND_NAF: /* Send /NOT-AFTER:date-time */ - case SND_NBE: /* Send /NOT-BEFORE:date-time */ - if (!getval) break; - if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) { - if (x == -3) { - printf("?Date-time required\n"); - x = -9; - } - goto xputx; - } - pv[n].ival = 1; - makestr(&(pv[n].sval),s); - break; - - case SND_ASN: /* /AS-NAME: */ - debug(F101,"ftp put /as-name getval","",getval); - if (!getval) break; - if ((x = cmfld("Name to send under","",&s,NULL)) < 0) { - if (x == -3) { - printf("?name required\n"); - x = -9; - } - goto xputx; - } - makestr(&(pv[n].sval),brstrip(s)); - debug(F110,"ftp put /as-name 1",pv[n].sval,0); - if (pv[n].sval) pv[n].ival = 1; - break; - -#ifdef PUTARRAY - case SND_ARR: /* /ARRAY */ - if (!getval) break; - ap = NULL; - if ((x = cmfld("Array name (a single letter will do)", - "", - &s, - NULL - )) < 0) { - if (x == -3) - break; - else - return(x); - } - if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) { - printf("?Bad array: %s\n",s); - return(-9); - } - if (!(ap = a_ptr[x])) { - printf("?No such array: %s\n",s); - return(-9); - } - pv[n].ival = 1; - pv[SND_CMD].ival = 0; /* Undo any conflicting ones... */ - pv[SND_RES].ival = 0; - pv[SND_FIL].ival = 0; - arrayx = x; - break; -#endif /* PUTARRAY */ - - case SND_BIN: /* /BINARY */ - case SND_TXT: /* /TEXT or /ASCII */ - case SND_TEN: /* /TENEX */ - pv[SND_BIN].ival = 0; - pv[SND_TXT].ival = 0; - pv[SND_TEN].ival = 0; - pv[n].ival = 1; - break; - -#ifdef PUTPIPE - case SND_CMD: /* These take no args */ - if (nopush) { - printf("?Sorry, system command access is disabled\n"); - x = -9; - goto xputx; - } -#ifdef PIPESEND - else if (sndfilter) { - printf("?Sorry, no PUT /COMMAND when SEND FILTER selected\n"); - x = -9; - goto xputx; - } -#endif /* PIPESEND */ - sw.hlpmsg = "Command, or switch"; /* Change help message */ - pv[n].ival = 1; /* Just set the flag */ - pv[SND_ARR].ival = 0; - break; -#endif /* PUTPIPE */ - -#ifdef CKSYMLINK - case SND_LNK: - nolinks = 0; - goto again; /* Because CMIFI params changed... */ - case SND_NLK: - nolinks = 2; - goto again; -#endif /* CKSYMLINK */ - -#ifdef FTP_RESTART - case SND_RES: /* /RECOVER (resend) */ - pv[SND_ARR].ival = 0; /* fall thru on purpose... */ -#endif /* FTP_RESTART */ - - case SND_NOB: - case SND_DEL: /* /DELETE */ - case SND_SHH: /* /QUIET */ - case SND_UPD: /* /UPDATE */ - case SND_SIM: /* /UPDATE */ - case SND_USN: /* /UNIQUE */ - pv[n].ival = 1; /* Just set the flag */ - break; - - case SND_REC: /* /RECURSIVE */ - recursive = 2; /* Must be set before cmifi() */ - x_recurse = 1; - goto again; /* Because CMIFI params changed... */ - break; - -#ifdef UNIXOROSK - case SND_DOT: /* /DOTFILES */ - matchdot = 1; - break; - case SND_NOD: /* /NODOTFILES */ - matchdot = 0; - break; -#endif /* UNIXOROSK */ - - case SND_ERR: /* /ERROR-ACTION */ - if ((x = cmkey(qorp,2,"","",xxstring)) < 0) - goto xputx; - pv[n].ival = x; - break; - - case SND_EXC: /* Excludes */ - if (!getval) break; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Pattern required\n"); - x = -9; - } - goto xputx; - } - if (s) if (!*s) s = NULL; - makestr(&(pv[n].sval),s); - if (pv[n].sval) - pv[n].ival = 1; - break; - - case SND_PRM: /* /PERMISSIONS */ - if (!getval) - x = 1; - else if ((x = cmkey(onoff,2,"","on",xxstring)) < 0) - goto xputx; - pv[SND_PRM].ival = x; - break; - -#ifdef PIPESEND - case SND_FLT: /* /FILTER */ - debug(F101,"ftp put /filter getval","",getval); - if (!getval) break; - if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) { - if (x == -3) - s = ""; - else - goto xputx; - } - if (*s) s = brstrip(s); - y = strlen(s); - for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */ - if (s[x] != '\\') continue; - if (s[x+1] == 'v') break; - } - if (x == y) { - printf( - "?Filter must contain a replacement variable for filename.\n" - ); - x = -9; - goto xputx; - } - if (s) if (!*s) s = NULL; - makestr(&(pv[n].sval),s); - if (pv[n].sval) - pv[n].ival = 1; - break; -#endif /* PIPESEND */ - - case SND_NAM: /* /FILENAMES */ - if (!getval) break; - if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0) - goto xputx; - debug(F101,"ftp put /filenames","",x); - pv[n].ival = x; - break; - - case SND_SMA: /* Smaller / larger than */ - case SND_LAR: - if (!getval) break; - if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0) - goto xputx; - pv[n].ival = y; - break; - - case SND_FIL: /* Name of file containing filenames */ - if (!getval) break; - if ((x = cmifi("Name of file containing list of filenames", - "",&s,&y,xxstring)) < 0) { - if (x == -3) { - printf("?Filename required\n"); - x = -9; - } - goto xputx; - } else if (y && iswild(s)) { - printf("?Wildcards not allowed\n"); - x = -9; - goto xputx; - } - if (s) if (!*s) s = NULL; - makestr(&(pv[n].sval),s); - if (pv[n].sval) { - pv[n].ival = 1; - pv[SND_ARR].ival = 0; - } else { - pv[n].ival = 0; - } - mput = 0; - break; - - case SND_MOV: /* MOVE after */ - case SND_REN: /* RENAME after */ - case SND_SRN: { /* SERVER-RENAME after */ - char * m = ""; - switch (n) { - case SND_MOV: - m = "device and/or directory for source file after sending"; - break; - case SND_REN: - m = "new name for source file after sending"; - break; - case SND_SRN: - m = "new name for destination file after sending"; - break; - } - if (!getval) break; - if ((x = cmfld(m, "", &s, n == SND_MOV ? xxstring : NULL)) < 0) { - if (x == -3) { - printf("%s\n", n == SND_MOV ? - "?Destination required" : - "?New name required" - ); - x = -9; - } - goto xputx; - } - if (s) if (!*s) s = NULL; - makestr(&(pv[n].sval),s ? brstrip(s) : NULL); - pv[n].ival = (pv[n].sval) ? 1 : 0; - break; - } - case SND_STA: /* Starting position (= PSEND) */ - if (!getval) break; - if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0) - goto xputx; - pv[n].ival = y; - break; - - case SND_TYP: /* /TYPE */ - if (!getval) break; - if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0) - goto xputx; - pv[n].ival = (x == 2) ? -1 : x; - break; - -#ifndef NOCSETS - case SND_CSL: /* Local character set */ - case SND_CSR: /* Remote (server) charset */ - if ((x = cmkey(fcstab,nfilc,"","",xxstring)) < 0) { - return((x == -3) ? -2 : x); - } - if (n == SND_CSL) - x_csl = x; - else - x_csr = x; - x_xla = 1; /* Overrides global OFF setting */ - break; - - case SND_XPA: /* Transparent */ - x_xla = 0; - x_csr = -1; - x_csl = -1; - break; -#endif /* NOCSETS */ - } - } -#ifdef PIPESEND - if (pv[SND_RES].ival > 0) { /* /RECOVER */ - if (sndfilter || pv[SND_FLT].ival > 0) { - printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n"); - x = -9; - goto xputx; - } - if (sfttab[0] > 0 && sfttab[SFT_REST] == 0) - printf("WARNING: Server says it doesn't support REST.\n"); - } -#endif /* PIPESEND */ - - cmarg = ""; - cmarg2 = asnambuf; - line[0] = NUL; - s = line; - wild = 0; - - switch (cmresult.fcode) { /* How did we get out of switch loop */ - case _CMIFI: /* Input filename */ - if (pv[SND_FIL].ival > 0) { - printf("?You may not give a PUT filespec and a /LISTFILE\n"); - x = -9; - goto xputx; - } - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */ - if (pv[SND_ARR].ival > 0) - ckstrncpy(asnambuf,line,CKMAXPATH); - else - wild = cmresult.nresult; /* Wild flag */ - debug(F111,"ftp put wild",line,wild); - if (!wild && !recursive && !mput) - nolinks = 0; - break; - case _CMFLD: /* Field */ - /* Only allowed with /COMMAND and /ARRAY */ - if (pv[SND_FIL].ival > 0) { - printf("?You may not give a PUT filespec and a /LISTFILE\n"); - x = -9; - goto xputx; - } - /* For MPUT it's OK to have filespecs that don't match any files */ - if (mput) - break; - if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) { -#ifdef CKROOT - if (ckrooterr) - printf("?Off limits: %s\n",cmresult.sresult); - else -#endif /* CKROOT */ - printf("?%s - \"%s\"\n", - iswild(cmresult.sresult) ? - "No files match" : "File not found", - cmresult.sresult - ); - x = -9; - goto xputx; - } - ckstrncpy(line,cmresult.sresult,LINBUFSIZ); - if (pv[SND_ARR].ival > 0) - ckstrncpy(asnambuf,line,CKMAXPATH); - break; - case _CMCFM: /* Confirmation */ - confirmed = 1; - break; - default: - printf("?Unexpected function code: %d\n",cmresult.fcode); - x = -9; - goto xputx; - } - debug(F110,"ftp put string",s,0); - debug(F101,"ftp put confirmed","",confirmed); - - /* Save and change protocol and transfer mode */ - /* Global values are restored in main parse loop */ - - g_displa = fdispla; - if (ftp_dis > -1) - fdispla = ftp_dis; - g_skipbup = skipbup; - - if (pv[SND_NOB].ival > -1) { /* /NOBACKUP (skip backup file) */ - g_skipbup = skipbup; - skipbup = 1; - } - if (pv[SND_TYP].ival > -1) { /* /TYPE */ - xfiletype = pv[SND_TYP].ival; - if (xfiletype == 2) - xfiletype = -1; - } - if (pv[SND_BIN].ival > 0) { /* /BINARY really means binary... */ - forcetype = 1; /* So skip file scan */ - ftp_typ = FTT_BIN; /* Set binary */ - } else if (pv[SND_TXT].ival > 0) { /* Similarly for /TEXT... */ - forcetype = 1; - ftp_typ = FTT_ASC; - } else if (pv[SND_TEN].ival > 0) { /* and /TENEX*/ - forcetype = 1; - ftp_typ = FTT_TEN; - } else if (ftp_cmdlin && xfermode == XMODE_M) { - forcetype = 1; - ftp_typ = binary; - g_ftp_typ = binary; - } - -#ifdef PIPESEND - if (pv[SND_CMD].ival > 0) { /* /COMMAND - strip any braces */ - debug(F110,"PUT /COMMAND before stripping",s,0); - s = brstrip(s); - debug(F110,"PUT /COMMAND after stripping",s,0); - if (!*s) { - printf("?Sorry, a command to send from is required\n"); - x = -9; - goto xputx; - } - cmarg = s; - } -#endif /* PIPESEND */ - -/* Set up /MOVE and /RENAME */ - - if (pv[SND_DEL].ival > 0 && - (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) { - printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n"); - x = -9; - goto xputx; - } -#ifdef CK_TMPDIR - if (pv[SND_MOV].ival > 0) { - int len; - char * p = pv[SND_MOV].sval; - len = strlen(p); - if (!isdir(p)) { /* Check directory */ -#ifdef CK_MKDIR - char * s = NULL; - s = (char *)malloc(len + 4); - if (s) { - strcpy(s,p); /* safe */ -#ifdef datageneral - if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; } -#else - if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; } -#endif /* datageneral */ - s[len++] = 'X'; - s[len] = NUL; -#ifdef NOMKDIR - x = -1; -#else - x = zmkdir(s); -#endif /* NOMKDIR */ - free(s); - if (x < 0) { - printf("?Can't create \"%s\"\n",p); - x = -9; - goto xputx; - } - } -#else - printf("?Directory \"%s\" not found\n",p); - x = -9; - goto xputx; -#endif /* CK_MKDIR */ - } - makestr(&snd_move,p); - } -#endif /* CK_TMPDIR */ - - if (pv[SND_REN].ival > 0) { /* /RENAME */ - char * p = pv[SND_REN].sval; - if (!p) p = ""; - if (!*p) { - printf("?New name required for /RENAME\n"); - x = -9; - goto xputx; - } - p = brstrip(p); -#ifndef NOSPL - /* If name given is wild, rename string must contain variables */ - if (wild) { - char * s = tmpbuf; - x = TMPBUFSIZ; - zzstring(p,&s,&x); - if (!strcmp(tmpbuf,p)) { - printf( - "?/RENAME for file group must contain variables such as \\v(filename)\n" - ); - x = -9; - goto xputx; - } - } -#endif /* NOSPL */ - makestr(&snd_rename,p); - debug(F110,"FTP snd_rename",snd_rename,0); - } - if (pv[SND_SRN].ival > 0) { /* /SERVER-RENAME */ - char * p = pv[SND_SRN].sval; - if (!p) p = ""; - if (!*p) { - printf("?New name required for /SERVER-RENAME\n"); - x = -9; - goto xputx; - } - p = brstrip(p); -#ifndef NOSPL - if (wild) { - char * s = tmpbuf; - x = TMPBUFSIZ; - zzstring(p,&s,&x); - if (!strcmp(tmpbuf,p)) { - printf( -"?/SERVER-RENAME for file group must contain variables such as \\v(filename)\n" - ); - x = -9; - goto xputx; - } - } -#endif /* NOSPL */ - makestr(&srv_renam,p); - debug(F110,"ftp put srv_renam",srv_renam,0); - } - if (!confirmed) { /* CR not typed yet, get more fields */ - char * lp; - if (mput) { /* MPUT or MMOVE */ - nfils = 0; /* We already have the first one */ -#ifndef NOMSEND - if (cmresult.fcode == _CMIFI) { - /* First filespec is valid */ - msfiles[nfils++] = line; /* Store pointer */ - lp = line + (int)strlen(line) + 1; /* Point past it */ - debug(F111,"ftp put mput",msfiles[nfils-1],nfils-1); - } else { - /* First filespec matches no files */ - debug(F110,"ftp put mput skipping first filespec", - cmresult.sresult, - 0 - ); - lp = line; - } - /* Parse a filespec, a "field", or confirmation */ - - cmfdbi(&sf, /* 1st FDB - file to send */ - _CMIFI, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - nolinks | x_recurse, /* addtl numeric data 1 */ - 0, /* dirflg 0 means "not dirs only" */ - xxstring, - NULL, - &fl - ); - cmfdbi(&fl, /* 2nd FDB - local filespec */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - &cm - ); - cmfdbi(&cm, /* 3rd FDB - Confirmation */ - _CMCFM, /* fcode */ - "", - "", - "", - 0, - 0, - NULL, - NULL, - NULL - ); - - while (!confirmed) { /* Get more filenames */ - x = cmfdb(&sf); /* Parse something */ - debug(F101,"ftp put cmfdb B","",x); - debug(F101,"ftp put fcode B","",cmresult.fcode); - if (x < 0) /* Error */ - goto xputx; /* or reparse needed */ - switch (cmresult.fcode) { - case _CMCFM: /* End of command */ - confirmed++; - if (nfils < 1) { - debug(F100,"ftp put mput no files match","",0); - printf("?No files match MPUT list\n"); - x = -9; - goto xputx; - } - break; - case _CMFLD: /* No match */ - debug(F110,"ftp put mput skipping",cmresult.sresult,0); - continue; - case _CMIFI: /* Good match */ - s = cmresult.sresult; - msfiles[nfils++] = lp; /* Got one, count, point to it, */ - p = lp; /* remember pointer, */ - while ((*lp++ = *s++)) /* and copy it into buffer */ - if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */ - printf("?MPUT list too long\n"); - line[0] = NUL; - x = -9; - goto xputx; - } - debug(F111,"ftp put mput adding",msfiles[nfils-1],nfils-1); - if (nfils == 1) /* Take care of \v(filespec) */ - fspec[0] = NUL; -#ifdef ZFNQFP - zfnqfp(p,TMPBUFSIZ,tmpbuf); - p = tmpbuf; -#endif /* ZFNQFP */ - if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) { - strcat(fspec,p); /* safe */ - strcat(fspec," "); /* safe */ - } else { -#ifdef COMMENT - printf("WARNING - \\v(filespec) buffer overflow\n"); -#else - debug(F101,"doxput filespec buffer overflow","",0); -#endif /* COMMENT */ - } - } - } -#endif /* NOMSEND */ - } else { /* Regular PUT */ - nfils = -1; - if ((x = cmtxt(wild ? -"\nOptional as-name template containing replacement variables \ -like \\v(filename)" : - "Optional name to send it with", - "",&p,NULL)) < 0) - goto xputx; - - if (p) if (!*p) p = NULL; - p = brstrip(p); - - if (p && *p) { - makestr(&(pv[SND_ASN].sval),p); - if (pv[SND_ASN].sval) - pv[SND_ASN].ival = 1; - debug(F110,"ftp put /as-name 2",pv[SND_ASN].sval,0); - } - } - } - /* Set cmarg2 from as-name, however we got it. */ - - CHECKCONN(); - if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !asnambuf[0]) { - char * p; - p = brstrip(pv[SND_ASN].sval); - ckstrncpy(asnambuf,p,CKMAXPATH+1); - } - debug(F110,"ftp put asnambuf",asnambuf,0); - - if (pv[SND_FIL].ival > 0) { - if (confirmed) { - if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) { - debug(F110,"ftp put can't open",pv[SND_FIL].sval,0); - printf("?Failure to open %s\n",pv[SND_FIL].sval); - x = -9; - goto xputx; - } - makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */ - debug(F110,"ftp PUT /LISTFILE opened",filefile,0); - wild = 1; - } - } - if (confirmed && !line[0] && !filefile) { -#ifndef NOMSEND - if (filehead) { /* OK if we have a SEND-LIST */ - nfils = filesinlist; - sndsrc = nfils; /* Like MSEND */ - addlist = 1; /* But using a different list... */ - filenext = filehead; - goto doput; - } -#endif /* NOMSEND */ - printf("?Filename required but not given\n"); - x = -9; - goto xputx; - } -#ifndef NOMSEND - addlist = 0; /* Don't use SEND-LIST. */ -#endif /* NOMSEND */ - - if (mput) { /* MPUT (rather than PUT) */ -#ifndef NOMSEND - cmlist = msfiles; /* List of filespecs */ - sndsrc = nfils; /* rather filespec and as-name */ -#endif /* NOMSEND */ - pipesend = 0; - } else if (filefile) { /* File contains list of filenames */ - s = ""; - cmarg = ""; - line[0] = NUL; - nfils = 1; - sndsrc = 1; - - } else if (pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) { - - /* Not MSEND, MMOVE, /LIST, or /ARRAY */ - nfils = sndsrc = -1; - if (!wild) { - y = zchki(s); - if (y < 0) { - printf("?Read access denied - \"%s\"\n", s); - x = -9; - goto xputx; - } - } - if (s != line) /* We might already have done this. */ - ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */ -#ifdef DEBUG - else - debug(F110,"doxput line=s",line,0); -#endif /* DEBUG */ - cmarg = line; /* File to send */ - } -#ifndef NOMSEND - zfnqfp(cmarg,fspeclen,fspec); /* Get full name */ -#endif /* NOMSEND */ - - if (!mput) { /* For all but MPUT... */ -#ifdef PIPESEND - if (pv[SND_CMD].ival > 0) /* /COMMAND sets pipesend flag */ - pipesend = 1; - debug(F101,"ftp put /COMMAND pipesend","",pipesend); - if (pipesend && filefile) { - printf("?Invalid switch combination\n"); - x = -9; - goto xputx; - } -#endif /* PIPESEND */ - -#ifndef NOSPL - /* If as-name given and filespec is wild, as-name must contain variables */ - if ((wild || mput) && asnambuf[0]) { - char * s = tmpbuf; - x = TMPBUFSIZ; - zzstring(asnambuf,&s,&x); - if (!strcmp(tmpbuf,asnambuf)) { - printf( - "?As-name for file group must contain variables such as \\v(filename)\n" - ); - x = -9; - goto xputx; - } - } -#endif /* NOSPL */ - } - - doput: - - if (pv[SND_SHH].ival > 0) { /* SEND /QUIET... */ - fdispla = 0; - debug(F101,"ftp put display","",fdispla); - } else { - displa = 1; - if (ftp_deb) - fdispla = XYFD_B; - } - -#ifdef PUTARRAY /* SEND /ARRAY... */ - if (pv[SND_ARR].ival > 0) { - if (!ap) { x = -2; goto xputx; } /* (shouldn't happen) */ - if (range[0] == -1) /* If low end of range not specified */ - range[0] = 1; /* default to 1 */ - if (range[1] == -1) /* If high not specified */ - range[1] = a_dim[arrayx]; /* default to size of array */ - if ((range[0] < 0) || /* Check range */ - (range[0] > a_dim[arrayx]) || - (range[1] < range[0]) || - (range[1] > a_dim[arrayx])) { - printf("?Bad array range - [%d:%d]\n",range[0],range[1]); - x = -9; - goto xputx; - } - sndarray = ap; /* Array pointer */ - sndxin = arrayx; /* Array index */ - sndxlo = range[0]; /* Array range */ - sndxhi = range[1]; - sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE); - if (!asnambuf[0]) - ckstrncpy(asnambuf,sndxnam,CKMAXPATH); - cmarg = ""; - } -#endif /* PUTARRAY */ - - moving = 0; - - if (pv[SND_ARR].ival < 1) { /* File selection & disposition... */ - if (pv[SND_DEL].ival > 0) /* /DELETE was specified */ - moving = 1; - if (pv[SND_AFT].ival > 0) /* Copy SEND criteria */ - ckstrncpy(sndafter,pv[SND_AFT].sval,19); - if (pv[SND_BEF].ival > 0) - ckstrncpy(sndbefore,pv[SND_BEF].sval,19); - if (pv[SND_NAF].ival > 0) - ckstrncpy(sndnafter,pv[SND_NAF].sval,19); - if (pv[SND_NBE].ival > 0) - ckstrncpy(sndnbefore,pv[SND_NBE].sval,19); - if (pv[SND_EXC].ival > 0) - makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT); - if (pv[SND_SMA].ival > -1) - sndsmaller = pv[SND_SMA].ival; - if (pv[SND_LAR].ival > -1) - sndlarger = pv[SND_LAR].ival; - if (pv[SND_NAM].ival > -1) - x_cnv = pv[SND_NAM].ival; - if (pv[SND_USN].ival > -1) - x_usn = pv[SND_USN].ival; - if (pv[SND_ERR].ival > -1) - puterror = pv[SND_ERR].ival; - -#ifdef DOUPDATE - if (pv[SND_UPD].ival > 0) { - if (x_usn) { - printf("?Conflicting switches: /UPDATE /UNIQUE\n"); - x = -9; - goto xputx; - } - putflags |= PUT_UPD; - ftp_dates |= 2; - } -#ifdef COMMENT - /* This works but it's useless, maybe dangerous */ - if (pv[SND_DIF].ival > 0) { - if (x_usn) { - printf("?Conflicting switches: /DATES-DIFFER /UNIQUE\n"); - x = -9; - goto xputx; - } - putflags |= PUT_DIF; - ftp_dates |= 2; - } -#endif /* COMMENT */ -#endif /* DOUPDATE */ - - if (pv[SND_SIM].ival > 0) - putflags |= PUT_SIM; - - if (pv[SND_PRM].ival > -1) { -#ifdef UNIX - if (x_usn) { - printf("?Conflicting switches: /PERMISSIONS /UNIQUE\n"); - x = -9; - goto xputx; - } - x_prm = pv[SND_PRM].ival; -#else /* UNIX */ - printf("?/PERMISSIONS switch is not supported\n"); -#endif /* UNIX */ - } -#ifdef FTP_RESTART - if (pv[SND_RES].ival > 0) { - if (!sizeok) { - printf("?PUT /RESTART can't be used because SIZE disabled.\n"); - x = -9; - goto xputx; - } - if (x_usn || putflags) { - printf("?Conflicting switches: /RECOVER %s\n", - x_usn && putflags ? "/UNIQUE /UPDATE" : - (x_usn ? "/UNIQUE" : "/UPDATE") - ); - x = -9; - goto xputx; - } -#ifndef NOCSETS - if (x_xla && - (x_csl == FC_UCS2 || - x_csl == FC_UTF8 || - x_csr == FC_UCS2 || - x_csr == FC_UTF8)) { - printf("?/RECOVER can not be used with Unicode translation\n"); - x = -9; - goto xputx; - } -#endif /* NOCSETS */ - putflags = PUT_RES; - } -#endif /* FTP_RESTART */ - } - debug(F101,"ftp PUT restart","",putflags & PUT_RES); - debug(F101,"ftp PUT update","",putflags & PUT_UPD); - -#ifdef PIPESEND - if (pv[SND_FLT].ival > 0) { /* Have SEND FILTER? */ - if (!pv[SND_FLT].sval) { - sndfilter = NULL; - } else { - sndfilter = (char *) malloc((int) strlen(pv[SND_FLT].sval) + 1); - if (sndfilter) strcpy(sndfilter,pv[SND_FLT].sval); /* safe */ - } - debug(F110,"ftp put /FILTER", sndfilter, 0); - } - if (sndfilter || pipesend) /* No /UPDATE or /RESTART */ - if (putflags) /* with pipes or filters */ - putflags = 0; -#endif /* PIPESEND */ - - tfc = 0L; /* Initialize stats and counters */ - filcnt = 0; - pktnum = 0; - spackets = 0L; - - if (wild) /* (is this necessary?) */ - cx = FTP_MPU; - - t0 = gmstimer(); /* Record starting time */ - - done = 0; /* Loop control */ - cancelgroup = 0; - - cdlevel = 0; - cdsimlvl = 0; - while (!done && !cancelgroup) { /* Loop for all files */ - /* or until canceled. */ -#ifdef FTP_PROXY - /* - If we are using a proxy, we don't use the local file list; - instead we use the list on the remote machine which we want - sent to someone else, and we use remglob() to get the names. - But in that case we shouldn't even be executing this routine; - see ftp_mput(). - */ -#endif /* FTP_PROXY */ - - cancelfile = 0; - x = gnfile(); /* Get next file from list(s) */ - - if (x == 0) /* (see gnfile() comments...) */ - x = gnferror; - debug(F111,"FTP PUT gnfile",filnam,x); - - switch (x) { - case 1: /* File to send */ - s2 = asnambuf; -#ifndef NOSPL - if (asnambuf[0]) { /* As-name */ - int n; char *p; /* to be evaluated... */ - n = TMPBUFSIZ; - p = tmpbuf; - zzstring(asnambuf,&p,&n); - s2 = tmpbuf; - debug(F110,"ftp put asname",s2,0); - } -#endif /* NOSPL */ - rc = putfile(cx, /* Function (PUT, APPEND) */ - filnam, s2, /* Name to send, as-name */ - forcetype, moving, /* Parameters from switches... */ - snd_move, snd_rename, srv_renam, - x_cnv, x_usn, xfiletype, x_prm, -#ifndef NOCSETS - x_csl, (!x_xla ? -1 : x_csr), -#else - -1, -1, -#endif /* NOCSETS */ - putflags - ); - debug(F111,"ftp put putfile rc",filnam,rc); - debug(F111,"ftp put putfile cancelfile",filnam,cancelfile); - debug(F111,"ftp put putfile cancelgroup",filnam,cancelgroup); - if (rc > -1) { - good++; - status = 1; - } - if (cancelfile) - continue; - if (rc < 0) { - ftp_fai++; - if (puterror) { - status = 0; - printf("?Fatal upload error: %s\n",filnam); - done++; - } - } - continue; - case 0: /* No more files, done */ - done++; - continue; - case -1: - printf("?%s: file not found - \"%s\"\n", - puterror ? "Fatal" : "Warning", - filnam - ); - if (puterror) { - status = 0; - done++; - break; - } - continue; - case -2: - if (puterror) { - printf("?Fatal: file not found - \"%s\"\n", filnam); - status = 0; - done++; - break; - } - continue; /* Not readable, keep going */ - case -3: - if (puterror) { - printf("?Fatal: Read access denied - \"%s\"\n", filnam); - status = 0; - done++; - break; - } - printf("?Warning access denied - \"%s\"\n", filnam); - continue; -#ifdef COMMENT - case -4: /* Canceled */ - done++; - break; -#endif /* COMMENT */ - case -5: - printf("?Too many files match\n"); - done++; - break; - case -6: - if (good < 1) - printf("?No files selected\n"); - done++; - break; - default: - printf("?getnextfile() - unknown failure\n"); - done++; - } - } - if (cdlevel > 0) { - while (cdlevel--) { - if (cdsimlvl) { - cdsimlvl--; - } else if (!doftpcdup()) - break; - } - } - if (status > 0) { - if (cancelgroup) - status = 0; - else if (cancelfile && good < 1) - status = 0; - } - success = status; - x = success; - - xputx: - if (x > -1) { -#ifdef GFTIMER - t1 = gmstimer(); /* End time */ - sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */ - if (!sec) sec = 0.001; - fptsecs = sec; -#else - sec = (t1 - t0) / 1000; - if (!sec) sec = 1; -#endif /* GFTIMER */ - tfcps = (long) (tfc / sec); - tsecs = (int)sec; - lastxfer = W_FTP|W_SEND; - xferstat = success; - if (dpyactive) - ftscreen(SCR_TC,0,0L,""); - } - for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */ - if (pv[i].sval) - free(pv[i].sval); - } - ftreset(); /* Undo switch effects */ - dpyactive = 0; - return(x); -} - - -static char ** mgetlist = NULL; /* For MGET */ -static int mgetn = 0, mgetx = 0; -static char xtmpbuf[4096]; - -/* - c m d l i n g e t - - Get files specified by -g command-line option. - File list is set up in cmlist[] by ckuusy.c; nfils is length of list. -*/ -int -cmdlinget(stay) int stay; { - int i, x, rc = 0, done = 0, good = 0, status = 0, append = 0; - int lcs = -1, rcs = -1, xlate = 0; - int first = 1; - int mget = 1; - int nc; - char * s, * s2, * s3; - ULONG t0, t1; /* Times for stats */ -#ifdef GFTIMER - CKFLOAT sec; -#else - int sec = 0; -#endif /* GFTIMER */ - - if (quiet) { /* -q really means quiet */ - displa = 0; - fdispla = 0; - } else { - displa = 1; - fdispla = XYFD_B; - } - testing = 0; - dpyactive = 0; - out2screen = 0; - what = W_FTP|W_RECV; - mgetmethod = 0; - mgetforced = 0; - - havetype = 0; - havesize = -1L; - makestr(&havemdtm,NULL); - - if (ftp_fnc < 0) - ftp_fnc = fncact; - -#ifndef NOSPL - cmd_quoting = 0; -#endif /* NOSPL */ - debug(F101,"ftp cmdlinget nfils","",nfils); - - if (ftp_cnv == CNV_AUTO) { /* Name conversion is auto */ - if (alike) { /* If server & client are alike */ - nc = 0; /* no conversion */ - } else { /* If they are different */ - if (servertype == SYS_UNIX || servertype == SYS_WIN32) - nc = -1; /* only minimal conversions needed */ - else /* otherwise */ - nc = 1; /* full conversion */ - } - } else /* Not auto - do what user said */ - nc = ftp_cnv; - - if (nfils < 1) - doexit(BAD_EXIT,-1); - - t0 = gmstimer(); /* Starting time for this batch */ - -#ifndef NOCSETS - if (xlate) { /* SET FTP CHARACTER-SET-TRANSLATION */ - lcs = ftp_csl; /* Local charset */ - if (lcs < 0) lcs = fcharset; - if (lcs < 0) xlate = 0; - } - if (xlate) { /* Still ON? */ - rcs = ftp_csx; /* Remote (Server) charset */ - if (rcs < 0) rcs = ftp_csr; - if (rcs < 0) xlate = 0; - } -#endif /* NOCSETS */ - /* - If we have only one file and it is a directory, then we ask for a - listing of its contents, rather than retrieving the directory file - itself. This is what (e.g.) Netscape does. - */ - if (nfils == 1) { - if (doftpcwd((char *)cmlist[mgetx],-1)) { - /* If we can CD to it, it must be a directory */ - if (recursive) { - cmlist[mgetx] = "*"; - } else { - status = - (recvrequest("LIST","-","","wb",0,0,NULL,xlate,lcs,rcs)==0); - done = 1; - } - } - } -/* - The following is to work around UNIX servers which, when given a command - like "NLST path/blah" (not wild) returns the basename without the path. -*/ - if (!done && servertype == SYS_UNIX && nfils == 1) { - mget = iswild(cmlist[mgetx]); - } - if (!mget && !done) { /* Invoked by command-line FTP URL */ - if (ftp_deb) - printf("DOING GET...\n"); - done++; - cancelfile = 0; /* This file not canceled yet */ - s = cmlist[mgetx]; - rc = 0; /* Initial return code */ - fsize = -1L; - if (sizeok) { - x = ftpcmd("SIZE",s,lcs,rcs,ftp_vbm); /* Get remote file's size */ - if (x == REPLY_COMPLETE) - fsize = atol(&ftp_reply_str[4]); - } - ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */ - debug(F111,"ftp cmdlinget filnam",filnam,fsize); - - nzrtol(s,tmpbuf,nc,0,CKMAXPATH); /* Strip path and maybe convert */ - s2 = tmpbuf; - - /* If local file already exists, take collision action */ - - x = zchki(s2); - if (x > -1) { - switch (ftp_fnc) { - case XYFX_A: /* Append */ - append = 1; - break; - case XYFX_R: /* Rename */ - case XYFX_B: { /* Backup */ - char * p = NULL; - int x = -1; - znewn(s2,&p); /* Make unique name */ - debug(F110,"ftp cmdlinget znewn",p,0); - if (ftp_fnc == XYFX_B) { /* Backup existing file */ - x = zrename(s2,p); - debug(F111,"ftp cmdlinget backup zrename",p,x); - } else { /* Rename incoming file */ - x = ckstrncpy(tmpbuf,p,CKMAXPATH+1); - s2 = tmpbuf; - debug(F111,"ftp cmdlinget rename incoming",p,x); - } - if (x < 0) { - printf("?Backup/Rename failed\n"); - return(success = 0); - } - break; - } - case XYFX_D: /* Discard */ - ftscreen(SCR_FN,'F',0L,s); - ftscreen(SCR_ST,ST_SKIP,SKP_NAM,s); - tlog(F100," refused: name","",0); - debug(F110,"ftp cmdlinget skip name",s2,0); - goto xclget; - - case XYFX_X: /* Overwrite */ - case XYFX_U: /* Update (already handled above) */ - case XYFX_M: /* ditto */ - break; - } - } - rc = getfile(s, /* Remote name */ - s2, /* Local name */ - 0, /* Recover/Restart */ - append, /* Append */ - NULL, /* Pipename */ - 0, /* Translate charsets */ - -1, /* File charset (none) */ - -1 /* Server charset (none) */ - ); - debug(F111,"ftp cmdlinget rc",s,rc); - debug(F111,"ftp cmdlinget cancelfile",s,cancelfile); - debug(F111,"ftp cmdlinget cancelgroup",s,cancelgroup); - - if (rc < 0 && haveurl && s[0] == '/') /* URL failed - try again */ - rc = getfile(&s[1], /* Remote name without leading '/' */ - s2, /* Local name */ - 0, /* Recover/Restart */ - append, /* Append */ - NULL, /* Pipename */ - 0, /* Translate charsets */ - -1, /* File charset (none) */ - -1 /* Server charset (none) */ - ); - if (rc > -1) { - good++; - status = 1; - } - if (cancelfile) - goto xclget; - if (rc < 0) { - ftp_fai++; - if (geterror) { - status = 0; - done++; - } - } - } - if (ftp_deb && !done) - printf("DOING MGET...\n"); - while (!done && !cancelgroup) { - cancelfile = 0; /* This file not canceled yet */ - s = (char *)remote_files(first,(CHAR *)cmlist[mgetx],NULL,0); - if (!s) s = ""; - if (!*s) { - first = 1; - mgetx++; - if (mgetx < nfils) - s = (char *)remote_files(first,(CHAR *)cmlist[mgetx],NULL,0); - else - s = NULL; - debug(F111,"ftp cmdlinget remote_files B",s,0); - if (!s) { - done = 1; - break; - } - } - /* - The semantics of NLST are ill-defined. Suppose we have just sent - NLST /path/[a-z]*. Most servers send back names like /path/foo, - /path/bar, etc. But some send back only foo and bar, and subsequent - RETR commands based on the pathless names are not going to work. - */ - if (servertype == SYS_UNIX && !ckstrchr(s,'/')) { - if ((s3 = ckstrrchr(cmlist[mgetx],'/'))) { - int len, left = 4096; - char * tmp = xtmpbuf; - len = s3 - cmlist[mgetx] + 1; - ckstrncpy(tmp,cmlist[mgetx],left); - tmp += len; - left -= len; - ckstrncpy(tmp,s,left); - s = xtmpbuf; - debug(F111,"ftp cmdlinget remote_files X",s,0); - } - } - first = 0; /* Not first any more */ - - debug(F111,"ftp cmdlinget havetype",s,havetype); - if (havetype > 0 && havetype != FTYP_FILE) { /* Server says not file */ - debug(F110,"ftp cmdlinget not-a-file",s,0); - continue; - } - rc = 0; /* Initial return code */ - if (havesize > -1L) { /* Already have file size? */ - fsize = havesize; - } else { /* No - must ask server */ - /* - Prior to sending the NLST command we necessarily put the - server into ASCII mode. We must now put it back into the - the requested mode so the upcoming SIZE command returns - right kind of size; this is especially important for - GET /RECOVER; otherwise the server returns the "ASCII" size - of the file, rather than its true size. - */ - changetype(ftp_typ,0); /* Change to requested type */ - fsize = -1L; - if (sizeok) { - x = ftpcmd("SIZE",s,lcs,rcs,ftp_vbm); - if (x == REPLY_COMPLETE) - fsize = atol(&ftp_reply_str[4]); - } - } - ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */ - debug(F111,"ftp cmdlinget filnam",filnam,fsize); - - nzrtol(s,tmpbuf,nc,0,CKMAXPATH); /* Strip path and maybe convert */ - s2 = tmpbuf; - - /* If local file already exists, take collision action */ - - x = zchki(s2); - if (x > -1) { - switch (ftp_fnc) { - case XYFX_A: /* Append */ - append = 1; - break; - case XYFX_R: /* Rename */ - case XYFX_B: { /* Backup */ - char * p = NULL; - int x = -1; - znewn(s2,&p); /* Make unique name */ - debug(F110,"ftp cmdlinget znewn",p,0); - if (ftp_fnc == XYFX_B) { /* Backup existing file */ - x = zrename(s2,p); - debug(F111,"ftp cmdlinget backup zrename",p,x); - } else { /* Rename incoming file */ - x = ckstrncpy(tmpbuf,p,CKMAXPATH+1); - s2 = tmpbuf; - debug(F111,"ftp cmdlinget rename incoming",p,x); - } - if (x < 0) { - printf("?Backup/Rename failed\n"); - return(success = 0); - } - break; - } - case XYFX_D: /* Discard */ - ftscreen(SCR_FN,'F',0L,s); - ftscreen(SCR_ST,ST_SKIP,SKP_NAM,s); - tlog(F100," refused: name","",0); - debug(F110,"ftp cmdlinget skip name",s2,0); - continue; - case XYFX_X: /* Overwrite */ - case XYFX_U: /* Update (already handled above) */ - case XYFX_M: /* ditto */ - break; - } - } - /* ^^^ ADD CHARSET STUFF HERE ^^^ */ - rc = getfile(s, /* Remote name */ - s2, /* Local name */ - 0, /* Recover/Restart */ - append, /* Append */ - NULL, /* Pipename */ - 0, /* Translate charsets */ - -1, /* File charset (none) */ - -1 /* Server charset (none) */ - ); - debug(F111,"ftp cmdlinget rc",s,rc); - debug(F111,"ftp cmdlinget cancelfile",s,cancelfile); - debug(F111,"ftp cmdlinget cancelgroup",s,cancelgroup); - - if (rc > -1) { - good++; - status = 1; - } - if (cancelfile) - continue; - if (rc < 0) { - ftp_fai++; - if (geterror) { - status = 0; - done++; - } - } - } - - xclget: - if (cancelgroup) - mlsreset(); - if (status > 0) { - if (cancelgroup) - status = 0; - else if (cancelfile && good < 1) - status = 0; - } - success = status; - -#ifdef GFTIMER - t1 = gmstimer(); /* End time */ - sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */ - if (!sec) sec = 0.001; - fptsecs = sec; -#else - sec = (t1 - t0) / 1000; - if (!sec) sec = 1; -#endif /* GFTIMER */ - - tfcps = (long) (tfc / sec); - tsecs = (int)sec; - lastxfer = W_FTP|W_RECV; - xferstat = success; - if (dpyactive) - ftscreen(SCR_TC,0,0L,""); - if (!stay) - doexit(success ? GOOD_EXIT : BAD_EXIT, -1); - return(success); -} - -/* d o f t p g e t -- Parse and execute GET, MGET, MDELETE, ... */ - -/* - Note: if we wanted to implement /AFTER:, /BEFORE:, etc, we could use - zstrdat() to convert to UTC-based time_t. But it doesn't make sense from - the user-interface perspective, since the server's directory listings show - its own local times and since we don't know what timezone it's in, there's - no way to reconcile our local times with the server's. -*/ -int -doftpget(cx,who) int cx, who; { /* who == 1 for ftp, 0 for kermit */ - struct FDB fl, sw, cm; - int i, n, rc, getval = 0, mget = 0, done = 0, pipesave = 0; - int x_cnv = 0, x_prm = 0, restart = 0, status = 0, good = 0; - int x_fnc = 0, first = 0, skipthis = 0, append = 0, selected = 0; - int renaming = 0, mdel = 0, listfile = 0, updating = 0, getone = 0; - int moving = 0, deleting = 0, toscreen = 0, haspath = 0; - int gotsize = 0; - int matchdot = 0; - long getlarger = -1, getsmaller = -1; - char * msg, * s, * s2, * nam, * pipename = NULL, * pn = NULL; - char * src = "", * local = ""; - char * pat = ""; - - int x_csl = -1, x_csr = -1; /* Local and remote charsets */ - int x_xla = 0; - char c; /* Worker char */ - ULONG t0 = 0L, t1; /* Times for stats */ -#ifdef GFTIMER - CKFLOAT sec; -#else - int sec = 0; -#endif /* GFTIMER */ - - struct stringint { /* Temporary array for switch values */ - char * sval; - int ival; - } pv[SND_MAX+1]; - - success = 0; /* Assume failure */ - forcetype = 0; /* No /TEXT or /BINARY given yet */ - restart = 0; /* No restart yet */ - out2screen = 0; /* No TO-SCREEN switch given yet */ - mgetmethod = 0; /* No NLST or MLSD switch yet */ - mgetforced = 0; - - g_displa = fdispla; - if (ftp_dis > -1) - fdispla = ftp_dis; - - x_cnv = ftp_cnv; /* Filename conversion */ - if (x_cnv == CNV_AUTO) { /* Name conversion is auto */ - if (alike) { /* If server & client are alike */ - x_cnv = 0; /* no conversion */ - } else { /* If they are different */ - if (servertype == SYS_UNIX || servertype == SYS_WIN32) - x_cnv = -1; /* only minimal conversions needed */ - else /* otherwise */ - x_cnv = 1; /* full conversion */ - } - } else /* Not auto - do what user said */ - x_cnv = ftp_cnv; - - x_prm = ftp_prm; /* Permissions */ - if (x_prm == SET_AUTO) /* Permissions AUTO */ - x_prm = alike; - -#ifndef NOCSETS - x_csr = ftp_csr; /* Inherit global server charset */ - x_csl = ftp_csl; /* Inherit global local charset */ - if (x_csl < 0) /* If none, use current */ - x_csl = fcharset; /* file character-set. */ - x_xla = ftp_xla; /* Translation On/Off */ -#endif /* NOCSETS */ - - geterror = ftp_err; /* Inherit global error action. */ - asnambuf[0] = NUL; /* No as-name yet. */ - pipesave = pipesend; - pipesend = 0; - - havetype = 0; - havesize = -1L; - makestr(&havemdtm,NULL); - - if (g_ftp_typ > -1) { /* Restore TYPE if saved */ - ftp_typ = g_ftp_typ; - /* g_ftp_typ = -1; */ - } - for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */ - pv[i].sval = NULL; /* to null pointers */ - pv[i].ival = -1; /* and -1 int values */ - } - zclose(ZMFILE); /* In case it was left open */ - - x_fnc = ftp_fnc > -1 ? ftp_fnc : fncact; /* Filename collision action */ - - if (fp_nml) { /* Reset /NAMELIST */ - if (fp_nml != stdout) - fclose(fp_nml); - fp_nml = NULL; - } - makestr(&ftp_nml,NULL); - - /* Initialize list of remote filespecs */ - - if (!mgetlist) { - mgetlist = (char **)malloc(MGETMAX * sizeof(char *)); - if (!mgetlist) { - printf("?Memory allocation failure - MGET list\n"); - return(-9); - } - for (i = 0; i < MGETMAX; i++) - mgetlist[i] = NULL; - } - mgetn = 0; /* Number of mget arguments */ - mgetx = 0; /* Current arg */ - - if (who == 0) { /* Called with unprefixed command */ - if (cx == XXGET || cx == XXREGET || cx == XXRETR) - getone++; - switch (cx) { - case XXREGET: pv[SND_RES].ival = 1; break; - case XXRETR: pv[SND_DEL].ival = 1; break; - case XXGET: - case XXMGET: mget++; break; - } - } else { /* FTP command */ - if (cx == FTP_GET || cx == FTP_RGE) - getone++; - switch (cx) { - case FTP_DEL: /* (fall thru on purpose) */ - case FTP_MDE: mdel++; /* (ditto) */ - case FTP_GET: /* (ditto) */ - case FTP_MGE: mget++; break; - case FTP_RGE: pv[SND_RES].ival = 1; break; - } - } - cmfdbi(&sw, /* First FDB - command switches */ - _CMKEY, /* fcode */ - "Remote filename;\n or switch", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - mdel ? ndelswi : ngetswi, /* addtl numeric data 1: tbl size */ - 4, /* addtl numeric data 2: 4 = cmswi */ - xxstring, /* Processing function */ - mdel ? delswi : getswi, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* 2nd FDB - remote filename */ - _CMFLD, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - &cm - ); - cmfdbi(&cm, /* 3rd FDB - Confirmation */ - _CMCFM, /* fcode */ - "", /* hlpmsg */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - NULL, - NULL, - NULL - ); - - while (1) { /* Parse 0 or more switches */ - x = cmfdb(&sw); /* Parse something */ - debug(F101,"ftp get cmfdb","",x); - if (x < 0) /* Error */ - goto xgetx; /* or reparse needed */ - if (cmresult.fcode != _CMKEY) /* Break out of loop if not a switch */ - break; - c = cmgbrk(); /* Get break character */ - getval = (c == ':' || c == '='); /* to see how they ended the switch */ - if (getval && !(cmresult.kflags & CM_ARG)) { - printf("?This switch does not take arguments\n"); - x = -9; - goto xgetx; - } - n = cmresult.nresult; /* Numeric result = switch value */ - debug(F101,"ftp get switch","",n); - - if (!getval && (cmgkwflgs() & CM_ARG)) { - printf("?This switch requires an argument\n"); - x = -9; - goto xgetx; - } - switch (n) { /* Process the switch */ - case SND_ASN: /* /AS-NAME: */ - debug(F101,"ftp get /as-name getval","",getval); - if (!getval) break; - if ((x = cmfld("Name to store it under","",&s,NULL)) < 0) { - if (x == -3) { - printf("?name required\n"); - x = -9; - } - goto xgetx; - } - s = brstrip(s); - if (!*s) s = NULL; - makestr(&(pv[n].sval),s); - pv[n].ival = 1; - break; - - case SND_BIN: /* /BINARY */ - case SND_TXT: /* /TEXT or /ASCII */ - case SND_TEN: /* /TENEX */ - pv[SND_BIN].ival = 0; - pv[SND_TXT].ival = 0; - pv[SND_TEN].ival = 0; - pv[n].ival = 1; - break; - -#ifdef PUTPIPE - case SND_CMD: /* These take no args */ - if (nopush) { - printf("?Sorry, system command access is disabled\n"); - x = -9; - goto xgetx; - } -#ifdef PIPESEND - else if (rcvfilter) { - printf("?Sorry, no PUT /COMMAND when SEND FILTER selected\n"); - x = -9; - goto xgetx; - } -#endif /* PIPESEND */ - sw.hlpmsg = "Command, or switch"; /* Change help message */ - pv[n].ival = 1; /* Just set the flag */ - pv[SND_ARR].ival = 0; - break; -#endif /* PUTPIPE */ - - case SND_SHH: /* /QUIET */ - case SND_RES: /* /RECOVER (reget) */ - case SND_NOB: /* /NOBACKUPFILES */ - case SND_DEL: /* /DELETE */ - case SND_UPD: /* /UPDATE */ - case SND_USN: /* /UNIQUE */ - case SND_NOD: /* /NODOTFILES */ - case SND_REC: /* /RECOVER */ - case SND_MAI: /* /TO-SCREEN */ - pv[n].ival = 1; /* Just set the flag */ - break; - - case SND_DIF: /* /DATES-DIFFER */ - pv[SND_COL].ival = XYFX_M; /* Now it's a collision option */ - pv[n].ival = 1; - break; - - case SND_COL: /* /COLLISION: */ - if ((x = cmkey(ftpcolxtab,nftpcolx,"","",xxstring)) < 0) - goto xgetx; - if (x == XYFX_M) - pv[SND_DIF].ival = 1; /* (phase this out) */ - pv[n].ival = x; /* this should be sufficient */ - break; - - case SND_ERR: /* /ERROR-ACTION */ - if ((x = cmkey(qorp,2,"","",xxstring)) < 0) - goto xgetx; - pv[n].ival = x; - break; - - case SND_EXC: /* Exception list */ - if (!getval) break; - if ((x = cmfld("Pattern","",&s,xxstring)) < 0) { - if (x == -3) { - printf("?Pattern required\n"); - x = -9; - } - goto xgetx; - } - if (s) if (!*s) s = NULL; - makestr(&(pv[n].sval),s); - if (pv[n].sval) - pv[n].ival = 1; - break; - -#ifdef PIPESEND - case SND_FLT: - debug(F101,"ftp get /filter getval","",getval); - if (!getval) break; - if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) { - if (x == -3) - s = ""; - else - goto xgetx; - } - s = brstrip(s); - if (pv[SND_MAI].ival < 1) { - y = strlen(s); - /* Make sure they included "\v(...)" */ - for (x = 0; x < y; x++) { - if (s[x] != '\\') continue; - if (s[x+1] == 'v') break; - } - if (x == y) { - printf( - "?Filter must contain a replacement variable for filename.\n" - ); - x = -9; - goto xgetx; - } - } - if (*s) { - pv[n].ival = 1; - makestr(&(pv[n].sval),s); - } else { - pv[n].ival = 0; - makestr(&(pv[n].sval),NULL); - } - break; -#endif /* PIPESEND */ - - case SND_NAM: - if (!getval) break; - if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0) - goto xgetx; - debug(F101,"ftp get /filenames","",x); - pv[n].ival = x; - break; - - case SND_SMA: /* Smaller / larger than */ - case SND_LAR: - if (!getval) break; - if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0) - goto xgetx; - pv[n].ival = y; - break; - - case SND_FIL: /* Name of file containing filnames */ - if (!getval) break; - if ((x = cmifi("Name of file containing list of filenames", - "",&s,&y,xxstring)) < 0) { - if (x == -3) { - printf("?Filename required\n"); - x = -9; - } - goto xgetx; - } else if (y && iswild(s)) { - printf("?Wildcards not allowed BBB\n"); - x = -9; - goto xgetx; - } - if (s) if (!*s) s = NULL; - makestr(&(pv[n].sval),s); - if (pv[n].sval) - pv[n].ival = 1; - break; - - case SND_MOV: /* MOVE after */ - case SND_REN: /* RENAME after */ - case SND_SRN: { /* SERVER-RENAME */ - char * m = ""; - switch (n) { - case SND_MOV: - m = - "Device and/or directory for incoming file after reception"; - break; - case SND_REN: - m = "New name for incoming file after reception"; - break; - case SND_SRN: - m = "New name for source file on server after reception"; - break; - } - if (!getval) break; - if ((x = cmfld(m, "", &s, n == SND_MOV ? xxstring : NULL)) < 0) { - if (x == -3) { - printf("%s\n", n == SND_MOV ? - "?Destination required" : - "?New name required" - ); - x = -9; - } - goto xgetx; - } - makestr(&(pv[n].sval),*s ? brstrip(s) : NULL); - pv[n].ival = (pv[n].sval) ? 1 : 0; - break; - } -#ifndef NOCSETS - case SND_CSL: /* Local character set */ - case SND_CSR: /* Remote (server) charset */ - if ((x = cmkey(fcstab,nfilc,"","",xxstring)) < 0) - return((x == -3) ? -2 : x); - if (n == SND_CSL) - x_csl = x; - else - x_csr = x; - x_xla = 1; /* Overrides global OFF setting */ - break; - - case SND_XPA: /* Transparent */ - x_xla = 0; - x_csr = -1; - x_csl = -1; - break; -#endif /* NOCSETS */ - - case SND_NML: - if ((x = cmofi("Local filename","-",&s,xxstring)) < 0) - goto xgetx; - makestr(&ftp_nml,s); - break; - - case SND_PAT: /* /PATTERN: */ - if (!getval) break; - if ((x = cmfld("Pattern","*", &s, xxstring)) < 0) - goto xgetx; - makestr(&(pv[n].sval),*s ? brstrip(s) : NULL); - pv[n].ival = (pv[n].sval) ? 1 : 0; - break; - - case SND_NLS: /* /NLST */ - pv[n].ival = 1; /* Use NLST */ - pv[SND_MLS].ival = 0; /* Don't use MLSD */ - break; - - case SND_MLS: /* /MLSD */ - pv[n].ival = 1; /* Use MLSD */ - pv[SND_NLS].ival = 0; /* Don't use NLST */ - break; - - default: /* /AFTER, /PERMISSIONS, etc... */ - printf("?Sorry, \"%s\" works only with [M]PUT\n",atmbuf); - x = -9; - goto xgetx; - } - } - line[0] = NUL; - cmarg = line; - cmarg2 = asnambuf; - s = line; -/* - For GET, we want to parse an optional as-name, like with PUT. - For MGET, we must parse a list of names, and then send NLST or MLSD - commands for each name separately. -*/ - switch (cmresult.fcode) { /* How did we get out of switch loop */ - case _CMFLD: /* Field */ - if (!getone) { - s = brstrip(cmresult.sresult); - makestr(&(mgetlist[mgetn++]),s); - while ((x = cmfld("Remote filename","",&s,xxstring)) != -3) { - if (x < 0) - goto xgetx; - makestr(&(mgetlist[mgetn++]),brstrip(s)); - if (mgetn >= MGETMAX) { - printf("?Too many items in MGET list\n"); - goto xgetx; - } - } - if ((x = cmcfm()) < 0) - goto xgetx; - } else { - s = brstrip(cmresult.sresult); - ckstrncpy(line,s,LINBUFSIZ); - if ((x = cmfld("Name to store it under","",&s,xxstring)) < 0) - if (x != -3) - goto xgetx; - s = brstrip(s); - ckstrncpy(asnambuf,s,CKMAXPATH+1); - if ((x = cmcfm()) < 0) - goto xgetx; - } - break; - case _CMCFM: /* Confirmation */ - break; - default: - printf("?Unexpected function code: %d\n",cmresult.fcode); - x = -9; - goto xgetx; - } - if (pv[SND_REC].ival > 0) /* /RECURSIVE */ - recursive = 2; - - if (pv[SND_BIN].ival > 0) { /* /BINARY really means binary... */ - forcetype = 1; /* So skip the name-pattern match */ - ftp_typ = XYFT_B; /* Set binary */ - } else if (pv[SND_TXT].ival > 0) { /* Similarly for /TEXT... */ - forcetype = 1; - ftp_typ = XYFT_T; - } else if (pv[SND_TEN].ival > 0) { /* and /TENEX*/ - forcetype = 1; - ftp_typ = FTT_TEN; - } else if (ftp_cmdlin && xfermode == XMODE_M) { - forcetype = 1; - ftp_typ = binary; - g_ftp_typ = binary; - } - if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !asnambuf[0]) { - char * p; - p = brstrip(pv[SND_ASN].sval); /* As-name */ - ckstrncpy(asnambuf,p,CKMAXPATH+1); - } - debug(F110,"ftp get asnambuf",asnambuf,0); - -#ifdef PIPESEND - if (pv[SND_CMD].ival > 0) { /* /COMMAND - strip any braces */ - char * p; - p = asnambuf; - debug(F110,"GET /COMMAND before stripping",p,0); - p = brstrip(p); - debug(F110,"GET /COMMAND after stripping",p,0); - if (!*p) { - printf("?Sorry, a command to write to is required\n"); - x = -9; - goto xgetx; - } - pipename = p; - pipesend = 1; - } -#endif /* PIPESEND */ - -/* Set up /MOVE and /RENAME */ - - if (pv[SND_DEL].ival > 0 && - (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) { - printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n"); - x = -9; - goto xgetx; - } -#ifdef CK_TMPDIR - if (pv[SND_MOV].ival > 0 && pv[SND_MOV].sval) { - int len; - char * p = pv[SND_MOV].sval; - len = strlen(p); - if (!isdir(p)) { /* Check directory */ -#ifdef CK_MKDIR - char * s = NULL; - s = (char *)malloc(len + 4); - if (s) { - strcpy(s,p); /* safe */ -#ifdef datageneral - if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; } -#else - if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; } -#endif /* datageneral */ - s[len++] = 'X'; - s[len] = NUL; -#ifdef NOMKDIR - x = -1; -#else - x = zmkdir(s); -#endif /* NOMKDIR */ - free(s); - if (x < 0) { - printf("?Can't create \"%s\"\n",p); - x = -9; - goto xgetx; - } - } -#else - printf("?Directory \"%s\" not found\n",p); - x = -9; - goto xgetx; -#endif /* CK_MKDIR */ - } - makestr(&rcv_move,p); - moving = 1; - } -#endif /* CK_TMPDIR */ - - if (pv[SND_REN].ival > 0) { /* /RENAME */ - char * p = pv[SND_REN].sval; - if (!p) p = ""; - if (!*p) { - printf("?New name required for /RENAME\n"); - x = -9; - goto xgetx; - } - p = brstrip(p); -#ifndef NOSPL - /* If name given is wild, rename string must contain variables */ - if (mget && !getone) { - char * s = tmpbuf; - x = TMPBUFSIZ; - zzstring(p,&s,&x); - if (!strcmp(tmpbuf,p)) { - printf( - "?/RENAME for file group must contain variables such as \\v(filename)\n" - ); - x = -9; - goto xgetx; - } - } -#endif /* NOSPL */ - renaming = 1; - makestr(&rcv_rename,p); - debug(F110,"FTP rcv_rename",rcv_rename,0); - } - if (!cmarg[0] && mgetn == 0 && getone && pv[SND_FIL].ival < 1) { - printf("?Filename required but not given\n"); - x = -9; - goto xgetx; - } else if ((cmarg[0] || mgetn > 0) && pv[SND_FIL].ival > 0) { - printf("?You can't give both /LISTFILE and a remote filename\n"); - x = -9; - goto xgetx; - } - CHECKCONN(); /* Check connection */ - - if (pv[SND_COL].ival > -1) - x_fnc = pv[SND_COL].ival; - -#ifndef NOSPL - /* If as-name given for MGET, as-name must contain variables */ - if (mget && !getone && asnambuf[0] && x_fnc != XYFX_A) { - char * s = tmpbuf; - x = TMPBUFSIZ; - zzstring(asnambuf,&s,&x); - if (!strcmp(tmpbuf,asnambuf)) { - printf( - "?As-name for MGET must contain variables such as \\v(filename)\n" - ); - x = -9; - goto xgetx; - } - } -#endif /* NOSPL */ - -/* doget: */ - - if (pv[SND_SHH].ival > 0 || ftp_nml) { /* GET /QUIET... */ - fdispla = 0; - } else { - displa = 1; - if (mdel || ftp_deb) - fdispla = XYFD_B; - } - deleting = 0; - if (pv[SND_DEL].ival > 0) /* /DELETE was specified */ - deleting = 1; - if (pv[SND_EXC].ival > 0) - makelist(pv[SND_EXC].sval,rcvexcept,NSNDEXCEPT); - if (pv[SND_SMA].ival > -1) - getsmaller = pv[SND_SMA].ival; - if (pv[SND_LAR].ival > -1) - getlarger = pv[SND_LAR].ival; - if (pv[SND_NAM].ival > -1) - x_cnv = pv[SND_NAM].ival; - if (pv[SND_ERR].ival > -1) - geterror = pv[SND_ERR].ival; - if (pv[SND_MAI].ival > -1) - toscreen = 1; - - if (pv[SND_NLS].ival > 0) { /* Force NLST or MLSD? */ - mgetmethod = SND_NLS; - mgetforced = 1; - } else if (pv[SND_MLS].ival > 0) { - mgetmethod = SND_MLS; - mgetforced = 1; - } - -#ifdef FTP_RESTART - if (pv[SND_RES].ival > 0) { - if (!ftp_typ) { - printf("?Sorry, GET /RECOVER requires binary mode\n"); - x = -9; - goto xgetx; -#ifdef COMMENT - /* Not true - the fact that the initial REST fails does not mean */ - /* it will fail here. */ - } else if (!okrestart) { - printf("WARNING: Server might not support restart...\n"); -#endif /* COMMENT */ - } - restart = 1; - } -#endif /* FTP_RESTART */ - -#ifdef PIPESEND - if (pv[SND_FLT].ival > 0) { /* Have SEND FILTER? */ - if (pipesend) { - printf("?Switch conflict: /FILTER and /COMMAND\n"); - x = -9; - goto xgetx; - } - makestr(&rcvfilter,pv[SND_FLT].sval); - debug(F110,"ftp get /FILTER", rcvfilter, 0); - } - if (rcvfilter || pipesend) { /* /RESTART */ -#ifdef FTP_RESTART - if (restart) { /* with pipes or filters */ - printf("?Switch conflict: /FILTER or /COMMAND and /RECOVER\n"); - x = -9; - goto xgetx; - } -#endif /* FTP_RESTART */ - if (pv[SND_UPD].ival > 0 || x_fnc == XYFX_M || x_fnc == XYFX_U) { - printf( - "?Switch conflict: /FILTER or /COMMAND and Date Checking\n"); - x = -9; - goto xgetx; - } - } -#endif /* PIPESEND */ - - tfc = 0L; /* Initialize stats and counters */ - filcnt = 0; - pktnum = 0; - rpackets = 0L; - - if (pv[SND_FIL].ival > 0) { - if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) { - debug(F111,"ftp get can't open listfile",pv[SND_FIL].sval,errno); - printf("?Failure to open listfile - \"%s\"\n",pv[SND_FIL].sval); - x = -9; - goto xgetx; - } - if (zsinl(ZMFILE,tmpbuf,CKMAXPATH) < 0) { /* Read a line */ - zclose(ZMFILE); /* Failed */ - debug(F110,"ftp get listfile EOF",pv[SND_FIL].sval,0); - printf("?Empty listfile - \"%s\"\n",pv[SND_FIL].sval); - x = -9; - goto xgetx; - } - listfile = 1; - debug(F110,"ftp get listfile first",tmpbuf,0); - makestr(&(mgetlist[0]),tmpbuf); - } - t0 = gmstimer(); /* Record starting time */ - - updating = 0; /* Checking dates? */ - if (pv[SND_UPD].ival > 0 || (!mdel && x_fnc == XYFX_U)) - updating = 1; - if (pv[SND_DIF].ival > 0 || x_fnc == XYFX_M) - updating = 2; - if (updating) /* These switches force FTP DATES ON */ - ftp_dates |= 2; - - what = mdel ? W_FTP|W_FT_DELE : W_RECV|W_FTP; /* What we're doing */ - - cancelgroup = 0; /* Group not canceled yet */ - if (!(xfermode == XMODE_A && patterns && get_auto && !forcetype)) - changetype(ftp_typ,0); /* Change to requested type */ - binary = ftp_typ; /* For file-transfer display */ - first = 1; /* For MGET list */ - done = 0; /* Loop control */ - -#ifdef CK_TMPDIR - if (dldir && !f_tmpdir) { /* If they have a download directory */ - if ((s = zgtdir())) { /* Get current directory */ - if (zchdir(dldir)) { /* Change to download directory */ - ckstrncpy(savdir,s,TMPDIRLEN); - f_tmpdir = 1; /* Remember that we did this */ - } - } - } -#endif /* CK_TMPDIR */ - - if (ftp_nml) { /* /NAMELIST */ - debug(F110,"ftp GET ftp_nml",ftp_nml,0); - if (ftp_nml[0] == '-' && ftp_nml[1] == 0) - fp_nml = stdout; - else - fp_nml = fopen(ftp_nml, "wb"); - if (!fp_nml) { - printf("?%s: %s\n",ftp_nml,ck_errstr()); - goto xgetx; - } - } - while (!done && !cancelgroup) { /* Loop for all files */ - /* or until canceled. */ -#ifdef FTP_PROXY - /* do something here if proxy */ -#endif /* FTP_PROXY */ - - rs_len = 0L; /* REGET position */ - cancelfile = 0; /* This file not canceled yet */ - haspath = 0; /* Recalculate this each time thru */ - - if (getone) { /* GET */ - char * p; - s = line; - src = line; /* Server name */ - done = 1; - debug(F111,"ftp get file",s,0); - } else if (mget) { /* MGET */ - src = mgetlist[mgetx]; - debug(F111,"ftp mget remote_files A",src,first); - s = (char *)remote_files(first, - (CHAR *)mgetlist[mgetx], - (CHAR *)pv[SND_PAT].sval, - 0 - ); - debug(F110,"ftp mget remote_files B",s,0); - if (!s) s = ""; - if (!*s) { - first = 1; - if (listfile) { /* Names from listfile */ - again: - tmpbuf[0] = NUL; - while (!tmpbuf[0]) { - if (zsinl(ZMFILE,tmpbuf,CKMAXPATH) < 0) { - zclose(ZMFILE); - debug(F110,"ftp get listfile EOF", - pv[SND_FIL].sval,0); - makestr(&(mgetlist[0]),NULL); - s = NULL; - done = 1; - break; - } - } - if (done) - continue; - - makestr(&(mgetlist[0]),tmpbuf); - debug(F110,"ftp get listfile next",tmpbuf,0); - s = (char *)remote_files(first, - (CHAR *)mgetlist[0], - (CHAR *)pv[SND_PAT].sval, - 0 - ); - debug(F110,"ftp mget remote_files C",s,0); - if (!s) { - ftscreen(SCR_FN,'F',0L,s); - ftscreen(SCR_ST,ST_MSG,0L,"File not found"); - tlog(F110,"ftp get file not found:",s,0); - goto again; - } - } else { /* Names from command line */ - mgetx++; - if (mgetx < mgetn) - s = (char *)remote_files(first, - (CHAR *)mgetlist[mgetx], - (CHAR *)pv[SND_PAT].sval, - 0 - ); - else - s = NULL; - if (!s) mgetx++; - debug(F111,"ftp mget remote_files D",s,mgetx); - } - if (!s) { - if (!first || mgetx >= mgetn) { - done = 1; - break; - } else if (geterror) { - status = 0; - done = 1; - break; - } else { - continue; - } - } - } - } - debug(F111,"ftp mget remote_files E",s,0); - /* - The semantics of NLST are ill-defined. Suppose we have just sent - NLST /path/[a-z]*. Most servers send back names like /path/foo, - /path/bar, etc. But some send back only foo and bar, and subsequent - RETR commands based on the pathless names are not going to work. - */ - if (servertype == SYS_UNIX && !ckstrchr(s,'/')) { - char * s3; - if ((s3 = ckstrrchr(mgetlist[mgetx],'/'))) { - int len, left = 4096; - char * tmp = xtmpbuf; - len = s3 - mgetlist[mgetx] + 1; - ckstrncpy(tmp,mgetlist[mgetx],left); - tmp += len; - left -= len; - ckstrncpy(tmp,s,left); - s = xtmpbuf; - debug(F111,"ftp mget remote_files F",s,0); - } - } - first = 0; - skipthis = 0; /* File selection... */ - msg = ""; - nam = s; /* Filename (without path) */ - rc = 0; /* Initial return code */ - s2 = ""; - - if (!getone && !skipthis) { /* For MGET and MDELETE... */ - char c, * p = s; - int srvpath = 0; - int usrpath = 0; - int i, k = 0; - - debug(F111,"ftp mget havetype",s,havetype); - if (havetype > 0 && havetype != FTYP_FILE) { - /* Server says it's not file... */ - debug(F110,"ftp mget not-a-file",s,0); - continue; - } -/* - Explanation: Some ftp servers (such as wu-ftpd) return a recursive list. - But if the client did not ask for a recursive list, we have to ignore any - server files that include a pathname that extends beyond any path that - was included in the user's request. - - User's filespec is blah or path/blah (or other non-UNIX syntax). We need to - get the user's path segment. Then, for each incoming file, if it begins - with the same path segment, we must strip it (point past it). -*/ - src = mgetlist[mgetx]; /* In case it moved! */ - if (src) { - for (i = 0; src[i]; i++) { /* Find rightmost path separator */ - if (ispathsep(src[i])) /* in user's pathname */ - k = i + 1; - } - } else { - src = ""; - } - usrpath = k; /* User path segment length */ - debug(F111,"ftp get usrpath",src,usrpath); - - p = s; /* Server filename */ - while ((c = *p++)) { /* Look for path in server filename */ - if (ispathsep(c)) { - /* haspath++; */ - nam = p; /* Pathless name (for ckmatch) */ - srvpath = p - s; /* Server path segment length */ - } - } - debug(F111,"ftp get srvpath",s,srvpath); - - if (usrpath == 0) { -/* - Here we handle the case where the user said "mget foo" where foo is a - directory name, and the server is sending back names like "foo/file1", - "foo/file2", etc. This is a nasty trick but it's necessary because the - user can't compensate by typing "mget foo/" because then the server is - likely to send back "foo//file1, foo//file2" etc, and we still won't - get a match... -*/ - int srclen = 0, srvlen = 0; - if (src) srclen = strlen(src); - if (s) srvlen = strlen(s); - if (src && (srvlen > srclen)) { - if (!strncmp(src,s,srclen) && ispathsep(s[srclen])) { - char * tmpsrc = NULL; - tmpsrc = (char *)malloc(srclen + 2); - strncpy(tmpsrc,src,srclen); - tmpsrc[srclen] = s[srclen]; - tmpsrc[srclen+1] = NUL; - free(mgetlist[mgetx]); - mgetlist[mgetx] = tmpsrc; - tmpsrc = NULL; - src = mgetlist[mgetx]; - usrpath = srclen+1; - } - } - } -/* - If as-name not given and server filename includes path that matches - the pathname from the user's file specification, we must trim the common - path prefix from the server's name when constructing the local name. -*/ - if (src && /* Wed Sep 25 17:27:48 2002 */ - !asnambuf[0] && - !recursive && /* Thu Sep 19 16:11:59 2002 */ - (srvpath > 0) && - !strncmp(src,s,usrpath)) { - s2 = s + usrpath; /* Local name skips past remote path */ - } -#ifdef COMMENT - /* This doesn't work if the path prefix contains wildcards! */ - haspath = (srvpath > usrpath); -#else - { /* Count path segments instead */ - int x1 = 0, x2 = 0; - char *p; - for (p = s; *p; p++) - if (ispathsep(*p)) x1++; - for (p = src; *p; p++) { - if (ispathsep(*p)) x2++; - } - haspath = recursive ? x1 || x2 : x1 > x2; - debug(F111,"ftp get server path segments",s,x1); - debug(F111,"ftp get user path segments",src,x2); - } - -#endif /* COMMENT */ - debug(F111,"ftp get haspath",s+usrpath,haspath); - - if (haspath) { /* Server file has path segments? */ - if (!recursive) { /* [M]GET /RECURSIVE? */ -/* - We did not ask for a recursive listing, but the server is sending us one - anyway (as wu-ftpd is wont to do). We get here if the current filename - includes a path segment beyond any path segment we asked for in our - non-recursive [M]GET command. We MUST skip this file. -*/ - debug(F111,"ftp get skipping because of path",s,0); - continue; - } - } - } else if (getone && !skipthis) { /* GET (not MGET) */ - char * p = nam; - while ((c = *p++)) { /* Handle path in local name */ - if (ispathsep(c)) { - if (recursive) { /* If recursive, keep it */ - haspath = 1; - break; - } else { /* Otherwise lose it. */ - nam = p; - } - } - } - s2 = nam; - } - if (!*nam) /* Name without path */ - nam = s; - - if (!skipthis && pv[SND_NOD].ival > 0) { /* /NODOTFILES */ - if (nam[0] == '.') - continue; - } - if (!skipthis && rcvexcept[0]) { /* /EXCEPT: list */ - int xx; - for (i = 0; i < NSNDEXCEPT; i++) { - if (!rcvexcept[i]) { - break; - } - xx = ckmatch(rcvexcept[i], nam, servertype == SYS_UNIX, 1); - debug(F111,"ftp mget /except match",rcvexcept[i],xx); - if (xx) { - tlog(F100," refused: exception list","",0); - msg = "Refused: Exception List"; - skipthis++; - break; - } - } - } - if (!skipthis && pv[SND_NOB].ival > 0) { /* /NOBACKUPFILES */ - if (ckmatch( -#ifdef CKREGEX - "*.~[0-9]*~" -#else - "*.~*~" -#endif /* CKREGEX */ - ,nam,0,1) > 0) - continue; - } - if (!x_xla) { /* If translation is off */ - x_csl = -2; /* unset the charsets */ - x_csr = -2; - } - ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */ - if (!*s2) /* Local name */ - s2 = asnambuf; /* As-name */ - - if (!*s2) /* Sat Nov 16 19:19:39 2002 */ - s2 = recursive ? s : nam; /* Fri Jan 10 13:15:19 2003 */ - - debug(F110,"ftp get filnam ",s,0); - debug(F110,"ftp get asname A",s2,0); - - /* Receiving to real file */ - if (!pipesend && -#ifdef PIPESEND - !rcvfilter && -#endif /* PIPESEND */ - !toscreen) { -#ifndef NOSPL - /* Do this here so we can decide whether to skip */ - if (cmd_quoting && !skipthis && asnambuf[0]) { - int n; char *p; - n = TMPBUFSIZ; - p = tmpbuf; - zzstring(asnambuf,&p,&n); - s2 = tmpbuf; - debug(F111,"ftp get asname B",s2,updating); - } -#endif /* NOSPL */ - - local = *s2 ? s2 : s; - - if (!skipthis && x_fnc == XYFX_D) { /* File Collision = Discard */ - int x; - x = zchki(local); - debug(F111,"ftp get DISCARD zchki",local,x); - if (x > -1) { - skipthis++; - debug(F110,"ftp get skip name",local,0); - tlog(F100," refused: name","",0); - msg = "Refused: Name"; - } - } - -#ifdef DOUPDATE - if (!skipthis && updating) { /* If updating and not yet skipping */ - if (zchki(local) > -1) { - x = chkmodtime(local,s,0); -#ifdef DEBUG - if (deblog) { - if (updating == 2) - debug(F111,"ftp get /dates-diff chkmodtime",local,x); - else - debug(F111,"ftp get /update chkmodtime",local,x); - } -#endif /* DEBUG */ - if ((updating == 1 && x > 0) || /* /UPDATE */ - (updating == 2 && x == 1)) { /* /DATES-DIFFER */ - skipthis++; - tlog(F100," refused: date","",0); - msg = "Refused: Date"; - debug(F110,"ftp get skip date",local,0); - } - } - } -#endif /* DOUPDATE */ - } - /* Initialize file size to -1 in case server doesn't understand */ - /* SIZE command, so xxscreen() will know we don't know the size */ - - fsize = -1L; - - /* Ask for size now only if we need it for selection */ - /* because if you're going thru a list 100,000 files to select */ - /* a small subset, 100,000 SIZE commands can take hours... */ - - gotsize = 0; - if (!mdel && !skipthis && /* Don't need size for DELE... */ - (getsmaller > -1L || getlarger > -1L)) { - if (havesize > -1L) { /* Already have file size? */ - fsize = havesize; - gotsize = 1; - } else { /* No - must ask server */ - /* - Prior to sending the NLST command we necessarily put the - server into ASCII mode. We must now put it back into the - the requested mode so the upcoming SIZE command returns - right kind of size; this is especially important for - GET /RECOVER; otherwise the server returns the "ASCII" size - of the file, rather than its true size. - */ - changetype(ftp_typ,0); /* Change to requested type */ - fsize = -1L; - if (sizeok) { - x = ftpcmd("SIZE",s,x_csl,x_csr,ftp_vbm); - if (x == REPLY_COMPLETE) { - fsize = atol(&ftp_reply_str[4]); - gotsize = 1; - } - } - } - if (gotsize) { - if (getsmaller > -1L && fsize >= getsmaller) - skipthis++; - if (getlarger > -1L && fsize <= getlarger) - skipthis++; - if (skipthis) { - debug(F111,"ftp get skip size",s,fsize); - tlog(F100," refused: size","",0); - msg = "Refused: Size"; - } -#ifdef COMMENT - } else if (getone) { - /* SIZE can fail for many reasons. Does the file exist? */ - x = ftpcmd("NLST",s,x_csl,x_csr,ftp_vbm); - if (x != REPLY_COMPLETE) { - printf(">>> FILE NOT FOUND: %s\n",s); - break; - } -#endif /* COMMENT */ - } - } - if (skipthis) { /* Skipping this file? */ - ftscreen(SCR_FN,'F',0L,s); - if (msg) - ftscreen(SCR_ST,ST_ERR,0L,msg); - else - ftscreen(SCR_ST,ST_SKIP,0L,s); - continue; - } - if (fp_nml) { /* /NAMELIST only - no transfer */ - fprintf(fp_nml,"%s\n",s); - continue; - } - if (recursive && haspath && !pipesend -#ifdef PIPESEND - && !rcvfilter -#endif /* PIPESEND */ - ) { - int x; - -#ifdef NOMKDIR - x = -1; -#else - x = zmkdir(s); /* Try to make the directory */ -#endif /* NOMKDIR */ - - if (x < 0) { - rc = -1; /* Failure is fatal */ - if (geterror) { - status = 0; - ftscreen(SCR_EM,0,0L,"Directory creation failure"); - break; - } - } - } - - /* Not skipping */ - - selected++; /* Count this file as selected */ - pn = NULL; - - if (!gotsize && !mdel) { /* Didn't get size yet */ - if (havesize > -1L) { /* Already have file size? */ - fsize = havesize; - gotsize = 1; - } else { /* No - must ask server */ - fsize = -1L; - if (sizeok) { - x = ftpcmd("SIZE",s,x_csl,x_csr,ftp_vbm); - if (x == REPLY_COMPLETE) { - fsize = atol(&ftp_reply_str[4]); - gotsize = 1; - } - } - } - } - if (mdel) { /* [M]DELETE */ - if (displa && !ftp_vbm) - printf(" %s...",s); - rc = - (ftpcmd("DELE",s,x_csl,x_csr,ftp_vbm) == REPLY_COMPLETE) ? 1 : -1; - if (rc > -1) { - tlog(F110,"ftp mdelete",s,0); - if (displa && !ftp_vbm) - printf("OK\n"); - } else { - tlog(F110,"ftp mdelete failed:",s,0); - if (displa) - printf("Failed\n"); - } -#ifndef NOSPL -#ifdef PIPESEND - } else if (rcvfilter) { /* [M]GET with filter */ - int n; char * p; - n = CKMAXPATH; - p = tmpbuf; /* Safe - no asname with filter */ - zzstring(rcvfilter,&p,&n); - if (n > -1) - pn = tmpbuf; - debug(F111,"ftp get rcvfilter",pn,n); -#endif /* PIPESEND */ -#endif /* NOSPL */ - if (toscreen) s2 = "-"; - } else if (pipesend) { /* [M]GET /COMMAND */ - int n; char * p; - n = CKMAXPATH; - p = tmpbuf; /* Safe - no asname with filter */ - zzstring(pipename,&p,&n); - if (n > -1) - pn = tmpbuf; - debug(F111,"ftp get pipename",pipename,n); - if (toscreen) s2 = "-"; - } else { /* [M]GET with no pipes or filters */ - debug(F111,"ftp get s2 A",s2,x_cnv); - if (toscreen) { - s2 = "-"; /* (hokey convention for stdout) */ - } else if (!*s2) { /* No asname? */ - if (x_cnv) { /* If converting */ - nzrtol(s,tmpbuf,x_cnv,1,CKMAXPATH); /* convert */ - s2 = tmpbuf; - debug(F110,"ftp get nzrtol",s2,0); - } else /* otherwise */ - s2 = s; /* use incoming file's name */ - } - debug(F110,"ftp get s2 B",s2,0); - - /* If local file already exists, take collision action */ - - if (!pipesend && -#ifdef PIPESEND - !rcvfilter && -#endif /* PIPESEND */ - !toscreen) { - x = zchki(s2); - debug(F111,"ftp get zchki",s2,x); - debug(F111,"ftp get x_fnc",s2,x_fnc); - - if (x > -1 && !restart) { - int x = -1; - char * newname = NULL; - - switch (x_fnc) { - case XYFX_A: /* Append */ - append = 1; - break; - case XYFX_R: /* Rename */ - case XYFX_B: /* Backup */ - znewn(s2,&newname); /* Make unique name */ - debug(F110,"ftp get znewn",newname,0); - if (x_fnc == XYFX_B) { /* Backup existing file */ - x = zrename(s2,newname); - debug(F111,"ftp get backup zrename",newname,x); - } else { /* Rename incoming file */ - x = ckstrncpy(tmpbuf,newname,CKMAXPATH+1); - s2 = tmpbuf; - debug(F111,"ftp get rename incoming",newname,x); - } - if (x < 0) { - ftscreen(SCR_EM,0,0L,"Backup/Rename failed"); - x = 0; - goto xgetx; - } - break; - case XYFX_D: /* Discard (already handled above) */ - case XYFX_U: /* Update (ditto) */ - case XYFX_M: /* Update (ditto) */ - case XYFX_X: /* Overwrite */ - break; - } - } - } - } - if (!mdel) { -#ifdef PIPESEND - debug(F111,"ftp get pn",pn,rcvfilter ? 1 : 0); -#endif /* PIPESEND */ - if (pipesend && !toscreen) - s2 = NULL; -#ifdef DEBUG - if (deblog) { - debug(F101,"ftp get x_xla","",x_xla); - debug(F101,"ftp get x_csl","",x_csl); - debug(F101,"ftp get x_csr","",x_csr); - debug(F101,"ftp get append","",append); - } -#endif /* DEBUG */ - - rc = getfile(s,s2,restart,append,pn,x_xla,x_csl,x_csr); - -#ifdef DEBUG - if (deblog) { - debug(F111,"ftp get rc",s,rc); - debug(F111,"ftp get cancelfile",s,cancelfile); - debug(F111,"ftp get cancelgroup",s,cancelgroup); - debug(F111,"ftp get renaming",s,renaming); - } -#endif /* DEBUG */ - } - if (rc > -1) { - good++; - status = 1; - if (!cancelfile) { - if (deleting) { /* GET /DELETE (source file) */ - rc = - (ftpcmd("DELE",s,x_csl,x_csr,ftp_vbm) == REPLY_COMPLETE) - ? 1 : -1; - tlog(F110, (rc > -1) ? - " deleted" : " failed to delete", s, 0); - } else if (renaming && rcv_rename && !toscreen) { - char *p; /* Rename downloaded file */ -#ifndef NOSPL - char tmpbuf[CKMAXPATH+1]; - int n; - n = CKMAXPATH; - p = tmpbuf; - debug(F111,"ftp get /rename",rcv_rename,0); - zzstring(rcv_rename,&p,&n); - debug(F111,"ftp get /rename",rcv_rename,0); - p = tmpbuf; -#else - p = rcv_rename; -#endif /* NOSPL */ - rc = (zrename(s2,p) < 0) ? -1 : 1; - debug(F111,"doftpget /RENAME zrename",p,rc); - tlog(F110, (rc > -1) ? - " renamed to" : - " failed to rename to", - p, - 0 - ); - } else if (moving && rcv_move && !toscreen) { - char *p; /* Move downloaded file */ -#ifndef NOSPL - char tmpbuf[CKMAXPATH+1]; - int n; - n = TMPBUFSIZ; - p = tmpbuf; - debug(F111,"ftp get /move-to",rcv_move,0); - zzstring(rcv_move,&p,&n); - p = tmpbuf; -#else - p = rcv_move; -#endif /* NOSPL */ - debug(F111,"ftp get /move-to",p,0); - rc = (zrename(s2,p) < 0) ? -1 : 1; - debug(F111,"doftpget /MOVE zrename",p,rc); - tlog(F110, (rc > -1) ? - " moved to" : " failed to move to", p, 0); - } - if (pv[SND_SRN].ival > 0 && pv[SND_SRN].sval) { - char * s = pv[SND_SRN].sval; - char * srvrn = pv[SND_SRN].sval; - char tmpbuf[CKMAXPATH+1]; -#ifndef NOSPL - int y; /* Pass it thru the evaluator */ - extern int cmd_quoting; /* for \v(filename) */ - debug(F111,"ftp get srv_renam",s,1); - - if (cmd_quoting) { - y = CKMAXPATH; - s = (char *)tmpbuf; - zzstring(srvrn,&s,&y); - s = (char *)tmpbuf; - } -#endif /* NOSPL */ - debug(F111,"ftp get srv_renam",s,1); - if (s) if (*s) { - int x; - x = ftp_rename(s2,s); - debug(F111,"ftp get ftp_rename",s2,x); - tlog(F110, (x > 0) ? - " renamed source file to" : - " failed to rename source file to", - s, - 0 - ); - if (x < 1) - return(-1); - } - } - } - } - if (cancelfile) - continue; - if (rc < 0) { - ftp_fai++; - if (geterror) { - status = 0; - ftscreen(SCR_EM,0,0L,"Fatal download error"); - done++; - } - } - } -#ifdef DEBUG - if (deblog) { - debug(F101,"ftp get status","",status); - debug(F101,"ftp get cancelgroup","",cancelgroup); - debug(F101,"ftp get cancelfile","",cancelfile); - debug(F101,"ftp get selected","",selected); - debug(F101,"ftp get good","",good); - } -#endif /* DEBUG */ - - if (selected == 0) { /* No files met selection criteria */ - status = 1; /* which is a kind of success. */ - } else if (status > 0) { /* Some files were selected */ - if (cancelgroup) /* but MGET was canceled */ - status = 0; /* so MGET failed */ - else if (cancelfile && good < 1) /* If file was canceled */ - status = 0; /* MGET failed if it got no files */ - } - success = status; - x = success; - debug(F101,"ftp get success","",success); - - xgetx: - pipesend = pipesave; /* Restore global pipe selection */ - if (fp_nml) { /* Close /NAMELIST */ - if (fp_nml != stdout) - fclose(fp_nml); - fp_nml = NULL; - } - if (x > -1) { /* Download successful */ -#ifdef GFTIMER - t1 = gmstimer(); /* End time */ - sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */ - if (!sec) sec = 0.001; - fptsecs = sec; -#else - sec = (t1 - t0) / 1000; - if (!sec) sec = 1; -#endif /* GFTIMER */ - tfcps = (long) (tfc / sec); - tsecs = (int)sec; - lastxfer = W_FTP|W_RECV; - xferstat = success; - } - if (dpyactive) - ftscreen(SCR_TC,0,0L,""); -#ifdef CK_TMPDIR - if (f_tmpdir) { /* If we changed to download dir */ - zchdir((char *) savdir); /* Go back where we came from */ - f_tmpdir = 0; - } -#endif /* CK_TMPDIR */ - - for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */ - if (pv[i].sval) - free(pv[i].sval); - } - for (i = 0; i < mgetn; i++) /* MGET list too */ - makestr(&(mgetlist[i]),NULL); - - if (cancelgroup) /* Clear temp-file stack */ - mlsreset(); - - ftreset(); /* Undo switch effects */ - dpyactive = 0; - return(x); -} - -static struct keytab ftprmt[] = { - { "cd", XZCWD, 0 }, - { "cdup", XZCDU, 0 }, - { "cwd", XZCWD, CM_INV }, - { "delete", XZDEL, 0 }, - { "directory", XZDIR, 0 }, - { "exit", XZXIT, 0 }, - { "help", XZHLP, 0 }, - { "login", XZLGI, 0 }, - { "logout", XZLGO, 0 }, - { "mkdir", XZMKD, 0 }, - { "pwd", XZPWD, 0 }, - { "rename", XZREN, 0 }, - { "rmdir", XZRMD, 0 }, - { "type", XZTYP, 0 }, - { "", 0, 0 } -}; -static int nftprmt = (sizeof(ftprmt) / sizeof(struct keytab)) - 1; - -int -doftpsite() { /* Send a SITE command */ - int reply; - char * s; - int lcs = -1, rcs = -1; -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - if ((x = cmtxt("Command", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) printf(" ftp site \"%s\"...\n",line); - if ((reply = ftpcmd("SITE",line,lcs,rcs,ftp_vbm)) == REPLY_PRELIM) { - do { - reply = getreply(0,lcs,rcs,ftp_vbm,0); - } while (reply == REPLY_PRELIM); - } - return(success = (reply == REPLY_COMPLETE)); -} - - -int -dosetftppsv() { /* Passive mode */ - x = seton(&ftp_psv); - if (x > 0) passivemode = ftp_psv; - return(x); -} - -/* d o f t p r m t -- Parse and execute REMOTE commands */ - -int -doftprmt(cx,who) int cx, who; { /* who == 1 for ftp, 0 for kermit */ - /* cx == 0 means REMOTE */ - /* cx != 0 is a XZxxx value */ - char * s; - - if (who != 0) - return(0); - - if (cx == 0) { - if ((x = cmkey(ftprmt,nftprmt,"","",xxstring)) < 0) - return(x); - cx = x; - } - switch (cx) { - case XZCDU: /* CDUP */ - if ((x = cmcfm()) < 0) return(x); - return(doftpcdup()); - - case XZCWD: /* RCD */ - if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0) - return(x); - ckstrncpy(line,s,LINBUFSIZ); - return(doftpcwd((char *)line,1)); - case XZPWD: /* RPWD */ - return(doftppwd()); - case XZDEL: /* RDEL */ - return(doftpget(FTP_MDE,1)); - case XZDIR: /* RDIR */ - return(doftpdir(FTP_DIR)); - case XZHLP: /* RHELP */ - return(doftpxhlp()); - case XZMKD: /* RMKDIR */ - return(doftpmkd()); - case XZREN: /* RRENAME */ - return(doftpren()); - case XZRMD: /* RRMDIR */ - return(doftprmd()); - case XZLGO: /* LOGOUT */ - return(doftpres()); - case XZXIT: /* EXIT */ - return(ftpbye()); - } - printf("?Not usable with FTP - \"%s\"\n", atmbuf); - return(-9); -} - -int -doxftp() { /* Command parser for built-in FTP */ - int cx, n; - struct FDB kw, fl; - char * s; - int usetls = 0; - int lcs = -1, rcs = -1; - -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - - if (inserver) /* FTP not allowed in IKSD. */ - return(-2); - - if (g_ftp_typ > -1) { /* Restore TYPE if saved */ - ftp_typ = g_ftp_typ; - /* g_ftp_typ = -1; */ - } -#ifdef COMMENT -/* - We'll set the collision action locally in doftpget() based on whether - ftp_fnc was ever set to a value. if not, we'll use the fncact value. -*/ - if (ftp_fnc < 0) /* Inherit global collision action */ - ftp_fnc = fncact; /* if none specified for FTP */ -#endif /* COMMENT */ - - /* Restore global verbose mode */ - if (ftp_deb) - ftp_vbm = 1; - else if (quiet) - ftp_vbm = 0; - else - ftp_vbm = ftp_vbx; - - ftp_dates &= 1; /* Undo any previous /UPDATE switch */ - - dpyactive = 0; /* Reset global transfer-active flag */ - printlines = 0; /* Reset printlines */ - - if (fp_nml) { /* Reset /NAMELIST */ - if (fp_nml != stdout) - fclose(fp_nml); - fp_nml = NULL; - } - makestr(&ftp_nml,NULL); - - cmfdbi(&kw, /* First FDB - commands */ - _CMKEY, /* fcode */ - "Hostname; or FTP command", /* help */ - "", /* default */ - "", /* addtl string data */ - nftpcmd, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: none */ - xxstring, /* Processing function */ - ftpcmdtab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* A host name or address */ - _CMFLD, /* fcode */ - "Hostname or address", /* help */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - x = cmfdb(&kw); /* Parse a hostname or a keyword */ - if (x == -3) { - printf("?ftp what? \"help ftp\" for hints\n"); - return(-9); - } - if (x < 0) - return(x); - if (cmresult.fcode == _CMFLD) { /* If hostname */ - return(openftp(cmresult.sresult,0)); /* go open the connection */ - } else { - cx = cmresult.nresult; - } - switch (cx) { - case FTP_ACC: /* ACCOUNT */ - if ((x = cmtxt("Remote account", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - makestr(&ftp_acc,s); - if (testing) - printf(" ftp account: \"%s\"\n",ftp_acc); - success = (ftpcmd("ACCT",ftp_acc,-1,-1,ftp_vbm) == REPLY_COMPLETE); - return(success); - - case FTP_GUP: /* Go UP */ - if ((x = cmcfm()) < 0) return(x); - CHECKCONN(); - if (testing) printf(" ftp cd: \"(up)\"\n"); - return(success = doftpcdup()); - - case FTP_CWD: /* CD */ - if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) - printf(" ftp cd: \"%s\"\n", line); - return(success = doftpcwd(line,1)); - - case FTP_CHM: /* CHMOD */ - if ((x = cmfld("Permissions or protection code","",&s,xxstring)) < 0) - return(x); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,tmpbuf," ",s,NULL); - if (testing) - printf(" ftp chmod: %s\n",ftpcmdbuf); - success = - (ftpcmd("SITE CHMOD",ftpcmdbuf,lcs,rcs,ftp_vbm) == REPLY_COMPLETE); - return(success); - - case FTP_CLS: /* CLOSE FTP connection */ - if ((y = cmcfm()) < 0) - return(y); - CHECKCONN(); - if (testing) - printf(" ftp closing...\n"); - ftpclose(); - return(success = 1); - - case FTP_DIR: /* DIRECTORY of remote files */ - case FTP_VDI: - return(doftpdir(cx)); - - case FTP_GET: /* GET a remote file */ - case FTP_RGE: /* REGET */ - case FTP_MGE: /* MGET */ - case FTP_MDE: /* MDELETE */ - return(doftpget(cx,1)); - - case FTP_IDL: /* IDLE */ - if ((x = cmnum("Number of seconds","-1",10,&z,xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) - return(y); - CHECKCONN(); - if (z < 0) { /* Display idle timeout */ - if (testing) - printf(" ftp query idle timeout...\n"); - success = (ftpcmd("SITE IDLE",NULL,0,0,1) == REPLY_COMPLETE); - } else { /* Set idle timeout */ - if (testing) - printf(" ftp idle timeout set: %d...\n",z); - success = - (ftpcmd("SITE IDLE",ckitoa(z),0,0,1) == REPLY_COMPLETE); - } - return(success); - - case FTP_MKD: /* MKDIR */ - return(doftpmkd()); - - case FTP_MOD: /* MODTIME */ - if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) - printf(" ftp modtime \"%s\"...\n",line); - success = 0; - if (ftpcmd("MDTM",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE) { - success = 1; - mdtmok = 1; - if (!quiet) { - int flag = 0; - char c, * s; - struct tm tmremote; - - bzero((char *)&tmremote, sizeof(struct tm)); - s = ftp_reply_str; - while ((c = *s++)) { - if (c == SP) { - flag++; - break; - } - } - if (flag) { - if (sscanf(s, "%04d%02d%02d%02d%02d%02d", - &tmremote.tm_year, - &tmremote.tm_mon, - &tmremote.tm_mday, - &tmremote.tm_hour, - &tmremote.tm_min, - &tmremote.tm_sec - ) == 6) { - printf(" %s %04d-%02d-%02d %02d:%02d:%02d GMT\n", - line, - tmremote.tm_year, - tmremote.tm_mon, - tmremote.tm_mday, - tmremote.tm_hour, - tmremote.tm_min, - tmremote.tm_sec - ); - } else { - success = 0; - } - } - } - } - return(success); - - case FTP_OPN: /* OPEN connection */ -#ifdef COMMENT - x = cmfld("IP hostname or address","",&s,xxstring); - if (x < 0) { - success = 0; - return(x); - } - ckstrncpy(line,s,LINBUFSIZ); - s = line; - return(openftp(s,0)); -#else - { /* OPEN connection */ - char name[TTNAMLEN+1], *p; - extern int network; - extern char ttname[]; - if (network) /* If we have a current connection */ - ckstrncpy(name,ttname,LINBUFSIZ); /* get the host name */ - else - *name = '\0'; /* as default host */ - for (p = name; *p; p++) /* Remove ":service" from end. */ - if (*p == ':') { *p = '\0'; break; } -#ifndef USETLSTAB - x = cmfld("IP hostname or address",name,&s,xxstring); -#else - cmfdbi(&kw, /* First FDB - commands */ - _CMKEY, /* fcode */ - "Hostname or switch", /* help */ - "", /* default */ - "", /* addtl string data */ - ntlstab, /* addtl numeric data 1: tbl size */ - 0, /* addtl numeric data 2: none */ - xxstring, /* Processing function */ - tlstab, /* Keyword table */ - &fl /* Pointer to next FDB */ - ); - cmfdbi(&fl, /* A host name or address */ - _CMFLD, /* fcode */ - "Hostname or address", /* help */ - "", /* default */ - "", /* addtl string data */ - 0, /* addtl numeric data 1 */ - 0, /* addtl numeric data 2 */ - xxstring, - NULL, - NULL - ); - - for (n = 0;; n++) { - x = cmfdb(&kw); /* Parse a hostname or a keyword */ - if (x == -3) { - printf("?ftp open what? \"help ftp\" for hints\n"); - return(-9); - } - if (x < 0) - break; - if (cmresult.fcode == _CMFLD) { /* Hostname */ - s = cmresult.sresult; - break; - } else if (cmresult.nresult == OPN_TLS) { - usetls = 1; - } - } -#endif /* USETLSTAB */ - if (x < 0) { - success = 0; - return(x); - } - ckstrncpy(line,s,LINBUFSIZ); - s = line; - return(openftp(s,usetls)); - } -#endif /* COMMENT */ - - case FTP_PUT: /* PUT */ - case FTP_MPU: /* MPUT */ - case FTP_APP: /* APPEND */ - return(doftpput(cx,1)); - - case FTP_PWD: /* PWD */ - x = doftppwd(); - if (x > -1) success = x; - return(x); - - case FTP_REN: /* RENAME */ - return(doftpren()); - - case FTP_RES: /* RESET */ - return(doftpres()); - - case FTP_HLP: /* (remote) HELP */ - return(doftpxhlp()); - - case FTP_RMD: /* RMDIR */ - return(doftprmd()); - - case FTP_STA: /* STATUS */ - if ((x = cmtxt("Command", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) printf(" ftp status \"%s\"...\n",line); - success = (ftpcmd("STAT",line,lcs,rcs,1) == REPLY_COMPLETE); - return(success); - - case FTP_SIT: { /* SITE */ - return(doftpsite()); - } - - case FTP_SIZ: /* (ask for) SIZE */ - if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if (testing) - printf(" ftp size \"%s\"...\n",line); - success = (ftpcmd("SIZE",line,lcs,rcs,1) == REPLY_COMPLETE); - if (success) - sizeok = 1; - return(success); - - case FTP_SYS: /* Ask for server's SYSTEM type */ - if ((x = cmcfm()) < 0) return(x); - CHECKCONN(); - if (testing) - printf(" ftp system...\n"); - success = (ftpcmd("SYST",NULL,0,0,1) == REPLY_COMPLETE); - return(success); - - case FTP_UMA: /* Set/query UMASK */ - if ((x = cmfld("Umask to set or nothing to query","",&s,xxstring)) < 0) - if (x != -3) - return(x); - ckstrncpy(tmpbuf,s,TMPBUFSIZ); - if ((x = cmcfm()) < 0) return(x); - CHECKCONN(); - if (testing) { - if (tmpbuf[0]) - printf(" ftp umask \"%s\"...\n",tmpbuf); - else - printf(" ftp query umask...\n"); - } - success = ftp_umask(tmpbuf); - return(success); - - case FTP_USR: - return(doftpusr()); - - case FTP_QUO: - if ((x = cmtxt("FTP protocol command", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - success = (ftpcmd(s,NULL,0,0,ftp_vbm) == REPLY_COMPLETE); - return(success); - - case FTP_TYP: /* Type */ - if ((x = cmkey(ftptyp,nftptyp,"","",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) return(y); - CHECKCONN(); - ftp_typ = x; - g_ftp_typ = x; - tenex = (ftp_typ == FTT_TEN); - changetype(ftp_typ,ftp_vbm); - return(1); - - case FTP_CHK: /* Check if remote file(s) exist(s) */ - if ((x = cmtxt("remote filename", "", &s, xxstring)) < 0) - return(x); - CHECKCONN(); - success = remote_files(1,(CHAR *)s,NULL,0) ? 1 : 0; - return(success); - - case FTP_FEA: /* RFC2389 */ - if ((y = cmcfm()) < 0) - return(y); - CHECKCONN(); - success = (ftpcmd("FEAT",NULL,0,0,1) == REPLY_COMPLETE); - if (success) { - if (sfttab[0] > 0) { - ftp_aut = sfttab[SFT_AUTH]; - sizeok = sfttab[SFT_SIZE]; - mdtmok = sfttab[SFT_MDTM]; - mlstok = sfttab[SFT_MLST]; - } - } - return(success); - - case FTP_OPT: /* RFC2389 */ - /* Perhaps this should be a keyword list... */ - if ((x = cmfld("FTP command","",&s,xxstring)) < 0) - return(x); - CHECKCONN(); - ckstrncpy(line,s,LINBUFSIZ); - if ((x = cmtxt("Options for this command", "", &s, xxstring)) < 0) - return(x); - success = (ftpcmd("OPTS",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE); - return(success); - - case FTP_ENA: /* FTP ENABLE */ - case FTP_DIS: /* FTP DISABLE */ - if ((x = cmkey(ftpenatab,nftpena,"","",xxstring)) < 0) - return(x); - if ((y = cmcfm()) < 0) return(y); - switch (x) { - case ENA_AUTH: /* OK to use autoauthentication */ - ftp_aut = (cx == FTP_ENA) ? 1 : 0; - sfttab[SFT_AUTH] = ftp_aut; - break; - case ENA_FEAT: /* OK to send FEAT command */ - featok = (cx == FTP_ENA) ? 1 : 0; - break; - case ENA_MLST: /* OK to use MLST/MLSD */ - mlstok = (cx == FTP_ENA) ? 1 : 0; - sfttab[SFT_MLST] = mlstok; - break; - case ENA_MDTM: /* OK to use MDTM */ - mdtmok = (cx == FTP_ENA) ? 1 : 0; - sfttab[SFT_MDTM] = mdtmok; - break; - case ENA_SIZE: /* OK to use SIZE */ - sizeok = (cx == FTP_ENA) ? 1 : 0; - sfttab[SFT_SIZE] = sizeok; - break; - } - return(success = 1); - } - return(-2); -} - -#ifndef NOSHOW -static char * -shopl(x) int x; { - switch (x) { - case FPL_CLR: return("clear"); - case FPL_PRV: return("private"); - case FPL_SAF: return("safe"); - case 0: return("(not set)"); - default: return("(unknown)"); - } -} - -int -shoftp(brief) { - char * s = "?"; - int n, x; - - if (g_ftp_typ > -1) { /* Restore TYPE if saved */ - ftp_typ = g_ftp_typ; - /* g_ftp_typ = -1; */ - } - printf("\n"); - printf("FTP connection: %s\n",connected ? - ftp_host : - "(none)" - ); - n = 2; - if (connected) { - n++; - printf("FTP server type: %s\n", - ftp_srvtyp[0] ? ftp_srvtyp : "(unknown)"); - } - if (loggedin) - printf("Logged in as: %s\n", - strval(ftp_logname,"(unknown)")); - else - printf("Not logged in\n"); - n++; - if (brief) return(0); - - printf("\nSET FTP values:\n\n"); - n += 3; - - printf(" ftp anonymous-password: %s\n", - ftp_apw ? ftp_apw : "(default)" - ); - printf(" ftp auto-login: %s\n",showoff(ftp_log)); - printf(" ftp auto-authentication: %s\n",showoff(ftp_aut)); - switch (ftp_typ) { - case FTT_ASC: s = "text"; break; - case FTT_BIN: s = "binary"; break; - case FTT_TEN: s = "tenex"; break; - } - printf(" ftp type: %s\n",s); - printf(" ftp get-filetype-switching: %s\n",showoff(get_auto)); - printf(" ftp dates: %s\n",showoff(ftp_dates)); - printf(" ftp error-action: %s\n",ftp_err ? "quit":"proceed"); - printf(" ftp filenames: %s\n", - ftp_cnv == CNV_AUTO ? "auto" : (ftp_cnv ? "converted" : "literal") - ); - printf(" ftp debug %s\n",showoff(ftp_deb)); - - printf(" ftp passive-mode: %s\n",showoff(ftp_psv)); - printf(" ftp permissions: %s\n",showooa(ftp_prm)); - printf(" ftp verbose-mode: %s\n",showoff(ftp_vbx)); - printf(" ftp send-port-commands: %s\n",showoff(ftp_psv)); - printf(" ftp unique-server-names: %s\n",showoff(ftp_usn)); -#ifdef COMMENT - /* See note in doxftp() */ - if (ftp_fnc < 0) - ftp_fnc = fncact; -#endif /* COMMENT */ - printf(" ftp collision: %s\n", - fncnam[ftp_fnc > -1 ? ftp_fnc : fncact]); - printf(" ftp server-time-offset: %s\n", - fts_sto ? fts_sto : "(none)"); - n += 15; - -#ifndef NOCSETS - printf(" ftp character-set-translation: %s\n",showoff(ftp_xla)); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - - printf(" ftp server-character-set: %s\n",fcsinfo[ftp_csr].keyword); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - - printf(" file character-set: %s\n",fcsinfo[fcharset].keyword); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } -#endif /* NOCSETS */ - - x = ftp_dis; - if (x < 0) - x = fdispla; - switch (x) { - case XYFD_N: s = "none"; break; - case XYFD_R: s = "serial"; break; - case XYFD_C: s = "fullscreen"; break; - case XYFD_S: s = "crt"; break; - case XYFD_B: s = "brief"; break; - } - printf(" ftp display: %s\n",s); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - - if (mlstok || featok || mdtmok || sizeok || ftp_aut) { - printf(" enabled: "); - if (ftp_aut) printf(" AUTH"); - if (featok) printf(" FEAT"); - if (mdtmok) printf(" MDTM"); - if (mlstok) printf(" MLST"); - if (sizeok) printf(" SIZE"); - printf("\n"); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - } - if (!mlstok || !featok || !mdtmok || !sizeok || !ftp_aut) { - printf(" disabled: "); - if (!ftp_aut) printf(" AUTH"); - if (!featok) printf(" FEAT"); - if (!mdtmok) printf(" MDTM"); - if (!mlstok) printf(" MLST"); - if (!sizeok) printf(" SIZE"); - printf("\n"); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - } - switch (ftpget) { - case 0: s = "kermit"; break; - case 1: s = "ftp"; break; - case 2: s = "auto"; break; - default: s = "?"; - } - printf(" get-put-remote: %s\n",s); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - - printf("\n"); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - -#ifdef FTP_SECURITY - printf("Available security methods: "); -#ifdef FTP_GSSAPI - printf("GSSAPI "); -#endif /* FTP_GSSAPI */ -#ifdef FTP_KRB4 - printf("Kerberos4 "); -#endif /* FTP_KRB4 */ -#ifdef FTP_SRP - printf("SRP "); -#endif /* FTP_SRP */ -#ifdef FTP_SSL - printf("SSL "); -#endif /* FTP_SSL */ - - n++; - printf("\n\n"); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - printf(" ftp authtype: %s\n",strval(auth_type,NULL)); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - printf(" ftp auto-encryption: %s\n",showoff(ftp_cry)); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - printf(" ftp credential-forwarding: %s\n",showoff(ftp_cfw)); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - printf(" ftp command-protection-level: %s\n",shopl(ftp_cpl)); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - printf(" ftp data-protection-level: %s\n",shopl(ftp_dpl)); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } - printf(" ftp secure proxy: %s\n",shopl(ssl_ftp_proxy)); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } -#else - printf("Available security methods: (none)\n"); - if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; } -#endif /* FTP_SECURITY */ - - if (n <= cmd_rows - 3) - printf("\n"); - return(0); -} -#endif /* NOSHOW */ - -#ifndef NOHELP -/* FTP HELP text strings */ - -static char * fhs_ftp[] = { - "Syntax: FTP subcommand [ operands ]", - " Makes an FTP connection, or sends a command to the FTP server.", - " To see a list of available FTP subcommands, type \"ftp ?\".", - " and then use HELP FTP xxx to get help about subcommand xxx.", - " Also see HELP SET FTP, HELP SET GET-PUT-REMOTE, and HELP FIREWALL.", - "" -}; - -static char * fhs_acc[] = { /* ACCOUNT */ - "Syntax: FTP ACCOUNT text", - " Sends an account designator to an FTP server that needs one.", - " Most FTP servers do not use accounts; some use them for other", - " other purposes, such as disk-access passwords.", - "" -}; -static char * fhs_app[] = { /* APPEND */ - "Syntax: FTP APPEND filname", - " Equivalent to [ FTP ] PUT /APPEND. See HELP FTP PUT.", - "" -}; -static char * fhs_cls[] = { /* BYE, CLOSE */ - "Syntax: [ FTP ] BYE", - " Logs out from the FTP server and closes the FTP connection.", - " Also see HELP SET GET-PUT-REMOTE. Synonym: [ FTP ] CLOSE.", - "" -}; -static char * fhs_cwd[] = { /* CD, CWD */ - "Syntax: [ FTP ] CD directory", - " Asks the FTP server to change to the given directory.", - " Also see HELP SET GET-PUT-REMOTE. Synonyms: [ FTP ] CWD, RCD, RCWD.", - "" -}; -static char * fhs_gup[] = { /* CDUP, UP */ - "Syntax: FTP CDUP", - " Asks the FTP server to change to the parent directory of its current", - " directory. Also see HELP SET GET-PUT-REMOTE. Synonym: FTP UP.", - "" -}; -static char * fhs_chm[] = { /* CHMOD */ - "Syntax: FTP CHMOD filename permissions", - " Asks the FTP server to change the permissions, protection, or mode of", - " the given file. The given permissions must be in the syntax of the", - " the server's file system, e.g. an octal number for UNIX. Also see", - " FTP PUT /PERMISSIONS", - "" -}; -static char * fhs_mde[] = { /* DELETE */ - "Syntax: FTP DELETE [ switches ] filespec", - " Asks the FTP server to delete the given file or files.", - " Synonym: MDELETE (Kermit makes no distinction between single and", - " multiple file deletion). Optional switches:", - " ", - " /ERROR-ACTION:{PROCEED,QUIT}", - " /EXCEPT:pattern", - " /FILENAMES:{AUTO,CONVERTED,LITERAL}", - " /LARGER-THAN:number", -#ifdef UNIXOROSK - " /NODOTFILES", -#endif /* UNIXOROSK */ - " /QUIET", -#ifdef RECURSIVE - " /RECURSIVE (depends on server)", - " /SUBDIRECTORIES", -#endif /* RECURSIVE */ - " /SMALLER-THAN:number", - "" -}; -static char * fhs_dir[] = { /* DIRECTORY */ - "Syntax: FTP DIRECTORY [ filespec ]", - " Asks the server to send a directory listing of the files that match", - " the given filespec, or if none is given, all the files in its current", - " directory. The filespec, including any wildcards, must be in the", - " syntax of the server's file system. Also see HELP SET GET-PUT-REMOTE.", - " Synonym: RDIRECTORY.", - "" -}; -static char * fhs_vdi[] = { /* VDIRECTORY */ - "Syntax: FTP VDIRECTORY [ filespec ]", - " Asks the server to send a directory listing of the files that match", - " the given filespec, or if none is given, all the files in its current", - " directory. VDIRECTORY is needed for getting verbose directory", - " listings from certain FTP servers, such as on TOPS-20. Try it if", - " FTP DIRECTORY lists only filenames without details.", - "" -}; -static char * fhs_fea[] = { /* FEATURES */ - "Syntax: FTP FEATURES", - " Asks the FTP server to list its special features. Most FTP servers", - " do not recognize this command.", - "" -}; -static char * fhs_mge[] = { /* MGET */ - "Syntax: [ FTP ] MGET [ options ] filespec [ filespec [ filespec ... ] ]", - " Download a single file or multiple files. Asks the FTP server to send", - " the given file or files. Also see FTP GET. Optional switches:", - " ", - " /AS-NAME:text", - " Name under which to store incoming file.", - " Pattern required for for multiple files.", - " /BINARY", /* /IMAGE */ - " Force binary mode. Synonym: /IMAGE.", - " /COLLISION:{BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE}", - " What to do if an incoming file has the same name as an existing file.", - -#ifdef PUTPIPE - " /COMMAND", - " Specifies that the as-name is a command to which the incoming file", - " is to be piped as standard input.", -#endif /* PUTPIPE */ - -#ifdef DOUPDATE - " /DATES-DIFFER", - " Download only those files whose modification date-times differ from", - " those of the corresponding local files, or that do not already", - " exist on the local computer.", -#endif /* DOUPDATE */ - - " /DELETE", - " Specifies that each file is to be deleted from the server after,", - " and only if, it is successfully downloaded.", - " /ERROR-ACTION:{PROCEED,QUIT}", - " When downloading a group of files, what to do upon failure to", - " transfer a file: quit or proceed to the next one.", - " /EXCEPT:pattern", - " Exception list: don't download any files that match this pattern.", - " See HELP WILDCARD for pattern syntax.", - " /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}", - " Whether to convert incoming filenames to local syntax.", -#ifdef PIPESEND -#ifndef NOSPL - " /FILTER:command", - " Pass incoming files through the given command.", -#endif /* NOSPL */ -#endif /* PIPESEND */ - " /LARGER-THAN:number", - " Only download files that are larger than the given number of bytes.", - " /LISTFILE:filename", - " Obtain the list of files to download from the given file.", -#ifndef NOCSETS - " /LOCAL-CHARACTER-SET:name", - " When downloading in text mode and character-set conversion is", - " desired, this specifies the target set.", -#endif /* NOCSETS */ - " /MATCH:pattern", - " Specifies a pattern to be used to select filenames locally from the", - " server's list.", - " /MLSD", - " Forces sending of MLSD (rather than NLST) to get the file list.", -#ifdef CK_TMPDIR - " /MOVE-TO:directory", - " Each file that is downloaded is to be moved to the given local", - " directory immediately after, and only if, it has been received", - " successfully.", -#endif /* CK_TMPDIR */ - " /NAMELIST:filename", - " Instead of downloading the files, stores the list of files that", - " would be downloaded in the given local file, one filename per line.", - " /NLST", - " Forces sending of NLST (rather than MLSD) to get the file list.", - " /NOBACKUPFILES", - " Don't download any files whose names end with .~~.", - " /NODOTFILES", - " Don't download any files whose names begin with period (.).", - " /QUIET", - " Suppress the file-transfer display.", -#ifdef FTP_RESTART - " /RECOVER", /* /RESTART */ - " Resume a download that was previously interrupted from the point of", - " failure. Works only in binary mode. Not supported by all servers.", - " Synonym: /RESTART.", -#endif /* FTP_RESTART */ -#ifdef RECURSIVE - " /RECURSIVE", /* /SUBDIRECTORIES */ - " Create subdirectories automatically if the server sends files", - " recursively and includes pathnames (most don't).", -#endif /* RECURSIVE */ - " /RENAME-TO:text", - " Each file that is downloaded is to be renamed as indicated just,", - " after, and only if, it has arrived successfully.", -#ifndef NOCSETS - " /SERVER-CHARACTER-SET:name", - " When downloading in text mode and character-set conversion is desired" -, " this specifies the original file's character set on the server.", -#endif /* NOCSETS */ - " /SERVER-RENAME:text", - " Each server source file is to be renamed on the server as indicated", - " immediately after, but only if, it has arrived succesfully.", - " /SMALLER-THAN:number", - " Download only those files smaller than the given number of bytes.", - " /TEXT", /* /ASCII */ - " Force text mode. Synonym: /ASCII.", - " /TENEX", - " Force TENEX (TOPS-20) mode (see HELP SET FTP TYPE).", -#ifndef NOCSETS - " /TRANSPARENT", - " When downloading in text mode, do not convert chracter-sets.", -#endif /* NOCSETS */ - " /TO-SCREEN", - " The downloaded file is to be displayed on the screen.", -#ifdef DOUPDATE - " /UPDATE", - " Equivalent to /COLLISION:UPDATE. Download only those files that are", - " newer than than their local counterparts, or that do not exist on", - " the local computer.", -#endif /* DOUPDATE */ - "" -}; -static char * fhs_hlp[] = { /* HELP */ - "Syntax: FTP HELP [ command [ subcommand... ] ]", - " Asks the FTP server for help about the given command. First use", - " FTP HELP by itself to get a list of commands, then use HELP FTP xxx", - " to get help for command \"xxx\". Synonyms: REMOTE HELP, RHELP.", - "" -}; -static char * fhs_idl[] = { /* IDLE */ - "Syntax: FTP IDLE [ number ]", - " If given without a number, this asks the FTP server to tell its", - " current idle-time limit. If given with a number, it asks the server", - " to change its idle-time limit to the given number of seconds.", - "" -}; -static char * fhs_usr[] = { /* USER, LOGIN */ - "Syntax: FTP USER username [ password [ account ] ]", - " Log in to the FTP server. To be used when connected but not yet", - " logged in, e.g. when SET FTP AUTOLOGIN is OFF or autologin failed.", - " If you omit the password, and one is required by the server, you are", - " prompted for it. If you omit the account, no account is sent.", - " Synonym: FTP LOGIN.", - "" -}; -static char * fhs_get[] = { /* GET */ - "Syntax: [ FTP ] GET [ options ] filename [ as-name ]", - " Download a single file. Asks the FTP server to send the given file.", - " The optional as-name is the name to store it under when it arrives;", - " if omitted, the file is stored with the name it arrived with, as", - " modified according to the FTP FILENAMES setting or /FILENAMES: switch", - " value. Aside from the file list and as-name, syntax and options are", - " the same as for FTP MGET, which is used for downloading multiple files." -, "" -}; -static char * fhs_mkd[] = { /* MKDIR */ - "Syntax: FTP MKDIR directory", - " Asks the FTP server to create a directory with the given name,", - " which must be in the syntax of the server's file system. Synonyms:", - " REMOTE MKDIR, RMKDIR.", - "" -}; -static char * fhs_mod[] = { /* MODTIME */ - "Syntax: FTP MODTIME filename", - " Asks the FTP server to send the modification time of the given file,", - " to be displayed on the screen. The date-time format is all numeric:", - " yyyymmddhhmmssxxx... (where xxx... is 0 or more digits indicating", - " fractions of seconds).", - "" -}; -static char * fhs_mpu[] = { /* MPUT */ - "Syntax: [ FTP ] MPUT [ switches ] filespec [ filespec [ filespec ... ] ]", - " Uploads files. Sends the given file or files to the FTP server.", - " Also see FTP PUT. Optional switches are:", - " ", - " /AFTER:date-time", - " Uploads only those files newer than the given date-time.", - " HELP DATE for info about date-time formats. Synonym: /SINCE.", -#ifdef PUTARRAY - " /ARRAY:array-designator", - " Tells Kermit to upload the contents of the given array, rather than", - " a file.", -#endif /* PUTARRAY */ - " /AS-NAME:text", - " Name under which to send files.", - " Pattern required for for multiple files.", - " /BEFORE:date-time", - " Upload only those files older than the given date-time.", - " /BINARY", - " Force binary mode. Synonym: /IMAGE.", -#ifdef PUTPIPE - " /COMMAND", - " Specifies that the filespec is a command whose standard output is", - " to be sent.", -#endif /* PUTPIPE */ - -#ifdef COMMENT -#ifdef DOUPDATE - " /DATES-DIFFER", - " Upload only those files whose modification date-times differ from", - " those on the server, or that don't exist on the server at all.", -#endif /* DOUPDATE */ -#endif /* COMMENT */ - - " /DELETE", - " Specifies that each source file is to be deleted after, and only if,", - " it is successfully uploaded.", - " /DOTFILES", - " Include files whose names begin with period (.).", - " /ERROR-ACTION:{PROCEED,QUIT}", - " When uploading a group of files, what to do upon failure to", - " transfer a file: quit or proceed to the next one.", - " /EXCEPT:pattern", - " Exception list: don't upload any files that match this pattern.", - " See HELP WILDCARD for pattern syntax.", - " /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}", - " Whether to convert outbound filenames to common syntax.", -#ifdef PIPESEND -#ifndef NOSPL - " /FILTER:command", - " Pass outbound files through the given command.", -#endif /* NOSPL */ -#endif /* PIPESEND */ -#ifdef CKSYMLINK - " /FOLLOWINKS", - " Send files that are pointed to by symbolic links.", - " /NOFOLLOWINKS", - " Skip over symbolic links (default).", -#endif /* CKSYMLINK */ - " /LARGER-THAN:number", - " Only upload files that are larger than the given number of bytes.", - " /LISTFILE:filename", - " Obtain the list of files to upload from the given file.", -#ifndef NOCSETS - " /LOCAL-CHARACTER-SET:name", - " When uploading in text mode and character-set conversion is", - " desired, this specifies the source-file character set.", -#endif /* NOCSETS */ -#ifdef CK_TMPDIR - " /MOVE-TO:directory", - " Each source file that is uploaded is to be moved to the given local", - " directory when, and only if, the transfer is successful.", -#endif /* CK_TMPDIR */ - " /NOBACKUPFILES", - " Don't upload any files whose names end with .~~.", -#ifdef UNIXOROSK - " /NODOTFILES", - " Don't upload any files whose names begin with period (.).", -#endif /* UNIXOROSK */ - " /NOT-AFTER:date-time", - " Upload only files that are not newer than the given date-time", - " /NOT-BEFORE:date-time", - " Upload only files that are not older than the given date-time", -#ifdef UNIX - " /PERMISSIONS", - " Ask the server to set the permissions of each file it receives", - " according to the source file's permissions.", -#endif /* UNIX */ - " /QUIET", - " Suppress the file-transfer display.", -#ifdef FTP_RESTART - " /RECOVER", - " Resume an upload that was previously interrupted from the point of", - " failure. Synonym: /RESTART.", -#endif /* FTP_RESTART */ -#ifdef RECURSIVE - " /RECURSIVE", - " Send files from the given directory and all the directories beneath", - " it. Synonym: /SUBDIRECTORIES.", -#endif /* RECURSIVE */ - " /RENAME-TO:text", - " Each source file that is uploaded is to be renamed on the local", - " local computer as indicated when and only if, the transfer completes", - " successfully.", -#ifndef NOCSETS - " /SERVER-CHARACTER-SET:name", - " When uploading in text mode and character-set conversion is desired,", - " this specifies the character set to which the file should be", - " converted for storage on the server.", -#endif /* NOCSETS */ - " /SERVER-RENAME:text", - " Each file that is uploaded is to be renamed as indicated on the", - " server after, and only if, if arrives successfully.", - " /SIMULATE", - " Show which files would be sent without actually sending them.", - " /SMALLER-THAN:number", - " Upload only those files smaller than the given number of bytes.", - " /TEXT", - " Force text mode. Synonym: /ASCII.", - " /TENEX", - " Force TENEX (TOPS-20) mode (see HELP SET FTP TYPE).", -#ifndef NOCSETS - " /TRANSPARENT", - " When uploading in text mode, do not convert chracter-sets.", -#endif /* NOCSETS */ - " /TYPE:{TEXT,BINARY}", - " Upload only files of the given type.", -#ifdef DOUPDATE - " /UPDATE", - " If a file of the same name exists on the server, upload only if", - " the local file is newer.", -#endif /* DOUPDATE */ - " /UNIQUE-SERVER-NAMES", - " Ask the server to compute new names for any incoming file that has", - " the same name as an existing file.", - "" -}; -static char * fhs_opn[] = { /* OPEN */ -#ifdef CK_SSL - "Syntax: FTP [ OPEN ] [ { /SSL, /TLS } ] hostname [ port ] [ switches ]", - " Opens a connection to the FTP server on the given host. The default", - " TCP port is 21 (990 if SSL/TLS is used), but a different port number", - " can be supplied if necessary. Optional switches are:", -#else /* CK_SSL */ - "Syntax: FTP [ OPEN ] hostname [ port ] [ switches ]", - " Opens a connection to the FTP server on the given host. The default", - " TCP port is 21, but a different port number can be supplied if", - " necessary. Optional switches are:", -#endif /* CK_SSL */ - " ", - " /ANONYMOUS", - " Logs you in anonymously.", - " /USER:text", - " Supplies the given text as your username.", - " /PASSWORD:text", - " Supplies the given text as your password. If you include a username", - " but omit this switch and the server requires a password, you are", - " prompted for it.", - " /ACCOUNT:text", - " Supplies the given text as your account, if required by the server.", - " /ACTIVE", - " Forces an active (rather than passive) connection.", - " /PASSIVE", - " Forces a passive (rather than active) connection.", - " /NOINIT", - " Inhibits sending initial REST, STRU, and MODE commands, which are", - " well-known standard commands, but to which some servers react badly.", - " /NOLOGIN", - " Inhibits autologin for this connection only.", - "" -}; -static char * fhs_opt[] = { /* OPTS, OPTIONS */ - "Syntax: FTP OPTIONS", - " Asks the FTP server to list its current options. Advanced, new,", - " not supported by most FTP servers.", - "" -}; -static char * fhs_put[] = { /* PUT, SEND */ - "Syntax: [ FTP ] PUT [ switches ] filespec [ as-name ]", - " Like FTP MPUT, but only one filespec is allowed, and if it is followed", - " by an additional field, this is interpreted as the name under which", - " to send the file or files. See HELP FTP MPUT.", - "" -}; -static char * fhs_pwd[] = { /* PWD */ - "Syntax: FTP PWD", - " Asks the FTP server to reveal its current working directory.", - " Synonyms: REMOTE PWD, RPWD.", - "" -}; -static char * fhs_quo[] = { /* QUOTE */ - "Syntax: FTP QUOTE text", - " Sends an FTP protocol command to the FTP server. Use this command", - " for sending commands that Kermit might not support.", - "" -}; -static char * fhs_rge[] = { /* REGET */ - "Syntax: FTP REGET", - " Synonym for FTP GET /RECOVER.", - "" -}; -static char * fhs_ren[] = { /* RENAME */ - "Syntax: FTP RENAME name1 name1", - " Asks the FTP server to change the name of the file whose name is name1", - " and which resides in the FTP server's file system, to name2. Works", - " only for single files; wildcards are not accepted.", - "" -}; -static char * fhs_res[] = { /* RESET */ - "Syntax: FTP RESET", - " Asks the server to log out your session, terminating your access", - " rights, without closing the connection.", - "" -}; -static char * fhs_rmd[] = { /* RMDIR */ - "Syntax: FTP RMDIR directory", - " Asks the FTP server to remove the directory whose name is given.", - " This usually requires the directory to be empty. Synonyms: REMOTE", - " RMDIR, RRMDIR.", - "" -}; -static char * fhs_sit[] = { /* SITE */ - "Syntax: FTP SITE text", - " Sends a site-specific command to the FTP server.", - "" -}; -static char * fhs_siz[] = { /* SIZE */ - "Syntax: FTP SIZE filename", - " Asks the FTP server to send a numeric string representing the size", - " of the given file.", - "" -}; -static char * fhs_sta[] = { /* STATUS */ - "Syntax: FTP STATUS [ filename ]", - " Asks the FTP server to report its status. If a filename is given,", - " the FTP server should report details about the file.", - "" -}; -static char * fhs_sys[] = { /* SYSTEM */ - "Syntax: FTP SYSTEM", - " Asks the FTP server to report its operating system type.", - "" -}; -static char * fhs_typ[] = { /* TYPE */ - "Syntax: FTP TYPE { TEXT, BINARY, TENEX }", - " Puts the client and server in the indicated transfer mode.", - " ASCII is a synonym for TEXT. TENEX is used only for uploading 8-bit", - " binary files to a 36-bit platforms such as TENEX or TOPS-20 and/or", - " downloading files from TENEX or TOPS-20 that have been uploaded in", - " TENEX mode.", - "" -}; -static char * fhs_uma[] = { /* UMASK */ - "Syntax: FTP UMASK number", - " Asks the FTP server to set its file creation mode mask. Applies", - " only (or mainly) to UNIX-based FTP servers.", - "" -}; -static char * fhs_chk[] = { /* CHECK */ - "Syntax: FTP CHECK remote-filespec", - " Asks the FTP server if the given file or files exist. If the", - " remote-filespec contains wildcards, this command fails if no server", - " files match, and succeeds if at least one file matches. If the", - " remote-filespec does not contain wildcards, this command succeeds if", - " the given file exists and fails if it does not.", - "" -}; -static char * fhs_ena[] = { /* ENABLE */ - "Syntax: FTP ENABLE { AUTH, FEAT, MDTM, MLST, SIZE }", - " Enables the use of the given FTP protocol command in case it has been", - " disabled (but this is no guarantee that the FTP server understands it)." -, - " Use SHOW FTP to see which of these commands is enabled and disabled.", - " Also see FTP DISABLE.", - "" -}; -static char * fhs_dis[] = { /* DISABLE */ - "Syntax: FTP DISABLE { AUTH, FEAT, MDTM, MLST, SIZE }", - " Disables the use of the given FTP protocol command.", - " Also see FTP ENABLE.", - "" -}; - -#endif /* NOHELP */ - -int -doftphlp() { - int cx; - if ((cx = cmkey(ftpcmdtab,nftpcmd,"","",xxstring)) < 0) - if (cx != -3) - return(cx); - if ((x = cmcfm()) < 0) - return(x); - -#ifdef NOHELP - printf("Sorry, no help available\n"); -#else - switch (cx) { - case -3: - return(hmsga(fhs_ftp)); - case FTP_ACC: /* ACCOUNT */ - return(hmsga(fhs_acc)); - case FTP_APP: /* APPEND */ - return(hmsga(fhs_app)); - case FTP_CLS: /* BYE, CLOSE */ - return(hmsga(fhs_cls)); - case FTP_CWD: /* CD, CWD */ - return(hmsga(fhs_cwd)); - case FTP_GUP: /* CDUP, UP */ - return(hmsga(fhs_gup)); - case FTP_CHM: /* CHMOD */ - return(hmsga(fhs_chm)); - case FTP_MDE: /* DELETE, MDELETE */ - return(hmsga(fhs_mde)); - case FTP_DIR: /* DIRECTORY */ - return(hmsga(fhs_dir)); - case FTP_VDI: /* VDIRECTORY */ - return(hmsga(fhs_vdi)); - case FTP_FEA: /* FEATURES */ - return(hmsga(fhs_fea)); - case FTP_GET: /* GET */ - return(hmsga(fhs_get)); - case FTP_HLP: /* HELP */ - return(hmsga(fhs_hlp)); - case FTP_IDL: /* IDLE */ - return(hmsga(fhs_idl)); - case FTP_USR: /* USER, LOGIN */ - return(hmsga(fhs_usr)); - case FTP_MGE: /* MGET */ - return(hmsga(fhs_mge)); - case FTP_MKD: /* MKDIR */ - return(hmsga(fhs_mkd)); - case FTP_MOD: /* MODTIME */ - return(hmsga(fhs_mod)); - case FTP_MPU: /* MPUT */ - return(hmsga(fhs_mpu)); - case FTP_OPN: /* OPEN */ - return(hmsga(fhs_opn)); - case FTP_OPT: /* OPTS, OPTIONS */ - return(hmsga(fhs_opt)); - case FTP_PUT: /* PUT, SEND */ - return(hmsga(fhs_put)); - case FTP_PWD: /* PWD */ - return(hmsga(fhs_pwd)); - case FTP_QUO: /* QUOTE */ - return(hmsga(fhs_quo)); - case FTP_RGE: /* REGET */ - return(hmsga(fhs_rge)); - case FTP_REN: /* RENAME */ - return(hmsga(fhs_ren)); - case FTP_RES: /* RESET */ - return(hmsga(fhs_res)); - case FTP_RMD: /* RMDIR */ - return(hmsga(fhs_rmd)); - case FTP_SIT: /* SITE */ - return(hmsga(fhs_sit)); - case FTP_SIZ: /* SIZE */ - return(hmsga(fhs_siz)); - case FTP_STA: /* STATUS */ - return(hmsga(fhs_sta)); - case FTP_SYS: /* SYSTEM */ - return(hmsga(fhs_sys)); - case FTP_TYP: /* TYPE */ - return(hmsga(fhs_typ)); - case FTP_UMA: /* UMASK */ - return(hmsga(fhs_uma)); - case FTP_CHK: /* CHECK */ - return(hmsga(fhs_chk)); - case FTP_ENA: - return(hmsga(fhs_ena)); - case FTP_DIS: - return(hmsga(fhs_dis)); - default: - printf("Sorry, help available for this command.\n"); - break; - } -#endif /* NOHELP */ - return(success = 0); -} - -int -dosetftphlp() { - int cx; - if ((cx = cmkey(ftpset,nftpset,"","",xxstring)) < 0) - if (cx != -3) - return(cx); - if (cx != -3) - ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ); - if ((x = cmcfm()) < 0) - return(x); - -#ifdef NOHELP - printf("Sorry, no help available\n"); -#else - switch (cx) { - case -3: - printf("\nSyntax: SET FTP parameter value\n"); - printf(" Type \"help set ftp ?\" for a list of parameters.\n"); - printf(" Type \"help set ftp xxx\" for information about setting\n"); - printf(" parameter xxx. Type \"show ftp\" for current values.\n\n"); - return(0); - - case FTS_BUG: - printf("\nSyntax: SET FTP BUG {ON, OFF}\n"); - printf( - " Activates a workaround for the named bug in the FTP server.\n"); - printf(" Type SET FTP BUG ? for a list of names.\n"); - printf(" For each bug, the default is OFF\n\n"); - return(0); - -#ifdef FTP_SECURITY - case FTS_ATP: /* "authtype" */ - printf("\nSyntax: SET FTP AUTHTYPE list\n"); - printf(" Specifies an ordered list of authentication methods to be\n" - ); - printf(" when FTP AUTOAUTHENTICATION is ON. The default list is:\n"); - printf(" GSSAPI-KRB5, SRP, KERBEROS_V4, TLS, SSL.\n\n"); - return(0); - - case FTS_AUT: /* "autoauthentication" */ - printf("\nSyntax:SET FTP AUTOAUTHENTICATION { ON, OFF }\n"); - printf(" Tells whether authentication should be negotiated by the\n"); - printf(" FTP OPEN command. Default is ON.\n\n"); - break; - - case FTS_CRY: /* "autoencryption" */ - printf("\nSET FTP AUTOENCRYPTION { ON, OFF }\n"); - printf(" Tells whether encryption (privacy) should be negotiated\n"); - printf(" by the FTP OPEN command. Default is ON.\n\n"); - break; -#endif /* FTP_SECURITY */ - - case FTS_LOG: /* "autologin" */ - printf("\nSET FTP AUTOLOGIN { ON, OFF }\n"); - printf(" Tells Kermit whether to try to log you in automatically\n"); - printf(" as part of the connection process.\n\n"); - break; - - case FTS_DIS: - printf("\nSET FTP DISPLAY { BRIEF, FULLSCREEN, CRT, ... }\n"); - printf(" Chooses the file-transfer display style for FTP.\n"); - printf(" Like SET TRANSFER DISPLAY but applies only to FTP.\n\n"); - break; - -#ifndef NOCSETS - case FTS_XLA: /* "character-set-translation" */ - printf("\nSET FTP CHARACTER-SET-TRANSLATION { ON, OFF }\n"); - printf(" Whether to translate character sets when transferring\n"); - printf(" text files with FTP. OFF by default.\n\n"); - break; - -#endif /* NOCSETS */ - case FTS_FNC: /* "collision" */ - printf("\n"); - printf( -"Syntax: SET FTP COLLISION { BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE }\n" - ); - printf(" Tells what do when an incoming file has the same name as\n"); - printf(" an existing file when downloading with FTP.\n\n"); - break; - -#ifdef FTP_SECURITY - case FTS_CPL: /* "command-protection-level" */ - printf("\n"); - printf( -"Syntax: SET FTP COMMAND-PROTECTION-LEVEL { CLEAR,CONFIDENTIAL,PRIVATE,SAFE }" - ); - printf("\n"); - printf( -" Tells what level of protection is applied to the FTP command channel.\n\n"); - break; - case FTS_CFW: /* "credential-forwarding" */ - printf("\nSyntax: SET FTP CREDENTIAL-FORWARDING { ON, OFF }\n"); - printf(" Tells whether end-user credentials are to be forwarded\n"); - printf(" to the server if supported by the authentication method\n"); - printf(" (GSSAPI-KRB5 only).\n\n"); - break; - case FTS_DPL: /* "data-protection-level" */ - printf("\n"); - printf( -"Syntax: SET FTP DATA-PROTECTION-LEVEL { CLEAR,CONFIDENTIAL,PRIVATE,SAFE }" - ); - printf("\n"); - printf( -" Tells what level of protection is applied to the FTP data channel.\n\n"); - break; -#endif /* FTP_SECURITY */ - - case FTS_DBG: /* "debug" */ - printf("\nSyntax: SET FTP DEBUG { ON, OFF }\n"); - printf(" Whether to print FTP protocol messages.\n\n"); - return(0); - - case FTS_ERR: /* "error-action" */ - printf("\nSyntax: SET FTP ERROR-ACTION { QUIT, PROCEED }\n"); - printf(" What to do when an error occurs when transferring a group\n") - ; - printf(" of files: quit and fail, or proceed to the next file.\n\n"); - return(0); - - case FTS_CNV: /* "filenames" */ - printf("\nSyntax: SET FTP FILENAMES { AUTO, CONVERTED, LITERAL }\n"); - printf(" What to do with filenames: convert them, take and use them\n" - ); - printf(" literally; or choose what to do automatically based on the\n" - ); - printf(" OS type of the server. The default is AUTO.\n\n"); - return(0); - - case FTS_PSV: /* "passive-mode" */ - printf("\nSyntax: SET FTP PASSIVE-MODE { ON, OFF }\n"); - printf(" Whether to use passive mode, which helps to get through\n"); - printf(" firewalls. ON by default.\n\n"); - return(0); - - case FTS_PRM: /* "permissions" */ - printf("\nSyntax: SET FTP PERMISSIONS { AUTO, ON, OFF }\n"); - printf(" Whether to try to send file permissions when uploading.\n"); - printf(" OFF by default. AUTO means only if client and server\n"); - printf(" have the same OS type.\n\n"); - return(0); - - case FTS_TST: /* "progress-messages" */ - printf("\nSyntax: SET FTP PROGRESS-MESSAGES { ON, OFF }\n"); - printf(" Whether Kermit should print locally-generated feedback\n"); - printf(" messages for each non-file-transfer command."); - printf(" ON by default.\n\n"); - return(0); - - case FTS_SPC: /* "send-port-commands" */ - printf("\nSyntax: SET FTP SEND-PORT-COMMANDS { ON, OFF }\n"); - printf(" Whether Kermit should send a new PORT command for each"); - printf(" task.\n\n"); - return(0); - -#ifndef NOCSETS - case FTS_CSR: /* "server-character-set" */ - printf("\nSyntax: SET FTP SERVER-CHARACTER-SET name\n"); - printf(" The name of the character set used for text files on the\n"); - printf(" server. Enter a name of '?' for a menu.\n\n"); - return(0); -#endif /* NOCSETS */ - - case FTS_STO: /* "server-time-offset */ - printf( -"\nSyntax: SET FTP SERVER-TIME-OFFSET +hh[:mm[:ss]] or -hh[:mm[:ss]]\n"); - printf( -" Specifies an offset to apply to the server's file timestamps.\n"); - printf( -" Use this to correct for misconfigured server time or timezone.\n"); - printf( -" Format: must begin with + or - sign. Hours must be given; minutes\n"); - printf( -" and seconds are optional: +4 = +4:00 = +4:00:00 (add 4 hours).\n\n"); - return(0); - - case FTS_TYP: /* "type" */ - printf("\nSyntax: SET FTP TYPE { TEXT, BINARY, TENEX }\n"); - printf(" Establishes the default transfer mode.\n"); - printf(" TENEX is used for uploading 8-bit binary files to 36-bit\n"); - printf(" platforms such as TENEX and TOPS-20 and for downloading\n"); - printf(" them again.\n\n"); - return(0); - -#ifdef PATTERNS - case FTS_GFT: - printf("\nSyntax: SET FTP GET-FILETYPE-SWITCHING { ON, OFF }\n"); - printf(" Tells whether GET and MGET should automatically switch\n"); - printf(" the appropriate file type, TEXT, BINARY, or TENEX, by\n"); - printf(" matching the name of each incoming file with its list of\n"); - printf(" FILE TEXT-PATTERNS and FILE BINARY-PATTERNS. ON by\n"); - printf(" default. SHOW PATTERNS displays the current pattern\n"); - printf(" list. HELP SET FILE to see how to change it.\n"); - break; -#endif /* PATTERNS */ - - case FTS_USN: /* "unique-server-names" */ - printf("\nSyntax: SET FTP UNIQUE-SERVER-NAMES { ON, OFF }\n"); - printf(" Tells whether to ask the server to create unique names\n"); - printf(" for any uploaded file that has the same name as an\n"); - printf(" existing file. Default is OFF.\n\n"); - return(0); - - case FTS_VBM: /* "verbose-mode" */ - printf("\nSyntax: SET FTP VERBOSE-MODE { ON, OFF }\n"); - printf(" Whether to display all responses from the FTP server.\n"); - printf(" OFF by default.\n\n"); - return(0); - - case FTS_DAT: - printf("\nSyntax: SET FTP DATES { ON, OFF }\n"); - printf(" Whether to set date of incoming files from the file date\n"); - printf(" on the server. ON by default. Note: there is no way to\n") - ; - printf(" set the date on files uploaded to the server. Also note\n"); - printf(" that not all servers support this feature.\n\n"); - return(0); - - case FTS_APW: - printf("\nSyntax: SET FTP ANONYMOUS-PASSWORD [ text ]\n"); - printf(" Password to supply automatically on anonymous FTP\n"); - printf(" connections instead of the default user@host.\n"); - printf(" Omit optional text to restore default.\n\n"); - return(0); - - default: - printf("Sorry, help not available for \"set ftp %s\"\n",tmpbuf); - } -#endif /* NOHELP */ - return(0); -} - -#ifndef L_SET -#define L_SET 0 -#endif /* L_SET */ -#ifndef L_INCR -#define L_INCR 1 -#endif /* L_INCR */ - -#ifdef FTP_SRP -char srp_user[BUFSIZ]; /* where is BUFSIZ defined? */ -char *srp_pass; -char *srp_acct; -#endif /* FTP_SRP */ - -static int kerror; /* Needed for all auth types */ - -static struct sockaddr_in hisctladdr; -static struct sockaddr_in hisdataaddr; -static struct sockaddr_in data_addr; -static int data = -1; -static int ptflag = 0; -static struct sockaddr_in myctladdr; - -#ifdef COMMENT -#ifndef OS2 -UID_T getuid(); -#endif /* OS2 */ -#endif /* COMMENT */ - - -static int cpend = 0; /* No pending replies */ - -#ifdef CK_SSL -extern SSL *ssl_ftp_con; -extern SSL_CTX *ssl_ftp_ctx; -extern SSL *ssl_ftp_data_con; -extern int ssl_ftp_active_flag; -extern int ssl_ftp_data_active_flag; -#endif /* CK_SSL */ - -/* f t p c m d -- Send a command to the FTP server */ -/* - Call with: - char * cmd: The command to send. - char * arg: The argument (e.g. a filename). - int lcs: The local character set index. - int rcs: The remote (server) character set index. - int vbm: Verbose mode: - 0 = force verbosity off - >0 = force verbosity on - - If arg is given (not NULL or empty) and lcs != rcs and both are > -1, - and neither lcs or rcs is UCS-2, the arg is translated from the local - character set to the remote one before sending the result to the server. - - Returns: - 0 on failure with ftpcode = -1 - >= 0 on success (getreply() result) with ftpcode = 0. -*/ -static char xcmdbuf[RFNBUFSIZ]; - -static int -ftpcmd(cmd,arg,lcs,rcs,vbm) char * cmd, * arg; int lcs, rcs, vbm; { - char * s = NULL; - int r = 0, x = 0, fc = 0, len = 0, cmdlen = 0, q = -1; - sig_t oldintr; - - if (ftp_deb) /* DEBUG */ - vbm = 1; - else if (quiet || dpyactive) /* QUIET or File Transfer Active */ - vbm = 0; - else if (vbm < 0) /* VERBOSE */ - vbm = ftp_vbm; - - cancelfile = 0; - if (!cmd) cmd = ""; - if (!arg) arg = ""; - cmdlen = (int)strlen(cmd); - len = cmdlen + (int)strlen(arg) + 1; - - if (ftp_deb /* && !dpyactive */ ) { -#ifdef FTP_PROXY - if (ftp_prx) printf("%s ", ftp_host); -#endif /* FTP_PROXY */ - printf("---> "); - if (!anonymous && strcmp("PASS",cmd) == 0) - printf("PASS XXXX"); - else - printf("%s %s",cmd,arg); - printf("\n"); - } - /* bzero(xcmdbuf,RFNBUFSIZ); */ - ckmakmsg(xcmdbuf,RFNBUFSIZ, cmd, *arg ? " " : "", arg, NULL); - -#ifdef DEBUG - if (deblog) { - debug(F110,"ftpcmd cmd",cmd,0); - debug(F110,"ftpcmd arg",arg,0); - debug(F101,"ftpcmd lcs","",lcs); - debug(F101,"ftpcmd rcs","",rcs); - } -#endif /* DEBUG */ - - if (csocket == -1) { - perror("No control connection for command"); - ftpcode = -1; - return(0); - } - havesigint = 0; - oldintr = signal(SIGINT, cmdcancel); - -#ifndef NOCSETS - if (*arg && /* If an arg was given */ - lcs > -1 && /* and a local charset */ - rcs > -1 && /* and a remote charset */ - lcs != rcs && /* and the two are not the same */ - lcs != FC_UCS2 && /* and neither one is UCS-2 */ - rcs != FC_UCS2 /* ... */ - ) { - initxlate(lcs,rcs); /* Translate arg from lcs to rcs */ - xgnbp = arg; /* Global pointer to input string */ - rfnptr = rfnbuf; /* Global pointer to output buffer */ - - while (1) { - if ((c0 = xgnbyte(FC_UCS2,lcs,strgetc)) < 0) break; - if (xpnbyte(c0,TC_UCS2,rcs,strputc) < 0) break; - } - /* - We have to copy here instead of translating directly into - xcmdbuf[] so strputc() can check length. Alternatively we could - write yet another xpnbyte() output function. - */ - if ((int)strlen(rfnbuf) > (RFNBUFSIZ - (cmdlen+1))) { - printf("?FTP command too long: %s + arg\n",cmd); - ftpcode = -1; - return(0); - } - x = ckstrncpy(&xcmdbuf[cmdlen+1], rfnbuf, RFNBUFSIZ - (cmdlen+1)); - } -#endif /* NOCSETS */ - - s = xcmdbuf; /* Command to send to server */ - -#ifdef DEBUG - if (deblog) { /* Log it */ - if (!anonymous && !ckstrcmp(s,"PASS ",5,0)) { - /* But don't log passwords */ - debug(F110,"FTP SENT ","PASS XXXX",0); - } else { - debug(F110,"FTP SENT ",s,0); - } - } -#endif /* DEBUG */ - -#ifdef CK_ENCRYPTION - again: -#endif /* CK_ENCRYPTION */ - if (scommand(s) == 0) { /* Send it. */ - signal(SIGINT, oldintr); - return(0); - } - cpend = 1; - x = !strcmp(cmd,"QUIT"); /* Is it the QUIT command? */ - if (x) /* In case we're interrupted */ - connected = 0; /* while waiting for the reply... */ - - fc = 0; /* Function code for getreply() */ - if (!strncmp(cmd,"AUTH ",5) /* Must parse AUTH reply */ -#ifdef FTPHOST - && strncmp(cmd, "HOST ",5) -#endif /* FTPHOST */ - ) { - fc = GRF_AUTH; - } else if (!ckstrcmp(cmd,"FEAT",-1,0)) { /* Must parse FEAT reply */ - fc = GRF_FEAT; /* But FEAT not widely understood */ - if (!ftp_deb) /* So suppress error messages */ - vbm = 9; - } - r = getreply(x, /* Expect connection to close */ - lcs,rcs, /* Charsets */ - vbm, /* Verbosity */ - fc /* Function code */ - ); - if (q > -1) - quiet = q; - -#ifdef CK_ENCRYPTION - if (ftpcode == 533 && ftp_cpl == FPL_PRV) { - fprintf(stderr, - "ENC command not supported at server; retrying under MIC...\n"); - ftp_cpl = FPL_SAF; - goto again; - } -#endif /* CK_ENCRYPTION */ -#ifdef COMMENT - if (cancelfile && oldintr != SIG_IGN) - (*oldintr)(SIGINT); -#endif /* COMMENT */ - signal(SIGINT, oldintr); - return(r); -} - -static VOID -lostpeer() { - debug(F100,"lostpeer","",0); - if (connected) { - if (csocket != -1) { -#ifdef CK_SSL - if (ssl_ftp_active_flag) { - SSL_shutdown(ssl_ftp_con); - SSL_free(ssl_ftp_con); - ssl_ftp_proxy = 0; - ssl_ftp_active_flag = 0; - ssl_ftp_con = NULL; - } -#endif /* CK_SSL */ -#ifdef TCPIPLIB - socket_close(csocket); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(csocket, 1+1); -#endif /* USE_SHUTDOWN */ - close(csocket); -#endif /* TCPIPLIB */ - csocket = -1; - } - if (data != -1) { -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; - } -#endif /* CK_SSL */ -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = -1; - } - connected = 0; - anonymous = 0; - loggedin = 0; - auth_type = NULL; - ftp_cpl = ftp_dpl = FPL_CLR; -#ifdef CKLOGDIAL - ftplogend(); -#endif /* CKLOGDIAL */ - -#ifdef LOCUS - if (autolocus) /* Auotomatic locus switching... */ - setlocus(1,1); /* Switch locus to local. */ -#endif /* LOCUS */ -#ifdef OS2 - DialerSend(OPT_KERMIT_HANGUP, 0); -#endif /* OS2 */ - } -#ifdef FTP_PROXY - pswitch(1); - if (connected) { - if (csocket != -1) { -#ifdef TCPIPLIB - socket_close(csocket); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(csocket, 1+1); -#endif /* USE_SHUTDOWN */ - close(csocket); -#endif /* TCPIPLIB */ - csocket = -1; - } - connected = 0; - anonymous = 0; - loggedin = 0; - auth_type = NULL; - ftp_cpl = ftp_dpl = FPL_CLR; - } - proxflag = 0; - pswitch(0); -#endif /* FTP_PROXY */ -} - -int -ftpisopen() { - return(connected); -} - -static int -ftpclose() { - extern int quitting; - if (!connected) - return(0); - if (!ftp_vbm && !quiet) printlines = 1; - ftpcmd("QUIT",NULL,0,0,ftp_vbm); - if (csocket) { -#ifdef CK_SSL - if (ssl_ftp_active_flag) { - SSL_shutdown(ssl_ftp_con); - SSL_free(ssl_ftp_con); - ssl_ftp_proxy = 0; - ssl_ftp_active_flag = 0; - ssl_ftp_con = NULL; - } -#endif /* CK_SSL */ -#ifdef TCPIPLIB - socket_close(csocket); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(csocket, 1+1); -#endif /* USE_SHUTDOWN */ - close(csocket); -#endif /* TCPIPLIB */ - } - csocket = -1; - connected = 0; - anonymous = 0; - loggedin = 0; - mdtmok = 1; - sizeok = 1; - featok = 1; - stouarg = 1; - typesent = 0; - data = -1; - globaldin = -1; -#ifdef FTP_PROXY - if (!proxy) - macnum = 0; -#endif /* FTP_PROXY */ - auth_type = NULL; - ftp_dpl = FPL_CLR; -#ifdef CKLOGDIAL - ftplogend(); -#endif /* CKLOGDIAL */ -#ifdef LOCUS - /* Unprefixed file management commands are executed locally */ - if (autolocus && !ftp_cmdlin && !quitting) { - setlocus(1,1); - } -#endif /* LOCUS */ -#ifdef OS2 - DialerSend(OPT_KERMIT_HANGUP, 0); -#endif /* OS2 */ - return(0); -} - -int -ftpopen(remote, service, use_tls) char * remote, * service; int use_tls; { - char * host; - - if (connected) { - printf("?Already connected to %s, use FTP CLOSE first.\n", ftp_host); - ftpcode = -1; - return(0); - } -#ifdef FTPHOST - hostcmd = 0; -#endif /* FTPHOST */ - alike = 0; - ftp_srvtyp[0] = NUL; - if (!service) service = ""; - if (!*service) service = use_tls ? "ftps" : "ftp"; - - if (!isdigit(service[0])) { - struct servent *destsp; - destsp = getservbyname(service, "tcp"); - if (!destsp) { - if (!ckstrcmp(service,"ftp",-1,0)) { - ftp_port = 21; - } else if (!ckstrcmp(service,"ftps",-1,0)) { - ftp_port = 990; - } else { - printf("?Bad port name - \"%s\"\n", service); - ftpcode = -1; - return(0); - } - } else { - ftp_port = destsp->s_port; - ftp_port = ntohs(ftp_port); - } - } else - ftp_port = atoi(service); - if (ftp_port <= 0) { - printf("?Bad port name - \"%s\"\n", service); - ftpcode = -1; - return(0); - } - host = ftp_hookup(remote, ftp_port, use_tls); - if (host) { - ckstrncpy(ftp_user_host,remote,MAX_DNS_NAMELEN); - connected = 1; /* Set FTP defaults */ - ftp_cpl = ftp_dpl = FPL_CLR; - curtype = FTT_ASC; /* Server uses ASCII mode */ - form = FORM_N; - mode = MODE_S; - stru = STRU_F; - strcpy(bytename, "8"); - bytesize = 8; - -#ifdef FTP_SECURITY - if (ftp_aut) { - if (ftp_auth()) { - if (ftp_cry -#ifdef OS2 - && ck_crypt_is_installed() -#endif /* OS2 */ - ) { - if (!quiet) - printf("FTP Command channel is Private (encrypted)\n"); - ftp_cpl = FPL_PRV; - if (setpbsz(DEFAULT_PBSZ) < 0) { - /* a failure here is most likely caused by a mixup */ - /* in the session key used by client and server */ - printf("?Protection buffer size negotiation failed\n"); - return(0); - } - if (ftpcmd("PROT P",NULL,0,0,ftp_vbm) == REPLY_COMPLETE) { - if (!quiet) - printf("FTP Data channel is Private (encrypted)\n"); - ftp_dpl = FPL_PRV; - } else - printf("?Unable to enable encryption on data channel\n"); - } else { - ftp_cpl = FPL_SAF; - } - } - if (!connected) - goto fail; - } -#endif /* FTP_SECURITY */ - if (ftp_log) /* ^^^ */ - ftp_login(remote); - - if (!connected) - goto fail; - -#ifdef CKLOGDIAL - dologftp(); -#endif /* CKLOGDIAL */ -#ifdef OS2 - DialerSend(OPT_KERMIT_CONNECT, 0); -#endif /* OS2 */ - passivemode = ftp_psv; - sendport = ftp_spc; - mdtmok = 1; - sizeok = 1; - stouarg = 1; - typesent = 0; - - if (ucbuf == NULL) { - actualbuf = DEFAULT_PBSZ; - while (actualbuf && (ucbuf = (CHAR *)malloc(actualbuf)) == NULL) - actualbuf >>= 2; - } - if (!maxbuf) - ucbufsiz = actualbuf - FUDGE_FACTOR; - debug(F101,"ftpopen ucbufsiz","",ucbufsiz); - return(1); - } - fail: - printf("?Can't FTP connect to %s:%s\n",remote,service); - ftpcode = -1; - return(0); -} - -#ifdef CK_SSL -int -ssl_auth() { - int i; - char* p; - - if (ssl_debug_flag) { - fprintf(stderr,"SSL DEBUG ACTIVE\n"); - fflush(stderr); - /* for the moment I want the output on screen */ - } - if (ssl_ftp_data_con != NULL) { - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_con = NULL; - } - if (ssl_ftp_con != NULL) { - SSL_free(ssl_ftp_con); - ssl_ftp_con=NULL; - } - if (ssl_ftp_ctx != NULL) { - SSL_CTX_free(ssl_ftp_ctx); - ssl_ftp_ctx = NULL; - } - - /* The SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS - * was added to OpenSSL 0.9.6e and 0.9.7. It does not exist in previous - * versions - */ -#ifndef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS -#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0L -#endif - if (auth_type && !strcmp(auth_type,"TLS")) { - ssl_ftp_ctx=SSL_CTX_new(SSLv3_client_method()); - if (!ssl_ftp_ctx) - return(0); - SSL_CTX_set_options(ssl_ftp_ctx, - SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA - ); - } else { - ssl_ftp_ctx = SSL_CTX_new(ftp_bug_use_ssl_v2 ? SSLv23_client_method() : - SSLv3_client_method()); - if (!ssl_ftp_ctx) - return(0); - SSL_CTX_set_options(ssl_ftp_ctx, - (ftp_bug_use_ssl_v2 ? 0 : SSL_OP_NO_SSLv2)| - SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA - ); - } - SSL_CTX_set_default_passwd_cb(ssl_ftp_ctx, - (pem_password_cb *)ssl_passwd_callback); - SSL_CTX_set_info_callback(ssl_ftp_ctx,ssl_client_info_callback); - SSL_CTX_set_session_cache_mode(ssl_ftp_ctx,SSL_SESS_CACHE_CLIENT); - -#ifdef OS2 -#ifdef NT - /* The defaults in the SSL crypto library are not appropriate for OS/2 */ - { - char path[CKMAXPATH]; - extern char exedir[]; - - ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-dir: %s\r\n",path); - } - - ckmakmsg(path,CKMAXPATH, - (char *)GetAppData(1),"kermit 95/certs",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-dir: %s\r\n",path); - } - - ckmakmsg(path,CKMAXPATH, - (char *)GetAppData(0),"kermit 95/certs",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-dir: %s\r\n",path); - } - - ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-file: %s\r\n",path); - } - - ckmakmsg(path,CKMAXPATH,(char *)GetAppData(1), - "kermit 95/ca_certs.pem",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-file: %s\r\n",path); - } - - ckmakmsg(path,CKMAXPATH,(char *)GetAppData(0), - "kermit 95/ca_certs.pem",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-file: %s\r\n",path); - } - } -#else /* NT */ - /* The defaults in the SSL crypto library are not appropriate for OS/2 */ - { - - char path[CKMAXPATH]; - extern char exedir[]; - - ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-dir: %s\r\n",path); - } - ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL); - if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) { - debug(F110,"ftp ssl_auth unable to load path",path,0); - if (ssl_debug_flag) - printf("?Unable to load verify-file: %s\r\n",path); - } - } -#endif /* NT */ -#else /* OS2 */ - SSL_CTX_set_default_verify_paths(ssl_ftp_ctx); -#endif /* OS2 */ - - if (ssl_verify_file && - SSL_CTX_load_verify_locations(ssl_ftp_ctx,ssl_verify_file,NULL) == 0) { - debug(F110, - "ftp ssl auth unable to load ssl_verify_file", - ssl_verify_file, - 0 - ); - if (ssl_debug_flag) - printf("?Unable to load verify-file: %s\r\n",ssl_verify_file); - } - if (ssl_verify_dir && - SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,ssl_verify_dir) == 0) { - debug(F110, - "ftp ssl auth unable to load ssl_verify_dir", - ssl_verify_dir, - 0 - ); - if (ssl_debug_flag) - printf("?Unable to load verify-dir: %s\r\n",ssl_verify_dir); - } - - /* set up the new CRL Store */ - crl_store = (X509_STORE *)X509_STORE_new(); - if (crl_store) { -#ifdef OS2 - char path[CKMAXPATH]; - extern char exedir[]; - - ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL); - if (X509_STORE_load_locations(crl_store,NULL,path) == 0) { - debug(F110,"ftp ssl auth unable to load dir",path,0); - if (ssl_debug_flag) - printf("?Unable to load crl-dir: %s\r\n",path); - } -#ifdef NT - ckmakmsg(path,CKMAXPATH, - (char *)GetAppData(1),"kermit 95/crls",NULL,NULL); - if (X509_STORE_load_locations(crl_store,NULL,path) == 0) { - debug(F110,"ftp ssl auth unable to load dir",path,0); - if (ssl_debug_flag) - printf("?Unable to load crl-dir: %s\r\n",path); - } - ckmakmsg(path,CKMAXPATH, - (char *)GetAppData(0),"kermit 95/crls",NULL,NULL); - if (X509_STORE_load_locations(crl_store,NULL,path) == 0) { - debug(F110,"ftp ssl auth unable to load dir",path,0); - if (ssl_debug_flag) - printf("?Unable to load crl-dir: %s\r\n",path); - } -#endif /* NT */ - - ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL); - if (X509_STORE_load_locations(crl_store,path,NULL) == 0) { - debug(F110,"ftp ssl auth unable to load file",path,0); - if (ssl_debug_flag) - printf("?Unable to load crl-file: %s\r\n",path); - } -#ifdef NT - ckmakmsg(path,CKMAXPATH,(char *)GetAppData(1), - "kermit 95/ca_crls.pem",NULL,NULL); - if (X509_STORE_load_locations(crl_store,path,NULL) == 0) { - debug(F110,"ftp ssl auth unable to load file",path,0); - if (ssl_debug_flag) - printf("?Unable to load crl-file: %s\r\n",path); - } - ckmakmsg(path,CKMAXPATH,(char *)GetAppData(0), - "kermit 95/ca_crls.pem",NULL,NULL); - if (X509_STORE_load_locations(crl_store,path,NULL) == 0) { - debug(F110,"ftp ssl auth unable to load file",path,0); - if (ssl_debug_flag) - printf("?Unable to load crl-file: %s\r\n",path); - } -#endif /* NT */ -#endif /* OS2 */ - - if (ssl_crl_file || ssl_crl_dir) { - if (ssl_crl_file && - X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 0) { - debug(F110, - "ftp ssl auth unable to load ssl_crl_file", - ssl_crl_file, - 0 - ); - if (ssl_debug_flag) - printf("?Unable to load crl-file: %s\r\n",ssl_crl_file); - } - if (ssl_crl_dir && - X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 0) { - debug(F110, - "ftp ssl auth unable to load ssl_crl_dir", - ssl_crl_dir, - 0 - ); - if (ssl_debug_flag) - printf("?Unable to load crl-dir: %s\r\n",ssl_crl_dir); - } - } else { - X509_STORE_set_default_paths(crl_store); - } - } - SSL_CTX_set_verify(ssl_ftp_ctx,ssl_verify_flag, - ssl_client_verify_callback); - ssl_verify_depth = -1; - ssl_ftp_con=(SSL *)SSL_new(ssl_ftp_ctx); - tls_load_certs(ssl_ftp_ctx,ssl_ftp_con,0); - SSL_set_fd(ssl_ftp_con,csocket); - SSL_set_verify(ssl_ftp_con,ssl_verify_flag,NULL); - if (ssl_cipher_list) { - SSL_set_cipher_list(ssl_ftp_con,ssl_cipher_list); - } else { - char * p; - if (p = getenv("SSL_CIPHER")) { - SSL_set_cipher_list(ssl_ftp_con,p); - } else { - SSL_set_cipher_list(ssl_ftp_con,DEFAULT_CIPHER_LIST); - } - } - if (ssl_debug_flag) { - fprintf(stderr,"=>START SSL/TLS connect on COMMAND\n"); - fflush(stderr); - } - if (SSL_connect(ssl_ftp_con) <= 0) { - static char errbuf[1024]; - ckmakmsg(errbuf,1024,"ftp: SSL/TLS connect COMMAND error: ", - ERR_error_string(ERR_get_error(),NULL),NULL,NULL); - fprintf(stderr,"%s\n", errbuf); - fflush(stderr); - ssl_ftp_active_flag=0; - SSL_free(ssl_ftp_con); - ssl_ftp_con = NULL; - } else { - ssl_ftp_active_flag = 1; - - if (!ssl_certsok_flag && !tls_is_krb5(1)) { - char *subject = ssl_get_subject_name(ssl_ftp_con); - - if (!subject) { - if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { - debug(F110,"ssl_auth","[SSL - FAILED]",0); - return(ssl_ftp_active_flag = 0); - } else { - if (uq_ok("Warning: Server didn't provide a certificate\n", - "Continue? (Y/N)",3,NULL,0) <= 0) { - debug(F110, "ssl_auth","[SSL - FAILED]",0); - return(ssl_ftp_active_flag = 0); - } - } - } else if (ssl_check_server_name(ssl_ftp_con, ftp_user_host)) { - debug(F110,"ssl_auth","[SSL - FAILED]",0); - return(ssl_ftp_active_flag = 0); - } - } - debug(F110,"ssl_auth","[SSL - OK]",0); - ssl_display_connect_details(ssl_ftp_con,0,ssl_verbose_flag); - } - if (ssl_debug_flag) { - fprintf(stderr,"=>DONE SSL/TLS connect on COMMAND\n"); - fflush(stderr); - } - return(ssl_ftp_active_flag); -} -#endif /* CK_SSL */ - -static sigtype -cmdcancel(sig) int sig; { -#ifdef OS2 - /* In Unix we "chain" to trap(), which prints this */ - printf("^C...\n"); -#endif /* OS2 */ - debug(F100,"ftp cmdcancel caught SIGINT ","",0); - fflush(stdout); - secure_getc(0,1); /* Initialize net input buffers */ - cancelfile++; - cancelgroup++; - mlsreset(); -#ifndef OS2 -#ifdef FTP_PROXY - if (ptflag) /* proxy... */ - longjmp(ptcancel,1); -#endif /* FTP_PROXY */ - debug(F100,"ftp cmdcancel chain to trap()...","",0); - trap(SIGINT); - /* NOTREACHED */ - debug(F100,"ftp cmdcancel return from trap()...","",0); -#else - debug(F100,"ftp cmdcancel PostCtrlCSem()...","",0); - PostCtrlCSem(); -#endif /* OS2 */ -} - -static int -#ifdef CK_ANSIC -scommand(char * s) /* Was secure_command() */ -#else -scommand(s) char * s; -#endif /* CK_ANSIC */ -{ - int length = 0, len2; - char in[FTP_BUFSIZ], out[FTP_BUFSIZ]; -#ifdef CK_SSL - if (ssl_ftp_active_flag) { - int error, rc; - length = strlen(s) + 2; - length = ckmakmsg(out,FTP_BUFSIZ,s,"\r\n",NULL,NULL); - rc = SSL_write(ssl_ftp_con,out,length); - error = SSL_get_error(ssl_ftp_con,rc); - switch (error) { - case SSL_ERROR_NONE: - return(1); - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - case SSL_ERROR_SYSCALL: -#ifdef NT - { - int gle = GetLastError(); - } -#endif /* NT */ - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - lostpeer(); - } - return(0); - } -#endif /* CK_SSL */ - - if (auth_type && ftp_cpl != FPL_CLR) { -#ifdef FTP_SRP - if (ck_srp_is_installed() && (strcmp(auth_type,"SRP") == 0)) - if ((length = srp_encode(ftp_cpl == FPL_PRV, - (CHAR *)s, - (CHAR *)out, - strlen(s))) < 0) { - fprintf(stderr, "SRP failed to encode message\n"); - return(0); - } -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 - if (ck_krb4_is_installed() && - (strcmp(auth_type, "KERBEROS_V4") == 0)) { - if (ftp_cpl == FPL_PRV) { - length = - krb_mk_priv((CHAR *)s, (CHAR *)out, - strlen(s), ftp_sched, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &myctladdr, &hisctladdr); - } else { - length = - krb_mk_safe((CHAR *)s, - (CHAR *)out, - strlen(s), -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &myctladdr, &hisctladdr); - } - if (length == -1) { - fprintf(stderr, "krb_mk_%s failed for KERBEROS_V4\n", - ftp_cpl == FPL_PRV ? "priv" : "safe"); - return(0); - } - } -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - /* Scommand (based on level) */ - if (ck_gssapi_is_installed() && (strcmp(auth_type, "GSSAPI") == 0)) { - gss_buffer_desc in_buf, out_buf; - OM_uint32 maj_stat, min_stat; - int conf_state; - in_buf.value = s; - in_buf.length = strlen(s) + 1; - maj_stat = gss_seal(&min_stat, gcontext, - (ftp_cpl==FPL_PRV), /* private */ - GSS_C_QOP_DEFAULT, - &in_buf, &conf_state, - &out_buf); - if (maj_stat != GSS_S_COMPLETE) { /* Generally need to deal */ - user_gss_error(maj_stat, min_stat, - (ftp_cpl==FPL_PRV)? - "gss_seal ENC didn't complete": - "gss_seal MIC didn't complete"); - } else if ((ftp_cpl == FPL_PRV) && !conf_state) { - fprintf(stderr, "GSSAPI didn't encrypt message"); - } else { - if (ftp_deb) - fprintf(stderr, "sealed (%s) %d bytes\n", - ftp_cpl==FPL_PRV?"ENC":"MIC", - out_buf.length); - memcpy(out, out_buf.value, - length=out_buf.length); - gss_release_buffer(&min_stat, &out_buf); - } - } -#endif /* FTP_GSSAPI */ - /* Other auth types go here ... */ - - len2 = FTP_BUFSIZ; - if ((kerror = radix_encode((CHAR *)out, (CHAR *)in, - length, &len2, RADIX_ENCODE)) - ) { - fprintf(stderr,"Couldn't base 64 encode command (%s)\n", - radix_error(kerror)); - return(0); - } - if (ftp_deb) - fprintf(stderr, "scommand(%s)\nencoding %d bytes\n", s, length); - len2 = ckmakmsg(out, - FTP_BUFSIZ, - ftp_cpl == FPL_PRV ? "ENC " : "MIC ", - in, - "\r\n", - NULL - ); - send(csocket,(SENDARG2TYPE)out,len2,0); - } else { - char out[FTP_BUFSIZ]; - int len = ckmakmsg(out,FTP_BUFSIZ,s,"\r\n",NULL,NULL); - send(csocket,(SENDARG2TYPE)out,len,0); - } - return(1); -} - -static int -mygetc() { - static char inbuf[4096]; - static int bp = 0, ep = 0; - int rc; - - if (bp == ep) { - bp = ep = 0; -#ifdef CK_SSL - if (ssl_ftp_active_flag) { - int error; - rc = SSL_read(ssl_ftp_con,inbuf,4096); - error = SSL_get_error(ssl_ftp_con,rc); - switch (error) { - case SSL_ERROR_NONE: - break; - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - return(0); - case SSL_ERROR_SYSCALL: - if (rc == 0) { /* EOF */ - break; - } else { -#ifdef NT - int gle = GetLastError(); -#endif /* NT */ - break; - } - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - break; - } - } else -#endif /* CK_SSL */ - rc = recv(csocket,(char *)inbuf,4096,0); - if (rc <= 0) - return(EOF); - ep = rc; - } - return(inbuf[bp++]); -} - -/* x l a t e c -- Translate a character */ -/* - Call with: - fc = Function code: 0 = translate, 1 = initialize. - c = Character (as int). - incs = Index of charset to translate from. - outcs = Index of charset to translate to. - - Returns: - 0: OK - -1: Error -*/ -static int -xlatec(fc,c,incs,outcs) int fc, c, incs, outcs; { -#ifdef NOCSETS - return(c); -#else - static char buf[128]; - static int cx; - int c0, c1; - - if (fc == 1) { /* Initialize */ - cx = 0; /* Catch-up buffer write index */ - xgnbp = buf; /* Catch-up buffer read pointer */ - buf[0] = NUL; /* Buffer is empty */ - return(0); - } - if (cx >= 127) { /* Catch-up buffer full */ - debug(F100,"xlatec overflow","",0); /* (shouldn't happen) */ - printf("?Translation buffer overflow\n"); - return(-1); - } - /* Add char to buffer. */ - /* The buffer won't grow unless incs is a multibyte set, e.g. UTF-8. */ - - debug(F000,"xlatec buf",ckitoa(cx),c); - buf[cx++] = c; - buf[cx] = NUL; - - while ((c0 = xgnbyte(FC_UCS2,incs,strgetc)) > -1) { - if (xpnbyte(c0,TC_UCS2,outcs,NULL) < 0) /* (NULL was xprintc) */ - return(-1); - } - /* If we're caught up, reinitialize the buffer */ - return((cx == (xgnbp - buf)) ? xlatec(1,0,0,0) : 0); -#endif /* NOCSETS */ -} - - -/* p a r s e f e a t */ - -/* Note: for convenience we align keyword values with table indices */ -/* If you need to insert a new keyword, adjust the SFT_xxx definitions */ - -static struct keytab feattab[] = { - { "$$$$", 0, 0 }, /* Dummy for sfttab[0] */ - { "AUTH", SFT_AUTH, 0 }, - { "LANG", SFT_LANG, 0 }, - { "MDTM", SFT_MDTM, 0 }, - { "MLST", SFT_MLST, 0 }, - { "PBSZ", SFT_PBSZ, 0 }, - { "PROT", SFT_PROT, 0 }, - { "REST", SFT_REST, 0 }, - { "SIZE", SFT_SIZE, 0 }, - { "TVFS", SFT_TVFS, 0 }, - { "UTF8", SFT_UTF8, 0 } -}; -static int nfeattab = (sizeof(feattab) / sizeof(struct keytab)); - -#define FACT_CSET 1 -#define FACT_CREA 2 -#define FACT_LANG 3 -#define FACT_MTYP 4 -#define FACT_MDTM 5 -#define FACT_PERM 6 -#define FACT_SIZE 7 -#define FACT_TYPE 8 -#define FACT_UNIQ 9 - -static struct keytab facttab[] = { - { "CHARSET", FACT_CSET, 0 }, - { "CREATE", FACT_CREA, 0 }, - { "LANG", FACT_LANG, 0 }, - { "MEDIA-TYPE", FACT_MTYP, 0 }, - { "MODIFY", FACT_MDTM, 0 }, - { "PERM", FACT_PERM, 0 }, - { "SIZE", FACT_SIZE, 0 }, - { "TYPE", FACT_TYPE, 0 }, - { "UNIQUE", FACT_UNIQ, 0 } -}; -static int nfacttab = (sizeof(facttab) / sizeof(struct keytab)); - -static struct keytab ftyptab[] = { - { "CDIR", FTYP_CDIR, 0 }, - { "DIR", FTYP_DIR, 0 }, - { "FILE", FTYP_FILE, 0 }, - { "PDIR", FTYP_PDIR, 0 } -}; -static int nftyptab = (sizeof(ftyptab) / sizeof(struct keytab)); - -static VOID -parsefeat(s) char * s; { /* Parse a FEATURE response */ - char kwbuf[8]; - int i, x; - if (!s) return; - if (!*s) return; - while (*s < '!') - s++; - for (i = 0; i < 4; i++) { - if (s[i] < '!') - break; - kwbuf[i] = s[i]; - } - if (s[i] && s[i] != SP) - return; - kwbuf[i] = NUL; - /* xlookup requires a full (but case independent) match */ - i = xlookup(feattab,kwbuf,nfeattab,&x); - debug(F111,"ftp parsefeat",s,i); - if (i < 0 || i > 15) - return; - - switch (i) { - case SFT_MDTM: /* Controlled by ENABLE/DISABLE */ - sfttab[i] = mdtmok; - if (mdtmok) sfttab[0]++; - break; - case SFT_MLST: /* ditto */ - sfttab[i] = mlstok; - if (mlstok) sfttab[0]++; - break; - case SFT_SIZE: /* ditto */ - sfttab[i] = sizeok; - if (sizeok) sfttab[0]++; - break; - case SFT_AUTH: /* ditto */ - sfttab[i] = ftp_aut; - if (ftp_aut) sfttab[0]++; - break; - default: /* Others */ - sfttab[0]++; - sfttab[i]++; - } -} - -static char * -parsefacts(s) char * s; { /* Parse MLS[DT] File Facts */ - char * p; - int i, j, x; - if (!s) return(NULL); - if (!*s) return(NULL); - - /* Maybe we should make a copy of s so we can poke it... */ - - while ((p = ckstrchr(s,'='))) { - *p = NUL; /* s points to fact */ - i = xlookup(facttab,s,nfacttab,&x); - debug(F111,"ftp parsefact fact",s,i); - *p = '='; - s = p+1; /* Now s points to arg */ - p = ckstrchr(s,';'); - if (!p) - p = ckstrchr(s,SP); - if (!p) { - debug(F110,"ftp parsefact end-of-val search fail",s,0); - break; - } - *p = NUL; - debug(F110,"ftp parsefact valu",s,0); - switch (i) { - case FACT_CSET: /* Ignore these for now */ - case FACT_CREA: - case FACT_LANG: - case FACT_PERM: - case FACT_MTYP: - case FACT_UNIQ: - break; - case FACT_MDTM: /* Modtime */ - makestr(&havemdtm,s); - debug(F110,"ftp parsefact mdtm",havemdtm,0); - break; - case FACT_SIZE: /* Size */ - havesize = atol(s); - debug(F101,"ftp parsefact size","",havesize); - break; - case FACT_TYPE: /* Type */ - j = xlookup(ftyptab,s,nftyptab,NULL); - debug(F111,"ftp parsefact type",s,j); - havetype = (j < 1) ? 0 : j; - break; - } - *p = ';'; - s = p+1; /* s points next fact or name */ - } - while (*s == SP) /* Skip past spaces. */ - s++; - if (!*s) /* Make sure we still have a name */ - s = NULL; - debug(F110,"ftp parsefact name",s,0); - return(s); -} - -/* g e t r e p l y -- (to an FTP command sent to server) */ - -/* vbm = 1 (verbose); 0 (quiet except for error messages); 9 (super quiet) */ - -static int -getreply(expecteof,lcs,rcs,vbm,fc) int expecteof, lcs, rcs, vbm, fc; { - /* lcs, rcs, vbm parameters as in ftpcmd() */ - register int i, c, n; - register int dig; - register char *cp; - int xlate = 0; - int count = 0; - int auth = 0; - int originalcode = 0, continuation = 0; - sig_t oldintr; - int pflag = 0; - char *pt = pasv; - char ibuf[FTP_BUFSIZ], obuf[FTP_BUFSIZ]; /* (these are pretty big...) */ - int safe = 0; - int xquiet = 0; - - auth = (fc == GRF_AUTH); - -#ifndef NOCSETS - debug(F101,"ftp getreply lcs","",lcs); - debug(F101,"ftp getreply rcs","",rcs); - if (lcs > -1 && rcs > -1 && lcs != rcs) { - xlate = 1; - initxlate(rcs,lcs); - xlatec(1,0,rcs,lcs); - } -#endif /* NOCSETS */ - debug(F101,"ftp getreply fc","",fc); - - if (quiet) - xquiet = 1; - if (vbm == 9) { - xquiet = 1; - vbm = 0; - } - if (ftp_deb) /* DEBUG */ - vbm = 1; - else if (quiet || dpyactive) /* QUIET or File Transfer Active */ - vbm = 0; - else if (vbm < 0) /* VERBOSE */ - vbm = ftp_vbm; - - ibuf[0] = '\0'; - if (reply_parse) - reply_ptr = reply_buf; - havesigint = 0; - oldintr = signal(SIGINT, cmdcancel); - for (count = 0;; count++) { - obuf[0] = '\0'; - dig = n = ftpcode = i = 0; - cp = ftp_reply_str; - while ((c = ibuf[0] ? ibuf[i++] : mygetc()) != '\n') { - if (c == IAC) { /* Handle telnet commands */ - switch (c = mygetc()) { - case WILL: - case WONT: - c = mygetc(); - obuf[0] = IAC; - obuf[1] = DONT; - obuf[2] = c; - obuf[3] = NUL; -#ifdef CK_SSL - if (ssl_ftp_active_flag) { - int error, rc; - rc = SSL_write(ssl_ftp_con,obuf,3); - error = SSL_get_error(ssl_ftp_con,rc); - switch (error) { - case SSL_ERROR_NONE: - break; - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - return(0); - case SSL_ERROR_SYSCALL: - if (rc == 0) { /* EOF */ - break; - } else { -#ifdef NT - int gle = GetLastError(); -#endif /* NT */ - break; - } - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - break; - } - } else -#endif /* CK_SSL */ - send(csocket,(SENDARG2TYPE)obuf,3,0); - break; - case DO: - case DONT: - c = mygetc(); - obuf[0] = IAC; - obuf[1] = WONT; - obuf[2] = c; - obuf[3] = NUL; -#ifdef CK_SSL - if (ssl_ftp_active_flag) { - int error, rc; - rc = SSL_write(ssl_ftp_con,obuf,3); - error = SSL_get_error(ssl_ftp_con,rc); - switch (error) { - case SSL_ERROR_NONE: - break; - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - signal(SIGINT,oldintr); - return(0); - case SSL_ERROR_SYSCALL: - if (rc == 0) { /* EOF */ - break; - } else { -#ifdef NT - int gle = GetLastError(); -#endif /* NT */ - break; - } - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - break; - } - } else -#endif /* CK_SSL */ - send(csocket,(SENDARG2TYPE)obuf,3,0); - break; - default: - break; - } - continue; - } - dig++; - if (c == EOF) { - if (expecteof) { - signal(SIGINT,oldintr); - ftpcode = 221; - debug(F101,"ftp getreply EOF","",ftpcode); - return(0); - } - lostpeer(); - if (!xquiet) { - if (ftp_deb) - printf("421 "); - printf( - "Service not available, connection closed by server\n"); - fflush(stdout); - } - signal(SIGINT,oldintr); - ftpcode = 421; - debug(F101,"ftp getreply EOF","",ftpcode); - return(4); - } - if (n == 0) { /* First digit */ - n = c; /* Save it */ - } - if (auth_type && -#ifdef CK_SSL - !ssl_ftp_active_flag && -#endif /* CK_SSL */ - !ibuf[0] && (n == '6' || continuation)) { - if (c != '\r' && dig > 4) - obuf[i++] = c; - } else { - if (auth_type && -#ifdef CK_SSL - !ssl_ftp_active_flag && -#endif /* CK_SSL */ - !ibuf[0] && dig == 1 && vbm) - printf("Unauthenticated reply received from server:\n"); - if (reply_parse) { - *reply_ptr++ = c; - *reply_ptr = NUL; - } - if ((!dpyactive || ftp_deb) && /* Don't mess up xfer display */ - ftp_cmdlin < 2) { - if ((c != '\r') && - (ftp_deb || ((vbm || (!auth && n == '5')) && - (dig > 4 || ( dig <= 4 && !isdigit(c) && ftpcode == 0 - ))))) - { -#ifdef FTP_PROXY - if (ftp_prx && (dig == 1 || (dig == 5 && vbm == 0))) - printf("%s:",ftp_host); -#endif /* FTP_PROXY */ - - if (!xquiet) { -#ifdef NOCSETS - printf("%c",c); -#else - if (xlate) { - xlatec(0,c,rcs,lcs); - } else { - printf("%c",c); - } -#endif /* NOCSETS */ - } - } - } - } - if (auth_type && -#ifdef CK_SSL - !ssl_ftp_active_flag && -#endif /* CK_SSL */ - !ibuf[0] && n != '6') - continue; - if (dig < 4 && isdigit(c)) - ftpcode = ftpcode * 10 + (c - '0'); - if (!pflag && ftpcode == 227) - pflag = 1; - if (dig > 4 && pflag == 1 && isdigit(c)) - pflag = 2; - if (pflag == 2) { - if (c != '\r' && c != ')') - *pt++ = c; - else { - *pt = '\0'; - pflag = 3; - } - } - if (dig == 4 && c == '-' && n != '6') { - if (continuation) - ftpcode = 0; - continuation++; - } - if (cp < &ftp_reply_str[FTP_BUFSIZ - 1]) { - *cp++ = c; - *cp = NUL; - } - } - if (deblog || -#ifdef COMMENT -/* - Sometimes we need to print the server reply. printlines is nonzero for any - command where the results are sent back on the control connection rather - than the data connection, e.g. STAT. In the TOPS-20 case, each file line - has ftpcode 213. But if you do this with a UNIX server, it sends "213-Start - STAT", , "213-End" or somesuch. So when printlines - is nonzero, we want the 213 lines from TOPS-20 and we DON'T want the 213 - lines from UNIX. Further experimentation needed with other servers. Of - course RFC959 is mute as to the format of the server reply. - - 'printlines' is also true for PWD and BYE. -*/ - (printlines && ((ftpcode == 0) || (servertype == SYS_TOPS20))) -#else -/* No, we can't be that clever -- it breaks other things like RPWD... */ - (printlines && - (ftpcode != 631 && ftpcode != 632 && ftpcode != 633)) -#endif /* COMMENT */ - ) { - char * q = cp; - char *r = ftp_reply_str; - *q-- = NUL; /* NUL-terminate */ - while (*q < '!' && q > r) /* Strip CR, etc */ - *q-- = NUL; - if (!ftp_deb && printlines) { /* If printing */ - if (ftpcode != 0) /* strip ftpcode if any */ - r += 4; -#ifdef NOCSETS - printf("%s\n",r); /* and print */ -#else - if (!xlate) { - printf("%s\n",r); - } else { /* Translating */ - xgnbp = r; /* Set up strgetc() */ - while ((c0 = xgnbyte(FC_UCS2,rcs,strgetc)) > -1) { - if (xpnbyte(c0,TC_UCS2,lcs,NULL) < 0) { /* (xprintc) */ - signal(SIGINT,oldintr); - return(-1); - } - } - printf("\n"); - } -#endif /* NOCSETS */ - } - } - debug(F110,"FTP RCVD ",ftp_reply_str,0); - - if (fc == GRF_FEAT) { /* Parsing FEAT command response? */ - if (count == 0 && n == '2') { - int i; /* (Re)-init server FEATure table */ - debug(F100,"ftp getreply clearing feature table","",0); - for (i = 0; i < 16; i++) - sfttab[i] = 0; - } else { - parsefeat((char *)ftp_reply_str); - } - } - if (auth_type && -#ifdef CK_SSL - !ssl_ftp_active_flag && -#endif /* CK_SSL */ - !ibuf[0] && n != '6') { - signal(SIGINT,oldintr); - return(getreply(expecteof,lcs,rcs,vbm,auth)); - } - ibuf[0] = obuf[i] = '\0'; - if (ftpcode && n == '6') - if (ftpcode != 631 && ftpcode != 632 && ftpcode != 633) { - printf("Unknown reply: %d %s\n", ftpcode, obuf); - n = '5'; - } else safe = (ftpcode == 631); - if (obuf[0] /* if there is a string to decode */ -#ifdef CK_SSL - && !ssl_ftp_active_flag /* and not SSL/TLS */ -#endif /* CK_SSL */ - ) { - if (!auth_type) { - printf("Cannot decode reply:\n%d %s\n", ftpcode, obuf); - n = '5'; - } -#ifndef CK_ENCRYPTION - else if (ftpcode == 632) { - printf("Cannot decrypt %d reply: %s\n", ftpcode, obuf); - n = '5'; - } -#endif /* CK_ENCRYPTION */ -#ifdef NOCONFIDENTIAL - else if (ftpcode == 633) { - printf("Cannot decrypt %d reply: %s\n", ftpcode, obuf); - n = '5'; - } -#endif /* NOCONFIDENTIAL */ - else { - int len = FTP_BUFSIZ; - if ((kerror = radix_encode((CHAR *)obuf, - (CHAR *)ibuf, - 0, - &len, - RADIX_DECODE)) - ) { - printf("Can't decode base 64 reply %d (%s)\n\"%s\"\n", - ftpcode, radix_error(kerror), obuf); - n = '5'; - } -#ifdef FTP_SRP - else if (strcmp(auth_type, "SRP") == 0) { - int outlen; - outlen = srp_decode(!safe, (CHAR *)ibuf, - (CHAR *) ibuf, len); - if (outlen < 0) { - printf("Warning: %d reply %s!\n", - ftpcode, safe ? "modified" : "garbled"); - n = '5'; - } else { - ckstrncpy(&ibuf[outlen], "\r\n",FTP_BUFSIZ-outlen); - if (ftp_deb) - printf("%c:", safe ? 'S' : 'P'); - continue; - } - } -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 - else if (strcmp(auth_type, "KERBEROS_V4") == 0) { - if (safe) { - kerror = krb_rd_safe((CHAR *)ibuf, len, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &hisctladdr, - &myctladdr, - &ftp_msg_data - ); - } else { - kerror = krb_rd_priv((CHAR *)ibuf, len, - ftp_sched, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &hisctladdr, - &myctladdr, - &ftp_msg_data - ); - } - if (kerror != KSUCCESS) { - printf("%d reply %s! (krb_rd_%s: %s)\n", ftpcode, - safe ? "modified" : "garbled", - safe ? "safe" : "priv", - krb_get_err_text(kerror)); - n = '5'; - } else if (ftp_msg_data.app_length >= FTP_BUFSIZ - 3) { - kerror = KFAILURE; - n = '5'; - printf("reply data too large for buffer\n"); - } else { - if (ftp_deb) - printf("%c:", safe ? 'S' : 'P'); - memcpy(ibuf,ftp_msg_data.app_data, - ftp_msg_data.app_length); - ckstrncpy(&ibuf[ftp_msg_data.app_length], "\r\n", - FTP_BUFSIZ - ftp_msg_data.app_length); - continue; - } - } -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - else if (strcmp(auth_type, "GSSAPI") == 0) { - gss_buffer_desc xmit_buf, msg_buf; - OM_uint32 maj_stat, min_stat; - int conf_state; - xmit_buf.value = ibuf; - xmit_buf.length = len; - /* decrypt/verify the message */ - conf_state = safe; - maj_stat = gss_unseal(&min_stat, gcontext, - &xmit_buf, &msg_buf, - &conf_state, NULL); - if (maj_stat != GSS_S_COMPLETE) { - user_gss_error(maj_stat, min_stat, - "failed unsealing reply"); - n = '5'; - } else { - memcpy(ibuf, msg_buf.value, msg_buf.length); - ckstrncpy(&ibuf[msg_buf.length], "\r\n", - FTP_BUFSIZ-msg_buf.length); - gss_release_buffer(&min_stat,&msg_buf); - if (ftp_deb) - printf("%c:", safe ? 'S' : 'P'); - continue; - } - } -#endif /* FTP_GSSAPI */ - /* Other auth types go here... */ - } - } else if ((!dpyactive || ftp_deb) && ftp_cmdlin < 2 && - !xquiet && (vbm || (!auth && (n == '4' || n == '5')))) { -#ifdef NOCSETS - printf("%c",c); -#else - if (xlate) { - xlatec(0,c,rcs,lcs); - } else { - printf("%c",c); - } -#endif /* NOCSETS */ - fflush (stdout); - } - if (continuation && ftpcode != originalcode) { - if (originalcode == 0) - originalcode = ftpcode; - continue; - } - *cp = '\0'; - if (n != '1') - cpend = 0; - signal(SIGINT,oldintr); - if (ftpcode == 421 || originalcode == 421) { - lostpeer(); - if (!xquiet && !ftp_deb) - printf("%s\n",reply_buf); - } - if ((cancelfile != 0) && -#ifndef ULTRIX3 - /* Ultrix 3.0 cc objects violently to this clause */ - (oldintr != cmdcancel) && -#endif /* ULTRIX3 */ - (oldintr != SIG_IGN)) { - if (oldintr) - (*oldintr)(SIGINT); - } - if (reply_parse) { - *reply_ptr = '\0'; - if ((reply_ptr = ckstrstr(reply_buf, reply_parse))) { - reply_parse = reply_ptr + strlen(reply_parse); - if ((reply_ptr = ckstrpbrk(reply_parse, " \r"))) - *reply_ptr = '\0'; - } else - reply_parse = reply_ptr; - } - while (*cp < '!' && cp > ftp_reply_str) /* Remove trailing junk */ - *cp-- = NUL; - debug(F111,"ftp getreply",ftp_reply_str,n - '0'); - return(n - '0'); - } /* for (;;) */ -} - -#ifdef BSDSELECT -static int -#ifdef CK_ANSIC -empty(fd_set * mask, int sec) -#else -empty(mask, sec) fd_set * mask; int sec; -#endif /* CK_ANSIC */ -{ - struct timeval t; - t.tv_sec = (long) sec; - t.tv_usec = 0L; - debug(F100,"ftp empty calling select...","",0); -#ifdef INTSELECT - x = select(32, (int *)mask, NULL, NULL, &t); -#else - x = select(32, mask, (fd_set *) 0, (fd_set *) 0, &t); -#endif /* INTSELECT */ - debug(F101,"ftp empty select","",x); - return(x); -} -#else /* BSDSELECT */ -#ifdef IBMSELECT -static int -empty(mask, cnt, sec) int * mask, sec; - int cnt; -{ - return(select(mask,cnt,0,0,sec*1000)); -} -#endif /* IBMSELECT */ -#endif /* BSDSELECT */ - -static sigtype -cancelsend(sig) int sig; { - havesigint++; - cancelgroup++; - cancelfile = 0; - printf(" Canceled...\n"); - secure_getc(0,1); /* Initialize net input buffers */ - debug(F100,"ftp cancelsend caught SIGINT ","",0); - fflush(stdout); -#ifndef OS2 - longjmp(sendcancel, 1); -#else - PostCtrlCSem(); -#endif /* OS2 */ -} - -static VOID -#ifdef CK_ANSIC -secure_error(char *fmt, ...) -#else -/* VARARGS1 */ -secure_error(fmt, p1, p2, p3, p4, p5) - char *fmt; int p1, p2, p3, p4, p5; -#endif /* CK_ANSIC */ -{ -#ifdef CK_ANSIC - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -#else - fprintf(stderr, fmt, p1, p2, p3, p4, p5); -#endif - fprintf(stderr, "\n"); -} - -/* - * Internal form of settype; changes current type in use with server - * without changing our notion of the type for data transfers. - * Used to change to and from ascii for listings. - */ -static VOID -changetype(newtype, show) int newtype, show; { - int rc; - char * s; - - if ((newtype == curtype) && typesent++) - return; - switch (newtype) { - case FTT_ASC: - s = "A"; - break; - case FTT_BIN: - s = "I"; - break; - case FTT_TEN: - s = "L 8"; - break; - default: - s = "I"; - break; - } - rc = ftpcmd("TYPE",s,-1,-1,show); - if (rc == REPLY_COMPLETE) - curtype = newtype; -} - -/* PUT a file. Returns -1 on error, 0 on success, 1 if file skipped */ - -static VOID -#ifdef CK_ANSIC -doftpsend(void * threadinfo) -#else -doftpsend(threadinfo) VOID * threadinfo; -#endif -{ -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "doftpsend called with threadinfo block","", 0); - } else debug(F100, "doftpsend - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - - if (initconn()) { -#ifndef NOHTTP - int y = -1; - debug(F101,"doftpsend","tcp_http_proxy",tcp_http_proxy); - - /* If the connection failed and we are using an HTTP Proxy - * and the reason for the failure was an authentication - * error, then we need to give the user to ability to - * enter a username and password, just like a browser. - * - * I tried to do all of this within the netopen() call - * but it is much too much work. - */ - while (y != 0 && tcp_http_proxy != NULL ) { - - if (tcp_http_proxy_errno == 401 || - tcp_http_proxy_errno == 407 ) { - char uid[UIDBUFLEN]; - char pwd[PWDSIZ]; - struct txtbox tb[2]; - int ok; - - tb[0].t_buf = uid; - tb[0].t_len = UIDBUFLEN; - tb[0].t_lbl = "Proxy Userid: "; - tb[0].t_dflt = NULL; - tb[0].t_echo = 1; - tb[1].t_buf = pwd; - tb[1].t_len = 256; - tb[1].t_lbl = "Proxy Passphrase: "; - tb[1].t_dflt = NULL; - tb[1].t_echo = 2; - - ok = uq_mtxt("Proxy Server Authentication Required\n", - NULL, 2, tb); - if (ok && uid[0]) { - char * proxy_user, * proxy_pwd; - - proxy_user = tcp_http_proxy_user; - proxy_pwd = tcp_http_proxy_pwd; - - tcp_http_proxy_user = uid; - tcp_http_proxy_pwd = pwd; - - y = initconn(); - - debug(F101,"doftpsend","initconn",y); - memset(pwd,0,PWDSIZ); - tcp_http_proxy_user = proxy_user; - tcp_http_proxy_pwd = proxy_pwd; - } else - break; - } else - break; - } - - if ( y != 0 ) { -#endif /* NOHTTP */ - signal(SIGINT, ftpsnd.oldintr); -#ifdef SIGPIPE - if (ftpsnd.oldintp) - signal(SIGPIPE, ftpsnd.oldintp); -#endif /* SIGPIPE */ - ftpcode = -1; - zclose(ZIFILE); - ftpsndret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; -#ifndef NOHTTP - } -#endif /* NOHTTP */ - } - ftpsndret = 0; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ -} - -static VOID -#ifdef CK_ANSIC -failftpsend(void * threadinfo) -#else -failftpsend(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "docmdfile called with threadinfo block","", 0); - } else debug(F100, "docmdfile - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - - while (cpend) { - ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0); - debug(F111,"ftp sendrequest getreply","null command",ftpsnd.reply); - } - if (data >= 0) { -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; - } -#endif /* CK_SSL */ -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = -1; - } - if (ftpsnd.oldintr) - signal(SIGINT,ftpsnd.oldintr); -#ifdef SIGPIPE - if (ftpsnd.oldintp) - signal(SIGPIPE,ftpsnd.oldintp); -#endif /* SIGPIPE */ - ftpcode = -1; -#ifndef OS2 - /* TEST ME IN K95 */ - if (havesigint) { - havesigint = 0; - debug(F100,"ftp failftpsend chain to trap()...","",0); - if (ftpsnd.oldintr != SIG_IGN) - (*ftpsnd.oldintr)(SIGINT); - /* NOTREACHED (I hope!) */ - debug(F100,"ftp failftpsend return from trap()...","",0); - } -#endif /* OS2 */ -} - -static VOID -#ifdef CK_ANSIC -failftpsend2(void * threadinfo) -#else -failftpsend2(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "docmdfile called with threadinfo block","", 0); - } else debug(F100, "docmdfile - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - - debug(F101,"ftp sendrequest canceled","",ftpsnd.bytes); - tfc += ffc; -#ifdef GFTIMER - fpfsecs = gftimer(); -#endif /* GFTIMER */ - zclose(ZIFILE); -#ifdef PIPESEND - if (sndfilter) - pipesend = 0; -#endif /* PIPESEND */ - signal(SIGINT, ftpsnd.oldintr); -#ifdef SIGPIPE - if (ftpsnd.oldintp) - signal(SIGPIPE, ftpsnd.oldintp); -#endif /* SIGPIPE */ - if (!cpend) { - ftpcode = -1; - ftpsndret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - if (data >= 0) { -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; - } -#endif /* CK_SSL */ -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = -1; - } - if (dout) { -#ifdef TCPIPLIB - socket_close(dout); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(dout, 1+1); -#endif /* USE_SHUTDOWN */ - close(dout); -#endif /* TCPIPLIB */ - } - ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0); - ftpcode = -1; - ftpsndret = -1; - -#ifndef OS2 - /* TEST ME IN K95 */ - if (havesigint) { - havesigint = 0; - debug(F100,"ftp failftpsend2 chain to trap()...","",0); - if (ftpsnd.oldintr != SIG_IGN) - (*ftpsnd.oldintr)(SIGINT); - /* NOTREACHED (I hope!) */ - debug(F100,"ftp failftpsend2 return from trap()...","",0); - } -#endif /* OS2 */ -} - -static VOID -#ifdef CK_ANSIC -doftpsend2(void * threadinfo) -#else -doftpsend2(threadinfo) VOID * threadinfo; -#endif -{ - register int c, d = 0; - int n, t, x, notafile, unique = 0; - char *buf, *bufp; - -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "doftpsend2 called with threadinfo block","", 0); - } else debug(F100, "doftpsend2 - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - - buf = ftpsndbuf; /* (not on stack) */ - - unique = strcmp(ftpsnd.cmd,"STOU") ? 0 : 1; - notafile = sndarray || pipesend; - -#ifdef FTP_RESTART - if (ftpsnd.restart && ((curtype == FTT_BIN) || (alike > 0))) { - char * p; - changetype(FTT_BIN,0); /* Change to binary */ - - /* Ask for remote file's size */ - x = ftpcmd("SIZE",ftpsnd.remote,ftpsnd.incs,ftpsnd.outcs,ftp_vbm); - - if (x == REPLY_COMPLETE) { /* Have ftpsnd.reply */ - p = &ftp_reply_str[4]; /* Parse it */ - while (isdigit(*p)) { - sendstart = sendstart * 10 + (int)(*p - '0'); - p++; - } - if (*p && *p != CR) { /* Bad number */ - debug(F110,"doftpsend2 bad size",ftp_reply_str,0); - sendstart = 0L; - } else if (sendstart > fsize) { /* Remote file bigger than local */ - debug(F110,"doftpsend2 big size",ckltoa(fsize),sendstart); - sendstart = 0L; - } - /* Local is newer */ - debug(F111,"doftpsend2 size",ftpsnd.remote,sendstart); - if (chkmodtime(ftpsnd.local,ftpsnd.remote,0) == 2) { - debug(F110,"doftpsend2 date mismatch",ftp_reply_str,0); - sendstart = 0L; /* Send the whole file */ - } - } - changetype(ftp_typ,0); /* Change back to appropriate type */ - if (sendstart > 0L) { /* Still restarting? */ - if (sendstart == fsize) { /* Same size - no need to send */ - debug(F111,"doftpsend2 /restart SKIP",fsize,sendstart); - zclose(ZIFILE); - ftpsndret = SKP_RES; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - errno = 0; /* Restart needed, seek to the spot */ - if (zfseek((long)sendstart) < 0) { - debug(F111,"doftpsend2 zfseek fails", - ftpsnd.local,sendstart); - fprintf(stderr, "FSEEK: %s: %s\n", ftpsnd.local, ck_errstr()); - sendstart = 0; - zclose(ZIFILE); - ftpsndret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } -#ifdef COMMENT - debug(F111,"doftpsend2 zfseek ok",ftpsnd.local,sendstart); - x = ftpcmd("REST",ckltoa(sendstart),-1,-1,ftp_vbm); - if (x != REPLY_CONTINUE) { - sendstart = 0; - zclose(ZIFILE); - ftpsndret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } else { - ftpsnd.cmd = "STOR"; - } -#else - sendmode = SM_RESEND; - ftpsnd.cmd = "APPE"; -#endif /* COMMENT */ - /* sendstart = 0L; */ - } - } -#endif /* FTP_RESTART */ - - if (unique && !stouarg) /* If we know STOU accepts no arg */ - ftpsnd.remote = NULL; /* don't include one. */ - - x = ftpcmd(ftpsnd.cmd, ftpsnd.remote, ftpsnd.incs, ftpsnd.outcs, ftp_vbm); - debug(F111,"doftpsend2 ftpcode",ftpsnd.cmd,ftpcode); - - if (x != REPLY_PRELIM && unique) { - /* - RFC959 says STOU does not take an argument. But every FTP server - I've encountered but one accepts the arg and constructs the unique - name from it, which is better than making up a totally random name - for the file, which is what RFC959 calls for. Especially because - there is no way for the client to find out the name chosen by the - server. So we try STOU with the argument first, which works with - most servers, and if it fails we retry it without the arg, for - the benefit of the one picky server that is not "liberal in what - it accepts" UNLESS the first STOU got a 502 code ("not implemented") - which means STOU is not accepted, period. - */ - if ((x == 5) && stouarg && (ftpcode != 502)) { - x = ftpcmd(ftpsnd.cmd,NULL,ftpsnd.incs,ftpsnd.outcs,ftp_vbm); - if (x == REPLY_PRELIM) /* If accepted */ - stouarg = 0; /* flag no STOU arg for this server */ - } - } - if (x != REPLY_PRELIM) { - signal(SIGINT, ftpsnd.oldintr); -#ifdef SIGPIPE - if (ftpsnd.oldintp) - signal(SIGPIPE, ftpsnd.oldintp); -#endif /* SIGPIPE */ - zclose(ZIFILE); -#ifdef PIPESEND - if (sndfilter) - pipesend = 0; -#endif /* PIPESEND */ - ftpsndret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - dout = dataconn(ftpsnd.lmode); /* Get data connection */ - if (dout == -1) { - failftpsend2(threadinfo); -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - /* Initialize per-file stats */ - ffc = 0L; /* Character counter */ - cps = oldcps = 0L; /* Thruput */ -#ifdef GFTIMER - rftimer(); /* reset f.p. timer */ -#endif /* GFTIMER */ - -#ifdef SIGPIPE - ftpsnd.oldintp = signal(SIGPIPE, SIG_IGN); -#endif /* SIGPIPE */ - switch (curtype) { - case FTT_BIN: /* Binary mode */ - case FTT_TEN: - errno = d = 0; - while ((n = zxin(ZIFILE,buf,FTP_BUFSIZ - 1)) > 0 && !cancelfile) { - ftpsnd.bytes += n; - ffc += n; - debug(F111,"doftpsend2 zxin",ckltoa(n),ffc); - hexdump("doftpsend2 zxin",buf,16); -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - for (bufp = buf; n > 0; n -= d, bufp += d) { - if ((d = SSL_write(ssl_ftp_data_con, bufp, n)) <= 0) - break; - spackets++; - pktnum++; - if (fdispla != XYFD_B) { - spktl = d; - ftscreen(SCR_PT,'D',spackets,NULL); - } - } - } else { -#endif /* CK_SSL */ - for (bufp = buf; n > 0; n -= d, bufp += d) { - if (((d = secure_write(dout, (CHAR *)bufp, n)) <= 0) - || iscanceled()) - break; - spackets++; - pktnum++; - if (fdispla != XYFD_B) { - spktl = d; - ftscreen(SCR_PT,'D',spackets,NULL); - } - } -#ifdef CK_SSL - } -#endif /* CK_SSL */ - if (d <= 0) - break; - } - if (n < 0) - fprintf(stderr, "local: %s: %s\n", ftpsnd.local, ck_errstr()); - if (d < 0 || (d = secure_flush(dout)) < 0) { - if (d == -1 && errno && errno != EPIPE) - perror("netout"); - ftpsnd.bytes = -1; - } - break; - - case FTT_ASC: /* Text mode */ -#ifndef NOCSETS - if (ftpsnd.xlate) { /* With translation */ - initxlate(ftpsnd.incs,ftpsnd.outcs); - while (!cancelfile) { - if ((c0 = xgnbyte(FC_UCS2,ftpsnd.incs,NULL)) < 0) break; - if ((x = xpnbyte(c0,TC_UCS2,ftpsnd.outcs,xxout)) < 0) break; - } - } else { -#endif /* NOCSETS */ - /* Text mode, no translation */ - while (((c = zminchar()) > -1) && !cancelfile) { - ffc++; - if (xxout(c) < 0) - break; - } - d = 0; -#ifndef NOCSETS - } -#endif /* NOCSETS */ - if (dout == -1 || (d = secure_flush(dout)) < 0) { - if (d == -1 && errno && errno != EPIPE) - perror("netout"); - ftpsnd.bytes = -1; - } - break; - } - tfc += ffc; /* Total file chars */ -#ifdef GFTIMER - fpfsecs = gftimer(); -#endif /* GFTIMER */ - zclose(ZIFILE); /* Close input file */ -#ifdef PIPESEND - if (sndfilter) /* Undo this (it's per file) */ - pipesend = 0; -#endif /* PIPESEND */ - -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; - } -#endif /* CK_SSL */ - -#ifdef TCPIPLIB - socket_close(dout); /* Close data connection */ -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(dout, 1+1); -#endif /* USE_SHUTDOWN */ - close(dout); -#endif /* TCPIPLIB */ - ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0); - signal(SIGINT, ftpsnd.oldintr); /* Put back interrupts */ -#ifdef SIGPIPE - if (ftpsnd.oldintp) - signal(SIGPIPE, ftpsnd.oldintp); -#endif /* SIGPIPE */ - if (ftpsnd.reply == REPLY_TRANSIENT || ftpsnd.reply == REPLY_ERROR) { - debug(F101,"doftpsend2 ftpsnd.reply","",ftpsnd.reply); - ftpsndret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } else if (cancelfile) { - debug(F101,"doftpsend2 canceled","",ftpsnd.bytes); - ftpsndret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - debug(F101,"doftpsend2 ok","",ftpsnd.bytes); - ftpsndret = 0; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ -} - -static int -sendrequest(cmd, local, remote, xlate, incs, outcs, restart) - char *cmd, *local, *remote; int xlate, incs, outcs, restart; -{ - if (!remote) remote = ""; /* Check args */ - if (!*remote) remote = local; - if (!local) local = ""; - if (!*local) return(-1); - if (!cmd) cmd = ""; - if (!*cmd) cmd = "STOR"; - - debug(F111,"ftp sendrequest restart",local,restart); - - nout = 0; /* Init output buffer count */ - ftpsnd.bytes = 0; /* File input byte count */ - dout = -1; - -#ifdef FTP_PROXY - if (proxy) { - proxtrans(cmd, local, remote, !strcmp(cmd,"STOU")); - return(0); - } -#endif /* FTP_PROXY */ - - changetype(ftp_typ,0); /* Change type for this file */ - - ftpsnd.oldintr = NULL; /* Set up interrupt handler */ - ftpsnd.oldintp = NULL; - ftpsnd.restart = restart; - ftpsnd.xlate = xlate; - ftpsnd.lmode = "wb"; - -#ifdef PIPESEND /* Use Kermit API for file i/o... */ - if (sndfilter) { - char * p = NULL, * q; -#ifndef NOSPL - int n = CKMAXPATH; - if (cmd_quoting && (p = (char *) malloc(n + 1))) { - q = p; - debug(F110,"sendrequest pipesend filter",sndfilter,0); - zzstring(sndfilter,&p,&n); - debug(F111,"sendrequest pipename",q,n); - if (n <= 0) { - printf("?Sorry, send filter + filename too long, %d max.\n", - CKMAXPATH - ); - free(q); - return(-1); - } - ckstrncpy(filnam,q,CKMAXPATH+1); - free(q); - local = filnam; - } -#endif /* NOSPL */ - } - - if (sndfilter) /* If sending thru a filter */ - pipesend = 1; /* set this for open and i/o */ -#endif /* PIPESEND */ - - if (openi(local) == 0) /* Try to open the input file */ - return(-1); - - ftpsndret = 0; - ftpsnd.incs = incs; - ftpsnd.outcs = outcs; - ftpsnd.cmd = cmd; - ftpsnd.local = local; - ftpsnd.remote = remote; - ftpsnd.oldintr = signal(SIGINT, cancelsend); - havesigint = 0; - - if (cc_execute(ckjaddr(sendcancel), doftpsend, failftpsend) < 0) - return(-1); - if (ftpsndret < 0) - return(-1); - if (cc_execute(ckjaddr(sendcancel), doftpsend2, failftpsend2) < 0) - return(-1); - - return(ftpsndret); -} - -static sigtype -cancelrecv(sig) int sig; { - havesigint++; - cancelfile = 0; - cancelgroup++; - secure_getc(0,1); /* Initialize net input buffers */ - printf(" Canceling...\n"); - debug(F100,"ftp cancelrecv caught SIGINT","",0); - fflush(stdout); - if (fp_nml) { - if (fp_nml != stdout) - fclose(fp_nml); - fp_nml = NULL; - } -#ifndef OS2 - longjmp(recvcancel, 1); -#else - PostCtrlCSem(); -#endif /* OS2 */ -} - -/* Argumentless front-end for secure_getc() */ - -static int -netgetc() { - return(secure_getc(globaldin,0)); -} - -/* Returns -1 on failure, 0 on success, 1 if file skipped */ - -/* - Sets ftpcode < 0 on failure if failure reason is not server reply code: - -1: interrupted by user. - -2: error opening or writing output file (reason in errno). - -3: failure to make data connection. - -4: network read error (reason in errno). -*/ - -struct xx_ftprecv { - int reply; - int fcs; - int rcs; - int recover; - int xlate; - int din; - int is_retr; - sig_t oldintr, oldintp; - char * cmd; - char * local; - char * remote; - char * lmode; - char * pipename; - int tcrflag; - long localsize; -}; -static struct xx_ftprecv ftprecv; - -static int ftprecvret = 0; - -static VOID -#ifdef CK_ANSIC -failftprecv(VOID * threadinfo) -#else -failftprecv(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "docmdfile called with threadinfo block","", 0); - } else debug(F100, "docmdfile - threadinfo is NULL", "", 0); -#endif /* NTSIG */ - -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - - while (cpend) { - ftprecv.reply = getreply(0,ftprecv.fcs,ftprecv.rcs,ftp_vbm,0); - } - if (data >= 0) { -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; - } -#endif /* CK_SSL */ -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = -1; - } - if (ftprecv.oldintr) - signal(SIGINT, ftprecv.oldintr); - ftpcode = -1; - ftprecvret = -1; - -#ifndef OS2 - /* TEST ME IN K95 */ - if (havesigint) { - havesigint = 0; - debug(F100,"ftp failftprecv chain to trap()...","",0); - if (ftprecv.oldintr != SIG_IGN) - (*ftprecv.oldintr)(SIGINT); - /* NOTREACHED (I hope!) */ - debug(F100,"ftp failftprecv return from trap()...","",0); - } -#endif /* OS2 */ - return; -} - -static VOID -#ifdef CK_ANSIC -doftprecv(VOID * threadinfo) -#else -doftprecv(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "docmdfile called with threadinfo block","", 0); - } else debug(F100, "docmdfile - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - -#ifndef COMMENT - if (!out2screen && !ftprecv.pipename) { - int x; - char * local; - local = ftprecv.local; - x = zchko(local); - if (x < 0) { - if ((!dpyactive || ftp_deb)) - fprintf(stderr, - "Temporary file %s: %s\n", ftprecv.local, ck_errstr()); - signal(SIGINT, ftprecv.oldintr); - ftpcode = -2; - ftprecvret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - } -#endif /* COMMENT */ - changetype((!ftprecv.is_retr) ? FTT_ASC : ftp_typ, 0); - if (initconn()) { /* Initialize the data connection */ - signal(SIGINT, ftprecv.oldintr); - ftpcode = -1; - ftprecvret = -3; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - secure_getc(0,1); /* Initialize net input buffers */ - ftprecvret = 0; - -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ -} - -static VOID -#ifdef CK_ANSIC -failftprecv2(VOID * threadinfo) -#else -failftprecv2(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "docmdfile called with threadinfo block","", 0); - } else debug(F100, "docmdfile - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - - /* Cancel using RFC959 recommended IP,SYNC sequence */ - - debug(F100,"ftp recvrequest CANCEL","",0); -#ifdef GFTIMER - fpfsecs = gftimer(); -#endif /* GFTIMER */ -#ifdef SIGPIPE - if (ftprecv.oldintp) - signal(SIGPIPE, ftprecv.oldintr); -#endif /* SIGPIPE */ - signal(SIGINT, SIG_IGN); - if (!cpend) { - ftpcode = -1; - signal(SIGINT, ftprecv.oldintr); - ftprecvret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - cancel_remote(ftprecv.din); - if (ftpcode > -1) - ftpcode = -1; - if (data >= 0) { -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; - } -#endif /* CK_SSL */ -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = -1; - } - if (!out2screen) { - int x = 0; - debug(F111,"ftp failrecv2 zclose",ftprecv.local,keep); - zclose(ZOFILE); - switch (keep) { /* which is... */ - case SET_AUTO: /* AUTO */ - if (curtype == FTT_ASC) /* Delete file if TYPE A. */ - x = 1; - break; - case SET_OFF: /* DISCARD */ - x = 1; /* Delete file, period. */ - break; - default: /* KEEP */ - break; - } - if (x) { - x = zdelet(ftprecv.local); - debug(F111,"ftp failrecv2 delete incomplete",ftprecv.local,x); - } - } - if (ftprecv.din) { -#ifdef TCPIPLIB - socket_close(ftprecv.din); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(ftprecv.din, 1+1); -#endif /* USE_SHUTDOWN */ - close(ftprecv.din); -#endif /* TCPIPLIB */ - } - signal(SIGINT, ftprecv.oldintr); - ftprecvret = -1; - - if (havesigint) { - havesigint = 0; - debug(F100,"FTP failftprecv2 chain to trap()...","",0); -#ifdef OS2 - debug(F100,"FTP failftprecv2 PostCtrlCSem()...","",0); - PostCtrlCSem(); -#else /* OS2 */ - if (ftprecv.oldintr != SIG_IGN) - (*ftprecv.oldintr)(SIGINT); - /* NOTREACHED (I hope!) */ - debug(F100,"ftp failftprecv2 return from trap()...","",0); -#endif /* OS2 */ - } -} - -static VOID -#ifdef CK_ANSIC -doftprecv2(VOID * threadinfo) -#else -doftprecv2(threadinfo) VOID * threadinfo; -#endif /* CK_ANSIC */ -{ - register int c, d; - long bytes = 0L; - int bare_lfs = 0; - int blksize = 0; - ULONG start = 0L, stop; - char * p; - static char * rcvbuf = NULL; - static int rcvbufsiz = 0; -#ifdef CK_URL - char newname[CKMAXPATH+1]; /* For file dialog */ -#endif /* CK_URL */ - extern int adl_ask; - - ftprecv.din = -1; -#ifdef NTSIG - if (threadinfo) { /* Thread local storage... */ - TlsSetValue(TlsIndex,threadinfo); - debug(F100, "docmdfile called with threadinfo block","", 0); - } else debug(F100, "docmdfile - threadinfo is NULL", "", 0); -#endif /* NTSIG */ -#ifdef CK_LOGIN -#ifdef IKSD -#ifdef NT - if (inserver) - setntcreds(); -#endif /* NT */ -#endif /* IKSD */ -#endif /* CK_LOGIN */ - - if (ftprecv.recover) { /* Initiate recovery */ - x = ftpcmd("REST",ckltoa(ftprecv.localsize),-1,-1,ftp_vbm); - debug(F111,"ftp reply","REST",x); - if (x == REPLY_CONTINUE) { - ftprecv.lmode = "ab"; - rs_len = ftprecv.localsize; - } else { - ftprecv.recover = 0; - } - } - /* IMPORTANT: No FTP commands can come between REST and RETR! */ - - debug(F111,"ftp recvrequest recover E",ftprecv.remote,ftprecv.recover); - - /* Send the command and get reply */ - debug(F110,"ftp recvrequest cmd",ftprecv.cmd,0); - debug(F110,"ftp recvrequest remote",ftprecv.remote,0); - - if (ftpcmd(ftprecv.cmd,ftprecv.remote,ftprecv.fcs,ftprecv.rcs,ftp_vbm) - != REPLY_PRELIM) { - signal(SIGINT, ftprecv.oldintr); /* Bad reply, fail. */ - ftprecvret = -1; /* ftpcode is set by ftpcmd() */ -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - ftprecv.din = dataconn("r"); /* Good reply, open data connection */ - globaldin = ftprecv.din; /* Global copy of file descriptor */ - if (ftprecv.din == -1) { /* Check for failure */ - ftpcode = -3; /* Code for no data connection */ - ftprecvret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } -#ifdef CK_URL - /* In K95 GUI put up a file box */ - if (haveurl && g_url.pth && adl_ask ) { /* Downloading from a URL */ - int x; - char * preface = -"\r\nIncoming file from FTP server...\r\n\ -Please confirm output file specification or supply an alternative:"; - - x = uq_file(preface, /* K95 GUI: Put up file box. */ - NULL, - 4, - NULL, - ftprecv.local ? ftprecv.local : ftprecv.remote, - newname, - CKMAXPATH+1 - ); - if (x > 0) { - ftprecv.local = newname; /* Substitute user's file name */ - if (x == 2) /* And append if user said to */ - ftprecv.lmode = "ab"; - } - } -#endif /* CK_URL */ - x = 1; /* Output file open OK? */ - if (ftprecv.pipename) { /* Command */ - x = zxcmd(ZOFILE,ftprecv.pipename); - debug(F111,"ftp recvrequest zxcmd",ftprecv.pipename,x); - } else if (!out2screen) { /* File */ - struct filinfo xx; - xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0; - xx.typ = 0; xx.os_specific = NUL; xx.lblopts = 0; - /* Append or New */ - xx.dsp = !strcmp(ftprecv.lmode,"ab") ? XYFZ_A : XYFZ_N; - x = zopeno(ZOFILE,ftprecv.local,NULL,&xx); - debug(F111,"ftp recvrequest zopeno",ftprecv.local,x); - } - if (x < 1) { /* Failure to open output file */ - if ((!dpyactive || ftp_deb)) - fprintf(stderr, "local(2): %s: %s\n", ftprecv.local, ck_errstr()); - ftprecvret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - blksize = FTP_BUFSIZ; /* Allocate input buffer */ - - debug(F101,"ftp recvrequest blksize","",blksize); - debug(F101,"ftp recvrequest rcvbufsiz","",rcvbufsiz); - - if (rcvbufsiz < blksize) { /* if necessary */ - if (rcvbuf) { - free(rcvbuf); - rcvbuf = NULL; - } - rcvbuf = (char *)malloc((unsigned)blksize); - if (!rcvbuf) { - debug(F100,"ftp get rcvbuf malloc failed","",0); - ftpcode = -2; -#ifdef ENOMEM - errno = ENOMEM; -#endif /* ENOMEM */ - if ((!dpyactive || ftp_deb)) - perror("malloc"); - rcvbufsiz = 0; - ftprecvret = -1; -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - debug(F101,"ftp get rcvbuf malloc ok","",blksize); - rcvbufsiz = blksize; - } - debug(F111,"ftp get rcvbufsiz",ftprecv.local,rcvbufsiz); - - ffc = 0L; /* Character counter */ - cps = oldcps = 0L; /* Thruput */ - start = gmstimer(); /* Start time (msecs) */ -#ifdef GFTIMER - rftimer(); /* Start time (float) */ -#endif /* GFTIMER */ - - debug(F111,"ftp get type",ftprecv.local,curtype); - debug(F101,"ftp recvrequest ftp_dpl","",ftp_dpl); - switch (curtype) { - case FTT_BIN: /* Binary mode */ - case FTT_TEN: /* TENEX mode */ - d = 0; - while (1) { - errno = 0; - c = secure_read(ftprecv.din, rcvbuf, rcvbufsiz); - if (cancelfile) { - failftprecv2(threadinfo); -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - if (c < 1) - break; -#ifdef printf /* (What if it isn't?) */ - if (out2screen && !ftprecv.pipename) { - int i; - for (i = 0; i < c; i++) - printf("%c",rcvbuf[i]); - } else -#endif /* printf */ - { - register int i; - i = 0; - errno = 0; - while (i < c) { - if (zmchout(rcvbuf[i++]) < 0) { - d = i; - break; - } - } - } - bytes += c; - ffc += c; - } - if (c < 0) { - debug(F111,"ftp recvrequest errno",ckitoa(c),errno); - if (c == -1 && errno != EPIPE) - if ((!dpyactive || ftp_deb)) - perror("netin"); - bytes = -1; - ftpcode = -4; - } - if (d < c) { - ftpcode = -2; - if ((!dpyactive || ftp_deb)) { - char * p; - p = ftprecv.local ? ftprecv.local : ftprecv.pipename; - if (d < 0) - fprintf(stderr, - "local(3): %s: %s\n", ftprecv.local, ck_errstr()); - else - fprintf(stderr, - "%s: short write\n", ftprecv.local); - } - } - break; - - case FTT_ASC: /* Text mode */ - debug(F101,"ftp recvrequest TYPE A xlate","",ftprecv.xlate); -#ifndef NOCSETS - if (ftprecv.xlate) { - int t; -#ifdef CK_ANSIC - int (*fn)(char); -#else - int (*fn)(); -#endif /* CK_ANSIC */ - debug(F110,"ftp recvrequest (data)","initxlate",0); - initxlate(ftprecv.rcs,ftprecv.fcs); /* (From,To) */ - if (ftprecv.pipename) { - fn = pipeout; - debug(F110,"ftp recvrequest ASCII","pipeout",0); - } else { - fn = out2screen ? scrnout : putfil; - debug(F110,"ftp recvrequest ASCII", - out2screen ? "scrnout" : "putfil",0); - } - while (1) { - /* Get byte from net */ - c0 = xgnbyte(FC_UCS2,ftprecv.rcs,netgetc); - if (cancelfile) { - failftprecv2(threadinfo); -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - if (c0 < 0) - break; - /* Second byte from net */ - c1 = xgnbyte(FC_UCS2,ftprecv.rcs,netgetc); - if (cancelfile) { - failftprecv2(threadinfo); -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - if (c1 < 0) - break; -#ifdef COMMENT - /* K95: Check whether we need this */ - if (fileorder > 0) /* Little Endian */ - bytswap(&c0,&c1); /* swap bytes*/ -#endif /* COMMENT */ - -#ifdef OS2 - if ( out2screen && /* we're translating to UCS-2 */ - !k95stdout && !inserver) /* for the real screen... */ - { - union { - USHORT ucs2; - UCHAR bytes[2]; - } output; - - output.bytes[0] = c1; - output.bytes[1] = c0; - - VscrnWrtUCS2StrAtt(VCMD, - &output.ucs2, - 1, - wherey[VCMD], - wherex[VCMD], - &colorcmd - ); - - } else -#endif /* OS2 */ - { - if ((x = xpnbyte(c0,TC_UCS2,ftprecv.fcs,fn)) < 0) break; - if ((x = xpnbyte(c1,TC_UCS2,ftprecv.fcs,fn)) < 0) break; - } - } - } else { -#endif /* NOCSETS */ - while (1) { - c = secure_getc(ftprecv.din,0); - if (cancelfile) { - failftprecv2(threadinfo); -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - if (c < 0 || c == EOF) - break; -#ifdef UNIX - /* Record format conversion for Unix */ - /* SKIP THIS FOR WINDOWS! */ - if (c == '\n') - bare_lfs++; - while (c == '\r') { - bytes++; - if ((c = secure_getc(ftprecv.din,0)) != '\n' || - ftprecv.tcrflag) { - if (cancelfile) { - failftprecv2(threadinfo); -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ - return; - } - if (c < 0 || c == EOF) - goto break2; - if (c == '\0') { - bytes++; - goto contin2; - } - } - } - if (c < 0) - break; -#endif /* UNX */ - - if (out2screen && !ftprecv.pipename) -#ifdef printf - printf("%c",(char)c); -#else - putchar((char)c); -#endif /* printf */ - else - if ((d = zmchout(c)) < 0) - break; - bytes++; - ffc++; - contin2: - ; - } - break2: - if (bare_lfs && (!dpyactive || ftp_deb)) { - printf("WARNING! %d bare linefeeds received in ASCII mode\n", - bare_lfs); - printf("File might not have transferred correctly.\n"); - } - if (ftprecv.din == -1) { - bytes = -1; - } - if (c == -2) - bytes = -1; - break; -#ifndef NOCSETS - } -#endif /* NOCSETS */ - } - if (ftprecv.pipename || !out2screen) { - zclose(ZOFILE); /* Close the file */ - debug(F111,"doftprecv2 zclose ftpcode",ftprecv.local,ftpcode); - if (ftpcode < 0) { /* If download failed */ - int x = 0; - switch (keep) { /* which is... */ - case SET_AUTO: /* AUTO */ - if (curtype == FTT_ASC) /* Delete file if TYPE A. */ - x = 1; - break; - case SET_OFF: /* DISCARD */ - x = 1; /* Delete file, period. */ - break; - default: /* KEEP */ - break; - } - if (x) { - x = zdelet(ftprecv.local); - debug(F111,"ftp get delete incomplete",ftprecv.local,x); - } - } - } - signal(SIGINT, ftprecv.oldintr); -#ifdef SIGPIPE - if (ftprecv.oldintp) - signal(SIGPIPE, ftprecv.oldintp); -#endif /* SIGPIPE */ - stop = gmstimer(); -#ifdef GFTIMER - fpfsecs = gftimer(); -#endif /* GFTIMER */ - tfc += ffc; - -#ifdef TCPIPLIB - socket_close(ftprecv.din); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(ftprecv.din, 1+1); -#endif /* USE_SHUTDOWN */ - close(ftprecv.din); -#endif /* TCPIPLIB */ - ftprecv.reply = getreply(0,ftprecv.fcs,ftprecv.rcs,ftp_vbm,0); - ftprecvret = ((ftpcode < 0 || ftprecv.reply == REPLY_TRANSIENT || - ftprecv.reply == REPLY_ERROR) ? -1 : 0); -#ifdef NTSIG - ckThreadEnd(threadinfo); -#endif /* NTSIG */ -} - -static int -recvrequest(cmd, local, remote, lmode, printnames, recover, pipename, - xlate, fcs, rcs) - char *cmd, *local, *remote, *lmode, *pipename; - int printnames, recover, xlate, fcs, rcs; -{ -#ifdef NT - struct _stat stbuf; -#else /* NT */ - struct stat stbuf; -#endif /* NT */ - -#ifdef DEBUG - if (deblog) { - debug(F111,"ftp recvrequest cmd",cmd,recover); - debug(F110,"ftp recvrequest local ",local,0); - debug(F111,"ftp recvrequest remote",remote,ftp_typ); - debug(F110,"ftp recvrequest pipename ",pipename,0); - debug(F101,"ftp recvrequest xlate","",xlate); - debug(F101,"ftp recvrequest fcs","",fcs); - debug(F101,"ftp recvrequest rcs","",rcs); - } -#endif /* DEBUG */ - - ftprecv.localsize = 0L; - - if (remfile) { /* See remcfm(), remtxt() */ - if (rempipe) { - pipename = remdest; - } else { - local = remdest; - if (remappd) lmode = "ab"; - } - } - out2screen = 0; - if (!cmd) cmd = ""; /* Core dump prevention */ - if (!remote) remote = ""; - if (!lmode) lmode = ""; - - if (pipename) { /* No recovery for pipes. */ - recover = 0; - if (!local) - local = pipename; - } else { - if (!local) /* Output to screen? */ - local = "-"; - out2screen = !strcmp(local,"-"); - } - debug(F101,"ftp recvrequest out2screen","",out2screen); - -#ifdef OS2 - if ( ftp_xla && out2screen && !k95stdout && !inserver ) - fcs = FC_UCS2; -#endif /* OS2 */ - - if (out2screen) /* No recovery to screen */ - recover = 0; - if (!ftp_typ) /* No recovery in text mode */ - recover = 0; - ftprecv.is_retr = (strcmp(cmd, "RETR") == 0); - - if (!ftprecv.is_retr) /* No recovery except for RETRieve */ - recover = 0; - -#ifdef COMMENT - if (!out2screen && !pipename && ftprecv.is_retr) { /* To real file */ - if (recursive && ckstrchr(local,'/')) { - - } - } -#endif /* COMMENT */ - - ftprecv.localsize = 0L; /* Local file size */ - rs_len = 0L; /* Recovery point */ - - debug(F101,"ftp recvrequest recover","",recover); - if (recover) { /* Recovering... */ - if (stat(local, &stbuf) < 0) { /* Can't stat local file */ - debug(F101,"ftp recvrequest recover stat failed","",errno); - recover = 0; /* So cancel recovery */ - } else { /* Have local file info */ - ftprecv.localsize = stbuf.st_size; /* Get size */ - /* Remote file smaller than local */ - if (fsize < ftprecv.localsize) { - debug(F101,"ftp recvrequest recover remote smaller","",fsize); - recover = 0; /* Recovery can't work */ - } else if (fsize == ftprecv.localsize) { /* Sizes are equal */ - debug(F111,"ftp recvrequest recover equal size", - remote,ftprecv.localsize); - return(1); - } -#ifdef COMMENT -/* - The problem here is that the original partial file never got its date - set, either because FTP DATES was OFF, or because the partial file was - downloaded by some other program that doesn't set local file dates, or - because Kermit only sets the file's date when the download was complete - and successful. In all these cases, the local file has a later time - than the remote. -*/ - if (recover) { /* Remote is bigger */ - x = chkmodtime(local,remote,0); /* Check file dates */ - debug(F111,"ftp recvrequest chkmodtime",remote,x); - if (x != 1) /* Dates must be equal! */ - recover = 0; /* If not, get whole file */ - } -#endif /* COMMENT */ - } - debug(F111,"ftp recvrequest recover",remote,recover); - } - -#ifdef FTP_PROXY - if (proxy && ftprecv.is_retr) - return(proxtrans(cmd, local ? local : remote, remote)); -#endif /* FTP_PROXY */ - - ftprecv.tcrflag = (feol != CR) && ftprecv.is_retr; - - ftprecv.reply = 0; - ftprecv.fcs = fcs; - ftprecv.rcs = rcs; - ftprecv.recover = recover; - ftprecv.xlate = xlate; - ftprecv.cmd = cmd; - ftprecv.local = local; - ftprecv.remote = remote; - ftprecv.lmode = lmode; - ftprecv.pipename = pipename; - ftprecv.oldintp = NULL; - ftpcode = 0; - - havesigint = 0; - ftprecv.oldintr = signal(SIGINT, cancelrecv); - if (cc_execute(ckjaddr(recvcancel), doftprecv, failftprecv) < 0) - return -1; - if (ftprecvret < 0) - return -1; - - if (cc_execute(ckjaddr(recvcancel), doftprecv2, failftprecv2) < 0) - return -1; - return ftprecvret; -} - -/* - * Need to start a listen on the data channel before we send the command, - * otherwise the server's connect may fail. - */ -static int -initconn() { - register char *p, *a; - int result, tmpno = 0; - int on = 1; - GSOCKNAME_T len; - -#ifndef NO_PASSIVE_MODE - int a1,a2,a3,a4,p1,p2; - - if (passivemode) { - data = socket(AF_INET, SOCK_STREAM, 0); - globaldin = data; - if (data < 0) { - perror("ftp: socket"); - return(-1); - } - if (ftpcmd("PASV",NULL,0,0,ftp_vbm) != REPLY_COMPLETE) { - printf("Passive mode refused\n"); - passivemode = 0; - return(initconn()); - } -/* - Now we have a string of comma-separated one-byte unsigned integer values, - The first four are the an IP address. The fifth is the MSB of the port - number, the sixth is the LSB. From that we can make a sockaddr_in. -*/ - if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",&a1,&a2,&a3,&a4,&p1,&p2) != 6) { - printf("Passive mode address scan failure\n"); - return(-1); - }; -#ifndef NOHTTP - if (tcp_http_proxy) { -#ifdef OS2 - char * agent = "Kermit 95"; /* Default user agent */ -#else - char * agent = "C-Kermit"; -#endif /* OS2 */ - register struct hostent *hp = 0; - struct servent *destsp; - char host[512], *p, *q; -#ifdef IP_TOS -#ifdef IPTOS_THROUGHPUT - int tos; -#endif /* IPTOS_THROUGHPUT */ -#endif /* IP_TOS */ - int s; -#ifdef DEBUG - extern int debtim; - int xdebtim; - xdebtim = debtim; - debtim = 1; -#endif /* DEBUG */ - - ckmakxmsg(proxyhost,HTTPCPYL,ckuitoa(a1),".",ckuitoa(a2), - ".",ckuitoa(a3),".",ckuitoa(a4),":",ckuitoa((p1<<8)|p2), - NULL,NULL,NULL - ); - memset((char *)&hisctladdr, 0, sizeof (hisctladdr)); - for (p = tcp_http_proxy, q=host; *p != '\0' && *p != ':'; p++, q++) - *q = *p; - *q = '\0'; - - hisctladdr.sin_addr.s_addr = inet_addr(host); - if (hisctladdr.sin_addr.s_addr != -1) { - debug(F110,"initconn A",host,0); - hisctladdr.sin_family = AF_INET; - } else { - debug(F110,"initconn B",host,0); - hp = gethostbyname(host); -#ifdef HADDRLIST - hp = ck_copyhostent(hp); /* make safe copy that won't change */ -#endif /* HADDRLIST */ - if (hp == NULL) { - fprintf(stderr, "ftp: %s: Unknown host\n", host); - ftpcode = -1; -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - return(0); - } - hisctladdr.sin_family = hp->h_addrtype; -#ifdef HADDRLIST - memcpy((char *)&hisctladdr.sin_addr, hp->h_addr_list[0], - sizeof(hisctladdr.sin_addr)); -#else /* HADDRLIST */ - memcpy((char *)&hisctladdr.sin_addr, hp->h_addr, - sizeof(hisctladdr.sin_addr)); -#endif /* HADDRLIST */ - } - data = socket(hisctladdr.sin_family, SOCK_STREAM, 0); - debug(F101,"initconn socket","",data); - if (data < 0) { - perror("ftp: socket"); - ftpcode = -1; -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - return(0); - } - if (*p == ':') - p++; - else - p = "http"; - - destsp = getservbyname(p,"tcp"); - if (destsp) - hisctladdr.sin_port = destsp->s_port; - else if (p) - hisctladdr.sin_port = htons(atoi(p)); - else - hisctladdr.sin_port = htons(80); - errno = 0; -#ifdef HADDRLIST - debug(F100,"initconn HADDRLIST","",0); - while -#else - debug(F100,"initconn no HADDRLIST","",0); - if -#endif /* HADDRLIST */ - (connect(data, (struct sockaddr *)&hisctladdr, - sizeof (hisctladdr)) < 0) { - debug(F101,"initconn connect failed","",errno); -#ifdef HADDRLIST - if (hp && hp->h_addr_list[1]) { - int oerrno = errno; - - fprintf(stderr, - "ftp: connect to address %s: ", - inet_ntoa(hisctladdr.sin_addr) - ); - errno = oerrno; - perror((char *)0); - hp->h_addr_list++; - memcpy((char *)&hisctladdr.sin_addr, - hp->h_addr_list[0], - sizeof(hisctladdr.sin_addr)); - fprintf(stdout, "Trying %s...\n", - inet_ntoa(hisctladdr.sin_addr)); -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ - close(data); -#endif /* TCPIPLIB */ - data = socket(hisctladdr.sin_family, SOCK_STREAM, 0); - if (data < 0) { - perror("ftp: socket"); - ftpcode = -1; -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - return(0); - } - continue; - } -#endif /* HADDRLIST */ - perror("ftp: connect"); - ftpcode = -1; - goto bad; - } - if (http_connect(data, - tcp_http_proxy_agent ? - tcp_http_proxy_agent : - agent, - NULL, - tcp_http_proxy_user, - tcp_http_proxy_pwd, - 0, - proxyhost - ) < 0) { -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ - close(data); -#endif /* TCPIPLIB */ - perror("ftp: connect"); - ftpcode = -1; - goto bad; - } - } else -#endif /* NOHTTP */ - { - data_addr.sin_family = AF_INET; - data_addr.sin_addr.s_addr = htonl((a1<<24)|(a2<<16)|(a3<<8)|a4); - data_addr.sin_port = htons((p1<<8)|p2); - - if (connect(data, - (struct sockaddr *)&data_addr, - sizeof(data_addr)) < 0 - ) { - perror("ftp: connect"); - return(-1); - } - } - debug(F100,"initconn connect ok","",0); -#ifdef IP_TOS -#ifdef IPTOS_THROUGHPUT - on = IPTOS_THROUGHPUT; - if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); -#endif /* IPTOS_THROUGHPUT */ -#endif /* IP_TOS */ - memcpy(&hisdataaddr,&data_addr,sizeof(struct sockaddr_in)); - return(0); - } -#endif /* NO_PASSIVE_MODE */ - - noport: - memcpy(&data_addr,&myctladdr,sizeof(struct sockaddr_in)); - if (sendport) - data_addr.sin_port = 0; /* let system pick one */ - if (data != -1) { -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - } - data = socket(AF_INET, SOCK_STREAM, 0); - globaldin = data; - if (data < 0) { - perror("ftp: socket"); - if (tmpno) - sendport = 1; - return(-1); - } - if (!sendport) { - if (setsockopt(data, - SOL_SOCKET, - SO_REUSEADDR, - (char *)&on, - sizeof (on) - ) < 0 - ) { - perror("ftp: setsockopt (reuse address)"); - goto bad; - } - } - if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) { - perror("ftp: bind"); - goto bad; - } - len = sizeof (data_addr); - if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) { - perror("ftp: getsockname"); - goto bad; - } - if (listen(data, 1) < 0) { - perror("ftp: listen"); - goto bad; - } - if (sendport) { - a = (char *)&data_addr.sin_addr; - p = (char *)&data_addr.sin_port; - ckmakxmsg(ftpcmdbuf,FTP_BUFSIZ,"PORT ", - UC(a[0]),",",UC(a[1]),",", UC(a[2]),",", UC(a[3]),",", - UC(p[0]),",", UC(p[1])); - result = ftpcmd(ftpcmdbuf,NULL,0,0,ftp_vbm); - if (result == REPLY_ERROR && sendport) { - sendport = 0; - tmpno = 1; - goto noport; - } - return(result != REPLY_COMPLETE); - } - if (tmpno) - sendport = 1; -#ifdef IP_TOS -#ifdef IPTOS_THROUGHPUT - on = IPTOS_THROUGHPUT; - if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); -#endif -#endif - return(0); - bad: -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - if (tmpno) - sendport = 1; - return(-1); -} - -#ifdef CK_SSL -static int -ssl_dataconn() { - if (ssl_ftp_data_con!=NULL) { /* Do SSL */ - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_con=NULL; - } - ssl_ftp_data_con=(SSL *)SSL_new(ssl_ftp_ctx); - - SSL_set_fd(ssl_ftp_data_con,data); - SSL_set_verify(ssl_ftp_data_con,ssl_verify_flag,NULL); - - SSL_copy_session_id(ssl_ftp_data_con,ssl_ftp_con); - - if (ssl_debug_flag) { - fprintf(stderr,"=>START SSL connect on DATA\n"); - fflush(stderr); - } - if (SSL_connect(ssl_ftp_data_con) <= 0) { - static char errbuf[1024]; - ckmakmsg(errbuf,1024,"ftp: SSL_connect DATA error: ", - ERR_error_string(ERR_get_error(),NULL),NULL,NULL); - fprintf(stderr,"%s\n", errbuf); - fflush(stderr); -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - return(-1); - } else { - ssl_ftp_data_active_flag=1; - - if (!ssl_certsok_flag && !tls_is_krb5(2)) { - char *subject = ssl_get_subject_name(ssl_ftp_data_con); - - if (!subject) { - if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { - debug(F110,"dataconn","[SSL _- FAILED]",0); - - ssl_ftp_data_active_flag = 0; -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - return(-1); - } else { - if (!out2screen && displa && fdispla) { - ftscreen(SCR_TC,0,0L,"Display canceled"); - /* fdispla = XYFD_B; */ - } - - if (uq_ok( - "Warning: Server didn't provide a certificate on data connection\n", - "Continue with file transfer? (Y/N)", - 3,NULL,0) <= 0) { - debug(F110, "dataconn","[SSL - FAILED]",0); - ssl_ftp_data_active_flag = 0; -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - return(-1); - } - } - } else { - if (!out2screen && displa && fdispla == XYFD_C) { - ftscreen(SCR_TC,0,0L,"Display canceled"); - /* fdispla = XYFD_B; */ - } - - if (ssl_check_server_name(ssl_ftp_data_con,ftp_user_host)) { - debug(F110,"dataconn","[SSL - FAILED]",0); - ssl_ftp_data_active_flag = 0; -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - return(-1); - } - } - } - debug(F110,"dataconn","[SSL - OK]",0); -#ifdef COMMENT - /* This messes up the full screen file transfer display */ - ssl_display_connect_details(ssl_ftp_con,0,ssl_verbose_flag); -#endif /* COMMENT */ - } - if (ssl_debug_flag) { - fprintf(stderr,"=>DONE SSL connect on DATA\n"); - fflush(stderr); - } - return(data); -} -#endif /* CK_SSL */ - -static int -dataconn(lmode) char *lmode; { - int s; -#ifdef IP_TOS - int tos; -#endif /* IP_TOS */ -#ifdef UCX50 - static u_int fromlen; -#else - static SOCKOPT_T fromlen; -#endif /* UCX50 */ - - fromlen = sizeof(hisdataaddr); - -#ifndef NO_PASSIVE_MODE - if (passivemode) { -#ifdef CK_SSL - ssl_ftp_data_active_flag=0; - if (ssl_ftp_active_flag && - (ssl_ftp_proxy || ftp_dpl == FPL_PRV)) - return(ssl_dataconn()); -#endif /* CK_SSL */ - return(data); - } -#endif /* NO_PASSIVE_MODE */ - - s = accept(data, (struct sockaddr *) &hisdataaddr, &fromlen); - if (s < 0) { - perror("ftp: accept"); -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - return(-1); - } -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = s; - globaldin = data; -#ifdef IP_TOS -#ifdef IPTOS_THROUGHPUT - tos = IPTOS_THROUGHPUT; - if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); -#endif /* IPTOS_THROUGHPUT */ -#endif /* IP_TOS */ - -#ifdef CK_SSL - ssl_ftp_data_active_flag=0; - if (ssl_ftp_active_flag && - (ssl_ftp_proxy || ftp_dpl == FPL_PRV)) - return(ssl_dataconn()); -#endif /* CK_SSL */ - return(data); -} - -#ifdef FTP_PROXY -static sigtype -pscancel(sig) int sig; { - cancelfile++; -} - -static VOID -pswitch(flag) int flag; { - extern int proxy; - sig_t oldintr; - static struct comvars { - int connect; - char name[MAXHOSTNAMELEN]; - struct sockaddr_in mctl; - struct sockaddr_in hctl; - FILE *in; - FILE *out; - int tpe; - int curtpe; - int cpnd; - int sunqe; - int runqe; - int mcse; - int ntflg; - char nti[17]; - char nto[17]; - int mapflg; - char mi[CKMAXPATH]; - char mo[CKMAXPATH]; - char *authtype; - int clvl; - int dlvl; -#ifdef FTP_KRB4 - des_cblock session; - des_key_schedule ftp_sched; -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - gss_ctx_id_t gcontext; -#endif /* GSSAPI */ - } proxstruct, tmpstruct; - struct comvars *ip, *op; - - cancelfile = 0; - oldintr = signal(SIGINT, pscancel); - if (flag) { - if (proxy) - return; - ip = &tmpstruct; - op = &proxstruct; - proxy++; - } else { - if (!proxy) - return; - ip = &proxstruct; - op = &tmpstruct; - proxy = 0; - } - ip->connect = connected; - connected = op->connect; - if (ftp_host) { - strncpy(ip->name, ftp_host, MAXHOSTNAMELEN - 1); - ip->name[MAXHOSTNAMELEN - 1] = '\0'; - ip->name[strlen(ip->name)] = '\0'; - } else - ip->name[0] = 0; - ftp_host = op->name; - ip->hctl = hisctladdr; - hisctladdr = op->hctl; - ip->mctl = myctladdr; - myctladdr = op->mctl; - ip->in = csocket; - csocket = op->in; - ip->out = csocket; - csocket = op->out; - ip->tpe = ftp_typ; - ftp_typ = op->tpe; - ip->curtpe = curtype; - curtype = op->curtpe; - ip->cpnd = cpend; - cpend = op->cpnd; - ip->sunqe = ftp_usn; - ftp_usn = op->sunqe; - ip->mcse = mcase; - mcase = op->mcse; - ip->ntflg = ntflag; - ntflag = op->ntflg; - strncpy(ip->nti, ntin, 16); - (ip->nti)[strlen(ip->nti)] = '\0'; - strcpy(ntin, op->nti); - strncpy(ip->nto, ntout, 16); - (ip->nto)[strlen(ip->nto)] = '\0'; - strcpy(ntout, op->nto); - ip->mapflg = mapflag; - mapflag = op->mapflg; - strncpy(ip->mi, mapin, CKMAXPATH - 1); - (ip->mi)[strlen(ip->mi)] = '\0'; - strcpy(mapin, op->mi); - strncpy(ip->mo, mapout, CKMAXPATH - 1); - (ip->mo)[strlen(ip->mo)] = '\0'; - strcpy(mapout, op->mo); - ip->authtype = auth_type; - auth_type = op->authtype; - ip->clvl = ftp_cpl; - ftp_cpl = op->clvl; - ip->dlvl = ftp_dpl; - ftp_dpl = op->dlvl; - if (!ftp_cpl) - ftp_cpl = FPL_CLR; - if (!ftp_dpl) - ftp_dpl = FPL_CLR; -#ifdef FTP_KRB4 - memcpy(ip->session, ftp_cred.session, sizeof(ftp_cred.session)); - memcpy(ftp_cred.session, op->session, sizeof(ftp_cred.session)); - memcpy(ip->schedule, ftp_sched, sizeof(ftp_sched)); - memcpy(ftp_sched, op->schedule, sizeof(ftp_sched)); -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - ip->gcontext = gcontext; - gcontext = op->gcontext; -#endif /* GSSAPI */ - signal(SIGINT, oldintr); - if (cancelfile) { - cancelfile = 0; - debug(F101,"pswitch cancelfile B","",cancelfile); - (*oldintr)(SIGINT); - } -} - -static sigtype -cancelpt(sig) int sig; { - printf("\n"); - fflush(stdout); - ptabflg++; - cancelfile = 0; -#ifndef OS2 - longjmp(ptcancel, 1); -#else - PostCtrlCSem(); -#endif /* OS2 */ -} - -void -proxtrans(cmd, local, remote, unique) char *cmd, *local, *remote; int unique; { - sig_t oldintr; - int secndflag = 0, prox_type, nfnd; - char *cmd2; -#ifdef BSDSELECT - fd_set mask; -#endif /* BSDSELECT */ - sigtype cancelpt(); - - if (strcmp(cmd, "RETR")) - cmd2 = "RETR"; - else - cmd2 = unique ? "STOU" : "STOR"; - if ((prox_type = type) == 0) { - if (servertype == SYS_UNIX && unix_proxy) - prox_type = FTT_BIN; - else - prox_type = FTT_ASC; - } - if (curtype != prox_type) - changetype(prox_type, 1); - if (ftpcmd("PASV",NULL,0,0,ftp_vbm) != REPLY_COMPLETE) { - printf("Proxy server does not support third party transfers.\n"); - return; - } - pswitch(0); - if (!connected) { - printf("No primary connection\n"); - pswitch(1); - ftpcode = -1; - return; - } - if (curtype != prox_type) - changetype(prox_type, 1); - - if (ftpcmd("PORT",pasv,-1,-1,ftp_vbm) != REPLY_COMPLETE) { - pswitch(1); - return; - } - - /* Replace with calls to cc_execute() */ - if (setjmp(ptcancel)) - goto cancel; - oldintr = signal(SIGINT, cancelpt); - if (ftpcmd(cmd,remote,-1,-1,ftp_vbm) != PRELIM) { - signal(SIGINT, oldintr); - pswitch(1); - return; - } - sleep(2000); - pswitch(1); - secndflag++; - if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM) - goto cancel; - ptflag++; - getreply(0,-1,-1,ftp_vbm,0); - pswitch(0); - getreply(0,-1,-1,ftp_vbm,0); - signal(SIGINT, oldintr); - pswitch(1); - ptflag = 0; - return; - - cancel: - signal(SIGINT, SIG_IGN); - ptflag = 0; - if (strcmp(cmd, "RETR") && !proxy) - pswitch(1); - else if (!strcmp(cmd, "RETR") && proxy) - pswitch(0); - if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */ - if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM) { - pswitch(0); - if (cpend) - cancel_remote(0); - } - pswitch(1); - if (ptabflg) - ftpcode = -1; - signal(SIGINT, oldintr); - return; - } - if (cpend) - cancel_remote(0); - pswitch(!proxy); - if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */ - if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM) { - pswitch(0); - if (cpend) - cancel_remote(0); - pswitch(1); - if (ptabflg) - ftpcode = -1; - signal(SIGINT, oldintr); - return; - } - } - if (cpend) - cancel_remote(0); - pswitch(!proxy); - if (cpend) { -#ifdef BSDSELECT - FD_ZERO(&mask); - FD_SET(csocket, &mask); - if ((nfnd = empty(&mask, 10)) <= 0) { - if (nfnd < 0) { - perror("cancel"); - } - if (ptabflg) - ftpcode = -1; - lostpeer(); - } -#else /* BSDSELECT */ -#ifdef IBMSELECT - if ((nfnd = empty(&csocket, 1, 10)) <= 0) { - if (nfnd < 0) { - perror("cancel"); - } - if (ptabflg) - ftpcode = -1; - lostpeer(); - } -#endif /* IBMSELECT */ -#endif /* BSDSELECT */ - getreply(0,-1,-1,ftp_vbm,0); - getreply(0,-1,-1,ftp_vbm,0); - } - if (proxy) - pswitch(0); - pswitch(1); - if (ptabflg) - ftpcode = -1; - signal(SIGINT, oldintr); -} -#endif /* FTP_PROXY */ - -#ifdef FTP_SECURITY -#ifdef FTP_GSSAPI - -struct { - CONST gss_OID_desc * CONST * mech_type; - char *service_name; -} gss_trials[] = { - { &gss_mech_krb5, "ftp" }, - { &gss_mech_krb5, "host" }, -}; - -int n_gss_trials = sizeof(gss_trials)/sizeof(gss_trials[0]); -#endif /* FTP_GSSAPI */ - -static int -ftp_auth() { - extern int setsafe(); - int j = 0, n; -#ifdef FTP_KRB4 - char *service, inst[INST_SZ]; - ULONG cksum; - ULONG checksum = (ULONG) getpid(); - CHAR out_buf[FTP_BUFSIZ]; - int i; -#else /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - CHAR out_buf[FTP_BUFSIZ]; - int i; -#endif /* FTP_GSSAPI */ -#endif /* FTP_KRB4 */ - - if (ssl_ftp_proxy) /* Do not allow AUTH over SSL proxy */ - return(0); - - if (auth_type) - return(1); /* auth already succeeded */ - - /* Try each auth type as specified by the end user */ - for (j = 0; j < 8 && ftp_auth_type[j] != 0; j++) { -#ifdef FTP_GSSAPI - if (ftp_auth_type[j] == FTA_GK5 && ck_gssapi_is_installed()) { - n = ftpcmd("AUTH GSSAPI",NULL,0,0,ftp_vbm); - if (n == REPLY_CONTINUE) { - OM_uint32 maj_stat, min_stat; - gss_name_t target_name; - gss_buffer_desc send_tok, recv_tok, *token_ptr; - char stbuf[FTP_BUFSIZ]; - int comcode, trial; - struct gss_channel_bindings_struct chan; - char * realm = NULL; - char tgt[256]; - - chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */ - chan.initiator_address.length = 4; - chan.initiator_address.value = &myctladdr.sin_addr.s_addr; - chan.acceptor_addrtype = GSS_C_AF_INET; /* OM_uint32 */ - chan.acceptor_address.length = 4; - chan.acceptor_address.value = &hisctladdr.sin_addr.s_addr; - chan.application_data.length = 0; - chan.application_data.value = 0; - - if (!quiet) - printf("GSSAPI accepted as authentication type\n"); - - realm = ck_krb5_realmofhost(ftp_user_host); - if (realm) { - ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm); - debug(F110,"ftp_auth(GSSAPI) TGT",tgt,0); - if ( krb5_autoget && - !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) || - (ck_krb5_is_tgt_valid() > 0)) ) - ck_krb5_autoget_TGT(realm); - } - - /* Blob from gss-client */ - for (trial = 0; trial < n_gss_trials; trial++) { - /* ftp@hostname first, the host@hostname */ - /* the V5 GSSAPI binding canonicalizes this for us... */ - ckmakmsg(stbuf,FTP_BUFSIZ, - gss_trials[trial].service_name, - "@", - ftp_user_host, - NULL - ); - if (ftp_deb) - fprintf(stderr, - "Authenticating to <%s>...\n", stbuf); - send_tok.value = stbuf; - send_tok.length = strlen(stbuf); - maj_stat = gss_import_name(&min_stat, &send_tok, - gss_nt_service_name, - &target_name - ); - if (maj_stat != GSS_S_COMPLETE) { - user_gss_error(maj_stat, min_stat, "parsing name"); - secure_error("name parsed <%s>\n", stbuf); - continue; - } - token_ptr = GSS_C_NO_BUFFER; - gcontext = GSS_C_NO_CONTEXT; /* structure copy */ - - do { - if (ftp_deb) - fprintf(stderr, "calling gss_init_sec_context\n"); - maj_stat = - gss_init_sec_context(&min_stat, - GSS_C_NO_CREDENTIAL, - &gcontext, - target_name, - (gss_OID) * - gss_trials[trial].mech_type, - GSS_C_MUTUAL_FLAG | - GSS_C_REPLAY_FLAG | - (ftp_cfw ? - GSS_C_DELEG_FLAG : 0), - 0, - /* channel bindings */ - (krb5_d_no_addresses ? - GSS_C_NO_CHANNEL_BINDINGS : - &chan), - token_ptr, - NULL, /* ignore mech type */ - &send_tok, - NULL, /* ignore ret_flags */ - NULL - ); /* ignore time_rec */ - - if (maj_stat != GSS_S_COMPLETE && - maj_stat != GSS_S_CONTINUE_NEEDED) { - if (trial == n_gss_trials-1) - user_gss_error(maj_stat, - min_stat, - "initializing context" - ); - gss_release_name(&min_stat, &target_name); - /* maybe we missed on the service name */ - goto outer_loop; - } - if (send_tok.length != 0) { - int len; - reply_parse = "ADAT="; /* for ftpcmd() later */ - len = FTP_BUFSIZ; - kerror = - radix_encode(send_tok.value, - out_buf, - send_tok.length, - &len, - RADIX_ENCODE - ); - if (kerror) { - fprintf(stderr, - "Base 64 encoding failed: %s\n", - radix_error(kerror) - ); - goto gss_complete_loop; - } - comcode = ftpcmd("ADAT",out_buf,-1,-1,0); - if (comcode != REPLY_COMPLETE - && comcode != REPLY_CONTINUE /* (335) */ - ) { - if (trial == n_gss_trials-1) { - fprintf(stderr, "GSSAPI ADAT failed\n"); - /* force out of loop */ - maj_stat = GSS_S_FAILURE; - } - /* - Backoff to the v1 gssapi is still possible. - Send a new AUTH command. If that fails, - terminate the loop. - */ - if (ftpcmd("AUTH GSSAPI",NULL,0,0,ftp_vbm) - != REPLY_CONTINUE) { - fprintf(stderr, - "GSSAPI ADAT failed, AUTH restart failed\n"); - /* force out of loop */ - maj_stat = GSS_S_FAILURE; - } - goto outer_loop; - } - if (!reply_parse) { - fprintf(stderr, - "No authentication data received from server\n"); - if (maj_stat == GSS_S_COMPLETE) { - fprintf(stderr, - "...but no more was needed\n"); - goto gss_complete_loop; - } else { - user_gss_error(maj_stat, - min_stat, - "no reply, huh?" - ); - goto gss_complete_loop; - } - } - len = FTP_BUFSIZ; - kerror = radix_encode(reply_parse,out_buf,i,&len, - RADIX_DECODE); - if (kerror) { - fprintf(stderr, - "Base 64 decoding failed: %s\n", - radix_error(kerror)); - goto gss_complete_loop; - } - - /* everything worked */ - token_ptr = &recv_tok; - recv_tok.value = out_buf; - recv_tok.length = len; - continue; - - /* get out of loop clean */ - gss_complete_loop: - trial = n_gss_trials-1; - gss_release_buffer(&min_stat, &send_tok); - gss_release_name(&min_stat, &target_name); - goto outer_loop; - } - } while (maj_stat == GSS_S_CONTINUE_NEEDED); - - outer_loop: - if (maj_stat == GSS_S_COMPLETE) - break; - } - if (maj_stat == GSS_S_COMPLETE) { - printf("GSSAPI authentication succeeded\n"); - reply_parse = NULL; - auth_type = "GSSAPI"; - return(1); - } else { - fprintf(stderr, "GSSAPI authentication failed\n"); - reply_parse = NULL; - } - } else { - if (ftp_deb) - fprintf(stderr, "GSSAPI rejected as an authentication type\n"); - if (ftpcode == 500 || ftpcode == 502) - return(0); - } - } -#endif /* FTP_GSSAPI */ -#ifdef FTP_SRP - if (ftp_auth_type[j] == FTA_SRP && ck_srp_is_installed()) { - if (srp_ftp_auth(ftp_user_host,NULL,NULL)) - return(1); - else if (ftpcode == 500 || ftpcode == 502) - return(0); - } -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 - if (ftp_auth_type[j] == FTA_K4 && ck_krb4_is_installed()) { - n = ftpcmd("AUTH KERBEROS_V4",NULL,0,0,ftp_vbm); - if (n == REPLY_CONTINUE) { - char tgt[4*REALM_SZ+1]; - int rc; - - if (!quiet) - printf("KERBEROS_V4 accepted as authentication type\n"); - ckstrncpy(inst, (char *) krb_get_phost(ftp_user_host),INST_SZ); - ckstrncpy(ftp_realm, - (char *)ck_krb4_realmofhost(ftp_user_host), - REALM_SZ - ); - - ckmakmsg(tgt,sizeof(tgt),"krbtgt.",ftp_realm,"@",ftp_realm); - rc = ck_krb4_tkt_isvalid(tgt); - - if (rc <= 0 && krb4_autoget) - ck_krb4_autoget_TGT(ftp_realm); - - service = "ftp"; - kerror = krb_mk_req(&ftp_tkt,service,inst,ftp_realm,checksum); - if (kerror == KDC_PR_UNKNOWN) { - service = "rcmd"; - kerror = krb_mk_req(&ftp_tkt, - service, - inst, - ftp_realm, - checksum - ); - } - if (kerror) - fprintf(stderr, "Kerberos V4 krb_mk_req failed: %s\n", - krb_get_err_text(kerror)); - if (!kerror) { - kerror = krb_get_cred(service, inst, ftp_realm,&ftp_cred); - if (kerror) - fprintf(stderr, "Kerberos V4 krb_get_cred failed: %s\n", - krb_get_err_text(kerror)); - } - if (!kerror) { - int rc; - rc = des_key_sched(ftp_cred.session, ftp_sched); - if (rc == -1) { - printf("?Invalid DES key specified in credentials\r\n"); - debug(F110,"ftp_auth", - "invalid DES Key specified in credentials",0); - } else if ( rc == -2 ) { - printf("?Weak DES key specified in credentials\r\n"); - debug(F110,"ftp_auth", - "weak DES Key specified in credentials",0); - } else if ( rc != 0 ) { - printf("?DES Key Schedule not set by credentials\r\n"); - debug(F110,"ftp_auth", - "DES Key Schedule not set by credentials",0); - } - reply_parse = "ADAT="; - i = FTP_BUFSIZ; - kerror = radix_encode(ftp_tkt.dat, out_buf, ftp_tkt.length, - &i, RADIX_ENCODE); - if (kerror) { - fprintf(stderr, "Base 64 encoding failed: %s\n", - radix_error(kerror)); - goto krb4_err; - } - if (i > FTP_BUFSIZ - 6) - printf("?ADAT data too long\n"); - if (ftpcmd("ADAT",out_buf,-1,-1,0) != - REPLY_COMPLETE) { - fprintf(stderr, "Kerberos V4 authentication failed\n"); - goto krb4_err; - } - if (!reply_parse) { - fprintf(stderr, - "No authentication data received from server\n"); - goto krb4_err; - } - i = sizeof(out_buf); - kerror = - radix_encode(reply_parse, out_buf, 0, &i, RADIX_DECODE); - if (kerror) { - fprintf(stderr, "Base 64 decoding failed: %s\n", - radix_error(kerror)); - goto krb4_err; - } - kerror = krb_rd_safe(out_buf, i, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &hisctladdr, - &myctladdr, - &ftp_msg_data - ); - if (kerror) { - fprintf(stderr, "Kerberos V4 krb_rd_safe failed: %s\n", - krb_get_err_text(kerror)); - goto krb4_err; - } - - /* fetch the (modified) checksum */ - memcpy(&cksum, ftp_msg_data.app_data, sizeof(cksum)); - if (ntohl(cksum) == checksum + 1) { - if (ftp_vbm) - printf("Kerberos V4 authentication succeeded\n"); - reply_parse = NULL; - auth_type = "KERBEROS_V4"; - return(1); - } else - fprintf(stderr, - "Kerberos V4 mutual authentication failed\n"); - krb4_err: - reply_parse = NULL; - } - } else { - if (ftp_deb) - fprintf(stderr, - "KERBEROS_V4 rejected as an authentication type\n"); - if (ftpcode == 500 || ftpcode == 502) - return(0); - } - } -#endif /* FTP_KRB4 */ -#ifdef CK_SSL - if (ftp_auth_type[j] == FTA_TLS && ck_ssleay_is_installed()) { -#ifdef FTPHOST - if (!hostcmd) { - ftpcmd("HOST",ftp_user_host,0,0,0); - hostcmd = 1; - } -#endif /* FTPHOST */ - n = ftpcmd("AUTH TLS",NULL,0,0,ftp_vbm); - if (n != REPLY_COMPLETE) - n = ftpcmd("AUTH TLS-P",NULL,0,0,ftp_vbm); - if (n == REPLY_COMPLETE) { - if (!quiet) - printf("TLS accepted as authentication type\n"); - - auth_type = "TLS"; - ssl_auth(); - if (ssl_ftp_active_flag ) { - ftp_dpl = FPL_CLR; - ftp_cpl = FPL_PRV; - return(1); - } else { - fprintf(stderr,"TLS authentication failed\n"); - auth_type = NULL; -#ifdef TCPIPLIB - socket_close(csocket); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(csocket, 1+1); -#endif /* USE_SHUTDOWN */ - close(csocket); -#endif /* TCPIPLIB */ - csocket = -1; - if (ftp_hookup(ftp_user_host,ftp_port,0) == NULL) - return(0); - } - } else { - if (ftp_deb) - fprintf(stderr,"TLS rejected as an authentication type\n"); - if (ftpcode == 500 || ftpcode == 502) - return(0); - } - } - if (ftp_auth_type[j] == FTA_SSL && ck_ssleay_is_installed()) { -#ifdef FTPHOST - if (!hostcmd) { - ftpcmd("HOST",ftp_user_host,0,0,0); - hostcmd = 1; - } -#endif /* FTPHOST */ - n = ftpcmd("AUTH SSL",NULL,0,0,ftp_vbm); - if (n == REPLY_CONTINUE || n == REPLY_COMPLETE) { - if (!quiet) - printf("SSL accepted as authentication type\n"); - auth_type = "SSL"; - ssl_auth(); - if (ssl_ftp_active_flag) { - ftp_dpl = FPL_PRV; - ftp_cpl = FPL_PRV; - setprotbuf(1<<20); - return(1); - } else { - fprintf(stderr,"SSL authentication failed\n"); - auth_type = NULL; -#ifdef TCPIPLIB - socket_close(csocket); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(csocket, 1+1); -#endif /* USE_SHUTDOWN */ - close(csocket); -#endif /* TCPIPLIB */ - csocket = -1; - if (ftp_hookup(ftp_user_host,ftp_port,0) == NULL) - return(0); - } - } else { - if (ftp_deb) - fprintf(stderr, "SSL rejected as an authentication type\n"); - if (ftpcode == 500 || ftpcode == 502) - return(0); - } - } -#endif /* CK_SSL */ - /* Other auth types go here ... */ - } /* for (j;;) */ - return(0); -} -#endif /* FTP_SECURITY */ - -static int -#ifdef CK_ANSIC -setprotbuf(unsigned int size) -#else -setprotbuf(size) unsigned int size; -#endif /* CK_ANSIC */ -/* setprotbuf */ { - if (ucbuf) - free(ucbuf); - ucbuf = NULL; - ucbufsiz = 0; - actualbuf = size; - while ((ucbuf = (CHAR *)malloc(actualbuf)) == NULL) { - if (actualbuf) - actualbuf /= 2; - else - return(0); - } - ucbufsiz = actualbuf - FUDGE_FACTOR; - debug(F101,"setprotbuf ucbufsiz","",ucbufsiz); - if (ucbufsiz < 128) { - printf("WARNING: tiny ucbufsiz: %d\n",ucbufsiz); - } else if (ucbufsiz < 0) { - printf("ERROR: ucbuf allocation failure\n"); - return(-1); - } - maxbuf = actualbuf; - return(1); -} - -static int -#ifdef CK_ANSIC -setpbsz(unsigned int size) -#else -setpbsz(size) unsigned int size; -#endif /* CK_ANSIC */ -/* setpbsz */ { - if (!setprotbuf(size)) { - perror("?Error while trying to malloc PROT buffer:"); -#ifdef FTP_SRP - srp_reset(); -#endif /* FTP_SRP */ - ftpclose(); - return(-1); - } - reply_parse = "PBSZ="; - ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,"PBSZ ", -#ifdef CK_SSL - ssl_ftp_active_flag ? "0" : -#endif /* CK_SSL */ - ckuitoa(actualbuf),NULL,NULL); - if (ftpcmd(ftpcmdbuf,NULL,0,0,0) != REPLY_COMPLETE) { - if (connected) { - printf("?Unable to negotiate PROT buffer size with FTP server\n"); - ftpclose(); - } - return(-1); - } - if (reply_parse) { - if ((maxbuf = (unsigned int) atol(reply_parse)) > actualbuf) - maxbuf = actualbuf; - } else - maxbuf = actualbuf; - ucbufsiz = maxbuf - FUDGE_FACTOR; - debug(F101,"setpbsz ucbufsiz","",ucbufsiz); - reply_parse = NULL; - return(0); -} - -static VOID -cancel_remote(din) int din; { - CHAR buf[FTP_BUFSIZ]; - int x, nfnd; -#ifdef BSDSELECT - fd_set mask; -#endif /* BSDSELECT */ -#ifdef IBMSELECT - int fds[2], fdcnt = 0; -#endif /* IBMSELECT */ -#ifdef DEBUG - extern int debtim; - int xdebtim; - xdebtim = debtim; - debtim = 1; -#endif /* DEBUG */ - debug(F100,"ftp cancel_remote entry","",0); -#ifdef CK_SSL - if (ssl_ftp_active_flag) { - /* - * Send Telnet IP, Telnet DM but do so inline and within the - * TLS channel - */ - int count, error; - - buf[0] = IAC; - buf[1] = TN_IP; - buf[2] = IAC; - buf[3] = TN_DM; - buf[4] = NUL; - - count = SSL_write(ssl_ftp_con, buf, 4); - debug(F111,"ftp cancel_remote","SSL_write(IAC IP IAC DM)",count); - error = SSL_get_error(ssl_ftp_con,count); - debug(F111,"ftp cancel_remote","SSL_get_error()",error); - switch (error) { - case SSL_ERROR_NONE: - break; - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - case SSL_ERROR_SYSCALL: -#ifdef NT - { - int gle = GetLastError(); - } -#endif /* NT */ - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - lostpeer(); - return; - } - } else -#endif /* CK_SSL */ - { - /* - * send IAC in urgent mode instead of DM because 4.3BSD places oob mark - * after urgent byte rather than before as is protocol now. - */ - buf[0] = IAC; - buf[1] = TN_IP; - buf[2] = IAC; - buf[3] = NUL; - if ((x = send(csocket, (SENDARG2TYPE)buf, 3, MSG_OOB)) != 3) - perror("cancel"); - debug(F101,"ftp cancel_remote send 1","",x); - buf[0] = TN_DM; - x = send(csocket,(SENDARG2TYPE)buf,1,0); - debug(F101,"ftp cancel_remote send 2","",x); - } - x = scommand("ABOR"); - debug(F101,"ftp cancel_remote scommand","",x); -#ifdef BSDSELECT - FD_ZERO(&mask); - FD_SET(csocket, &mask); - if (din) { - FD_SET(din, &mask); - } - nfnd = empty(&mask, 10); - debug(F101,"ftp cancel_remote empty","",nfnd); - if ((nfnd) <= 0) { - if (nfnd < 0) { - perror("cancel"); - } -#ifdef FTP_PROXY - if (ptabflg) - ftpcode = -1; -#endif /* FTP_PROXY */ - lostpeer(); - } - debug(F110,"ftp cancel_remote","D",0); - if (din && FD_ISSET(din, &mask)) { - /* Security: No threat associated with this read. */ - /* But you can't simply read the TLS data stream */ -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - int count, error; - while ((count = SSL_read(ssl_ftp_data_con, buf, FTP_BUFSIZ)) > 0) - /* LOOP */ ; - } else -#endif /* CK_SSL */ - { - while (recv(din, (SENDARG2TYPE)buf, FTP_BUFSIZ,0) > 0) - /* LOOP */ ; - } - } - debug(F110,"ftp cancel_remote","E",0); -#else /* BSDSELECT */ -#ifdef IBMSELECT - fds[0] = csocket; - fdcnt++; - if (din) { - fds[1] = din; - fdcnt++; - } - nfnd = empty(fds, fdcnt, 10); - debug(F101,"ftp cancel_remote empty","",nfnd); - if ((nfnd) <= 0) { - if (nfnd < 0) { - perror("cancel"); - } -#ifdef FTP_PROXY - if (ptabflg) - ftpcode = -1; -#endif /* FTP_PROXY */ - lostpeer(); - } - debug(F110,"ftp cancel_remote","D",0); - if (din && select(&din, 1,0,0,1) ) { -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - int count, error; - while ((count = SSL_read(ssl_ftp_data_con, buf, FTP_BUFSIZ)) > 0) - /* LOOP */ ; - } else -#endif /* CK_SSL */ - { - while (recv(din, (SENDARG2TYPE)buf, FTP_BUFSIZ,0) > 0) - /* LOOP */ ; - } - } - debug(F110,"ftp cancel_remote","E",0); -#else /* IBMSELECT */ - Some form of select is required. -#endif /* IBMSELECT */ -#endif /* BSDSELECT */ - if (getreply(0,-1,-1,ftp_vbm,0) == REPLY_ERROR && ftpcode == 552) { - debug(F110,"ftp cancel_remote","F",0); - /* 552 needed for NIC style cancel */ - getreply(0,-1,-1,ftp_vbm,0); - debug(F110,"ftp cancel_remote","G",0); - } - debug(F110,"ftp cancel_remote","H",0); - getreply(0,-1,-1,ftp_vbm,0); - debug(F110,"ftp cancel_remote","I",0); -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ -} - -static int -fts_dpl(x) int x; { - if (!auth_type -#ifdef OS2 - || !ck_crypt_is_installed() -#endif /* OS2 */ - ) { - switch ( x ) { - case FPL_PRV: - printf("?Cannot set protection level to PRIVATE\n"); - return(0); - case FPL_SAF: - printf("?Cannot set protection level to SAFE\n"); - return(0); - } - ftp_dpl = x; - return(1); - } - -#ifdef CK_SSL - if (x == FPL_SAF && - (!strcmp(auth_type,"SSL") || !strcmp(auth_type,"TLS"))) { - printf("Cannot set protection level to safe\n"); - return(0); - } -#endif /* CK_SSL */ - /* Start with a PBSZ of 1 meg */ - if (x != FPL_CLR) { - if (setpbsz(DEFAULT_PBSZ) < 0) - return(0); - } - y = ftpcmd(x == FPL_CLR ? "PROT C" : - (x == FPL_SAF ? "PROT S" : "PROT P"), NULL, 0, 0,ftp_vbm); - if (y == REPLY_COMPLETE) { - ftp_dpl = x; - return(1); - } - return(0); -} - -static int -fts_cpl(x) int x; { - if (!auth_type -#ifdef OS2 - || !ck_crypt_is_installed() -#endif /* OS2 */ - ) { - switch ( x ) { - case FPL_PRV: - printf("?Cannot set protection level to PRIVATE\n"); - return(0); - case FPL_SAF: - printf("?Cannot set protection level to SAFE\n"); - return(0); - } - ftp_cpl = x; - return(1); - } - if (x == FPL_CLR) { - y = ftpcmd("CCC",NULL,0,0,ftp_vbm); - if (y == REPLY_COMPLETE) { - ftp_cpl = x; - return(1); - } - return(0); - } - ftp_cpl = x; - return(1); -} - -#ifdef FTP_GSSAPI -static VOID -user_gss_error(maj_stat, min_stat, s) - OM_uint32 maj_stat, min_stat; - char *s; -{ - /* a lot of work just to report the error */ - OM_uint32 gmaj_stat, gmin_stat, msg_ctx; - gss_buffer_desc msg; - msg_ctx = 0; - while (!msg_ctx) { - gmaj_stat = gss_display_status(&gmin_stat, maj_stat, - GSS_C_GSS_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &msg - ); - if ((gmaj_stat == GSS_S_COMPLETE)|| - (gmaj_stat == GSS_S_CONTINUE_NEEDED)) { - fprintf(stderr, "GSSAPI error major: %s\n", - (char*)msg.value); - gss_release_buffer(&gmin_stat, &msg); - } - if (gmaj_stat != GSS_S_CONTINUE_NEEDED) - break; - } - msg_ctx = 0; - while (!msg_ctx) { - gmaj_stat = gss_display_status(&gmin_stat, min_stat, - GSS_C_MECH_CODE, - GSS_C_NULL_OID, - &msg_ctx, - &msg - ); - if ((gmaj_stat == GSS_S_COMPLETE)|| - (gmaj_stat == GSS_S_CONTINUE_NEEDED)) { - fprintf(stderr, "GSSAPI error minor: %s\n", (char*)msg.value); - gss_release_buffer(&gmin_stat, &msg); - } - if (gmaj_stat != GSS_S_CONTINUE_NEEDED) - break; - } - fprintf(stderr, "GSSAPI error: %s\n", s); -} -#endif /* FTP_GSSAPI */ - -#ifndef NOMHHOST -#ifdef datageneral -#define NOMHHOST -#else -#ifdef HPUX5WINTCP -#define NOMHHOST -#endif /* HPUX5WINTCP */ -#endif /* datageneral */ -#endif /* NOMHHOST */ - -#ifdef INADDRX -static struct in_addr inaddrx; -#endif /* INADDRX */ - -static char * -ftp_hookup(host, port, tls) char * host; int port; int tls; { - register struct hostent *hp = 0; -#ifdef IP_TOS -#ifdef IPTOS_THROUGHPUT - int tos; -#endif /* IPTOS_THROUGHPUT */ -#endif /* IP_TOS */ - int s; - GSOCKNAME_T len; - static char hostnamebuf[MAXHOSTNAMELEN]; - char hostname[MAXHOSTNAMELEN] /* , *p, *q */ ; - int cport; -#ifdef DEBUG - extern int debtim; - int xdebtim; - xdebtim = debtim; - debtim = 1; -#endif /* DEBUG */ - -#ifndef NOHTTP - if (tcp_http_proxy) { - struct servent *destsp; - char *p, *q; - - ckmakmsg(proxyhost,HTTPCPYL,host,":",ckuitoa(port),NULL); - for (p = tcp_http_proxy, q = hostname; - *p != '\0' && *p != ':'; - p++, q++ - ) - *q = *p; - *q = '\0'; - - if (*p == ':') - p++; - else - p = "http"; - - destsp = getservbyname(p,"tcp"); - if (destsp) - cport = ntohs(destsp->s_port); - else if (p) { - cport = atoi(p); - } else - cport = 80; - } else -#endif /* NOHTTP */ - { - ckstrncpy(hostname,host,MAXHOSTNAMELEN); - cport = port; - } - memset((char *)&hisctladdr, 0, sizeof (hisctladdr)); - hisctladdr.sin_addr.s_addr = inet_addr(host); - if (hisctladdr.sin_addr.s_addr != -1) { - debug(F110,"ftp hookup A",hostname,0); - hisctladdr.sin_family = AF_INET; - ckstrncpy(hostnamebuf, hostname, MAXHOSTNAMELEN); - } else { - debug(F110,"ftp hookup B",hostname,0); - hp = gethostbyname(hostname); -#ifdef HADDRLIST - hp = ck_copyhostent(hp); /* make safe copy that won't change */ -#endif /* HADDRLIST */ - if (hp == NULL) { - fprintf(stderr, "ftp: %s: Unknown host\n", host); - ftpcode = -1; -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - return((char *) 0); - } - hisctladdr.sin_family = hp->h_addrtype; -#ifdef HADDRLIST - memcpy((char *)&hisctladdr.sin_addr, hp->h_addr_list[0], - sizeof(hisctladdr.sin_addr)); -#else /* HADDRLIST */ - memcpy((char *)&hisctladdr.sin_addr, hp->h_addr, - sizeof(hisctladdr.sin_addr)); -#endif /* HADDRLIST */ - ckstrncpy(hostnamebuf, hp->h_name, MAXHOSTNAMELEN); - } - debug(F110,"ftp hookup C",hostnamebuf,0); - ftp_host = hostnamebuf; - s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); - debug(F101,"ftp hookup socket","",s); - if (s < 0) { - perror("ftp: socket"); - ftpcode = -1; -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - return(0); - } - hisctladdr.sin_port = htons(cport); - errno = 0; -#ifdef HADDRLIST - debug(F100,"ftp hookup HADDRLIST","",0); - while -#else - debug(F100,"ftp hookup no HADDRLIST","",0); - if -#endif /* HADDRLIST */ - (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) { - debug(F101,"ftp hookup connect failed","",errno); -#ifdef HADDRLIST - if (hp && hp->h_addr_list[1]) { - int oerrno = errno; - - fprintf(stderr, "ftp: connect to address %s: ", - inet_ntoa(hisctladdr.sin_addr)); - errno = oerrno; - perror((char *) 0); - hp->h_addr_list++; - memcpy((char *)&hisctladdr.sin_addr, - hp->h_addr_list[0], - sizeof(hisctladdr.sin_addr)); - fprintf(stdout, "Trying %s...\n", - inet_ntoa(hisctladdr.sin_addr)); -#ifdef TCPIPLIB - socket_close(s); -#else /* TCPIPLIB */ - close(s); -#endif /* TCPIPLIB */ - s = socket(hisctladdr.sin_family, SOCK_STREAM, 0); - if (s < 0) { - perror("ftp: socket"); - ftpcode = -1; -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - return(0); - } - continue; - } -#endif /* HADDRLIST */ - perror("ftp: connect"); - ftpcode = -1; - goto bad; - } - debug(F100,"ftp hookup connect ok","",0); - - len = sizeof (myctladdr); - errno = 0; - if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) { - debug(F101,"ftp hookup getsockname failed","",errno); - perror("ftp: getsockname"); - ftpcode = -1; - goto bad; - } - debug(F100,"ftp hookup getsockname ok","",0); - -#ifndef NOHTTP - if (tcp_http_proxy) { -#ifdef OS2 - char * agent = "Kermit 95"; /* Default user agent */ -#else - char * agent = "C-Kermit"; -#endif /* OS2 */ - - if (http_connect(s,agent,NULL, - tcp_http_proxy_user, - tcp_http_proxy_pwd, - 0, - proxyhost - ) < 0) { - char * foo = NULL; -#ifdef TCPIPLIB - socket_close(s); -#else /* TCPIPLIB */ - close(s); -#endif /* TCPIPLIB */ - - while (foo == NULL && tcp_http_proxy != NULL ) { - - if (tcp_http_proxy_errno == 401 || - tcp_http_proxy_errno == 407 ) { - char uid[UIDBUFLEN]; - char pwd[PWDSIZ]; - struct txtbox tb[2]; - int ok; - - tb[0].t_buf = uid; - tb[0].t_len = UIDBUFLEN; - tb[0].t_lbl = "Proxy Userid: "; - tb[0].t_dflt = NULL; - tb[0].t_echo = 1; - tb[1].t_buf = pwd; - tb[1].t_len = 256; - tb[1].t_lbl = "Proxy Passphrase: "; - tb[1].t_dflt = NULL; - tb[1].t_echo = 2; - - ok = uq_mtxt("Proxy Server Authentication Required\n", - NULL, 2, tb); - - if (ok && uid[0]) { - char * proxy_user, * proxy_pwd; - - proxy_user = tcp_http_proxy_user; - proxy_pwd = tcp_http_proxy_pwd; - - tcp_http_proxy_user = uid; - tcp_http_proxy_pwd = pwd; - - foo = ftp_hookup(host, port, 0); - - debug(F110,"ftp_hookup()",foo,0); - memset(pwd,0,PWDSIZ); - tcp_http_proxy_user = proxy_user; - tcp_http_proxy_pwd = proxy_pwd; - } else - break; - } else - break; - } - if (foo != NULL) - return(foo); - perror("ftp: connect"); - ftpcode = -1; - goto bad; - } - ckstrncpy(hostnamebuf, proxyhost, MAXHOSTNAMELEN); - } -#endif /* NOHTTP */ - - csocket = s; - -#ifdef CK_SSL - if (tls) { - /* FTP over SSL - * If the connection is over an SSL proxy then the - * auth_type will be NULL. However, I'm not sure - * whether we should protect the data channel in - * that case or not. - */ - - debug(F100,"ftp hookup use_tls","",0); - if (!ssl_auth()) { - debug(F100,"ftp hookup ssl_auth failed","",0); - auth_type = NULL; - ftpcode = -1; - csocket = -1; - goto bad; - } - ssl_ftp_proxy = 1; - } -#endif /* CK_SSL */ - -#ifdef IP_TOS -#ifdef IPTOS_LOWDELAY - tos = IPTOS_LOWDELAY; - if (setsockopt(csocket, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0) - perror("ftp: setsockopt TOS (ignored)"); -#endif -#endif - if (!quiet) - printf("Connected to %s.\n", host); - - /* Read greeting from server */ - if (getreply(0,ftp_csl,ftp_csr,ftp_vbm,0) > 2) { - debug(F100,"ftp hookup bad reply","",0); -#ifdef TCPIPLIB - socket_close(csocket); -#else /* TCPIPLIB */ - close(csocket); -#endif /* TCPIPLIB */ - ftpcode = -1; - goto bad; - } -#ifdef SO_OOBINLINE - { - int on = 1; - errno = 0; - if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, - sizeof(on)) < 0) { - perror("ftp: setsockopt"); - debug(F101,"ftp hookup setsockopt failed","",errno); - } -#ifdef DEBUG - else - debug(F100,"ftp hookup setsockopt ok","",0); -#endif /* DEBUG */ - } -#endif /* SO_OOBINLINE */ - -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - return(ftp_host); - - bad: - debug(F100,"ftp hookup bad","",0); -#ifdef TCPIPLIB - socket_close(s); -#else /* TCPIPLIB */ - close(s); -#endif /* TCPIPLIB */ -#ifdef DEBUG - debtim = xdebtim; -#endif /* DEBUG */ - csocket = -1; - return((char *)0); -} - -static VOID -ftp_init() { - int i, n; - - /* The purpose of the initial REST 0 is not clear, but other FTP */ - /* clients do it. In any case, failure of this command is not a */ - /* reliable indication that the server does not support Restart. */ - - okrestart = 0; - if (!noinit) { - n = ftpcmd("REST 0",NULL,0,0,0); - if (n == REPLY_COMPLETE) - okrestart = 1; -#ifdef COMMENT - else if (ftp_deb) - printf("WARNING: Unable to restore file pointer.\n"); -#endif /* COMMENT */ - } - n = ftpcmd("SYST",NULL,0,0,0); /* Get server system type */ - if (n == REPLY_COMPLETE) { - register char *cp, c = NUL; - cp = ckstrchr(ftp_reply_str+4,' '); /* Get first word of reply */ - if (cp == NULL) - cp = ckstrchr(ftp_reply_str+4,'\r'); - if (cp) { - if (cp[-1] == '.') - cp--; - c = *cp; /* Save this char */ - *cp = '\0'; /* Replace it with NUL */ - } - if (!quiet) - printf("Remote system type is %s.\n",ftp_reply_str+4); - ckstrncpy(ftp_srvtyp,ftp_reply_str+4,SRVNAMLEN); - if (cp) /* Put back saved char */ - *cp = c; - } - alike = !ckstrcmp(ftp_srvtyp,myostype,-1,0); - - if (!ckstrcmp(ftp_srvtyp,"UNIX",-1,0)) servertype = SYS_UNIX; - else if (!ckstrcmp(ftp_srvtyp,"WIN32",-1,0)) servertype = SYS_WIN32; - else if (!ckstrcmp(ftp_srvtyp,"OS/2",-1,0)) servertype = SYS_WIN32; - else if (!ckstrcmp(ftp_srvtyp,"VMS",-1,0)) servertype = SYS_VMS; - else if (!ckstrcmp(ftp_srvtyp,"DOS",-1,0)) servertype = SYS_DOS; - else if (!ckstrcmp(ftp_srvtyp,"TOPS20",-1,0)) servertype = SYS_TOPS20; - else if (!ckstrcmp(ftp_srvtyp,"TOPS10",-1,0)) servertype = SYS_TOPS10; - -#ifdef FTP_PROXY - unix_proxy = 0; - if (servertype == SYS_UNIX && proxy) unix_proxy = 1; -#endif /* FTP_PROXY */ - - if (ftp_cmdlin && xfermode == XMODE_M) - ftp_typ = binary; /* Type given on command line */ - else /* Otherwise set it automatically */ - ftp_typ = alike ? FTT_BIN : FTT_ASC; - changetype(ftp_typ,0); /* Change to this type */ - g_ftp_typ = ftp_typ; /* Make it the global type */ - if (!quiet) - printf("Default transfer mode is %s\n", - ftp_typ ? "BINARY" : "TEXT (\"ASCII\")" - ); - for (i = 0; i < 16; i++) /* Init server FEATure table */ - sfttab[i] = 0; - if (!noinit) { - n = ftpcmd("MODE S",NULL,0,0,0); /* We always send in Stream mode */ -#ifdef COMMENT - if (n != REPLY_COMPLETE) - printf("WARNING: Server does not accept MODE S(TREAM)\n"); -#endif /* COMMENT */ - n = ftpcmd("STRU F",NULL,0,0,0); /* STRU File (not Record or Page) */ -#ifdef COMMENT - if (n != REPLY_COMPLETE) - printf("WARNING: Server does not accept STRU F(ILE)\n"); -#endif /* COMMENT */ - if (featok) { - n = ftpcmd("FEAT",NULL,0,0,0); /* Ask server about features */ - if (n == REPLY_COMPLETE) { - debug(F101,"ftp_init FEAT","",sfttab[0]); - if (deblog || ftp_deb) { - int i; - for (i = 1; i < 16 && i < nfeattab; i++) { - debug(F111,"ftp_init FEAT",feattab[i].kwd,sfttab[i]); - if (ftp_deb) - printf(" Server %s %s\n", - sfttab[i] ? "supports" : "does not support", - feattab[i].kwd - ); - } - /* Deal with disabled MLST opts here if necessary */ - /* But why would it be? */ - } - } - } - } -} - -static int -ftp_login(host) char * host; { /* (also called from ckuusy.c) */ - static char ftppass[PASSBUFSIZ]=""; - char tmp[PASSBUFSIZ]; - char *user = NULL, *pass = NULL, *acct = NULL; - int n, aflag = 0; - extern char uidbuf[]; - extern char pwbuf[]; - extern int pwflg, pwcrypt; - - debug(F111,"ftp_login",ftp_logname,ftp_log); - - if (!ckstrcmp(ftp_logname,"anonymous",-1,0)) - anonymous = 1; - if (!ckstrcmp(ftp_logname,"ftp",-1,0)) - anonymous = 1; - -#ifdef FTP_SRP - if (auth_type && !strcmp(auth_type, "SRP")) { - user = srp_user; - pass = srp_pass; - acct = srp_acct; - } else -#endif /* FTP_SRP */ - if (anonymous) { - user = "anonymous"; - if (ftp_tmp) { /* They gave a password */ - pass = ftp_tmp; - } else if (ftp_apw) { /* SET FTP ANONYMOUS-PASSWORD */ - pass = ftp_apw; - } else { /* Supply user@host */ - ckmakmsg(tmp,PASSBUFSIZ,whoami(),"@",myhost,NULL); - pass = tmp; - } - debug(F110,"ftp anonymous",pass,0); - } else { -#ifdef USE_RUSERPASS - if (ruserpass(host, &user, &pass, &acct) < 0) { - ftpcode = -1; - return(0); - } -#endif /* USE_RUSERPASS */ - if (ftp_logname) { - user = ftp_logname; - pass = ftp_tmp; - } else if (uidbuf[0] && (ftp_tmp || pwbuf[0] && pwflg)) { - user = uidbuf; - if (ftp_tmp) { - pass = ftp_tmp; - } else if (pwbuf[0] && pwflg) { - ckstrncpy(ftppass,pwbuf,PASSBUFSIZ); -#ifdef OS2 - if ( pwcrypt ) - ck_encrypt((char *)ftppass); -#endif /* OS2 */ - pass = ftppass; - } - } - acct = ftp_acc; - while (user == NULL) { - char *myname, prompt[PROMPTSIZ]; - int ok; - - myname = whoami(); - if (myname) - ckmakxmsg(prompt,PROMPTSIZ," Name (",host,":",myname,"): ", - NULL,NULL,NULL,NULL,NULL,NULL,NULL); - else - ckmakmsg(prompt,PROMPTSIZ," Name (",host,"): ",NULL); - tmp[0] = '\0'; - - ok = uq_txt(NULL,prompt,1,NULL,tmp,PASSBUFSIZ,NULL, - DEFAULT_UQ_TIMEOUT); - if (!ok || *tmp == '\0') - user = myname; - else - user = brstrip(tmp); - } - } - n = ftpcmd("USER",user,-1,-1,ftp_vbm); - if (n == REPLY_COMPLETE) { - /* determine if we need to send a dummy password */ - if (ftpcmd("PWD",NULL,0,0,0) != REPLY_COMPLETE) - ftpcmd("PASS dummy",NULL,0,0,1); - } else if (n == REPLY_CONTINUE) { -#ifdef CK_ENCRYPTION - int oldftp_cpl; -#endif /* CK_ENCRYPTION */ - - if (pass == NULL) { - int ok; - setint(); - ok = uq_txt(NULL," Password: ",2,NULL,ftppass,PASSBUFSIZ,NULL, - DEFAULT_UQ_TIMEOUT); - if (ok) - pass = brstrip(ftppass); - } - -#ifdef CK_ENCRYPTION - oldftp_cpl = ftp_cpl; - ftp_cpl = FPL_PRV; -#endif /* CK_ENCRYPTION */ - n = ftpcmd("PASS",pass,-1,-1,1); - if (!anonymous && pass) { - char * p = pass; - while (*p++) *(p-1) = NUL; - makestr(&ftp_tmp,NULL); - } -#ifdef CK_ENCRYPTION - /* level may have changed */ - if (ftp_cpl == FPL_PRV) - ftp_cpl = oldftp_cpl; -#endif /* CK_ENCRYPTION */ - } - if (n == REPLY_CONTINUE) { - aflag++; - if (acct == NULL) { - static char ftpacct[80]; - int ok; - setint(); - ok = uq_txt(NULL," Account: ",2,NULL,ftpacct,80,NULL, - DEFAULT_UQ_TIMEOUT); - if (ok) - acct = brstrip(ftpacct); - } - n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm); - } - if (n != REPLY_COMPLETE) { - fprintf(stderr, "FTP login failed.\n"); - if (haveurl) - doexit(BAD_EXIT,-1); - return(0); - } - if (!aflag && acct != NULL) { - ftpcmd("ACCT",acct,-1,-1,ftp_vbm); - } - makestr(&ftp_logname,user); - loggedin = 1; -#ifdef LOCUS - /* Unprefixed file management commands go to server */ - if (autolocus && !ftp_cmdlin) { - setlocus(0,1); - } -#endif /* LOCUS */ - ftp_init(); - - if (anonymous && !quiet) { - printf(" Logged in as anonymous (%s)\n",pass); - memset(pass, 0, strlen(pass)); - } - if (ftp_rdir) { - if (doftpcwd(ftp_rdir,-1) < 1) - doexit(BAD_EXIT,-1); - } - -#ifdef FTP_PROXY - if (proxy) - return(1); -#endif /* FTP_PROXY */ - return(1); -} - -static int -ftp_reset() { - int rc; -#ifdef BSDSELECT - int nfnd = 1; - fd_set mask; - FD_ZERO(&mask); - while (nfnd > 0) { - FD_SET(csocket, &mask); - if ((nfnd = empty(&mask,0)) < 0) { - perror("reset"); - ftpcode = -1; - lostpeer(); - return(0); - } else if (nfnd) { - getreply(0,-1,-1,ftp_vbm,0); - } - } -#else /* BSDSELECT */ -#ifdef IBMSELECT - int nfnd = 1; - while (nfnd > 0) { - if ((nfnd = empty(&csocket,1,0)) < 0) { - perror("reset"); - ftpcode = -1; - lostpeer(); - return(0); - } else if (nfnd) { - getreply(0,-1,-1,ftp_vbm,0); - } - } -#endif /* IBMSELECT */ -#endif /* BSDSELECT */ - rc = (ftpcmd("REIN",NULL,0,0,ftp_vbm) == REPLY_COMPLETE); - if (rc > 0) - loggedin = 0; - return(rc); -} - -static int -ftp_rename(from, to) char * from, * to; { - int lcs = -1, rcs = -1; -#ifndef NOCSETS - if (ftp_xla) { - lcs = ftp_csl; - if (lcs < 0) lcs = fcharset; - rcs = ftp_csx; - if (rcs < 0) rcs = ftp_csr; - } -#endif /* NOCSETS */ - if (ftpcmd("RNFR",from,lcs,rcs,ftp_vbm) == REPLY_CONTINUE) { - return(ftpcmd("RNTO",to,lcs,rcs,ftp_vbm) == REPLY_COMPLETE); - } - return(0); /* Failure */ -} - -static int -ftp_umask(mask) char * mask; { - int rc; - rc = (ftpcmd("SITE UMASK",mask,-1,-1,1) == REPLY_COMPLETE); - return(rc); -} - -static int -ftp_user(user,pass,acct) char * user, * pass, * acct; { - int n = 0, aflag = 0; - char pwd[PWDSIZ]; - - if (!auth_type && ftp_aut) { -#ifdef FTP_SRP - if (ck_srp_is_installed()) { - if (srp_ftp_auth( NULL, user, pass)) { - makestr(&pass,srp_pass); - } - } -#endif /* FTP_SRP */ - } - n = ftpcmd("USER",user,-1,-1,ftp_vbm); - if (n == REPLY_COMPLETE) - n = ftpcmd("PASS dummy",NULL,0,0,1); - else if (n == REPLY_CONTINUE) { -#ifdef CK_ENCRYPTION - int oldftp_cpl; -#endif /* CK_ENCRYPTION */ - if (pass == NULL || !pass[0]) { - int ok; - pwd[0] = '\0'; - setint(); - ok = uq_txt(NULL," Password: ",2,NULL,pwd,PWDSIZ,NULL, - DEFAULT_UQ_TIMEOUT); - if (ok) - pass = brstrip(pwd); - } - -#ifdef CK_ENCRYPTION - if ((oldftp_cpl = ftp_cpl) == PROT_S) - ftp_cpl = PROT_P; -#endif /* CK_ENCRYPTION */ - n = ftpcmd("PASS",pass,-1,-1,1); - memset(pass, 0, strlen(pass)); -#ifdef CK_ENCRYPTION - /* level may have changed */ - if (ftp_cpl == PROT_P) - ftp_cpl = oldftp_cpl; -#endif /* CK_ENCRYPTION */ - } - if (n == REPLY_CONTINUE) { - if (acct == NULL || !acct[0]) { - int ok; - pwd[0] = '\0'; - setint(); - ok = uq_txt(NULL," Account: ",2,NULL,pwd,PWDSIZ,NULL, - DEFAULT_UQ_TIMEOUT); - if (ok) - acct = pwd; - } - n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm); - aflag++; - } - if (n != REPLY_COMPLETE) { - printf("Login failed.\n"); - return(0); - } - if (!aflag && acct != NULL && acct[0]) { - n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm); - } - if (n == REPLY_COMPLETE) { - makestr(&ftp_logname,user); - loggedin = 1; - ftp_init(); - return(1); - } - return(0); -} - -char * -ftp_authtype() { - if (!connected) - return("NULL"); - return(auth_type ? auth_type : "NULL"); -} - -char * -ftp_cpl_mode() { - switch (ftp_cpl) { - case FPL_CLR: - return("clear"); - case FPL_SAF: - return("safe"); - case FPL_PRV: - return("private"); - case FPL_CON: - return("confidential"); - default: - return("(error)"); - } -} - -char * -ftp_dpl_mode() { - switch (ftp_dpl) { - case FPL_CLR: - return("clear"); - case FPL_SAF: - return("safe"); - case FPL_PRV: - return("private"); - case FPL_CON: - return("confidential"); - default: - return("(error)"); - } -} - - -/* remote_files() */ -/* - Returns next remote filename on success; - NULL on error or no more files with global rfrc set to: - -1: Bad argument - -2: Server error response to NLST, e.g. file not found - -3: No more files - -9: Internal error -*/ -#define FTPNAMBUFLEN CKMAXPATH+1024 - -/* Check: ckmaxfiles CKMAXOPEN */ - -#define MLSDEPTH 128 /* Stack of open temp files */ -static int mlsdepth = 0; /* Temp file stack depth */ -static FILE * tmpfilptr[MLSDEPTH+1] = { NULL, NULL }; /* Temp file pointers */ -static char * tmpfilnam[MLSDEPTH+1] = { NULL, NULL }; /* Temp file names */ - -static VOID -mlsreset() { /* Reset MGET temp-file stack */ - int i; - for (i = 0; i <= mlsdepth; i++) { - if (tmpfilptr[i]) { - fclose(tmpfilptr[i]); - tmpfilptr[i] = NULL; - if (tmpfilnam[i]) { -#ifdef OS2 - unlink(tmpfilnam[i]); -#endif /* OS2 */ - free(tmpfilnam[i]); - } - } - } - mlsdepth = 0; -} - -static CHAR * -#ifdef CK_ANSIC -remote_files(int new_query, CHAR * arg, CHAR * pattern, int proxy_switch) -#else /* CK_ANSIC */ -remote_files(new_query, arg, pattern, proxy_switch) - int new_query; - CHAR * arg; /* That we send to the server */ - CHAR * pattern; /* That we use locally */ - int proxy_switch; -#endif /* CK_ANSIC */ -/* remote_files */ { - static CHAR buf[FTPNAMBUFLEN]; - CHAR *cp, *whicharg; - char * cdto = NULL; - char * p; - int i, x, forced = 0; - int lcs = 0, rcs = 0, xlate = 0; - - debug(F101,"ftp remote_files new_query","",new_query); - debug(F110,"ftp remote_files arg",arg,0); - debug(F110,"ftp remote_files pattern",pattern,0); - - rfrc = -1; - if (pattern) /* Treat empty pattern same as NULL */ - if (!*pattern) - pattern = NULL; - if (arg) /* Ditto for arg */ - if (!*arg) - arg = NULL; - - again: - - if (new_query) { - if (tmpfilptr[mlsdepth]) { - fclose(tmpfilptr[mlsdepth]); - tmpfilptr[mlsdepth] = NULL; -#ifdef OS2 - if (!ftp_deb && !deblog) - unlink(tmpfilnam[mlsdepth]); -#endif /* OS2 */ - } - } - if (tmpfilptr[mlsdepth] == NULL) { - extern char * tempdir; - char * p; - debug(F110,"ftp remote_files tempdir",tempdir,0); - if (tempdir) { - p = tempdir; - } else { -#ifdef OS2 -#ifdef NT - p = getenv("K95TMP"); -#else - p = getenv("K2TMP"); -#endif /* NT */ - if (!p) -#endif /* OS2 */ - p = getenv("CK_TMP"); - if (!p) - p = getenv("TMPDIR"); - if (!p) p = getenv("TEMP"); - if (!p) p = getenv("TMP"); -#ifdef OS2ORUNIX - if (p) { - int len = strlen(p); - if (p[len-1] != '/' -#ifdef OS2 - && p[len-1] != '\\' -#endif /* OS2 */ - ) { - static char foo[CKMAXPATH]; - ckstrncpy(foo,p,CKMAXPATH); - ckstrncat(foo,"/",CKMAXPATH); - p = foo; - } - } else -#else /* OS2ORUNIX */ - if (!p) -#endif /* OS2ORUNIX */ -#ifdef UNIX /* Systems that have a standard */ - p = "/tmp/"; /* temporary directory... */ -#else -#ifdef datageneral - p = ":TMP:"; -#else - p = ""; -#endif /* datageneral */ -#endif /* UNIX */ - } - debug(F110,"ftp remote_files p",p,0); - - /* Get temp file */ - - if ((tmpfilnam[mlsdepth] = (char *)malloc(CKMAXPATH+1))) { - ckmakmsg((char *)tmpfilnam[mlsdepth], - CKMAXPATH+1,p,"ckXXXXXX",NULL,NULL); - } else { - printf("?Malloc failure: remote_files()\n"); - return(NULL); - } - -#ifdef NT - { - char * tmpfil = mktemp((char *)tmpfilnam[mlsdepth]); - if ( tmpfil ) - ckstrncpy(tmpfilnam[mlsdepth],tmpfil,CKMAXPATH+1); - } -#else /* NT */ -#ifdef MKTEMP -#ifdef MKSTEMP - x = mkstemp((char *)tmpfilnam[mlsdepth]); - if (x > -1) close(x); /* We just want the name. */ -#else - mktemp((char *)tmpfilnam[mlsdepth]); -#endif /* MKSTEMP */ - /* if no mktmpnam() the name will just be "ckXXXXXX"... */ -#endif /* MKTEMP */ -#endif /* NT */ - - debug(F111,"ftp remote_files tmpfilnam[mlsdepth]", - tmpfilnam[mlsdepth],mlsdepth); - -#ifdef FTP_PROXY - if (proxy_switch) { - pswitch(!proxy); - } -#endif /* FTP_PROXY */ - - debug(F101,"ftp remote_files ftp_xla","",ftp_xla); - debug(F101,"ftp remote_files ftp_csl","",ftp_csl); - debug(F101,"ftp remote_files ftp_csr","",ftp_csr); - -#ifndef NOCSETS - xlate = ftp_xla; /* SET FTP CHARACTER-SET-TRANSLATION */ - if (xlate) { /* ON? */ - lcs = ftp_csl; /* Local charset */ - if (lcs < 0) lcs = fcharset; - if (lcs < 0) xlate = 0; - } - if (xlate) { /* Still ON? */ - rcs = ftp_csx; /* Remote (Server) charset */ - if (rcs < 0) rcs = ftp_csr; - if (rcs < 0) xlate = 0; - } -#endif /* NOCSETS */ - - forced = mgetforced; /* MGET method forced? */ - if (!forced || !mgetmethod) /* Not forced... */ - mgetmethod = (sfttab[0] && sfttab[SFT_MLST]) ? /* so pick one */ - SND_MLS : - SND_NLS; -/* - User's Command: Result: - mget /nlst NLST (NULL) - mget /nlst foo NLST foo - mget /nlst *.txt NLST *.txt - mget /nlst /match:*.txt NLST (NULL) - mget /nlst /match:*.txt foo NLST foo - mget /mlsd MLSD (NULL) - mget /mlsd foo MLSD foo - mget /mlsd *.txt MLSD (NULL) - mget /mlsd /match:*.txt MLSD (NULL) - mget /mlsd /match:*.txt foo MLSD foo -*/ - x = -1; - while (x < 0) { - if (pattern) { /* Don't simplify this! */ - whicharg = arg; - } else if (mgetmethod == SND_MLS) { - if (arg) - whicharg = iswild((char *)arg) ? NULL : arg; - else - whicharg = NULL; - } else { - whicharg = arg; - } - debug(F110,"ftp remote_files mgetmethod", - mgetmethod == SND_MLS ? "MLSD" : "NLST", 0); - debug(F110,"ftp remote_files whicharg",whicharg,0); - - x = recvrequest((mgetmethod == SND_MLS) ? "MLSD" : "NLST", - (char *)tmpfilnam[mlsdepth], - (char *)whicharg, - "wb", - 0, - 0, - NULL, - xlate, - lcs, - rcs - ); - if (x < 0) { /* Chosen method wasn't accepted */ - if (forced) { - if (ftpcode > 500 && ftpcode < 505 && !quiet) - printf("?%s: Not supported by server\n", - mgetmethod == SND_MLS ? "MLSD" : "NLST" - ); - rfrc = -2; /* Fail */ - return(NULL); - } - /* Not forced - if MLSD failed, try NLST */ - if (mgetmethod == SND_MLS) { /* Server lied about MLST */ - sfttab[SFT_MLST] = 0; /* So disable it */ - mlstok = 0; /* and */ - mgetmethod = SND_NLS; /* try NLST */ - continue; - } - rfrc = -2; - return(NULL); - } - } -#ifdef FTP_PROXY - if (proxy_switch) { - pswitch(!proxy); - } -#endif /* FTP_PROXY */ - tmpfilptr[mlsdepth] = fopen((char *)tmpfilnam[mlsdepth], "r"); -#ifndef OS2 - if (tmpfilptr[mlsdepth]) { - if (!ftp_deb && !deblog) - unlink(tmpfilnam[mlsdepth]); - } -#endif /* OS2 */ - notemp: - if (!tmpfilptr[mlsdepth]) { - debug(F110,"ftp remote_files open fail",tmpfilnam[mlsdepth],0); - if ((!dpyactive || ftp_deb)) - printf("?Can't find list of remote files, oops\n"); - rfrc = -9; - return(NULL); - } - if (ftp_deb) - printf("LISTFILE: %s\n",tmpfilnam[mlsdepth]); - } - buf[0] = NUL; - buf[FTPNAMBUFLEN-1] = NUL; - buf[FTPNAMBUFLEN-2] = NUL; - - /* We have to redo all this because the first time was only for */ - /* for getting the file list, now it's for getting each file */ - - if (arg && mgetmethod == SND_MLS) { /* MLSD */ - if (!pattern && iswild((char *)arg)) { - pattern = arg; /* Wild arg is really a pattern */ - if (pattern) - if (!*pattern) - pattern = NULL; - arg = NULL; /* and not an arg */ - } - if (new_query) { /* Initial query? */ - cdto = (char *)arg; /* (nonwild) arg given? */ - if (cdto) - if (!*cdto) - cdto = NULL; - if (cdto) /* If so, then CD to it */ - doftpcwd(cdto,0); - } - } - new_query = 0; - - if (fgets((char *)buf, FTPNAMBUFLEN, tmpfilptr[mlsdepth]) == NULL) { - fclose(tmpfilptr[mlsdepth]); - tmpfilptr[mlsdepth] = NULL; - -#ifdef OS2 - if (!ftp_deb && !deblog) - unlink(tmpfilnam[mlsdepth]); -#endif /* OS2 */ - if (ftp_deb && !deblog) { - printf("(Temporary file %s NOT deleted)\n", - (char *)tmpfilnam[mlsdepth]); - } - if (mlsdepth <= 0) { /* EOF at depth 0 */ - rfrc = -3; /* means we're done */ - return(NULL); - } - printf("POPPING(%d)...\n",mlsdepth-1); - if (tmpfilnam[mlsdepth]) free(tmpfilnam[mlsdepth]); - mlsdepth--; - doftpcdup(); - zchdir(".."); /* <-- Not portable */ - goto again; - } - if (buf[FTPNAMBUFLEN-1]) { - printf("?BUFFER OVERFLOW -- FTP NLST or MLSD string longer than %d\n", - FTPNAMBUFLEN - ); - debug(F101,"remote_files buffer overrun","",FTPNAMBUFLEN); - return(NULL); - } - /* debug(F110,"ftp remote_files buf 1",buf,0); */ - if ((cp = (CHAR *)ckstrchr((char *)buf,'\n')) != NULL) - *cp = '\0'; - if ((cp = (CHAR *)ckstrchr((char *)buf,'\r')) != NULL) - *cp = '\0'; - debug(F110,"ftp remote_files buf",buf,0); - rfrc = 0; - - if (ftp_deb) - printf("[%s]\n",(char *)buf); - - havesize = -1L; /* Initialize file facts... */ - havetype = -0; - makestr(&havemdtm,NULL); - p = (char *)buf; - - if (mgetmethod == SND_NLS) { /* NLST... */ - if (pattern) { - if (!ckmatch((char *)pattern,p,(servertype == SYS_UNIX),1)) - goto again; - } - } else { /* MLSD... */ - p = parsefacts((char *)buf); - switch (havetype) { - case FTYP_FILE: /* File: Get it if it matches */ - if (pattern) { - if (!ckmatch((char *)pattern,p,(servertype == SYS_UNIX),1)) - goto again; - } - break; - case FTYP_CDIR: /* Current directory */ - case FTYP_PDIR: /* Parent directory */ - goto again; /* Skip */ - case FTYP_DIR: /* (Sub)Directory */ - if (!recursive) /* If not /RECURSIVE */ - goto again; /* Skip */ - if (mlsdepth < MLSDEPTH) { - char * p2 = NULL; - mlsdepth++; - printf("RECURSING [%s](%d)...\n",p,mlsdepth); - if (doftpcwd(p,0) > 0) { - int x; - if (!ckstrchr(p,'/')) { - /* zmkdir() needs dirsep */ - if ((p2 = (char *)malloc((int)strlen(p) + 2))) { - strcpy(p2,p); /* SAFE */ - strcat(p2,"/"); /* SAFE */ - p = p2; - } - } -#ifdef NOMKDIR - x = -1; -#else - x = zmkdir(p); -#endif /* NOMKDIR */ - if (x > -1) { - zchdir(p); - p = (char *)remote_files(1,arg,pattern,0); - if (p2) free(p2); - } else { - printf("?mkdir failed: [%s] Depth=%d\n", - p, - mlsdepth - ); - mlsreset(); - if (p2) free(p2); - return(NULL); - } - } else { - printf("?CWD failed: [%s] Depth=%d\n",p,mlsdepth); - mlsreset(); - return(NULL); - } - } else { - printf("MAX DIRECTORY STACK DEPTH EXCEEDED: %d\n", - mlsdepth - ); - mlsreset(); - return(NULL); - } - } - } - -#ifdef DEBUG - if (deblog) { - debug(F101,"remote_files havesize","",havesize); - debug(F101,"remote_files havetype","",havetype); - debug(F110,"remote_files havemdtm",havemdtm,0); - debug(F110,"remote_files name",p,0); - } -#endif /* DEBUG */ - return((CHAR *)p); -} - -/* N O T P O R T A B L E !!! */ - -#if (SIZEOF_SHORT == 4) -typedef unsigned short ftp_uint32; -typedef short ftp_int32; -#else -#if (SIZEOF_INT == 4) -typedef unsigned int ftp_uint32; -typedef int ftp_int32; -#else -#if (SIZEOF_LONG == 4) -typedef ULONG ftp_uint32; -typedef long ftp_int32; -#endif -#endif -#endif - -/* Perhaps use these in general, certainly use them for GSSAPI */ - -#ifndef looping_write -#define ftp_int32 int -#define ftp_uint32 unsigned int -static int -looping_write(fd, buf, len) - int fd; - register CONST char *buf; - int len; -{ - int cc; - register int wrlen = len; - do { - cc = send(fd, (SENDARG2TYPE)buf, wrlen, 0); - if (cc < 0) { - if (errno == EINTR) - continue; - return(cc); - } else { - buf += cc; - wrlen -= cc; - } - } while (wrlen > 0); - return(len); -} -#endif -#ifndef looping_read -static int -looping_read(fd, buf, len) - int fd; - register char *buf; - register int len; -{ - int cc, len2 = 0; - - do { - cc = recv(fd, (char *)buf, len,0); - if (cc < 0) { - if (errno == EINTR) - continue; - return(cc); /* errno is already set */ - } else if (cc == 0) { - return(len2); - } else { - buf += cc; - len2 += cc; - len -= cc; - } - } while (len > 0); - return(len2); -} -#endif /* looping_read */ - -#define ERR -2 - -#ifdef COMMENT -static -secure_putbyte(fd, c) int fd; CHAR c; { - int ret; - - ucbuf[nout++] = c; - if (nout == (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR) { - nout = 0; - if (!ftpissecure()) - ret = send(fd, (SENDARG2TYPE)ucbuf, - (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR, 0); - else - ret = secure_putbuf(fd, - ucbuf, - (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR - ); - return(ret?ret:c); - } - return(c); -} -#endif /* COMMENT */ - -/* returns: - * 0 on success - * -1 on error (errno set) - * -2 on security error - */ -static int -secure_flush(fd) int fd; { - int rc = 0; - int len = 0; - - if (nout > 0) { - len = nout; - if (!ftpissecure()) { - rc = send(fd, (SENDARG2TYPE)ucbuf, nout, 0); - nout = 0; - goto xflush; - } else { - rc = secure_putbuf(fd, ucbuf, nout); - if (rc) - goto xflush; - } - } - rc = (!ftpissecure()) ? 0 : secure_putbuf(fd, (CHAR *)"", nout = 0); - - xflush: - if (rc > -1 && len > 0 && fdispla != XYFD_B) { - spackets++; - spktl = len; - ftscreen(SCR_PT,'D',spackets,NULL); - } - return(rc); -} - -#ifdef COMMENT /* (not used) */ -/* returns: - * c>=0 on success - * -1 on error - * -2 on security error - */ -static int -#ifdef CK_ANSIC -secure_putc(char c, int fd) -#else -secure_putc(c, fd) char c; int fd; -#endif /* CK_ANSIC */ -/* secure_putc */ { - return(secure_putbyte(fd, (CHAR) c)); -} -#endif /* COMMENT */ - -/* returns: - * nbyte on success - * -1 on error (errno set) - * -2 on security error - */ -static int -#ifdef CK_ANSIC -secure_write(int fd, CHAR * buf, unsigned int nbyte) -#else -secure_write(fd, buf, nbyte) - int fd; - CHAR * buf; - unsigned int nbyte; -#endif /* CK_ANSIC */ -{ - int ret; - - if (!ftpissecure()) { - if (nout > 0) { - if ((ret = send(fd, (SENDARG2TYPE)ucbuf, nout, 0)) < 0) - return(ret); - nout = 0; - } - return(send(fd,(SENDARG2TYPE)buf,nbyte,0)); - } else { - int ucbuflen = (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR; - int bsent = 0; - - while (bsent < nbyte) { - int b2cp = ((nbyte - bsent) > (ucbuflen - nout) ? - (ucbuflen - nout) : (nbyte - bsent)); -#ifdef DEBUG - if (deblog) { - debug(F101,"secure_write ucbuflen","",ucbuflen); - debug(F101,"secure_write ucbufsiz","",ucbufsiz); - debug(F101,"secure_write bsent","",bsent); - debug(F101,"secure_write b2cp","",b2cp); - } -#endif /* DEBUG */ - memcpy(&ucbuf[nout],&buf[bsent],b2cp); - nout += b2cp; - bsent += b2cp; - - if (nout == ucbuflen) { - nout = 0; - ret = secure_putbuf(fd, ucbuf, ucbuflen); - if (ret < 0) - return(ret); - } - } - return(bsent); - } -} - -/* returns: - * 0 on success - * -1 on error (errno set) - * -2 on security error - */ -static int -#ifdef CK_ANSIC -secure_putbuf(int fd, CHAR * buf, unsigned int nbyte) -#else -secure_putbuf(fd, buf, nbyte) int fd; CHAR * buf; unsigned int nbyte; -#endif /* CK_ANSIC */ -{ - static char *outbuf = NULL; /* output ciphertext */ -#ifdef FTP_SECURITY - static unsigned int bufsize = 0; /* size of outbuf */ -#endif /* FTP_SECURITY */ - ftp_int32 length = 0; - ftp_uint32 net_len = 0; - - /* Other auth types go here ... */ -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - int count, error; - - /* there is no need to send an empty buffer when using SSL/TLS */ - if ( nbyte == 0 ) - return(0); - - count = SSL_write(ssl_ftp_data_con, buf, nbyte); - error = SSL_get_error(ssl_ftp_data_con,count); - switch (error) { - case SSL_ERROR_NONE: - return(0); - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - case SSL_ERROR_SYSCALL: -#ifdef NT - { - int gle = GetLastError(); - if (gle == 0) - return(0); - debug(F111,"secure_putbuf","SSL_ERROR_SYSCALL",gle); - } -#endif /* NT */ - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - return(-1); - } - return(-1); - } -#endif /* CK_SSL */ - -#ifdef FTP_SRP - if (ck_srp_is_installed() && (strcmp(auth_type, "SRP") == 0)) { - if (bufsize < nbyte + FUDGE_FACTOR) { - if (outbuf? - (outbuf = realloc(outbuf, (unsigned) (nbyte + FUDGE_FACTOR))): - (outbuf = malloc((unsigned) (nbyte + FUDGE_FACTOR)))) { - bufsize = nbyte + FUDGE_FACTOR; - } else { - bufsize = 0; - secure_error("%s (in malloc of PROT buffer)", ck_errstr()); - return(ERR); - } - } - if ((length = - srp_encode(ftp_dpl == FPL_PRV, - (CHAR *) buf, - (CHAR *) outbuf, - nbyte - ) - ) < 0) { - secure_error ("srp_encode failed"); - return ERR; - } - } -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 - if (ck_krb4_is_installed() && (strcmp(auth_type, "KERBEROS_V4") == 0)) { - struct sockaddr_in myaddr, hisaddr; - GSOCKNAME_T len; - len = sizeof(myaddr); - if (getsockname(fd, (struct sockaddr*)&myaddr, &len) < 0) { - secure_error("secure_putbuf: getsockname failed"); - return(ERR); - } - len = sizeof(hisaddr); - if (getpeername(fd, (struct sockaddr*)&hisaddr, &len) < 0) { - secure_error("secure_putbuf: getpeername failed"); - return(ERR); - } - if (bufsize < nbyte + FUDGE_FACTOR) { - if (outbuf ? - (outbuf = realloc(outbuf, (unsigned) (nbyte + FUDGE_FACTOR))): - (outbuf = malloc((unsigned) (nbyte + FUDGE_FACTOR)))) { - bufsize = nbyte + FUDGE_FACTOR; - } else { - bufsize = 0; - secure_error("%s (in malloc of PROT buffer)", ck_errstr()); - return(ERR); - } - } - if (ftp_dpl == FPL_PRV) { - length = krb_mk_priv(buf, (CHAR *) outbuf, nbyte, - ftp_sched, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &myaddr, - &hisaddr - ); - } else { - length = krb_mk_safe(buf, (CHAR *) outbuf, nbyte, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &myaddr, - &hisaddr - ); - } - if (length == -1) { - secure_error("krb_mk_%s failed for KERBEROS_V4", - ftp_dpl == FPL_PRV ? "priv" : "safe"); - return(ERR); - } - } -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - if (ck_gssapi_is_installed() && (strcmp(auth_type, "GSSAPI") == 0)) { - gss_buffer_desc in_buf, out_buf; - OM_uint32 maj_stat, min_stat; - int conf_state; - - in_buf.value = buf; - in_buf.length = nbyte; - maj_stat = gss_seal(&min_stat, gcontext, - (ftp_dpl == FPL_PRV), /* confidential */ - GSS_C_QOP_DEFAULT, - &in_buf, - &conf_state, - &out_buf - ); - if (maj_stat != GSS_S_COMPLETE) { - /* generally need to deal */ - /* ie. should loop, but for now just fail */ - user_gss_error(maj_stat, min_stat, - ftp_dpl == FPL_PRV? - "GSSAPI seal failed": - "GSSAPI sign failed"); - return(ERR); - } - if (bufsize < out_buf.length) { - if (outbuf ? - (outbuf = realloc(outbuf, (unsigned) out_buf.length)): - (outbuf = malloc((unsigned) out_buf.length))) { - bufsize = out_buf.length; - } else { - bufsize = 0; - secure_error("%s (in malloc of PROT buffer)", - ck_errstr()); - return(ERR); - } - } - memcpy(outbuf, out_buf.value, length=out_buf.length); - gss_release_buffer(&min_stat, &out_buf); - } -#endif /* FTP_GSSAPI */ - net_len = htonl((ULONG) length); - if (looping_write(fd, (char *)&net_len, 4) == -1) - return(-1); - if (looping_write(fd, outbuf, length) != length) - return(-1); - return(0); -} - -/* fc = 0 means to get a byte; nonzero means to initialize buffer pointers */ - -static int -secure_getbyte(fd,fc) int fd,fc; { - /* number of chars in ucbuf, pointer into ucbuf */ - static unsigned int nin = 0, bufp = 0; - int kerror; - ftp_uint32 length; - - if (fc) { - nin = bufp = 0; - ucbuf[0] = NUL; - return(0); - } - if (nin == 0) { - if (iscanceled()) - return(-9); -#ifdef CK_SSL - if (ssl_ftp_data_active_flag) { - int count, error; - count = SSL_read(ssl_ftp_data_con, ucbuf, ucbufsiz); - error = SSL_get_error(ssl_ftp_data_con,count); - switch (error) { - case SSL_ERROR_NONE: - nin = bufp = count; - rpackets++; - pktnum++; - if (fdispla != XYFD_B) { - rpktl = count; - ftscreen(SCR_PT,'D',rpackets,NULL); - } - break; - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - case SSL_ERROR_SYSCALL: -#ifdef NT - { - int gle = GetLastError(); - } -#endif /* NT */ - case SSL_ERROR_WANT_X509_LOOKUP: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - nin = bufp = count = 0; - SSL_shutdown(ssl_ftp_data_con); - SSL_free(ssl_ftp_data_con); - ssl_ftp_data_active_flag = 0; - ssl_ftp_data_con = NULL; -#ifdef TCPIPLIB - socket_close(data); -#else /* TCPIPLIB */ -#ifdef USE_SHUTDOWN - shutdown(data, 1+1); -#endif /* USE_SHUTDOWN */ - close(data); -#endif /* TCPIPLIB */ - data = -1; - globaldin = data; - break; - } - } else -#endif /* CK_SSL */ - { - kerror = looping_read(fd, (char *)&length, sizeof(length)); - if (kerror != sizeof(length)) { - secure_error("Couldn't read PROT buffer length: %d/%s", - kerror, - kerror == -1 ? ck_errstr() - : "premature EOF" - ); - return(ERR); - } - debug(F101,"secure_getbyte length","",length); - debug(F101,"secure_getbyte ntohl(length)","",ntohl(length)); - - length = (ULONG) ntohl(length); - if (length > maxbuf) { - secure_error("Length (%d) of PROT buffer > PBSZ=%u", - length, - maxbuf - ); - return(ERR); - } - if ((kerror = looping_read(fd, ucbuf, length)) != length) { - secure_error("Couldn't read %u byte PROT buffer: %s", - length, - kerror == -1 ? ck_errstr() : "premature EOF" - ); - return(ERR); - } - - /* Other auth types go here ... */ -#ifdef FTP_SRP - if (strcmp(auth_type, "SRP") == 0) { - if ((nin = bufp = srp_decode (ftp_dpl == FPL_PRV, - (CHAR *) ucbuf, - ucbuf, - length - ) - ) == -1) { - secure_error ("srp_encode failed" ); - return ERR; - } - } -#endif /* FTP_SRP */ -#ifdef FTP_KRB4 - if (strcmp(auth_type, "KERBEROS_V4") == 0) { - struct sockaddr_in myaddr, hisaddr; - GSOCKNAME_T len; - len = sizeof(myaddr); - if (getsockname(fd, (struct sockaddr*)&myaddr, &len) < 0) { - secure_error("secure_putbuf: getsockname failed"); - return(ERR); - } - len = sizeof(hisaddr); - if (getpeername(fd, (struct sockaddr*)&hisaddr, &len) < 0) { - secure_error("secure_putbuf: getpeername failed"); - return(ERR); - } - if (ftp_dpl) { - kerror = krb_rd_priv(ucbuf, length, ftp_sched, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &hisaddr, &myaddr, &ftp_msg_data); - } else { - kerror = krb_rd_safe(ucbuf, length, -#ifdef KRB524 - ftp_cred.session, -#else /* KRB524 */ - &ftp_cred.session, -#endif /* KRB524 */ - &hisaddr, &myaddr, &ftp_msg_data); - } - if (kerror) { - secure_error("krb_rd_%s failed for KERBEROS_V4 (%s)", - ftp_dpl == FPL_PRV ? "priv" : "safe", - krb_get_err_text(kerror)); - return(ERR); - } - memcpy(ucbuf,ftp_msg_data.app_data,ftp_msg_data.app_length); - nin = bufp = ftp_msg_data.app_length; - } -#endif /* FTP_KRB4 */ -#ifdef FTP_GSSAPI - if (strcmp(auth_type, "GSSAPI") == 0) { - gss_buffer_desc xmit_buf, msg_buf; - OM_uint32 maj_stat, min_stat; - int conf_state; - - xmit_buf.value = ucbuf; - xmit_buf.length = length; - conf_state = (ftp_dpl == FPL_PRV); - /* decrypt/verify the message */ - maj_stat = gss_unseal(&min_stat, gcontext, &xmit_buf, - &msg_buf, &conf_state, NULL); - if (maj_stat != GSS_S_COMPLETE) { - user_gss_error(maj_stat, min_stat, - (ftp_dpl == FPL_PRV)? - "failed unsealing ENC message": - "failed unsealing MIC message"); - return ERR; - } - memcpy(ucbuf, msg_buf.value, nin = bufp = msg_buf.length); - gss_release_buffer(&min_stat, &msg_buf); - } -#endif /* FTP_GSSAPI */ - /* Other auth types go here ... */ - - /* Update file transfer display */ - rpackets++; - pktnum++; - if (fdispla != XYFD_B) { - rpktl = nin; - ftscreen(SCR_PT,'D',rpackets,NULL); - } - } - } - if (nin == 0) - return(EOF); - else - return(ucbuf[bufp - nin--]); -} - -/* secure_getc(fd,fc) - * Call with: - * fd = file descriptor for connection. - * fc = 0 to get a character, fc != 0 to initialize buffer pointers. - * Returns: - * c>=0 on success (character value) - * -1 on EOF - * -2 on security error - */ -static int -secure_getc(fd,fc) int fd,fc; { /* file descriptor, function code */ - if (!ftpissecure()) { - static unsigned int nin = 0, bufp = 0; - if (fc) { - nin = bufp = 0; - ucbuf[0] = NUL; - return(0); - } - if (nin == 0) { - if (iscanceled()) - return(-9); - nin = bufp = recv(fd,(char *)ucbuf,actualbuf,0); - if (nin <= 0) { - debug(F111,"secure_getc recv errno",ckitoa(nin),errno); - debug(F101,"secure_getc returns EOF","",EOF); - nin = bufp = 0; - return(EOF); - } - debug(F101,"ftp secure_getc recv","",nin); - hexdump("ftp secure_getc recv",ucbuf,16); - rpackets++; - pktnum++; - if (fdispla != XYFD_B) { - rpktl = nin; - ftscreen(SCR_PT,'D',rpackets,NULL); - } - } - return(ucbuf[bufp - nin--]); - } else - return(secure_getbyte(fd,fc)); -} - -/* returns: - * n>0 on success (n == # of bytes read) - * 0 on EOF - * -1 on error (errno set), only for FPL_CLR - * -2 on security error - */ -static int -secure_read(fd, buf, nbyte) int fd; char *buf; int nbyte; { - static int c = 0; - int i; - - debug(F101,"secure_read bytes requested","",nbyte); - if (c == EOF) - return(c = 0); - for (i = 0; nbyte > 0; nbyte--) { - c = secure_getc(fd,0); - switch (c) { - case -9: /* Canceled from keyboard */ - debug(F101,"ftp secure_read interrupted","",c); - return(0); - case ERR: - debug(F101,"ftp secure_read error","",c); - return(c); - case EOF: - debug(F101,"ftp secure_read EOF","",c); - if (!i) - c = 0; - return(i); - default: - buf[i++] = c; - } - } - return(i); -} - -#ifdef USE_RUSERPASS -/* BEGIN_RUSERPASS - * - * Copyright (c) 1985 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)ruserpass.c 5.3 (Berkeley) 3/1/91"; -#endif /* not lint */ - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -char * renvlook(); -static FILE * cfile; - -#define DEFAULT 1 -#define LOGIN 2 -#define PASSWD 3 -#define ACCOUNT 4 -#define MACDEF 5 -#define ID 10 -#define MACH 11 - -static char tokval[100]; - -static struct toktab { - char *tokstr; - int tval; -} toktab[]= { - "default", DEFAULT, - "login", LOGIN, - "password", PASSWD, - "passwd", PASSWD, - "account", ACCOUNT, - "machine", MACH, - "macdef", MACDEF, - 0, 0 -}; - -static int -token() { - char *cp; - int c; - struct toktab *t; - - if (feof(cfile)) - return(0); - while ((c = getc(cfile)) != EOF && - (c == '\n' || c == '\t' || c == ' ' || c == ',')) - continue; - if (c == EOF) - return(0); - cp = tokval; - if (c == '"') { - while ((c = getc(cfile)) != EOF && c != '"') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - } - } else { - *cp++ = c; - while ((c = getc(cfile)) != EOF - && c != '\n' && c != '\t' && c != ' ' && c != ',') { - if (c == '\\') - c = getc(cfile); - *cp++ = c; - } - } - *cp = 0; - if (tokval[0] == 0) - return(0); - for (t = toktab; t->tokstr; t++) - if (!strcmp(t->tokstr, tokval)) - return(t->tval); - return(ID); -} - -ruserpass(host, aname, apass, aacct) - char *host, **aname, **apass, **aacct; -{ - char *hdir, buf[FTP_BUFSIZ], *tmp; - char myname[MAXHOSTNAMELEN], *mydomain; - int t, i, c, usedefault = 0; -#ifdef NT - struct _stat stb; -#else /* NT */ - struct stat stb; -#endif /* NT */ - - hdir = getenv("HOME"); - if (hdir == NULL) - hdir = "."; - ckmakmsg(buf,FTP_BUFSIZ,hdir,"/.netrc",NULL,NULL); - cfile = fopen(buf, "r"); - if (cfile == NULL) { - if (errno != ENOENT) - perror(buf); - return(0); - } - if (gethostname(myname, MAXHOSTNAMELEN) < 0) - myname[0] = '\0'; - if ((mydomain = ckstrchr(myname, '.')) == NULL) - mydomain = ""; - - next: - while ((t = token())) switch(t) { - - case DEFAULT: - usedefault = 1; - /* FALL THROUGH */ - - case MACH: - if (!usedefault) { - if (token() != ID) - continue; - /* - * Allow match either for user's input host name - * or official hostname. Also allow match of - * incompletely-specified host in local domain. - */ - if (ckstrcmp(host, tokval,-1,1) == 0) - goto match; - if (ckstrcmp(ftp_host, tokval,-1,0) == 0) - goto match; - if ((tmp = ckstrchr(ftp_host, '.')) != NULL && - ckstrcmp(tmp, mydomain,-1,1) == 0 && - ckstrcmp(ftp_host, tokval, tmp-ftp_host,0) == 0 && - tokval[tmp - ftp_host] == '\0') - goto match; - if ((tmp = ckstrchr(host, '.')) != NULL && - ckstrcmp(tmp, mydomain,-1,1) == 0 && - ckstrcmp(host, tokval, tmp - host, 0) == 0 && - tokval[tmp - host] == '\0') - goto match; - continue; - } - - match: - while ((t = token()) && t != MACH && t != DEFAULT) switch(t) { - - case LOGIN: - if (token()) - if (*aname == 0) { - *aname = malloc((unsigned) strlen(tokval) + 1); - strcpy(*aname, tokval); /* safe */ - } else { - if (strcmp(*aname, tokval)) - goto next; - } - break; - case PASSWD: - if (strcmp(*aname, "anonymous") && - fstat(fileno(cfile), &stb) >= 0 && - (stb.st_mode & 077) != 0) { - fprintf(stderr, "Error - .netrc file not correct mode.\n"); - fprintf(stderr, "Remove password or correct mode.\n"); - goto bad; - } - if (token() && *apass == 0) { - *apass = malloc((unsigned) strlen(tokval) + 1); - strcpy(*apass, tokval); /* safe */ - } - break; - case ACCOUNT: - if (fstat(fileno(cfile), &stb) >= 0 - && (stb.st_mode & 077) != 0) { - fprintf(stderr, "Error - .netrc file not correct mode.\n"); - fprintf(stderr, "Remove account or correct mode.\n"); - goto bad; - } - if (token() && *aacct == 0) { - *aacct = malloc((unsigned) strlen(tokval) + 1); - strcpy(*aacct, tokval); /* safe */ - } - break; - - default: - fprintf(stderr, "Unknown .netrc keyword %s\n", tokval); - break; - } - goto done; - } - - done: - fclose(cfile); - return(0); - - bad: - fclose(cfile); - return(-1); -} -#endif /* USE_RUSERPASS */ - -static char *radixN = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static char pad = '='; - -static int -radix_encode(inbuf, outbuf, inlen, outlen, decode) - CHAR inbuf[], outbuf[]; - int inlen, *outlen, decode; -{ - int i, j, D = 0; - char *p; - CHAR c = NUL; - - if (decode) { - for (i = 0, j = 0; inbuf[i] && inbuf[i] != pad; i++) { - if ((p = ckstrchr(radixN, inbuf[i])) == NULL) - return(1); - D = p - radixN; - switch (i&3) { - case 0: - outbuf[j] = D<<2; - break; - case 1: - outbuf[j++] |= D>>4; - outbuf[j] = (D&15)<<4; - break; - case 2: - outbuf[j++] |= D>>2; - outbuf[j] = (D&3)<<6; - break; - case 3: - outbuf[j++] |= D; - } - if (j == *outlen) - return(4); - } - switch (i&3) { - case 1: return(3); - case 2: if (D&15) return(3); - if (strcmp((char *)&inbuf[i], "==")) return(2); - break; - case 3: if (D&3) return(3); - if (strcmp((char *)&inbuf[i], "=")) return(2); - } - *outlen = j; - } else { - for (i = 0, j = 0; i < inlen; i++) { - switch (i%3) { - case 0: - outbuf[j++] = radixN[inbuf[i]>>2]; - c = (inbuf[i]&3)<<4; - break; - case 1: - outbuf[j++] = radixN[c|inbuf[i]>>4]; - c = (inbuf[i]&15)<<2; - break; - case 2: - outbuf[j++] = radixN[c|inbuf[i]>>6]; - outbuf[j++] = radixN[inbuf[i]&63]; - c = 0; - } - if (j == *outlen) - return(4); - } - if (i%3) outbuf[j++] = radixN[c]; - switch (i%3) { - case 1: outbuf[j++] = pad; - case 2: outbuf[j++] = pad; - } - outbuf[*outlen = j] = '\0'; - } - return(0); -} - -static char * -radix_error(e) int e; -{ - switch (e) { - case 0: return("Success"); - case 1: return("Bad character in encoding"); - case 2: return("Encoding not properly padded"); - case 3: return("Decoded # of bits not a multiple of 8"); - case 4: return("Output buffer too small"); - default: return("Unknown error"); - } -} -/* END_RUSERPASS */ - -#ifdef FTP_SRP -/*---------------------------------------------------------------------------+ - | | - | Package: srpftp | - | Author: Eugene Jhong | - | | - +---------------------------------------------------------------------------*/ - -/* - * Copyright (c) 1997-1999 The Stanford SRP Authentication Project - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - * - * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * In addition, the following conditions apply: - * - * 1. Any software that incorporates the SRP authentication technology - * must display the following acknowlegment: - * "This product uses the 'Secure Remote Password' cryptographic - * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)." - * - * 2. Any software that incorporates all or part of the SRP distribution - * itself must also display the following acknowledgment: - * "This product includes software developed by Tom Wu and Eugene - * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)." - * - * 3. Redistributions in source or binary form must retain an intact copy - * of this copyright notice and list of conditions. - */ - -#define SRP_PROT_VERSION 1 - -#ifdef CK_ENCRYPTION -#define SRP_DEFAULT_CIPHER CIPHER_ID_CAST5_CBC -#else -#define SRP_DEFAULT_CIPHER CIPHER_ID_NONE -#endif /* CK_ENCRYPTION */ - -#define SRP_DEFAULT_HASH HASH_ID_SHA - -CHAR srp_pref_cipher = CIPHER_ID_DES3_ECB; -CHAR srp_pref_hash = HASH_ID_SHA; - -static struct t_client *tc = NULL; -static CHAR *skey = NULL; -static krypto_context *incrypt = NULL; -static krypto_context *outcrypt = NULL; - -typedef unsigned int srp_uint32; - -/*--------------------------------------------------------------+ - | srp_selcipher: select cipher | - +--------------------------------------------------------------*/ -static int -srp_selcipher (cname) char *cname; { - cipher_desc *cd; - - if (!(cd = cipher_getdescbyname (cname))) { - int i; - CHAR *list = cipher_getlist (); - - fprintf (stderr, "ftp: supported ciphers:\n\n"); - for (i = 0; i < strlen (list); i++) - fprintf (stderr, " %s\n", (cipher_getdescbyid(list[i]))->name); - fprintf (stderr, "\n"); - return -1; - } - srp_pref_cipher = cd->id; - return 0; -} - -/*--------------------------------------------------------------+ - | srp_selhash: select hash | - +--------------------------------------------------------------*/ -static int -srp_selhash (hname) char *hname; { - hash_desc *hd; - - if (!(hd = hash_getdescbyname (hname))) { - int i; - CHAR *list = hash_getlist (); - - fprintf (stderr, "ftp: supported hash functions:\n\n"); - for (i = 0; i < strlen (list); i++) - fprintf (stderr, " %s\n", (hash_getdescbyid(list[i]))->name); - fprintf (stderr, "\n"); - return -1; - } - srp_pref_hash = hd->id; - return 0; -} - -/*--------------------------------------------------------------+ - | srp_userpass: get username and password | - +--------------------------------------------------------------*/ -static int -srp_userpass (host) char *host; { - char tmp[BUFSIZ], prompt[PROMPTSIZ]; - char *user; - - user = NULL; -#ifdef USE_RUSERPASS - ruserpass (host, &user, &srp_pass, &srp_acct); -#endif /* USE_RUSERPASS */ - - while (user == NULL) { - char *myname; - int ok; - - myname = whoami(); - if (!myname) myname = ""; - if (myname[0]) - ckmakxmsg(prompt,PROMPTSIZ," Name (",host,":",myname,"): ", - NULL,NULL,NULL,NULL,NULL,NULL,NULL); - else - ckmakmsg(prompt,PROMPTSIZ," Name (",host,"): ",NULL); - tmp[0] = '\0'; - ok = uq_txt(NULL,prompt,1,NULL,tmp,BUFSIZ,NULL, - DEFAULT_UQ_TIMEOUT); - if (!ok || *tmp == '\0') - user = myname; - else - user = brstrip(tmp); - } - ckstrncpy (srp_user, user,BUFSIZ); - return(0); -} - -/*--------------------------------------------------------------+ - | srp_reset: reset srp information | - +--------------------------------------------------------------*/ -static int -srp_reset () { - if (tc) { t_clientclose (tc); tc = NULL; } - if (incrypt) { krypto_delete (incrypt); incrypt = NULL; } - if (outcrypt) { krypto_delete (outcrypt); outcrypt = NULL; } - return(0); -} - -/*--------------------------------------------------------------+ - | srp_ftp_auth: perform srp authentication | - +--------------------------------------------------------------*/ -static int -srp_ftp_auth(host, user, pass) - char *host; - char *user; - char *pass; -{ - struct t_num *wp; - struct t_num N; - struct t_num g; - struct t_num s; - struct t_num yp; - CHAR buf[FTP_BUFSIZ]; - CHAR tmp[FTP_BUFSIZ]; - CHAR *bp, *cp; - int n, e, clen, blen, len, i; - CHAR cid = 0; - CHAR hid = 0; - - srp_pass = srp_acct = 0; - - n = ftpcmd("AUTH SRP",NULL,0,0,ftp_vbm); - if (n != REPLY_CONTINUE) { - if (ftp_deb) - fprintf(stderr, "SRP rejected as an authentication type\n"); - return(0); - } else { /* Send protocol version */ - CHAR vers[4]; - memset (vers, 0, 4); - vers[3] = SRP_PROT_VERSION; - if (!quiet) - printf ("SRP accepted as authentication type.\n"); - bp = tmp; blen = 0; - srp_put (vers, &bp, 4, &blen); - len = FTP_BUFSIZ; - if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE)) - goto encode_error; - reply_parse = "ADAT="; - n = ftpcmd("ADAT",buf,-1,-1,0); - } - if (n == REPLY_CONTINUE) { /* Get protocol version */ - bp = buf; - if (!reply_parse) - goto data_error; - blen = FTP_BUFSIZ; - if (e = radix_encode(reply_parse, bp, 0, &blen, RADIX_DECODE)) - goto decode_error; - if (srp_get (&bp, &cp, &blen, &clen) != 4) - goto data_error; - - if (host) { /* Get username/password if needed */ - srp_userpass (host); - } else { - ckstrncpy (srp_user, user, BUFSIZ); - srp_pass = pass; - } - bp = tmp; blen = 0; /* Send username */ - srp_put (srp_user, &bp, strlen (srp_user), &blen); - len = FTP_BUFSIZ; - if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE)) - goto encode_error; - reply_parse = "ADAT="; - n = ftpcmd("ADAT",buf,-1,-1,0); - } - if (n == REPLY_CONTINUE) { /* Get N, g and s */ - bp = buf; - if (!reply_parse) - goto data_error; - blen = FTP_BUFSIZ; - if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE)) - goto decode_error; - if (srp_get (&bp, &(N.data), &blen, &(N.len)) < 0) - goto data_error; - if (srp_get (&bp, &(g.data), &blen, &(g.len)) < 0) - goto data_error; - if (srp_get (&bp, &(s.data), &blen, &(s.len)) < 0) - goto data_error; - if ((tc = t_clientopen (srp_user, &N, &g, &s)) == NULL) { - fprintf (stderr, "Unable to open SRP client structure.\n"); - goto bad; - } - wp = t_clientgenexp (tc); /* Send wp */ - bp = tmp; blen = 0; - srp_put (wp->data, &bp, wp->len, &blen); - len = FTP_BUFSIZ; - if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE)) - goto encode_error; - reply_parse = "ADAT="; - n = ftpcmd("ADAT",buf,-1,-1,0); - } - if (n == REPLY_CONTINUE) { /* Get yp */ - bp = buf; - if (!reply_parse) - goto data_error; - blen = FTP_BUFSIZ; - if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE)) - goto decode_error; - if (srp_get (&bp, &(yp.data), &blen, &(yp.len)) < 0) - goto data_error; - if (!srp_pass) { - static char ftppass[PASSBUFSIZ]; - int ok; - setint(); - ok = uq_txt(NULL," SRP Password: ",2,NULL,ftppass,PASSBUFSIZ,NULL, - DEFAULT_UQ_TIMEOUT); - if (ok) - srp_pass = brstrip(ftppass); - } - t_clientpasswd (tc, srp_pass); - memset (srp_pass, 0, strlen (srp_pass)); - skey = t_clientgetkey (tc, &yp); /* Send response */ - bp = tmp; blen = 0; - srp_put (t_clientresponse (tc), &bp, 20, &blen); - len = FTP_BUFSIZ; - if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE)) - goto encode_error; - reply_parse = "ADAT="; - n = ftpcmd("ADAT",buf,-1,-1,0); - } - if (n == REPLY_CONTINUE) { /* Get response */ - bp = buf; - if (!reply_parse) - goto data_error; - blen = FTP_BUFSIZ; - if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE)) - goto encode_error; - if (srp_get (&bp, &cp, &blen, &clen) != 20) - goto data_error; - if (t_clientverify (tc, cp)) { - fprintf (stderr, "WARNING: bad response to client challenge.\n"); - goto bad; - } - bp = tmp; blen = 0; /* Send nothing */ - srp_put ("\0", &bp, 1, &blen); - len = FTP_BUFSIZ; - if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE)) - goto encode_error; - reply_parse = "ADAT="; - n = ftpcmd("ADAT",buf,-1,-1,0); - } - if (n == REPLY_CONTINUE) { /* Get cipher & hash lists, seqnum */ - CHAR seqnum[4]; - CHAR *clist; - CHAR *hlist; - CHAR *p1; - int clist_len, hlist_len; - bp = buf; - if (!reply_parse) - goto data_error; - blen = FTP_BUFSIZ; - if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE)) - goto encode_error; - if (srp_get (&bp, &clist, &blen, &clist_len) < 0) - goto data_error; - if (srp_get (&bp, &hlist, &blen, &hlist_len) < 0) - goto data_error; - if (srp_get (&bp, &cp, &blen, &clen) != 4) - goto data_error; - memcpy (seqnum, cp, 4); - if (cipher_supported (clist, srp_pref_cipher)) /* Choose cipher */ - cid = srp_pref_cipher; - if (!cid && cipher_supported (clist, SRP_DEFAULT_CIPHER)) - cid = SRP_DEFAULT_CIPHER; - if (!cid) { - CHAR *loclist = cipher_getlist (); - for (i = 0; i < strlen (loclist); i++) - if (cipher_supported (clist, loclist[i])) { - cid = loclist[i]; - break; - } - } - if (!cid) { - fprintf (stderr, "Unable to agree on cipher.\n"); - goto bad; - } - /* Choose hash */ - - if (srp_pref_hash && hash_supported (hlist, srp_pref_hash)) - hid = srp_pref_hash; - - if (!hid && hash_supported (hlist, SRP_DEFAULT_HASH)) - hid = SRP_DEFAULT_HASH; - - if (!hid) { - CHAR *loclist = hash_getlist (); - for (i = 0; i < strlen (loclist); i++) - if (hash_supported (hlist, loclist[i])) { - hid = loclist[i]; - break; - } - } - if (!hid) { - fprintf (stderr, "Unable to agree on hash.\n"); - goto bad; - } - /* Set incrypt */ - - if (!(incrypt = krypto_new (cid, hid, skey, 20, NULL, 0, seqnum, - KRYPTO_DECODE))) - goto bad; - - /* Generate random number for outkey and outseqnum */ - - t_random (seqnum, 4); - - /* Send cid, hid, outkey, outseqnum */ - - bp = tmp; blen = 0; - srp_put (&cid, &bp, 1, &blen); - srp_put (&hid, &bp, 1, &blen); - srp_put (seqnum, &bp, 4, &blen); - len = FTP_BUFSIZ; - if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE)) - goto encode_error; - reply_parse = "ADAT="; - n = ftpcmd("ADAT",buf,-1,-1,0); - - /* Set outcrypt */ - - if (!(outcrypt = krypto_new (cid, hid, skey+20, 20, NULL, 0, seqnum, - KRYPTO_ENCODE))) - goto bad; - - t_clientclose (tc); - tc = NULL; - } - if (n != REPLY_COMPLETE) - goto bad; - - if (ftp_vbm) { - if (ftp_deb) - printf("\n"); - printf ("SRP authentication succeeded.\n"); - printf ("Using cipher %s and hash function %s.\n", - (cipher_getdescbyid(cid))->name, - (hash_getdescbyid(hid))->name - ); - } - reply_parse = NULL; - auth_type = "SRP"; - return(1); - - encode_error: - fprintf (stderr, "Base 64 encoding failed: %s.\n", radix_error (e)); - goto bad; - - decode_error: - fprintf (stderr, "Base 64 decoding failed: %s.\n", radix_error (e)); - goto bad; - - data_error: - fprintf (stderr, "Unable to unmarshal authentication data.\n"); - goto bad; - - bad: - fprintf (stderr, "SRP authentication failed, trying regular login.\n"); - reply_parse = NULL; - return(0); -} - -/*--------------------------------------------------------------+ - | srp_put: put item to send buffer | - +--------------------------------------------------------------*/ -static int -srp_put (in, out, inlen, outlen) - CHAR *in; - CHAR **out; - int inlen; - int *outlen; -{ - srp_uint32 net_len; - - net_len = htonl (inlen); - memcpy (*out, &net_len, 4); - - *out += 4; *outlen += 4; - - memcpy (*out, in, inlen); - - *out += inlen; *outlen += inlen; - return(0); -} - -/*--------------------------------------------------------------+ - | srp_get: get item from receive buffer | - +--------------------------------------------------------------*/ -static int -srp_get (in, out, inlen, outlen) - CHAR **in; - CHAR **out; - int *inlen; - int *outlen; -{ - srp_uint32 net_len; - - if (*inlen < 4) return -1; - - memcpy (&net_len, *in, 4); *inlen -= 4; *in += 4; - *outlen = ntohl (net_len); - - if (*inlen < *outlen) return -1; - - *out = *in; *inlen -= *outlen; *in += *outlen; - - return *outlen; -} - -/*--------------------------------------------------------------+ - | srp_encode: encode control message | - +--------------------------------------------------------------*/ -static int -srp_encode (private, in, out, len) - int private; - CHAR *in; - CHAR *out; - unsigned len; -{ - if (private) - return krypto_msg_priv (outcrypt, in, out, len); - else - return krypto_msg_safe (outcrypt, in, out, len); -} - -/*--------------------------------------------------------------+ - | srp_decode: decode control message | - +--------------------------------------------------------------*/ -static int -srp_decode (private, in, out, len) - int private; - CHAR *in; - CHAR *out; - unsigned len; -{ - if (private) - return krypto_msg_priv (incrypt, in, out, len); - else - return krypto_msg_safe (incrypt, in, out, len); -} - -#endif /* FTP_SRP */ - - - -#ifdef NOT_USED -/* - The following code is from the Unix FTP client. Be sure to - make sure that the functionality is not lost. Especially - the Proxy stuff even though we have not yet implemented it. -*/ - -/* Send multiple files */ - -static int -ftp_mput(argc, argv) int argc; char **argv; { - register int i; - sig_t oldintr; - int ointer; - char *tp; - sigtype mcancel(); - - if (argc < 2 && !another(&argc, &argv, "local-files")) { - printf("usage: %s local-files\n", argv[0]); - ftpcode = -1; - return; - } - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT, mcancel); - - /* Replace with calls to cc_execute() */ - setjmp(jcancel); -#ifdef FTP_PROXY - if (proxy) { - char *cp, *tp2, tmpbuf[CKMAXPATH]; - - while ((cp = remglob(argv,0)) != NULL) { - if (*cp == 0) { - mflag = 0; - continue; - } - if (mflag && confirm(argv[0], cp)) { - tp = cp; - if (mcase) { - while (*tp && !islower(*tp)) { - tp++; - } - if (!*tp) { - tp = cp; - tp2 = tmpbuf; - while ((*tp2 = *tp) != 0) { - if (isupper(*tp2)) { - *tp2 = 'a' + *tp2 - 'A'; - } - tp++; - tp2++; - } - } - tp = tmpbuf; - } - if (ntflag) { - tp = dotrans(tp); - } - if (mapflag) { - tp = domap(tp); - } - sendrequest((sunique) ? "STOU" : "STOR", cp, tp, 0, -1, -1, 0); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with","mput")) { - mflag++; - } - interactive = ointer; - } - } - } - signal(SIGINT, oldintr); - mflag = 0; - return; - } -#endif /* FTP_PROXY */ - for (i = 1; i < argc; i++) { - register char **cpp, **gargs; - - if (mflag && confirm(argv[0], argv[i])) { - tp = argv[i]; - sendrequest((ftp_usn) ? "STOU" : "STOR", argv[i], tp, 0,-1,-1, 0); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with","mput")) { - mflag++; - } - interactive = ointer; - } - } - continue; - - gargs = ftpglob(argv[i]); - if (globerr != NULL) { - printf("%s\n", globerr); - if (gargs) { - blkfree(gargs); - free((char *)gargs); - } - continue; - } - for (cpp = gargs; cpp && *cpp != NULL; cpp++) { - if (mflag && confirm(argv[0], *cpp)) { - tp = *cpp; - sendrequest((sunique) ? "STOU":"STOR", *cpp, tp, 0, -1, -1, 0); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with","mput")) { - mflag++; - } - interactive = ointer; - } - } - } - if (gargs != NULL) { - blkfree(gargs); - free((char *)gargs); - } - } - signal(SIGINT, oldintr); - mflag = 0; -} - -/* Get multiple files */ - -static int -ftp_mget(argc, argv) int argc; char **argv; { - int rc = -1; - sig_t oldintr; - int ointer; - char *cp, *tp, *tp2, tmpbuf[CKMAXPATH]; - sigtype mcancel(); - - if (argc < 2 && !another(&argc, &argv, "remote-files")) { - printf("usage: %s remote-files\n", argv[0]); - ftpcode = -1; - return(-1); - } - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT,mcancel); - /* Replace with calls to cc_execute() */ - setjmp(jcancel); - while ((cp = remglob(argv,proxy)) != NULL) { - if (*cp == '\0') { - mflag = 0; - continue; - } - if (mflag && confirm(argv[0], cp)) { - tp = cp; - if (mcase) { - while (*tp && !islower(*tp)) { - tp++; - } - if (!*tp) { - tp = cp; - tp2 = tmpbuf; - while ((*tp2 = *tp) != 0) { - if (isupper(*tp2)) { - *tp2 = 'a' + *tp2 - 'A'; - } - tp++; - tp2++; - } - } - tp = tmpbuf; - } - rc = (recvrequest("RETR", tp, cp, "wb", - tp != cp || !interactive) == 0,0,NULL,0,0,0); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with","mget")) { - mflag++; - } - interactive = ointer; - } - } - } - signal(SIGINT,oldintr); - mflag = 0; - return(rc); -} - -/* Delete multiple files */ - -static int -mdelete(argc, argv) int argc; char **argv; { - sig_t oldintr; - int ointer; - char *cp; - sigtype mcancel(); - - if (argc < 2 && !another(&argc, &argv, "remote-files")) { - printf("usage: %s remote-files\n", argv[0]); - ftpcode = -1; - return(-1); - } - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT, mcancel); - /* Replace with calls to cc_execute() */ - setjmp(jcancel); - while ((cp = remglob(argv,0)) != NULL) { - if (*cp == '\0') { - mflag = 0; - continue; - } - if (mflag && confirm(argv[0], cp)) { - rc = (ftpcmd("DELE",cp,-1,-1,ftp_vbm) == REPLY_COMPLETE); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", "mdelete")) { - mflag++; - } - interactive = ointer; - } - } - } - signal(SIGINT, oldintr); - mflag = 0; - return(rc); -} - -/* Get a directory listing of multiple remote files */ - -static int -mls(argc, argv) int argc; char **argv; { - sig_t oldintr; - int ointer, i; - char *cmd, mode[1], *dest; - sigtype mcancel(); - int rc = -1; - - if (argc < 2 && !another(&argc, &argv, "remote-files")) - goto usage; - if (argc < 3 && !another(&argc, &argv, "local-file")) { - usage: - printf("usage: %s remote-files local-file\n", argv[0]); - ftpcode = -1; - return(-1); - } - dest = argv[argc - 1]; - argv[argc - 1] = NULL; - if (strcmp(dest, "-") && *dest != '|') - if (!globulize(&dest) || - !confirm("output to local-file:", dest)) { - ftpcode = -1; - return(-1); - } - cmd = argv[0][1] == 'l' ? "NLST" : "LIST"; - mname = argv[0]; - mflag = 1; - oldintr = signal(SIGINT, mcancel); - /* Replace with calls to cc_execute() */ - setjmp(jcancel); - for (i = 1; mflag && i < argc-1; ++i) { - *mode = (i == 1) ? 'w' : 'a'; - rc = recvrequest(cmd, dest, argv[i], mode, 0,0,NULL,0,0,0); - if (!mflag && fromatty) { - ointer = interactive; - interactive = 1; - if (confirm("Continue with", argv[0])) { - mflag ++; - } - interactive = ointer; - } - } - signal(SIGINT, oldintr); - mflag = 0; - return(rc); -} - -static char * -remglob(argv,doswitch) char *argv[]; int doswitch; { - char temp[16]; - static char buf[CKMAXPATH]; - static FILE *ftemp = NULL; - static char **args; - int oldhash; - char *cp, *mode; - - if (!mflag) { - if (!doglob) { - args = NULL; - } else { - if (ftemp) { - (void) fclose(ftemp); - ftemp = NULL; - } - } - return(NULL); - } - if (!doglob) { - if (args == NULL) - args = argv; - if ((cp = *++args) == NULL) - args = NULL; - return(cp); - } - if (ftemp == NULL) { - (void) strcpy(temp, _PATH_TMP); -#ifdef MKTEMP -#ifndef MKSTEMP - (void) mktemp(temp); -#endif /* MKSTEMP */ -#endif /* MKTEMP */ - verbose = 0; - oldhash = hash, hash = 0; -#ifdef FTP_PROXY - if (doswitch) { - pswitch(!proxy); - } -#endif /* FTP_PROXY */ - for (mode = "wb"; *++argv != NULL; mode = "ab") - recvrequest ("NLST", temp, *argv, mode, 0); -#ifdef FTP_PROXY - if (doswitch) { - pswitch(!proxy); - } -#endif /* FTP_PROXY */ - hash = oldhash; - ftemp = fopen(temp, "r"); - unlink(temp); - if (ftemp == NULL && (!dpyactive || ftp_deb)) { - printf("Can't find list of remote files, oops\n"); - return(NULL); - } - } - if (fgets(buf, CKMAXPATH, ftemp) == NULL) { - fclose(ftemp), ftemp = NULL; - return(NULL); - } - if ((cp = ckstrchr(buf,'\n')) != NULL) - *cp = '\0'; - return(buf); -} -#endif /* NOT_USED */ -#endif /* TCPSOCKET (top of file) */ -#endif /* SYSFTP (top of file) */ -#endif /* NOFTP (top of file) */ diff --git a/.pc/060_speeling.patch/ckcpro.w b/.pc/060_speeling.patch/ckcpro.w deleted file mode 100644 index cd9d1fa..0000000 --- a/.pc/060_speeling.patch/ckcpro.w +++ /dev/null @@ -1,3591 +0,0 @@ -char *protv = /* -*-C-*- */ -"C-Kermit Protocol Module 8.0.158, 11 Sep 2002"; - -int kactive = 0; /* Kermit protocol is active */ - -#define PKTZEROHACK - -/* C K C P R O -- C-Kermit Protocol Module, in Wart preprocessor notation. */ -/* - Author: Frank da Cruz , - Columbia University Academic Information Systems, 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. -*/ -#ifndef NOXFER -#include "ckcsym.h" -#include "ckcdeb.h" -#include "ckcasc.h" -#include "ckcker.h" -#ifdef OS2 -#ifndef NT -#define INCL_NOPM -#define INCL_VIO /* Needed for ckocon.h */ -#include -#undef COMMENT -#endif /* NT */ -#include "ckocon.h" -#endif /* OS2 */ - -/* - Note -- This file may also be preprocessed by the UNIX Lex program, but - you must indent the above #include statements before using Lex, and then - restore them to the left margin in the resulting C program before compilation. - Also, the invocation of the "wart()" function below must be replaced by an - invocation of the "yylex()" function. It might also be necessary to remove - comments in the (%)(%)...(%)(%) section. -*/ - -/* State definitions for Wart (or Lex) */ -%states ipkt rfile rattr rdpkt ssinit ssfile ssattr ssdata sseof sseot -%states serve generic get rgen ssopkt ropkt - -_PROTOTYP(static VOID xxproto,(void)); -_PROTOTYP(static VOID wheremsg,(void)); -_PROTOTYP(int wart,(void)); -_PROTOTYP(static int sgetinit,(int,int)); -_PROTOTYP(int sndspace,(int)); - -/* External C-Kermit variable declarations */ - extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist, *rf_err; - extern char * rfspec, * sfspec, * srfspec, * rrfspec; - extern char * prfspec, * psfspec, * psrfspec, * prrfspec; - extern char *cdmsgfile[]; - extern char * snd_move, * snd_rename, * srimsg; - extern char filnam[], ofilnam[], fspec[], ttname[], ofn1[]; - extern CHAR sstate, *srvptr, *data; - extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network; - extern int oopts, omode, oname, opath, nopush, isguest, xcmdsrc, rcdactive; - extern int rejection, moving, fncact, bye_active, urserver, fatalio; - extern int protocol, prefixing, filcnt, carrier, fnspath, interrupted; - extern int recursive, inserver, nzxopts, idletmo, srvidl, xfrint; - extern struct ck_p ptab[]; - extern int remfile, rempipe, xferstat, filestatus, wearealike, fackpath; - extern int patterns, filepeek, gnferror; - extern char * remdest; - -#ifdef PKTZEROHACK -#define PKTZEROLEN 32 -static char ipktack[PKTZEROLEN]; -static int ipktlen = 0; -#endif /* PKTZEROHACK */ - -static int s_timint = -1; /* For saving timeout value */ -static int myjob = 0; -static int havefs = 0; -#ifdef CK_LOGIN -static int logtries = 0; -#endif /* CK_LOGIN */ - -static int cancel = 0; -int fackbug = 0; - -#ifdef STREAMING -extern int streaming, streamok; - -static VOID -streamon() { - if (streamok) { - debug(F100,"streamon","",0); - streaming = 1; - timint = 0; /* No timeouts while streaming. */ - } -} - -#ifdef COMMENT /* (not used) */ -static VOID -streamoff() { - if (streaming) { - debug(F100,"streamoff","",0); - streaming = 0; - timint = s_timint; /* Restore timeout */ - } -} -#endif /* COMMENT */ -#else /* STREAMING */ -#define streamon() -#define streamoff() -#endif /* STREAMING */ - -#ifndef NOSPL -_PROTOTYP( int addmac, (char *, char *) ); -_PROTOTYP( int zzstring, (char *, char **, int *) ); -#endif /* NOSPL */ -#ifndef NOICP -_PROTOTYP( int cmdsrc, (void) ); -#endif /* NOICP */ - -#ifndef NOSERVER - extern char * x_user, * x_passwd, * x_acct; - extern int x_login, x_logged; -#endif /* NOSERVER */ - -#include "ckcnet.h" - -#ifdef TNCODE - extern int ttnproto; /* Network protocol */ -#endif /* TNCODE */ - -#ifdef CK_SPEED - extern short ctlp[]; /* Control-character prefix table */ -#endif /* CK_SPEED */ - -#ifdef TNCODE - extern int tn_b_nlm, tn_b_xfer, tn_nlm; -#ifdef CK_ENCRYPTION - extern int tn_no_encrypt_xfer; -#endif /* CK_ENCRYPTION */ -#endif /* TNCODE */ - -#ifdef TCPSOCKET -#ifndef NOLISTEN - extern int tcpsrfd; -#endif /* NOLISTEN */ -#endif /* TCPSOCKET */ - - extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl; - extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo; - extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla; - extern int timef, stdinf, rscapu, sendmode, epktflg, epktrcvd, epktsent; - extern int binary, fncnv; - extern long speed, ffc, crc16, calibrate, dest; -#ifdef COMMENT - extern char *TYPCMD, *DIRCMD, *DIRCM2; -#endif /* COMMENT */ -#ifndef OS2 - extern char *SPACMD, *SPACM2, *WHOCMD; -#endif /* OS2 */ - extern CHAR *rdatap; - extern struct zattr iattr; - -#ifdef VMS - extern int batch; -#endif /* VMS */ - -#ifdef GFTIMER - extern CKFLOAT fptsecs; -#endif /* GFTIMER */ - - extern CHAR *srvcmd; - extern CHAR *epktmsg; - -#ifdef CK_TMPDIR -extern int f_tmpdir; /* Directory changed temporarily */ -extern char savdir[]; /* For saving current directory */ -extern char * dldir; -#endif /* CK_TMPDIR */ - - extern int query; /* Query-active flag */ -#ifndef NOSPL - extern int cmdlvl; - char querybuf[QBUFL+1] = { NUL, NUL }; /* QUERY response buffer */ - char *qbufp = querybuf; /* Pointer to it */ - int qbufn = 0; /* Length of data in it */ -#else - extern int tlevel; -#endif /* NOSPL */ - -#ifndef NOICP - extern int escape; -#endif /* NOICP */ -/* - If the following flag is nonzero when the protocol module is entered, - then server mode persists for exactly one transaction, rather than - looping until BYE or FINISH is received. -*/ -extern int justone; - -static int r_save = -1; -static int p_save = -1; - -/* Function to let remote-mode user know where their file(s) went */ - -int whereflg = 1; /* Unset with SET XFER REPORT */ - -static VOID -wheremsg() { - extern int quiet, filrej; - int n; - n = filcnt - filrej; - debug(F101,"wheremsg n","",n); - - debug(F110,"wheremsg prfspec",prfspec,0); - debug(F110,"wheremsg rfspec",rfspec,0); - debug(F110,"wheremsg psfspec",psfspec,0); - debug(F110,"wheremsg sfspec",sfspec,0); - - debug(F110,"wheremsg prrfspec",prrfspec,0); - debug(F110,"wheremsg rrfspec",rrfspec,0); - debug(F110,"wheremsg psrfspec",psrfspec,0); - debug(F110,"wheremsg srfspec",srfspec,0); - - if (!quiet && !local) { - if (n == 1) { - switch (myjob) { - case 's': - if (sfspec) { - printf(" SENT: [%s]",sfspec); - if (srfspec) - printf(" To: [%s]",srfspec); - printf(" (%s)\n", success ? "OK" : "FAILED"); - } - break; - case 'r': - case 'v': - if (rrfspec) { - printf(" RCVD: [%s]",rrfspec); - if (rfspec) - printf(" To: [%s]",rfspec); - printf(" (%s)\n", success ? "OK" : "FAILED"); - } - } - } else if (n > 1) { - switch (myjob) { - case 's': - if (sfspec) { - printf(" SENT: (%d files)",n); - if (srfspec) - printf(" Last: [%s]",srfspec); - printf(" (%s)\n", success ? "OK" : "FAILED"); - } - break; - case 'r': - case 'v': - if (rrfspec) { - printf(" RCVD: (%d files)",n); - if (rfspec) - printf(" Last: [%s]",rfspec); - printf(" (%s)\n", success ? "OK" : "FAILED"); - } - } - } else if (n == 0) { - if (myjob == 's') - printf(" SENT: (0 files) \n"); - else if (myjob == 'r' || myjob == 'v') - printf(" RCVD: (0 files) \n"); - } - } -} - -static VOID -rdebug() { - if (server) - debug(F111,"RESUME","server=1",justone); - else - debug(F111,"RESUME","server=0",justone); -} - -/* Flags for the ENABLE and DISABLE commands */ -extern int - en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri, - en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit, - en_mkd, en_rmd; -#ifndef NOSPL -extern int en_asg, en_que; -#endif /* NOSPL */ -extern int what, lastxfer; - -/* Global variables declared here */ - - int whatru = 0; /* What are you. */ - int whatru2 = 0; /* What are you, cont'd. */ - -/* Local variables */ - - static char vstate = 0; /* Saved State */ - static char vcmd = 0; /* Saved Command */ - static int reget = 0; /* Flag for executing REGET */ - static int retrieve = 0; /* Flag for executing RETRIEVE */ - static int opkt = 0; /* Send Extended GET packet */ - - static int x; /* General-purpose integer */ - static char *s; /* General-purpose string pointer */ - -/* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */ -/* BEGIN is NOT a GOTO! */ -#define TINIT if (tinit(1) < 0) return(-9) -#define SERVE { TINIT; resetc(); nakstate=1; what=W_NOTHING; cmarg2=""; \ -sendmode=SM_SEND; havefs=0; recursive=r_save; fnspath=p_save; BEGIN serve; } -#define RESUME { rdebug(); if (!server) { wheremsg(); return(0); } else \ -if (justone) { justone=0; wheremsg(); return(0); } else { SERVE; } } - -#ifdef GFTIMER -#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); \ - fptsecs=gftimer(); quiet=x; return(success) -#else -#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x; \ - return(success) -#endif /* GFTIMER */ - -/* - By late 1999, the big switch() statement generated from the following state - table began choking even gcc, so here we extract the code from the larger - states into static routines to reduce the size of the cases and the - switch() overall. The routines follow the state table; the prototypes are - here. Each of these routines simply contains the text from the - corresponding case, but with return(-1) added in appropriate places; see - instructions after the state table switcher. -*/ -static int rc; /* Return code for these routines */ -static int rcv_s_pkt(); /* Received an S packet */ -static int rcv_firstdata(); /* Received first Data packet */ -static int rcv_shortreply(); /* Short reply to a REMOTE command */ -static int srv_query(); /* Server answers an query */ -static int srv_copy(); /* Server executes REMOTE COPY */ -static int srv_rename(); /* Server executes REMOTE RENAME */ -static int srv_login(); /* Server executes REMOTE LOGIN */ -static int srv_timeout(); /* Server times out */ - -%% - -/* - Protocol entry points, one for each start state (sstate). - The lowercase letters are internal "inputs" from the user interface. - NOTE: The start state letters that appear on the left margin immediately - below can NOT be used as packet types OR as G-packet subcodes. -*/ - -s { TINIT; /* Send file(s) */ - if (sinit() > 0) BEGIN ssinit; - else RESUME; } - -v { TINIT; nakstate = 1; BEGIN get; } /* Receive file(s) */ - -r { /* Client sends a GET command */ - TINIT; - vstate = get; - reget = 0; - retrieve = 0; - opkt = 0; - vcmd = 0; -#ifdef PKTZEROHACK - ipktack[0] = NUL; -#endif /* PKTZEROHACK */ - if (sipkt('I') >= 0) - BEGIN ipkt; - else - RESUME; -} - -h { /* Client sends a RETRIEVE command */ - TINIT; - vstate = get; - reget = 0; - retrieve = 1; - opkt = 0; - vcmd = 0; - if (sipkt('I') >= 0) - BEGIN ipkt; - else - RESUME; -} -j { /* Client sends a REGET command */ - TINIT; - vstate = get; - reget = 1; - retrieve = 0; - opkt = 0; - vcmd = 0; - if (sipkt('I') >= 0) - BEGIN ipkt; - else - RESUME; -} -o { /* Client sends Extended GET Packet */ - TINIT; - vstate = get; - reget = oopts & GOPT_RES; - retrieve = oopts & GOPT_DEL; - opkt = 1; - vcmd = 0; - if (sipkt('I') >= 0) - BEGIN ipkt; - else - RESUME; -} -c { /* Client sends a Host command */ - TINIT; - vstate = rgen; - vcmd = 'C'; - if (sipkt('I') >= 0) - BEGIN ipkt; - else - RESUME; -} -k { TINIT; /* Client sends a Kermit command */ - vstate = rgen; - vcmd = 'K'; - if (sipkt('I') >= 0) - BEGIN ipkt; - else - RESUME; -} -g { /* Client sends a REMOTE command */ - TINIT; - vstate = rgen; - vcmd = 'G'; - if (sipkt('I') >= 0) - BEGIN ipkt; - else - RESUME; -} -x { /* Enter server mode */ - int x; - x = justone; - if (!ENABLED(en_del)) { /* If DELETE is disabled */ - if (fncact == XYFX_B || /* undo any file collision action */ - fncact == XYFX_U || /* that could result in deletion or */ - fncact == XYFX_A || /* modification of existing files. */ - fncact == XYFX_X) { -#ifndef NOICP - extern int g_fncact; - g_fncact = fncact; /* Save current setting */ -#endif /* NOICP */ - fncact = XYFX_R; /* Change to RENAME */ - debug(F101,"server DELETE disabled so fncact RENAME","",fncact); - } - } - SERVE; /* tinit() clears justone... */ - justone = x; -#ifdef IKSDB - if (ikdbopen) slotstate(what, "SERVER", "", ""); -#endif /* IKSDB */ -} - -a { - int b1 = 0, b2 = 0; - if (!data) TINIT; /* "ABEND" -- Tell other side. */ -#ifndef pdp11 - if (epktflg) { /* If because of E-PACKET command */ - b1 = bctl; b2 = bctu; /* Save block check type */ - bctl = bctu = 1; /* set it to 1 */ - } -#endif /* pdp11 */ - errpkt((CHAR *)"User cancelled"); /* Send the packet */ -#ifndef pdp11 - if (epktflg) { /* Restore the block check */ - epktflg = 0; - bctl = b1; bctu = b2; - } -#endif /* pdp11 */ - success = 0; - return(0); /* Return from protocol. */ -} - -/* - Dynamic states: input-character { action } - nakstate != 0 means we're in a receiving state, in which we send ACKs & NAKs. -*/ - -S { /* Receive Send-Init packet. */ - rc = rcv_s_pkt(); - cancel = 0; /* Reset cancellation counter */ - debug(F101,"rcv_s_pkt","",rc); - if (rc > -1) return(rc); /* (see below) */ -} - -/* States in which we get replies back from commands sent to a server. */ -/* Complicated because direction of protocol changes, packet number */ -/* stays at zero through I-G-S sequence, and complicated even more by */ -/* sliding windows buffer allocation. */ - -Y { /* Get ack for I-packet */ - int x = 0; -#ifdef PKTZEROHACK - ckstrncpy(ipktack,(char *)rdatap,PKTZEROLEN); /* Save a copy of the ACK */ - ipktlen = strlen(ipktack); -#endif /* PKTZEROHACK */ - spar(rdatap); /* Set parameters */ - cancel = 0; - winlo = 0; /* Set window-low back to zero */ - debug(F101,"Y winlo","",winlo); - urserver = 1; /* So I know I'm talking to a server */ - if (vcmd) { /* If sending a generic command */ - if (tinit(0) < 0) return(-9); /* Initialize many things */ - x = scmd(vcmd,(CHAR *)cmarg); /* Do that */ - if (x >= 0) x = 0; /* (because of O-Packet) */ - debug(F101,"proto G packet scmd","",x); - vcmd = 0; /* and then un-remember it. */ - } else if (vstate == get) { - debug(F101,"REGET sstate","",sstate); - x = srinit(reget, retrieve, opkt); /* GET or REGET, etc */ - } - if (x < 0) { /* If command was too long */ - if (!srimsg) - srimsg = "Error sending string"; - errpkt((CHAR *)srimsg); /* cancel both sides. */ - success = 0; - RESUME; - } else if (x > 0) { /* Need to send more O-Packets */ - BEGIN ssopkt; - } else { - rtimer(); /* Reset the elapsed seconds timer. */ -#ifdef GFTIMER - rftimer(); -#endif /* GFTIMER */ - winlo = 0; /* Window back to 0, again. */ - debug(F101,"Y vstate","",vstate); - nakstate = 1; /* Can send NAKs from here. */ - BEGIN vstate; /* Switch to desired state */ - } -} - -Y { /* Got ACK to O-Packet */ - debug(F100,"CPCPRO Y","",0); - x = sopkt(); - debug(F101,"CPCPRO Y x","",x); - if (x < 0) { /* If error */ - errpkt((CHAR *)srimsg); /* cancel both sides. */ - success = 0; - RESUME; - } else if (x == 0) { /* This was the last O-Packet */ - rtimer(); /* Reset the elapsed seconds timer. */ -#ifdef GFTIMER - rftimer(); -#endif /* GFTIMER */ - winlo = 0; /* Window back to 0, again. */ - debug(F101,"Y winlo","",winlo); - nakstate = 1; /* Can send NAKs from here. */ - BEGIN vstate; /* Switch to desired state */ - } - debug(F101,"CPCPRO Y not changing state","",x); -} - -E { /* Ignore Error reply to I packet */ - int x = 0; - winlo = 0; /* Set window-low back to zero */ - debug(F101,"E winlo","",winlo); - if (vcmd) { /* In case other Kermit doesn't */ - if (tinit(0) < 0) return(-9); - x = scmd(vcmd,(CHAR *)cmarg); /* understand I-packets. */ - if (x >= 0) x = 0; /* (because of O-Packet) */ - vcmd = 0; /* Otherwise act as above... */ - } else if (vstate == get) x = srinit(reget, retrieve, opkt); - if (x < 0) { /* If command was too long */ - errpkt((CHAR *)srimsg); /* cancel both sides. */ - success = 0; - RESUME; - } else if (x > 0) { /* Need to send more O-Packets */ - BEGIN ssopkt; - } else { - freerpkt(winlo); /* Discard the Error packet. */ - debug(F101,"E winlo","",winlo); - winlo = 0; /* Back to packet 0 again. */ - nakstate = 1; /* Can send NAKs from here. */ - BEGIN vstate; - } -} - -Y { /* Resend of previous I-pkt ACK, same seq number */ - freerpkt(0); /* Free the ACK's receive buffer */ - resend(0); /* Send the GET packet again. */ -} - -/* States in which we're being a server */ - -I { /* Get I-packet */ -#ifndef NOSERVER - spar(rdatap); /* Set parameters from it */ - ack1(rpar()); /* Respond with our own parameters */ -#ifdef COMMENT - pktinit(); /* Reinitialize packet numbers */ -#else -#ifdef COMMENT - /* This can't be right - it undoes the stuff we just negotiated */ - x = justone; - tinit(1); /* Reinitialize EVERYTHING */ - justone = x; /* But this... */ -#else - tinit(0); /* Initialize most things */ -#endif /* COMMENT */ -#endif /* COMMENT */ -#endif /* NOSERVER */ - cancel = 0; /* Reset cancellation counter */ -} - -R { /* GET */ -#ifndef NOSERVER - if (x_login && !x_logged) { - errpkt((CHAR *)"Login required"); - SERVE; - } else if (sgetinit(0,0) < 0) { - RESUME; - } else { -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "GET", (char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; - } -#endif /* NOSERVER */ -} - -H { /* GET /DELETE (RETRIEVE) */ -#ifndef NOSERVER - if (x_login && !x_logged) { - errpkt((CHAR *)"Login required"); - RESUME; - } else if (!ENABLED(en_del)) { - errpkt((CHAR *)"Deleting files is disabled"); - RESUME; - } else if (sgetinit(0,0) < 0) { - RESUME; - } else { - moving = 1; -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "GET /DELETE", (char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; - } -#endif /* NOSERVER */ -} - -V { /* GET /RECURSIVE */ -#ifndef NOSERVER - recursive = 1; /* Set these before sgetinit() */ - if (fnspath == PATH_OFF) - fnspath = PATH_REL; /* Don't worry, they will be */ - if (x_login && !x_logged) { /* reset next time through. */ - errpkt((CHAR *)"Login required"); - RESUME; - } else if (sgetinit(0,0) < 0) { - RESUME; - } else { -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "GET /RECURSIVE", (char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; - } -#endif /* NOSERVER */ -} - -W { /* GET /RECURSIVE /DELETE */ -#ifndef NOSERVER - recursive = 1; /* Set these before sgetinit() */ - if (fnspath == PATH_OFF) - fnspath = PATH_REL; /* Don't worry, they will be */ - moving = 1; /* reset next time through. */ - if (x_login && !x_logged) { - errpkt((CHAR *)"Login required"); - RESUME; - } else if (!ENABLED(en_del)) { - errpkt((CHAR *)"Deleting files is disabled"); - RESUME; - } else if (sgetinit(0,0) < 0) { - RESUME; - } else { -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR,1,"server", - "GET /RECURSIVE /DELETE",(char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; - } -#endif /* NOSERVER */ -} - -J { /* GET /RECOVER (REGET) */ -#ifndef NOSERVER - if (x_login && !x_logged) { - errpkt((CHAR *)"Login required"); - SERVE; - } else if (sgetinit(1,0) < 0) { - RESUME; - } else { -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "GET /RECOVER", (char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; - } -#endif /* NOSERVER */ -} - -O { /* Extended GET */ -#ifndef NOSERVER - if (x_login && !x_logged) { /* (any combination of options) */ - errpkt((CHAR *)"Login required"); - SERVE; - } else if ((x = sgetinit(0,1)) < 0) { - debug(F101,"CKCPRO O sgetinit fail","",x); - RESUME; - } else if (x == 0) { - debug(F101,"CKCPRO O sgetinit done","",x); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; - } else { /* Otherwise stay in this state */ - debug(F101,"CKCPRO O sgetinit TBC","",x); - ack(); - BEGIN ropkt; - } -#endif /* NOSERVER */ -} - -O { -#ifndef NOSERVER - if (x_login && !x_logged) { /* (any combination of options) */ - errpkt((CHAR *)"Login required"); - SERVE; - } else if ((x = sgetinit(0,1)) < 0) { - debug(F101,"CKCPRO O sgetinit fail","",x); - RESUME; - } else if (x == 0) { - debug(F101,"CKCPRO O sgetinit done","",x); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; - } else { /* Otherwise stay in this state */ - debug(F101,"CKCPRO O sgetinit TBC","",x); - ack(); - } -#endif /* NOSERVER */ -} - -G { /* Generic server command */ -#ifndef NOSERVER - srvptr = srvcmd; /* Point to command buffer */ - decode(rdatap,putsrv,0); /* Decode packet data into it */ - putsrv(NUL); /* Insert a couple nulls */ - putsrv(NUL); /* for termination */ - if (srvcmd[0]) { - sstate = srvcmd[0]; /* Set requested start state */ - if (x_login && !x_logged && /* Login required? */ - /* Login, Logout, and Help are allowed when not logged in */ - sstate != 'I' && sstate != 'L' && sstate != 'H') { - errpkt((CHAR *)"Login required"); - SERVE; - } else { - nakstate = 0; /* Now I'm the sender. */ - what = W_REMO; /* Doing a REMOTE command. */ -#ifdef STREAMING - if (!streaming) -#endif /* STREAMING */ - if (timint < 1) - timint = chktimo(rtimo,timef); /* Switch to per-packet timer */ - binary = XYFT_T; /* Switch to text mode */ - BEGIN generic; /* Switch to generic command state */ - } - } else { - errpkt((CHAR *)"Badly formed server command"); /* report error */ - RESUME; /* & go back to server command wait */ - } -#endif /* NOSERVER */ -} - -C { /* Receive Host command */ -#ifndef NOSERVER - if (x_login && !x_logged) { - errpkt((CHAR *)"Login required"); - SERVE; - } else if (!ENABLED(en_hos)) { - errpkt((CHAR *)"REMOTE HOST disabled"); - RESUME; - } else if (nopush) { - errpkt((CHAR *)"HOST commands not available"); - RESUME; - } else { - srvptr = srvcmd; /* Point to command buffer */ - decode(rdatap,putsrv,0); /* Decode command packet into it */ - putsrv(NUL); /* Null-terminate */ - nakstate = 0; /* Now sending, not receiving */ - binary = XYFT_T; /* Switch to text mode */ - if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */ - what = W_REMO; /* Doing a REMOTE command. */ -#ifdef STREAMING - if (!streaming) -#endif /* STREAMING */ - if (timint < 1) - timint = chktimo(rtimo,timef); /* Switch to per-packet timer */ -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE HOST", (char *)srvcmd); -#endif /* CKSYSLOG */ - BEGIN ssinit; /* If OK, send back its output */ - } else { /* Otherwise */ - errpkt((CHAR *)"Can't do system command"); /* report error */ - RESUME; /* & go back to server command wait */ - } - } -#endif /* NOSERVER */ -} - -q { /* Interrupted or connection lost */ - rc = srv_timeout(); - debug(F101,"srv_timeout","",rc); - if (rc > -1) return(rc); /* (see below) */ -} - -N { /* Server got a NAK in command-wait */ -#ifndef NOSERVER - errpkt((CHAR *)"Did you say RECEIVE instead of GET?"); - RESUME; -#endif /* NOSERVER */ -} - -. { /* Any other command in this state */ -#ifndef NOSERVER - if (c != ('E' - SP) && c != ('Y' - SP)) /* except E and Y packets. */ - errpkt((CHAR *)"Unimplemented server function"); - /* If we answer an E with an E, we get an infinite loop. */ - /* A Y (ACK) can show up here if we sent back a short-form reply to */ - /* a G packet and it was echoed. ACKs can be safely ignored here. */ - RESUME; /* Go back to server command wait. */ -#endif /* NOSERVER */ -} - -I { /* Login/Out */ - rc = srv_login(); - debug(F101,"I srv_login","",rc); - if (rc > -1) return(rc); /* (see below) */ -} - -C { /* Got REMOTE CD command */ -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE CD", (char *)srvcmd); -#endif /* CKSYSLOG */ - if (!ENABLED(en_cwd)) { - errpkt((CHAR *)"REMOTE CD disabled"); - RESUME; - } else { - char * p = NULL; - x = cwd((char *)(srvcmd+1)); /* Try to change directory */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE CD", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - if (!x) { /* Failed */ - errpkt((CHAR *)"Can't change directory"); - RESUME; /* Back to server command wait */ - } else if (x == 2) { /* User wants message */ - if (!ENABLED(en_typ)) { /* Messages (REMOTE TYPE) disabled? */ - errpkt((CHAR *)"REMOTE TYPE disabled"); - RESUME; - } else { /* TYPE is enabled */ - int i; - for (i = 0; i < 8; i++) { - if (zchki(cdmsgfile[i]) > -1) { - break; - } - } - binary = XYFT_T; /* Use text mode for this. */ - if (i < 8 && sndtype(cdmsgfile[i])) { /* Have readme file? */ - BEGIN ssinit; /* OK */ - } else { /* not OK */ - p = zgtdir(); - if (!p) p = ""; - success = (*p) ? 1 : 0; - ack1((CHAR *)p); /* ACK with new directory name */ - success = 1; - RESUME; /* wait for next server command */ - } - } - } else { /* User doesn't want message */ - p =zgtdir(); - if (!p) p = ""; - success = (*p) ? 1 : 0; - ack1((CHAR *)p); - success = 1; - RESUME; /* Wait for next server command */ - } - } -#endif /* NOSERVER */ -} - -A { /* Got REMOTE PWD command */ -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE PWD", NULL); -#endif /* CKSYSLOG */ - if (!ENABLED(en_cwd)) { - errpkt((CHAR *)"REMOTE CD disabled"); - RESUME; - } else { - if (encstr((CHAR *)zgtdir()) > -1) { /* Encode current directory */ - ack1(data); /* If it fits, send it back in ACK */ - success = 1; - } else { /* Failed */ - ack(); /* Send empty ACK */ - success = 0; /* and indicate failure locally */ - } - RESUME; /* Back to server command wait */ - } -#endif /* NOSERVER */ -} - -D { /* REMOTE DIRECTORY command */ -#ifndef NOSERVER - char *n2; -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE DIRECTORY", (char *)srvcmd); -#endif /* CKSYSLOG */ - if (!ENABLED(en_dir)) { /* If DIR is disabled, */ - errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */ - RESUME; - } else { /* DIR is enabled. */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE DIR", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - if (!ENABLED(en_cwd)) { /* But CWD is disabled */ - zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */ - if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */ - errpkt((CHAR *)"Access denied"); - RESUME; /* Remember, this is not a goto! */ - } - } - if (state == generic) { /* It's OK to go ahead. */ -#ifdef COMMENT - n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2; - if (syscmd(n2,(char *)(srvcmd+2))) /* If it can be done */ -#else - int x; - if ((x = snddir((char*)(srvcmd+2))) > 0) -#endif /* COMMENT */ - { - BEGIN ssinit; /* send the results back; */ - } else { /* otherwise */ - if (x < 0) - errpkt((CHAR *)"No files match"); - else - errpkt((CHAR *)"Can't list directory"); - RESUME; /* return to server command wait */ - } - } - } -#endif /* NOSERVER */ -} - -E { /* REMOTE DELETE (Erase) */ -#ifndef NOSERVER - char *n2; -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE DELETE", (char *)srvcmd); -#endif /* CKSYSLOG */ - if (!ENABLED(en_del)) { - errpkt((CHAR *)"REMOTE DELETE disabled"); - RESUME; - } else { /* DELETE is enabled */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE DELETE", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - if (!ENABLED(en_cwd)) { /* but CWD is disabled */ - zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */ - if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */ - errpkt((CHAR *)"Access denied"); - RESUME; /* Remember, this is not a goto! */ - } - } else if (isdir((char *)(srvcmd+2))) { /* A directory name? */ - errpkt((CHAR *)"It's a directory"); - RESUME; - } - if (state == generic) { /* It's OK to go ahead. */ - int x; - if ((x = snddel((char*)(srvcmd+2))) > 0) { - BEGIN ssinit; /* If OK send results back */ - } else { /* otherwise */ - if (x < 0) - errpkt((CHAR *)"File not found"); /* report failure */ - else - errpkt((CHAR *)"DELETE failed"); - RESUME; /* & return to server command wait */ - } - } - } -#endif /* NOSERVER */ -} - -F { /* FINISH */ -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "FINISH", NULL); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"SERVER FINISH", "", ""); -#endif /* IKSDB */ - if (!ENABLED(en_fin)) { - errpkt((CHAR *)"FINISH disabled"); - RESUME; - } else { - ack(); /* Acknowledge */ - xxscreen(SCR_TC,0,0L,""); /* Display */ - success = 1; - return(0); /* Done */ - } -#endif /* NOSERVER */ -} - -X { /* EXIT */ -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE EXIT", NULL); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE EXIT", "", ""); -#endif /* IKSDB */ - if (!ENABLED(en_xit)) { - errpkt((CHAR *)"EXIT disabled"); - RESUME; - } else { - ack(); /* Acknowledge */ - xxscreen(SCR_TC,0,0L,""); /* Display */ - doexit(GOOD_EXIT,xitsta); - } -#endif /* NOSERVER */ -} - -L { /* BYE (Logout) */ -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "BYE", NULL); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"SERVER BYE", "", ""); -#endif /* IKSDB */ - if (!ENABLED(en_bye)) { - errpkt((CHAR *)"BYE disabled"); - RESUME; - } else { - ack(); /* Acknowledge */ - success = 1; - msleep(750); /* Give the ACK time to get out */ - if (local) - ttres(); /* Reset the terminal */ - xxscreen(SCR_TC,0,0L,""); /* Display */ - doclean(1); /* Clean up files, etc */ -#ifdef DEBUG - debug(F100,"C-Kermit BYE - Loggin out...","",0); - zclose(ZDFILE); -#endif /* DEBUG */ -#ifdef IKSD -#ifdef CK_LOGIN - if (inserver) - ckxlogout(); - else -#endif /* CK_LOGIN */ -#endif /* IKSD */ -#ifdef TCPSOCKET -#ifndef NOLISTEN - if (network && tcpsrfd > 0 && !inserver) - doexit(GOOD_EXIT,xitsta); - else -#endif /* NOLISTEN */ -#endif /* TCPSOCKET */ - return(zkself()); /* Try to log self out */ - } -#endif /* NOSERVER */ -} - -H { /* REMOTE HELP */ -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE HELP", NULL); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE HELP", "", ""); -#endif /* IKSDB */ -#ifndef NOSERVER - if (sndhlp(NULL)) { - BEGIN ssinit; /* try to send it */ - } else { /* If not ok, */ - errpkt((CHAR *)"Can't send help"); /* send error message instead */ - RESUME; /* and return to server command wait */ - } -#endif /* NOSERVER */ -} - -R { /* REMOTE RENAME */ - rc = srv_rename(); - debug(F101,"srv_rename","",rc); - if (rc > -1) return(rc); /* (see below) */ -} - -K { /* REMOTE COPY */ - rc = srv_copy(); - debug(F101,"srv_copy","",rc); - if (rc > -1) return(rc); /* (see below) */ -} - -S { /* REMOTE SET */ -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE SET", (char *)srvcmd); -#endif /* CKSYSLOG */ -#ifndef NOSERVER -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE SET", (char *)(srvcmd+1), ""); -#endif /* IKSDB */ - if (!ENABLED(en_set)) { - errpkt((CHAR *)"REMOTE SET disabled"); - RESUME; - } else { - if (remset((char *)(srvcmd+1))) { /* Try to do what they ask */ - success = 1; - ack(); /* If OK, then acknowledge */ - } else /* Otherwise */ - errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */ - RESUME; /* Return to server command wait */ - } -#endif /* NOSERVER */ -} - -T { /* REMOTE TYPE */ -#ifndef NOSERVER - char *n2; -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE TYPE", (char *)srvcmd); -#endif /* CKSYSLOG */ - if (!ENABLED(en_typ)) { - errpkt((CHAR *)"REMOTE TYPE disabled"); - RESUME; - } else { -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE TYPE", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - if (!ENABLED(en_cwd)) { /* If CWD disabled */ - zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */ - if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */ - errpkt((CHAR *)"Access denied"); - RESUME; /* Remember, this is not a goto! */ - } - } - if (state == generic) { /* It's OK to go ahead. */ - binary = XYFT_T; /* Use text mode for this. */ - if ( /* (RESUME didn't change state) */ -#ifdef COMMENT - syscmd(TYPCMD,(char *)(srvcmd+2)) /* Old way */ -#else - sndtype((char *)(srvcmd+2)) /* New way */ -#endif /* COMMENT */ - ) - BEGIN ssinit; /* OK */ - else { /* not OK */ - errpkt((CHAR *)"Can't type file"); /* give error message */ - RESUME; /* wait for next server command */ - } - } - } -#endif /* NOSERVER */ -} - -m { /* REMOTE MKDIR */ -#ifndef NOSERVER -#ifdef CK_MKDIR -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE MKDIR", (char *)srvcmd); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE MKDIR", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - if (!ENABLED(en_mkd)) { - errpkt((CHAR *)"REMOTE MKDIR disabled"); - RESUME; - } else if (!ENABLED(en_cwd)) { /* If CWD disabled */ - errpkt((CHAR *)"Directory access restricted"); - RESUME; /* Remember, this is not a goto! */ - } - if (state == generic) { /* OK to go ahead. */ - char *p = NULL; - x = ckmkdir(0,(char *)(srvcmd+2),&p,0,1); /* Make the directory */ - if (!p) p = ""; - if (x > -1) { - encstr((CHAR *)p); /* OK - encode the name */ - ack1(data); /* Send short-form response */ - success = 1; - RESUME; - } else { /* not OK */ - if (!*p) p = "Directory creation failure"; - errpkt((CHAR *)p); /* give error message */ - RESUME; /* Wait for next server command */ - } - } -#else - errpkt((CHAR *)"REMOTE MKDIR not available"); - RESUME; -#endif /* CK_MKDIR */ -#endif /* NOSERVER */ -} - -d { /* REMOTE RMDIR */ -#ifndef NOSERVER -#ifdef CK_MKDIR -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE RMDIR", (char *)srvcmd); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE RMDIR", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - if (!ENABLED(en_rmd)) { - errpkt((CHAR *)"REMOTE RMDIR disabled"); - RESUME; - } else if (!ENABLED(en_cwd)) { /* If CWD disabled */ - errpkt((CHAR *)"Directory access restricted"); - RESUME; /* Remember, this is not a goto! */ - } - if (state == generic) { /* OK to go ahead. */ - char *p = NULL; - x = ckmkdir(1,(char *)(srvcmd+2),&p,0,1); - if (!p) p = ""; - if (x > -1) { - encstr((CHAR *)p); /* OK - encode the name */ - ack1(data); /* Send short-form response */ - success = 1; - RESUME; - } else { /* not OK */ - if (!*p) p = "Directory removal failure"; - errpkt((CHAR *)p); /* give error message */ - RESUME; /* Wait for next server command */ - } - } -#else - errpkt((CHAR *)"REMOTE RMDIR not available"); - RESUME; -#endif /* CK_MKDIR */ -#endif /* NOSERVER */ -} - -U { /* REMOTE SPACE */ -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE SPACE", (char *)srvcmd); -#endif /* CKSYSLOG */ - if (!ENABLED(en_spa)) { - errpkt((CHAR *)"REMOTE SPACE disabled"); - RESUME; - } else { - x = srvcmd[1]; /* Get area to check */ - x = ((x == NUL) || (x == SP) -#ifdef OS2 - || (x == '!') || (srvcmd[3] == ':') -#endif /* OS2 */ - ); -#ifdef IKSDB - if (ikdbopen) slotstate(what, - "REMOTE SPACE", - (x ? "" : (char *)srvcmd), - "" - ); -#endif /* IKSDB */ - if (!x && !ENABLED(en_cwd)) { /* CWD disabled */ - errpkt((CHAR *)"Access denied"); /* and non-default area given, */ - RESUME; /* refuse. */ - } else { -#ifdef OS2 -_PROTOTYP(int sndspace,(int)); - if (sndspace(x ? toupper(srvcmd[2]) : 0)) { - BEGIN ssinit; /* send the report. */ - } else { /* If not ok, */ - errpkt((CHAR *)"Can't send space"); /* send error message */ - RESUME; /* and return to server command wait */ - } -#else - if (nopush) - x = 0; - else - x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2))); - if (x) { /* If we got the info */ - BEGIN ssinit; /* send it */ - } else { /* otherwise */ - errpkt((CHAR *)"Can't check space"); /* send error message */ - RESUME; /* and await next server command */ - } -#endif /* OS2 */ - } - } -#endif /* NOSERVER */ -} - -W { /* REMOTE WHO */ -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE WHO", (char *)srvcmd); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE WHO", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - if (!ENABLED(en_who)) { - errpkt((CHAR *)"REMOTE WHO disabled"); - RESUME; - } else { -#ifdef OS2 -_PROTOTYP(int sndwho,(char *)); - if (sndwho((char *)(srvcmd+2))) { - BEGIN ssinit; /* try to send it */ - } else { /* If not ok, */ - errpkt((CHAR *)"Can't do who command"); /* send error msg */ - RESUME; /* and return to server command wait */ - } -#else - if (syscmd(WHOCMD,(char *)(srvcmd+2))) { - BEGIN ssinit; - } else { - errpkt((CHAR *)"Can't do who command"); - RESUME; - } -#endif /* OS2 */ - } -#endif /* NOSERVER */ -} - -V { /* Variable query or set */ - rc = srv_query(); - debug(F101,"srv_query","",rc); - if (rc > -1) return(rc); -} - -q { /* Interrupted or connection lost */ -#ifndef NOSERVER - if (fatalio) { /* Connection lost */ -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL); -#endif /* CKSYSLOG */ - success = 0; - xitsta |= (what & W_KERMIT); - QUIT; - } else if (interrupted) { - if (!ENABLED(en_fin)) { /* Ctrl-C typed */ - errpkt((CHAR *)"QUIT disabled"); - RESUME; - } else { -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL); -#endif /* CKSYSLOG */ - success = 0; - xitsta |= (what & W_KERMIT); - QUIT; - } - } else { /* Shouldn't happen */ - debug(F100,"SERVER (generic) GOT UNEXPECTED 'q'","",0); - QUIT; - } -#endif /* NOSERVER */ -} - -. { /* Anything else in this state... */ -#ifndef NOSERVER - errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */ - RESUME; /* and return to server command wait */ -#endif /* NOSERVER */ -} - -q { /* Sent BYE and connection broken */ - if (bye_active && ttchk() < 0) { - msleep(500); - bye_active = 0; - ttclos(0); /* Close our end of the connection */ - clsof(0); - return(success = 1); - } else { /* Other generic command */ - return(success = 0); /* or connection not broken */ - } -} - -Y { /* Short-Form reply */ - rc = rcv_shortreply(); - debug(F101,"Y rcv_shortreply","",rc); - if (rc > -1) return(rc); -} - -F { /* File header */ - /* char *n2; */ - extern int rsn; - debug(F101,"F winlo 1","",winlo); - xflg = 0; /* Not screen data */ - if (!czseen) - cancel = 0; /* Reset cancellation counter */ -#ifdef CALIBRATE - if (dest == DEST_N) - calibrate = 1; -#endif /* CALIBRATE */ - if (!rcvfil(filnam)) { /* Figure out local filename */ - errpkt((CHAR *)rf_err); /* Trouble */ - RESUME; - } else { /* Real file, OK to receive */ - char * fnp; - debug(F111,"F winlo 2",fspec,winlo); - if (filcnt == 1) /* rcvfil set this to 1 for 1st file */ - crc16 = 0L; /* Clear file CRC */ - fnp = fspec; /* This is the full path */ - if (server && !ENABLED(en_cwd) || /* if DISABLE CD */ - !fackpath /* or F-ACK-PATH OFF */ - ) { - zstrip(fspec,&fnp); /* don't send back full path */ - } - encstr((CHAR *)fnp); - if (fackbug) - ack(); - else - ack1(data); /* Send it back in ACK */ - initattr(&iattr); /* Clear file attribute structure */ - streamon(); - if (window(wslotn) < 0) { /* Allocate negotiated window slots */ - errpkt((CHAR *)"Can't open window"); - RESUME; - } -#ifdef IKSDB - if (ikdbopen) slotstate(what, - server ? "SERVER" : "", - "RECEIVE", - fspec - ); -#endif /* IKSDB */ - BEGIN rattr; /* Now expect Attribute packets */ - } -} - -X { /* X-packet instead of file header */ - xflg = 1; /* Screen data */ - if (!czseen) - cancel = 0; /* Reset cancellation counter */ - ack(); /* Acknowledge the X-packet */ - initattr(&iattr); /* Initialize attribute structure */ - streamon(); - if (window(wslotn) < 0) { /* allocate negotiated window slots */ - errpkt((CHAR *)"Can't open window"); - RESUME; - } -#ifndef NOSPL - if (query) { /* If this is the response to */ - qbufp = querybuf; /* a query that we sent, initialize */ - qbufn = 0; /* the response buffer */ - querybuf[0] = NUL; - } -#endif /* NOSPL */ - what = W_REMO; /* we're doing a REMOTE command */ -#ifdef IKSDB - if (ikdbopen) slotstate(what, - server ? "SERVER" : "", - "RECEIVE", - fspec - ); -#endif /* IKSDB */ - BEGIN rattr; /* Expect Attribute packets */ -} - -A { /* Attribute packet */ - if (gattr(rdatap,&iattr) == 0) { /* Read into attribute structure */ -#ifdef CK_RESEND - ack1((CHAR *)iattr.reply.val); /* Reply with data */ -#else - ack(); /* If OK, acknowledge */ -#endif /* CK_RESEND */ - } else { /* Otherwise */ - extern long fsize; - char *r; - r = getreason(iattr.reply.val); - ack1((CHAR *)iattr.reply.val); /* refuse to accept the file */ - xxscreen(SCR_ST,ST_REFU,0L,r); /* reason */ -#ifdef TLOG - if (tralog && !tlogfmt) - doxlog(what,filnam,fsize,binary,1,r); -#endif /* TLOG */ - } -} - -D { /* First data packet */ - debug(F100," D firstdata","",0); - rc = rcv_firstdata(); - debug(F101,"rcv_firstdata rc","",rc); - if (rc > -1) return(rc); /* (see below) */ -} - -B { /* EOT, no more files */ - ack(); /* Acknowledge the B packet */ - reot(); /* Do EOT things */ -#ifdef CK_TMPDIR -/* If we were cd'd temporarily to another device or directory ... */ - if (f_tmpdir) { - int x; - x = zchdir((char *) savdir); /* ... restore previous directory */ - f_tmpdir = 0; /* and remember we did it. */ - debug(F111,"ckcpro.w B tmpdir restoring",savdir,x); - } -#endif /* CK_TMPDIR */ - RESUME; /* and quit */ -} - -D { /* Got Data packet */ - debug(F101,"D cxseen","",cxseen); - debug(F101,"D czseen","",czseen); - if (cxseen || czseen || discard) { /* If file or group interruption */ - CHAR * msg; - msg = czseen ? (CHAR *)"Z" : (CHAR *)"X"; -#ifdef STREAMING - if (streaming) { /* Need to cancel */ - debug(F111,"D streaming cancel",msg,cancel); - if (cancel++ == 0) { /* Only do this once */ - ack1(msg); /* Put "X" or "Z" in ACK */ - } else if (czseen) { - errpkt((CHAR *)"User canceled"); - RESUME; - } else { - fastack(); - } - } else -#endif /* STREAMING */ - ack1(msg); - } else { /* No interruption */ - int rc, qf; -#ifndef NOSPL - qf = query; -#else - qf = 0; -#endif /* NOSPL */ -#ifdef CKTUNING - rc = (binary && !parity) ? - bdecode(rdatap,putfil): - decode(rdatap, qf ? puttrm : putfil, 1); -#else - rc = decode(rdatap, qf ? puttrm : putfil, 1); -#endif /* CKTUNING */ - if (rc < 0) { - discard = (keep == 0 || (keep == SET_AUTO && binary != XYFT_T)); - errpkt((CHAR *)"Error writing data"); /* If failure, */ - RESUME; - } else /* Data written OK, send ACK */ -#ifdef STREAMING - if (streaming) - fastack(); - else -#endif /* STREAMING */ - ack(); - } -} - -Z { /* EOF immediately after A-Packet. */ - rf_err = "Can't create file"; - timint = s_timint; - if (discard) { /* Discarding a real file... */ - x = 1; - } else if (xflg) { /* If screen data */ - if (remfile) { /* redirected to file */ - if (rempipe) /* or pipe */ - x = openc(ZOFILE,remdest); /* Pipe: start command */ - else - x = opena(remdest,&iattr); /* File: open with attributes */ - } else { /* otherwise */ - x = opent(&iattr); /* "open" the screen */ - } -#ifdef CALIBRATE - } else if (calibrate) { /* If calibration run */ - x = ckopenx(&iattr); /* do this */ -#endif /* CALIBRATE */ - } else { /* otherwise */ - x = opena(filnam,&iattr); /* open the file, with attributes */ - if (x == -17) { /* REGET skipped because same size */ - discard = 1; - rejection = 1; - } - } - if (!x || reof(filnam, &iattr) < 0) { /* Close output file */ - errpkt((CHAR *) rf_err); /* If problem, send error msg */ - RESUME; /* and quit */ - } else { /* otherwise */ - if (x == -17) - xxscreen(SCR_ST,ST_SKIP,SKP_RES,""); - ack(); /* acknowledge the EOF packet */ - BEGIN rfile; /* and await another file */ - } -} - -q { /* Ctrl-C or connection loss. */ - timint = s_timint; - window(1); /* Set window size back to 1... */ - cxseen = 1; - x = clsof(1); /* Close file */ - return(success = 0); /* Failed */ -} - -Z { /* End Of File (EOF) Packet */ -/* wslots = 1; */ /* (don't set) Window size back to 1 */ -#ifndef COHERENT /* Coherent compiler blows up on this switch() statement. */ - x = reof(filnam, &iattr); /* Handle the EOF packet */ - switch (x) { /* reof() sets the success flag */ - case -5: /* Handle problems */ - errpkt((CHAR *)"RENAME failed"); /* Fatal */ - RESUME; - break; - case -4: - errpkt((CHAR *)"MOVE failed"); /* Fatal */ - RESUME; - break; - case -3: /* If problem, send error msg */ - errpkt((CHAR *)"Can't print file"); /* Fatal */ - RESUME; - break; - case -2: - errpkt((CHAR *)"Can't mail file"); /* Fatal */ - RESUME; - break; - case 2: /* Not fatal */ - case 3: - xxscreen(SCR_EM,0,0L,"Receiver can't delete temp file"); - RESUME; - break; - default: - if (x < 0) { /* Fatal */ - errpkt((CHAR *)"Can't close file"); - RESUME; - } else { /* Success */ -#ifndef NOSPL - if (query) /* Query reponses generally */ - conoll(""); /* don't have line terminators */ -#endif /* NOSPL */ - if (czseen) { /* Batch canceled? */ - if (cancel++ == 0) { /* If we haven't tried this yet */ - ack1((CHAR *)"Z"); /* Try it once */ - } else { /* Otherwise */ - errpkt((CHAR *)"User canceled"); /* quite with Error */ - RESUME; - } - } else - ack(); /* Acknowledge the EOF packet */ - BEGIN rfile; /* and await another file */ - } - } -#else - if (reof(filnam, &iattr) < 0) { /* Close the file */ - errpkt((CHAR *)"Error at end of file"); - RESUME; - } else { /* reof() sets success flag */ - ack(); - BEGIN rfile; - } -#endif /* COHERENT */ -} - -Y { /* ACK for Send-Init */ - spar(rdatap); /* set parameters from it */ - cancel = 0; - bctu = bctr; /* switch to agreed-upon block check */ - bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */ -#ifdef CK_RESEND - if ((sendmode == SM_RESEND) && (!atcapu || !rscapu)) { /* RESEND */ - errpkt((CHAR *) "RESEND capabilities not negotiated"); - RESUME; - } else { -#endif /* CK_RESEND */ - what = W_SEND; /* Remember we're sending */ - lastxfer = W_SEND; - x = sfile(xflg); /* Send X or F header packet */ - cancel = 0; /* Reset cancellation counter */ - if (x) { /* If the packet was sent OK */ - if (!xflg && filcnt == 1) /* and it's a real file */ - crc16 = 0L; /* Clear the file CRC */ - resetc(); /* reset per-transaction counters */ - rtimer(); /* reset timers */ -#ifdef GFTIMER - rftimer(); -#endif /* GFTIMER */ - streamon(); /* turn on streaming */ -#ifdef IKSDB - if (ikdbopen) slotstate(what, - (server ? "SERVER" : ""), - "SEND", - filnam - ); -#endif /* IKSDB */ - BEGIN ssfile; /* and switch to receive-file state */ - } else { /* otherwise send error msg & quit */ - s = xflg ? "Can't execute command" : (char *)epktmsg; - if (!*s) s = "Can't open file"; - errpkt((CHAR *)s); - RESUME; - } -#ifdef CK_RESEND - } -#endif /* CK_RESEND */ -} - -/* - These states are necessary to handle the case where we get a server command - packet (R, G, or C) reply with an S packet, but the client retransmits the - command packet. The input() function doesn't catch this because the packet - number is still zero. -*/ -R { /* R packet was retransmitted. */ - xsinit(); /* Resend packet 0 */ -} - -G { /* Same deal if G packet comes again */ - xsinit(); -} - -/* should probably add cases for O, W, V, H, J, ... */ - -C { /* Same deal if C packet comes again */ - xsinit(); -} - -Y { /* ACK for F or X packet */ - srvptr = srvcmd; /* Point to string buffer */ - decode(rdatap,putsrv,0); /* Decode data field, if any */ - putsrv(NUL); /* Terminate with null */ - ffc = 0L; /* Reset file byte counter */ - debug(F101,"Y cxseen","",cxseen); - if (*srvcmd) { /* If remote name was recorded */ - if (sendmode != SM_RESEND) { - if (fdispla == XYFD_C || fdispla == XYFD_S) - xxscreen(SCR_AN,0,0L,(char *)srvcmd); - tlog(F110," remote name:",(char *) srvcmd,0L); - makestr(&psrfspec,(char *)srvcmd); - } - } - if (cxseen||czseen) { /* Interrupted? */ - debug(F101,"Y canceling","",0); - x = clsif(); /* Close input file */ - sxeof(1); /* Send EOF(D) */ - BEGIN sseof; /* and switch to EOF state. */ - } else if (atcapu) { /* If attributes are to be used */ - if (sattr(xflg | stdinf, 1) < 0) { /* send them */ - errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */ - RESUME; /* and quit */ - } else BEGIN ssattr; /* if ok, switch to attribute state */ - } else { /* Attributes not negotiated */ - if (window(wslotn) < 0) { /* Open window */ - errpkt((CHAR *)"Can't open window"); - RESUME; - } else if ((x = sdata()) == -2) { /* Send first data packet data */ - window(1); /* Connection lost, reset window */ - x = clsif(); /* Close input file */ - return(success = 0); /* Return failure */ - } else if (x == -9) { /* User interrupted */ - errpkt((CHAR *)"User cancelled"); /* Send Error packet */ - window(1); /* Set window size back to 1... */ - timint = s_timint; /* Restore timeout */ - return(success = 0); /* Failed */ - } else if (x < 0) { /* EOF (empty file) or interrupted */ - window(1); /* put window size back to 1, */ - debug(F101,"Y cxseen","",cxseen); - x = clsif(); /* If not ok, close input file, */ - if (x < 0) /* treating failure as interruption */ - cxseen = 1; /* Send EOF packet */ - seof(cxseen||czseen); - BEGIN sseof; /* and switch to EOF state. */ - } else { /* First data sent OK */ - BEGIN ssdata; /* All ok, switch to send-data state */ - } - } -} - -Y { /* Got ACK to A packet */ - ffc = 0L; /* Reset file byte counter */ - debug(F101,"Y cxseen","",cxseen); - if (cxseen||czseen) { /* Interrupted? */ - debug(F101,"Y canceling","",0); - x = clsif(); /* Close input file */ - sxeof(1); /* Send EOF(D) */ - BEGIN sseof; /* and switch to EOF state. */ - } else if (rsattr(rdatap) < 0) { /* Was the file refused? */ - discard = 1; /* Set the discard flag */ - clsif(); /* Close the file */ - sxeof(1); /* send EOF with "discard" code */ - BEGIN sseof; /* switch to send-EOF state */ - } else if ((x = sattr(xflg | stdinf, 0)) < 0) { /* Send more? */ - errpkt((CHAR *)"Can't send attributes"); /* Trouble... */ - RESUME; - } else if (x == 0) { /* No more to send so now the data */ - if (window(wslotn) < 0) { /* Allocate negotiated window slots */ - errpkt((CHAR *)"Can't open window"); - RESUME; - } - if ((x = sdata()) == -2) { /* File accepted, send first data */ - window(1); /* Connection broken */ - x = clsif(); /* Close file */ - return(success = 0); /* Return failure */ - } else if (x == -9) { /* User interrupted */ - errpkt((CHAR *)"User cancelled"); /* Send Error packet */ - window(1); /* Set window size back to 1... */ - timint = s_timint; /* Restore timeout */ - return(success = 0); /* Failed */ - } else if (x < 0) { /* If data was not sent */ - window(1); /* put window size back to 1, */ - debug(F101,"Y cxseen","",cxseen); - if (clsif() < 0) /* Close input file */ - cxseen = 1; /* Send EOF packet */ - seof(cxseen||czseen); - BEGIN sseof; /* and switch to EOF state. */ - } else { - BEGIN ssdata; /* All ok, switch to send-data state */ - } - } -} - -q { /* Ctrl-C or connection loss. */ - window(1); /* Set window size back to 1... */ - cxseen = 1; /* To indicate interruption */ - x = clsif(); /* Close file */ - return(success = 0); /* Failed */ -} - -Y { /* Got ACK to Data packet */ - canned(rdatap); /* Check if file transfer cancelled */ - debug(F111,"Y cxseen",rdatap,cxseen); - debug(F111,"Y czseen",rdatap,czseen); - if ((x = sdata()) == -2) { /* Try to send next data */ - window(1); /* Connection lost, reset window */ - x = clsif(); /* Close file */ - return(success = 0); /* Failed */ - } else if (x == -9) { /* User interrupted */ - errpkt((CHAR *)"User cancelled"); /* Send Error packet */ - window(1); /* Set window size back to 1... */ - timint = s_timint; /* Restore original timeout */ - return(success = 0); /* Failed */ - } else if (x < 0) { /* EOF - finished sending data */ - debug(F101,"Y cxseen","",cxseen); - window(1); /* Set window size back to 1... */ - if (clsif() < 0) /* Close input file */ - cxseen = 1; /* Send EOF packet */ - debug(F101,"Y CALLING SEOF()","",cxseen); - seof(cxseen||czseen); - BEGIN sseof; /* and enter send-eof state */ - } - /* NOTE: If x == 0 it means we're draining: see sdata()! */ -} - -Y { /* Got ACK to EOF */ - int g, xdiscard; - canned(rdatap); /* Check if file transfer cancelled */ - debug(F111,"Y cxseen",rdatap,cxseen); - debug(F111,"Y czseen",rdatap,czseen); - debug(F111,"Y discard",rdatap,discard); - xdiscard = discard; - discard = 0; - success = (cxseen == 0 && czseen == 0); /* Transfer status... */ - debug(F101,"Y success","",success); - if (success && rejection > 0) /* If rejected, succeed if */ - if (rejection != '#' && /* reason was date */ - rejection != 1 && rejection != '?') /* or name; */ - success = 0; /* fail otherwise. */ - cxseen = 0; /* This goes back to zero. */ - if (success) { /* Only if transfer succeeded... */ - xxscreen(SCR_ST,ST_OK,0L,""); - if (!xdiscard) { - makestr(&sfspec,psfspec); /* Record filenames for WHERE */ - makestr(&srfspec,psrfspec); - } - if (moving) { /* If MOVE'ing */ - x = zdelet(filnam); /* Try to delete the source file */ -#ifdef TLOG - if (tralog) { - if (x > -1) { - tlog(F110," deleted",filnam,0); - } else { - tlog(F110," delete failed:",ck_errstr(),0); - } - } -#endif /* TLOG */ - } else if (snd_move) { /* Or move it */ - int x; - x = zrename(filnam,snd_move); -#ifdef TLOG - if (tralog) { - if (x > -1) { - tlog(F110," moved to ",snd_move,0); - } else { - tlog(F110," move failed:",ck_errstr(),0); - } - } -#endif /* TLOG */ - } else if (snd_rename) { /* Or rename it */ - char *s = snd_rename; /* Renaming string */ -#ifndef NOSPL - int y; /* Pass it thru the evaluator */ - extern int cmd_quoting; /* for \v(filename) */ - if (cmd_quoting) { /* But only if cmd_quoting is on */ - y = MAXRP; - s = (char *)srvcmd; - zzstring(snd_rename,&s,&y); - s = (char *)srvcmd; - } -#endif /* NOSPL */ - if (s) if (*s) { - int x; - x = zrename(filnam,s); -#ifdef TLOG - if (tralog) { - if (x > -1) { - tlog(F110," renamed to",s,0); - } else { - tlog(F110," rename failed:",ck_errstr(),0); - } - } -#endif /* TLOG */ -#ifdef COMMENT - *s = NUL; -#endif /* COMMENT */ - } - } - } - if (czseen) { /* Check group interruption flag */ - g = 0; /* No more files if interrupted */ - } else { /* Otherwise... */ -#ifdef COMMENT - /* This code makes any open error fatal to a file-group transfer. */ - g = gnfile(); - debug(F111,"Y gnfile",filnam,g); - if (g > 0) { /* Any more files to send? */ - if (sfile(xflg)) /* Yes, try to send next file header */ - BEGIN ssfile; /* if ok, enter send-file state */ - else { /* otherwise */ - s = xflg ? "Can't execute command" : (char *)epktmsg; - if (!*s) s = "Can't open file"; - errpkt((CHAR *)s); /* send error message */ - RESUME; /* and quit */ - } - } else { /* No next file */ - tsecs = gtimer(); /* get statistics timers */ -#ifdef GFTIMER - fptsecs = gftimer(); -#endif /* GFTIMER */ - seot(); /* send EOT packet */ - BEGIN sseot; /* enter send-eot state */ - } -#else /* COMMENT */ - while (1) { /* Keep trying... */ - g = gnfile(); /* Get next file */ - debug(F111,"Y gnfile",filnam,g); - if (g == 0 && gnferror == 0) /* No more, stop trying */ - break; - if (g > 0) { /* Have one */ - if (sfile(xflg)) { /* Try to open and send F packet */ - BEGIN ssfile; /* If OK, enter send-file state */ - break; /* and break out of loop. */ - } - } /* Otherwise keep trying to get one we can send... */ - } - } - if (g == 0) { - debug(F101,"Y no more files","",czseen); - tsecs = gtimer(); /* Get statistics timers */ -#ifdef GFTIMER - fptsecs = gftimer(); -#endif /* GFTIMER */ - seot(); /* Send EOT packet */ - BEGIN sseot; /* Enter send-eot state */ - } -#endif /* COMMENT */ -} - -Y { /* Got ACK to EOT */ - debug(F101,"sseot justone","",justone); - RESUME; /* All done, just quit */ -} - -E { /* Got Error packet, in any state */ - char *s = ""; - window(1); /* Close window */ - timint = s_timint; /* Restore original timeout */ - if (*epktmsg) /* Message from Error packet */ - s = (char *)epktmsg; - if (!*s) { /* If not there then maybe here */ - s = (char *)rdatap; - ckstrncpy((char *)epktmsg,(char *)rdatap,PKTMSGLEN); - } - if (!*s) /* Hopefully we'll never see this. */ - s = "Unknown error"; - success = 0; /* For IF SUCCESS/FAIL. */ - debug(F101,"ckcpro.w justone at E pkt","",justone); - - success = 0; /* Transfer failed */ - xferstat = success; /* Remember transfer status */ - if (!epktsent) { - x = quiet; quiet = 1; /* Close files silently, */ - epktrcvd = 1; /* Prevent messages from clsof() */ - clsif(); - clsof(1); /* discarding any output file. */ - ermsg(s); /* Issue the message (calls screen). */ - quiet = x; /* Restore quiet state */ - } - tstats(); /* Get stats */ -/* - If we are executing commands from a command file or macro, let the command - file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR. -*/ - if ( -#ifndef NOICP - !xcmdsrc && -#endif /* NOICP */ - backgrd && !server) - fatal("Protocol error"); - xitsta |= (what & W_KERMIT); /* Save this for doexit(). */ -#ifdef CK_TMPDIR -/* If we were cd'd temporarily to another device or directory ... */ - if (f_tmpdir) { - int x; - x = zchdir((char *) savdir); /* ... restore previous directory */ - f_tmpdir = 0; /* and remember we did it. */ - debug(F111,"ckcpro.w E tmpdir restored",savdir,x); - } -#endif /* CK_TMPDIR */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"ERROR", (char *)epktmsg, ""); -#endif /* IKSDB */ - RESUME; -} - -q { success = 0; QUIT; } /* Ctrl-C or connection loss. */ - -. { /* Anything not accounted for above */ - errpkt((CHAR *)"Unexpected packet type"); /* Give error message */ - window(1); - xitsta |= (what & W_KERMIT); /* Save this for doexit(). */ - RESUME; /* and quit */ -} - -%% - -/* - From here down to proto() are routines that were moved out of the state - table switcher because the resulting switch() had become too large. - To move the contents of a state-table case to a routine: - 1. Add a prototype to the list above the state table switcher. - 2. Make a routine with an appropriate name, returning int. - 3. Move the code into it. - 4. Put a call to the new routine in the former spot: - rc = name_of_routine(); - if (rc > -1) return(rc); - 5. Add "return(-1);" after every RESUME, SERVE, or BEGIN macro and - at the end if the code is open-ended. -*/ -static int -rcv_firstdata() { - extern int dispos; - debug(F101,"rcv_firstdata","",dispos); - - if (discard) { /* if we're discarding the file */ - ack1((CHAR *)"X"); /* just ack the data like this. */ - cancel++; /* and count it */ - BEGIN rdpkt; /* and wait for more data packets. */ - return(-1); - } else { /* Not discarding. */ - rf_err = "Can't open file"; - if (xflg) { /* If screen data */ - if (remfile) { /* redirected to file */ - if (rempipe) /* or pipe */ - x = openc(ZOFILE,remdest); /* Pipe: start command */ - else - x = opena(remdest,&iattr); /* File: open with attributes */ - } else { /* otherwise */ - x = opent(&iattr); /* "open" the screen */ - } - } else { /* otherwise */ -#ifdef CALIBRATE - if (calibrate) { /* If calibration run */ - x = ckopenx(&iattr); /* open nothing */ -#ifdef STREAMING - if (streaming) /* Streaming */ - fastack(); /* ACK without ACKing. */ - else -#endif /* STREAMING */ - ack(); /* Send real ACK */ - BEGIN rdpkt; /* Proceed to next state */ - return(-1); - } else -#endif /* CALIBRATE */ -#ifdef UNIX -/* - In UNIX we can pipe the file data into the mail program, which is to be - preferred to writing it out to a temp file and then mailing it afterwards. - This depends rather heavily on all UNIXes having a mail command that - accepts '-s "subject"' on the command line. MAILCMD (e.g. mail, Mail, mailx) - is defined in ckufio.c. -*/ - if (dispos == 'M') { /* Mail... */ - char *s; - char * tmp = NULL; - int n = 0; - extern char *MAILCMD; - s = iattr.disp.val + 1; - n = (int)strlen(MAILCMD) + /* Mail command */ - (int)strlen(s) + /* address */ - (int)strlen(ofilnam) + 32; /* subject */ - if (tmp = (char *)malloc(n)) { - ckmakxmsg(tmp,n, - MAILCMD," -s \"",ofilnam,"\" ",s, - NULL,NULL,NULL,NULL,NULL,NULL,NULL); - debug(F111,"rcv_firsdata mail",tmp,(int)strlen(tmp)); - x = openc(ZOFILE,(char *)tmp); - free(tmp); - } else - x = 0; - } else if (dispos == 'P') { /* Ditto for print */ - char * tmp = NULL; - int n; - extern char *PRINTCMD; - n = (int)strlen(PRINTCMD) + (int)strlen(iattr.disp.val+1) + 4; - if (tmp = (char *)malloc(n)) { - sprintf(tmp, /* safe (prechecked) */ - "%s %s", PRINTCMD, iattr.disp.val + 1); - x = openc(ZOFILE,(char *)tmp); - free(tmp); - } else - x = 0; - } else -#endif /* UNIX */ - x = opena(filnam,&iattr); /* open the file, with attributes */ - } - if (x) { /* If file was opened ok */ - int rc, qf; -#ifndef NOSPL - qf = query; -#else - qf = 0; -#endif /* NOSPL */ - -#ifdef CKTUNING - rc = (binary && !parity) ? - bdecode(rdatap,putfil): - decode(rdatap, qf ? puttrm : putfil, 1); -#else - rc = decode(rdatap, qf ? puttrm : putfil, 1); -#endif /* CKTUNING */ - if (rc < 0) { - errpkt((CHAR *)"Error writing data"); - RESUME; - return(-1); - } -#ifdef STREAMING - if (streaming) /* Streaming was negotiated */ - fastack(); /* ACK without ACKing. */ - else -#endif /* STREAMING */ - ack(); /* acknowledge it */ - BEGIN rdpkt; /* and switch to receive-data state */ - return(-1); - } else { /* otherwise */ - errpkt((CHAR *) rf_err); /* send error packet */ - RESUME; /* and quit. */ - return(-1); - } - } -} - -static int -rcv_shortreply() { -#ifdef PKTZEROHACK - success = 0; - debug(F111,"rcv_shortreply",rdatap,ipktlen); - if (ipktack[0] && !strncmp(ipktack,(char *)rdatap,ipktlen)) { - /* No it's the ACK to the I packet again */ - x = scmd(vcmd,(CHAR *)cmarg); /* So send the REMOTE command again */ - /* Maybe this should be resend() */ - debug(F110,"IPKTZEROHACK",ipktack,x); - if (x < 0) { - errpkt((CHAR *)srimsg); - RESUME; - return(-1); - } - } else { - ipktack[0] = NUL; -#endif /* PKTZEROHACK */ - urserver = 1; -#ifndef NOSERVER -#ifndef NOSPL - if (query) { /* If to query, */ - qbufp = querybuf; /* initialize query response buffer */ - qbufn = 0; - querybuf[0] = NUL; - } -#endif /* NOSPL */ - x = 1; - if (remfile) { /* Response redirected to file */ - rf_err = "Can't open file"; - if (rempipe) /* or pipe */ - x = -#ifndef NOPUSH - zxcmd(ZOFILE,remdest) /* Pipe: Start command */ -#else - 0 -#endif /* NOPUSH */ - ; - else - x = opena(remdest,&iattr); /* File: Open with attributes */ - debug(F111,"rcv_shortreply remfile",remdest,x); - } else { - x = opent(&iattr); /* "open" the screen */ - } - if (x) { /* If file was opened ok */ - if (decode(rdatap, -#ifndef NOSPL - (query || !remfile) ? puttrm : -#else - !remfile ? puttrm : -#endif /* NOSPL */ - zputfil, 1) < 0) { /* Note: zputfil, not putfil. */ - errpkt((CHAR *)"Error writing data"); - RESUME; - return(-1); - } else { - if (rdatap) /* If we had data */ - if (*rdatap) /* add a line terminator */ - if (remfile) { /* to file */ - zsoutl(ZOFILE,""); - } else { /* or to screen. */ -#ifndef NOICP - if (!query || !xcmdsrc) -#endif /* NOICP */ - if (!(quiet && rcdactive)) - conoll(""); - } - if (bye_active && network) { /* I sent BYE or REMOTE LOGOUT */ - msleep(500); /* command and got the ACK... */ - bye_active = 0; - ttclos(0); - } - clsof(0); - if (!epktsent && !epktrcvd) /* If no error packet... */ - success = 1; /* success. */ - RESUME; - return(-1); - } - } else { /* File not opened OK */ - errpkt((CHAR *) rf_err); /* send error message */ - RESUME; /* and quit. */ - return(-1); - } -#endif /* NOSERVER */ -#ifdef PKTZEROHACK - } -#endif /* PKTZEROHACK */ - debug(F101,"rcv_shortreply fallthru","",success); - return(-1); -} - - -static int -srv_query() { -#ifndef NOSERVER -#ifndef NOSPL - char c; -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE QUERY", (char *)srvcmd); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE QUERY", (char *)(srvcmd+2), ""); -#endif /* IKSDB */ - c = *(srvcmd+2); /* Q = Query, S = Set */ - if (c == 'Q') { /* Query */ - if (!ENABLED(en_que)) { /* Security */ - errpkt((CHAR *)"REMOTE QUERY disabled"); - RESUME; - return(-1); - } else { /* Query allowed */ - int n; char *p, *q; - qbufp = querybuf; /* Wipe out old stuff */ - qbufn = 0; - querybuf[0] = NUL; - p = (char *) srvcmd + 3; /* Pointer for making wrapper */ - n = strlen((char *)srvcmd); /* Position of end */ - c = *(srvcmd+4); /* Which type of variable */ - - if (*(srvcmd+6) == CMDQ) { /* Starts with command quote? */ - p = (char *) srvcmd + 6; /* Take it literally */ - if (*p == CMDQ) p++; - } else { /* They played by the rules */ - if (c == 'K') { /* Kermit variable */ - int k; - k = (int) strlen(p); - if (k > 0 && p[k-1] == ')') { - p = (char *)(srvcmd + 4); - *(srvcmd+4) = CMDQ; - *(srvcmd+5) = 'f'; /* Function, so make it \f...() */ - } else { - *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */ - *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */ - *(srvcmd+5) = '('; /* around variable name */ - *(srvcmd+n) = ')'; - *(srvcmd+n+1) = NUL; - } - } else { - *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */ - *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */ - *(srvcmd+5) = '('; /* around variable name */ - *(srvcmd+n) = ')'; - *(srvcmd+n+1) = NUL; - if (c == 'S') { /* System variable */ - *(srvcmd+4) = '$'; /* so it's \$(...) */ - } else if (c == 'G') { /* Non-\ Global variable */ - *(srvcmd+4) = 'm'; /* so wrap it in \m(...) */ - } - } - } /* Now evaluate it */ - n = QBUFL; /* Max length */ - q = querybuf; /* Where to put it */ - if (zzstring(p,&q,&n) < 0) { - errpkt((n > 0) ? (CHAR *)"Can't get value" - : (CHAR *)"Value too long" - ); - RESUME; - return(-1); - } else { - if (encstr((CHAR *)querybuf) > -1) { /* Encode it */ - ack1(data); /* If it fits, send it back in ACK */ - success = 1; - RESUME; - return(-1); - } else if (sndstring(querybuf)) { /* Long form response */ - BEGIN ssinit; - return(-1); - } else { /* sndhlp() fails */ - errpkt((CHAR *)"Can't send value"); - RESUME; - return(-1); - } - } - } - } else if (c == 'S') { /* Set (assign) */ - if (!ENABLED(en_asg)) { /* Security */ - errpkt((CHAR *)"REMOTE ASSIGN disabled"); - RESUME; - return(-1); - } else { /* OK */ - int n; - n = xunchar(*(srvcmd+3)); /* Length of name */ - n = 3 + n + 1; /* Position of length of value */ - *(srvcmd+n) = NUL; /* Don't need it */ - if (addmac((char *)(srvcmd+4),(char *)(srvcmd+n+1)) < 0) - errpkt((CHAR *)"REMOTE ASSIGN failed"); - else { - ack(); - success = 1; - } - RESUME; - return(-1); - } - } else { - errpkt((CHAR *)"Badly formed server command"); - RESUME; - return(-1); - } -#else - errpkt((CHAR *)"Variable query/set not available"); - RESUME; - return(-1); -#endif /* NOSPL */ -#endif /* NOSERVER */ -} - -static int -srv_copy() { -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE COPY", (char *)srvcmd); -#endif /* CKSYSLOG */ -#ifdef ZCOPY - if (!ENABLED(en_cpy)) { - errpkt((CHAR *)"REMOTE COPY disabled"); - RESUME; - return(-1); - } else { - char *str1, *str2, f1[256], f2[256]; - int len1, len2; - len1 = xunchar(srvcmd[1]); /* Separate the parameters */ - len2 = xunchar(srvcmd[2+len1]); - strncpy(f1,(char *)(srvcmd+2),len1); - f1[len1] = NUL; - strncpy(f2,(char *)(srvcmd+3+len1),len2); - f2[len2] = NUL; -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE COPY", f1, f2); -#endif /* IKSDB */ - if (!ENABLED(en_cwd)) { /* If CWD is disabled */ - zstrip(f1,&str1); /* and they included a pathname, */ - zstrip(f2,&str2); - if (strcmp(f1,str1) || strcmp(f2,str2)) { /* Refuse. */ - errpkt((CHAR *)"Access denied"); - RESUME; /* Remember, this is not a goto! */ - return(-1); - } - } - if (state == generic) { /* It's OK to go ahead. */ - if (zcopy(f1,f2)) { /* Try */ - errpkt((CHAR *)"Can't copy file"); /* give error message */ - } else { - success = 1; - ack(); - } - RESUME; /* wait for next server command */ - return(-1); - } - } - return(-1); -#else /* no ZCOPY */ - errpkt((CHAR *)"REMOTE COPY not available"); /* give error message */ - RESUME; /* wait for next server command */ - return(-1); -#endif /* ZCOPY */ -#endif /* NOSERVER */ -} - -static int -srv_rename() { -#ifndef NOSERVER -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE RENAME", (char *)srvcmd); -#endif /* CKSYSLOG */ -#ifdef ZRENAME - if (!ENABLED(en_ren)) { - errpkt((CHAR *)"REMOTE RENAME disabled"); - RESUME; - return(-1); - } else { /* RENAME is enabled */ - char *str1, *str2, f1[256], f2[256]; - int len1, len2; - len1 = xunchar(srvcmd[1]); /* Separate the parameters */ - len2 = xunchar(srvcmd[2+len1]); - strncpy(f1,(char *)(srvcmd+2),len1); - f1[len1] = NUL; - strncpy(f2,(char *)(srvcmd+3+len1),len2); - f2[len2] = NUL; - len2 = xunchar(srvcmd[2+len1]); - strncpy(f1,(char *)(srvcmd+2),len1); - f1[len1] = NUL; - strncpy(f2,(char *)(srvcmd+3+len1),len2); - f2[len2] = NUL; -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE RENAME", f1, f2); -#endif /* IKSDB */ - if (!ENABLED(en_cwd)) { /* If CWD is disabled */ - zstrip(f1,&str1); /* and they included a pathname, */ - zstrip(f2,&str2); - if ( strcmp(f1,str1) || strcmp(f2,str2) ) { /* refuse. */ - errpkt((CHAR *)"Access denied"); - RESUME; /* Remember, this is not a goto! */ - return(-1); - } - } - if (state == generic) { /* It's OK to go ahead. */ - if (zrename(f1,f2)) { /* Try */ - errpkt((CHAR *)"Can't rename file"); /* Give error msg */ - } else { - success = 1; - ack(); - } - RESUME; /* Wait for next server command */ - return(-1); - } - } - return(-1); -#else /* no ZRENAME */ - /* Give error message */ - errpkt((CHAR *)"REMOTE RENAME not available"); - RESUME; /* Wait for next server command */ - return(-1); -#endif /* ZRENAME */ -#endif /* NOSERVER */ -} - -static int -srv_login() { -#ifndef NOSERVER - char f1[LOGINLEN+1], f2[LOGINLEN+1], f3[LOGINLEN+1]; - CHAR *p; - int len, i; - - debug(F101,"REMOTE LOGIN x_login","",x_login); - debug(F101,"REMOTE LOGIN x_logged","",x_logged); - - f1[0] = NUL; f2[0] = NUL; f3[0] = NUL; - len = 0; - if (srvcmd[1]) /* First length field */ - len = xunchar(srvcmd[1]); /* Separate the parameters */ - - if (x_login) { /* Login required */ - if (x_logged) { /* And already logged in */ - if (len > 0) { /* Logging in again */ - errpkt((CHAR *)"Already logged in."); - } else { /* Logging out */ - debug(F101,"REMOTE LOGOUT","",x_logged); -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGOUT", NULL); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"REMOTE LOGOUT", "", ""); -#endif /* IKSDB */ - tlog(F110,"Logged out",x_user,0); - ack1((CHAR *)"Logged out"); - success = 1; - msleep(500); -#ifdef CK_LOGIN - x_logged = 0; -#ifdef IKSD - if (inserver) - ckxlogout(); -#endif /* IKSD */ -#endif /* CK_LOGIN */ - } - } else { /* Not logged in yet */ - debug(F101,"REMOTE LOGIN len","",len); - if (len > 0) { /* Have username */ -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGIN", NULL); -#endif /* CKSYSLOG */ - if (len > LOGINLEN) { - errpkt((CHAR *)"Username too long"); - } - p = srvcmd + 2; /* Point to it */ - for (i = 0; i < len; i++) /* Copy it */ - f1[i] = p[i]; - f1[len] = NUL; /* Terminate it */ - p += len; /* Point to next length field */ - if (*p) { /* If we have one */ - len = xunchar(*p++); /* decode it */ - if (len > 0 && len <= LOGINLEN) { - for (i = 0; i < len; i++) /* Same deal for password */ - f2[i] = p[i]; - f2[len] = NUL; - p += len; /* And account */ - if (*p) { - len = xunchar(*p++); - if (len > 0 && len <= LOGINLEN) { - for (i = 0; i < len; i++) - f3[i] = p[i]; /* Set but never used */ - f3[len] = NUL; /* (because account not used) */ - } - } - } - } - debug(F101,"REMOTE LOGIN 1","",x_logged); -#ifdef IKSD -#ifdef CK_LOGIN - if (inserver) { /* Log in to system for real */ - x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0); - debug(F101,"REMOTE LOGIN 2","",x_logged); - if (x_logged) { /* Count attempts */ - logtries = 0; - justone = 1; - } else { - logtries++; - sleep(logtries); - } - } else -#endif /* CK_LOGIN */ -#endif /* IKSD */ - if (x_user && x_passwd) { /* User and password must match */ - if (!strcmp(x_user,f1)) /* SET SERVER LOGIN */ - if (!strcmp(x_passwd,f2)) - x_logged = 1; - debug(F101,"REMOTE LOGIN 3","",x_logged); - } else if (x_user) { /* Only username given, no password */ - if (!strcmp(x_user,f1)) /* so only username must match */ - x_logged = 1; - debug(F101,"REMOTE LOGIN 4","",x_logged); - } -#ifdef CK_LOGIN - else { - x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0); - debug(F101,"REMOTE LOGIN 5","",x_logged); - } -#endif /* CK_LOGIN */ - if (x_logged) { /* Logged in? */ - tlog(F110,"Logged in", x_user, 0); - if (isguest) - ack1((CHAR *)"Logged in as guest - restrictions apply"); - else - ack1((CHAR *)"Logged in"); - success = 1; - } else { - tlog(F110,"Login failed", f1, 0); - errpkt((CHAR *)"Access denied."); -#ifdef IKSD -#ifdef CK_LOGIN - if (inserver && logtries > 2) - ckxlogout(); -#endif /* CK_LOGIN */ -#endif /* IKSD */ - } - } else { /* LOGOUT */ - errpkt((CHAR *)"Logout ignored"); - } - } - } else { /* Login not required */ - if (len > 0) - errpkt((CHAR *)"Login ignored."); - else - errpkt((CHAR *)"Logout ignored."); - } -#endif /* NOSERVER */ - RESUME; - return(-1); -} - -static int -srv_timeout() { - /* K95 does this its own way */ - if (idletmo) { -#ifdef IKSD - if (inserver) { - printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", srvidl); - doexit(GOOD_EXIT,xitsta); - } -#endif /* IKSD */ - idletmo = 0; - printf("\r\nSERVER IDLE TIMEOUT: %d sec\r\n", srvidl); - xitsta |= (what & W_KERMIT); - QUIT; - } -#ifndef NOSERVER - else if (fatalio) { /* Connection lost */ -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "Connection lost", NULL); -#endif /* CKSYSLOG */ -#ifdef IKSDB - if (ikdbopen) slotstate(what,"SERVER DISCONNECT",(char *)srvcmd, ""); -#endif /* IKSDB */ - xitsta |= what; - QUIT; - } else if (interrupted) { /* Interrupted by hand */ - if (!ENABLED(en_fin)) { - errpkt((CHAR *)"QUIT disabled"); - RESUME; - return(-1); - } else { - if (what == W_SEND || what == W_RECV || what == W_REMO) { - success = 0; -#ifdef CKSYSLOG - if (ckxsyslog >= SYSLG_PR && ckxlogging) - cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL); -#endif /* CKSYSLOG */ - } else if (what == W_NOTHING && filcnt == 0) { - success = 1; - } /* Otherwise leave success alone */ - xitsta |= (what & W_KERMIT); - QUIT; - } - } else { /* Shouldn't happen */ - debug(F100,"SERVER (top) GOT UNEXPECTED 'q'","",0); - QUIT; - } -#endif /* NOSERVER */ -} - -static int -rcv_s_pkt() { -#ifndef NOSERVER - if (state == rgen) - urserver = 1; - if (/* state == serve && */ x_login && !x_logged) { - errpkt((CHAR *)"Login required"); - SERVE; - } else -#endif /* NOSERVER */ - if (state == serve && !ENABLED(en_sen)) { /* Not in server mode */ - errpkt((CHAR *)"SEND disabled"); /* when SEND is disabled. */ - RESUME; - return(-1); - } else { /* OK to go ahead. */ -#ifdef CK_TMPDIR - if (dldir && !f_tmpdir) { /* If they have a download directory */ - debug(F110,"receive download dir",dldir,0); - if (s = zgtdir()) { /* Get current directory */ - debug(F110,"receive current dir",s,0); - if (zchdir(dldir)) { /* Change to download directory */ - debug(F100,"receive zchdir ok","",0); - ckstrncpy(savdir,s,TMPDIRLEN); - f_tmpdir = 1; /* Remember that we did this */ - } else - debug(F100,"receive zchdir failed","",0); - } - } -#endif /* CK_TMPDIR */ - nakstate = 1; /* Can send NAKs from here. */ - rinit(rdatap); /* Set parameters */ - bctu = bctr; /* Switch to agreed-upon block check */ - bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */ - what = W_RECV; /* Remember we're receiving */ - lastxfer = W_RECV; - resetc(); /* Reset counters */ - rtimer(); /* Reset timer */ -#ifdef GFTIMER - rftimer(); -#endif /* GFTIMER */ - streamon(); - BEGIN rfile; /* Go into receive-file state */ - } - return(-1); -} - - -/* END OF ROUTINES MOVED OUT OF STATE MACHINE */ - - -/* P R O T O -- Protocol entry function */ - -static int is_tn = 0; /* It's a Telnet connection */ - -#ifdef CK_SPEED -int f_ctlp = 0; /* Control-character prefix table */ -#ifdef COMMENT -short s_ctlp[256]; -#endif /* COMMENT */ -#endif /* CK_SPEED */ - -/* - This is simply a wrapper for the real protocol function just below, - that saves any items that might be changed automatically by protocol - negotiations and then restores them upon exit from protocol mode. -*/ -VOID -proto() { - extern int b_save, f_save, c_save, ss_save, slostart, reliable, urclear; -#ifndef NOCSETS - extern int fcharset, fcs_save, tcharset, tcs_save; -#endif /* NOCSETS */ - -#ifdef PIPESEND - extern int pipesend; -#endif /* PIPESEND */ -#ifndef NOLOCAL -#ifdef OS2 - extern int cursorena[], cursor_save, term_io; - extern BYTE vmode; - extern int display_demo; - int term_io_save; -#endif /* OS2 */ -#endif /* NOLOCAL */ -#ifdef TNCODE - int _u_bin=0, _me_bin = 0; -#ifdef IKS_OPTION - int /* _u_start=0, */ _me_start = 0; -#endif /* IKS_OPTION */ -#endif /* TNCODE */ -#ifdef PATTERNS - int pa_save; - int i; -#endif /* PATTERNS */ - int scan_save; - -#ifdef PATTERNS - pa_save = patterns; -#endif /* PATTERNS */ - scan_save = filepeek; - - myjob = sstate; - -#ifdef CK_LOGIN - if (isguest) { /* If user is anonymous */ - en_pri = 0; /* disable printing */ - en_mai = 0; /* and disable email */ - en_del = 0; /* and file deletion */ - } -#endif /* CK_LOGIN */ - -#ifndef NOLOCAL -#ifdef OS2 - cursor_save = cursorena[vmode]; - cursorena[vmode] = 0; - term_io_save = term_io; - term_io = 0; -#endif /* OS2 */ -#endif /* NOLOCAL */ - b_save = binary; /* SET FILE TYPE */ - f_save = fncnv; /* SET FILE NAMES */ - c_save = bctr; - p_save = fnspath; - r_save = recursive; - s_timint = timint; - ss_save = slostart; -#ifndef NOCSETS - fcs_save = fcharset; - tcs_save = tcharset; -#endif /* NOCSETS */ - -#ifdef COMMENT -/* Don't do this because then user can never find out what happened. */ -#ifdef CK_SPEED - for (i = 0; i < 256; i++) - s_ctlp[i] = ctlp[i]; - f_ctlp = 1; -#endif /* CK_SPEED */ -#endif /* COMMENT */ - if (reliable == SET_ON) - slostart = 0; - is_tn = (!local && sstelnet) -#ifdef TNCODE - || (local && network && ttnproto == NP_TELNET) -#endif /* TNCODE */ - ; -#ifdef TNCODE - if (is_tn) { - if (tn_b_xfer && !(sstelnet || inserver)) { - /* Save the current state of Telnet Binary */ - _u_bin = TELOPT_U(TELOPT_BINARY); - _me_bin = TELOPT_ME(TELOPT_BINARY); - - /* If either direction is not Binary attempt to negotiate it */ - if (!_u_bin && TELOPT_U_MODE(TELOPT_BINARY) != TN_NG_RF) { - tn_sopt(DO,TELOPT_BINARY); - TELOPT_UNANSWERED_DO(TELOPT_BINARY) = 1; - } - if (!_me_bin && TELOPT_ME_MODE(TELOPT_BINARY) != TN_NG_RF) { - tn_sopt(WILL,TELOPT_BINARY); - TELOPT_UNANSWERED_WILL(TELOPT_BINARY) = 1; - } - if (!(_me_bin && _u_bin)) - tn_wait("proto set binary mode"); - } -#ifdef IKS_OPTION -#ifdef CK_XYZ - if (protocol != PROTO_K) { /* Non-Kermit protocol selected */ - if (TELOPT_U(TELOPT_KERMIT) && - TELOPT_SB(TELOPT_KERMIT).kermit.u_start) { - iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */ - /* _u_start = 1; */ - } - if (TELOPT_ME(TELOPT_KERMIT) && - TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { - tn_siks(KERMIT_STOP); /* I'm not servering */ - TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0; - _me_start = 1; - } - } else -#endif /* CK_XYZ */ - if (sstate == 'x' || sstate == 'v') { /* Responding to a request */ - if (!inserver && TELOPT_U(TELOPT_KERMIT) && - TELOPT_SB(TELOPT_KERMIT).kermit.u_start) { - iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */ - /* _u_start = 1; */ - } - if (TELOPT_ME(TELOPT_KERMIT) && - !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { - tn_siks(KERMIT_START); /* Send Kermit-Server Start */ - TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1; - } - } else { /* Initiating a request */ - if (TELOPT_ME(TELOPT_KERMIT) && - TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { - tn_siks(KERMIT_STOP); /* I'm not servering */ - TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0; - _me_start = 1; - } - if (TELOPT_U(TELOPT_KERMIT) && - !TELOPT_SB(TELOPT_KERMIT).kermit.u_start) { - /* Send Req-Server-Start */ - if (!iks_wait(KERMIT_REQ_START,0)) { - if (sstate != 's') { - success = 0; /* Other Kermit refused to serve */ - if (local) - printf("A Kermit Server is not available\r\n"); - debug(F110,"proto()", - "A Kermit Server is not available",0); - tlog(F110,"IKS client/server failure", - "A Kermit Server is not available",0); - goto xxprotox; - } - } - } - } -#endif /* IKS_OPTION */ -#ifdef CK_ENCRYPTION - if (tn_no_encrypt_xfer && !(sstelnet || inserver)) { - ck_tn_enc_stop(); - } -#endif /* CK_ENCRYPTION */ - } -#endif /* TNCODE */ - - if (!xfrint) connoi(); - xxproto(); /* Call the real protocol function */ - -#ifdef IKS_OPTION - xxprotox: -#endif /* IKS_OPTION */ - xferstat = success; /* Remember transfer status */ - kactive = 0; - -#ifdef TNCODE -#ifdef CK_ENCRYPTION - if (tn_no_encrypt_xfer && !(sstelnet || inserver)) { - ck_tn_enc_start(); - } -#endif /* CK_ENCRYPTION */ -#ifdef IKS_OPTION - if (TELOPT_ME(TELOPT_KERMIT) && - TELOPT_SB(TELOPT_KERMIT).kermit.me_start && !_me_start) { - tn_siks(KERMIT_STOP); /* Server is stopped */ - TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0; - } -#endif /* IKS_OPTION */ - if (is_tn && tn_b_xfer && !(sstelnet || inserver)) { - /* if we negotiated Binary mode try to reset it */ - if (!_u_bin) { - /* Check to see if the state changed during the transfer */ - if (TELOPT_U(TELOPT_BINARY)) { - tn_sopt(DONT,TELOPT_BINARY); - TELOPT_UNANSWERED_DONT(TELOPT_BINARY) = 1; - } else - _u_bin = 1; /* So we don't call tn_wait() */ - } - if (!_me_bin) { - /* Check to see if the state changed during the transfer */ - if (TELOPT_ME(TELOPT_BINARY)) { - tn_sopt(WONT,TELOPT_BINARY); - TELOPT_UNANSWERED_WONT(TELOPT_BINARY) = 1; - } else - _me_bin = 1; /* So we don't call tn_wait() */ - } - if (!(_me_bin && _u_bin)) - tn_wait("proto reset binary mode"); - } -#endif /* TNCODE */ - -#ifdef PATTERNS - patterns = pa_save; -#endif /* PATTERNS */ - filepeek = scan_save; - -#ifdef STREAMING - streaming = 0; - /* streamok = 0; */ -#endif /* STREAMING */ -#ifdef COMMENT -#ifdef CK_SPEED - for (i = 0; i < 256; i++) - ctlp[i] = s_ctlp[i]; - f_ctlp = 0; -#endif /* CK_SPEED */ -#endif /* COMMENT */ - urclear = 0; - if (!success) { - xitsta |= (what & W_KERMIT); - tlog(F110," failed:",(char *)epktmsg,0); - } - debug(F111,"proto xferstat",epktmsg,xferstat); - slostart = ss_save; - if (s_timint > -1) { /* Because of REMOTE SET */ - timint = s_timint; - s_timint = -1; - } - recursive = r_save; - fnspath = p_save; - if (c_save > -1) { /* Because of REMOTE SET */ - bctr = c_save; - c_save = -1; - } - fncnv = f_save; - binary = b_save; -#ifdef PIPESEND - pipesend = 0; /* Next time might not be pipesend */ -#endif /* PIPESEND */ -#ifndef NOLOCAL -#ifdef OS2 - cursorena[vmode] = cursor_save; - term_io = term_io_save; - display_demo = 1; -#endif /* OS2 */ -#endif /* NOLOCAL */ -} - -static VOID -xxproto() { - int x; - long lx; -#ifdef CK_XYZ -#ifdef XYZ_INTERNAL -_PROTOTYP( int pxyz, (int) ); -#endif /* XYZ_INTERNAL */ -#endif /* CK_XYZ */ - - char xss[2]; /* String representation of sstate */ - xss[0] = sstate; - xss[1] = NUL; - s_timint = timint; - - debug(F101,"xxproto entry justone","",justone); - success = 0; - - retrieve = 0; /* Reset these ... */ - reget = 0; - opkt = 0; - - if (local && ttchk() < 0) { /* Giving BYE or FIN */ - if (bye_active) { /* but there is no connection */ - ttclos(0); - success = 1; - return; - } - /* Ditto for any REMOTE command */ - if (sstate == 'g' && cmarg ) { - if (*cmarg == 'L' || *cmarg == 'F' || *cmarg == 'X') - success = 1; - else - printf("?No connection\r\n"); - return; - } - } - -/* Set up the communication line for file transfer. */ -/* NOTE: All of the xxscreen() calls prior to the wart() invocation */ -/* could just as easily be printf's or, for that matter, hints. */ - - if (local && (speed < 0L) && (network == 0)) { - xxscreen(SCR_EM,0,0L,"Sorry, you must 'set speed' first"); - return; - } - x = -1; - if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) { - debug(F111,"failed: proto ttopen local",ttname,local); - xxscreen(SCR_EM,0,0L,"Can't open line"); - return; - } - if (x > -1) local = x; - debug(F111,"proto ttopen local",ttname,local); - - lx = (local && !network) ? speed : -1; -#ifdef NETCONN -#ifdef CK_SPEED - if (is_tn) { - ctlp[(unsigned)255] = ctlp[CR] = 1; - if (parity == 'e' || parity == 'm') ctlp[127] = 1; - if (flow == FLO_XONX) { /* Also watch out for Xon/Xoff */ - ctlp[17] = ctlp[19] = 1; - ctlp[17+128] = ctlp[19+128] = 1; - } - } -#endif /* CK_SPEED */ -#endif /* NETCONN */ - if (ttpkt(lx,flow,parity) < 0) { /* Put line in packet mode, */ - xxscreen(SCR_EM,0,0L,"Can't condition line"); - return; - } - if (local && !network && carrier != CAR_OFF) { - int x; /* Serial connection */ - x = ttgmdm(); /* with carrier checking */ - if (x > -1) { - if (!(x & BM_DCD)) { - debug(F101,"proto ttgmdm","",0); - xxscreen(SCR_EM,0,0L,"Carrier required but not detected"); - return; - } - } - } - /* Send remote side's "receive" or "server" startup string, if any */ - if (local && ckindex((char *)xss,"srgcjhk",0,0,1)) { - char *s = NULL; - if ( -#ifdef IKS_OPTION - /* Don't send auto-blah string if we know other side is serving */ - !TELOPT_U(TELOPT_KERMIT) || - !TELOPT_SB(TELOPT_KERMIT).kermit.u_start -#else - 1 -#endif /* IKS_OPTION */ - ) { - if (sstate == 's') { /* Sending file(s) */ - s = binary ? ptab[protocol].h_b_init : ptab[protocol].h_t_init; - } else if (protocol == PROTO_K) { /* Command for server */ - s = ptab[protocol].h_x_init; - } - } -#ifdef CK_SPEED -#ifndef UNPREFIXZERO - if (protocol == PROTO_K) /* Because of C-strings... */ - ctlp[0] = 1; -#endif /* UNPREFIXZERO */ -#endif /* CK_SPEED */ - if (s) if (*s) { /* If we have a command to send... */ - char tmpbuf[356]; - int tmpbufsiz = 356; - int stuff = -1, stuff2 = -1, len = 0; - extern int tnlm; - if (sstate == 's') { /* Sending file(s) */ -#ifdef CK_XYZ - if (protocol == PROTO_X) { - char * s2; - s2 = cmarg2[0] ? cmarg2 : cmarg; - if ((int)strlen(s) + (int)strlen(s2) + 4 < 356) - sprintf(tmpbuf, s, s2); - else - tmpbuf[0] = NUL; - } else { -#endif /* CK_XYZ */ - ckmakmsg(tmpbuf, 356, s, NULL, NULL, NULL); -#ifdef CK_XYZ - } -#endif /* CK_XYZ */ - } else { /* Command for server */ - ckstrncpy(tmpbuf,s,356); - } - ckstrncat(tmpbuf, "\015",sizeof(tmpbuf)); - if (tnlm) /* TERMINAL NEWLINE ON */ - stuff = LF; /* Stuff LF */ -#ifdef TNCODE - /* TELNET NEWLINE MODE */ - if (is_tn) { - switch (TELOPT_ME(TELOPT_BINARY) ? tn_b_nlm : tn_nlm) { - case TNL_CR: - break; - case TNL_CRNUL: - break; - case TNL_CRLF: - stuff2 = stuff; - stuff = LF; - break; - } - } -#endif /* TNCODE */ - -#ifdef NETCONN -#ifdef TCPSOCKET -#ifdef RLOGCODE - if (network && ttnproto == NP_RLOGIN) { - switch (tn_b_nlm) { /* Always BINARY */ - case TNL_CR: - break; - case TNL_CRNUL: - stuff2 = stuff; - stuff = NUL; - break; - case TNL_CRLF: - stuff2 = stuff; - stuff = LF; - break; - } - } -#endif /* RLOGCODE */ -#endif /* TCPSOCKET */ -#endif /* NETCONN */ - - len = strlen(tmpbuf); - if (stuff >= 0 && len < tmpbufsiz - 1) { - tmpbuf[len++] = stuff; - if (stuff2 >= 0 && len < tmpbufsiz - 1) - tmpbuf[len++] = stuff2; - tmpbuf[len] = NUL; - } - ttol((CHAR *)tmpbuf,len); - if (protocol == PROTO_K) /* Give remote Kermit time to start */ - msleep(400); - } - } - -#ifdef CK_XYZ - if (protocol != PROTO_K) { /* Non-Kermit protocol selected */ - char tmpbuf[356]; - int tmpbufsiz = 356; - char * s = ""; - -#ifdef CK_TMPDIR - if (sstate == 'v') { /* If receiving and... */ - if (dldir && !f_tmpdir) { /* if they have a download directory */ - if (s = zgtdir()) { /* Get current directory */ - if (zchdir(dldir)) { /* Change to download directory */ - ckstrncpy(savdir,s,TMPDIRLEN); - f_tmpdir = 1; /* Remember that we did this */ - } - } - } - } -#endif /* CK_TMPDIR */ - -#ifdef XYZ_INTERNAL /* Internal */ - success = !pxyz(sstate); -#else -#ifdef CK_REDIR /* External */ - switch (sstate) { - case 's': /* 'Tis better to SEND... */ - s = binary ? ptab[protocol].p_b_scmd : ptab[protocol].p_t_scmd; - break; - case 'v': /* ... than RECEIVE */ - s = binary ? ptab[protocol].p_b_rcmd : ptab[protocol].p_t_rcmd; - break; - } - if (!s) s = ""; - if (*s) { - if (sstate == 's') { - if ((int)strlen(s) + (int)strlen(fspec) < tmpbufsiz) { - sprintf(tmpbuf,s,fspec); /* safe (prechecked) */ - tlog(F110,"Sending",fspec,0L); - } - } else { - if ((int)strlen(s) + (int)strlen(cmarg2) < tmpbufsiz) { - sprintf(tmpbuf,s,cmarg2); /* safe (prechecked) */ - tlog(F110,"Receiving",cmarg2,0L); - } - } - tlog(F110," via external protocol:",tmpbuf,0); - debug(F110,"ckcpro ttruncmd",tmpbuf,0); - success = ttruncmd(tmpbuf); - tlog(F110," status:",success ? "OK" : "FAILED", 0); - } else { - printf("?Sorry, no external protocol defined for %s\r\n", - ptab[protocol].p_name - ); - } -#else - printf( -"Sorry, only Kermit protocol is supported in this version of Kermit\n" - ); -#endif /* CK_REDIR */ -#endif /* XYZ_INTERNAL */ - return; - } -#endif /* CK_XYZ */ - -#ifdef NTSIGX - conraw(); - connoi(); -#else - if (!local) - connoi(); /* No console interrupts if remote */ -#endif /* NTSIG */ - - kactive = 1; - if (sstate == 'x') { /* If entering server mode, */ - extern int howcalled; - server = 1; /* set flag, */ - debug(F101,"server backgrd","",backgrd); - debug(F101,"server quiet","",quiet); - debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0); - if (howcalled == I_AM_SSHSUB) { /* and issue appropriate message. */ - ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26); - } else if (!local) { - if (!quiet && !backgrd -#ifdef IKS_OPTION - && !TELOPT_ME(TELOPT_KERMIT) /* User was told by negotiation */ -#endif /* IKS_OPTION */ - ) { - conoll(srvtxt); - conoll("KERMIT READY TO SERVE..."); - } - } else { - conol("Entering server mode on "); - conoll(ttname); - conoll("Type Ctrl-C to quit."); - if (srvdis) intmsg(-1L); -#ifdef TCPSOCKET -#ifndef NOLISTEN - if (network && tcpsrfd > 0) - ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26); -#endif /* NOLISTEN */ -#endif /* TCPSOCKET */ - } - } else - server = 0; -#ifdef VMS - if (!quiet && !backgrd) /* So message doesn't overwrite prompt */ - conoll(""); - if (local) conres(); /* So Ctrl-C will work */ -#endif /* VMS */ -/* - If in remote mode, not shushed, not in background, and at top command level, - issue a helpful message telling what to do... -*/ - if (!local && !quiet && !backgrd) { - if (sstate == 'v') { - conoll("Return to your local Kermit and give a SEND command."); - conoll(""); - conoll("KERMIT READY TO RECEIVE..."); - } else if (sstate == 's') { - conoll("Return to your local Kermit and give a RECEIVE command."); - conoll(""); - conoll("KERMIT READY TO SEND..."); - } else if ( sstate == 'g' || sstate == 'r' || sstate == 'h' || - sstate == 'j' || sstate == 'c' ) { - conoll("Return to your local Kermit and give a SERVER command."); - conoll(""); - conoll((sstate == 'r' || sstate == 'j' || sstate == 'h') ? - "KERMIT READY TO GET..." : - "KERMIT READY TO SEND SERVER COMMAND..."); - } - } -#ifdef COMMENT - if (!local) sleep(1); -#endif /* COMMENT */ -/* - The 'wart()' function is generated by the wart program. It gets a - character from the input() routine and then based on that character and - the current state, selects the appropriate action, according to the state - table above, which is transformed by the wart program into a big case - statement. The function is active for one transaction. -*/ - rtimer(); /* Reset elapsed-time timer */ -#ifdef GFTIMER - rftimer(); -#endif /* GFTIMER */ - resetc(); /* & other per-transaction counters. */ - - debug(F101,"proto calling wart, justone","",justone); - - wart(); /* Enter the state table switcher. */ -/* - Note: the following is necessary in case we have just done a remote-mode - file transfer, in which case the controlling terminal modes have been - changed by ttpkt(). In particular, special characters like Ctrl-C and - Ctrl-\ might have been turned off (see ttpkt). So this call to ttres() is - essential. IMPORTANT: restore interrupt handlers first, otherwise any - terminal interrupts that occur before this is done in the normal place - later will cause a crash. -*/ -#ifdef OS2 - ttres(); /* Reset the communication device */ -#else - if (!local) { - setint(); /* Arm interrupt handlers FIRST */ - msleep(500); - ttres(); /* Then restore terminal. */ - } -#endif /* OS2 */ - xxscreen(SCR_TC,0,0L,""); /* Transaction complete */ - x = quiet; - quiet=1; - clsif(); /* Failsafe in case we missed */ - clsof(1); /* a case in the state machine. */ - quiet = x; - - if (server) { /* Back from packet protocol. */ - if (!quiet && !backgrd -#ifdef IKSD - && !inserver -#endif /* IKSD */ - ) { /* Give appropriate message */ - conoll(""); - conoll("C-Kermit server done"); - } - server = 0; /* Not a server any more */ - } -} - -/* S G E T I N I T -- Handle incoming GET-Class packets */ - -/* - Returns: - -1: On error - 0: GET packet processed OK - ready to Send. - 1: Extended GET processed OK - wait for another. -*/ -static int -sgetinit(reget,xget) int reget, xget; { /* Server end of GET command */ - char * fs = NULL; /* Pointer to filespec */ - int i, n, done = 0; -#ifdef PIPESEND - extern int usepipes, pipesend; -#endif /* PIPESEND */ - extern int nolinks; - - if (!ENABLED(en_get)) { /* Only if not disabled! */ - errpkt((CHAR *)"GET disabled"); - return(-1); - } - - /* OK to proceed */ - - nolinks = recursive; - filcnt = 0; - -#ifdef WHATAMI - /* If they are alike this was already done in whoarewe() */ - debug(F101,"sgetinit whatru","",whatru); - if (whatru & WMI_FLAG) { /* Did we get WHATAMI info? */ - debug(F101,"sgetinit binary (1)","",binary); -#ifdef VMS - if (binary != XYFT_I && binary != XYFT_L) -#else -#ifdef OS2 - if (binary != XYFT_L) -#endif /* OS2 */ -#endif /* VMS */ - binary = (whatru & WMI_FMODE) ? /* Yes, set file type */ - XYFT_B : XYFT_T; /* automatically */ - debug(F101,"sgetinit binary (2)","",binary); - if (!wearealike) - fncnv = (whatru & WMI_FNAME) ? 1 : 0; /* And name conversion */ - } -#endif /* WHATAMI */ - - fs = (char *)srvcmd; - srvptr = srvcmd; /* Point to server command buffer */ - decode(rdatap,putsrv,0); /* Decode the GET command into it */ - /* Accept multiple filespecs */ - cmarg2 = ""; /* Don't use cmarg2 */ - cmarg = ""; /* Don't use cmarg */ - - done = 1; /* Only 1 packet needed... */ - if (xget) { /* Special decoding for Extended GET */ - char L, next, c; /* PLV items */ - int len, val; /* More PLV items */ - char * p = (char *)srvcmd; /* String to decode */ - - done = 0; /* Maybe more packets needed */ - fs = NULL; /* We don't know the filespec yet */ - c = *p++; /* Get first parameter */ - - while (c) { /* For all parameters... */ - debug(F000,"sgetinit c","",c); - L = *p++; /* Get length */ - if (L >= SP) /* Decode length */ - len = xunchar(L); - else if (c == '@') { /* Allow missing EOP length field */ - len = 0; - } else { - len = (xunchar(*p++) * 95); - len += xunchar(*p++); - } - debug(F101,"sgetinit len","",len); - next = *(p+len); /* Get next parameter */ - *(p+len) = NUL; /* Zero it out to terminal value */ - debug(F110,"sgetinit p",p,0); - switch (c) { /* Do the parameter */ - case 'O': /* GET Options */ - val = atoi(p); /* Convert to int */ - debug(F101,"sgetinit O val","",val); - if (val & GOPT_DEL) moving = 1; - if (val & GOPT_RES) reget = 1; - if (val & GOPT_REC) { - recursive = 1; - nolinks = 2; - if (fnspath == PATH_OFF) - fnspath = PATH_REL; - } - break; - case 'M': /* Transfer Mode */ - val = atoi(p); - debug(F101,"sgetinit M val","",val); - if (val < 1) - break; - patterns = 0; /* Takes precedence over patterns */ - filepeek = 0; /* and FILE SCAN */ - if (val == GMOD_TXT) binary = XYFT_T; /* Text */ - if (val == GMOD_BIN) binary = XYFT_B; /* Binary */ - if (val == GMOD_LBL) binary = XYFT_L; /* Labeled */ - break; - case 'F': /* Filename */ - fs = p; - debug(F110,"sgetinit filename",fs,0); - break; - case '@': /* End Of Parameters */ - done = 1; - debug(F100,"sgetinit EOP","",0); - break; - default: - errpkt((CHAR *)"Unknown GET Parameter"); - debug(F100,"sgetinit unknown parameter","",0); - return(-1); - } - p += (len + 1); - c = next; - } - } - if (!fs) fs = ""; /* A filename is required */ - if (*fs) { - havefs = 1; - n = 0; /* Check for quoted name */ - if ((n = strlen(fs)) > 1) { - /* Note: this does not allow for multiple quoted names */ - if ((fs[0] == '{' && fs[n-1] == '}') || - (fs[0] == '"' && fs[n-1] == '"')) { - fs[n-1] = '\0'; - fs++; - debug(F111,"sgetinit unquoted filename",fs,n); - } else - n = 0; /* This means no quoting */ - } - -#ifdef PIPESEND - debug(F111,"sgetinit",fs,usepipes); - if (usepipes && ENABLED(en_hos) && *fs == '!') { - cmarg = fs + 1; /* Point past the bang */ - *fs = NUL; - nfils = -1; - pipesend = 1; - debug(F111,"sgetinit pipesend",cmarg,pipesend); - } - if (!pipesend) { /* If it's not a pipe */ -#endif /* PIPESEND */ - if (n == 0) { /* If the name was not quoted */ -#ifndef NOMSEND - nfils = fnparse(fs); /* Allow it to be a list of names */ - debug(F111,"sgetinit A",fs,nfils); -#ifdef COMMENT -/* This doesn't work if a GET-PATH is set. */ - if (nfils == 1 && !iswild(fs)) { /* Single file */ - char * m; - if ((x = zchki(fs)) < 0) { /* Check if it's sendable */ - switch (x) { - case -1: m = "File not found"; break; - case -2: m = "Not a regular file"; break; - case -3: m = "Read access denied"; break; - } - errpkt((CHAR *)m); - return(-1); - } - } -#endif /* COMMENT */ - } else { /* If it was quoted */ -#endif /* NOMSEND */ - nzxopts = 0; -#ifdef UNIXOROSK - if (matchdot) nzxopts |= ZX_MATCHDOT; -#endif /* UNIXOROSK */ - if (recursive) nzxopts |= ZX_RECURSE; - /* Treat as a single filespec */ - nfils = 0 - nzxpand(fs,nzxopts); - debug(F111,"sgetinit B",fs,nfils); - cmarg = fs; - } -#ifdef PIPESEND - } -#endif /* PIPESEND */ - } - if (!done) { /* Need more O packets... */ - debug(F100,"sgetinit O-Packet TBC","",0); /* To Be Continued */ - return(1); - } - debug(F100,"sgetinit O-Packet done - havefs","",havefs); - if (!havefs) { /* Done - make sure we have filename */ - errpkt((CHAR *)"GET without filename"); - return(-1); - } - freerpkt(winlo); - winlo = 0; /* Back to packet 0 again. */ - debug(F101,"sgetinit winlo","",winlo); - nakstate = 0; /* Now I'm the sender! */ - if (reget) sendmode = SM_RESEND; - if (sinit() > 0) { /* Send Send-Init */ -#ifdef STREAMING - if (!streaming) -#endif /* STREAMING */ - timint = chktimo(rtimo,timef); /* Switch to per-packet timer */ - return(0); /* If successful, switch state */ - } else return(-1); /* Else back to server command wait */ -} - -#else /* NOXFER */ - -#include "ckcdeb.h" - -VOID -proto() { - extern int success; - success = 0; -} -#endif /* NOXFER */ diff --git a/.pc/060_speeling.patch/ckermit80.txt b/.pc/060_speeling.patch/ckermit80.txt deleted file mode 100644 index 493338a..0000000 --- a/.pc/060_speeling.patch/ckermit80.txt +++ /dev/null @@ -1,10349 +0,0 @@ - - C-Kermit 8.0 Update Notes - - [ [1]Contents ] [ [2]C-Kermit ] [ [3]Kermit Home ] - - Second Supplement to Using C-Kermit, Second Edition - -For C-Kermit 8.0 - - As of C-Kermit version: 8.0.211 - Date of C-Kermit release: 10 April 2003 - This file last updated: Sat Apr 10 16:36:11 2004 - - * IF YOU ARE READING A PLAIN-TEXT version of this document, note - that it is a plain-text dump of a Web page. You can visit the - original (and possibly more up-to-date) Web page here: - [4]http://www.columbia.edu/kermit/ckermit80.html - * If you are reading the HTML version of this file with a GUI Web - browser, the features added since C-Kermit 8.0.201 are shown in - red if your browser and monitor permit. Features that were new to - versions 8.0.200 and 201 are in black. - -Authors: Frank da Cruz and Christine M. Gianone -Address: The Kermit Project - Columbia University - 612 West 115th Street - New York NY 10025-7799 - USA -Fax: +1 (212) 662-6442 -E-Mail: [5]kermit-support@columbia.edu -Web: [6]http://www.columbia.edu/kermit/ -Or: [7]http://www.kermit-project.org/ -Or: [8]http://www.columbia.nyc.ny.us/kermit/ - _________________________________________________________________ - - NOTICES - - This document: - Copyright © 1997, 2002, Frank da Cruz and Christine M. Gianone. - All rights reserved. - - Kermit 95: - Copyright © 1995, 2002, Trustees of Columbia University in the - City of New York. All rights reserved. - - C-Kermit: - Copyright © 1985, 2002, - Trustees of Columbia University in the City of New York. All - rights reserved. See the C-Kermit [9]COPYING.TXT file or the - copyright text in the [10]ckcmai.c module for disclaimer and - permissions. - - When Kerberos(TM) and/or SRP(TM) (Secure Remote Password) and/or - SSL/TLS protocol are included: - Portions Copyright © 1990, Massachusetts Institute of - Technology. - Portions Copyright © 1991, 1993 Regents of the University of - California. - Portions Copyright © 1991, 1992, 1993, 1994, 1995 by AT&T. - Portions Copyright © 1997, Stanford University. - Portions Copyright © 1995-1997, Eric Young - . - - For the full text of the third-party copyright notices, see - [11]Appendix V. - _________________________________________________________________ - - WHAT IS IN THIS FILE - - This file lists changes made to C-Kermit since version 7.0 was - released in January 2000. Use this file as a supplement to: - - * The second edition of [12]Using C-Kermit; and: - * The [13]C-Kermit 7.0 Update Notes. Also available in plain-text - form as [14]ckermit70.txt. - - until the third edition of Using C-Kermit is published. We apologize - for the scattered documentation and will consolidate it when we are - able. - _________________________________________________________________ - - ADDITIONAL FILES Several other files accompany this new Kermit - release: - - [15]ckututor.html - C-Kermit Tutorial (for Unix). Also distributed in Nroff form as - [16]ckuker.nr, the Unix C-Kermit manual page. - - [17]security.htm - Discussion of Kermit's new authentication and encryption - features, updated for C-Kermit 8.0. - - [18]telnet.htm - Detailed documentation of Kermit's Telnet client, updated for - C-Kermit 8.0. - - [19]ftpscripts.html - Tutorial: Writing FTP automation scripts - - [20]ckcbwr.html - Platform-independent C-Kermit hints and tips. Also distributed - in plain text form as [21]ckcbwr.txt - - [22]ckubwr.html - Unix-specific C-Kermit hints and tips. Also distributed in - plain text form as [23]ckubwr.txt. - - [24]ckvbwr.html - VMS-specific C-Kermit hints and tips. Also distributed in plain - text form as [25]ckvbwr.txt. - - [26]ckuins.html - Unix C-Kermit installation instructions. Also distributed in - plain text form as [27]ckuins.txt. - - [28]ckvins.html - VMS C-Kermit installation instructions. Also distributed in - plain text form as [29]ckvins.txt. - - [30]ckccfg.html - Compile-time configuration options. Also distributed in plain - text form as [31]ckccfg.txt. - - [32]ckcplm.html - C-Kermit Program Logic Manual. Also distributed in plain text - form as [33]ckcplm.txt. - - [34]iksd.html - Internet Kermit Service Aministrators Guide for Unix. - - [35]skermit.html - C-Kermit as an SSH Subsystem (SFTP server replacement). - - [ [36]Top ] [ [37]C-Kermit ] [ [38]Kermit Home ] - __________________________________________________________________________ - -CONTENTS - - [39]0. WHAT'S NEW - [40]1. FIXES SINCE VERSION 7.0.196 - [41]2. SSH AND HTTP - [42]2.1. SSH Connections - [43]2.2. HTTP Connections - [44]2.2.1. HTTP Command Switches - [45]2.2.2. HTTP Action Commands - [46]2.2.3. HTTP Headers - [47]2.2.4. Secure HTTP Connections - [48]2.2.5. HTTP Variables - [49]2.2.6. The HTTP Command-Line Personality - [50]3. THE BUILT-IN FTP CLIENT - [51]3.1. Making and Managing FTP Connections - [52]3.1.1. Kermit Command-Line Options for FTP - [53]3.1.2. The FTP Command-Line Personality - [54]3.1.3. The FTP URL Interpreter - [55]3.1.4. Interactive FTP Session Establishment - [56]3.2. Making Secure FTP Connections - [57]3.3. Setting FTP Preferences - [58]3.4. Managing Directories and Files - [59]3.5. Uploading Files With FTP - [60]3.5.1. FTP PUT Switches - [61]3.5.2. Update Mode - [62]3.5.3. Recovery - [63]3.6. Downloading Files With FTP - [64]3.6.1. FTP GET Switches - [65]3.6.2. Filename Collisions - [66]3.6.3. Recovery - [67]3.7. Translating Character Sets - [68]3.7.1. Character Sets and Uploading - [69]3.7.2. Character Sets and Downloading - [70]3.8. FTP Command Shortcuts - [71]3.9. Dual Sessions - [72]3.10. Automating FTP Sessions - [73]3.10.1. FTP-Specific Variables and Functions - [74]3.10.2. Examples - [75]3.10.3. Automating Secure FTP Connections - [76]3.11. Advanced FTP Protocol Features [77]4. FILE SCANNING - [78]5. FILE AND DIRECTORY NAMES CONTAINING SPACES - [79]6. OTHER COMMAND PARSING IMPROVEMENTS - [80]6.1. Grouping Macro Arguments - [81]6.2. Directory and File Name Completion - [82]6.3. Passing Arguments to Command Files - [83]6.4. More-Prompting - [84]6.5. Commas in Macro Definitions - [85]6.6. Arrow Keys - [86]7. NEW COMMANDS AND SWITCHES - [87]8. SCRIPTING IMPROVEMENTS - [88]8.1. Performance and Debugging - [89]8.2. Using Macros as Numeric Variables - [90]8.3. New IF Conditions - [91]8.4. The ON_UNKNOWN_COMMAND and ON_CD Macros - [92]8.5. The SHOW MACRO Command - [93]8.6. Arrays - [94]8.7. New or Improved Built-in Variables and Functions - [95]8.8. The RETURN and END Commands - [96]8.9. UNDEFINing Groups of Variables - [97]8.10. The INPUT and MINPUT Commands - [98]8.11. Learned Scripts - [99]8.12. Pattern Matching - [100]8.13. Dates and Times - [101]8.14. Trapping Keyboard Interruption - [102]9. S-EXPRESSIONS - [103]9.1. What is an S-Expression? - [104]9.2. Integer and Floating-Point-Arithmetic - [105]9.3. How to Use S-Expressions - [106]9.4. Summary of Built-in Constants and Operators - [107]9.5. Variables - [108]9.6. Assignments and Scope - [109]9.7. Conditional Expressions - [110]9.8. Extensibility - [111]9.9. Examples - [112]9.10. Differences from Algebraic Notation - [113]9.11.Differences from Lisp - [114]10. FILE TRANSFER - [115]11. MODEMS AND DIALING - [116]12. TERMINAL CONNECTION - [117]13. CHARACTER SETS - [118]14. DIALOUT FROM TELNET TERMINAL SERVERS - [119]15. COPING WITH BROKEN KERMIT PARTNERS - [120]16. NEW COMMAND-LINE OPTIONS - [121]17. LOGS - - [ [122]Top ] [ [123]C-Kermit ] [ [124]Kermit Home ] - __________________________________________________________________________ - -0. WHAT'S NEW - - The Initialization and Customization Files - C-Kermit 8.0 now supports specification of the initialization - file name (path) in an environment variable, CKERMIT_INI. It - also relies far less than before on the initialization for - functioning. See [125]Section 5 of the Unix C-Kermit - [126]installation instructions for details. As of version - 8.0.201, C-Kermit also executes your customization file (if you - have one) even if the initialization file was not found. - Previously, the customization file was executed by a TAKE - command in the initialization file (and it still is, if an - initialization is found). - - Incompatible Changes - As always, we do our best to avoid changes that break existing - scripts. However, C-Kermit 8.0 does include a rather pervasive - syntax change that might alter the behavior of scripts that - depend on the previous behavior. As described in [127]Section - 5, C-Kermit now accepts doublequotes in most contexts where you - previously had to use braces to group multiple words into a - single field, or to force inclusion of leading or trailing - blanks. Most noticeably, in C-Kermit 7.0 and earlier: - - echo {this is a string} - - would print: - - this is a string - - whereas: - - echo "this is a string" - - printed: - - "this is a string" - - In C-Kermit 8.0, both print: - - this is a string - - To force the doublequotes to be treated as part of the string, - use either of the following forms: - - echo {"this is a string"} - echo ""this is a string"" - - Similarly, to force braces to be treated as part of the string: - - echo "{this is a string}" - echo {{this is a string}} - - Other incompatibilities: - - 1. Using the SET HOST command to make HTTP connections is no - longer supported. Instead, use the new HTTP OPEN command, - described in [128]Section 2.2. - - C-Kermit 7.1 Alpha.01 (8 December 2000) - - Its major new features are those listed in the [129]Table of - Contents: the FTP client, file scanning, command parsing and - scripting improvements, S-Expressions, and support for the - Telnet Com Port Option, plus wider availability of the - Kerberos, SSL/TLS, and SRP security options for secure Internet - connections. - - C-Kermit 7.1.199 Alpha.02 (4 January 2001) - - + C-Kermit now accepts [130]FTP, TELNET, and IKSD URLs as its - first command-line argument. - + Character-set translation added to the FTP client for - [131]filenames. - + Optional [132]setting of date of incoming files by FTP [M]GET - from the server date. - + [133]FTP CHECK filename added to let FTP client check the - existence of a file on the server. - + [134]FTP GET /NAMELIST:filename added to get list of server - filenames into a local file. - + [135]FTP [M]PUT /SERVER-RENAME:template added to make server - rename a file as indicated by the template after it has - arrived completely. - + FTP [M]GET /SERVER-RENAME:template added to make server - rename a file as indicated by the template after it has been - sent completely. - + FTP [136]VDIRECTORY added for getting verbose directory - listings from TOPS-20. - + [137]FTP TYPE TENEX added for transferring 8-bit binary files - with PDP-10s. - + Added [138]automatic text/binary mode switching for FTP - [M]GET, based on filename patterns (e.g. *.zip, *.gz, *.exe - are binary; *.txt, *.c are text). - + [139]SET SEND I-PACKETS OFF added for coping with Kermit - servers that do not support I packets. - + A new option was added to [140]\fword() and \fsplit() for - parsing comma-separated lists that might contain empty - elements. - + Bug fixes including: - o {} or "" could not be used as expected to represent the - empty string. - o ,- on a line by itself in a macro definition caused - subsequent statements to be skipped. - o FTP [M]GET didn't work right if path segments were - included in the filespec. - o FTP MGET, if interrupted, did not clear its file list. - o Various problems with FTP PUT /AS-NAME that nobody - noticed. - o Some FTP messages and displays interfered with each - other. - o Parsing of YESTERDAY, TODAY, and TOMORROW in date-time - fields was broken. - o Automatic old-to-new dialing directory format conversion - was broken on VMS. - o Various source-code portability problems fixed. - + Improvement of various HELP and SHOW messages. - - C-Kermit 7.1.199 Alpha.04 (1 April 2001) - - + Big changes: - o Changed default modem type from NONE to GENERIC. - o Generic dialing now sends no init string at all. - o Changed default terminal bytesize from 7 to 8. - + New features: - o SET SESSION-LOG TIMESTAMPED-TEXT for timestamped session - log. - + New modem types: - o Conexant modem family - o Lucent VENUS chipset - o PCTel V.90 chipset - o Zoom V.90 - o Zoom V.92 - + FTP client: - o FTP OPEN /PASSIVE and /ACTIVE switches added. - o Now works with servers that that don't include path in - NLST response. - o Fixed SEND /RECURSIVE not to follow symlinks (UNIX). - o SET FTP VERBOSE-MODE default is now OFF instead of ON. - + Kermit protocol: - o Fixed what I hope is the last "Receive window full" - error. - o SET PREFIXING or SET CONTROL PREFIX now automatically - sets CLEARCHANNEL OFF. - o Fixed incorrect report of number of files transferred at - end of transfer. - o Fixed SEND /RECURSIVE not to follow symlinks (UNIX). - + UNIX: - o HTTP and shadow passwords enabled for SCO 5.0.6. - o Even with SET FILENAMES CONVERTED, spaces were still - accepted in incoming filenames; now they are converted - to underscores. - o Added support for compile-time mktemp()/mkstemp() - selection. - + VMS: - o Session-log format for scripted sessions fixed. - + Scripting: - o Fixed \frdir() not to follow symlinks (UNIX). - o Fixed \fday() not to dump core for dates prior to 17 Mar - 1858. - + General: - o "Closing blah..." message upon exit could not be - surpressed. - o Added /PAGE and /NOPAGE to DELETE switches. - o Added GO response for DELETE /ASK (delete all the rest - without asking). - o Added GO response to "more?" prompt (for multi-page - screen output). - o Updated HELP texts. - - C-Kermit 7.1.199 Beta.01 (10 May 2001) - - + FTP client verbosity adjustments. - + Bug with generic modem dialing pausing several secs fixed. - + SET HOST /USER:, SET LOGIN USERID, etc, fixed when given no - user ID. - + A couple \v(dm_blah) dial modifier variables added. - + "--version" command-line switch added. - + Fixed NetBSD serial-port DTR handling. - + Lots of syntax cleanups for Flexelint and gcc -Wall. - + Fixed modem-type aliases to not take precedence over real - names. - + Fixed funny treatment of doublequotes by ECHO command. - + Enabled SET SESSION-LOG for VMS and other non-UNIX platorms. - + Fixed changing direction in command history buffer. - + Fixed handling of IKSD URLs. - + Made sure DELETE prints a message if it got any errors. - - C-Kermit 8.0.200 Beta.02 (28 June 2001) - - + Major version number increased from 7 to 8. - + [141]SSH command. - + More-consistent Kermit protocol defaults. - + CONNECT idle timeout and action selection. - + CONNECT status variable. - + A way to allocate more space for filename lists. - + Pseudoterminal handler fixed for late-model Linuxes. - + Command-line option -dd for timestamped debug log. - + Download directory now works for external protocols too. - + GREP /COUNT:variable. - + SET ATTRIBUTE RECORD-FORMAT { OFF, ON }. - + Bug fixes. - - C-Kermit 8.0.200 Beta.03 (9 Sep 2001) - - + [142]HTTP 1.1 connections and scripting - + [143]ON_CTRLC macro for trapping Ctrl-C in scripts - + [144]Date-time parsing improvements, timezones, comparison, - arithmetic - + [145]Pattern-matching improvements - + FTP improvements - + SET EXIT HANGUP { ON, OFF } - + SET FILE EOF { CTRL-Z, LENGTH } - + ASK[Q] /TIMEOUT - + Bug fixes - + New platforms - - C-Kermit 8.0.200 Beta.04 (16 Nov 2001) - - + [146]New Unix man page - + [147]New Unix installation instructions - + SET TELOPT policies are now enforced on non-Telnet ports if - the server begins Telnet negotiations. - + SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }. - + UUCP lockfile creation race condition fixed. - + Dialout, modem signals, hangup, hardware flow control, etc, - tested extensively on many platforms, numerous problems - fixed. - + Improved hints when dialing fails. - + SET STOP-BITS 2 can now be given without SET FLOW HARDWARE. - + Major improvements in RFC 2217 Telnet Com-Port Control. - + Improved ability to REDIAL a modem server port. - + kermit -h now shows the command name in the usage usage - string. - + kermit -h now shows ALL command-line options. - + kermit -s blah, where blah is a symlink, now works. - + --noperms command-line option = SET ATTRIBUTE PERMISSIONS - OFF. - + HTTP and HTTPS URLs now supported on the command line. - + An http command-line personality is now available. - + Initialization file streamlined to load faster, anachronisms - removed. - + Updated NEWS, INTRO, HELP text, SHOW commands. In particular, - see SHOW COMM, HELP SET LINE, HELP WAIT. - + Date/time arithmetic routines converted from floating-point - to integer arithmetic (internally) for greater accuracy and - portability. - + Quoted strings containing commas no longer break macro - execution. - + Dynamic Kermit file-transfer timeouts are now much more - aggressive. - + New "hot keys" to turn debug.log on/off during file transfer. - + Improved hints when file transfer fails. - + FTP CD orientation messages are now printed. - + -R now accepted on the FTP command line to request Recursion. - + -m allows Active or Passive mode to be chosen on the FTP - command line. - + -dd on the FTP command line creates a timestamped debug.log. - + FTP command-line security options filled in. - + Improved automatic text/binary mode switching for MGET. - + Removed spurious error messages that sometimes occur during - MGET. - + DIRECTORY, GREP, TYPE, HEAD, and TAIL now have a /OUTPUT:file - option. - + TYPE /NUMBER adds line numbers. - + CAT = TYPE /NOPAGE; MORE = TYPE /PAGE. - + GETOK ?-help fixed. - + \v(timestamp) (= "\v(ndate) \v(time)") - + \v(hour) (hour of the day, 0-23) - + \funix2dospath() converts a UNIX path (/) to a DOS one (\). - + \fdos2unixpath() converts a DOS (Windows, OS/2) path to a - UNIX one. - + \fkeywordval() parses name=value pair, allows macro keyword - parameters. - + We now make every attempt to not write passwords to the - debug.log. - + New Certficate Authority certificates file, includes the - Kermit Project at Columbia University so you can access our - IKSD securely. - + Secure targets improved and better documented in Unix - makefile. - + All Linux (libc and glibc) builds consolidated under "make - linux". - + HP-UX makefile targets now have consistent names. - + New aix50 and aix51 targets added. - - C-Kermit 8.0.200 Final (12 Dec 2001) - - + Remote/local-mode confusion on some platforms introduced in - Beta.04, fixed. - + Many of the makefile targets adjusted, new ones added. - + New "make install" target should please most people. - + New command: SHOW IKSD. - + FTP over TLS. - + Last-minute touchups to text messages, HELP text, etc. - + Enable modem-signal reading for SCO OSR5 and Unixware 7. - + Special superfast TRANSMIT /BINARY /NOECHO /NOWAIT mode - added. - + Fixed PBX dialing in unmarked-area-code case. - + Improved SHOW COMMUNICATIONS tells lockfile directory, - typical dialout device name. - + Some FTP OPEN command parsing problems fixed. - + Some errors in date arithmetic fixed. - + New command: SET TERMINAL AUTODOWNLOAD { ..., ERROR { STOP, - CONTINUE } } - + New command: HELP FIREWALL. - + SET MODEM HANGUP-METHOD DTR added as synomym for RS232-SIGNAL - + Support for secure URL protocols added: telnets:, ftps:, - https:. - - C-Kermit 8.0.201 (8 Feb 2002) - - + Installability as an [148]SSH v2 Subsystem. - + [149]SET LOCUS command. - + [150]L-versions of CD, DIR, DELETE, MKDIR, etc, to force - local execution. - + [151]USER and ACCOUNT added as synonyms for FTP USER and FTP - ACCOUNT. - + [152]SHOW VARIABLES now accepts a list of variables. - + Rudimentary support for [153]Caller ID when receiving phone - calls. - + Up/Down [154]Arrow-key navigation of command history buffer. - + [155]Automatic execution of customization file if init file - is missing. - - C-Kermit 8.0.206 Beta.01 (11 Oct 2002) - - New commands: - - o ORIENTATION lists location-related variables and their - values. - o KCD changes to special directories by their symbolic - names ("kcd ?" for a list). - o SET CD HOME path to specify home directory for CD and - KCD commands. - o CONTINUE given at top level is equivalent to END -- - handy when PROMPT'ed out of a script, to continue the - script. - - New switches or operands for existing commands: - - o GETOK /TIMEOUT - o ASK, ASKQ, GETOK /QUIET (suppresses error message on - timeout) - o COPY /APPEND now allows concatenating multiple source - files into one dest file. - o SET TCP { HTTP-PROXY, SOCKS-SERVER } /USER, /PASSWORD. - o DIRECTORY command now accepts multiple filespecs, e.g. - "dir a b c". - - SET QUIET ON now also applies to: - - o SET HOST connection progress messages. - o "Press the X or E key to cancel" file-transfer message. - o REMOTE CD response. - o REMOTE LOGIN response. - - Improvements and new features: - - o Numerous FTP client fixes and new features, listed - below. - o C-Kermit, when in remote mode at the end of a file - transfer, now prints a one-line "where" message. Control - with SET TRANSFER REPORT. - o Unix makefile "install" target now creates an UNINSTALL - script. - o Improved operation and performance on RFC 2217 Telnet - connections. - o Improved CONNECT (interactive terminal connection) - performance. - o HELP text updated for many commands. - - New or fixed makefile targets: - - o Solaris 9 (several variations) - o Concurrent PowerMAX - o Mac OS X 10.2 - o FreeBSD 1.0 - o FreeBSD 4.6, 5.0 - o AIX 5.2, 5.3 - - Bugs fixed (general): - - o Failure to run in VMS Batch fixed. - o LDIRECTORY fixed to run Kermit's built-in DIRECTORY - command rather than an external one. - o Fixed Solaris and other SVORPOSIX builds to find out - their full hostnames rather than just the "uname -n" - name. - o Fixed some problems matching strings that start with - ".". - o Fixed some problems matching pattern that contain - {a,b,c} lists. - o Fixed erroneous reporting of text-mode reception as - binary when sender did not report the file size - (cosmetic only). - o Many problems with SWITCH statements fixed. - o Fixed SET OPTIONS DIRECTORY /DOTFILES to work for server - too. - o Fixed DELETE to print an error message if the file was - not found. - o Fixed SET CONTROL UNPREFIX ALL and SET PREFIXING NONE to - do the same thing. - o Fixed bugs executing macros from within the ON_EXIT - macro. - o \fday() and \fnday() fixed for dates prior to 17 Nov - 1858. - o Serial speed-changing bug in Linux fixed. - o "Unbalanced braces" script parsing errors when using - \{number} fixed. - o "if defined \v(name)" fixed to behave as described in - the book. - o Fixed Problems caused by LOCAL variables whose names are - left substrings of macro names. - o The INPUT command was fixed to honor the PARITY setting. - o Fixed bug with COPY to existing file that is longer than - source file. - o REINPUT command failed to strip braces/quotes around its - target string. - o Network directory lookups didn't work for SSH - connections. - o REMOTE SET { FILE, TRANSFER } CHARACTER-SET fixed. - o Closed some holes whereby an incompletely received file - was not deleted when SET FILE INCOMPLETE is DISCARD, - e.g. when the Kermit is hung up upon. - o SET XFER CHARACTER-SET TRANSPARENT fixed to do the same - as SET XFER TRANSLATION OFF. - o SET HOST PTY (e.g. SSH) connection fixed to pass along - window-size changes. - o C-Kermit search path for TAKE files was accidentally - disabled. - - FTP client bugs fixed: - - o Character set translation was broken on little-endian - (e.g. PC) architectures. - o FTP PUT /SERVER-RENAME:, /RENAME-TO:, /MOVE-TO: switches - were sticky. - o Make SET TRANSFER MODE MANUAL apply to FTP. - o Make SET FILE INCOMPLETE { KEEP, DISCARD } apply to FTP. - o FTP MGET /UPDATE handled equal times incorrectly. - o FTP MGET /RECOVER fixed to ignore file dates, use only - size. - o FTP MGET /RECOVER sometimes downloaded files it didn't - need to. - o FTP downloads with TRANSFER DISPLAY BRIEF could give - misleading error messages. - o FTP MGET temp file not deleted if FTP DEBUG set to OFF - after it was ON. - o LOCUS not switched back when FTP connection is lost. - o Set incoming file date even if it was not completely - received. - o FTP MGET sent SIZE and MDTM commands even when it didn't - have to. - o FTP MGET sent SIZE and MDTM commands even when it knew - they wouldn't work. - o FTP MGET failed if no files were selected for download. - o FTP MGET a* b* c* would fail to get any c*'s if no b*'s - existed. - o Big problems canceling MGET with Ctrl-C. - o Some extraneous LOCUS dialogs squelched. - o Some inconsistencies in SET FTP FILENAMES AUTO fixed. - o Fixed file-descriptor pileup after multiple MGETs when - using mkstemp(). - o Fixed "mget foo", where foo is a directory name. - - FTP improvements: - - o New [156]FTP protocol features added (FEAT, MLSD). - o FTP MGET /RECURSIVE now works as expected if server - supports MLSD. - o FTP MGET /DATES-DIFFER to download if local and remote - file dates differ. - o FTP DATES default changed to ON. - o FTP MPUT, MGET /EXCEPT now allows up to 64 patterns (up - from 8). - o Top-level SITE and PASSIVE commands added for - convenience. - o MGET /COLLISION:APPEND /AS-NAME:newfile *.* puts all - remote files into one local file. - o SET FTP SERVER-TIME-OFFSET for when server has wrong - timezone set. - o Allow for alternative server interpretations of [M]MPUT - /UNIQUE. - o SET FTP ANONOMOUS-PASSWORD lets you specify the default - anonymous password. - o Allow "GET /RECURSIVE path/file" to force local - subdirectory creation. - o SET FTP DISPLAY is like SET TRANSFER DISPLAY but applies - only to FTP. - o FTP { ENABLE, DISABLE } new-protocol-feature-name. - o FTP MGET /NODOTFILES. - o Debug log now records FTP commands and responses in - grep-able format. - - [ [157]Top ] [ [158]Contents ] [ [159]C-Kermit ] [ [160]Kermit Home ] - __________________________________________________________________________ - -1. FIXES SINCE VERSION 7.0.196 First, the changes from 7.0.196 to 7.0.197... -Source and makefile tweaks to get successful builds on platforms that were not -available in time for the 7.0 release: - - * 4.2BSD - * 4.3BSD - * AIX 4.3 - * AT&T 3B2 and 3B20 - * BeOS 4.5 - * CLIX - * Interactive UNIX System V/386 R3.2 V4.1.1 - * OS-9/68000 - * OSF/1 1.3. - * PS/2 AIX 1.2.1 - * SCO OSR5.0.x - * SCO Xenix 2.3.4 - * SINIX 5.41/Intel - * Stratus FTX - * Stratus VOS - * SunOS 4.1 with X.25 - * Ultrix 4.2 - * Unixware 2.0 - - There were no functional changes from 196 to 197. - - Fixes applied after C-Kermit 7.0.197 was released: - - Source code: Big flexelint and "gcc -Wall" audit and cleanup. - - Configuration: - * Solaris RTS/CTS (hardware flow control) didn't work. - * BSDI RTS/CTS worked only in one direction. - * FreeBSD 4.0 with ncurses 5.0 broke interactive command parsing. - * QNX-32 build lacked -DBIGBUFOK so couldn't execute big macros. - - Connections: - * SET HOST /PTY didn't work on some platforms. - * Broken SET HOST /USER:xxx /PASSWORD:yyy /ACCOUNT:zzz switches - fixed. - * Transparent printing was broken in Unix. - * ANSWER 0 (wait forever) didn't work. - * Some problems in Multitech modem command strings. - * Spurious "?Sorry, can't condition console terminal" errors. - * Disabling modem command strings by setting them to nothing broke - dialing. - * SET DIAL TIMEOUT value was usually ignored. - * SET DIAL METHOD PULSE didn't work. - * Certain modem commands, if changed, not refreshed if modem type - changed. - * SET SESSION-LOG command was missing from VMS. - * VMS session log format fixed for scripts. - * HANGUP by dropping DTR didn't work in NetBSD. - * SET FLOW /AUTO versus SET FLOW confusion fixed. - * Spurious secondary Solaris lockfile removed. - * SCO OSR5 DTR On/Off hangup. - * UUCP lockfile race condition. - - Commands and scripts: - * Missing CAUTIOUS and FAST commands restored. - * Broken PTY command in late-model Linuxes fixed (API changed). - * Fixed off-by-one error in command recall when switching direction. - * Fixed recall of commands that contain '?'. - * COPY /SWAP-BYTES didn't work on some architectures. - * Various combinations of COPY switches didn't work. - * Various problems with COPY or RENAME with a directory name as - target. - * SHIFT didn't decrement \v(argc) if used within IF, ELSE, or SWITCH - block. - * SHIFT didn't affect the \%* variable. - * Divide by zero improperly handled in some \function()s. - * Problems with RETURN from right-recursive functions. - * FSEEK /LINE \%c LAST didn't work if already at end. - * Some buffer vulnerabilities and potential memory leaks were - discovered and fixed. - * \frdirectory() fixed not to follow symbolic links. - * SET EXIT WARNING OFF fixed to work when EXIT given in a script. - * Missing DELETE and MKDIR error message fixed. - * \fday() core dump for ancient dates fixed. - - File transfer: - * SEND /COMMAND was broken. - * CRECEIVE was broken (but RECEIVE /COMMAND was OK). - * Quoting wildcard chars in filenames didn't work. - * Problems canceling streaming file transfers with X or Z. - * Problems shifting between streaming and windowing file transfer. - * Non-FULL file-transfer displays erroneously said STREAMING when - not. - * An active SEND-LIST prevented GET from working. - * SET SERVER GET-PATH interpretation of relative names like "." was - wrong. - * The MAIL command was broken. - * "kermit -s *" might have skipped some files. - * Transaction log entries were not made for external protocol - transfers. - * File count report fixed to show number of files actually - transferred. - * Fixed filename conversion to convert spaces to underscores. - * Made SET PREFIXING / SET CONTROL PREFIX also adjust CLEARCHANNEL. - * More "Receive window full" errors fixed. - * Broken terminal buffering after curses display in Solaris fixed. - * SET FILE INCOMPLETE DISCARD did not work in all cases. - * Packet log changed to reformat the start-of-packet character - printably. - * Dynamic timeouts could grow ridiculously large. - - Character sets: - * Hebrew-7 translations missed the letter Tav. - * C1 area of CP1252 was ignored. - * SET TRANSFER CHARACTER-SET TRANSPARENT could give garbage - translations. - * TRANSLATE might not work on Little Endian architectures. - * Insufficient range checking in certain TRANSLATE operations. - - The following bugs in C-Kermit 8.0.200 were fixed in 8.0.201: - - * An obscure path through the code could cause the Unix version of - C-Kermit to dump core during its startup sequence. This happened - to only one person, but now it's fixed. - * When C-Kermit 8.0 is in Kermit server mode and the client says - "get blah", where blah (on the server) is a symlink rather than a - real file, the server unreasonably refused to send the linked-to - file. - * When C-Kermit is an FTP client and says "get foo/bar" (i.e. a - filename that includes one or more path segments), it failed to - accept the incoming file (this happened only with GET, not MGET). - * Array references should be case insensitive but only lowercase - array letters were accepted. - * SHOW VARIABLES dumped core on \v(sexpression) and \v(svalue). - * Spurious refusals of remote directory listings if the remote - server's date was set in the past. - * In AIX, and maybe elsewhere too, Kermit's COPY command always - failed with "Source and destination are the same file" when the - destination file didn't exist. - * The VMS version of C-Kermit did not work in Batch or when SPAWN'd. - To compound the problem, it also pretty much ignored the -B and -z - command-line options, whose purpose is to work around such - problems. - * C-Kermit 8.0 could not be built on IRIX 5.x. - * The C-Kermit 8.0 build for QNX6 said it was an "(unknown - version)". - - Other fixes are listed in the [161]previous section. - - [ [162]Top ] [ [163]Contents ] [ [164]C-Kermit ] [ [165]Kermit Home ] - __________________________________________________________________________ - -2. SSH AND HTTP - - 2.1. SSH Connections - - This section does not apply to [166]Kermit 95 2.0, which has its - own built-in SSH client, which is documented [167]SEPARATELY. - - On most UNIX platforms, C-Kermit can make SSH (Secure SHell) - connection by running the external SSH command or program through its - pseudoterminal interface. The command is: - - SSH text - Tells Kermit to start the external SSH client, passing the - given text to it on the command line. Normally the text is just - the hostname, but it can be anything else that is acceptable to - the ssh client. If the command succeeds, the connection is made - and Kermit automatically enters CONNECT (terminal) mode. You - can use the SSH command to make a connection to any host that - has an SSH server. - - Kermit's SSH command gives you all the features of Kermit on an SSH - connection: command language, file transfer, character-set - translation, scripting, and all the rest. By default, C-Kermit invokes - SSH with "-e none", which disables the ssh escape character and makes - the connection transparent for purposes of file transfer. You can, - however, change the SSH invocation to whatever else you might need (an - explicit path, additional command-line arguments, etc) with: - - SET SSH COMMAND text - Specifies the system command that Kermit's SSH command should - use to invoke the external SSH client. Use this command to - supply a specific path or alternative name, or to include - different or more command-line options. - - In most cases, these connections work quite well. They can be scripted - like any other connection, and file transfer goes as fast as, or - faster than, on a regular Telnet connection. In some cases, however, - the underlying pseudoterminal driver is a limiting factor, resulting - in slow or failed file transfers. Sometimes you can work around such - problems by reducing the Kermit packet length. Note that Kermit does - not consider SSH connections to be reliable, so it does not offer to - use streaming in Kermit protocol transfers (but you can force it with - SET RELIABLE or SET STREAMING if you wish). - - The SSH command is like the TELNET command: it enters CONNECT mode - automatically when the connection is made. Therefore, to script an SSH - connection, use: - - set host /pty ssh -e none [ other-options ] host - if fail ... - - to make the connection. - - Here's a sequence that can be used to make a connection to a given - host using Telnet if the host accepts it, otherwise SSH: - - if not defined \%1 exit 1 Usage: \%0 host - set quiet on - set host \%1 23 /telnet - if fail { - set host /pty ssh -l \m(user) -e none \%1 - if fail exit 1 \%1: Telnet and SSH both fail - echo SSH connection to \%1 successful - } else { - echo Telnet connection to \%1 successful - } - - In SSH v2, it is possible to make an SSH connection direct to a Kermit - server system if the host administrator has configured the SSH server - to allow this; [168]CLICK HERE for details. - - Since Kermit uses external ssh client software, and since there are - different ssh clients (and different releases of each one), the exact - command to be used to make an SSH/Kermit connection can vary. Here is - the command for the OpenSSH 3.0.2p1 client: - -set host /pipe ssh -e none [ -l username ] -T -s hostname kermit - - Example: - -set host /pipe ssh -e none -l olga -T -s hq.xyzcorp.com kermit - - The SSH client might or might not prompt you for a password or other - information before it makes the connection; this depends on your SSH - configuration (your public and private keys, your authorized hosts - file, etc). Here's a brief synopsis of the OpenSSH client command - syntax ("man ssh" for details): - - -e none - This tells the SSH client to use no escape character. Since we - will be transferring files across the connection, we don't want - the connection to suddenly block because some character in the - data. - - -l username - This is the username on the remote host. You can omit the -l - option and its argument if your local and remote usernames are - the same. If they are different, you must supply the remote - username. - - -T - This tells the SSH client to tell the SSH server not to - allocate a pseudoterminal. We are not making a terminal - connection, we don't need a terminal, and in fact if a terminal - were allocated on the remote end, the connection would not - work. - - -s ... kermit - This tells the SSH client to tell the SSH server to start the - specified subsystem ("kermit") once the connection is made. The - subsystem name comes after the hostname. - - hostname - The IP host name or address of the desired host. - - You might want to include other or additional ssh command-line - options; "man ssh" explains what they are. Here are some examples for - the OpenSSH 3.0.2p1 client: - - -oClearAllForwardings yes - -oForwardAgent no - -oForwardX11 no - -oFallbackToRsh no - These ensure that a secure connection is used and that the - connection used for file transfer is not also used for - forwarding other things that might be specified in the - ssh_config file. - - -oProtocol 2 - (i.e. SSH v2) Ensures that the negotiated protocol supports - subsystems. - - Once you have an SSH connection to a Kermit server, it's just like any - other connection to a Kermit server (and very similar to a connection - to an FTP server). You give the client file transfer and management - commands for the server, and the server executes them. Of course you - can also give the client any other commands you wish. - - [ [169]SSH Kermit Server Subsystem ] [ [170]Kermit 95 Built-in SSH - Client ] - _________________________________________________________________ - - 2.2. HTTP Connections - - Hypertext Transfer Protocol, or HTTP, is the application protocol of - the World Wide Web (WWW), used between Web browsers (clients) and Web - servers. It allows a client to get files from websites, upload files - to websites, delete files from websites, get information about website - directories and files, and interact with server-side CGI scripts. - C-Kermit includes an HTTP client capable of both clear-text and secure - HTTP connections, that can do all these tasks and can be automated - through the Kermit scripting language. - - Although C-Kermit 7.0 could make HTTP connections to Web servers, it - could do so only when no other connection was open, and the procedure - was somewhat awkward. C-Kermit 8.0 improves matters by: - - * Allowing an HTTP connection to be open at the same time as a - regular SET LINE or SET HOST connection, and also at the same time - as an FTP connection ([171]Section 3); - * Upgrading the HTTP protocol level from 1.0 to 1.1, thus allowing - for persistent connections, in which a series of commands can be - sent on the same connection, rather than only one as in HTTP 1.0 - (and C-Kermit 7.0); - * Providing for "one-shot" URL-driven HTTP operations such as GET or - PUT. - * Providing a distinct HTTP command-line personality. - - Persistent HTTP connections are managed with the following commands: - - HTTP [ switches ] OPEN [ security-options ] host-or-url [ port ] - Opens a persistent connection to the specified host (IP host - name or address) on the specified port. If any switches - (options, listed in the next section) are included, their - values are saved and used for all subsequent HTTP action - commands on the same connection. If no port is specified, HTTP - (80) is used. A Uniform Resource Locator (URL, [172]RFC 1738) - can be given instead of a hostname (or address) and port (but - the URL can not include a directory/file path). The security - options are explained [173]below. The HTTP OPEN command - replaces the C-Kermit 7.0 SET HOST hostname HTTP command, which - no longer works with HTTP GET and related commands. - - HTTP CLOSE - Closes any open HTTP connection and clears any saved switch - values. - - A URL starts with a protocol name, which must be http or https in this - case; optionally includes a username and password; and must contain a - host name or address: - - protocol://[user[.password]]@host[:port][URI] - - HTTP is Hypertext Transfer Protocol. HTTPS is the secure (SSL/TLS) - version of HTTP. The TCP service port is derived from the protocol - prefix (so normally the ":port" field is omitted). Thus the URL - protocol name specifies a default TCP service port and the URL user - and password fields can take the place of the /USER and /PASSWORD - switches ([174]Section 2.2.1). The optional URI is a "compact string - of characters for identifying an abstract or physical resource" - ([175]RFC 2396), such as a file. It must begin with a slash (/); if - the URI is omitted, "/" is supplied. Examples: - - http open http://www.columbia.edu/ - Equivalent to http open www.columbia.edu or http open - www.columbia.edu http. - - http open https://olga.secret@www1.xyzcorp.com/ - Equivalent to http /user:olga /pass:secret open - www1.xyzcorp.com https. - - Persistence is accomplished unilaterally by C-Kermit 8.0. An HTTP 1.0 - server closes the connection after each action. Although HTTP 1.1 - allows multiple actions on the same connection, an HTTP 1.1 server - tends to close the connection if it is idle for more than a few - seconds, to defend itself against denial-of-service attacks. But when - you use Kermit's HTTP OPEN command to create a connection, Kermit - reopens it automatically (if necessary) for each HTTP action until you - close it with HTTP CLOSE, regardless of the server's HTTP protocol - version, or how many times it closes the connection. - - Firewalls can be negotiated through proxies with the following - commands: - - SET TCP HTTP-PROXY [ host[:port] ] - If a host (by hostname or IP address) is specified, Kermit uses - it as a proxy server when attempting outgoing TCP connections - -- not only HTTP connections, but all TCP/IP connections, - Telnet and FTP included. This allows Kermit to adapt to the - HTTP firewall penetration method (as opposed to other methods - such as SOCKS4). If no hostname or ip-address is specified, any - previously specified Proxy server is removed. If no port number - is specified, the "http" service is used. This command must be - given before the HTTP OPEN command if a proxy is to be used or - canceled. - - HTTP [ switches ] CONNECT host[:port] - Instructs the HTTP server to act as a proxy, establishing a - connection to the specified host (IP hostname or address) on - the given port (80 = HTTP by default) and to redirect all data - transmitted between Kermit and itself to the given host for the - life of the connection. This command is to be used only for - debugging HTTP proxy connections. If a proxy connection is - required, instruct Kermit to use the proxy with the SET TCP - HTTP-PROXY command. - - 2.2.1. HTTP Command Switches - - HTTP switches, like all other switches, are optional. When HTTP - switches are included with the HTTP OPEN command, they apply - automatically to this and all subsequent HTTP actions (GET, PUT, ...) - on the same connection until an HTTP CLOSE command is given. So if you - include switches (or the equivalent URL fields, such as user and - password) in the HTTP OPEN command, you can omit them from subsequent - commands on the same connection. If the connection has closed since - your last command, it is automatically reopened with the same options. - - If you include switches with an HTTP action command (such as GET or - PUT), they apply only to that command. - - /USER:name - To be used in case a page requires a username for access. The - username is sent with page requests. If it is given with the - OPEN command it is saved until needed. If a username is - included in a URL, it overrides the username given in the - switch. CAUTION: Username and password (and all other - information, including credit card numbers and other material - that you might prefer to protect from public view) are sent - across the network in clear text on regular HTTP connections, - but authentication is performed securely on HTTPS connections. - - /PASSWORD:text - To be used in case a web page requires a password for access. - The password is sent with page requests. If it is given with - the OPEN command it is saved until needed. If a password is - given in a URL, it overrides the one given here. CAUTION: (same - as for /USER:). - - /AGENT:user-agent - Identifies the client to the server. Overrides the default - agent string, which is "C-Kermit" (for C-Kermit) or "Kermit-95" - (for Kermit 95). - - /ARRAY:array-designator - Tells Kermit to store the response headers in the given array, - one line per element. The array need not be declared in - advance. Example: /array:&a. - - /TOSCREEN - Tells Kermit to display any response text on the screen. It - applies independently of the output file specification; thus it - is possible to have the server response go to the screen, a - file, both, or neither. - - /HEADER:header-item(s) - Used for specifying any optional headers to be sent with HTTP - requests. - - /HEADER:tag:value - - To send more than one header, use braces for grouping: - - /HEADER:{{tag:value}{tag:value}...} - - For a list of valid tags and value formats see [176]RFC 2616, - "Hypertext Transfer Protocol -- HTTP/1.1". A maximum of eight - headers may be specified. - - 2.2.2. HTTP Action Commands - - HTTP actions can occur within a persistent connection, or they can be - self-contained ("connectionless"). A persistent HTTP connection begins - with an HTTP OPEN command, followed by zero or more HTTP action - commands, and is terminated with an HTTP CLOSE command: - - http open www.columbia.edu - if failure stop 1 HTTP OPEN failed: \v(http_message) - http get kermit/index.html - if failure stop 1 HTTP GET failed: \v(http_message) - (more actions possible here...) - http close - - A self-contained HTTP action occurs when a URL is given instead of a - remote file name to an HTTP action command. In this case, Kermit makes - the HTTP connection, takes the action, and then closes the connection. - If an HTTP connection was already open, it is closed silently and - automatically. - - http get http://www.columbia.edu/kermit/index.html - - Kermit's HTTP action commands are as follows. Switches may be included - with any of these to override switch (or default) values given in the - HTTP OPEN command. - - HTTP [ switches ] GET remote-filename [ local-filename ] - Retrieves the named file from the server specified in the most - recent HTTP OPEN command for which a corresponding HTTP CLOSE - command has not been given. The filename may not include - wildcards (HTTP protocol does not support them). If no HTTP - OPEN command is in effect, this form of the HTTP GET command - fails. The default local filename is the same as the remote - name, but with any pathname stripped. For example, the command - http get kermit/index.html stores the file in the current local - directory as index.html. If the /HEADERS: switch is included, - information about the file is also stored in the specified - array (explained in [177]Section 2.2.3). All files are - transferred in binary mode. HTTP does not provide for - record-format or character-set conversion. - - HTTP [ switches ] GET url [ local-filename ] - When HTTP GET is given a URL rather than a filename, Kermit - opens a connection to the designated server (closing any - previously open HTTP connection), gets the file, and then - closes the connection. If the URL does not include a filename, - index.html is supplied. This is the self-contained one-step - "connectionless" method for getting a file from a Web server. - The data is not interpreted; HTTP GET is like "lynx -source" - rather than "lynx -dump". - - In the remaining HTTP action commands, the distinction between a - remote filename and a URL are the same as in the HTTP GET command. - - HTTP [ switches ] HEAD remote-filename-or-url [ local-filename ] - Like GET except without actually getting the file; instead it - retrieves only the headers. If the /ARRAY: or /TOSCREEN switch - is included, there is no default local output filename but you - can still specify one. If neither of these switches is - included, the default local filename is the same as the remote - filename, but with any path stripped and with ".head" appended. - The HEAD command can be used in a script with the /ARRAY: - switch to retrieve information about the requested resource to - determine whether the resource should actually be retrieved - with a subsequent GET request. - - HTTP [ switches ] INDEX remote-directory-or-url [ local-filename ] - Asks the server to send a listing of the files in the given - server directory. This command is not supported by most Web - servers. Even when it is supported, there is no standard format - for the listing. - - HTTP [ switches ] POST [ /MIME-TYPE:type ] source-file - remote-path-or-url [ result-file ] - Sends data to a process running on the remote host; the result - is usually an HTML file but could be anything. The data to be - posted must be read from a local file (the source-file). If a - result file is specified, Kermit stores the server's response - in it. - - HTTP [ switches ] PUT [ MIME-TYPE:type ] local-file [ - remote-file-or-url [ result-file ] ] - Uploads a local file to the server. Only the name of a single - file can be given; wildcards (and group transfers) are not - supported by HTTP protocol. If no remote filename is given, the - file is sent with the same name as the local file, but with any - pathname stripped. - - HTTP [ switches ] DELETE remote-file-or-url [ local-result-file ] - Asks the server to delete the specified single file. If a - result file is specified, it will contain any response data - returned by the server. - - Note the limitations of HTTP protocol compared to (say) FTP or Kermit. - There is no command for changing directories, no standard way to get - file or directory lists, no way to transfer file groups by using - wildcard notation, etc, and therefore no good way to (say) fetch all - pages, descend through subdirectories, perform automatic updates, etc. - There is no assurrance a connection will stay open and, as noted, - there is no provision for data conversion between unlike platforms. - The data's MIME headers can be used for postprocessing. - - 2.2.3. HTTP Headers - - Each HTTP request and response contains a set of name/value pairs - called headers. HTTP headers are specified in [178]RFC 2616. For - example, an HTTP GET request for /index.html on www.columbia.edu - contains the following headers: - - GET /index.html HTTP/1.1 - Host: www.columbia.edu:80 - User-agent: C-Kermit 8.0 - Authorization: Basic base64-encoded-username-password - - These might be followed by any others specified with a /HEADERS: - switch: - - Accept: image/gif, image/x-xbitmap, image/jpeg, *.* - Accept-Encoding: gzip - Accept-Language: en - Accept-Charset: iso-8859-1,utf-8 - Cookie: cookie-data - - The server sends back a short report about the file prior to sending - the file contents. Example: - - HTTP/1.1 200 OK - Date: Fri, 24 Aug 2001 21:09:39 GMT - Server: Apache/1.3.4 (Unix) - Last-Modified: Mon, 06 Aug 2001 21:16:13 GMT - ETag: "1fa137-10d7-3b6f091d" - Accept-Ranges: bytes - Content-Length: 4311 - Content-Type: text/html - - If you want to have this information available to a Kermit script you - can use the /ARRAY switch to have Kermit put it in array, one line per - array element. Example: - - set exit warning off - http open www.columbia.edu - if fail exit 1 Can't reach server - http /array:&a get /index.html - if fail exit 1 Can't get file - echo Header lines: \fdim(&a) - for \%i 1 \fdim(&a) 1 { - echo \%i. \&a[\%i] - } - - Note that the "Date:" item is the current date and time; the - "Last-Modifed:" item is the file's modification date and time. An - example showing how to use this information is presented in - [179]Section 8.13.7. - - 2.2.4. Secure HTTP Connections - - SSL/TLS (Secure Sockets Layer / Transport Layer Security) is the - protocol used to secure HTTP, SMTP, and other Internet applications. - See the [180]C-Kermit Reference Section 5.4 for an introduction to - SSL/TLS. To make a secure HTTP connection, you need: - - 1. A secure client (a version of C-Kermit or Kermit 95 with SSL/TLS - security built in). Type "check ssl" at the Kermit prompt to make - sure you have it. - 2. A secure server to connect to. - 3. The CA Root Certificate used to authenticate the server to the - client. (see [181]Section 15 of the security reference for an - introduction to certificates). - - And you must make a connection to the secure HTTP port: service name - HTTPS, port number 443 (as opposed to service HTTP, port 80). You can - also make secure connections to other ports by including the /TLS or - /SSL switch with the HTTP OPEN command, if the host supports SSL/TLS - on the given port: - - The quality of the SSL/TLS connection depends on the cipher suite. - There are several possibilities: - - Anonymous cipher suite: - If an anonymous cipher suite is negotiated, the connection is - encrypted but there is no authentication. This connection is - subject to a Man-In-The-Middle (MITM) attack. - - X.509 certificate on the server: - When you connect to certain secure servers, an X.509 - certificate is returned. This certificate is issued to a - special hostname, something like www1.xyzcorp.com or - wwws.xyzcorp.com (rather than the normal www.xyzcorp.com). It - is signed by the host's Certificate Authority (CA). If the host - certificate is configured on the client, it can be used to - verify the certificate received from the server. If the - certificate it verified as authentic, a check is made to ensure - it has not expired and it was issued to the host you were - attempting to connect to. If you had asked to connect to (say) - www.xyzcorp.com but were given a certificate for - www1.xyzcorp.com, you would be prompted for permission to - continue. - - If the verification succeeded, the connection would be - encrypted with one-way (server-to-client) authentication. This - connection is not subject to a MITM attack. - - If a username and password are transmitted over this - connection, they are not subject to interception. However, the - standard risks associated with passing the password to the host - for verification apply; for example, if the host has been - compromised, the password will be compromised. - - X.509 client certificate: - If a connection has been established with an X.509 server - certificate, the server can ask the client to send a - certificate of its own. This certificate must be verified - against a CA Root certificate. The certificate itself (or - subject info from the certificate) is used to determine the - authorization for the client, and if successful, the username - and password need not be sent to the server. - - Kerberos 5: - Instead of using X.509 certifcates, Kerberos 5 can be used to - perform the authentication and key exchange. In this situation, - there is mutual authentication between the client and server. - The Kerberos 5 principal is used by the server to look up the - appropriate authorization data. There is no need to send - username and password. - - An HTTP connection is made with the HTTP OPEN command: - - HTTP [ switches ] OPEN [ { /SSL, /TLS } ] host [ port ] - If /SSL or /TLS switches are included (these are synonyms), or - if the service is HTTPS or the port is 443, a secure connection - is attempted using the current authentication settings; see - HELP SET AUTHENTICATION for details ([182]Section 6.2 of the - security reference). If the no /SSL or /TLS switch is included - but the port is 443 or the service is HTTPS, a secure - connection is attempted. If an /SSL or /TLS switch is included - but a port is not specified, an SSL/TLS connection is attempted - on the default port (80). - - Certificates are covered in the separate [183]Kermit Security - Reference for C-Kermit 8.0. You should let Kermit know to verify - certificates with the SET AUTHENTICATION TLS command. For example: - - SET AUTHENTICATION TLS CRL-DIR directory - Specifies a directory that contains certificate revocation - files where each file is named by the hash of the certificate - that has been revoked. - - SET AUTHENTICATION TLS CRL-FILE filename - Specifies a file that contains a list of certificate - revocations. - - SET AUTHENTICATION TLS VERIFY-DIR directory - Specifies a directory that contains root CA certificate files - used to verify the certificate chains presented by the peer. - Each file is named by a hash of the certificate. - - SET AUTHENTICATION TLS VERIFY-FILE filename - Specifies a file that contains root CA certificates to be used - for verifying certificate chains. - - SET AUTHENTICATION TLS VERIFY OFF - Tells Kermit not to require a certificate and accept any - certificate that is presented regardless of whether it is - valid. - - There are many other options; see the security document for details. - - Now suppose you need need to fetch the file denoted by the following - URL: - - https://myuserid:mypassword@wwws.xyzcorp.com/clients/info/secret.html - - Once you have set up the handling of certificates as desired, you can - use the following Kermit commands: - - http /user:myuserid /password:mypassword open www1.xyzcorp.com https - if success { - http get /clients/info/secret.html - http close - } - - As another example, let's say that you have a web form you need to - populate with three fields: red,white and blue. - -
- - - -
- - You can handle this with the HTTP POST command. The data to be posted - is stored in the local file data.txt. - - Red=seven stripes&White=six stripes&Blue=fifty stars - - and the response from the server will be stored into response.txt. - - http open www.xyzcorp.com http - if success { - http /array:c post data.txt /cgi-bin/form.cgi response.txt - http close - } - - In this scenario, the Common Gateway Interface (CGI) sends a response - whether it succeeds or fails in a script-dependent manner. The script - can either report success and enclose the response data; or it might - send a 302 Found error which indicates that the "Location:" header - should be used to determine the URL at which the data can be found. - - 2.2.5. HTTP Variables - - \v(http_code) - The HTTP protocol code number of the most recent server reply, - e.g. 404 for "not found". - - \v(http_connected) - 1 when an HTTP connection is open, 0 when there is no HTTP - connection. - - \v(http_host) - If an HTTP connection is open, the hostname:port, e.g. - www.columbia.edu:80; otherwise, empty. - - \v(http_message) - Server error message, if any, from most recent HTTP command. - - \v(http_security) - A list of the security parameters and values for the current - connection, if any. Empty if the connection is not to a secure - server, or there is no connection. - - To display all the HTTP variables at once, type SHOW VAR HTTP: - - C-Kermit> http open www.columbia.edu - C-Kermit> http get lkjlkjlkjlkj - C-Kermit> sho var http - \v(http_code) = 404 - \v(http_connected) = 1 - \v(http_host) = www.columbia.edu:80 - \v(http_message) = Not Found - \v(http_security) = NULL - C-Kermit> - - 2.2.6. The HTTP Command-Line Personality - - If you invoke C-Kermit with the name "http" or "https", you can use a - special set of HTTP-specific command-line options. You can do this by - creating a symbolic linke "http" or "https" to the C-Kermit 8.0 - executable, or by having a separate copy of it called "http" or - "https". Here's the usage message ("http -h"): - - Usage: ./http host [ options... ] - -h This message. - -d Debug to debug.log. - -S Stay (issue command prompt when done). - -Y Do not execute Kermit initialization file. - -q Quiet (suppress most messages). - -u name Username. - -P password Password. - -g pathname Get remote pathname. - -p pathname Put remote pathname. - -H pathname Head remote pathname. - -l pathname Local path for -g, -p, and -H. - -z opt[=value] Security options... - cert=file Client certificate file - certsok Accept all certificates - key=file Client private key file - secure Use SSL - verify=n 0 = none, 1 = peer , 2 = certificate required - - The "host" argument is the name of a Web host, e.g. www.columbia.edu. - The action options are -p, -g, and -H. If you give an action option, - Kermit does the action and then exits. If you give a host without an - action option, Kermit makes an HTTP connection to the host and then - gives you the C-Kermit prompt. Here's a simple example that fetches a - publicly readable Web page: - - http www.columbia.edu -g kermit/index.html - - If you need to access a website for which a username and password are - required, you can supply them on the command line with -u and -P. If - you include a username but omit the password, Kermit prompts you for - it: - - http www.columbia.edu -u olga -p kermit/index.html -l index.html - Password: - - Note that when PUT'ing files to websites, you have to supply both the - -p (remote pathname) and -l (local path) options. - - If your version of Kermit is built with SSL/TLS security, you can also - use the -z option to make secure HTTP (https) connections. - - Finally, as noted in [184]Section 16, you can also give a URL instead - of a host name and options. - - [ [185]Top ] [ [186]Contents ] [ [187]C-Kermit Home ] [ [188]Kermit - Home ] - __________________________________________________________________________ - -3. THE BUILT-IN FTP CLIENT - - 3.1. [189]Making and Managing FTP Connections - 3.2. [190]Making Secure FTP Connections - 3.3. [191]Setting FTP Preferences - 3.4. [192]Managing Directories and Files - 3.5. [193]Uploading Files With FTP - 3.6. [194]Downloading Files With FTP - 3.7. [195]Translating Character Sets - 3.8. [196]FTP Command Shortcuts - 3.9. [197]Dual Sessions - 3.10. [198]Automating FTP Sessions - 3.11. [199]Advanced FTP Protocol Features - - Earlier versions of C-Kermit and K95 included an FTP command, but it - simply invoked an external FTP client. Now, by popular demand, Kermit - includes its own built-in FTP client that offers the following - advantages over traditional FTP clients (and its previous interface to - them): - - * Any of Kermit's built-in [200]security methods can be used to - establish and conduct secure FTP sessions with [201]FTP servers - that support these methods. (Security modules can be subject to - export restrictions.) - * Kermit's FTP client uses "passive mode" by default to avoid - blockage by firewalls and network address translators. Of course - active mode can be chosen too when needed. - * [202]Character sets can be translated as part of the transfer - process even when the FTP server does not support character-set - translation, including to/from the new Internet standard - international character set, [203]Unicode UTF-8. This includes - both the file's name and (for text files only) its contents. - * All of C-Kermit's [204]file-selection mechanisms are available: - size, date, name patterns and lists, exception lists, etc. - * [205]Atomic file movement capabilities are provided (delete, move, - or rename files automatically after successful transfer). - * The correct file type, "ascii" (i.e. text) or binary, is chosen - automatically for each file (explained in [206]Section 4), and any - mixture of text and binary files can be sent in a single - operation, even across platforms. - * Update mode ("don't bother transferring files that didn't change - since last time") and recovery (resumption of an interrupted - transfer from the point of failure) are available in both - directions. - * When uploading files from UNIX to UNIX, the file's permissions can - be preserved if desired. - * Recursive directory-tree PUTs are supported between any two - platforms that have tree-structured file systems. Recursive GETs - are supported between like platforms if the server cooperates and - between like or unlike platforms if the server supports MLSD - ([207]Section 3.11). - * When receiving files, all of Kermit's file collision actions are - available: backup, update, refuse, rename, etc. - * Multi-file transfers can be interrupted on a per-file basis, - automatically skipping to the next file. - * FTP sessions are [208]fully scriptable. - * An entire FTP session (connect, login, CD, upload or download, - logout) can be specified on the command line without using a - script. - * All of Kermit's logging options and formats are available to keep - an accurate and complete record of each connection and file - transfer, and to aid in troubleshooting. - * All of Kermit's file-transfer display options are available - (fullscreen, brief, CRT, serial, none). - - And best of all: - * Kermit doesn't give you those annoying per-file prompts every time - you start a multi-file transfer without remembering to give a - "prompt" command first :-). - - [ [209]Top ] [ [210]FTP Top ] [ [211]FTP Client Overview ] [ [212]FTP - Script Tutorial ] [ [213]C-Kermit Home ] [ [214]Kermit Home ] - _________________________________________________________________ - - 3.1. Making and Managing FTP Connections - - Each copy of Kermit can have one FTP connection open at a time. FTP - connections are independent of regular terminal connections; a - terminal connection (serial or network via SET LINE, DIAL, SET HOST, - TELNET, etc) may be, but need not be, open at the same time as an FTP - connection, and terminal connections can also be closed, and new - connections opened, without interfering with the FTP connection (and - vice versa). Thus, for example, Kermit can have an FTP connection and - a TELNET connection open to the same host simultaneously, using the - TELNET connection (e.g.) to send mail or take other desired actions as - various FTP actions complete. Of course, each copy of Kermit can do - only one thing at a time, so it can't (for example) transfer a file - with FTP and another file with Kermit protocol simultaneously. - - A Kermit FTP session can be established by [215]command-line options, - by [216]URL, or by [217]interactive commands. - - 3.1.1. Kermit Command-Line Options for FTP - - The new command-line option '-9' (sorry, we're out of letters) can be - used when starting C-Kermit, telling it to make an FTP connection: - - kermit -9 hostname - - or if a non-default FTP port is needed: - - kermit -9 hostname:port - - You can also specify the username on the command line with the -M ("My - User ID") option that was already there for other connection types: - - kermit -9 hostname -M olga - - If you specify the username on the command line, Kermit uses it when - making the connection and does not prompt you for it (but it does - prompt you for the password if one is required). - - Once the connection is made, you get the regular Kermit prompt, and - can give interactive commands such as the ones described below. When - you give a BYE command, Kermit closes the session and exits, just as a - regular FTP client would do. If you don't want Kermit to exit when you - give a BYE command, include the -S ("Stay") option on the command - line. - - Other Kermit command-line options that are not specific to non-FTP - connections should affect the FTP session in the expected ways; for - example, -i and -T force binary and text mode transfers, respectively. - - File transfers can not be initiated on the "kermit -9" command line; - for that you need to use Kermit's FTP personality (next section) or - you can use URLs ([218]Section 3.1.3). - _________________________________________________________________ - - 3.1.2. The FTP Command-Line Personality - - If you want to replace your regular FTP client with C-Kermit, you can - make a link called "ftp" to the C-Kermit binary (or you can store a - copy of the C-Kermit binary under the name "ftp"). When C-Kermit is - invoked with a program name of "ftp" (or "FTP", case doesn't matter), - it assumes the command-line personality of the regular FTP client: - - ftp [ options ] hostname [ port ] - - In this case the options are like those of a regular FTP client: - - -d Debug: enables debug messages and creates a debug.log file. - -n No autologin: Kermit should not send your user ID automatically. - -t Packet trace: accepted but is treated the same as -d. - -v Verbose: accepted but ignored (operation is verbose by default). - -i Not interactive: accepted but ignored. - - and the hostname can also be a URL (explained in [219]Section 3.1.3). - To specify a non-default TCP port for the FTP server, include the port - number or name after the hostname. - - There are also some bonus options that allow you to execute an entire - FTP session from the shell command line, as long as you don't include - the -n option. These are not available with regular FTP clients, and - at least one of these options (-g) conflicts with UNIX ftp (where -g - means "no globbing", which does not apply to Kermit), and some of them - (like the options above) also conflict with regular Kermit - command-line options: - - -m mode = "passive" (default) or "active" - -Y Don't execute the Kermit initialization file [1] - -q Quiet, suppresses all but error messages [1] - -S Stay, don't exit automatically [1] - -A Autologin anonymously [2] - -u name Username for autologin [2] (synonym: -M [1]) - -P password Password for autologin (see cautions below) [2] - -D directory cd after autologin [2] - -b Binary mode [2] - -a Text ("ascii") mode [2] (synonym: -T [1]) - -R Recursive (works with -p) [4] - -p files Files to put (upload) after autologin [2] (synonym: -s [1]) - -g files Files to get (download) after autologin [3] - - [1] Same as Kermit, not available in regular FTP clients. - [2] Conflicts with Kermit, not available in regular FTP clients. - [3] Same as Kermit, conflicts with regular FTP clients. - [4] Conflicts with Kermit, available in some FTP clients. - - Fancier options such as restart, character-set translation, filename - collision selection, automatic move/rename/delete, etc, are not - available from the command line; for these you can use the commands - described in the following sections. The -R option might also work - with -g (GET) but that depends on the server. - - The following security options are also available, explained in - [220]Section 3.2: - - -k realm Kerberos 4 realm [4] - -f Kerberos 5 credentials forwarding [4] - -x autoencryption mode [4] - -c cipher SRP cipher type [4] - -H hash SRP encryption hash [4] - -z option Security options [4] - - If you include -A or specify a name of "anonymous" or "ftp", you are - logged in anonymously and, in the absence of -P, Kermit automatically - supplies a password of "user@host", where "user" is your local user - ID, and "host" is the hostname of the computer where Kermit is - running. If you do not include -p or -g, Kermit enters command mode so - you can type commands or execute them from a script. - - If you include -p or -g, Kermit attempts to transfer the specified - files and then exits automatically at the end of the transfer unless - you also included -S (Stay). It uses the "brief" file transfer display - (one line per file) unless you include the -q option to suppress it. - - When uploading files with -p, Kermit switches automatically between - text and binary mode for each file. - - When downloading, you can either specify a particular mode (text or - binary) to be used for all the files, or you can let Kermit select the - type for each file automatically, based on its name (see [221]Sections - 3.5 and [222]3.6 for greater detail). In UNIX be sure to quote any - wildcard characters to prevent the shell from expanding them, as shown - in the examples just below. Filename collisions are handled according - Kermit's FILE COLLISION setting (if specified in your Kermit - customization file; otherwise the default, which is BACKUP). - - It should go without saying that the -P option should be used with - caution. In addition to the well-known risks of transmitting plaintext - passwords over the Internet, in this case the password also echos to - the screen if you type it, and can be seen in ps and w listings that - show the user's currently active command and command-line arguments. - Thus command-line FTP sessions are most appropriate for secure or - anonymous connections (those that do not require passwords). - - Here's an example in which you download the latest C-Kermit "tarball" - from the Columbia University FTP archive: - - ftp -A kermit.columbia.edu -bg kermit/archives/ckermit.tar.gz - - This assumes that "ftp" is a symbolic link to C-Kermit. It logs you in - anonymously and gets the ckermit.tar.gz file in binary mode from the - kermit/archives directory. - - Here's a slightly more ambitious example that illustrates CD'ing to - the desired server directory to get a group of files in text mode (in - this case the C-Kermit source files): - - ftp -A kermit.columbia.edu -D kermit/f -ag "ck[cuw]*.[cwh]" makefile - - In this case we CD to the kermit/f directory so we don't have to - include it in each file specification, and we quote the ck[cuw]*.[cwh] - specification so the shell doesn't expand it, since we have to pass it - as-is to the server. Note also that the quotes don't go around the - entire file list; only around each file specification that needs to be - quoted. - - Here's one more example, that uploads a debug log file in binary mode - to the Kermit incoming directory (as we might ask you to do when - following up on a problem report): - - ftp -A kermit.columbia.edu -D kermit/incoming -bp debug.log - - In this case the -D option is required to tell the server where to put - the incoming file. - - Unless the -Y option is included, your Kermit initialization file - (.mykermrc in UNIX, K95.INI in Windows) is executed before the command - line options, so you can set any FTP-related preferences there, as - described in the subsequent sections. - _________________________________________________________________ - - 3.1.3. The FTP URL Interpreter - - If Kermit is invoked with either its regular personality (as "kermit") - or its FTP personality (as "ftp"), you can also give a URL - (Universal Resource Locator) instead of a hostname and options, - with or without a username and password: - ftp ftp://user:password@host/path - ftp ftp://user@host/path - ftp ftp://@host/path (or ftp://:@host/path) - ftp ftp://host/path - kermit ftp://host/path - - If the FTP personality is used, the service must be "ftp". In all - cases, a hostname or address must be included. If a user is included - but no password, you are prompted for the password. If a path - (filename) is included: - * If "@" is included without a user, Kermit prompts for the username - and password. - * If no user and no "@" are included, "anonymous" is used. - * GET is assumed. - - If no path (and no action options) are included, an interactive FTP - session is started, as in this example: - ftp ftp://kermit.columbia.edu - - If a path is included, but a username is not included, "anonymous" is - used and an appropriate user@host password is supplied automatically. - If authentication is successful, Kermit attempts to GET the file - indicated by the path or, if the path is the name of a directory, it - asks the server for a directory listing. In both cases, Kermit - disconnects from the server and exits after the operation is complete - (unless you have included the -S option on the command line). - - Here's an example that gets a listing of the Kermit directory at the - Kermit ftp site: - ftp ftp://kermit.columbia.edu/kermit/ - - This example gets the top-level READ.ME file from the same directory: - ftp ftp://kermit.columbia.edu/kermit/READ.ME - - Here's the same example, but requesting a text-mode transfer: - ftp -T ftp://kermit.columbia.edu/kermit/READ.ME - This illustrates that you can mix command-line options and URLs - if you desire. - - Here's an example that logs in as a (fictitious) real user to get a - file: - ftp ftp://olga@ftp.xyzcorp.com/resume.txt - The password is not included, so Kermit prompts for it. - - This scheme allows Kermit to be used as the FTP helper of other - applications, such as Web browsers, with all its advantages over other - FTP clients (especially the ones that are built in to most Web - browsers), e.g. that it can be given wildcards, and it can pick text - and binary mode automatically for each file. - - HINT: suppose somebody sends you an FTP URL in email, or you see it in - some text. If your terminal screen supports copy/paste, copy the url, - and then at the shell prompt type "kermit", a space, and then paste - the URL, e.g.: - - $ kermit ftp://alpha.greenie.net/pub/mgetty/source/1.1/mgetty1.1.27-O - - "$ is the shell prompt; the part you type is underlined, the rest is - pasted in. Kermit does the rest. - _________________________________________________________________ - - 3.1.4. Interactive FTP Session Establishment - - As you read this and the following sections, bear in mind that any - command that can be given at the prompt can also be used in a script - program. Kermit's script programming language is the same as its - interactive command language. [223]CLICK HERE if you would like to - learn a bit more about script writing. - - An FTP session is established with the FTP OPEN command: - - FTP [ OPEN ] [ { /SSL, /TLS } ] hostname [ switches ] [ port ] - Opens an FTP connection to the given host on the given port - and, if FTP AUTOLOGIN is ON, also logs you in to the server, - prompting for username and password if necessary. If no port is - specified, the regular FTP protocol port (21) is used. The OPEN - keyword is optional (unless the hostname conflicts with one of - the FTP command keywords, which you can list by typing "ftp - ?"). - - The hostname can be an IP host name, numeric IP address, or if you - have a network directory active (SET NETWORK DIRECTORY; see Chapter 6 - of [224]Using C-Kermit), an entry name in the directory. In the latter - case, if the given hostname matches exactly one entry, the associated - name or address is used; if it matches more than one, Kermit cycles - through them until one is found that can be opened; if it matches - none, then the hostname is used as-is. If a directory is active but - you want to bypass directory lookup, include an "=" sign at the - beginning of the hostname, and/or use a numeric IP address. - - When an FTP connection is opened, the default file-transfer mode is - set to binary if the client and server platforms are alike (e.g. both - of them are some kind of UNIX), and to text ("ascii") if they are not - alike. This has no particular effect for uploading since Kermit - automatically switches between text and binary mode for each file, but - might be important for downloading. The connection is also set to - Stream mode and File structure. Record- or page-oriented file - transfers are not supported by C-Kermit's FTP client. - - The optional FTP OPEN switches are: - - /ANONYMOUS - Logs you in anonymously, automatically supplying username - "anonymous" and user@host as the password, based on your local - user and host names. - - /NOLOGIN - - Overrides SET FTP AUTOLOGIN ON for this connection only. - - /USER:name - Uses the given username to log you in, thus avoiding the Name: - prompt. - Overrides SET FTP AUTOLOGIN OFF for this connection only. - - /PASSWORD:text - Uses the given text as your password, thus avoiding the - Password: prompt. This switch is not recommended for use in - script files, which would be a security risk. - - /ACCOUNT:text - Uses the given text as your account (or secondary password, - depending on the requirements of the server; most servers do - not require or accept an account name). If an account is not - supplied, you are not prompted for one. - - /PASSIVE - Opens the connection in passive mode. Passive mode is the - default in Kermit's FTP client, unlike in most others, since it - works better through firewalls. The /PASSIVE and /ACTIVE - switches apply only to the connection that is being opened, and - do not affect the global FTP PASSIVE-MODE setting. - - /ACTIVE - Opens the connection in active mode. Use this switch if the - server does not support passive mode, or use the command SET - FTP PASSIVE-MODE OFF. - - /NOINIT - Added in C-Kermit 8.0.201. Tells C-Kermit not to send REST, - STRU, FEAT, and MODE commands to the server when the connection - is opened, since these have been reported to cause confusion in - certain servers. - - When a username or password is missing, a prompt is issued at the - controlling terminal and you must type the response; the response can - not be scripted. Use the switches to avoid prompts, or one of the - secure authentication methods described in the next section, or see - [225]SET FTP AUTOLOGIN and the [226]FTP USER and similar commands - described later in this section. - - Examples: - - ftp open kermit.columbia.edu /anonymous ; Open and log in anonymously - ftp kermit.columbia.edu /anonymous ; The OPEN keyword can be omitted - ftp xyzcorp.com ; Open and maybe prompt for username - ftp xyzcorp.com /user:olga ; Open and log in as olga - ftp testing.abccorp.com 449 ; Specify a special TCP port number - ftp testing.abccorp.com /user:olaf /password:secret 449 - - The FTP OPEN command succeeds if a connection was opened to the server - (even if the given username and password were not valid) and fails - otherwise (see [227]Section 3.8 for details). - - When your FTP session is complete, you can terminate it as follows: - - FTP BYE - Closes the FTP connection if one was open. The FTP prefix can - be omitted if no other connection is open at the same time (see - [228]Section 3.8 for details). If a connection log is active, - an FTP record is written to it. If Kermit was started with the - -9 command-line option or with its FTP command-line - personality, and the -S (Stay) option was not given, AND there - is no other active connection, the FTP BYE command also exits, - just as it does on a regular FTP client. Synonyms: FTP CLOSE, - FTP QUIT (but if the FTP prefix is omitted from QUIT, this - becomes the regular Kermit QUIT command, which is equivalent to - EXIT; i.e. it closes the connection and exits from Kermit). - - The following commands can be used to achieve greater control over the - connection and login process: - - SET FTP ANONYMOUS-PASSWORD text - Allows you to choose the password text to be sent automatically - by Kermit when you open an FTP connection with the /ANONYMOUS - switch. - - SET FTP AUTOLOGIN { ON, OFF } - If you give this command prior to opening an FTP connection, it - controls whether Kermit tries to log you in automatically as - part of the connection process. Normally ON, which means the - username and password are sent automatically (and prompted for - if they are not yet known). When OFF, FTP OPEN connects to the - server without logging in. OFF is equivalent to the -n - command-line option when using Kermit's FTP command-line - personality. - - FTP USER name [ password [ account ] ] - Used to log in to an FTP server to which a connection has been - made without autologin, or when autologin failed. If the - password is furnished on the command line, it is used; - otherwise you are prompted for a password. An account may also - be furnished if required by the server; it is not required by - Kermit and is not prompted for if omitted. Synonyms: USER, FTP - LOGIN. - - FTP ACCOUNT text - Sends an account name to a server that supports accounts. If - the server does not support accounts, an error response occurs. - If the server does support accounts, the account is accepted if - it is valid and rejected if it is not. The account might be - used for charging purposes or it might be a secondary password, - or it might be used for any other purpose, such as an access - password for a particular disk. Servers that support accounts - might or might not allow or require the account to be sent - prior to login; usually it is sent after login, if at all. - Synonym: ACCOUNT. - - Example: - -set ftp autologin off ; One thing at a time please -ftp xyzcorp.com ; Try to make the connection -if fail exit 1 FTP connection failed ; Check that it was made -ftp user olga secret ; Now log in to the server -if fail exit 1 FTP login failed ; Check that it worked -ftp account 103896854 ; Login OK - send account -if fail echo WARNING - FTP ACCT failed ; Warn if problem -... ; (have session here) -bye ; Log out and disconnect - - The following commands are used to control or get information about - the FTP connection. Any particular FTP server does not necessarily - support all of them. - - FTP RESET - Terminates a user session but leaves the connection open, - allowing a new login via FTP USER. - - FTP IDLE [ number ] - Most FTP servers automatically log you out and and disconnect - your session if there has been no activity for a certain amount - of time. Use this command to ask the server to set its idle - limit to the given number of seconds. Omit the number to ask - the server to inform you of its current idle limit. - - FTP STATUS [ filename ] - Asks the FTP server to send information about the current - session. The result is a free-format report that might include - server identification, username and login time, FTP protocol - settings, and file-transfer statistics. If a filename is given, - the server is supposed to send detailed information about the - file. - - FTP SYSTEM - Asks the FTP server to identify its operating system (Listed in - Internet Assigned Numbers, Operating System Names). Examples: - UNIX, VMS, VM/CMS, WINDOWS-NT. Unfortunately many variations - are allowed (e.g. LINUX-2.0, LINUX-2.2, FREEBSD, ULTRIX, etc, - instead of UNIX; WINDOWS-NT-3, WINDOWS-NT-3.5, WINDOWS-NT-3.51, - WINDOWS-NT-4, etc). The report might also include other - information like "Type L8", "Type I", or "Type A", indicating - the file-transfer mode. - - FTP HELP [ keyword [ keyword [ ... ] ] - Asks the server to list the commands it supports. The response - is usually cryptic, listing FTP command mnemonics, not the - commands used by the client (since the server has no way of - knowing anything about the client's user interface). For - example, the PUT command is STOR in FTP protocol. If a keyword - is given, which should be an FTP protocol command, - slightly-more- detailed help is given about the corresponding - command (if the FTP server supports this feature). Examples: - "ftp help", "ftp help stor". - - FTP SITE text - (Advanced) Sends an FTP SITE (site-specific) command. Usually - this means that the FTP server is asked to run an external - command with the given arguments. You might be able to find out - what SITE commands are available by sending "ftp help site" to - the server, but in general the availability of and response to - SITE commands is (not surprisingly) site specific. - - FTP QUOTE text - (Advanced) Sends an FTP command in FTP protocol format. Use - this command to send commands to the server that the FTP client - might not know about. - - SHOW FTP - Lists client (Kermit) FTP settings and information. Also SHOW - CONNECTION, SHOW COMMUNICATIONS. - - HELP FTP [ keyword ] - Asks Kermit to list and describe its built-in FTP commands. - - HELP SET FTP [ keyword ] - Asks Kermit to list and describe its built-in SET FTP commands. - - [ [229]Top ] [ [230]FTP Top ] [ [231]C-Kermit Home ] [ [232]Kermit - Home ] - _________________________________________________________________ - - 3.2. Making Secure FTP Connections - - Also see: [233]Accessing IBM Information Exchange with Kermit. - - In the previous section, you can see several examples of traditional - insecure authentication: username and password sent across the network - in clear text. Of course this is bad practice on at least two counts: - (1) storing passwords in files (such as script files) gives access to - the target systems to anybody who can obtain read access to your - scripts; and (2) sending this information over the network leaves it - open to interception by network sniffers or compromised hosts. - - Because of the increasing need for security on the Internet, FTP - servers are beginning to appear that offer secure forms of - authentication, in which no information is sent over the network that - would allow anyone who intercepts it to usurp your identity and gain - your access rights. - - Kermit provides an equivalent form of FTP security for each type of - IETF standard security implemented in Telnet. These include - GSSAPI-KERBEROS5, KERBEROS4, Secure Remote Password (SRP), and - Transport Layer Security (SSL and TLS). It does not presently include - SSL tunneling nor any form of SSH v1 or v2. When Kermit is built with - the necessary libraries, secure FTP connections are attempted by - default, in which all connections are authenticated and the command - and data channels are private. - - The use of authentication and encryption for FTP connections can be - adjusted with the commands listed below, which are available only if - your version of Kermit was built with the corresponding security - options and libraries: - - SET FTP AUTHTYPE { AUTOMATIC, GSSAPI-KRB5, KERBEROS4, SRP, SSL, TLS } - Specifies an ordered list of authentication methods to be - attempted when AUTOAUTHENTICATION is ON. The default list is: - GSSAPI-KRB5, SRP, KERBEROS_V4, TLS, SSL. If none of the - selected methods are supported by the server, an insecure login - is used as a fallback. Note, by the way, that SSL or TLS can be - used to secure an anonymous connection. - - SET FTP AUTOAUTHENTICATION { ON, OFF } - Tells whether authentication should be negotiated by the FTP - OPEN command. Default is ON. Use SET FTP AUTOAUTHENTICATION OFF - to force a clear-text, unencrypted connection to FTP servers - (such as the one at the Kermit FTP site) that normally would - try to negotiate secure authentication and encryption. - - SET FTP AUTOENCRYPTION { ON, OFF } - Tells whether encryption (privacy) should be negotiated by the - FTP OPEN command, which can happen only if secure - authentication is also negotiated. Default is ON. - - SET FTP AUTOLOGIN { ON, OFF } - Tells Kermit whether to try logging in automatically when you - make an FTP connection, as opposed to letting you do it "by - hand" with the FTP USER command. - - SET FTP COMMAND-PROTECTION-LEVEL { CLEAR, CONFIDENTIAL, PRIVATE, SAFE - } - Determines the level of protection applied to the command - channel: - - CLEAR Data is sent in plaintext and not protected against tampering. - CONFIDENTIAL Data is encrypted but not protected against tampering. - PRIVATE Data is encrypted and is protected against tampering. - SAFE Data is sent in plaintext but protected against tampering. - - The default is PRIVATE. - - SET FTP CREDENTIAL-FORWARDING { ON, OFF } - Tells whether end-user credentials are to be forwarded to the - server if supported by the authentication method (GSSAPI-KRB5 - only). This is often required to allow access to distributed - file systems (e.g. AFS.) - - SET FTP DATA-PROTECTION-LEVEL { CLEAR, CONFIDENTIAL, PRIVATE, SAFE } - Tells what level of protection is applied to subsequent data - channels. The meanings of the protection-level keywords are the - same as for SET FTP COMMAND-PROTECTION-LEVEL. The default is - PRIVATE. - - SET FTP SRP CIPHER name - Specifies the cipher to be used for encryption when SRP - authentication is in use. The list of possible choices is - computed based on the capabilities of the local SRP library and - includes NONE plus zero or more of the following: - - BLOWFISH_ECB CAST5_ECB DES_ECB DES3_ECB - BLOWFISH_CBC CAST5_CBC DES_CBC DES3_CBC - BLOWFISH_CFB64 CAST5_CFB64 DES_CFB64 DES3_CFB64 - BLOWFISH_OFB64 CAST5_OFB64 DES_OFB64 DES3_OFB64 - - The default is DES3_ECB. - - SET FTP SRP HASH name - Specifies the hash to be used for data protection when SRP - authentication is in use. The choices are MD5 and SHA. The - default is SHA. - - Command-line options: - - -k name - Specifies the realm to be used with Kerberos 4 authentication - (= SET AUTH K4 REALM name). - - -f - Enables forwarding of Kerberos 5 credentials to the host when - using GSSAPI authentication (= SET AUTH K5 FORWARDABLE ON). - - -x - Enables autoencryption (= SET FTP AUTOENCRYPTION ON). - - -c cipher - Specifies the kind of cipher to be used for encryption with SRP - authentication. Equivalent to SET FTP SRP CIPHER, with the same - choices. If this option is not given, CAST5_CBC is used. - - -H hash - Specifies the hash to be used for encryption with SRP - authentication. Equivalent to SET FTP SRP HASH, with the same - choices. If this option is not given, SHA is used. - - -z debug - Turns on SSL/TLS debugging. - - -z secure - Requires secure connection. - - -z certsok - Says to accept all certificates without checking validity. - - -z verify=n - Sets certificate verification mode to the given number, n: - 0 = no verification - 1 = verify certificate if presented - 2 = require verification of certificate - - -z cert=filename - Specifies a file containing a client certificate to be - presented to the FTP server. - - -z key=filename - Specifies a file containing a private key matching the client - certificate. - - -z !krb4 - (nokrb4) Disables the use of Kerberos 4. - - -z !gss - -z nogss - Disables the use of GSSAPI - Kerberos 5. - - -z !srp - -z nosrp - Disables use of SRP. - - -z !ssl - -z nossl - Disables the use of SSL. - - -z !tls - -z notls - Disables the use of TLS. - - Caution: If your FTP connection is secured via AUTH TLS, it is not - possible to interrupt a file transfer. This is a limitation of all - known FTP servers that support AUTH TLS. - - Note that when using certain security methods, such as SSL or TLS, you - may be prompted to confirm or verify certain actions or conditions, - for example, whether to accept self-signed certificates. This can - interfere with unattended operation of scripts; see [234]Section 3.10. - - [ [235]Top ] [ [236]FTP Top ] [ [237]C-Kermit Home ] [ [238]Kermit - Home ] - _________________________________________________________________ - - 3.3. Setting FTP Preferences FTP preferences can be set globally and - persistently with the commands in the following sections; many of - these can also be overridden on a per-command basis with switches that - have the same name. - - 3.3.1. Logs, Messages, and Other Feedback - - You can control the amount of feedback received from your FTP session - with the commands in this section. First, you can create a log of your - FTP transfers with the following commands: - - SET TRANSACTION-LOG { VERBOSE, FTP, BRIEF } - Selects the log format. VERBOSE is the default, and is - described in [239]the manual. FTP chooses a WU-FTPD format, the - same as is used by the popular FTP server. BRIEF creates - per-file records in comma-separated-list format. For greater - detail, see [240]Section 4.17 of the [241]C-Kermit 7.0 Update - Notes. - - LOG TRANSACTIONS filename - Records FTP (or Kermit, or any other protocol) uploads and - downloads in the given file using the format selected by the - most recent SET TRANSACTION-LOG command, if any, or else the - default format. - - FTP screen messages and displays are controlled by the following - commands: - - SET TRANSFER DISPLAY { FULLSCREEN, CRT, SERIAL, BRIEF, NONE, OFF } - FTP transfers use Kermit's normal file-transfer display styles. - Use this command to choose the desired format; the default on - most platforms is FULLSCREEN. The display is automatically - disabled if Kermit is running in the background or in batch. - BRIEF is always used for command-line initiated transfers - (unless suppressed by -q). While a file-transfer is in - progress, you can interrupt it in the normal Kermit way by - typing one of the following keys or key combinations: - X - Cancel current file but go on to the next one (if any). - Z - Cancel the entire transfer. Ctrl-L or Ctrl-W - Refresh - the file-transfer display (if any). - - SET FTP DISPLAY { FULLSCREEN, CRT, SERIAL, BRIEF, NONE, OFF } - Like SET TRANSFER DISPLAY, but applies only to FTP connections, - and does not affect Kermit- or other protocol file transfers. - - SET QUIET { ON, OFF } - This command applies to Kermit in general, not just FTP. OFF by - default; when ON, it surpresses most messages from most - commands as well as the file-transfer display. - - SET FTP PROGRESS-MESSAGES { ON, OFF } - Tells whether Kermit should print locally-generated feedback - messages for each non-file-transfer command. ON by default. - - SET FTP VERBOSE-MODE { ON, OFF } - Tells whether to display all responses from the FTP server. OFF - by default. This shows all responses to all commands, except - when the file-transfer display is active, and unless you have - SET QUIET ON. When OFF, responses are shown only for commands - such as FTP PWD whose purpose is to display a response. - - SET FTP DEBUG { ON, OFF } - Tells whether local client debugging information should be - displayed. OFF by default. When ON, the commands that are sent - to the server are shown, as well as its responses (even if - VERBOSE-MODE is OFF), plus additional informational messages - are printed regarding the progress of secure operations. Also, - the temporary file created by the [242]MGET command is not - deleted so you can see what's in it. - - Set all of these to OFF when silent running is desired. - - 3.3.2. Operational Preferences - - FTP DISABLE new-protocol-feature-name - FTP ENABLE new-protocol-feature-name - Explained in [243]Section 3.11. - - SET FTP AUTOLOGIN { ON, OFF } - If you give this command prior to opening an FTP connection, it - controls whether Kermit tries to log you in automatically as - part of the connection process. Normally ON, which means the - username and password are sent automatically (and prompted for - if they are not yet known). When OFF, FTP OPEN connects to the - server without logging in. OFF is equivalent to the -n - command-line option when using Kermit's FTP command-line - personality. See [244]Section 3.1.4 for usage. - - SET FTP PASSIVE-MODE { ON, OFF } - ON by default, to avoid random TCP port assignment for data - connections, which can prevent FTP protocol from working - through firewalls and network address translators (for more on - these topics, see the [245]Kermit security reference. Set to - OFF in case the FTP server does not support passive mode, or in - case the client has problems with it (it has been observed, for - example, that when using passive mode, the SCO XENIX 2.3.4 - TCP/IP stack hangs in the connect() call forever). Synonyms: - PASSIVE [ ON ], PASSIVE OFF, PASV [ ON ], PASV OFF. - - SET FTP SEND-PORT-COMMANDS { ON, OFF } - This command determines whether the FTP client sends a new PORT - command to the server when accepting incoming data connections - (as when not using passive mode.) When PASSIVE-MODE is OFF and - SET SEND-PORT is OFF, the port that was originally specified is - reused. This is the default behavior for normal FTP clients but - it is not compatible with many firewalls. - - SET FTP CHARACTER-SET-TRANSLATION { ON, OFF } - Whether to translate character sets when transferring files - with FTP (explained in [246]Section 3.7). OFF by default. - - SET FTP SERVER-CHARACTER-SET name - Tells Kermit the character set used by the FTP server, UTF-8 by - default ([247]Section 3.7). - - SET FTP SERVER-TIME-OFFSET delta-time - Tells Kermit to apply the given [248]delta time to file - timestamps provided by the server for its files; for use when - (for example) the server does not have its timezone set - correctly. - - SET FTP ERROR-ACTION { PROCEED, QUIT } - When transferring a group of files with FTP, and an error - occurs with one of the files, Kermit normally goes on the next - file. Use SET FTP ERROR-ACTION to QUIT to make Kermit stop the - transfer immediately and fail if an error occurs with any - single file in the group. Example: you have given Kermit a list - of files to send, and one of the files can not be found, or - read permission is denied. Note that cancelling a file by - typing 'X' during transfer is not considered an error (if you - want to cancel the entire transfer, type 'Z' or Ctrl-C). - - SET FTP PERMISSIONS { AUTO, ON, OFF } - When uploading files with PUT or MPUT, this tells whether - Kermit should send each file's permissions. The default is OFF, - which means not to send permissions, in which case the uploaded - file's permissions are set by the FTP server according to its - own criteria. ON means to send them, AUTO means to send them - only if the client (Kermit) and server are on like platforms - (e.g. both UNIX). This command has no effect when downloading, - since the FTP protocol does not include a way for the server to - inform the client of a file's permissions. Also see [249]FTP - PUT /PERMISSIONS. Note that setting permissions after uploading - is likely to work (correctly or at all) only when the client - and server platforms are alike (e.g. both of them are some form - of UNIX). Also note that Windows files don't have permissions. - Also see [250]FTP CHMOD. - - SET FTP DATES { ON, OFF } - When downloading files with GET or MGET, this tells whether - Kermit should try to set the received file's date from the - server's date. FTP DATES is ON by default. Note, however, that - FTP protocol does not allow date preservation when uploading. - So at best, SET FTP DATES ON can work only when downloading, - and then only when the server agrees to furnish file dates. - - SET FTP FILENAMES { AUTO, CONVERTED, LITERAL } - When uploading (sending) files, this tells whether to convert - outbound filenames to "common form". This means allowing only - one period in a name, uppercasing any lowercase letters, - replacing spaces by underscores, etc. AUTOMATIC is the default, - meaning LITERAL when client and server are the same type of - system (e.g. UNIX) and CONVERTED otherwise. Special case: if - the setting is AUTOMATIC and the client is not UNIX and the - server identifies itself as UNIX, Kermit uses a less-strict - form of conversion, in which lowercase letters are not - uppercased and the filename can contain any number of periods, - but spaces are still converted to underscore. When receiving, - conversion generally means to change all-uppercase names to - lowercase and spaces to underscore. - - SET FTP UNIQUE-SERVER-NAMES { ON, OFF } - Applies only to uploads. Tells the server to create new, unique - names for incoming files that have the same names as existing - files. OFF by default, in which case the server overwrites - existing files with new files of the same name. When ON, the - server uses its own built-in method for creating new names for - incoming files; for example, appending a period (.) and a - number to the name. CAUTION: Use this option only if you do not - need to refer to the file after it is uploaded, since FTP - protocol provides no mechanism for the client to find out what - name was assigned by the server. - - SET FTP COLLISION { ... } - When downloading, what to do if an incoming file has the same - name as an existing file. Options are the same as for SET FILE - COLLISION. If this command is not given, Kermit's regular FILE - COLLISION setting is used. If this command is given, it - overrides the FILE COLLISION setting for FTP transfers only. - See [251]Section 3.6.2 for details. - - SET FTP TYPE { TEXT, BINARY, TENEX } - Changes the default transfer mode. When sending (uploading) - files, this command has no effect unless you disable automatic - text/binary mode switching ([252]Section 4) with SET FILE SCAN - OFF or SET TRANSFER MODE MANUAL. When receiving (downloading) - files, this command establishes the transfer mode to be used - when a filename does not match any of Kermit's text or binary - filename patterns, unless you use SET FTP - GET-FILETYPE-SWITCHING or SET TRANSFER MODE MANUAL to disable - automatic switching, in which case, this command establishes - the transfer mode for all downloaded files. In all cases, - however, the FTP TYPE can be overridden in any GET or PUT - command by including a /TEXT (/ASCII), /BINARY, or /TENEX - switch. The FTP TYPE is independent of the Kermit FILE TYPE - setting. TENEX is used for sending 8-bit binary files to 36-bit - platforms such as TOPS-10, TOPS-20, and TENEX, and getting them - back again. Synonym: ASCII = TEXT. Note: there is also an FTP - TYPE command, which does what SET FTP TYPE does but also sends - a TYPE command to the server immediately if the given type is - different from the current one. - - If you want want specific FTP preference settings to be in effect for - all your Kermit FTP sessions, put the desired SET FTP commands in your - Kermit customization file (~/.mykermrc in UNIX, K95CUSTOM.INI in - Windows). - - [ [253]Top ] [ [254]FTP Top ] [ [255]C-Kermit Home ] [ [256]Kermit - Home ] - _________________________________________________________________ - - 3.4. Managing Directories and Files - - In Kermit, commands for directory and file management can refer to: - - * The local computer - * A remote computer when you have a connection to a Kermit server or - IKSD. - * A remote computer when you have a connection to an FTP server. - - (There can also be an HTTP connection, but the commands in this - section don't apply to HTTP connections.) - - Thus in general, each such command comes in three forms: - - 1. With no prefix in C-Kermit 8.0.200, it refers to the local - computer (CD, DIR, etc). In C-Kermit 8.0.201 and later, however, - the "locus" switches to automatically to the remote FTP server - when you make an FTP connection (see the SET LOCUS description - [257]Section 7); thus C-Kermit 8.0.201 acts almost exactly like a - regular FTP client when it has an FTP connection, yet still acts - like itself on other kinds of connections. - 2. With the REMOTE prefix, it is for a Kermit server (REMOTE CD, - REMOTE DIR). - 3. With the FTP prefix, it's for an FTP server (FTP CD, FTP DIR). - 4. Also see [258]Section 3.8, which explains "R-commands" and - "L-commands". - - Kermit's FTP file and directory management commands are as follows. - When an R-command is included in the Synonyms list, be sure to read - [259]Section 3.8 about rules for use of R-commands. - - FTP CD [ directory ] - Tells the FTP server to change its default (working) directory - to the one given, which usually must be expressed in the syntax - of the server platform (UNIX, VMS, etc). If the directory is - not specified, the result depends on the FTP server -- it might - complain that the command is illegal, or it might change to - your original login directory. Synonyms: FTP CWD (Change - Wording Directory); RCD. - - FTP CDUP - Tells the FTP server to change its default (working) directory - to the parent directory of its current one (equivalent to - "cd .." in UNIX, or "cd [-]" in VMS). Synonyms: RCDUP, FTP UP. - - FTP PWD - Asks the FTP server to report ("print") its current working - directory. Synonym: RPWD. - - FTP MKDIR directory - Asks the FTP server to create the directory whose name is - given. In general, the name must be in the syntax of the - server's file system, and it must be either absolute (a full - pathname) or relative to the server's current (working) - directory. This command fails if the directory can't be created - for any reason, including that it exists already. Synonym: - RMKDIR. - - FTP RMDIR directory - Asks the FTP server to remove the directory whose name is - given. The rules are the same as for MKDIR, plus in most cases, - the server will not remove any directory unless it is empty. - Synonym: RRMDIR. - - FTP DIRECTORY [ filespec ] [ redirectors ] - Tells the FTP server to send a directory listing of the - specified files. If no filespec is given, the server lists all - files in its current working directory. The results are in - whatever format the server chooses to send them. You can use - UNIX-like redirectors to send the listing to a file or a - pipeline, exactly as with the regular Kermit client/server - REMOTE DIRECTORY command ([260]Using C-Kermit, Chapter 11). - Synonym: RDIRECTORY. Examples: - - ftp dir ; Show listing of all files on screen - ftp dir *.txt ; List *.txt files on screen - ftp dir *.txt > somefile ; Put listing in somefile - ftp dir *.txt >> somefile ; Append listing to somefile - ftp dir *.txt | sort > somefile ; Put sorted listing in somefile - ftp dir | more ; Runs list through "more" - ftp dir | sort | more ; Runs list through "sort" and "more" - - FTP VDIRECTORY [ filespec ] [ redirectors ] - "Verbose" directory. This is an alternative FTP DIRECTORY - command primarily for use with DECSYSTEM-20 (TOPS-20) FTP - servers, which send only filenames when given a DIRECTORY - command; the VDIRECTORY command makes them also send file - sizes, dates, and attributes. - - FTP CHECK filespec - Asks the FTP server whether the given file exists or, if the - filespec contains wildcards, if any files match, and this - command succeeds or fails accordingly. - - FTP MODTIME filename - Asks the FTP server, via the not-yet-standard FTP MDTM command, - to send the modification date and time of the given file. The - response should be a numeric string in the format: - yyyymmddhhmmssxxxxx... where yyyy is the year, mm is the month, - dd is the day, hh is the hour (0-23), mm is the minute, ss is - the second, and xxx... is the optional fraction of the second - (0 or more digits). The date and time is expressed in UTC (GMT, - Zulu, Zero-Meridian). The result is available programmatically - in the [261]\v(ftp_message) variable, and is understandable by - Kermit's date-time switches and functions. For example, suppose - we want to upload all local files that are newer than a - particular file on the server: - - C-Kermit> ftp modtime signpost - C-Kermit> echo \v(ftp_message) - 20010807113542.014 - C-Kermit> ftp mput /after:\v(ftp_message)GMT * - - Note that we must append "GMT" to the date-time string to let - the /AFTER switch know the time is GMT rather than local. - - FTP SIZE filename - Asks the FTP server to send the size (in bytes) of the given - file. The result might vary depending on whether the current - FTP TYPE is binary or text ("ascii"). For a reliable byte - count, do FTP TYPE BINARY first. The result is available - programmatically in the [262]\v(ftp_message) variable. - - FTP CHMOD permissions filename - Tells the FTP server to set the permissions (protection) of the - given file to the ones given. The permissions and filename must - be given in whatever syntax is required by the server. Example - (for a UNIX-based FTP server): - - ftp chmod 664 oofa.txt - - Not all servers support this command. For non-UNIX-based - servers, you might need to use FTP QUOTE or FTP SITE and the - appropriate platform-specific FTP server command. - - FTP UMASK [ number ] - This command is probably specific to UNIX-based servers; it - sets the UNIX "umask", which is the default permissions mask - for new (in this case, incoming) files. Crudely put, the UNIX - umask is an octal representation of a binary number in in which - a 1 bit stands for a permission bit that must be 0, and a 0 bit - stands for a permission bit that can be 0 or 1 depending on - other factors, such as the permissions of the parent directory. - Example: "umask 007" requires that new files are created - without read/write/execute world permission. If the number is - not specified, the server's current umask is reported. - - FTP RENAME filename newname - Asks the FTP server to rename the file whose name is "filename" - to "newname". Works only for one file; can not be used with - wildcards. The server's interpretation of "newname" can vary - (in some cases it must be a filename, in others perhaps it can - also be a directory name, in which case if the filename denote - a regular file, the file might be moved to the given - directory). Some servers might allow files to be renamed - ("moved") between physical disks or partitions, others might - not. Synonym: RRENAME. - - FTP DELETE [ switches ] filespec [ filespec [ ... ] ] - Tells the FTP server to delete the file or files listed. Each - file specification may, but need not, contain wildcard - characters to match multiple files. File specifications and - wildcard syntax must be those of the server. Any file - specifications that contain spaces must be enclosed in braces - or doublequotes. FTP DELETE switches are: - - /ERROR-ACTION: /FILENAMES: /NOBACKUPFILES /QUIET - /EXCEPT: /LARGER-THAN: /NODOTFILES /NOPAGE - /PAGE /RECURSIVE /SMALLER-THAN: - - When used with FTP DELETE, the /RECURSIVE switch deletes files - but not directories, and furthermore depends on the server - providing recursive file lists, which is not the normal - behavior. For further details, see the decriptions of these - switches in [263]Section 3.6. Synonyms: FTP MDELETE (Kermit - makes no distinction between DELETE and MDELETE); RDELETE. - - FTP TYPE { TEXT, BINARY, TENEX } - Tells the FTP server to change its file-transfer type to the - one given, immediately. See [264]SET FTP TYPE for details. - - [ [265]Top ] [ [266]FTP Top ] [ [267]C-Kermit Home ] [ [268]Kermit - Home ] - _________________________________________________________________ - - 3.5. Uploading Files With FTP - - Uploading means sending files from the client (Kermit) to the FTP - server. The basic command for uploading files with FTP is PUT: - - FTP PUT [ switches ] [ filespec [ as-name ] ] - Uploads (sends) the file or files that match the file - specification, which may include wildcards, to the server. If - no filespec is given, the names of files to send are taken from - the /LISTFILE: file, if any, otherwise from the SEND-LIST, if - any. Unless you go out of your way to prevent it, Kermit - determines the transfer mode (text or binary) for each file - automatically, and switches automatically on a per-file basis. - If an as-name is given, the file is sent under that name - instead of its own (if an as-name is given with a wildcard - filespec, the result is a bit more complicated, and is - explained later in this section). - - Unlike normal FTP clients, Kermit does not prompt you by default (or - at all) for each file; it just sends them, just as it does with Kermit - protocol. The filespec can be a literal filename or a Kermit pattern, - described in: - - [269]http://www.columbia.edu/kermit/ckermit70.html#x4.9 - - Kermit patterns are equivalent to C-Shell patterns and provide a fair - amount of flexibility in selecting which files to send, which is - augmented by the file-selection switches presented in [270]Section - 3.5.1. - - FTP MPUT [ switches ] filespec [ filespec [ ... ] ] - FTP MPUT is just like FTP PUT except it allows you to give more - than one file specification, and it does not allow an as-name - in the file list. However, as-names can be given to either PUT - or MPUT with the /AS-NAME: switch. - - If a PUT or MPUT command results in one file being uploaded, it - succeeds if the file is uploaded completely and fails otherwise. If - more than one file is selected for upload, success or failure depends - on the [271]FTP ERROR-ACTION setting; if it is PROCEED (the default - setting), then the [M]PUT command succeeds if at least one of the - files was completely uploaded, and fails otherwise, If FTP - ERROR-ACTION is QUIT, the [M]PUT command succeeds if all selected - files were uploaded successfully, and fails if any file failed. - - FTP uploads may be interrupted just like Kermit uploads. While the - transfer is in progress, type: - - X to interrupt the current file and go on to the next file. - Z to cancel the current file and all remaining files. - ^C (Control-C): Like Z, but might act more quickly. - - MPUT may be used as in regular FTP clients, but it is not required to - send multiple files; in Kermit it is required only if you want to give - multiple file specifications. Examples: - - ftp put oofa.txt ; Send a single file oofa.txt - ftp put oofa.txt budget.txt ; Send single file oofa.txt as budget.txt - ftp put *.txt ; Send all *.txt files - ftp mput *.txt ; Send all *.txt files (same as "put *.txt") - ftp mput *.txt foo.bar ; Send all *.txt files plus foo.bar - - The distinction between PUT and MPUT is important only when more than - one filespec is given, just like the distinction between Kermit SEND - and MSEND: - - ftp put oofa.txt budget.txt ; Send oofa.txt AS budget.txt - ftp mput oofa.txt budget.txt ; Send oofa.txt AND budget.txt - - If the source file specification includes any path segments, for - example: - - put /tmp/oofa.txt - put subdir/another/andanother/oofa.txt - - the path portion is stripped from the filename that is sent to the - server. However, if an as-name contains a path, it is retained. - Examples: - - ftp put /usr/doc/oofa.txt ; Send as "oofa.txt". - ftp put oofa.txt /tmp/oofa.txt ; Send as "/tmp/oofa.txt" - - The latter example sends the file oofa.txt from your current local - directory to the server's /tmp directory. This works only if the - server uses the same directory notation that you used in the as-name - AND the given directory already exists on the server AND if you have - write access to it. - - Use caution when uploading from a case-sensitive file system, such as - UNIX, to a file system that is not case sensitive, such as Windows or - VMS. If you have two files in UNIX, AA and aa and upload both of them, - the second one will overwrite the first. The only way around this - provided by FTP protocol is its "unique server names" feature (SET FTP - UNIQUE-SERVER-NAMES or the /UNIQUE switch described below). - _________________________________________________________________ - - 3.5.1. FTP PUT Switches - - FTP PUT and MPUT are similar in format and behavior to the regular - Kermit SEND and MSEND commands, and they allow most of the same - optional switches: - -C-Kermit>ftp put ? Filename, or switch, one of the following: - /after: /larger-than: /rename-to: - /array: /listfile: /server-character-set: - /as-name: /local-character-set: /server-rename-to: - /before: /move-to: /simulate - /binary /nobackupfiles /smaller-than: - /command /nodotfiles /tenex - /delete /nofollowlinks /text - /dotfiles /not-after: /transparent - /error-action: /not-before: /type: - /except: /permissions: /update - /filenames: /quiet /unique-server-names - /filter: /recover - /followlinks /recursive - - Since most of these switches are common to Kermit's SEND and MSEND - commands, they described only briefly here. For greater detail see: - - [272]http://www.columbia.edu/kermit/ckermit70.html#x1.5 (explanation - of switches) - [273]http://www.columbia.edu/kermit/ckermit70.html#x4.7 - (file-transfer switches) - - First the file-selection switches: - - /AFTER:date-time - /BEFORE:date-time - /NOT-AFTER:date-time - /NOT-BEFORE:date-time - Only send those files modified on or after or before the given - date and time. These switches can be combined to select files - modified between two date/times. Various date-time formats are - accepted; if the date-time contains spaces, it must be enclosed - in braces or doublequotes. See - [274]http://www.columbia.edu/kermit/ckermit70.html#x1.6 and - [275]Section 8.13 of this document for details about date-time - formats. Examples: - - ftp put /after:{1 jan 2000 0:00:00} * - ftp put /after:-5days * - - /LARGER-THAN:number - /SMALLER-THAN:number - Only send files larger (smaller) than the given number of bytes - (octets). These switches can be combined to select files in a - certain size range. - - /TYPE:{TEXT,BINARY} - Only send files that are the given type, which is determined - for each file just before sending it by file scanning. BINARY - includes TENEX; if you have included a /TENEX switch, or - previously given a [SET] FTP TYPE TENEX command, binary files - are sent in TENEX, rather than BINARY mode. - - /[NO]DOTFILES - [Don't] include files whose names begin with dot (.). By - default, such files are not included unless your filespec - explicitly mentions them. - - /NOBACKUPFILES - Don't include files whose names end with .~nnn~, where nnn is a - number, e.g. oofa.txt.~27~. These are backup files created by - Kermit, EMACS, and other applications. By default, backup files - are included. - - /NOFOLLOWLINKS - (UNIX only) Skip over symbolic links rather than following them - (default). This applies to wildcard and/or recursive [M]PUTs; - if a single filename is given, and it happens to be a symbolic - link, the file it points to is sent. - - /FOLLOWLINKS - (UNIX only) Always follow (resolve) symbolic links, even in - wildcard or recursive [M]PUTs. Use with caution. Watch out for - circular links, endless loops, etc. - - /EXCEPT:pattern - Exception list -- don't send files whose names match the given - pattern. See [276]Section 1.5.4 of the [277]C-Kermit 7.0 Update - Notes for details. If you want to exclude a directory from a - recursive [M]PUT, use /EXCEPT:{dirname/*}. - - /RECURSIVE - Sends the desired files from the current (or given) directory, - plus all directories beneath it, including empty directories, - replicating the directory structure on the server. No special - capabilities are required in the server, but of course your - login ID on the server must have the appropriate access and - permission to create directories. Recursive PUTs work not only - between like platforms (e.g. UNIX to UNIX) but also between - unlike ones (e.g. UNIX to VMS or Windows), in which case - text-file format differences are handled by Kermit's automatic - text/binary mode switching ([278]Section 4) and character-set - translation ([279]Section 3.7). Synonym: /SUBDIRECTORIES. - - /UPDATE - Send only files that have changed since last time ([280]Section - 3.5.2). - - /ARRAY:arrayname - The "file" to be sent is an array, or a segment of one, rather - than a real file. In this case the other selection switches - don't apply. The array contents are sent in text mode, and each - array element is treated as a line. Example: - - ftp put /as-name:array.txt /array:&a - - (or, to send a segment of the array, /array:&a[100:199]). If - you don't include an /AS-NAME, a name of "_array_x_" is used - (where x is the array letter). If you include this switch, most - other switches are meaningless and ignored. - - /COMMAND - The "file" to be sent is the standard output of a command, - rather than a real file. It is sent in text or binary mode - according to the prevailing FTP TYPE, which can be overridden - with a /TEXT or /BINARY switch. Example: Example: - - ftp put /command /as-name:{userlist} {finger | sort -r} - - /LISTFILE:filename - Tells Kermit to obtain the list of files to be sent from the - file whose name is given. This file must contain one file - specification (which may be wild) per line. If the list - includes files from different directories, such as a recursive - listing of a directory tree, the paths are recreated on the - server (if possible) if you include the /RECURSIVE switch; - otherwise all the files are sent to the current directory on - the server. - - Now the other switches: - - /AS-NAME:text - If a single file is being sent, send it with the given text as - its name. If multiple files are being sent, the text must be a - template that includes variables such as \v(filename), - \v(filenumber), \v(ntime), to allow dynamic creation of each - name. The same applies to the as-name field of the FTP PUT - command. If this switch is not included (and an as-name is not - included as the second filename to PUT), each file is sent with - its own name. - - /BINARY - /TEXT - /TENEX - Forces this upload to take place in the given mode, regardless - of the current FTP TYPE setting, and without automatic - text/binary switching. /ASCII is a synonym for /TEXT. - - /FILTER:command - Specifies that the file(s) is/are to be passed through the - given command or pipeline on their way to the server. Example: - - ftp put /binary /filter:{gzip -c \v(filename)} /as-name:\v(filename).gz * - - /TRANSPARENT - /LOCAL-CHARACTER-SET:name - /SERVER-CHARACTER-SET:name - Character-set translation for text files, explained in - [281]Section 3.7. - - /ERROR-ACTION:{PROCEED,QUIT} - Overrides the prevailing [282]FTP ERROR-ACTION for the duration - of this PUT or MPUT command only. - - /RECOVER - Resume an interrupted transfer where from the point of - interruption (explained in [283]Section 3.5.2). Synonym: - /RESTART. - - /DELETE - Tells Kermit to delete each source file immediately after, and - only if, it has been uploaded completely and successfully. - This, in effect, moves the file from the client to the server. - - /MOVE-TO:directory - Tells Kermit to move each source file to the named local - directory after, and only if, it has been uploaded completely - and successfully. - - /RENAME-TO:template - Tells Kermit to rename each (local) source file according to - the given template after, and only if, it has been uploaded - completely and successfully. The template works as in /AS-NAME. - - /SERVER-RENAME-TO:template - Tells Kermit to ask the server to rename each file according to - the given template as soon as, and only if, it has been - received completely and successfully. The template works as in - /AS-NAME. Requires write and rename access on the server, so - doesn't usually work with (e.g.) anonymous uploads to public - incoming areas where the permissions don't allow renaming. - Examples: - - ftp mput /server-rename:\v(filename).ok * - Appends ".ok" to each filename on the server when it's - finished uploading. - - ftp mput /as-name:\v(filename).tmp /server-rename:\v(filename) * - This is the reverse of the previous example; it uses a - temporary name while uploading is in progress and reverts - the file to its real name when uploading is complete. - - ftp mput /as-name:\v(filename) - /server-rename:../final/\v(filename) * - Moves the file from the working directory to a final - directory when the upload is complete, but in this case - you have to know the pathname syntax of the server. If - the rename fails, the [M]PUT command fails according to - the [284]FTP ERROR-ACTION selection. - - /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL} - Overrides the [285]FTP FILENAMES setting for this upload only. - - /PERMISSIONS:{ON,OFF} - Overrides the [286]FTP PERMISSIONS setting for this upload - only. - - /UNIQUE - Tells Kermit to tell the server to give [287]unique names to - incoming files that would otherwise overwrite existing files - that have the same name. This switch conflicts with /UPDATE, - /RECOVER, /PERMISSIONS, and /SERVER-RENAME since the client has - no way of knowing the name assigned by the server. - - /QUIET - Don't display file-transfer progress or statistics. - - /SIMULATE - Shows which files would be sent without actually sending them. - Useful (for example) with /UPDATE (next section). The results - are shown in the file-transfer display (if it is not disabled) - and in the transaction log (if one is active). Hint: use SET - TRANSFER DISPLAY BRIEF. - _________________________________________________________________ - - 3.5.2. Update Mode - - When you include the /UPDATE switch, this means to skip sending any - file that already exists on the server if the local file's - modification date/time is not later than that of the corresponding - file on the server. Here is a typical application for update mode: - Suppose that on Computer A, you maintain a large set of files (say, a - collection of Web pages and graphics images, or the source files for a - software application), and you need to keep a parallel copy on another - Computer, B. Of course you could upload the entire collection every - day: - - cd source-directory - ftp computerb.xyzcorp.com - ( authentication details... ) - ftp cd target-directory - ftp put [ switches ] * - - But if the total size is large or the network slow, this would be - unnecessarily time-consuming. Worse, if other users or sites had to - update whenever new files appeared in B's directory, this would cause - them unnecessary work. By including the /UPDATE switch: - - ftp put /update [ other-switches ] * - - only those files that changed since last time are uploaded. Here's how - it works. For each local file that is selected for uploading: - - * The remote filename is determined in the normal way, according to - the [288]FTP FILENAMES setting, /FILENAMES switch, or the as-name, - if any. - * Kermit sends an MDTM (modification time) command for the - corresponding remote filename to the server. - * If the server does not understand the MDTM command, the file is - sent. - * If the server can't find a file with the given name, the file is - sent. - * If the local file's modification time is later than that of the - remote file, the file is sent. - * Otherwise -- the remote file exists but its modification time is - equal to or earlier than that of the local file -- the file is - skipped. - - All time comparisons take place in Coordinated Universal Time - (UTC)([289]1), also known as GMT or Zulu time: Timezone 0; standard - time, without daylight savings. - - WARNING: Some FTP servers, such as Novell NWFTPD.NLM, ignore or - misimplement the FTP specification and send local time rather than - UTC. - - Update mode is useful only when always used in the same direction. - When you upload (PUT) a file with FTP, the destination file receives - the current timestamp on the server's computer, not the original - file's timestamp ([290]2). If you try to FTP PUT /UPDATE the same file - again, it will be skipped (as expected) since the remote copy is - newer. However, if you try to FTP GET /UPDATE the same file - ([291]Section 3.6), it will be transferred for the same reason. - - To check the availability of PUT /UPDATE on a particular connection, - issue an FTP MODTIME command for a file that is known to exist on the - server. If it succeeds, PUT /UPDATE should work and in that case, you - can run a procedure like the one above every day: the first time, it - sends all the files; after that, it sends only the ones that changed. - If a transaction log is active, a notation is included for any files - that are skipped. - - Notes: - 1. Why is Coordinated Universal Time abbreviated UTC? From the - [292]National Institute of Standards and Technology FAQ: "In 1970 - the Coordinated Universal Time system was devised by an - international advisory group of technical experts within the - International Telecommunication Union (ITU). The ITU felt it was - best to designate a single abbreviation for use in all languages - in order to minimize confusion. Since unanimous agreement could - not be achieved on using either the English word order, CUT, or - the French word order, TUC, the acronym UTC was chosen as a - compromise." - 2. The Kermit FTP client is unusual in that, when downloading only, - it can set the received file's date from the file's date on the - server, but this should not affect the update feature. When - uploading to an FTP server, however, there is no mechanism for the - client to set the date of the uploaded file on the server. - _________________________________________________________________ - - 3.5.3 Recovery - - Suppose that while you are uploading a large file over a slow - connection, the connection is lost before the entire file is - transferred. With most FTP clients, you would have to start over, thus - resending the portion of the file that was sent already, and that is - already on the server. But Kermit's /RECOVER switch (Synonym: - /RESTART) lets you continue an interrupted transfer from the point of - failure, thus transferring only the part that wasn't sent already. The - prerequisites for recovery are: - - * The transfer must be in BINARY mode, or else the client and server - must reside on like systems (e.g. both on some form of UNIX). - * The FTP server must support the SIZE command. - - Here's how it works. When you include the /RECOVER switch: - - * Kermit checks for conflicting switches, such as /UPDATE and - /UNIQUE; if /RECOVER is given with these switches an error occurs. - If /RECOVER is given in other circumstances where it could serve - no useful purpose (e.g. with arrays, pipes, or filters), it is - ignored. - - If the switch is accepted, then for each selected file: - - * If it is not binary (determined by scanning) and the client and - server are not on like platforms, recovery is canceled (the entire - file is sent). Otherwise: - * A SIZE command is sent for the file (using its remote name). If - the reply indicates the file was not found, or the SIZE command - was not understood, or any other kind of error, recovery is - canceled. Otherwise: - * A MDTM (modification time) command is sent for the file. If a - valid reply is received, and the modification time of the local - file is later than that of the remote file, recovery is canceled. - Otherwise: - * If the sizes of the two files are identical, the file is not sent. - Otherwise: - * Kermit seeks to the recovery spot in the local file, tells the - server to APPEND the data which is about to arrive to the remote - file, and then sends the data starting at the recovery point. - - To safeguard file integrity, recovery is not attempted unless all the - preconditions are met. For the widest possible usefulness, APPEND is - used rather than RESTART. For stream transfers (the only kind that - Kermit supports) the results are the same. - - By design, the /RECOVER switch can be included with any FTP PUT or - MPUT command, even if it specifies a group of files. This allows you - to resume an interrupted batch transfer from where it left off. The - files that were already completely sent are skipped, the file that was - interrupted is recovered, and the remaining files are uploaded. - - By the way, it doesn't matter how the original partial file was - uploaded -- FTP, Kermit, Zmodem, etc: as long as the preconditions are - met, it can be recovered with FTP PUT /RECOVER, or for that matter - also using Kermit protocol and SEND /RECOVER. - - A word of caution, however, when the original upload was in text mode - with character-set translation ([293]Section 3.7): - - * If the original upload involved a translation from one single-byte - character set to another (e.g. Code Page 850 to Latin-1), recovery - is safe if you specify the same translations for the recovery. If - you don't, the resulting file will contain a mixture of character - sets. - * If the original upload involved a translation that changed the - size of the file (e.g. from an alphabetic Code Page or Latin - Alphabet to Unicode, or vice versa), recovery is NOT safe, even if - you specify the same translations. - - Kermit has no way of knowing anything about the previous upload. As a - safeguard, an error occurs if you include /RECOVER and also specify a - character-set of UCS2 or UTF8, since recovery can't possibly work in - that situation. Otherwise, it's up to you to avoid unsafe recovery - operations. - - [ [294]Top ] [ [295]FTP Top ] [ [296]C-Kermit Home ] [ [297]Kermit - Home ] - _________________________________________________________________ - - 3.6. Downloading Files With FTP - - Although uploading files with Kermit's FTP client is just as easy and - flexible as sending files with Kermit protocol, the same is not always - true for downloading because FTP servers lack some of the capabilities - of a Kermit server: - - * If you want to get more than one file, you have to use MGET, not - GET, since the underlying FTP protocol is different in the two - cases. Kermit can't "autodetect" which one you mean, as it can - with PUT and MPUT, since it can't be expected to know the wildcard - syntax of the remote platform and/or FTP server (the same is true - for all other FTP clients). To complicate matters, FTP protocol - now includes two underlying mechanisms (NLST and MLSD) for - accomplishing MGET operations and, as explained in [298]Section - 3.11, the two behave differently. - * Automatic text-binary mode switching is not done by the server. It - can be done by the client (Kermit), but in this case it is not - based on a file scan (since there is no way for Kermit prescan a - server file), but rather on the filename, using C-Kermit 7.0 - [299]filename patterns. - * Some options that are available with FTP PUT can not be used with - FTP [M]GET or don't work the same way: - /PERMISSIONS (FTP protocol has no mechanism for this). - /[NOT-]BEFORE, /[NOT-]AFTER (because of the timezone problem). - /RECOVER works only in binary mode. /RECURSIVE has limited - utility. - - The commands for downloading are: - - SET FILE DOWNLOAD-DIRECTORY [ directory ] - As with Kermit transfers, this command, if given, tells - C-Kermit where to store incoming files in the absence of a - specific as-name. If not given, incoming files are stored as - indicated by the as-name, if any, otherwise in the current - directory, just as with Kermit transfers. The more verbose - transfer display formats give the full pathname of each - received file, and, in case you have trouble finding a - downloaded file afterwards, its full path is also listed in the - transaction log (if you kept one), and you can also ask Kermit - where it went with the [300]WHERE command. - - SET FTP GET-FILETYPE-SWITCHING { ON, OFF } - ON by default, causing Kermit to switch automatically into text - or binary mode for each file based on whether its name matches - a text pattern or binary pattern. Set this OFF, or use a /TEXT, - /BINARY, or /TENEX switch to defeat this feature. Use SHOW - PATTERNS to see the current pattern list. - - [ FTP ] GET [ switches ] filename [ as-name ] - Asks the server to send the given file, and if it comes, stores - it locally under the given as-name, if any, otherwise under its - original name (modified according to the selected filename - conversion option), in your download directory, if you have - specified one, otherwise in the directory indicated in the - as-name, if any, otherwise in your current directory. If you - accidentally use a wildcard in the filename ("get *.txt") the - server will reply with a message like "File not found" (unless - there is a file whose name actually is "*.txt"). If FTP - GET-FILETYPE-SWITCHING is ON, and in the absence of any GET - switches to override it, the file is transferred in binary mode - if it matches any of Kermit's binary name patterns, and in text - mode if it matches any of Kermit's text name patterns, and in - the prevailing FTP TYPE if it matches none of these patterns. - - [ FTP ] MGET [ switches ] filespec [ filespec [ filespec [ ... ] ] ] - Like GET, but for multiple files. One or more file - specifications can be given, and any or all (or none) of them - can contain wildcards or can be directory names. The file list - may not include an as-name, but you can still give one with the - /AS-NAME: switch. - - In both the FTP GET and MGET commands, any filenames that contain - spaces must be enclosed in braces or doublequotes (see [301]Section 5 - for details). - - FTP downloads may be interrupted just like Kermit transfers. While the - transfer is in progress, type: - - * X to interrupt the current file and go on to the next file. - * Z (or Control-C) to cancel the current file and all remaining - files. - - Before proceeding, a brief word about temporary files. In FTP - protocol, the MGET command works by requesting a file list from the - server, and then (internally) issuing a GET command (FTP RETR protocol - directive) for each file. The file list returned by the server can be - any size at all, so in case it is huge, we don't store it in memory; - instead we put it in a temporary file. For troubleshooting purposes, - you should be aware of two points: - - 1. The location of the temporary file is chosen according the TMP or - TEMP environment variables. If neither of these variables is - defined, you might need to define it. In case there is not enough - space on the indicated disk or partition for the server's file - list, you might need to either clean up the temporary area, or - redefine the environment variable to indicate a different area - that has sufficient space. - 2. If you want to look at the list yourself, use SET FTP DEBUG ON. - This tells Kermit to (a) give you the full pathname of the - temporary file at the end of each MGET command, and (b) not to - delete it, as it normally does. - _________________________________________________________________ - - 3.6.1. FTP GET Switches - - The following switches are available with FTP GET and MGET: - - /TEXT - Specifies a text-mode transfer. Overrides the global FTP TYPE - setting and filename pattern-matching for the duration of the - current command only, All files are downloaded in text mode. - Synonym: /ASCII. - - /BINARY - Specifies a binary-mode transfer. Overrides the global FTP TYPE - setting and filename pattern-matching for the duration of the - current command only. All files are downloaded in binary mode. - - /TENEX - Like /BINARY but specifies a special binary transfer mode to be - used when getting 8-bit binary files from a 36-bit platform - such as TOPS-10, TOPS-20, or TENEX. All files are downloaded in - the special binary mode. - - /RECOVER - This instructs Kermit to try to recover an incomplete download - from the point of failure. Works only in binary mode, and only - if the server supports the (not-yet-standard) FTP "REST" - directive. See [302]Section 3.6.3 for details. Synonym: - /RESTART. - - /FILENAMES:{CONVERTED,LITERAL} - Overrides the [303]FTP FILENAMES (filename conversion) setting - for this download only, forcing incoming filenames to be either - converted or taken literally. - - /AS-NAME:text - For GET, this is equivalent to giving an as-name after the - filename. For MGET, this is the only way to specify alternative - names for the incoming files. With MGET, the /AS-NAME text - should (must) contain a Kermit variable, usually \v(filename) - or \v(filenumber). Example: - - mget /text /as-name:\v(filename).new *.c - - This gets all ".c" files and stores them with " - - .new" appended to their names. See the [304]C-Kermit 7.0 Update - Notes for details. - - /COMMAND - This specifies that the incoming file is to be written to the - standard input of a command, rather than to a file. The command - name is the as-name from the GET command or the /AS-NAME - argument. If you need to refer to the incoming file's name in - the command, use \v(filename). See the description of the - regular Kermit [305]GET /COMMAND command for details and - examples. - - /QUIET - Transfers the files quietly; don't put up a file-transfer - display. - - /ERROR-ACTION:{QUIT,PROCEED} - This switch affects only MGET. If an error occurs with a - particular file, this tells whether to go on to the next file - (PROCEED) or to stop right away and fail (QUIT). The default is - PROCEED. - - The file selection switches are: - - /EXCEPT:{pattern} or /EXCEPT:{{pattern}{pattern}{...}} - Exception list for MGET; skip downloading any file whose name - matches any of the given patterns (when using the second - format, up to 64 patterns may be specified). [306]CLICK HERE - for syntax details. - - /SMALLER-THAN:number - Download only files whose size is smaller than the given number - of bytes (octets). Requires that the FTP server support the - SIZE or MLSD directive. - - /LARGER-THAN:number - Download only files whose size is greater than the given number - of bytes. Requires that the FTP server support the SIZE or MLSD - directive. - - /NOBACKUPFILES - During MGET, don't download any files whose names end with - backup suffixes (.~n~ where n is a number). - - /NODOTFILES - During MGET, don't download any files whose names begin with - period (.). Equivalent to /EXCEPT:{.*}. - - /LISTFILE:local-filename - The given file contains a list of files to GET, one per line. - Filenames in the listfile can contain wildcard characters in - the syntax of the server. There is no limit on the number of - lines in the listfile. - - /NAMELIST:local-filename - If this switch is given, then instead of actually retrieving - the selected files, the GET command retrieves a list of the - names of the files that would be retrieved, and places it in - the specifed file. The resulting file is an ordinary text file, - with one filename per line, suitable for reading by a person, - or processing by a computer program, including Kermit itself - (FOPEN / FREAD / FWRITE / FCLOSE), and as /FILELIST: file. If - the filename is omitted or given as "-" (dash, hyphen), the - list goes to the screen. NOTE: if you want a copy of the - complete list sent by the server, use SET FTP DEBUG ON, perform - an MGET, and the temporary file containing the list will be - kept rather than deleted (and Kermit tells you its name). - - /UPDATE, /COLLISION:keyword - Explained in [307]Section 3.6.2. - - /RECURSIVE - This means to try to download an entire directory tree, rather - than just files from a particular directory. In fact, FTP - protocol does not provide a method to request a recursive - download (unless the server supports MLSD; see [308]Section - 3.11), so this works only if the FTP server does it anyway, - without being asked, as some do. In this case, Kermit detects - that names in the returned file list contain directory - separators, and therefore attempts to create the needed - directories as the files arrive. But this can work only if the - server is on the same kind of platform as the client, so the - pathname syntax can be recognized, and also because the server - does not switch between text and binary mode, which would be - vital for cross-platform transfers. Use with caution. Synonym: - /SUBDIRECTORIES. - - Even when the server does not provide recursive file lists, - [M]GET /RECURSIVE forces Kermit to replicate any directory - structure implied or expressed by the server's file list. For - example: - - get somepath/somefile - - Gets the file named somefile from the server's somepath - directory and puts it Kermit's current (or download) directory, - whereas: - - get /recursive somepath/somefile - - creates the path locally and then puts the file in it. - Similarly for MGET: - - mget */data/* - - downloads all the files in all the data subdirectories of all - the subdirectories of the server's current directory and stores - them locally in Kermit's current (or download) directory, - whereas: - - mget /recursive */data/* - - re-creates the server's directory structure locally. - - The FTP protocol does not include explicit mechanisms for recursion, - so Kermit builds upon what is available. Although an Internet draft - describes a mechanism ("MLSD") that would allow protocol-driven - recursion, similar to Kermit's File Attribute packets (circa 1984), it - has not yet attained RFC or standard status, and servers are not yet - widely available that offer this feature. In the meantime, the - effectiveness of MGET /RECURSIVE depends on the FTP server - implementation. If the server returns a recursive list in response to - the standard NLST command (whose behavior is ill-defined), Kermit's - FTP MGET /RECURSIVE command uses it to re-create the remote directory - tree locally. If the server supports MLSD, C-Kermit 8.0.206 and Kermit - 95 2.1 and later are able to sense it automatically and use it, as - described below in [309]Section 3.11. - - The /BEFORE:, /AFTER:, /NOT-BEFORE:, and /NOT-AFTER: switches are not - available for downloading because of the confusion with timezones. - Would the given times be in the local timezone, the server's timezone, - or GMT? The FTP server's directory listings show its own local times - but since we don't know what timezone the server is in, there's no way - to reconcile our local times with the server's. Similarly, - /PERMISSIONS can't be preserved in downloads because FTP protocol - provides no means of querying the server for a file's permission. - - Source-file disposition switches: - - /DELETE - Each file that is downloaded successfully is to be deleted from - the server. Requires the appropriate file access rights on the - server. - - /SERVER-RENAME-TO:template - Asks the server to rename each (remote) source file immediately - after, and only if, it is sent correctly. See [310]PUT - /SERVER-RENAME-TO: for details. - - Destination-file disposition switches: - - /TO-SCREEN - Displays the incoming file on the screen rather than storing it - on disk. If this switch is given, the /RENAME-TO and /MOVE-TO - switches are ignored, the file-transfer display is suppressed, - and the given file(s) is/are shown on the screen. Can be used - with /FILTER, e.g. - - get /text /to-screen /filter:more oofa.txt - - In fact, you should always use /TO-SCREEN with /FILTER or - /COMMAND when the command would result in displaying the - incoming file on the screen; otherwise C-Kermit would have no - way of knowing to suppress its file transfer display (since it - can't be expected to know what the command or filter does). - - /RENAME-TO:template - Each file that is downloaded is to be renamed as indicated if - and only if it was received completely and without error. The - template can be literal text or can contain variables that are - evaluated for each file. For MGET, the text must contain - variables; for GET it can be a literal string. The \v(filename) - variable contains the name of the current file, so: - - ftp mget /rename-to:\v(filename).ok * - - causes each file that is successfully downloaded to have ".ok" - appended to its name. For details see [311]Section 4.1 of the - [312]C-Kermit 7.0 Update Notes. - - /MOVE-TO:text - Just like /RENAME-TO:, except the text denotes the name of a - directory to which successfully downloaded files are to be - moved. If the directory does not exist, it is created. - - The file transfer display does not show the /MOVE-TO or /RENAME-TO - value, since the incoming file has not yet been moved or renamed. - _________________________________________________________________ - - 3.6.2. Filename Collisions - - What should happen if an incoming file has the same name as an - existing file in the same directory? By default, Kermit's FILE - COLLISION setting applies: BACKUP, RENAME, UPDATE, DISCARD, etc, as - described in [313]Using C-Kermit. Kermit's default FILE COLLISION - setting is BACKUP (rename the existing file and store the incoming - file under its own name) and therefore this is also the default FTP - collision action. - - The name under which an incoming file is to be stored is determined as - follows: - - * If an as-name was given, the as-name is used. Otherwise: - * If the client and server platforms are alike or [314]FTP FILENAMES - is set to LITERAL (or the /FILENAMES:LITERAL switch was given for - this download), the incoming filename is used literally. - Otherwise: - * The incoming filename is converted to a form that is friendly to - the local platform. For UNIX, for example, incoming filenames that - are all uppercase (as they might be from, say, VMS or an IBM - mainframe) are converted to lowercase. - - If the resulting name coincides with the name of a local file that - already exists, we have a filename collision. Collisions are handled - according to the currently selected collision action: - - SET FTP COLLISION { BACKUP, RENAME, UPDATE, DISCARD, APPEND, OVERWRITE - } - This establishes a filename collision for FTP, separate from - the Kermit one. The initial FTP collision setting is inherited - from Kermit's FILE COLLISION setting when the first FTP command - is given, but subsequent changes to Kermit's FILE COLLISION - setting do not affect the FTP COLLISION setting. SHOW FTP tells - the current FTP COLLISION setting. - - FTP GET /COLLISION:{BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE} - Overrides the current FTP COLLISION action for this download - only. - - FTP GET /UPDATE - This is equivalent to GET /COLLISION:UPDATE, and is included - for symmetry with PUT /UPDATE - - FTP GET /UPDATE and /COLLISION:UPDATE mean to download only those - files whose modification dates on the server are later than those on - the client. Date-time comparisons are done in Coordinated Universal - Time (UTC, GMT, ZULU). The command: - - FTP MGET /COLLISION:APPEND /AS-NAME:newfilename *.* - - Downloads all matching remote files into a single local file (in - whatever order the server sends them). - _________________________________________________________________ - - 3.6.3. Recovery - - Recovery is available for downloads too, but there are some - differences from the uploading case described in [315]Section 3.5.3: - - * The transfer must be in BINARY mode. It can not be in text mode, - even if the FTP server is on the same kind of platform as Kermit, - and even if there is no character-set translation. The original - download must also have been in binary mode. - * The FTP server must support the REST ("restart") directive. - Unfortunately, this is not a standard command; at this writing, it - is described only in an Internet Draft, not an RFC or Internet - Standard, but nevertheless it is found in several popular FTP - servers, such as [316]ProFTPD. - - Here's how download recovery works: - - * Kermit checks for conflicting switches, such as /UPDATE, /COMMAND, - or /FILTER. If /RECOVER is given with these switches an error - occurs. - * The prevailing transfer mode (SET FTP TYPE) must be BINARY. If it - is not, the /BINARY switch must have been included with the FTP - [M]GET command. - - If the /RECOVER switch is accepted, then for each selected file: - - * A SIZE command is sent for the file (using its remote name). If - the reply indicates the file was not found, or the SIZE command - was not understood, or any other kind of error, recovery is - canceled (i.e. the entire file is downloaded). - * If the sizes of the two files are identical, the file is not sent. - Otherwise: - * Kermit sends the REST directive to the server, indicating the size - of the local file. If the server responds affirmatively, Kermit - opens the local file in append mode and appends the incoming data - to it. Otherwise, recovery is canceled and the entire file is - downloaded. - - The /RECOVER switch can be included with any FTP GET or MGET command, - even if it specifies a group of files. This lets you resume an - interrupted batch transfer from where it left off. The files that were - already completely sent are skipped, the file that was interrupted is - recovered, and the remaining files are uploaded. BUT... unlike with - uploading, where this can be done with any mixture of text and binary - files, when downloading, it can only be done if all the files are - binary. - - It doesn't matter how the original partial file was downloaded -- FTP, - Kermit, HTTP, Zmodem, etc: as long as the preconditions are met, it - can be recovered with FTP [M]GET /RECOVER, or for that matter also - with GET /RECOVER (using Kermit protocol). - - [ [317]Top ] [ [318]FTP Top ] [ [319]C-Kermit Home ] [ [320]Kermit - Home ] - _________________________________________________________________ - - 3.7. Translating Character Sets - - A possibly unique feature of Kermit's FTP client is its ability to - convert character sets when transferring files in text mode, - independent of the capabilites of the FTP server, as well as to - translate the character sets of filenames regardless of transfer mode. - For compatibility with existing FTP clients, and because there is a - certain performance penalty, Kermit won't do this unless you ask for - it. If you enable this feature, you need to inform Kermit of the - character set (to be) used on the server and in some cases (explained - below) also the local file character set. This discussion assumes you - know a bit about character sets (as you must if you have to use them); - see Chapter 16 of [321]Using C-Kermit for a detailed treatment. The - Kermit commands for FTP character-set conversion are: - - SET FTP CHARACTER-SET-TRANSLATION { ON, OFF } - Whether to translate character sets when transferring text - files with FTP. OFF by default. Set this to ON to enable - character-set translation for subsequent FTP uploads and - downloads. - - SET FTP SERVER-CHARACTER-SET [322]name - Text character set (to be) used by the server. Most FTP servers - are ignorant of character sets, so all translations are done - unilaterally by Kermit's FTP client. This means that when - downloading files, you must know in advance the character-set - used in the files you are downloading (and in their names). - When uploading, you must specify the character-set to which - local filenames and text-file contents are to be translated for - transmission to the server. If you SET FTP - CHARACTER-SET-TRANSLATION ON but do not specify an FTP - SERVER-CHARACTER-SET, [323]UTF8 is used, since this is the new - Internet standard international character set; it is upwards - compatible with ASCII and it encompasses most written languages - and therefore does not favor any particular group of people, as - any other default would do. If you SET FTP SERVER-CHARACTER-SET - to something (anything) when FTP CHARACTER-SET TRANSLATION is - OFF, this also sets the latter ON. - - SET FILE CHARACTER-SET [324]name - This is the regular Kermit (non-FTP-specific) command for - identifying the character set (to be) used in local text files - and filenames. - - TO REITERATE: If you SET FTP CHARACTER-SET TRANSLATION ON but do not - specify an FTP SERVER-CHARACTER-SET, outbound text files are converted - to UTF-8 and inbound text files are assumed to be UTF-8. If this is - not appropriate, be sure to also specify the desired FTP - SERVER-CHARACTER-SET. - - You can use "special" (non-ASCII) characters in filenames in all the - client / server file management commands (FTP MKDIR, RMDIR, DIRECTORY, - VDIRECTORY, DELETE, etc), and also in file-transfer commands. When - giving commands such as FTP DIR (RDIR) and FTP PWD (RPWD), the reply - is translated too, so you can read it. In this example, the client and - server use entirely different codes to represent the special - characters of German: - - C-Kermit> ftp xyzcorp.de /anonymous - C-Kermit> set ftp server-character-set latin1 - C-Kermit> set file character-set german - C-Kermit> rcd Städte - C-Kermit> rpwd - "/pub/ftp/Städte is current directory" - C-Kermit> rdir - -rw-rw---- 1 olaf 54018 Jan 6 17:58 Adenbüttel.txt - -rw-rw---- 1 ursula 373 Jan 5 15:19 Aßlar.txt - -rw-rw---- 1 gisbert 482 Jan 5 15:20 Blowatz.txt - -rw-rw---- 1 gudrun 124 Jan 5 15:19 Böblingen.txt - -rw-rw---- 1 olga 14348 Jan 7 14:23 Köln.txt - - When the client and server file systems use different character sets, - you should take care to use only those characters that the two sets - share in common when creating filenames or text-file contents. For - example, PC code pages contain a lot line- and box-drawing characters, - and sometimes "smart quotes", etc, that are not found in ISO standard - 8-bit character sets. You should be especially careful to avoid using - such characters in filenames. - - [ [325]C-Kermit Character Sets ] - _________________________________________________________________ - - 3.7.1. Character Sets and Uploading - - Kermit's PUT and MPUT commands include full file-scanning - capabilities, as described in [326]Section 4. Thus if FTP - CHARACTER-SET-TRANSLATION is ON and your character-set associations - are set up appropriately, Kermit automatically switches on a per-file - basis between text and binary mode, and for each text file between - your chosen 7-bit text character set (e.g. ASCII or ISO 646 German), - 8-bit text (e.g. Latin-1 or Japanese EUC), UCS-2, and UTF-8, and - converts each of these automatically to the server character-set, and - furthermore automatically differentiates between the Little and Big - Endian forms of UCS-2, always sending in Big Endian form. - - WARNING: It is not advisable to use UCS-2 (or any Unicode - transformation other than UTF-8) "on the wire", i.e. as a server - character set. Most FTP servers are not able to cope with it, since - it contains lots of 0 (NUL) characters. If you do use it, Kermit - does not translate filenames to or from UCS-2, for reasons well - known to C programmers (for example, UNIX APIs assume filename - strings are NUL-terminated). [327]UTF-8 is the preferred (and - standard) Unicode format for the Internet. - - FTP character-set translations differ from the regular Kermit ones by - not restricting translations to a file-character-set / - transfer-character-set pair. You can have Kermit's FTP client - translate between any pair of character sets it knows about. You can - see the list of supported character sets by typing either of the - following: - - set ftp server-character-set ? - set file character-set ? - - A typical list looks like this ([328]CLICK HERE for an explanation of - the names): - - C-Kermit>set file char ? One of the following: - ascii cp869-greek hebrew-7 mazovia-pc - british cyrillic-iso hebrew-iso next-multinational - bulgaria-pc danish hp-roman8 norwegian - canadian-french dec-kanji hungarian portuguese - cp1250 dec-multinational iso2022jp-kanji shift-jis-kanji - cp1251-cyrillic dg-international italian short-koi - cp1252 dutch jis7-kanji spanish - cp437 elot927-greek koi8 swedish - cp850 elot928-greek koi8r swiss - cp852 euc-jp koi8u ucs2 - cp855-cyrillic finnish latin1-iso utf8 - cp858 french latin2-iso - cp862-hebrew german latin9-iso - cp866-cyrillic greek-iso macintosh-latin - C-Kermit> - - Thus you can translate not only between private sets (like PC code - pages) and standard ones (like Latin-1) as in Kermit protocol, but - also between any given pair of private sets (e.g. CP852 and Mazovia). - All conversions go through Unicode as the intermediate character set, - resulting in a minimum of character loss, since Unicode is a superset - of all other character sets known to Kermit. - - In addition to the SET commands listed above, the FTP PUT and MPUT - commands include switches that apply only to the current command: - - /LOCAL-CHARACTER-SET:name - /SERVER-CHARACTER-SET:name - Use these switches to force a particular translation. These - switches override the global FTP CHARACTER-SET-TRANSLATION and - SERVER-CHARACTER-SET settings and also character-set - differentiation by file scanning for the duration of the PUT or - MPUT command. The file scan is still performed, however, to - determine whether the file is text or binary; thus these - switches do not affect binary files unless you also include the - /TEXT switch to force all files to be treated as text. - - In other words, if you include one or both of these switches with a - PUT or MPUT command, they are used. Similarly, the /TRANSPARENT switch - disables character-set translation for the PUT or MPUT command despite - the prevailing FTP CHARACTER-SET-TRANSLATION and SERVER-CHARACTER-SET - settings. - - When uploading, the FILE CHARACTER-SET setting is ignored unless you - have forced Kermit not to [329]scan local files by including a /TEXT - or /BINARY switch with your [M]PUT command, or by disabling automatic - text/binary switching in some other way. - - Examples: - - 1. Suppose you have a CP852 (East European) text file that you want - to upload and store in ISO Latin Alphabet 2 encoding: - ftp put /local-char:cp852 /server-char:latin2 magyar.txt - 2. Suppose you always want your text files converted to Latin-2 when - uploading with FTP. Then put: - set ftp server-character-set latin2 - in your Kermit customization file, and then you can omit the - /SERVER-CHARACTER-SET: switch from your FTP PUT commands: - ftp put /local-char:cp852 magyar.txt - 3. Now suppose that all the text files on your PC are written in - Hungarian, but they have a variety of encodings, and you don't - want to have to include the /LOCAL-CHARACTER-SET: switch on every - FTP PUT command, or (more to the point) you want to be able to - send a mixture of these files all at once. Put these commands in - your Kermit customization file: - set ftp server-character-set latin2 ; ISO 8859-2 - set file default 7-bit-character-set hungarian ; ISO 646 Hungarian - set file default 8-bit-character-set cp852 ; PC East European Code Page - and now PUT and MPUT will automatically detect and switch among - ISO 646 Hungarian, Code Page 852, UTF-8, and UCS-2 encodings, - translating each one to Latin-2 for uploading: - ftp put *.txt - - And since binary files are also detected automatically, the latter can - be simplified to: - - ftp put * - - even when "*" matches a diverse collection of binary and text files, - because translations are skipped automatically for binary files. - _________________________________________________________________ - - 3.7.2. Character Sets and Downloading - - The commands and switches are the same as for uploading, but automatic - character-set switching works differently, since Kermit can't scan the - server files in advance. Instead, the transfer mode (text or binary) - is based on the filenames; each name is compared with Kermit's list of - text name patterns and binary name patterns. If the name matches a - binary pattern (for example, if the filename is oofa.tar.gz and one of - the filename patterns is "*.gz"), the file is downloaded in binary - mode; otherwise if it matches a text pattern (e.g. oofa.txt matches - "*.txt"), it is transferred in text ("ascii") mode. Otherwise, it is - transferred in the prevailing FTP TYPE. - - In C-Kermit 8.0, the pattern lists used with FTP GET are not the same - lists used with Kermit transfers, and can not be viewed with SHOW - PATTERNS, nor adjusted with ADD and REMOVE TEXT-PATTERNS and - BINARY-PATTERNS, or SET FILE TEXT-PATTERNS and BINARY-PATTERNS. - Configuration of the FTP patterns list will be added in a future - release. - - Examples: - - get /server-char:latin1 /local-char:cp850 Grüße.txt - In this command, the filename contains special characters, - which you enter using whatever character set your local - computer uses, in this case PC Code Page 850 (cp850). The - command tells Kermit (in case it didn't know already from its - FILE CHARACTER-SET setting) that the local character set is - cp850 and the server's character-set is ISO 8859-1 Latin - Alphabet 1 (latin1). Kermit translates the filename from cp850 - to latin1 and sends the latin1 name to the server. Since it's a - text file (matches "*.txt"), its contents are translated to - cp850 on arrival, and it is saved with a cp850 name. - - mget /text /server:latin1 /local:utf8 *.txt - This command: - - + Tells C-Kermit that the server's files are encoded in ISO - 8859-1 Latin Alphabet 1. - + Tells C-Kermit to translate the incoming files into Unicode - UTF-8 for storage. - + Asks the server to send all ".txt" files in text mode. - - mget /server:latin1 /local:utf8 * - Tells Kermit to get all files from the server's directory, - switching between text and binary mode based on the filename. - The names of all the files are translated (to UTF-8 in this - case), but contents are translated (also to UTF-8) only for - text files. - - Note that any pair of 8-bit character sets is likely to have some - incompatibilities. Any characters in the source file that do not have - equivalents in the destination file's character set are converted to - question marks. This applies to both filenames and to text file - contents. - - Also note that the server's ability to accept special characters in - filenames depends on the particular server. For example: - - get Grüße.txt - - works with WU-FTPD, but: - - mget Grüß*.txt - - does not. - _________________________________________________________________ - - 3.7.3. RFC2640 - - [330]RFC2640, July 1999, specifies a method by which the FTP client - and server can negotiate the use of UTF8. However, RFC2640-capable - servers are rare to nonexistent at this writing, and in any case you - don't need them to be able to transfer text in UTF8. C-Kermit lets you - upload and download text files in any character set it knows about, - converting to or from any other character set it knows about, without - the knowledge, permission, or cooperation of the server, and - regardless of its capabilities. - - [ [331]Top ] [ [332]FTP Top ] [ [333]C-Kermit Home ] [ [334]Kermit - Home ] - _________________________________________________________________ - - 3.8. FTP Command Shortcuts - - C-Kermit's FTP client coexists with other C-Kermit functions by - requiring the "ftp" prefix for each FTP-related command: FTP OPEN, FTP - GET, FTP BYE, and so on. For interactive use, however, this can be - rather awkward and sometimes surprising, for example when a GET - command starts a Kermit GET rather than an FTP GET. In fact, many - Kermit commands might just as easily apply to an FTP connection: GET, - PUT (SEND), BYE, and CLOSE. The following command lets you choose how - these commands are interpreted: - - SET GET-PUT-REMOTE { AUTO, KERMIT, FTP } - Controls the orientation of GET, PUT, REMOTE and other - file-transfer and client/server commands that might apply to - either Kermit or FTP. The default setting is AUTO, meaning that - these commands apply to FTP if an FTP connection is open, and - to Kermit otherwise. KERMIT means they always apply to Kermit, - FTP means they always apply to FTP. - - Here is a complete list of affected commands: - - Kermit Command FTP Equivalent - (none) FTP [ OPEN ] - LOGIN FTP USER - LOGOUT FTP RESET - BYE FTP BYE - FINISH FTP BYE - CLOSE FTP BYE - HANGUP FTP BYE - BINARY FTP TYPE BINARY - TEXT (or ASCII) FTP TYPE ASCII - SEND (or PUT) FTP PUT - MSEND (or MPUT) FTP MPUT - RESEND FTP PUT /RECOVER - CSEND FTP PUT /COMMAND - GET FTP GET - MGET FTP MGET - REGET FTP GET /RECOVER - REMOTE HELP (RHELP) FTP HELP - REMOTE CD (RCD) FTP CD (CWD) - REMOTE PWD (RPWD) FTP PWD - REMOTE DIRECTORY (RDIR) FTP DIRECTORY - REMOTE DELETE (RDEL) FTP DELETE - REMOTE MKDIR (RMKDIR) FTP MKDIR - REMOTE RMDIR (RRMDIR) FTP RMDIR - REMOTE RENAME (RRENAME) FTP RENAME - REMOTE TYPE (RTYPE) FTP TYPE - REMOTE EXIT (REXIT) FTP BYE - - The commands in the right-hand column always access FTP. The commands - in the left column can access either Kermit protocol or FTP: - - * When GET-PUT-REMOTE is set to KERMIT, or to AUTO when there is no - FTP connection, the commands in the left-hand column access Kermit - protocol, and those right-hand column are required for FTP. - * When GET-PUT-REMOTE is set to FTP, or to AUTO when there is an - active FTP connection, the commands in the left-hand column access - the FTP connection and can not be used to access Kermit protocol. - In this case, if you want to be able to use both Kermit protocol - and the FTP connection, you must SET GET-PUT-REMOTE KERMIT, and - then use the FTP commands in the right-hand column to access the - FTP connection. - - Note that file-management commands such as DIRECTORY, DELETE, CD, PWD, - MKDIR, RMDIR, HELP, RENAME, COPY, TYPE, and so on, always apply - locally, no matter what kind of connection you have. This is the - opposite of most FTP clients, where these commands are intended for - the server, and require an "L" prefix for local execution (e.g. "dir" - gets a directory listing from the server, "ldir" gets a local - directory listing). To illustrate with the CD command and a typical - UNIX FTP client: - - Client Server Change Local Directory Change Remote Directory - FTP FTP lcd cd (cwd) - Kermit Kermit cd rcd, remote cd - Kermit FTP cd ftp cd, rcd, remote cd - - Also note that not all REMOTE commands are useful with FTP, since FTP - servers do not offer the corresponding functions. These include: - - * REMOTE ASSIGN - FTP servers don't have variables - * REMOTE COPY - FTP servers don't copy files - * REMOTE HOST - FTP servers don't execute host (shell) commands - * REMOTE KERMIT - FTP servers don't execute Kermit commands - * REMOTE PRINT - FTP servers don't print files - * REMOTE QUERY - FTP servers don't have variables - * REMOTE SET - FTP servers don't have Kermit settings - * REMOTE WHO - FTP servers don't send user lists - - Finally note that command shortcuts do not apply to the HELP command. - For help about an FTP command, use (for example) "help ftp delete", - not "help delete" or "help rdelete". - - [ [335]Top ] [ [336]FTP Top ] [ [337]C-Kermit Home ] [ [338]Kermit - Home ] - _________________________________________________________________ - - 3.9. Dual Sessions - - You can have an FTP session open at the same time as a regular Kermit - SET LINE or SET HOST (terminal) session. In this case, the default SET - GET-PUT-REMOTE AUTO setting should ensure that all "two-faced" - commands like GET, PUT, REMOTE, HANGUP, BYE, etc, apply to the Kermit - session, and all commands for the FTP session must include the FTP - prefix. To be absolutely certain, you can use SET GET-PUT-REMOTE - KERMIT. - - ftp foo.bar.baz.com - if fail ... - (log in) - set host foo.bar.baz.com - if fail ... - (log in) - - Now you have both an FTP and Telnet connection to the same host (of - course they could also be to different hosts, and you could also have - a direct or dialed serial connection instead of a Telnet connection). - Now assuming you have a Kermit server on the far end of the Kermit - connection: - - rcd incoming ; Changes Kermit server's directory (= REMOTE CD) - ftp cd incoming ; Changes FTP server's directory - put oofa.txt ; Sends a file on the Kermit connection - ftp put oofa.txt ; Sends a file on the FTP connection - bye ; Shuts down the Kermit connection - ftp bye ; Shuts down the FTP connection - - Note that PUT and SEND are synonyms for both FTP and Kermit - connections. - - You can also establish dual sessions on the Kermit command line: - - kermit -j host1 -9 host2 - - This makes a Telnet connection to host1 and an FTP connection to - host2. - - [ [339]Top ] [ [340]FTP Top ] [ [341]C-Kermit Home ] [ [342]Kermit - Home ] - _________________________________________________________________ - - 3.10. Automating FTP Sessions - - Most of Kermit's scripting features can be used to make and control - FTP sessions: FOR and WHILE loops, IF-ELSE and SWITCH constructions, - variables, arrays, built-in functions, and all the rest. You can't use - INPUT, MINPUT, OUTPUT, CLEAR, or SCRIPT on an FTP session, but these - are not needed since the FTP protocol is well defined. - - [343]CLICK HERE for an FTP scripting tutorial. - - 3.10.1. FTP-Specific Variables and Functions - - The following variable tells whether an FTP connection is open: - - \v(ftp_connected) - 1 if there is an active FTP connection, 0 if there isn't. - - The FTP OPEN command sets: - - \v(ftp_host) - The host to which the most recent FTP connection was made. - - \v(ftp_security) - The security method negotiated for the current FTP session. The - value is "NULL" when no security is used. See [344]3.2. Making - Secure FTP Connections. - - \v(ftp_server) - The OS type (UNIX, VMS, etc) of the FTP server host. - - The FTP USER command (or FTP OPEN /USER:, or FTP with automatic login) - sets: - - \v(ftp_loggedin) - 1 if you are logged in to an FTP server, 0 if you are not. - - The current COMMAND-PROTECTION-LEVEL and DATA-PROTECTION-LEVEL values - are reflected in: - - \v(ftp_cpl) - \v(ftp_dpl) - The values are "clear", "confidential", "safe" or "private". - See [345]3.2. Making Secure FTP Connections. - - The FTP GET-PUT-REMOTE setting is reflected in: - - \v(ftp_getputremote) - The values are "auto", "ftp", or "kermit". - - Every FTP command sets the \v(success) variable, as well as the - following two FTP-specific variables: - - \v(ftp_code) - The standardized numeric FTP protocol code from the server's - response to the last client command, a 3-digit decimal number - defined in [346]RFC959. Briefly: - - 1xx = Positive Preliminary Reply - 2xx = Positive Completion Reply - 3xx = Positive Intermediate Reply - 4xx = Transient Negative Completion Reply - 5xx = Permanent Negative Completion Reply - - \v(ftp_message) - The text message, if any, from the server's response to the - last client command. If the most recent response had multiple - lines, this variable has only the final line. These messages - are not standardized and vary in format and content from server - to server. Synonym: \v(ftp_msg). - - FTP file transfers set the regular Kermit transfer status variables: - - \v(cps) Characters per second of most recent transfer. - \v(filespec) File specification used in most recent transfer. - \v(fsize) Size of file most recently transferred. - \v(tfsize) Total size of file group most recently transferred. - \v(xferstatus) Status of most recent transfer (0 = success, 1 = failure). - \v(tftime) Elapsed time of most recent transfer, in seconds. - - During an FTP transfer, the per-file variables are: - - \v(filename) Name of current file. - \v(filenumber) Ordinal file number in group (1, 2, 3, ...) - _________________________________________________________________ - - 3.10.2. Examples - - Let's begin with a simple example showing how to log in, send some - files, and log out: - - define error if fail { ftp bye, stop 1 Error: \%1 } - set transact brief - log t - ftp ftp.xyzcorp.com /anonymous - if fail stop 1 Connection failed - if not \v(ftp_loggedin) stop 1 Login failed - ftp cd incoming - error {ftp cd} - cd upload - error {local cd} - ftp put /delete * - error {put} - ftp bye - - First we define an error handling macro to be used after the - connection is made. Then we set up a brief-format transaction log to - keep a record of our file transfers. Then we make a connection to the - host and log in anonymously. The "if fail" command checks whether the - connection was made. The "if not" command checks whether login was - successful. Obviously the script should not continue unless both tests - succeed. - - Next we change to the server's 'incoming' directory and to our own - 'upload' directory, and send all the files that are in it (they can be - any mixture of text and binary files), deleting each source file - automatically after it is successfully uploaded. Each of these - operations is checked with the ERROR macro, which prevents the script - from continuing past a failure. - - Finally we close the FTP session with the "bye" command. - - Just like any other Kermit script, this one can be used in many ways: - - * It can be stored in a file, and Kermit can be told to TAKE the - file. - * In UNIX, it can be a "[347]kerbang" script and therefore run - directly from the shell prompt or as a cron job. - - We could have used command shortcuts like "rcd", "put", and "bye", but - since they can be ambiguous under certain circumstances, it is better - to avoid them in scripts; they are intended mainly for convenience - during interactive use. However, if you wish to use the shortcuts in a - script, you can do it this way (error handling omitted for brevity): - - local \%t ; Declare a local temporary veriable - assign \%t \v(ftp_getputremote) ; Save current FTP GET-PUT-REMOTE setting - set ftp get-put-remote ftp ; Choose FTP orientation - ftp xyzcorp.com /anonymous ; Open an FTP connection - get oofa.txt ; GET a file - put foo.bar ; PUT a file - rdel yesterday.log ; Delete a file on the server - bye ; Log out and disconnect from server. - set ftp get-put-remote \%t ; Restore previous GET-PUT-REMOTE setting - - Of course, FTP scripts can also be written as macros. This lets you - pass parameters such as hostnames, usernames, and filenames to them: - - define doftpget { - if < \v(argc) 4 end 1 Usage: \%0 host user remotefile [ localfile ] - ftp \%1 /user:\%2 - if fail end 1 FTP OPEN \%1 failed - if not \v(ftp_loggedin) end 1 FTP LOGIN failed - ftp get {\%3} {\%4} - if fail end 1 FTP GET \%3 failed - ftp bye - } - - Add this definition to your Kermit customization file, and it will - always be available when you start Kermit. This macro lets you - download a file with FTP by giving a single command, e.g.: - - doftpget xyzcorp.com anonymous oofa.txt - _________________________________________________________________ - - 3.10.3. Automating Secure FTP Sessions - - Often when making secure connections, you are prompted interactively - for certain information or permission to proceed. These prompts can - stop an automated procedure. To avoid them, you must give the - appropriate commands to disable them, and/or supply the prompted-for - information beforehand. Here are a few hints: - - * Make sure that SET TAKE ERROR and SET MACRO ERROR are both OFF. - This is the default, but in case you have set either one of these - ON in your script or initialization file, this makes the script - halt on any kind of error. Normally you would want to check each - operation for success or failure and take appropriate action. - * On SSL and TLS connections, you may be asked whether it is OK to - proceed with a connection to server that presents a self-signed - certificate. You can use the SET AUTHENTICATION SSL (or TLS) - VERIFY or SET AUTH SSL (or TLS) CERTS-OK commands to avoid this - prompt by not requesting a certificate from the peer. - * (More to be added...) - - [ [348]Top ] [ [349]FTP Top ] [ [350]FTP Script Tutorial ] [ - [351]C-Kermit Home ] [ [352]Kermit Home ] - _________________________________________________________________ - - 3.11. Advanced FTP Protocol Features - - The remainder of the FTP documention (through the end of Section 3) is - new to C-Kermit 8.0.206, but we leave it in black to prevent - headaches. Except for titles. - * [353]TERMINOLOGY - * [354]FEATURE NEGOTIATION - * [355]USING MGET: NLST VERSUS MLSD - * [356]EXAMPLES - * [357]REFERENCES - - The new releases of [358]C-Kermit (8.0.206) and [359]Kermit 95 (2.1) - support new FTP protocol features from RFC 2389 as well as most of - what's in the Elz and Hethmon Extensions to FTP Internet Draft (see - [360]References). Some of these features, such as SIZE (request a - file's size), MDTM (request file's modification time), and REST - (restart interrupted transfer) have been widely implemented in FTP - clients and servers for years (as well as in the initial release of - the Kermit FTP clients). Others such as FEAT and MLSD are rarely seen - and are new to the upcoming Kermit releases. TVFS (Trivial Virtual - File Store) is supported implicitly, and the UTF-8 character-set is - already fully supported at the protocol and data-interchange level. - - For Kermit users, the main benefit of the new FTP protocol extensions - is the ability to do recursive downloads. But the extensions also - introduce complications and tradeoffs that you should be aware of. Of - course Kermit tries to "do the right thing" automatically in every - case for backwards compatibility. But (as noted later) some cases are - inherently ambiguous and/or can result in nasty surprises, and for - those situations new commands and switches are available to give you - precise control over Kermit's behavior, in case the defaults don't - produce the desired results. - _________________________________________________________________ - - 3.11.1. Terminology Command-line FTP clients such as Kermit (as well - as the traditional FTP programs found on Unix, VMS, ..., even Windows) - have commands like PUT, MPUT, GET, MGET, and BYE, which they convert - into zero or more FTP protocol commands, such as NLST, RETR, QUIT. For - clarity, we'll use "command" to refer to commands given by the user to - the FTP client, and "directive" for FTP protocol commands sent by the - FTP client to the FTP server. - _________________________________________________________________ - - 3.11.2. Feature Negotiation New FTP protocol features are negotiated - by the client sending a FEAT directive and the server responding with - a list of (new) features it supports, or else with an error indication - if it does not support the FEAT directive at all, in which case the - client has to guess which new features it supports (Kermit guesses - that it supports SIZE and MDTM but not MLST). Note that the MLST - feature includes MLSD, which is not listed separately as a feature. - - Guessing is nice when it works, but sometimes it doesn't, and some FTP - servers become confused when you send them a directive they don't - understand, or they do something you didn't want, sometimes to the - point of closing the connection. For this reason, Kermit lets you - override default or negotiated features with the following new - commands: - - FTP { ENABLE, DISABLE } FEAT - Enables or disables the automatic sending of a FEAT directive - upon connection to an FTP server. Note that - FTP [ OPEN ] /NOINIT also inhibits sending the FEAT directive - (and several others) for the connection being OPEN'd, but - without necessarily disabling FEAT for subsequent connections - in the same Kermit instance. FEAT is ENABLED by default, in - which case many FTP servers are likely to reply: - -500 'FEAT': command not understood - - which is normally harmless (but you never know). (In C-Kermit - 8.0.208, this error message is suppressed unless you SET FTP - DEBUG ON.) - - FTP ENABLE { MDTM, MLST, SIZE } - Enables the given directive for implicit use by the FTP GET and - MGET commands in case it has been disabled or erroneously - omitted by the server in its FEAT response. Note: MLSD can be - used in the FTP ENABLE and DISABLE commands as a synonym for - MLST. YOU MUST GIVE THIS COMMAND AFTER MAKING THE FTP - CONNECTION. - - FTP DISABLE { MDTM, MLST, SIZE } - Disables implicit use of the given directive by GET or MGET in - case it causes problems; for example, because it makes - multifile downloads take too long or the server announces it - erroneously or misimplements it. Use DISABLE FEAT before making - a connection to prevent Kermit from sending the FEAT directive - as part of its initial sequence. Note that disabling FEAT, - SIZE, or MDTM does not prevent you from executing explicit FTP - FEATURES, FTP SIZE, or FTP MODTIME commands. Also note that - disabling SIZE prevents PUT /RESTART (recovery of interrupted - uploads) from working. YOU MUST GIVE THIS COMMAND AFTER MAKING - THE FTP CONNECTION. - - To enable or disable more than one feature, use multiple FTP ENABLE or - FTP DISABLE commands. The SHOW FTP command shows which features are - currently enabled and disabled. - - FTP FEATURES - This command sends a FEAT directive to the server. In case you - have been disabling and enabling different features, this - resynchronizes Kermit's feature list with the server's. If the - server does not support the FEAT directive, Kermit's feature - list is not changed. - - FTP OPTIONS directive - Informational only: the server tells what options, if any, it - supports for the given directive, e.g. MLST. Fails if the - server does not support the OPTS directive or if the directive - for which options are requested is not valid. The directive is - case-insensitive. - - FTP SIZE filename - Sends a SIZE directive to the server for the given file. The - filename must not contain wildcards. The server responds with - an error if the file can't be found, is not accessible, or the - SIZE directive is not supported, otherwise with the length of - the file in bytes, which Kermit displays and also makes - available to you in its \v(ftp_message) variable. If the - directive is successful, Kermit (re-)enables it for internal - use by the GET and MGET directives on this connection. - - FTP MODTIME filename - Works just like the SIZE directive except it sends an MDTM - directive. Upon success, the server sends modification - date-time string, which Kermit interprets for you and also - makes available in its \v(ftp_message) variable. - - Whenever a SIZE or MDTM directive is sent implicitly and rejected by - the server because it is unknown, Kermit automatically disables it. - _________________________________________________________________ - - 3.11.3. Using MGET: NLST versus MLSD When you give an MGET command to - an FTP client, it sends a request to the FTP server for a list of - files, and then upon successful receipt of the list, goes through it - and issues a RETR (retrieve) directive for each file on the list (or - possibly only for selected files). - - With the new FTP protocol extensions, now there are two ways to get - the list of files: the NLST directive, which has been part of FTP - protocol since the beginning, and the new MLSD directive, which is new - and not yet widely implemented. When NLST is used and you give a - command like "mget *.txt", the FTP client sends: - -NLST *.txt - - and the server sends back a list of the files whose names match, e.g. - -foo.txt -bar.txt -baz.txt - - Then when downloading each file, the client sends SIZE (if it wants - have a percent-done display) and MDTM (if it wants to set the - downloaded file's timestamp to match that of the original), as well as - RETR (to retrieve the file). - - But when MLSD is used, the client is not supposed to send the filename - or wildcard to the server; instead it sends an MLSD directive with no - argument (or the name of a directory), and the server sends back a - list of all the files in the current or given directory; then the - client goes through the list and checks each file to see if it matches - the given pattern, the rationale being that the user knows only the - local conventions for wildcards and not necessarily the server's - conventions. So with NLST the server interprets wildcards; with MLSD - the client does. - - The interpretation of NLST wildcards by the server is not - necessarily required or even envisioned by the FTP protocol - definition (RFC 959), but in practice most clients and servers work - this way. - - The principal advantage of MLSD is that instead of sending back a - simple list of filenames, it sends back a kind of database in which - each entry contains a filename together with information about the - file: type, size, timestamp, and so on; for example: - -size=0;type=dir;perm=el;modify=20020409191530; bin -size=3919312;type=file;perm=r;modify=20000310140400; bar.txt -size=6686176;type=file;perm=r;modify=20001215181000; baz.txt -size=3820092;type=file;perm=r;modify=20000310140300; foo.txt -size=27439;type=file;perm=r;modify=20020923151312; foo.zip -(etc etc...) - - (If the format of the file list were the only difference between NLST - and MLSD, the discussion would be finished: it would always be better - to use MLSD when available, and the MGET user interface would need no - changes. But there's a lot more to MLSD than the file-list format; - read on...) - - The client learns whether the server supports MLSD in FEAT exchange. - But the fact that the server supports MLSD doesn't mean the client - should always use it. It is better to use MLSD: - - * On connections where the server imposes a time penalty for every - command, e.g. the Red Hat Rawhide server. With MLSD, the client - needs to send only one command (RETR) per file, whereas NLST - requires three (SIZE, RETR, and MDTM). Suppose there is a - 30-second delay for each command and 1000 files are to be fetched; - in that case, MLSD saves 60,000 seconds = 1000 minutes = 16 hours - and 40 minutes. - * For recursive downloads since there is no dependable way to - download directory trees with NLST. - - But it is better to use NLST: - - * If you want only a couple short files out of a large directory. In - this case, NLST is the better choice since the server sends a list - of only the files you want, not a list of (say) a million files, - which can make a big difference on slow connections. For example, - suppose your wildcard matches three files of 1K each, but the - million-file listing is 80MB long, and your connection is through - a modem. The overhead of using MLSD is practically infinite. - * If the server supports wildcarding features not known to the - client, but that can be used to achieve desirable effects - otherwise unobtainable, such as "[dir...]*.txt" in VMS or AOS/VS - "except" clauses. - * If you have been given a wildcard string by an FTP site - administrator for fetching a specific group of files out of a - larger directory, e.g. "mget ck[cuw]*.[cwh] makefile", that is - expected to work with any client (an FTP site administrator can't - be expected to know the wildcard syntax of every FTP client). - - But when using MLSD there are complications: - - * MLSD wants either a blank argument (meaning the current directory) - or else the name of a specific directory. The client must not send - it a wildcard or a filename. - * But if the user's command is "mget xxx", how does the client know - whether to send "xxx" in the MLSD directive? It might be the name - of a directory on on the server, in which case it should be sent, - or it might be the name of a file on the server (or a wildcard), - in which case it must not be sent. Since the client knows its own - wildcard syntax, then in most cases it would be right to send - "MLSD" with no argument if xxx is wild, and to send "MLSD xxx" if - it is not. - * But suppose the server's file system allows filename characters - that correspond with the client's wildcard syntax? For example: - "[abc]" could be either a valid VMS directory name or a wildcard - pattern used by the FTP client. What should the client do with - "mget [abc]"? In this case there must be a way for the user to - force sending the MGET argument as the MLSD argument. - * If "xxx" is a regular file in the server's current directory, - "mget xxx" works with NLST but not with MLSD. - - To further complicate matters, NLST can (in theory) work just like - MLSD: if sent with a blank argument or a directory name, it is - supposed to return a complete list of files in the current or given - directory, which the client can match locally against some pattern. It - is not known if any FTP server or client does this but nevertheless, - it should be possible since this behavior can be inferred from RFC - 959. - - In view of these considerations, and given the need to preserve the - traditional FTP client command structure and behavior so the software - will be usable by most people: - - 1. The MGET command should produce the expected result in the common - cases, regardless of whether NLST or MLSD is used underneath. - 2. For anomalous cases, the user needs a way to control whether the - MGET argument is sent to the server or kept for local use. - 3. At the same time, the user might need a way to send a directory - name to the server, independent of any wildcard pattern. - 4. The user needs a way to force NLST or MLSD for a given MGET - command. - - By default, Kermit's MGET command uses MLSD if MLST is reported by the - server in its FEAT list. When MLSD is used, the filespec is sent to - the server if it is not wild (according to Kermit's own definition of - "wild" since it can't possibly know the server's definition). If the - filespec is wild it is held for local use to select files from the - list returned by the server. If MLST is not reported by the server or - is disabled, Kermit sends the MGET filespec with the NLST directive. - - The default behavior can be overridden globally with FTP DISABLE MLST, - which forces Kermit to use NLST to get file lists. And then for - situations in which MLSD is enabled, the following MGET switches can - be used to override the defaults for a specific MGET operation: - - /NLST - Forces the client to send NLST. Example: - -mget /nlst foo.* - - /MLSD - Forces the client to send MLSD (even if MLST is disabled). - Example: - -mget /mlsd foo.* - - /MATCH:pattern - When this switch is given, it forces the client to hold the - pattern for local use against the returned file list. If a - remote filespec is also given (e.g. the "blah" in "mget - /match:*.txt blah"), then it is sent as the NLST or MLSD - argument, presumably to specify the directory whose files are - to be listed. When the /MATCH switch is not given, the MGET - filespec is sent to the server if the directive is NLST or if - the filespec is not wild. Examples: - - Command: With NLST: With MLSD: - mget NLST MLSD - mget *.txt NLST *.txt MLSD - mget foo NLST foo MLSD foo - mget /match:*.txt NLST MLSD - mget /match:*.txt foo NLST foo MLSD foo - - In other words, the pattern is always intepreted locally unless MGET - uses NLST and no /MATCH switch was given. - _________________________________________________________________ - - 3.11.4. Examples - - 3.11.4.1. Downloading a Single File - - There are no choices here, just use the FTP GET command. Kermit always - sends the RETR directive, and possibly SIZE and/or MDTM. The small - advantage of using MLST in this case is outweighed by the risk and - effort of coding a special case. - - 3.11.4.2. Downloading a Group of Files from a Single Directory - - This case presents tradeoffs, especially on slow connections: - - * For downloading all or most of the files in a directory, MLSD is - better because it eliminates the need to send SIZE and MDTM for - each file. No special actions are required in this case; Kermit - uses MLSD automatically if the server supports it (unless you have - disabled it). - * For a small number of files from a large directory, NLST is better - because it bypasses downloading of a potentially huge file list - prior to the files themselves. If you have a connection to a - server that supports MLSD, use the /NLST switch to force NLST: - -mget /nlst t[1234].h - - * If the server supports MLSD but does not support separate SIZE or - MDTM directives, and you need the size and/or timestamp - information, MLSD is better; no special actions required. - * If the server supports MLSD but does not support the "size" and - "modify" facts, but it does support the SIZE or MDTM directives, - and you need the size and/or timestamp information, NLST is - better. - - 3.11.4.3. Downloading a Directory Tree - - MLSD is the only choice for recursive downloads; they rarely, if ever, - work with NLST (the few cases where they do work rely on - extra-protocol "secret" notations for the NLST argument). No special - actions are required to force MLSD when the server supports it, unless - you have disabled it. Examples: - - MGET /RECURSIVE - This tells the server to send all files and directories in the - tree rooted at its current directory. - - MGET /RECURSIVE *.txt - This tells the server to send all *.txt files in the tree - rooted at its current directory. - - MGET /MLSD /RECURSIVE *.txt - Same as the previous example but forces Kermit to send MLSD in - case it was disabled, or in case the server is known to support - it even though it did not announce it in its FEAT listing. - - MGET /RECURSIVE /MATCH:*.zip archives - Tells the server to send all ZIP files in the tree rooted at - its "archives" directory. - - MGET /RECURSIVE /MATCH:* [abc] - The server is running on VMS and you want it to send all the - files in the directory tree rooted at [ABC]. But since "[abc]" - looks just like a wildcard, you have to include a /MATCH: - switch to force Kermit to send "[abc]" as the MLSD argument. - - In all cases in which the /RECURSIVE switch is included, the server's - tree is duplicated locally. - - Although MLSD allows recursion and NLST does not, the MLSD - specification places a heavy burden on the client; the obvious, - straightforward, and elegant implementation (depth-first, the one - that Kermit currently uses) requires as many open temporary files - as the server's directory tree is deep, and therefore client - resource exhaustion -- e.g. exceeding the maximum number of open - files -- is a danger. Unfortunately MLSD was not designed with - recursion in mind. (Breadth-first traversal could be problematic - due to lack of sufficient navigation information.) - - Of course all of Kermit's other MGET switches can be used too, e.g. - for finer-grained file selection (by date, size, etc), for moving or - renaming files as they arrive, to override Kermit's automatic per-file - text/binary mode switching, to pass the incoming files through a - filter, to convert text-file character sets, and so on. - - 3.11.4.4. NLST/MLSD Summary Table - - Here's a table summarizing MGET behavior when the server supports both - NLST and MLSD. /NLST and /MLSD switches are included for clarity to - indicate which protocol is being used, and the expected effects. In - practice you can omit the /NLST and /MLSD switches and the Kermit - client chooses the appropriate or desired protocol as described above. - Sample commands presume a Unix file system on the server, but of - course the server can have any file system or syntax at all. - - User's Command FTP Sends Remarks - mget /nlst NLST Gets a list of all the files in the server's current - and downloads each file. The list includes names only, so Kermit also - must send SIZE and MDTM directives if size and timestamp information - is required (this is always true of NLST). Sending NLST without an - argument is allowed by the RFC959 NLST definition and by the Kermit - FTP client, but might not work with other clients, and also might not - work with every server. - mget /nlst foo NLST foo If "foo" is a directory, this gets a list of - all the files from the server's "foo" directory and downloads each - file; otherwise this downloads the file named "foo" (if any) from the - server's current directory. - mget /nlst *.txt NLST *.txt Gets a list of the files in the server's - current directory whose names match the pattern *.txt, and then - downloads each file from the list. Because we are using NLST, we send - the filespec (*.txt) to the server and the server interprets any - wildcards. - mget /nlst foo/*.txt NLST foo/*.txt Gets a list of the files in the - server's "foo" directory whose names match the pattern *.txt, and then - downloads each file from the list (server interprets wildcards). - mget /nlst /match:*.txt NLST Gets a list of all the files in the - server's current directory and then downloads each one whose name - matches the pattern *.txt (client interprets wildcards). - mget /nlst /match:*.txt foo NLST foo Gets a list of all the files in - the server's "foo" directory and then downloads each one whose name - matches the pattern *.txt (client interprets wildcards). - mget /mlsd MLSD Gets a list of all the files from the server's current - directory and then downloads each one. The list might include size and - timestamp information, in which case Kermit does not need to send SIZE - and MDTM directives for each file (this is always true of MLSD). - mget /mlsd foo MLSD foo Gets a list of all the files from the server's - "foo" directory (where the string "foo" does not contain wildcards) - and then downloads each one. If "foo" is a regular file and not a - directory, this command is supposed to fail, but some servers have - been observed that send the file. - mget /mlsd *.txt MLSD Gets a list of all the files from the server's - current directory and then downloads only the ones whose names match - the pattern "*.txt". Because we are using MLSD and the MGET filespec - is wild, we do not send the filespec to the server, but treat it as - though it had been given in a /MATCH: switch and use it locally to - match the names in the list. - mget /mlsd foo/*.txt MLSD This one won't work because MLSD requires - that the notions of server directory and filename-matching pattern be - separated. However, the client, which can't be expected to know the - server's file-system syntax, winds up sending a request that the - server will (or should) reject. - mget /mlsd /match:*.txt MLSD Gets a list of all the files from the - server's current directory and then downloads only the ones whose - names match the pattern "*.txt" (client interprets wildcards). - mget /mlsd /match:*.txt foo MLSD foo If "foo" is a directory on the - server, this gets a list of all the files from the server's "foo" - directory and then downloads only the ones whose names match the - pattern "*.txt" (client interprets wildcards). This leaves the server - CD'd to the "foo" directory; there's no way the client can restore the - server's original directory because MLSD doesn't give that - information, and since the client can not be expected to know the - server's file-system syntax, it would not be safe to guess. If "foo" - is a regular file, MLSD fails. - mget /mlsd foo bar MLSD This one is problematic. You're supposed to be - able to give MGET a list a filespecs; in this case we name two - directories. The client must change the server's directory to "foo" to - get the list of files, and then the files themselves. But then it has - no way to return to the server's previous directory in order to do the - same for "bar", as explained in the previous example. - mget /mlsd /match:* [abc] MLSD [abc] Including a /MATCH: switch forces - [abc] to be sent to the server even though the client would normally - think it was a wildcard and hold it for local interpretation. In this - example, [abc] might be a VMS directory name. - mget /mlsd /match:* t*.h MLSD t*.h Contrary to the MLSD specification, - some MLSD-capable FTP servers do interpret wildcards. This form of the - MGET command can be used to force a wildcard to be sent to the server - for interpretation. - - When MLSD is used implicitly (that is, without an /MLSD switch given - to force the use of MLSD) and an MGET command such as "mget foo/*.txt" - fails, Kermit automatically falls back to NLST and tries again. - _________________________________________________________________ - - 3.11.5. References - - 1. Postel, J., and J. Reynolds, File Transfer Protocol (FTP), RFC - 959, October 1985: [361]ftp://ftp.isi.edu/in-notes/rfc959.txt. - 2. Hethmon, P, and R. Elz, Feature negotiation mechanism for the File - Transfer Protocol, RFC 2389, August 1998: - [362]ftp://ftp.isi.edu/in-notes/rfc2389.txt. - 3. Elz, R, and P. Hethmon, Extensions to FTP, Internet Draft - draft-ietf-ftpext-mlst-16.txt, September 2002: - [363]http://www.ietf.org/internet-drafts/draft-ietf-ftpext-mlst-16 - .txt. - 4. [364]The Kermit FTP Client (overview). - - [ [365]Top ] [ [366]FTP Top ] [ [367]C-Kermit Home ] [ [368]Kermit - Home ] - __________________________________________________________________________ - -4. FILE SCANNING - - A new feature called file scanning is used in various contexts to - determine if a file is text or binary, and if it is text, what kind of - text. The overhead of file scanning is surprisingly tolerable, usually - about a quarter second per file. File scanning is now used instead of - filename patterns unless you SET FILE SCAN OFF, which restores the - previous behavior. - - The primary benefit of file scanning is in file transfer. For all - practical purposes, now you can stop worrying about whether a file - should be sent in binary or text mode, or about sending mixtures of - text and binary files in a single operation, or configuring and - fine-tuning your lists of binary-file and text-file name patterns: now - it all just works. - - File scanning is done by the file sender, which determines the type of - each file before it sends it and informs the receiver (Kermit or FTP - server) of the type. File scanning is NOT done by the receiver, - because it is the sender's responsibility to determine each file's - type, send the file in the right mode, and inform the receiver of the - mode. If both transfer partners are capable of this (or any other) - form of automatic text/binary mode switching, then files can be sent - in both directions with no worries about corruption due to - inappropriate transfer mode. (As noted in [369]Section 3, FTP servers - don't do this, so this discussion does not apply when using Kermit to - download from an FTP server.) - - The rest of this section is mainly for the curious. If you don't read - it and simply accept all defaults, every file you send should go in - the appropriate mode automatically. As always, however, for - character-set translation to work for 7- and 8-bit character-set - files, the appropriate SET FILE CHARACTER-SET command(s) must have - been executed to identify their encoding (Kermit's default file - character-set is neutral ASCII except on platforms like HP-UX or - DG/UX, where the default file character-set is known). And of course, - receiving is another matter -- obviously the other Kermit must also - send each file in the appropriate mode. - - Scanning is more reliable than filename patterns simply because - filenames are not reliable indicators of the file's contents. Classic - examples include ".doc" files, which are binary if Microsoft Word - documents but text on most other platforms, and ".com" files, which - are binary on DOS and Windows but text on VMS. Anyway, nobody knows - the naming conventions (if any) of all the applications (and persons!) - on your computer. Scanning, on the other hand, determines each file's - type by inspecting its contents rather than just looking at its name. - - Also, file patterns -- even when they work as intended -- categorize - each file only as text or binary, whereas file scanning can make finer - distinctions: - - BINARY - Binary data, not to be converted in any way. Examples include - binary machine code (executable programs), graphics images - (GIF, JPG, etc), compressed files (Z, GZ, etc), archives and - packages (ZIP, TAR, RPM, etc), object files and libraries (OBJ, - DLL, etc). - - 7-BIT TEXT - Text encoded in a 7-bit character set such as ASCII or one of - the ISO 646 national versions. Kermit has no way to tell which - character is used, only that it's 7-bit text. Typical examples - include program source code, README files, Perl or Kermit - scripts, plain-text email, HTML, TeX, and various textual - encodings of binary files: Hex, Base64, etc. When sending such - files, the FILE DEFAULT 7BIT-CHARACTER-SET is used as the file - character-set, and then the appropriate transfer character set - is chosen from the associations list (ASSOCIATE, SHOW - ASSOCIATIONS). - - 8-BIT TEXT - Text encoded in an 8-bit character set such as Latin-1, - Latin-2, Latin/Hebrew, Latin/Cyrillic, KOI8, HP-Roman8, JIS X - 0208, Code Page 437, or Code Page 1252. Again, Kermit has no - way of knowing which particular set is in use, only that it's - 8-bit text. When sending such files, the FILE DEFAULT - 8BIT-CHARACTER-SET is used as the file character-set, and then - the appropriate transfer character set is chosen from the - associations list. - - UCS2 TEXT - Unicode in its basic form, 16 bits (2 octets) per character. - When sending such files, UCS2 is the file character-set and the - byte order is identified automatically; the appropriate - transfer character set is chosen from the associations list. - Normally this would be UTF8. UTF-16 is not supported yet; - Kermit's Unicode translations are restricted to Plane 0, the - Base Multilingual Plane (BMP). - - UTF8 TEXT - Unicode in its 8-bit transformation format. When sending such - files, UTF8 is the file character-set; the appropriate transfer - character set is chosen from the associations list, normally - UCS2 or UTF8. - - File scanning is available in UNIX C-Kermit, in K-95, and to a limited - extent, in VMS C-Kermit (full scanning is problematic in VMS because - even plain-text files might contain binary record-format information). - The relevant commands are: - - SET TRANSFER MODE { AUTOMATIC, MANUAL } - Tells whether the file-transfer mode (text or binary) should be - set by automatic or "manual" means. AUTOMATIC is the default, - which allows any of the automatic methods that are enabled to - do their jobs: FILE SCAN, FILE PATTERNS, peer recognition, etc. - MANUAL lets you control the transfer mode with the SET FILE - TYPE commands. As always, /TEXT and /BINARY switches on your - file-transfer commands override all other methods; if you give - one of these switches, scanning is not done. SHOW TRANSFER - displays the current TRANSFER MODE setting. - - SET FILE SCAN { ON [ number ], OFF } - Turns this feature on and off. It's ON by default. When OFF, - the previous rules apply (SET FILE PATTERNS, etc). When ON is - given, you can also specify a number of bytes to be scanned. - The default is 49152 (= 48K). If a negative number is given, - the entire file is scanned, no matter how big, for maximum - certainty (for example, a PostScript file that appears to be - plain text might include an embedded graphic past the normal - scanning limit). SHOW FILE displays the current FILE SCAN - setting. - - SET FILE DEFAULT 7BIT-CHARACTER-SET name - Tells the 7-bit character-set to use if scanning identifies a - 7-bit text file, e.g. GERMAN. SHOW FILE displays the current - SET FILE DEFAULT settings. So does SHOW CHARACTER-SETS. - - SET FILE DEFAULT 8BIT-CHARACTER-SET name - Tells the 8-bit character-set to use if scanning identifies an - 8-bit text file, e.g. LATIN1. SHOW FILE and SHOW CHARACTER-SET - display this. - - ASSOCIATE FILE-CHARACTER-SET fcs tcs - When sending files and a file character-set (fcs) is identified - by scanning, this tells C-Kermit which transfer character-set - (tcs) to translate it to. It also allows C-Kermit to set the - appropriate transfer character-set automatically whenever you - give a SET FILE CHARACTER-SET command. - - ASSOCIATE TRANSFER-CHARACTER-SET tcs fcs - When receivinging files and a file arrives whose transfer - character-set (tcs) is announced by the sender, this command - tells C-Kermit which file character-set (fcs) to translate it - to. It also allows C-Kermit to set the appropriate file - character-set whenever you give a SET TRANSFER CHARACTER-SET - command. - - SET FILE CHARACTER-SET name - When given for a 7-bit set, also sets FILE DEFAULT - 7BIT-CHARACTER-SET to the same set. When given for an 8-bit - set, also sets FILE DEFAULT 8BIT-CHARACTER-SET to the same set. - If an ASSOCIATE FILE-CHARACTER-SET command has been given for - this set, also sets the corresponding transfer character-set. - - DIRECTORY /XFERMODE [ filespec ] - Performs a file scan of the given files, listing the result for - each file. If FILE SCAN is OFF but PATTERNS are ON, the result - shown according to the current FILE TEXT-PATTERNS and - BINARY-PATTERNS, and are restricted to (B) and (T). When FILE - SCAN is ON, the results are: - - (B) Binary - (T)(7BIT) Text: 7-bit - (T)(8BIT) Text: 8-bit - (T)(UTF8) Text: Unicode UTF8 - (T)(UCS2BE) Text: Unicode UCS2 Big Endian - (T)(UCS2LE) Text: Unicode UCS2 Little Endian - - So you can use DIR /XFER to get a preview of how each file in a - selected group will be transferred. Everything to the right of - the (B) or (T) is new. If FILE SCAN is OFF, you only get the - (B) or (T) as before. - - Note: Big and Little Endian refer to the ordering of bytes - within a computer word. Big Endian architecture is standard and - is used on most non-PC computers. Little Endian architecture is - used on PCs. - - To illustrate file-transfer with scanning, suppose you have a - directory containing a mixture of text and binary files, and each text - file can be 7-bit German ISO 646, 8-bit Latin-1, or Unicode in any of - the following forms: UCS2 Little Endian, UCS2 Big Endian, or UTF8 - ([370]UTF-16 is not supported yet). Assuming all the built-in defaults - are in effect, the following three commands do the job: - - set file char german ; This sets the default for 7-bit text files - set file char latin1 ; This sets the default for 8-bit text files - send * - - Each file is sent in the appropriate mode (text or binary), with text - files converted to the appropriate transfer character-set and labeled - so the receiver can convert them according to its own local - conventions. - - By the way, what if you want to inhibit character-set translation but - still allow automatic text/binary mode switching? Previously, you - could simply SET TRANSFER CHARACTER-SET TRANSPARENT. But now with file - scanning, the file and transfer character-sets are set automatically - per file. A new command was added for this purpose: - - SET TRANSFER TRANSLATION { ON, OFF } - Enables and disables file-transfer character-set translation. - It is enabled by default. - - When TRANSFER TRANSLATION is OFF but FILE SCAN is ON, files are still - scanned to see if they are text or binary, but no character-set - translation is done when they text: only the normal record-format - conversion. - - Like all SET commands, SET TRANSFER TRANSLATION is global and - persistent. You can also force a particular file-transfer command - (SEND, MSEND, GET, RECEIVE, TRANSMIT, etc) to not translate without - affecting the global translation settings by including the new - /TRANSPARENT switch, e.g. - - send /transparent oofa.txt - - As of C-Kermit 8.0.206, SET TRANSFER CHARACTER-SET TRANSPARENT implies - SET TRANSFER TRANSLATION OFF. - - File scanning is also used in the TYPE command. The source file type - and character set are determined as above, and then the file is - automatically converted to your display character-set, line by line. - In Kermit 95, the display character-set is Unicode, perhaps converted - to your current console code page; in other versions of C-Kermit, it - is your current file character-set. Thus if you have the following set - appriately: - - SET FILE CHARACTER-SET (necessary in Unix but not K95) - SET FILE DEFAULT 7BIT CHARACTER-SET - SET FILE DEFAULT 8BIT CHARACTER-SET - - then you should be able to TYPE any text file and see something - reasonable. For example, in Unix, if your DEFAULT 7BIT-CHARACTER-SET - is ITALIAN and your DEFAULT 8BIT-CHARACTER-SET is LATIN1, and your - FILE CHARACTER-SET is LATIN1, you can TYPE an Italian ISO 646 file, a - Latin-1 file, or any kind of Unicode file, and have it translated - automatically to Latin-1 for your display. - - In the GUI version of Kermit 95, you can see mixtures of many - different scripts if the file is UTF8 or UCS2: Roman, Cyrillic, - Hebrew, Greek, Armenian, Georgian, etc, all on the same screen at - once. - - File scanning also adds a new criterion for file selection, i.e. to - select only text (or binary) files. Several commands now include a new - switch, /TYPE:{BINARY,TEXT,ALL}. BINARY means select only binary - regular files (not directories). TEXT means select only text files. - ALL means don't scan; select all files. Examples: - - SEND /TYPE:BINARY *.* - Sends only binary files, skipping over text files. - - NOTE: File scanning is NOT done when using external protocols (because - the external protocol programs, such as sz, are processing each file, - not Kermit). - - DIRECTORY /TYPE:TEXT - Lists only text files but not binary files. - - DELETE /TYPE:BINARY foo.* - Deletes all foo.* files that are regular binary files but does - not delete any text files. - - CHMOD /TYPE:BINARY 775 * - (UNIX) Changes the permissions of all binary files to 775. - - When FILE SCAN is OFF and FILE PATTERNS are ON, behavior is as before - with PATTERNS ON, but with some improvements: - - * Pathnames are now stripped prior to pattern matching. - * Backup suffixes (like .~3~) are stripped prior to pattern - matching. - - [ [371]Top ] [ [372]Contents ] [ [373]C-Kermit Home ] [ [374]Kermit - Home ] - __________________________________________________________________________ - -5. FILE AND DIRECTORY NAMES CONTAINING SPACES - - Prior to the introduction of the graphical user interface (GUI), it - was inconceivable that file or directory names could contain spaces, - because space is a field delimiter in all command languages. GUIs, - however, use dialog boxes for filenames, so there is never any - question of distinguishing a filename from adjacent fields -- because - there are no adjacent fields -- and therefore it has become quite - common on computers that have GUIs to have file and directory names - composed of multiple words. Of course this poses problems for command - shells and other text-oriented programs. - - Most command shells address these problems by allowing such names to - be enclosed in doublequotes, e.g.: - - cd "c:\Program Files" - - C-Kermit previously used braces for this: - - cd {c:\Program Files} - - which was not what most people expected. And even when braces were - used, Kermit had difficulties with completion, file menus, and so - forth, within braced fields. - - C-Kermit 8.0 allows either doublequotes or braces to be used for - grouping: - - send "this file" - send {this file} - rename "this file" "that file" - rename {this file} "that file" - rename "this file" {that file} - cd {Program Files} - cd "Program Files" - - Note that the doublequotes or brackets must enclose the whole file or - directory specification: - - "c:\My Directory" - - not: - - c:\"My Directory" - - In C-Kermit 8.0, you can also use completion on these filenames, in - which case Kermit supplies the quotes (or braces) automatically. - Example (in which the current directory contains only one file whose - name starts with "th" and its full name is "this file" (without the - quotes, but with the space)): - - cat th - - Kermit repaints the filename field like this: - - cat "this file" - - That is, it backspaces over the original "th" and then writes the - filename in doublequotes. - - If completion is only partial, Kermit still supplies the quotes, but - in this case also beeps. To continue the filename, you must first - backspace over the closing quote. The closing quote is supplied in - this case to make sure that you can see the spaces, especially if they - are trailing. For example, if the current directory contains two files - whose names start with "th", and their fill names are "this file" and - "this other file": - - cat th - - Kermit prints: - - cat "this " - - If it didn't print the closing quote, you would probably wonder why it - was beeping. - - Also, if you begin a filename field with a doublequote or opening - brace, now you can use completion or get ?-help; this was never - possible before. - - C-Kermit>type "thi? Input file specification, one of the following: - this file this other file - C-Kermit>type "thi_ - - [ [375]Top ] [ [376]Contents ] [ [377]C-Kermit Home ] [ [378]Kermit - Home ] - __________________________________________________________________________ - -6. OTHER COMMAND PARSING IMPROVEMENTS - - 6.1. Grouping Macro Arguments - - Doublequotes now can be used in macro invocations to group arguments - containing spaces, where previously only braces could be used: - - define xx show args - xx one "this is two" three - - Result: - - Macro arguments at level 0 (\v(argc) = 4): - \%0 = xx - \%1 = one - \%2 = this is two - \%3 = three - - Also, you can now quote braces and quotes in macro args (this didn't - work before). Examples: - - xx "{" ; The argument is a single left brace - xx {"} ; The argument is a doublequote character - - In case this new behavior interferes with your scripts, you can - restore the previous behavior with: - - SET COMMAND DOUBLEQUOTING OFF - - 6.2. Directory and File Name Completion - - C-Kermit 8.0 also includes better completion for directory names, e.g. - in the CD command. If the name typed so far uniquely matches a - directory name, it is completed (as before), but now if the directory - contains any subdirectories, completion is partial (allowing you to - supply additional path segments without backspacing); otherwise it is - complete. - - Completion has also been improved for file and directory names that - contain not only spaces (as described above) but also "metacharacters" - such as asterisk (*) and tilde (~): now the field is repainted if - necessary. For example, if the current directory contains only one - file whose name contains "blah", then in: - - type *blah - - "*blah" is replaced by the filename. In earlier releases, the part - typed so far was left on the command line (and in the history buffer), - so even when the original command worked, the recalled version would - not. Similarly for ~ (the nearly-universal Unix notation for - username): - - type ~olga/x - - is repainted as (e.g.): - - type /users/home/olga/x(Beep) - - Speaking of command history, the new SHOW HISTORY command shows your - command history and recall buffer. SAVE COMMAND HISTORY saves it into - a file of your choice. - - 6.3. Passing Arguments to Command Files - - The method for passing arguments to command files has been improved. - Prior to C-Kermit 7.0 there was no provision for doing this. In - C-Kermit 7.0, the TAKE command was changed to allow arguments to be - given after the filename: - - take commandfile arg1 arg2 ... - - This was accomplished by replacing the current \%1, \%2, etc, with the - given arguments, since a new set of macro argument variables is - created only when a macro is executed, not a command file. It is much - more intuitive, however, if arguments to command files worked like - those to macros: the command file sees the arguments as its own \%1, - \%2, etc, but the caller's variables are not disturbed. C-Kermit 8.0 - accomplishes this by automatically creating an intermediate temporary - macro to start the command file (if any arguments were given), thus - creating a new level of arguments as expected. - - 6.4. More-Prompting - - The familiar --more?-- prompt that appears at the end of each - screenful of command-response output now accepts a new answer: G (Go) - meaning "show all the rest without pausing and asking me any more - questions". P (Proceed) is a synonym for G. - - 6.5. Commas in Macro Definitions - - As noted in the [379]C-Kermit manual, comma is used to separate - commands in a macro definition. Even when the macro is defined on - multiple lines using curly-brace block-structure notation without - commas, the definition is still stored internally as a comma-separated - list of commands. Therefore special tricks are needed to include a - comma in a command. The classic example is: - - define foo { - (some command) - if fail echo Sorry, blah failed... - } - - This would result in Kermit trying to execute a "blah" command. This - could always be handled by enclosing the text in braces: - - define foo { - (some command) - if fail echo {Sorry, blah failed...} - } - - but doublequotes (more intuitive) should have worked too. Now they do: - - define foo { - (some command) - if fail echo "Sorry, blah failed..." - } - - 6.6. Arrow Keys - - As of version 8.0.201, C-Kermit on most platforms lets you access the - command history buffer with arrow keys, just as you always could with - control characters. The restrictions are: - - 1. Only Up and Down arrow keys are accepted. - 2. Only 7-bit ANSI arrow-key sequences are understood (ESC followed - by [ or uppercase letter O, followed by uppercase letter A or (up) - B (down). - - This change was made to facilitate command recall in Linux-based PDAs - that don't have a Control key, or at least not one that's easily (or - always) accessible, such as the Sharp Zaurus SL5500. - - [ [380]Top ] [ [381]Contents ] [ [382]C-Kermit Home ] [ [383]Kermit - Home ] - __________________________________________________________________________ - -7. NEW COMMANDS AND SWITCHES - - See [384]Section 4 for more about file scanning and the /TYPE: switch. - - ASK[Q] [ /TIMEOUT:number /QUIET /DEFAULT:text ] variable [ prompt ] - The new optional /TIMEOUT: switch for ASK and ASKQ causes the - command to time out and and fail if no response is given within - the specified number of seconds, 1 or greater (0 or less means - no timeout, wait forever). This works just like SET ASK-TIMER, - except its effect is local to the ASK command with which it is - given and it does not disturb the global ask timer setting. The - new /QUIET switch tells Kermit not to print an error message if - the ASK or ASKQ command times out waiting for a response. - - Version 8.0.211 adds the /DEFAULT:text switch for ASK-Class - commands (ASK, ASKQ, and GETOK). This lets you supply a default - answer in case the user supplies an empty answer or the - /TIMEOUT: switch was included and the time limit expired - without an answer. In both these cases, the command succeeds. - - CAT filename - Equivalent to TYPE /NOPAGE. - - CDUP - Changes Kermit's local working directory to the parent of the - current one. Equivalent to "cd .." in UNIX or Windows, "cd [-]" - in VMS, "cd ^" in AOS/VS, etc; in other words, it's a - platform-independent way of moving one level up in a directory - tree. - - CHMOD [ switches ] permission files - UNIX only. Sets file permissions for one or more files or - directories. The permission must be given as an octal number, - e.g. 664, 755. Switches: /DIRECTORIES, /FILES, /NOLIST, /PAGE, - /DOTFILES, /LIST, /NOPAGE, /RECURSIVE, /TYPE:{TEXT,BINARY,ALL}, - /SIMULATE. The /TYPE: switch allows selection of only text or - binary files. For example, if you have a mixture of source - files and executables, you can use "chmod /files /type:text - 664" to give owner/group read/write and world read permission - to the text files, and "chmod /files /type:binary 775" to give - the same plus execute permission to the executables. Use - /SIMULATE to see which files would be affected, without - actually changing their permissions. - - CLEAR KEYBOARD-BUFFER - Flushes any as-yet unread characters from the keyboard input - buffer. Useful for flushing typeahead in scripts. - - CONTINUE - When given at an interactive command prompt that was reached by - issuing a PROMPT command (described in this section) from a - script, this command returns to the script, continuing its - execution at the command after the PROMPT command. In this - context, CONTINUE is simply a more-intuitive synonym for END. - - COPY, RENAME, and TRANSLATE - These commands now work on file groups if the target filename - is a directory, e.g. "copy oofa.* ..", "rename * ~olga/tmp/" - - COPY /APPEND source destination - The source file specification can now include wildcards, in - which case all of the source files that match will go into the - destination file in alphabetical order by name. - - DELETE /ASK - Asks permission to delete each file before deleting it. In - C-Kermit 7.0, the answers were "yes" (or "ok") and "no". - C-Kermit 8.0 adds "go" (meaning, delete all the rest without - asking) and "quit" (cancel the DELETE command and return to the - prompt). - - DELETE /DIRECTORIES - Deletes not only files but also directories. - - DELETE /RECURSIVE - Deletes all files that match the given file specification in - the current (or given) directory and all directories beneath - it. - - DELETE /SUMMARY - Prints only the number of files deleted and total size freed, - without listing each file. - - DELETE /TREE - Shorthand for DELETE /RECURSIVE /DIRECTORIES /DOTFILES/. - Equivalent to Windows DELTREE or Unix "rm -Rf". If no file - specification is given, the contents of the current directory, - plus all of its subdirectories and their contents, are deleted. - - DELETE /TYPE:BINARY - Delete only regular binary files (requires FILE SCAN ON). - - DELETE /TYPE:TEXT - Delete only regular text files (requires FILE SCAN ON). - - DIRECTORY [ switches ] [ filespec [ filespec [ filespec ... ] ] ] - The DIRECTORY command now accepts more than one file - specification; e.g. "directory moon.txt sun.doc stars.*". - - DIRECTORY /NORECURSIVE xxx - If xxx is a directory name, forces listing of the directory - itself rather than its contents. - - DIRECTORY /FOLLOWLINKS xxx - (UNIX only) Tells the DIRECTORY command to follow symbolic - links. This not the default because it can cause endless loops. - - DIRECTORY /NOFOLLOWLINKS xxx - (UNIX only) Tells the DIRECTORY command not to follow symbolic - links, but rather, merely to list them. This is the default. - - DIRECTORY /OUTPUT:filename - Sends the results of the DIRECTORY command to the given file. - - DIRECTORY /SUMMARY - Prints only the number of directories and files and the total - size, without listing each file. - - DIRECTORY /TYPE:{TEXT,BINARY} - Shows only files of the selected type, based on file scan. - - DIRECTORY /XFERMODE - Now shows results of file scan (see [385]Section 4). - - FOPEN [ switches ] channel filename - - As of version 8.0.211, FOPEN allows /dev/tty as a filename in - Unix-based operating systems. - - FREAD /TRIM - (8.0.211) Trims any trailing blanks or tabs from the item (such - as a line of text) that it has read. - - FREAD /UNTABIFY - (8.0.211) Converts Horizontal Tab characters to the appropriate - number of spaces, based on VT100-like tab stops - (1,9,17,25,...). - - GREP [ switches ] pattern files - Similar to Unix grep command: displays file lines that match - the given [386]pattern. Switches: - - /COUNT[:variable] - Don't show the matching lines, just tell how many lines - match. If a variable name is specified, the count is - stored in the given variable. - - /DOTFILES - Include files whose names begin with dot. - - /LINENUMBERS - Show line numbers of matching lines. - - /NAMEONLY - only list the names of files that contain matching lines, - but not the lines themselves. - - /NOBACKUP - Skip backup files. - - /NOCASE - Ignore alphabetic case while pattern matching. - - /NODOTFILES - skip files whose names start with dot (period). - - /NOLIST - Suppress output but set SUCCESS or FAILURE according to - search result. - - /NOMATCH - Look for lines that do not match the pattern. - - /NOPAGE - Don't pause between screens of output. - - /OUTPUT:filename - Write results into the given file. - - /PAGE - Pause between screens of output. - - /RECURSIVE - Search files in subdirectories too. - - /TYPE:{TEXT,BINARY} - Search only files of the specified type. - - Synonyms: FIND, SEARCH. - - GETOK /TIMEOUT:n /QUIET /DEFAULT:text - The new /QUIET switch instructs GETOK, when given a timeout, - not to print an error message if it times out. As of 8.0.211, a - default answer can be supplied (see ASK). - - HEAD [ switches ] filename - Equivalent to TYPE /HEAD [ other-switches ] filename. - - HELP DATE - Explains date-time formats, including timezone notation and - delta times. - - HELP FIREWALLS - Explains the firewall negotiation capabilities of your version - of Kermit. - - KCD [ symbolic-directory-name ] - Changes Kermit's working directory to the named symbolic - directory, such as such as exedir, inidir, startup, download, - or and home. Type "kcd ?" for a list of symbolic directory - names known to your copy of Kermit, or give the new ORIENTATION - command for a more detailed explanation. If you give a KCD - command without a directory name, Kermit returns to its "home" - directory, which is determined in some way that depends on the - underlying operating system, but which you can redefine with - the (new) SET CD HOME command. Your home directory is shown by - SHOW CD and it's also the value of the \v(home) variable. - - LICENSE - Displays the C-Kermit license. - - L-commands - When Kermit has a connection to a Kermit or FTP server, file - managment commands such as CD, DIRECTORY, and DELETE might be - intended for the local computer or the remote server. C-Kermit - 8.0.200 and earlier always executes these commands on the local - computer. If you want them executed by the remote server, you - have to prefix them with REMOTE (e.g. REMOTE CD) or use special - R-command aliases (e.g. RCD = REMOTE CD, RDIR = REMOTE DIR, - etc). But this feels unnatural to FTP users, who expect - unprefixed file management commands to be executed by the - remote server, rather than locally. C-Kermit 8.0.201 adds - automatic locus switching to present an FTP-like interface for - FTP connections and the normal Kermit interface for Kermit - connections, and a SET LOCUS command (described below) to - control whether or how this is done. For when LOCUS is REMOTE, - a new set of commands was added for local management: LCD - (Local CD), LDIR (Local DIR), etc. These are described below - under SET LOCUS. - - MORE filename - Equivalent to TYPE /PAGE. - - ORIENTATION - Displays symbolic directory names and the corresponding - variable names and values. The symbolic names, such as exedir, - inidir, startup, download, and home, can be used as arguments - to the new KCD command. - - PROMPT [ text ] - For use in a macro or command file: enters interactive command - mode within the current context ([387]Section 8.1). If the - optional text is included, the prompt is set to it. The text - can include variables, functions, etc, as in the SET PROMPT - command. They are evaluated each time the prompt is printed. - Unlike the SET PROMPT command, the text argument applies only - to the current command level. Thus you can have different - prompts at different levels. - - REMOTE SET MATCH { DOTIFILE, FIFO } { ON, OFF } - Allows the client to tell the server whether wildcards sent to - the server should match dot files (files whose names begin with - period) or FIFOs (named pipes). See SET MATCH. - - SET ATTRIBUTE RECORD-FORMAT { ON, OFF } - Allows control of the Kermit's Record-Format attribute. Set - this to OFF in case incoming file are refused due to unknown or - invalid record formats if you want to accept the file anyway - (and, perhaps, postprocess it to fix its record format). - - SET CD HOME [ directory ] - Specifies the target directory for the CD and KCD commands, - when they are given without an argument, and also sets the - value of the \v(home) variable. - - SET EXIT HANGUP { OFF, ON } - Normally ON, meaning that when Kermit exits, it also explicitly - hangs up the current SET LINE / SET PORT serial port according - to the current SET MODEM TYPE and SET MODEM HANGUP METHOD, and - closes the port device if it was opened by Kermit in the first - place (as opposed to inherited). SET EXIT HANGUP OFF tells - Kermit not to do this. This can't prevent the operating system - from closing the device when Kermit exits (and it's a "last - close") but if the port or modem have been conditioned to - somehow ignore the close and keep the connection open, at least - Kermit itself won't do anything explicit to hang it up or close - it. - - SET FILE EOF { CTRL-Z, LENGTH } - Specifies the end-of-file detection method to be used by - C-Kermit when sending and receiving text files, and in the TYPE - and similar text-file oriented commands. The normal and default - method is LENGTH. You can specify CTRL-Z when handling CP/M or - MS-DOS format text files, in which a Ctrl-Z (ASCII 26) - character within the file marks the end of the file. - - SET FILE LISTSIZE number - Allocates space for the given number of filenames to be filled - in by the wildcard expander. The current number is shown by - SHOW FILE. If you give a command that includes a filename - containing a wildcard (such as "*") that matches more files - that Kermit's list has room for, you can adjust the list size - with this command. - - SET FILE STRINGSPACE number - Allocates space for the given amount of filename strings for - use by the wildcard expander. The current number is shown by - SHOW FILE. The number is the total number of bytes of all the - file specifications that match the given wildcard. - - If you need to process a bigger list of files than your computer - has memory for, you might be able use an external file list. The - Kermit SEND and the FTP PUT and GET commands accept a /LISTFILE: - switch, which gives the name of a file that contains the list of - files to be transferred. Example for UNIX: - - !find . -print | grep / > /tmp/names - ftp put /update /recursive /listfile:/tmp/names - - SET LOCUS { AUTO, LOCAL, REMOTE } - Added in C-Kermit 8.0.201. Sets the locus for unprefixed file - management commands such as CD, DIRECTORY, MKDIR, etc. When - LOCUS is LOCAL these commands act locally and a REMOTE (or R) - prefix (e.g. REMOTE CD, RCD, RDIR) is required to send file - management commands to a remote server. When LOCUS is REMOTE, - an L prefix is required to issue local file management commands - (e.g. LCD, LDIR). The word LOCAL can't be used as a prefix - since it is already used for declaring local variables. LOCUS - applies to all types of connections, and thus is orthogonal to - SET GET-PUT-REMOTE, which selects between Kermit and FTP for - remote file-transfer and management commands. The default LOCUS - is AUTO, which means we switch to REMOTE whenever an FTP - connection is made, and to LOCAL whenever a non-FTP connection - is made, and switch back accordingly whenever a connnection is - closed. So by default, Kermit behaves in its traditional manner - unless you make an FTP connection, in which case it acts like a - regular FTP client (but better :-) LOCUS applies to the - following commands: - - Unprefixed Remote Local Description - CD (CWD) RCD LCD Change (Working) Directory - CDUP RCDUP LCDUP CD Up - PWD RPWD LPWD Print Working Directory - DIRECTORY RDIR LDIR Request a directory listinga - DELETE RDEL LDEL Delete (a) file(s) - RENEME RREN LREN Rename a file - MKDIR RMKDIR LMKDIR Create a directory - RMDIR RRMDIR LRMDIR Remove a directory - - SET MATCH { DOTIFILE, FIFO } { ON, OFF } - Whether C-Kermit filename patterns (wildcards) should match - filenames that start with dot (period), or (Unix only) FIFOs - (named pipes). The defaults are to skip dotfiles in Unix but - match them elsewhere, and to skip FIFOs. Applies to both - interactive use and to server mode, when the server receives - wildcards, e.g. in a GET command. Also see REMOTE SET MATCH. - - SET OPTIONS DIRECTORY /DOTFILES - Now works for server listings too (UNIX only). Give this - command prior to having Kermit enter server mode, and then it - will show files whose names begin with dot (period) when sent a - REMOTE DIRECTORY command. - - SET QUIET ON - (as well as the -q command-line option) Now applies also to: - - + SET HOST connection progress messages. - + "Press the X or E key to cancel" file-transfer message. - + REMOTE CD response. - + REMOTE LOGIN response. - - SET RECEIVE PERMISSIONS { ON, OFF } - Tells C-Kermit whether to set the permissions of incoming files - (received with Kermit protocol) from the permissions supplied - in the file's Attribute packet (if any). Normally ON. Also see - SET SEND PERMISSIONS. - - SET ROOT directory - Like UNIX chroot, without requiring privilege. Sets the root - for file access, does not allow reference to or creation of - files outside the root, and can't be undone. - - SET SEND PERMISSIONS { ON, OFF } - Tells C-Kermit whether to include file permissions in the - attributes it includes with each file when sending with Kermit - protocol. Also see SET RECEIVE PERMISSIONS. - - SET TCP { HTTP-PROXY, SOCKS-SERVER } /USER:name /PASSWORD:text - These commands now allow specification of username and - password. - - SET TERMINAL . . . - (See [388]Section 12.) - - SET TRANSFER MESSAGE [ text ] - Sets an initial text message to be displayed in the - file-transfer display. The transfer message is automatically - deleted once used, so must be set each time a message a - desired. Any variables in the message are evaluated at the time - the SET command is given. If the optional text is omitted, any - transfer message that is currently set is removed. Synonym: SET - XFER MSG. SHOW TRANSFER displays it if it has been set but not - yet used. - - SHOW COMMUNICATIONS - In C-Kermit 8.0, SHOW COMMUNICATIONS, when given in remote mode - (i.e. before any connection has been established), tells the - typical dialout device name for the particular platform on - which it's running (e.g. TXA0: for VMS, or /dev/cua0p0 for - HP-UX). On Unix platforms, it also tells the name of the - lockfile directory. This way, you have an idea of what the SET - LINE device name should look like, and if the SET LINE command - fails, you know the name of the directory or device that is - protected against you. - - SHOW VARIABLES [ name [ name [ ... ] ] ] - In C-Kermit 8.0.201 you can request values of a list of - built-in (\v(xxx)) variables. Each name is a pattern, as - before, but now it a free pattern rather than an anchored one - (explained in [389]Section 8.12) so now "show var date time" - shows the values of all variables whose names include the - strings "date" or "time". - - TAIL [ switches ] filename - Equivalent to TYPE /TAIL [ other-switches ] filename. - - TRANSMIT /NOECHO [ other switches ] filename - The /NOECHO switch is equivalent to giving the command SET - TRANSMIT ECHO OFF prior to the TRANSMIT command, except the - switch affects only the command with which it was given and - does not affect the prevailing global setting. - - TRANSMIT /NOWAIT [ other switches ] filename - The /NOWAIT switch is equivalent to giving the command SET - TRANSMIT PROMPT 0 prior to the TRANSMIT command, except the - switch affects only the command with which it was given and - does not affect the prevailing global setting. - - TRANSMIT /NOWAIT /NOECHO /BINARY [ other switches ] filename - When the TRANSMIT command is given with the /NOWAIT, /NOECHO, - and /BINARY switches, this activates a special "blast the whole - file out the communications connection all at once" mode that - Kermit didn't have prior to version 8.0. There has been - increasing demand for this type of transmission with the advent - of devices that expect image (e.g. .JPG) or sound (e.g. .MP3) - files as raw input. The obvious question is: how does the - receiving device know when it has the whole file? This depends - on the device, of course; usually after a certain amount of - time elapses with nothing arriving, or else when Kermit hangs - up or closes the connection. - - TYPE /CHARACTER-SET:name - Allows you to specify the character set in which the file to be - typed is encoded. - - TYPE /NUMBER - Adds line numbers. - - TYPE /OUTPUT:filename - Sends the results of the TYPE command to the given file. - - TYPE /TRANSLATE-TO:name - Used in conjunction with TYPE /CHARACTER-SET:xxx; allows you to - specify the character set in which the file is to be displayed. - - TYPE /TRANSPARENT - Used to disable character-set translation in the TYPE command, - which otherwise can take place automatically based on file - scanning, even when /CHARACTER-SET and /TRANSLATE-TO switches - are not given. - - VOID text - Parses the text, evaluating any backslash items in it (such as - function calls) but doesn't do anything further, except - possibly printing error messages. Useful for invoking functions - that have side effects without using or printing their direct - results, e.g. "void \fsplit(\%a,&a)". - - Symbolic Links in UNIX - - The UNIX versions of C-Kermit have had /FOLLOWLINKS and /NOFOLLOWLINKS - switches added to several commands to control the treatment of - symbolic links. Different commands deal differently with symbolic - links: - - Kermit SEND, FTP MPUT - /NOFOLLOWLINKS is the default, which means symbolic links are - skipped entirely. The alternative, /FOLLOWLINKS, should be used - with caution, since an innocent link might point to a whole - file system, or it might cause a loop. There is no way in - Kermit or FTP protocol to send the link itself. We either skip - them or follow them; we can't duplicate them. - - DIRECTORY - /NOFOLLOWLINKS is the default, which means the DIRECTORY - command lists symbolic links in a way that shows they are - links, but it does not follow them. The alternative, - /FOLLOWLINKS, follows links and gives information about the - linked-to directories and files. - - DELETE, RMDIR - The DELETE command does not have link-specific switches. DELETE - never follows links. If you tell Kermit to delete a symbolic - link, it deletes the link itself, not the linked-to file. Ditto - for RMDIR. - - COPY - The COPY command behaves just like the UNIX cp command; it - always follows links. - - RENAME - The RENAME command behaves just like the UNIX mv command; it - operates on links directly rather than following. - - [ [390]Top ] [ [391]Contents ] [ [392]C-Kermit Home ] [ [393]Kermit - Home ] - __________________________________________________________________________ - -8. OTHER SCRIPTING IMPROVEMENTS - - 8.1. Performance and Debugging - - A command cache for frequently used commands plus some related - optimizations increases the speed of compute-bound scripts by anywhere - from 50% to 1000%. - - The new PROMPT command can be used to set breakpoints for debugging - scripts. If executed in a command file or macro, it gives you an - interactive command prompt in the current context of the script, with - all its variables, arguments, command stack, etc, available for - examination or change, and the ability to resume the script at any - point (END resumes it, Ctrl-C or STOP cancels it and returns to top - level). - - The new Ctrl-C trapping feature ([394]Section 8.14) lets you intercept - interruption of scripts. This can be used in combination with the - PROMPT command to debug scripts. Example: - -define ON_CTRLC { - echo INTERRUPTED BY CTRL-C... - echo The command stack has not yet been rolled back: - show stack - echo Type Ctrl-C again or use the END command to return to top level. - prompt Debug> -} - - Adding this ON_CTRL definition to your script lets you interrupt it at - any point and get prompt that is issued at the current command level, - so you can query local variables, etc. - - [ [395]Top ] [ [396]Contents ] [ [397]C-Kermit Home ] [ [398]Kermit - Home ] - _________________________________________________________________ - - 8.2. Using Macros as Numeric Variables - - A macro is a way to assign a value to a name, and then use the name to - refer to the value. Macros are used in two ways in Kermit: as - "subroutines" or functions composed of Kermit commands, which are - executed, or as variables to hold arbitrary values -- text, numbers, - filenames, etc. - - When a macro is to be executed, its name is given as if it were a - C-Kermit command, optionally preceded by the word "do". When a macro - is used as a variable, it must be "escaped" with \m(xxx) (or - equivalent function, e.g. \s(xxx), \:(xxx), \fdefinition(xxx)), where - xxx is the macro name, for example: - - define filename /usr/olga/oofa.txt - send \m(filename) - - Of course variables can also hold numbers: - - define size 17 - declare \&a[\m(size)] - ... - define index 3 - if ( == \m(index) 3 ) echo The third value is: \&a[\m(index)] - evaluate index (\m(index) * 4) - if ( > \m(index) \m(size) ) echo Out of range! - - But these are contexts in which only numbers are valid. C-Kermit 8.0 - has been changed to treat non-escaped non-numeric items in strictly - numeric contexts as macro names. So it is now possible (but not - required) to omit the \m(...) notation and just use the macro name in - these contexts: - - define size 17 - declare \&a[size] - ... - define index 3 - if ( == index 3 ) echo The third value is: \&a[index] - evaluate index (index * 4) - if ( > index size ) echo Out of range! - - This is especially nice for loops that deal with arrays. Here, for - example, is a loop that reverses the order of the elements in an - array. Whereas formerly it was necessary to write: - - .\%n ::= \fdim(&a) - for \%i 1 \%n/2 1 { - .tmp := \&a[\%n-\%i+1] - .\&a[\%n-\%i+1] := \&a[\%i] - .\&a[\%i] := \m(tmp) - } - - Recoding this to use macro names "i" and "n" instead of the backslash - variables \%i and \%n, we have: - - .n ::= \fdim(&a) - for i 1 n/2 1 { - .tmp := \&a[n-i+1] - .\&a[n-i+1] := \&a[i] - .\&a[i] := \m(tmp) - } - - which reduces the backslash count to less than half. The final - statement in the loop could be written ".\&a[i] ::= tmp" if the array - contained only numbers (since ::= indicates arithmetic expression - evaluation). - - Also, now you can use floating-point numbers in integer contexts (such - as array subscripts), in which case they are truncated to an integer - value (i.e. the fractional part is discarded). - - Examples of numeric contexts include: - - * Array subscripts. - * Any numeric function argument. - * Right-hand side of ::= assignments. - * EVALUATE command or \fevaluate() function expression. - * The INCREMENT or DECREMENT by-value. - * IF =, >, <, !=, >=, and <= comparands. - * The IF number construct. - * FOR-loop variables. - * STOP, END, and EXIT status codes. - * The INPUT timeout value. - * PAUSE, WAIT, SLEEP, MSLEEP intervals. - * The SHIFT argument. - * Numeric switch arguments, e.g. TYPE /WIDTH:number, SEND - /LARGER:number. - * SCREEN MOVE-TO row and column number. - * Various SET DIAL parameters (timeout, retry limit, etc). - * Various SET SEND or RECEIVE parameters (packet length, window - size, etc). - * Various other SET parameters. - - and: - - * S-Expressions (explained in [399]Section 9). - - Macro names used in numeric contexts must not include mathematical - operators. Although it is legal to create a macro called "foo+bar", in - a numeric context this would be taken as the sum of the values of - "foo" and "bar". Any such conflict can be avoided, of course, by - enclosing the macro name in \m(...). - - [ [400]Top ] [ [401]Contents ] [ [402]C-Kermit Home ] [ [403]Kermit - Home ] - _________________________________________________________________ - - 8.3. New IF Conditions - - Several new IF conditions are available: - - IF DECLARED arrayname - Explained in [404]Section 8.6. - - IF KBHIT - Allows a script to test whether a key was pressed without - actually trying to read it. - - IF KERBANG (Unix only) - True if Kermit was started from a Kerbang script. This is - useful for knowing how to interpret the \&@[] and \&_[] - argument vector arrays, and under what conditions to exit. - - IF INTEGER n - This is just a synonym for IF NUMERIC, which is true if n - contains only digits (or, if n is a variable, its value - contains only digits). - - By contrast, IF FLOAT n succeeds if n is a floating-point number OR an - integer (or a variable with floating-point or integer value). - Therefore, IF FLOAT should be used whenever any kind of number is - acceptable, whereas IF INTEGER (or IF NUMERIC) when only an integer - can be used. - - [ [405]Top ] [ [406]Contents ] [ [407]C-Kermit Home ] [ [408]Kermit - Home ] - _________________________________________________________________ - - 8.4. The ON_UNKNOWN_COMMAND Macro - - The new ON_UNKNOWN_COMMAND macro, if defined, is executed whenever you - give a command that is not known to C-Kermit; any operands are passed - as arguments. Here are some sample definitions: - - DEF ON_UNKNOWN_COMMAND telnet \%1 ; Treat unknown commands as hostnames - DEF ON_UNKNOWN_COMMAND dial \%1 ; Treat unknown commands phone numbers - DEF ON_UNKNOWN_COMMAND take \%1 ; Treat unknown commands as filenames - DEF ON_UNKNOWN_COMMAND !\%* ; Treat unknown commands as shell commands - - The ON_CD macro, if defined, is executed whenever Kermit is given a CD - (change directory) command (8.0.211). Upon entry to this macro, the - directory has already changed and the new directory string is - available in the \v(directory) variable, and also as the first - argument (\%1). - - [ [409]Top ] [ [410]Contents ] [ [411]C-Kermit Home ] [ [412]Kermit - Home ] - _________________________________________________________________ - - 8.5. The SHOW MACRO Command - - The SHOW MACRO command has been changed to accept more than one macro - name: - - (setq a 1 b 2 c 3) - show mac a b c - a = 1 - b = 2 - c = 3 - - An exact match is required for each name (except that case doesn't - matter). If you include wildcard characters, however, a pattern match - is performed: - - show mac [a-c]*x - - shows all macros whose names start with a, b, or c, and end with x. - - [ [413]Top ] [ [414]Contents ] [ [415]C-Kermit Home ] [ [416]Kermit - Home ] - _________________________________________________________________ - - 8.6. Arrays - - A clarification regarding references to array names (as opposed to - array elements): You can use array-name "abbreviations" like &a only - in contexts that expect array names, like ARRAY commands or array-name - function arguments such as the second argument of \fsplit(). In a - LOCAL statement, however, you have to write \&a[], since "local &a" - might refer to a macro named "&a". - - In function arguments, however, you MUST use the abbreviated form: - \fsplit(\%a,&a) or \fsplit(\%a,&a[]). If you include the backslash (as - in "\fsplit(\%a,\&a[])") a parse error occurs. - - Here are the new array-related commands: - - IF DECLARED arrayname - Allows a script to test whether an array has been declared. The - arrayname can be a non-array backslash variable such as \%1 or - \m(name), in which case it is evaluated first, and the result - is treated as the array name. Otherwise, arrayname is treated - as in the ARRAY commands: it can be a, &a, &a[], \&a, \&a[], - \&a[3], \&a[3:9], etc, with the appropriate results in each - case. Synonym: IF DCL. - - UNDECLARE arrayname - UNDECLARE is a new top-level command to undeclare an array. - Previously this could only be done with "declare \&a[0]" (i.e. - re-declare the array with a dimension of 0). - - ARRAY LINK linkname arrayname - Creates a symbolic link from the array named by linkname (which - must be the name of an array that is not yet declared in the - current context) to the array named by arrayname (which must - the name of a currently declared array that is not itself a - link, or a variable containing the name of such an array). The - two names indicate the same array: if you change an array - element, the change is reflected in the link too, and vice - versa. If you undeclare the link, the real array is unaffected. - If you undeclare the real array, all links to it disappear. If - you resize an array (directly or through a link), all links to - it are updated automatically. - - Array links let you pass array names as arguments to macros. For - example, suppose you had a program that needed to uppercase all the - elements of different arrays at different times. You could write a - macro to do this, with the array name as an argument. But without - array links, there would be no way to refer to the argument array - within the macro. Array links make it easy: - - define arrayupper { - local \&e[] \%i - array link \&e[] \%1 - for i 1 \fdim(&e) 1 { .\&e[i] := \fupper(\&e[i]) } - } - declare \&a[] = these are some words - arrayupper &a - show array &a - - The macro declares the array link LOCAL, which means it doesn't - conflict with any array of the same name that might exist outside the - macro, and that the link is destroyed automatically when the macro - exits. This works, by the way, even if the link name and the macro - argument name are the same, as long as the link is declared LOCAL. - - As noted, you can't make a link to a nonexistent array. So when - writing a macro whose job is to create an array whose name is passed - as an argument, you must declare the array first (the size doesn't - matter as long as it's greater than 0). Example: - - define tryme { ; Demonstration macro - local \&e[] ; We only need this inside the macro - array link \&e[] \%1 ; Make local link - shift ; Shift argument list - void \fsplit(\%*,&e) ; Split remainder of arg list into array - } - declare \&a[1] ; Declare target array in advance - tryme &a here are some words ; Invoke the macro with array name and words - show array a ; See the results - - One final improvement allows the macro itself to declare the array - (this was not possible in earlier Kermit releases): if the array name - in the DECLARE command is a variable (and not an array name), or - includes variables, the resulting value is used as the array name. So: - - define tryme { ; Demonstration macro - declare \%1[1] ; Preliminary declaration for target array - local \&e[] ; We only need this inside the macro - array link \&e[] \%1 ; Make local link - shift ; Shift argument list - void \fsplit(\%*,&e) ; Split remainder of arg list into array - } - tryme &a here are some words ; Invoke the macro with array name and words - show array a ; See the results - - The SHOW ARRAY command now indicates whether an array name is a link. - - Also see the descriptions of [417]\fjoin() and [418]\fsplit(), plus - [419]Section 8.10 on the MINPUT command, which shows how an entire - array (or segment of it) can be used as the MINPUT target list. - - [ [420]Top ] [ [421]Contents ] [ [422]C-Kermit Home ] [ [423]Kermit - Home ] - _________________________________________________________________ - - 8.7. New or Improved Built-in Variables and Functions - - The following new built-in variables are available: - - \v(buildid) A date string like "20000808" indicating when C-Kermit was -built. - \v(ftime) Current time, secs since midnight, including fraction of se -cond. - \v(iprompt) The current SET PROMPT value - \v(sexp) The most recent S-Expression (see [424]Section 9) - \v(sdepth) The current S-Expression invocation depth ([425]Section 9) - \v(svalue) The value of the most recent S-Expression ([426]Section 9) - - \v(ftp_code) Most recent FTP response code ([427]Section 3) - \v(ftp_connected) FTP connection status ([428]Section 3) - \v(ftp_cpl) FTP Command Protection Level ([429]Section 3.2) - \v(ftp_dpl) FTP Data Protection Level ([430]Section 3.2) - \v(ftp_getputremote) The current SET GET-PUT-REMOTE setting ([431]Section 3.8 -) - \v(ftp_host) Name or IP address of FTP server ([432]Section 3) - \v(ftp_loggedin) FTP login status ([433]Section 3) - \v(ftp_message) Most recent FTP response message ([434]Section 3) - \v(ftp_security) FTP Security method ([435]Section 3.2) - \v(ftp_server) OS type of FTP server ([436]Section 3) - - \v(http_code) Most recent HTTP response code - \v(http_connected) HTTP connection status - \v(http_host) Name or IP address of HTTP server - \v(http_message) Most recent HTTP response message - \v(http_security) TLS cipher used to secure the HTTP session - - \v(hour) Hour of the day, 0 to 23. - \v(timestamp) Equivalent to "\v(ndate) \v(time)". - - \v(log_debug) Current debug log file, if any. - \v(log_packet) Current packet log file, if any. - \v(log_session) Current session log file, if any. - \v(log_transaction) Current transaction log file, if any. - \v(log_connection) Current connection log file, if any. - - The following new or improved built-in functions are available: - - \fcmdstack() Allows programmatic access to the command stack. - \fcvtdate() [437]Section 8.13, format options added - \fdelta2secs() [438]Section 8.13 - \fdostounixpath(s1) Converts a DOS filename to Unix format. - \fsplit() Now allows grouping/nesting in source string. - \fword() Allows the same grouping and nesting. - \fjoin(&a,s1,n1,n2) Copies an array into a single string. - \fsubstitute(s1,s2,s3) Substitutes characters within a string. - \freplace() Has new 4th "occurrence" argument. - \fsexpression() Evaluates an S-Expression (explained in [439]Section -9). - \ftrim(), \fltrim() Now trim CR and LF by default, as well as SP and Tab. - \funixtodospath(s1) Converts a Unix filename to DOS format. - \fkeywordval(s1,c1) Assigns values to keywords (macros) (explained below) -. - - Most functions that have "2" in their names to stand for the word "to" - can now also be written with "to", e.g. "\fdelta2secs()," - \fdeltatosecs()." - - \funtabify(string) - (New to 8.0.211) Replaces Horizontal Tab characters in the - given string with spaces based on VT100-like tab stops. - - \fverify(s1,s2,n) - As of version 8.0.211, returns -1 if s2 is an empty string. - Previously it returned 0, making \fverify(abc,\%a) look as if - \%a was a string combosed of a's, b's, and/or c's when in fact - it contained nothing. - - \fcode(string) - As of version 8.0.211, returns 0 if string is empty or missing. - Previously it returned the empty string, which made it unsafe - to use in arithmetic or boolean expressions. - - \v(inscale) - New to version 8.0.211, its value is the INPUT SCALE-FACTOR - ([440]Section 8.10), default 1.0. - - 8.7.1. The \fkeywordval() Function - - \fkeywordval(s1,c1) is new to C-Kermit 8.0. Given a string s1 of the - form "name=value", it creates a macro with the given name and assigns - it the given value. If no value appears after the equal sign, any - existing macro of the given name is undefined. Blanks are - automatically trimmed from around the name and value. The optional c1 - parameter is the assignment operator character, equal sign (=) by - default. This function is handy for processing keyword parameters or - any other form of parameter-value pair. Suppose, for example, you want - to write a macro that accepts keyword parameters rather than - positional ones: - - define MYDIAL { - local \%i modem hangup method device speed number - def number 5551234 ; Assign default parameter values - def speed 57600 - def modem usrobotics - def hangup rs232 - def method tone - def country 1 - for \%i 1 \v(argc)-1 1 { ; Parse any keyword parameters... - if not \fkeywordval(\&_[\%i]) end 1 Bad parameter: "\&_[\%i]" - } - set dial country \m(country) - set modem type \m(modem) - set modem hang \m(hangup) - set dial method \m(tone) - set line \m(device) - if fail stop 1 - set speed \m(speed) - if fail stop 1 - show comm - set dial display on - dial \m(number) - if success connect - } - - In this example, all the defaults are set up inside the macro, and - therefore it can be invoked with no parameters at all. But if you want - to have the macro dial a different number, you can supply it as - follows: - - mydial number=7654321 - - You can supply any number of keyword parameters, and you can give them - in any order: - - mydial number=7654321 hangup=modem speed=115200 - - 8.7.2. The \fsplit(), \fjoin(), and \fword() Functions - - \fjoin(&a,s1,n1,n2) is also new; it creates a string from an array (or - a piece of one). &a is the name of the array (a range specifier can be - included); s1 is a character or string to separate each element in the - result string (can be omitted, in which case the elements are not - separated at all), and n1 is a grouping mask, explained below. If s1 - is empty or not specified, the array elements are separated with - spaces. If you want the elements concatenated with no separator, - include a nonzero n2 argument. Given the array: - - declare \&a[] = 0 1 2 3 4 5 6 7 8 9 - - you can get effects like this: - - \fjoin(&a) 0 1 2 3 4 5 6 7 8 9 - \fjoin(&a,:) 0:1:2:3:4:5:6:7:8:9 - \fjoin(&a,{,}) 0,1,2,3,4,5,6,7,8,9 - \fjoin(&a,...) 0...1...2...3...4...5...6...7...8...9 - \fjoin(&a,,,1) 0123456789 - - \fsplit(), \fword(), \fstripb(), and \fjoin() accept a "grouping mask" - argument, n1, which is a number from 0 to 63, in which: - - 1 = "" doublequotes - 2 = {} braces - 4 = '' singlequotes - 8 = () parentheses - 16 = [] square brackets - 32 = <> angle brackets - - These can be OR'd (added) together to make any number 0-63 (-1 is - treated the same as 63, 0 means no grouping). If a bit is on, the - corresponding kind of grouping is selected. (If more than 1 bit is set - for \fjoin(), only the lowest-order one is used.) - - If you include the same character in the grouping mask and the include - list, the grouping mask takes precedence. Example: - - def \%a a "b c d" e - \fsplit(\%a,&a[],,,-1) = 3 <-- doublequote used for grouping - \fsplit(\%a,&a[],,",-1) = 3 <-- doublequote still used for grouping - - Nesting of matched left and right grouping characters (parentheses, - braces, and brackets, but not quotes) is recognized. Example: - - def \%a a (b c n o) p - \fsplit(\%a,&a,,,0) = 16 (no grouping) - \fsplit(\%a,&a,,,2) = 15 (braces only) - \fsplit(\%a,&a,,,16) = 11 (square brackets only) - \fsplit(\%a,&a,,,32) = 7 (angle brackets only) - \fsplit(\%a,&a,,,63) = 3 (all) - \fsplit(\%a,&a,,,-1) = 3 (all) - - \fsplit() and \fjoin() are "reciprocal" functions. You can split a - string up into an array and join it back into a new string that is - equivalent, as long as \fsplit() and \fjoin() are given equivalent - grouping masks, except that the type of braces might change. Example: - - def \%a a {b c [d e] f g} "h i" j m - echo STRING=[\%a] - echo WORDS=\fsplit(\%a,&a,,,-1) - show array a - asg \%b \fjoin(&a,{ },2) - echo JOIN =[\%b] - echo WORDS=\fsplit(\%b,&b,,,-1) - show array b - - The arrays a and b are identical. The strings a and b are as follows: - - \%a: a {b c [d e] f g} "h i" j m - \%b: a {b c [d e] f g} {h i} j {k l} m - - It is possible to quote separator grouping characters with backslash - to override their grouping function. And of course to include - backslash itself in the string, it must be quoted too. Furthermore, - each backslash must be doubled, so the command parser will still pass - one backslash to \fsplit() for each two that it sees. Here are some - examples using \fsplit() with a grouping mask of 8 (treat parentheses - as grouping characters). - - String Result - a b c d e f 6 - a b\\ c d e f 5 - a b (c d e) f 4 - a b \\(c d e\\) f 6 - a b \\\\(c d e\\\\) f 7 - - \fsplit() has also been changed to create its array (if one is given) - each time it is called, so now it can be conveniently called in a loop - without having to redeclare the array each time. - - Incidentally... Sometimes you might want to invoke \fsplit() in a - situation where you don't care about its return value, e.g. when you - just want to fill the array. Now you can "call" \fsplit() or any other - function with the new [441]VOID command: - - void \fsplit(\%a,&a) - - \fsplit() and \fjoin() also accept a new, optional 6th argument, an - options flag, a number that can specify a number of options. So far - there is just one option, whose value is 1: - - separator-flag - Normally separators are collapsed. So, for example, - - \fword(Three little words,2) - - returns "little" (the second word). Space is a separator, but - there are multiple spaces between each word. If the value 1 is - included in the option flag, however, each separator counts. If - two separators are adjacent, an empty word is produced between - them. This is useful for parsing (e.g.) comma-separated lists - exported from databases or spreadsheets. - - 8.7.3. The \fcmdstack() Function - - The new \fcmdstack() function gives access to the command stack: - - \fcmdstack(n1,n2) - Arguments: n1 is the command stack level. If omitted, the - current level, \v(cmdlevel), is used. n2 is a function code - specifying the desired type of information: - - 0 (default) = name of object at level n1. - 1 (nonzero) = object type (0 = prompt; 1 = command file; 2 = macro). - - The default for n2 is 0. - - The name associated with prompt is "(prompt)". Here's a loop that can - be included in a macro or command file to show the stack (similar to - what the SHOW STACK command does): - - for \%i \v(cmdlevel) 0 -1 { - echo \%i. [\fcmdstack(\%i,1)] \fcmdstack(\%i,0) - } - - In this connection, note that \v(cmdfile) always indicates the most - recently invoked active command file (if any), even if that file is - executing a macro. Similarly, \v(macro) indicates the most recently - invoked macro (if any), even if the current command source is not a - macro. The name of the "caller" of the currently executing object - (command file or macro) is: - - \fcmdstack(\v(cmdlevel)-1) - - and its type is: - - \fcmdstack(\v(cmdlevel)-1,1) - - To find the name of the macro that invoked the currently executing - object, even if one or more intermediate command files (or prompting - levels) are involved, use a loop like this: - - for \%i \v(cmdlevel)-1 0 -1 { - if = \fcmdstack(\%i,1) 2 echo CALLER = \fcmdstack(\%i,0) - } - - Of course if you make a macro to do this, the macro must account for - its own additional level: - - define CALLER { - for \%i \v(cmdlevel)-2 0 -1 { - if = \fcmdstack(\%i,1) 2 return \fcmdstack(\%i,0) - } - return "(none)" - } - - The built-in variable \v(cmdsource) gives the current command source - as a word ("prompt", "file", or "macro"). - - 8.7.4. The VOID Command - - VOID is like ECHO in that all functions and variables in its argument - text are evaluated. but it doesn't print anything (except possibly an - error message if a function was invocation contained or resulted in - any errors). VOID sets FAILURE if it encounters any errors, SUCCESS - otherwise. - - [ [442]Top ] [ [443]Contents ] [ [444]C-Kermit Home ] [ [445]Kermit - Home ] - _________________________________________________________________ - - 8.8. The RETURN and END Commands - - The execution of a macro is terminated in any of the following ways: - - * With an END [ number [ message ] ] command. If a number is given, - the macro succeeds if the number is 0, and fails if it is not - zero; if a number is not given, the macro succeeds. - * With a STOP command, which works just like END except it peels - back the command stack all the way to top level. - * With a RETURN [ text ] command, in which case the macro always - succeeds. - * By running out of commands to execute, in which case the macro - succeeds or fails according the most recently executed command - that sets success or failure. - - The same considerations apply to command files invoked by the TAKE - command. - - If a macro does not execute any commands that set success or failure, - then invoking the macro does not change the current SUCCESS/FAILURE - status. It follows, then, that the mere invocation of a macro does not - change the SUCCESS/FAILURE status either. This makes it possible to - write macros to react to the status of other commands (or macros), for - example: - - define CHKLINE { - if success end 0 - stop 1 SET LINE failed - please try another device. - } - set modem type usrobotics - set line /dev/cua0 - chkline - set speed 57600 - dial 7654321 - - By the way, none of this is news. But it was not explicitly documented - before, and C-Kermit 7.0 and earlier did not always handle the RETURN - statement as it should have. - - [ [446]Top ] [ [447]Contents ] [ [448]C-Kermit Home ] [ [449]Kermit - Home ] - _________________________________________________________________ - - 8.9. UNDEFINing Groups of Variables - - The UNDEFINE command, which previously accepted one variable name, now - accepts a list of them, and also accepts wildcard notation to allow - deletion of variables that match a given pattern. - - UNDEFINE [ switches ] name [ name [ name [ ... ] ] ] - Undefines the variables whose names are given. Up to 64 names - may be given in one UNDEFINE command. - - If you omit the switches and include only one name, the UNDEFINE - command works as before. - - Switches include: - - /MATCHING - Specifies that the names given are to treated as patterns - rather than literal variable names. Note: pattern matching - can't be used with array references; use the ARRAY command to - manipulate arrays and subarrays. - - /LIST - List the name of each variable to be undefined, and whether it - was undefined successfully ("ok" or "error"), plus a summary - count at the end. - - /SIMULATE - List the names of the variables that would be deleted without - actually deleting them. Implies /LIST. - - The UNDEFINE command fails if there were any errors and succeeds - otherwise. - - The new _UNDEFINE command is like UNDEFINE, except the names are - assumed to be variable names themselves, which contain the names (or - parts of them) of the variables to be undefined. For example, if you - have the following definitions: - - define \%a foo - define foo This is some text - - then: - - undef \%a - - undefines the variable \%a, but: - - _undef \%a - - undefines the macro foo. - - Normal Kermit patterns are used for matching; metacharacters include - asterisk, question mark, braces, and square brackets. Thus, when using - the /MATCHING switch, if the names of the macros you want to undefine - contain any of these characters, you must quote them with backslash to - force them to be taken literally. Also note that \%* is not the name - of a variable; it is a special notation used within a macro for "all - my arguments". The command "undef /match \%*" deletes all \%x - variables, where x is 0..9 and a..z. Use "undef /match \%[0-9]" to - delete macro argument variables or "undef /match \%[i-n]" to delete a - range of \%x variables. - - [ [450]Top ] [ [451]Contents ] [ [452]C-Kermit Home ] [ [453]Kermit - Home ] - _________________________________________________________________ - - 8.10. The INPUT and MINPUT Commands - - As of C-Kermit 8.0.211, the INPUT and MINPUT commands accept a switch: - - [M]INPUT /NOMATCH timeout - The /NOMATCH switch allows INPUT or MINPUT to read incoming - material for the specified amount of time, without attempting - to match it with any text or patterns. When this switch is - included, the [M]INPUT command succeeds when the timeout - interval expires, with \v(instatus) set to 1, meaning "timed - out", or fails upon interruption or i/o error. - - Also in version 8.0.211, there is a new way to apply a scale factor to - [M]INPUT timeouts: - - SET INPUT SCALE-FACTOR floating-point-number - This scales all [M]INPUT timeouts by the given factor, allowing - time-sensitive scripts to be adjusted to changing conditions - such as congested networks or different-speed modems without - having to change each INPUT-class command. This affects only - those timeouts that are given in seconds, not as wall-clock - times. Although the scale factor can have a fractional part, - the INPUT timeout is still an integer. The new built-in - variable \v(inscale) tells the current INPUT SCALE-FACTOR. - - The MINPUT command can be used to search the incoming data stream for - several targets simultaneously. For example: - - MINPUT 8 one two three - - waits up to 8 seconds for one of the words "one", "two", or "three" to - arrive. Words can be grouped to indicate targets that contain spaces: - - MINPUT 8 nineteeen twenty "twenty one" - - And of course you can also use variables in place of (or as part of) - the target names: - - MINPUT 8 \%a \&x[3] \m(foo) - - Until now you had to know the number of targets in advance when - writing the MINPUT statement. Each of the examples above has exactly - three targets. - - But suppose your script needs to look for a variable number of - targets. For this you can use arrays and \fjoin(), described in - [454]Section 8.7. Any number of \fjoin() invocations can be included - in the MINPUT target list, and each one is expanded into the - appropriate number of separate targets each time the MINPUT command is - executed. Example: - - declare \&a[10] = one two three - minput 10 foo \fjoin(&a) bar - - This declares an array of ten elements, and assigns values to the - first three of them. The MINPUT command looks for these three (as well - as the words "foo" and "bar"). Later, if you assign additional - elements to the array, the same MINPUT command also looks for the new - elements. - - If an array element contains spaces, each word becomes a separate - target. To create one target per array element, use \fjoin()'s - grouping feature: - - dcl \&a[] = {aaa bbb} {ccc ddd} {xxx yyy zzz} - - minput 10 \fjoin(&a) <-- 7 targets - minput 10 \fjoin(&a,,2) <-- 3 targets - - [ [455]Top ] [ [456]Contents ] [ [457]C-Kermit Home ] [ [458]Kermit - Home ] - _________________________________________________________________ - - 8.11. Learned Scripts - - C-Kermit now includes a simple script recorder that monitors your - commands, plus your actions during CONNECT mode, and automatically - generates a script program that mimics what it observed. You should - think of this feature as a script-writing ASSISTANT since, as you will - see [459]later in this section, the result generally needs some - editing to make it both secure and flexible. The script recorder is - controlled by the new LEARN command: - - LEARN [ /ON /OFF /CLOSE ] [ filename ] - If you give a filename, the file is opened for subsequent - recording. The /ON switch enables recording to the current file - (if any); /OFF disables recording. /CLOSE closes the current - script recording file (if any). If you give a filename without - any switches, /ON is assumed. - - The /OFF and /ON switches let you turn recording off and on during a - session without closing the file. - - When recording: - - * All commands that you type (or recall) at the prompt are recorded - in the file except: - + LEARN commands are not recorded. - + The CONNECT command is not recorded. - + The TELNET command is converted to SET HOST /NETWORK:TCP. - * Commands obtained from macros or command files are not recorded. - * During CONNECT: - + Every line you type is converted to an OUTPUT command. - + The last prompt before any line you type becomes an INPUT - command. - + Timeouts are calculated automatically for each INPUT command. - + A PAUSE command is inserted before each OUTPUT command just - to be safe. - - Thus the script recorder is inherently line-oriented. It can't be used - to script character-oriented interactions like typing Space to a - "More?" prompt or editing a text file with VI or EMACS. - - But it has advantages too; for example it takes control characters - into account that might not be visible to you otherwise, and it - automatically converts control characters in both the input and output - streams to the appropriate notation. It can tell, for example that the - "$ " prompt on the left margin in UNIX is really {\{13}\{10}$ }, - whereas in VMS it might be {\{13}\{10}\{13}$ }. These sequences are - detected and recorded automatically. - - A learned script should execute correctly when you give a TAKE command - for it. However, it is usually appropriate to edit the script a bit. - The most important change would be to remove any passwords from it. - For example, if the script contains: - - INPUT 9 {\{13}\{10}Password: } - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT bigsecret\{13} - - you should replace this by something like: - - INPUT 9 {\{13}\{10}Password: } - IF FAIL STOP 1 INPUT timeout - ASKQ pswd Please type your password: - PAUSE 1 - OUTPUT \m(pswd)\{13} - - The LEARN command can't do this for you since it knows nothing about - "content"; it only knows about lines and can't be expected to parse or - understand them -- after all, the Password prompt might be in some - other language. So remember: if you use the LEARN command to record a - login script, be sure edit the resulting file to remove any passwords. - Also be sure to delete any backup copies your editor or OS might have - made of the file. - - Other manual adjustments might also be appropriate: - - * If the target of an INPUT command can vary, you can replace the - INPUT command with MINPUT and the appropriate target list, and/or - the target with a \fpattern(). For example, suppose you are - dialing a number that can be answered by any one of 100 terminal - servers, whose prompts are ts-00>, ts-01>, ts-02>, ... ts-99>. The - script records a particular one of these, but you want it to work - for all of them, so change (e.g.): - INPUT 10 ts-23> ; or whatever - to: - INPUT 10 \fpattern(ts-[0-9][0-9]>) - * The INPUT timeout values are conservative, but they are based only - on a single observation; you might need to tune them. - * The PAUSE commands might not be necessary, or the PAUSE interval - might need adjustment. - * In case you made typographical errors during recording, they are - incorporated in your script; you can edit them out if you want to. - - Here is a sample script generated by Kermit ("learn vms.ksc") in which - a Telnet connection is made to a VMS computer, the user logs in, - starts Kermit on VMS, sends it a file, and then logs out: - - ; Scriptfile: vms.ksc - ; Directory: /usr/olga - ; Recorded: 20001124 15:21:23 - - SET HOST /NETWORK:TCP vms.xyzcorp.com - IF FAIL STOP 1 Connection failed - - INPUT 7 {\{13}\{10}\{13}Username: } - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT olga\{13} - INPUT 3 {\{13}\{10}\{13}Password: } - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT secret\{13} - INPUT 18 {\{13}\{10}\{13}$ } - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT set default [.incoming]\{13} - INPUT 12 {\{13}\{10}\{13}$ } - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT kermit\{13} - INPUT 15 {\{13}\{10}\{13}ALTO:[OLGA.INCOMING] C-Kermit>} - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT receive\{13} - send myfile.txt - - INPUT 18 {\{13}\{10}\{13}ALTO:[OLGA.INCOMING] C-Kermit>} - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT exit\{13} - INPUT 6 {\{13}\{10}\{13}$ } - IF FAIL STOP 1 INPUT timeout - PAUSE 1 - OUTPUT logout\{13} - close - exit - - The commands generated by Kermit during CONNECT (INPUT, IF FAIL, - PAUSE, and OUTPUT) have uppercase keywords; the commands typed by the - user are in whatever form the user typed them (in this case, - lowercase). - - [ [460]Top ] [ [461]Contents ] [ [462]C-Kermit Home ] [ [463]Kermit - Home ] - _________________________________________________________________ - - 8.12. Pattern Matching - - A pattern is a character string that is used to match other strings. - Patterns can contain metacharacters that represent special actions - like "match any single character", "match zero or more characters", - "match any single character from a list", and so on. The best known - application of patterns is in file specifications that contain - wildcards, as in "send *.txt", meaning "send all files whose names end - with .txt". - - Patterns are also used in increasingly many other ways, to the extent - it is useful to point out certain important distinctions in the ways - in which they are used: - - Anchored Patterns - If an anchored pattern does not begin with "*", it must match - the beginning of the string, and if it does not end with "*", - it must match the end of the string. For example, the anchored - pattern "abc" matches only the string "abc", not "abcde" or - "xyzabc" or "abcabc". The anchored pattern "abc*" matches any - string that starts with "abc"; the anchored pattern "*abc" - matches any string that ends with "abc"; the anchored pattern - "*abc*" matches any string that contains "abc" (including any - that start and/or end with it). - - Floating Patterns - A floating pattern matches any string that contains a substring - that matches the pattern. In other words, a floating pattern - has an implied "*" at the beginning and end. You can anchor a - floating pattern to the beginning by starting it with "^", and - you can anchor it to the end by ending it with "$" (see - examples below). - - Wildcards - A wildcard is an anchored pattern that has the additional - property that "*" does not match directory separators. - - This terminology lets us describe Kermit's commands with a bit more - precision. When a pattern is used for matching filenames, it is a - wildcard, except in the TEXT-PATTERNS and BINARY-PATTERNS lists and - /EXCEPT: clauses, in which case directory separators are not - significant (for example, a BINARY-PATTERN of "*.exe" matches any file - whose name ends in .exe, no matter how deeply it might be buried in - subdirectories). When Kermit parses a file specification directly, - however, it uses the strict wildcard definition. For example, "send - a*b" sends all files whose names start with "a" and end with "b" in - the current directory, and not any files whose names end with "b" that - happen to be in subdirectories whose names start with "a". And as - noted, wildcards are anchored, so "delete foo" deletes the file named - "foo", and not all files whose names happen to contain "foo". - - Most other patterns are anchored. For example: - - if match abc bc ... - - does not succeed (and you would be surprised if it did!). In fact, the - only floating patterns are the ones used by commands or functions that - search for patterns in files, arrays, or strings. These include: - - * The GREP and TYPE /MATCH commands. - * The \fsearch(), \frsearch(), and \farraylook() functions. - - Thus these are the only contexts in which explicit anchors ("^" and - "$") may be used: - - grep abc *.txt - Prints all lines containing "abc" in all files whose names end - with ".txt". - - grep ^abc *.txt - Prints all lines that start with "abc" in all ".txt" files. - - grep abc$ *.txt - Prints all lines that end with "abc" in all ".txt" files. - - grep ^a*z$ *.txt - Prints all lines that start with "a" and end with "z" in all - ".txt" files. - - Similarly for TYPE /PAGE, /fsearch(), /frsearch(), and \farraylook(). - - Here is a brief summary of anchored and floating pattern equivalences: - - Anchored Floating - abc ^abc$ - *abc abc$ - abc* ^abc - *abc* abc - - [ [464]Top ] [ [465]Contents ] [ [466]C-Kermit Home ] [ [467]Kermit - Home ] - _________________________________________________________________ - - 8.13. Dates and Times - - C-Kermit's comprehension of date-time formats is considerably expanded - in version 8.0. Any command that reads dates, including the DATE - command itself, or any switch, such as the /BEFORE: and /AFTER: - switches, or any function such as \fcvtdate(), now can understand - dates and times expressed in any ISO 8601 format, in Unix "asctime" - format, in FTP MDTM format, and in practically any format used in RFC - 822 or RFC 2822 electronic mail, with or without timezones, and in a - great many other formats as well. HELP DATE briefly summarizes the - acceptable date-time formats. - - Furthermore, C-Kermit 8.0 includes a new and easy-to-use form of - date-time arithmetic, in which any date or time can be combined with a - "delta time", to add or subtract the desired time interval (years, - months, weeks, days, hours, minutes, seconds) to/from the given date. - And new functions are available to compare dates and to compute their - differences. - - As you can imagine, all this requires quite a bit of "syntax". The - basic format is: - - [ date ] [ time ] [ delta ] - - Each field is optional, but in most cases (depending on the context) - there must be at least one field. If a date is given, it must come - first. If no date is given, the current date is assumed. If no time is - given, an appropriate time is supplied depending on whether a date was - supplied. If no delta is given, no arithmetic is done. If a delta is - given without a date or time, the current date and time are used as - the base. - - Date-time-delta fields are likely to contain spaces (although they - need not; space-free forms are always available). Therefore, in most - contexts -- and notably as switch arguments -- date-time information - must be enclosed in braces or doublequotes, for example: - - send /after:"8-Aug-2001 12:00 UTC" *.txt - - Kermit's standard internal format for dates and times is: - - yyyymmdd hh:mm:ss - - for example: - - 20010208 10:28:01 - - Date-times can always be given in this format. yyyy is the 4-digit - year, mm is the two-digit month (1-12; supply leading zero for - Jan-Sep), dd is the 2-digit day (leading zero for 1-9), hh is the hour - (0-23), mm the minute (0-59), ss the second (0-59), each with leading - zero if less than the field width. The date and time can be separated - by a space, an underscore, a colon, or the letter T. The time is in - 24-hour format. Thus the various quantites are at the following fixed - positions: - -Position Contents - 1-4 Year (4 digits, 0000-9999) - 5-6 Month (2 digits, 1-12) - 7-8 Day (2 digits, 1-31) - 9 Date-Time Separator (space, :, _, or the letter T) - 10-11 Hour (2 digits, 0-23) - 12 Hour-Minute Separator (colon) - 13-14 Minute (2 digits, 0-59) - 15 Minute-Second Separator (colon) - 16-17 Second (2 digits, 0-59) - - Example: - - 19800526 13:07:12 26 May 1980, 13:07:12 (1:07:12PM) - - This is the format produced by the DATE command and by any function - that returns a date-time. It is suitable for lexical comparison and - sorting, and for use as a date-time in any Kermit command. When this - format is given as input to a command or function, various date-time - separators (as noted) are accepted: - - 19800526 13:07:12 26 May 1980, 13:07:12 (1:07:12PM) - 20010208_10:28:35 2 February 2001, 10:28:35 AM - 18580101:12:00:00 1 January 1858, noon - 20110208T00:00:00 2 February 2011, midnight - - Certain other special date-time formats that are encountered on - computer networks are recognized: - - Asctime Format - This is a fixed format used by Unix, named after Unix's - asctime() ("ASCII time") function. It is always exactly 24 - characters long. Example: Fri Aug 10 16:38:01 2001 - - Asctime with Timezone - This is like Asctime format, but includes a 3-character - timezone between the time and year. It is exactly 28 characters - long. Example: Fri Aug 10 16:38:01 GMT 2001 - - E-Mail Format - E-mail date-time formats are defined in [468]RFC 2822 with a - fair amount of flexibility and options. The following examples - are typical of e-mails and HTTP (web-page) headers: - - Sat, 14 Jul 2001 11:49:29 (No timezone) - Fri, 24 Mar 2000 14:19:59 EST (Symbolic timezone) - Tue, 26 Jun 2001 10:19:45 -0400 (EDT) (GMT Offset + comment) - - FTP MDTM Format - This is the date-time format supplied by FTP servers that - support the (not yet standard but widely used nevertheless) - MDTM command, by which the FTP client asks for a file's - modification time: - - yyyymmddhhmmss[.ffff] - - where yyyy is the 4-digit year, mm is the 2-digit month, and so - on, exactly 14 digits long. An optional fractional part - (fraction of second) may also be included, separated by a - decimal point (period). Kermit rounds to the nearest second. - Example: - - 20020208102835.515 (8 February 2002 10:28:36 AM) - - 8.13.1. The Date - - The date, if given, must precede the time and/or delta, and can be in - many, many formats. For starters, you can use several symbolic date - names in place of actual dates: - - NOW - This is replaced by the current date and time. The time can not - be overriden (if you want to supply a specific time, use TODAY - rather than NOW). - - TODAY - This is replaced by the current date and a default time of - 00:00:00 is supplied, but can be overridden by a specific time; - for example, if today is 8 February 2002, then "TODAY" is - "20020802 00:00:00" but "TODAY 10:28" is "20020802 10:28:00". - - TOMORROW - Like TODAY, but one day later (if today is 8 February 2002, - then "TOMORROW" is "20020803 00:00:00" but "TOMORROW 16:30" is - "20020803 16:30:00"). - - YESTERDAY - Like TODAY, but one day earlier. - - MONDAY, TUESDAY, WEDNESDAY, ..., SUNDAY - The date on the given day of the week, today or later. A - default time of 00:00:00 is supplied but can be overridden. - Example: "SATURDAY 12:00" means next Saturday (or today, if - today is Saturday) at noon. - - You can give an explicit date in almost any conceivable format, but - there are some rules: - - * If a date is given, it must have three fields: day, month, and - year; the order can vary (except that the month can not be last). - * If names are used for days, months, etc, they must be English. - * The year must lie between 0000 and 9999, inclusive. - * All calendar calculations use Gregorian dating, so calculated - dates for years prior to 1582 (or later, depending on the country) - will not agree with historical dates. Other forms of dating (e.g. - Hebrew, Chinese) are not supported. - - Various date-field separators are accepted: hyphen, slash, space, - underscore, period. The same field separator (if any) must be used in - both places; for example 18-Sep-2001 but not 18-Sep/2001. Months can - be numeric (1-12) or English names or abbreviations. Month name - abbreviations are normally three letters, e.g. Apr, May, Jun, Jul. - Capitalization doesn't matter. - - Here are a few examples: - - 18 Sep 2001 (English month, abbreviated) - 18 September 2001 (English month, spelled out) - 2001 Sept 18 (Year, month, day) - 18-Sep-2001 (With hyphens) - 18/09/2001 (All numeric with slashes) - 18.09.2001 (Ditto, with periods) - 18_09_2001 (Ditto, with underscores) - 09/18/2001 (See below) - 2001/09/18 (See below) - September 18, 2001 (Correspondence style) - Sep-18-2001 (Month-day-year) - 20010918 (Numeric, no separators) - - You can also include the day of the week with a specific date, in - which case it is accepted (if it is a valid day name), but not - verified to agree with the given date: - - Tue, 18 Sep 2001 (Abbreviated, with comma) - Tue,18 Sep 2001 (Comma but no space) - Tue 18 Sep 2001 (Abbreviated, no comma) - Tuesday 18 Sep 2001 (Spelled out) - Tuesday, 18 Sep 2001 (etc) - Friday, 18 Sep 2001 (Accepted even if not Friday) - - In all-numeric dates with the year last, such as 18/09/2001, Kermit - identifies the year because it's 4 digits, then decides which of the - other two numbers is the month or day based on its value. If both are - 12 or less and are unequal, the date is ambiguous and is rejected. In - all-numeric dates with the year first, the second field is always the - month and the third is the day. The month never comes last. A date - with no separators is accepted only if it is all numeric and has - exactly eight digits, and is assumed to be in yyyymmdd format. - - 20010918 (18-Sep-2001 00:00:00) - - or 14 digits (as in FTP MDTM format): - - 20010918123456 (18-Sep-2001 12:34:56) - - You can always avoid ambiguity by putting the year first, or by using - an English, rather than numeric, month. A date such as 09/08/2001 - would be ambiguous but 2001/09/08 is not, nor is 09-Aug-2001. - - Until the late 1990s, it was common to encounter 2-digit years, and - these are found to this day in old e-mails and other documents. Kermit - accepts these dates if they have English months, and interprets them - according to the windowing rules of [469]RFC 2822: "If a two digit - year is encountered whose value is between 00 and 49, the year is - interpreted by adding 2000, ending up with a value between 2000 and - 2049. If a two digit year is encountered with a value between 50 and - 99, or any three digit year is encountered, the year is interpreted by - adding 1900." - - If you need to specify a year prior to 1000, use leading zeros to - ensure it is not misinterpreted as a "non-Y2K-compliant" modern year: - - 7-Oct-77 (19771007 00:00:00) - 7-Oct-0077 (00771007 00:00:00) - - 8.13.2. The Time - - The basic time format is hh:mm:dd; that is hours, minutes, seconds, - separated by colons, perhaps with an optional fractional second - separated by a decimal point (period). The hours are in 24-hour - format; 12 is noon, 13 is 1pm, and so on. Fields omitted from the - right default to zero. Fields can be omitted from the left or middle - by including the field's terminating colon. Examples: - - 11:59:59 (11:59:59 AM) - 11:59 (11:59:00 AM) - 11 (11:00:00 AM) - 11:59:59.33 (11:59:59 AM) - 11:59:59.66 (Noon) - 03:21:00 (3:21:00 AM) - 3:21:00 (3:21:00 AM) - 15:21:00 (3:21:00 PM) - :21:00 (00:21:00 AM) - ::01 (00:00:01 AM) - 11::59 (11:00:59 AM) - - Leading zeros can be omitted, but it is customary and more readable to - keep them in the minute and second fields: - - 03:02:01 (03:02:01 AM) - 3:02:01 (03:02:01 AM) - 3:2:1 (03:02:01 AM) - - AM/PM notation is accepted if you wish to use it: - - 11:59:59 (11:59:59 AM) - 11:59:59AM (11:59:59 AM) - 11:59:59A.M. (11:59:59 AM) - 11:59:59am (11:59:59 AM) - 11:59:59a.m. (11:59:59 AM) - 11:59:59PM (11:59:59 PM = 23:59:59) - 11:59:59P.M. (11:59:59 PM = 23:59:59) - 11:59:59pm (11:59:59 PM = 23:59:59) - 11:59:59p.m. (11:59:59 PM = 23:59:59) - - You can omit the colons if you wish, in which case Kermit uses the - following rules to interpret the time: - - 1. 6 digits is hh:mm:ss, e.g. 123456 is 12:34:56. - 2. 5 digits is h:mm:ss, e.g. 12345 is 1:23:45. - 3. 4 digits is hh:mm, e.g. 1234 is 12:34. - 4. 3 digits is h:mm, e.g. 123 is 1:23. - 5. 2 digits is hh, e.g. 12 is 12:00. - 6. 1 digit is h (the hour), e.g. 1 is 1:00. - - Examples: - - 1 (01:00:00 AM) - 10 (10:00:00 AM) - 230 (02:30:00 AM) - 230pm (02:30:00 PM = 14:30:00) - 1115 (11:15:00 AM) - 2315 (11:15:00 PM = 23:15:00 PM) - 23150 (02:31:50 AM) - 231500 (23:15:00 PM) - - 8.13.3. Time Zones - - If a time is given, it can (but need not) be followed by a time zone - designator. If no time zone is included, the time is treated as local - time and no timezone conversions are performed. - - The preferred time zone designator is the UTC Offset, as specified in - [470]RFC 2822: a plus sign or minus sign immediately followed by - exactly four decimal digits, signifying the difference in hh (hours) - and mm (minutes) from Universal Coordinated Time (UTC, also known as - Greenwich Mean Time, or GMT), with negative numbers to the West and - positive numbers to the East. For example: - - Fri, 13 Jul 2001 12:54:29 -0700 - - indicates a local time of 12:54:29 that is 07 hours and 00 minutes - behind (less than, East of) Universal Time. The space is optional, so - the example could also be written as: - - Fri, 13 Jul 2001 12:54:29-0700 - - The following symbolic time zones are also accepted, as specified by - [471]RFC 2822 and/or in ISO 8601: - - GMT = +0000 Greenwich Mean Time - Z = +0000 Zulu (Zero Meridian) Time - UTC = +0000 Universal Coordinated Time - UT = +0000 Universal Time - EDT = -0400 Eastern (USA) Daylight Time - EST = -0500 Eastern (USA) Standard Time - CDT = -0500 Central (USA) Daylight Time - CST = -0600 Central (USA) Standard Time - MDT = -0600 Mountain (USA) Daylight Time - MST = -0700 Mountain (USA) Standard Time - PDT = -0700 Pacific (USA) Daylight Time - PST = -0800 Pacific (USA) Standard Time - - Note that GMT, Z, UTC, and UT all express the same concept: standard - (not daylight) time at the Zero Meridian. UTC, by the way, is an - international standard symbol and does not correspond to the order of - the English words, Universal Coordinated Time, but it happens to have - the same initial letters as these words. Of course hundreds of other - symbolic timezones and variations exist, but they are not - standardized, and are therefore not supported by Kermit. - - When a time zone is included with a time, the time is converted to - local time. In case the conversion crosses a midnight boundary, the - date is adjusted accordingly. Examples converting to EST (Eastern USA - Standard Time = -0500): - - 11:30:00 = 11:30:00 - 11:30:00 EST = 11:30:00 - 11:30:00 GMT = 06:30:00 - 11:30:00 PST = 14:30:00 - 11:30:00Z = 06:30:00 - 11:30PM GMT = 18:30:00 - 11:30 -0500 = 11:30:00 - 11:30 -0800 = 08:30:00 - 11:30 +0200 = 04:30:00 - - Unlike most of Kermit's other date-time conversions, timezone - knowledge (specifically, the offset of local time from UTC) is - embodied in the underlying operating system, not in Kermit itself, and - any conversion errors in this department are the fault of the OS. For - example, most UNIX platforms do not perform conversions for years - prior to 1970. - - 8.13.4. Delta Time - - Date/time expressions can be composed of a date and/or time and a - delta time, or a delta time by itself. When a delta time is given by - itself, it is relative to the current local date and time. Delta times - have the following general format: - - {+,-}[number units][hh[:mm[:ss]]] - - In other words, a delta time always starts with a plus or minus sign, - which is followed by a "part1", a "part2", or both. The "part1", if - given, specifies a number of days, weeks, months, or years; "part2" - specifies a time in hh:mm:ss notation. In arithmetic terms, these - represents some number of days or other big time units, and then a - fraction of a day expressed as hours, minutes, and seconds; these are - to be added to or subtracted from the given (or implied) date and - time. The syntax is somewhat flexible, as shown by the following - examples: - - +1 day (Plus one day) - +1day (Ditto) - +1d (Ditto) - + 1 day (Ditto) - + 1 day 3:00 (Plus one day and 3 hours) - +1d3:00 (Ditto) - +1d3 (Ditto) - +3:00:00 (Plus 3 hours) - +3:00 (Ditto) - +3 (Ditto) - +2 days (Plus 2 days) - -12 days 7:14:22 (Minus 12 days, 7 hours, 14 minutes, and 22 seconds) - - The words "week", "month", and "year" can be used like "day" in the - examples above. A week is exactly equivalent to 7 days. When months - are specified, the numeric month number of the date is incremented or - decremented by the given number, and the year and day adjusted - accordingly if necessary (for example, 31-Jan-2001 +1month = - 03-Mar-2001 because February does not have 31 days). When years are - specified, they are added or subtracted to the base year. Examples - (assuming the current date is 10-Aug-2001 and the current time is - 19:21:11): - - 18-Sep-2001 +1day (20010918 00:00:00) - today +1day (20010811 00:00:00) - now+1d (20010811 19:21:11) - + 1 day (20010811 19:21:11) - + 1 day 3:14:42 (20010811 22:35:54) - + 7 weeks (20010928 19:21:11) - +1d3:14:42 (20010811 22:35:54) - +1w3:14:42 (20010817 22:35:54) - +1m3:14:42 (20010910 22:35:54) - +1y3:14:42 (20020810 22:35:54) - 2 feb 2001 + 10 years (20110208 00:00:00) - 2001-02-08 +10y12 (20110208 12:00:00) - 31-dec-1999 23:59:59+00:00:01 (20000101 00:00:00) - 28-feb-1996 +1day (19960229 00:00:00) (leap year) - 28-feb-1997 +1day (19970301 00:00:00) (nonleap year) - 28-feb-1997 +1month (19970328 00:00:00) - 28-feb-1997 +1month 11:59:59 (19970328 11:59:59) - 28-feb-1997 +20years (20170228 00:00:00) - 28-feb-1997 +8000years (99970228 00:00:00) - - For compatibility with VMS, the following special delta-time format is - also accepted: - - +number-hh:mm:ss - -number-hh:mm:ss - - (no spaces). The hyphen after the number indicates days. It - corresponds exactly to the Kermit notation: - - +numberdhh:mm:ss - -numberdhh:mm:ss - - The following forms all indicate exactly the same date and time: - - 18-Sep-2001 12:34:56 +1-3:23:01 - 18-Sep-2001 12:34:56 +1d3:23:01 - 18-Sep-2001 12:34:56 +1 day 3:23:01 - - and mean "add a day plus 3 hours, 23 minutes, and 1 second" to the - given date. - - Note that delta times are not at all the same as UTC offsets; the - former specifies an adjustment to the given date/time and the latter - specifies that the local time is a particular distance from Universal - Time, for example: - - 11-Aug-2001 12:34:56 -0800 (20010811 16:34:56 -- UTC Offset) - 11-Aug-2001 12:34:56 -08:00 (20010811 04:34:56 -- Delta time) - - If you give a time followed by a modifer that starts with a + or - - sign, how does Kermit know whether it's a UTC offset or a delta time? - It is treated as a UTC offset if the sign is followed by exactly four - decimal digits; otherwise it is a delta time. Examples (for USA - Eastern Daylight Time): - - 11-Aug-2001 12:34:56 -0800 (20010811 16:34:56 -- UTC Offset) - 11-Aug-2001 12:34:56 -08:00 (20010811 04:34:56 -- Delta time) - 11-Aug-2001 12:34:56 -800 (20010811 04:34:56 -- Delta time) - 11-Aug-2001 12:34:56 -8 (20010811 04:34:56 -- Delta time) - - The first example says that at some unknown place which is 8 hours - ahead of Universal Time, the time is 12:34:56, and this corresponds to - 16:34:56 in Eastern Daylight time. The second example says to subtract - 8 hours from the local time. The third and fourth are delta times - because, even though a colon is not included, the time does not - consist of exactly 4 digits. - - When a delta time is written after a timezone, however, there is no - ambiguity and no syntax distinction is required: - - 11-Aug-2001 12:34:56 -0800 -0800 (20010811 08:34:56) - 11-Aug-2001 12:34:56 -0800 -08:00 (Ditto) - 11-Aug-2001 12:34:56 -08:00 -08:00 (Illegal) - - 8.13.5. The DATE Command - - Obviously a great many combinations of date, time, time zone, and - delta time are possible, as well as many formatting options. The - purpose of all this flexibility is to comply with as many standards as - possible -- Internet RFCs, ISO standards, and proven corporate - standards -- as well as with notations commonly used by real people, - in order that dates and times from the widest variety of sources can - be assigned to a variable and used in any date-time field in any - Kermit command. - - You can test any date-and/or-time format with the DATE command, which - converts it to standard yyyymmdd hh:mm:ss format if it is understood, - or else gives an explicit error message (rather than just "BAD DATE" - as in previous C-Kermit releases) to indicate what is wrong with it. - Examples (on Tuesday, 31 July 2001 in New York City, Eastern Daylight - Time, UTC -0400): - - DATE command argument Result - 12:30 20010731 12:30:00 - 12:30:01 20010731 12:30:01 - 12:30:01.5 20010731 12:30:02 - 1230 20010731 12:30:00 - 230 20010731 02:30:00 - 230+1d 20010801 02:30:00 - 230+1d3:00 20010801 05:30:00 - 20010718 19:21:15 20010718 19:21:15 - 20010718_192115 20010718 19:21:15 - 20010718T192115 20010718 19:21:15 - 18 Jul 2001 +0400 20010717 23:59:59 - 18 Jul 2001 192115 20010718 19:21:15 - 18 Jul 2001 192115.8 20010718 19:21:16 - 18-Jul-2001T1921 20010718 19:21:00 - 18-Jul-2001 1921Z 20010718 15:21:00 - 18-Jul-2001 1921 GMT 20010718 15:21:00 - 18-Jul-2001 1921 UTC 20010718 15:21:00 - 18-Jul-2001 1921 Z 20010718 15:21:00 - 18-Jul-2001 1921Z 20010718 15:21:00 - 18-Jul-2001 1921 -04:00:00 20010718 19:21:00 - 21-Jul-2001_08:20:00am 20010721 08:20:00 - 21-Jul-2001_8:20:00P.M. 20010721 20:20:00 - Fri Jul 20 11:26:25 2001 20010720 11:26:25 - Fri Jul 20 11:26:25 GMT 2001 20010720 07:26:25 - Sun, 9 Apr 2000 06:46:46 +0100 20000409 01:46:46 - Sunday, 9 Apr 2000 06:46:46 +0100 20000409 01:46:46 - now 20010731 19:41:12 - today 20010731 00:00:00 - today 09:00 20010731 09:00:00 - tomorrow 20010801 00:00:00 - tomorrow 09:00 20010801 09:00:00 - tomorrow 09:00 GMT 20010801 05:00:00 - yesterday 20010730 00:00:00 - yesterday 09:00 20010730 09:00:00 - + 3 days 20010803 00:00:00 - +3 days 20010803 00:00:00 - +3days 20010803 00:00:00 - + 3days 20010803 00:00:00 - + 3 days 09:00 20010803 09:00:00 - + 2 weeks 20010814 00:00:00 - + 1 month 20010831 00:00:00 - - 7 months 20001231 00:00:00 - + 10 years 20110731 00:00:00 - friday 20010803 00:00:00 - saturday 20010804 00:00:00 - sunday 20010805 00:00:00 - monday 20010806 00:00:00 - tuesday 20010731 00:00:00 - wednesday 20010801 00:00:00 - thursday 20010802 00:00:00 - friday 07:00 20010803 07:00:00 - thursday 1:00pm 20010802 13:00:00 - thursday 1:00pm GMT 20010802 09:00:00 - Thu, 10 Nov 94 10:50:47 EST 19941110 10:50:47 - Fri, 20 Oct 1995 18:35:15 -0400 (EDT) 19951020 18:35:15 - 31/12/2001 20011231 00:00:00 - 12/31/2001 20011231 00:00:00 - 2001-July-20 20010720 00:00:00 - 2001-September-30 20010930 00:00:00 - 30-September-2001 20010930 00:00:00 - Sep 30, 2001 12:34:56 20010930 12:34:56 - September 30, 2001 20010930 00:00:00 - September 30, 2001 630 20010930 06:30:00 - September 30 2001 630 20010930 06:30:00 - Sep-30-2001 12:34:59 20010930 12:34:59 - 20010807113542.014 20010807 11:35.42 - 20010807113542.014Z 20010807 07:35:42 - - 8.13.6. New Date-Time Functions - - In the following descriptions, date-time function arguments are the - same free-format date-time strings discussed above, with the same - defaults for missing fields. They are automatically converted to - standard format internally prior to processing. - - \fcvtdate(d1) - Converts the date-time d1 to standard format and local time. - This function is not new, but now it accepts a wider range of - argument formats that can include timezones and/or delta times. - If the first argument is omitted, the current date and time are - assumed. The optional second argument is a format code for the - result: - - n1 = 1: yyyy-mmm-dd hh:mm:ss (mmm = English 3-letter month - abbreviation) - n1 = 2: dd-mmm-yyyy hh:mm:ss (ditto) - n1 = 3: yyyymmddhhmmss (all numeric) - - \futcdate(d1) - Converts the date-time d1 to Universal Coordinated Time (UTC), - also known as GMT or Zulu or Zero-Meridian time. The default d1 - is NOW. If d1 is a valid date-time, the UTC result is returned - in standard format, yyyymmdd hh:ss:mm. - - \fcmpdates(d1,d2) - Compares two free-format date-times, d1 and d2, and, if both - arguments are valid, returns a number: -1 if d1 is earlier than - (before) d2; 0 if d1 is the same as d2; 1 if d1 is later than - (after) d2. - - \fdiffdates(d1,d2) - Computes the difference between two free-format date-times, d1 - and d2. If both arguments are valid, returns a delta time which - is negative if d1 is earlier than (before) d2 and positive - otherwise. If d1 and d2 are equal, the result is "+0:00". - Otherwise, the result consists of the number of days, hours, - minutes, and seconds that separate the two date-times. If the - number of days is zero, it is omitted. If the number of days is - nonzero but the hours, minutes, and seconds are all zero, the - time is omitted. if the seconds are zero, they are omitted. - - \fdelta2secs(dt) - Converts a delta time to seconds. For example, "+1d00:00:01" to - 86401. Valid delta times must start with a + or - sign. Days - are accepted as time units, but not years, months, or weeks. If - the result would overflow a computer long word (as would happen - with 32-bit long words when the number of days is greater than - 24854), the function fails. - - HINT: Although Kermit has a number of built-in date and time - variables, it doesn't have a single one suitable for writing a - timestamp. For this you would normally use something like "\v(ndate) - \v(time)". But \fcvtdate() (with no arguments) is equivalent: it - returns the current date and time in yyyymmdd hh:mm:ss format, - suitable for time stamping. - - 8.13.7. Date-Time Programming Examples - - Here's a macro that converts any date-time to UTC, which you might use - if C-Kermit didn't already have a \futcdate() function: - - define utcdate { - .local := \fcvtdate(\%*) ; 1. - .tmp := \fcvtdate(\m(local)UTC) ; 2. - .offset := \fdiffdate(\m(local),\m(tmp)) ; 3. - .utc := \fcvtdate(\m(local)\m(offset)) ; 4. - sho mac utc ; 5. - } - - Brief explanation: Line 1 converts the macro argument, a free-format - date-time, to standard-format local time. Line 2 appends the "UTC" - timezone to the local time and converts the result to local time. In - other words, we take the same time as the local time, but pretend it's - UTC time, and convert it to local time. For example, if New York time - is 4 hours ahead of UTC, then 6:00pm New York time is 2:00pm UTC. Line - 3 gets the difference of the two results (e.g. "+04:00"). Line 4 - appends the difference (delta time) to the local time, and converts it - again, which adds (or subtracts) the UTC offset to the given time. - Line 5 displays the result. - - Here's a script that opens a web page, gets its headers into an array, - scans the array for the "Last-Modified:" header, and inteprets it: - http open www.columbia.edu - if fail stop 1 HTTP OPEN failed - http /array:a head index.html /dev/null - if fail stop 1 HTTP GET failed - show array a - for \%i 1 \fdim(&a) 1 { - .\%x := \findex(:,\&a[\%i]) - if not \%x continue - .tag := \fleft(\&a[\%i],\%x-1) - .val := \fltrim(\fsubstr(\&a[\%i],\%x+1)) - if ( eq "\m(tag)" "Last-Modified" ) { - echo HTTP Date: \m(val) - .rdate := \fcvtdate(\m(val)) - echo {Standard Date (local): \m(rdate)} - echo {Standard Date (UTC): \futcdate(\m(rdate))} - break - } - } - http close - - The result: - - HTTP Date: Mon, 13 Aug 2001 20:05:42 GMT - Standard Date (local): 20010813 16:05:42 - Standard Date (UTC): 20010813 20:05:42 - - As you can see, Kermit had no trouble decoding the date-time-string - from the website, converting to local time, and converting back to UTC - with no conflicts or loss of information. If it had been in any other - known format, the result would have been the same. - - Now suppose we want to download the web page only if it is newer than - our local copy. The \fdate(filename) function (which returns the - modification date-time of the given file) and the new \fcmpdates() - function make it easy. Insert the following just before the BREAK - statement: - - if ( < 0 \fcmpdates(\m(rdate),\fdate(index.html)) ) { - echo GETTING index.html... - http get index.html index.html - if success echo HTTP GET OK - } else { - echo index.html: no update needed - } - http close - exit - - This says, "if 0 is less than the comparison of the remote file date - and the local file date, get the remote file, otherwise skip it." And - it automatically reconciles the time-zone difference (if any). - - It would be nice to be able to extend this script into a - general-purpose website updater, but unfortunately HTTP protocol - doesn't provide any mechanism for the client to ask the server for a - list of files, recursive or otherwise. - - [ [472]Top ] [ [473]Contents ] [ [474]C-Kermit Home ] [ [475]Kermit - Home ] - _________________________________________________________________ - - 8.14. Trapping Keyboard Interruption - - Normally when you type Ctrl-C and Kermit is in command mode (as - opposed to CONNECT mode) with COMMAND INTERRUPTION ON (as it is unless - you have set it OFF), Kermit interrupts any command that is currently - in progress, and if a command file or macro is executing, rolls the - command stack back to top level, closing all open command files, - deactivating all macros, deallocating all local variables and arrays, - and leaving you at the command prompt. - - Suppose, however, you want certain actions to occur when a script is - interrupted; for example, closing open files, writing log entries, or - displaying summary results. You can do this by defining a macro named - ON_CTRLC. When Ctrl-C is detected, and a macro with this name is - defined, Kermit executes it from the current command level, thus - giving it full access to the environment in which the interruption - occurred, including local variables and open files. Only when the - ON_CTRLC macro completes execution is the command stack rolled back to - top level. - - Once the ON_CTRLC macro is defined, it can be executed only once. This - is to prevent recursion if the user types Ctrl-C while the ON_CTRLC - macro is executing. If you type Ctrl-C while the Ctrl-C macro is - active, this does not start a new copy of ON_CTRLC; rather, it returns - to the top-level command prompt. After the ON_CTRLC macro returns, it - has been removed from the macro table so if you want to use it again - or install a different Ctrl-C trap, you must execute a new DEFINE - ON_CTRLC command. In any case, as always when you interrupt a script - with Ctrl-C, its completion status is FAILURE. - - Normally the ON_CTRLC macro would be defined in the command file or - macro to which it applies, and should be declared LOCAL. This way, if - the command file or macro completes successfully without being - interrupted, the ON_CTRLC definition disappears automatically. - Otherwise the definition would still be valid and the macro would be - executed, probably out of context, the next time you typed Ctrl-C. - - Here's a simple example of a command file that sets a Ctrl-C trap for - itself: - - local on_ctrlc ; Make Ctrl-C trap local to this command file. - define on_ctrlc { ; Define the ON_CTRLC macro. - echo Interrupted at \v(time). - echo Iterations: \%n - } - xecho Type Ctrl-C to quit - for \%n 1 999 1 { ; Prints a dot every second until interrupted. - sleep 1 - xecho . - } - echo Finished normally at \v(time) ; Get here only if not interrupted. - decrement \%n - echo Iterations: \%n - - This prints a summary no matter whether it completes normally or is - interrupted from the keyboard. In both cases the trap is automatically - removed afterwards. - - For an example of how to use ON_CTRLC to debug scripts, see - [476]Section 8.1. - - [ [477]Top ] [ [478]Contents ] [ [479]C-Kermit Home ] [ [480]Kermit - Home ] - __________________________________________________________________________ - -9. S-EXPRESSIONS - - This section is primarily for those who want to write - calculation-intensive scripts, especially if they require - floating-point arithmetic, and/or for those who are familiar with the - LISP programming language. - - Ever since C-Kermit version 5 was released in 1988, scripting has been - one of its major attractions, and arithmetic is a key part of it. - Versions 5 and 6 included integer arithmetic only, using traditional - algebraic notation, e.g.: - - echo \fevaluate(3*(2+7)/2) - 13 - - C-Kermit 7.0 added support for floating-point arithmetic, but only - through function calls: - - echo \ffpdivide(\ffpmultiply(3.0,\ffpadd(2.0,7.0)),2.0) - 13.5 - - C-Kermit 8.0 introduces a third form of arithmetic that treats - integers and floating-point numbers uniformly, is easier to read and - write, and executes very quickly: - - (/ (* 3 (+ 2 7)) 2) - 13.5 - - But first some background. - - The Kermit command and scripting language differs from true - programming languages (such as C or Fortran) in many ways; one of the - most prominent differences is the way in which variables are - distinguished from constants. In a command language, words are taken - literally; for example, the Unix shell: - - cat foo.bar - - displays the file named foo.bar. Whereas in a programming language - like C, words are assumed to be variables: - - s = foo.bar; /* Assigns the value of foo.bar to the variable s */ - - To make a programming language take words literally, you have to quote - or "escape" them: - - s = "foo.bar"; /* Assigns a pointer to the string "foo.bar" to the variable -s */ - - The opposite holds for command languages: to get them to treat a word - as a variable rather than a constant, you have to escape them. For - example, in the Unix shell: - - foo=123 ; Assign value 123 to variable foo. - echo foo ; Prints "foo" - echo $foo ; Prints "123" - - And in Kermit: - - define foo 123 ; Assign value 123 to variable foo. - echo 123 ; This prints "123". - echo foo ; This prints "foo". - echo \m(foo) ; This prints "123". - - In other words, character strings (such as "foo" above) are - interpreted as literal strings, rather than variable names, except in - special commands like DEFINE that deal specifically with variable - names (or in numeric contexts as explained in [481]Section 8.2). The - special "escape" character (dollar sign ($) for the shell, backslash - (\) for Kermit) indicates that a variable is to be replaced by its - value. - - The requirement to escape variable names in command languages normally - does not impose any special hardship, but can add a considerable - notational burden to arithmetic expressions, which are typically full - of variables. Especially in Kermit when floating point numbers are - involved, where you must use special \ffpxxx() functions, e.g. - "\ffpadd(\m(a),\m(b))" rather than the simple "+" operator to add two - floating-point numbers together, because the original arithmetic - handler doesn't support floating point (this might change in the - future). To illustrate, the general formula for the area of a triangle - is: - - sqrt(s * (s - a) * (s - b) * (s - c)) - - where a, b, and c are the lengths of the triangle's three sides and: - - s = (a + b + c) / 2 - - Except in special cases (e.g. a = 3, b = 4, c = 5), the result has a - fractional part so the computation must be done using floating-point - arithmetic. We can create a Kermit 7.0 function for this as follows: - - def area { - local s t1 t2 t3 - assign s \ffpdiv(\ffpadd(\ffpadd(\%1,\%2),\%3),2.0) - assign t1 \ffpsub(\m(s),\%1) - assign t2 \ffpsub(\m(s),\%2) - assign t3 \ffpsub(\m(s),\%3) - return \ffpsqrt(\ffpmul(\m(s),\ffpmul(\m(t1),\ffpmul(\m(t2),\m(t3))))) - } - - But as you can see, this is rather cumbersome. Note, in particular, - that arithmetic functions like \ffpadd(), \ffpmul(), etc, take exactly - two operands (like their symbolic counterparts + and *), so obtaining - the product of three or more numbers (as we do in this case) is - awkward. - - Using the alternative S-Expression notation, we can reduce this to a - form that is both easier to read and executes faster (the details are - explained later): - - def newarea { - (let s (/ (+ \%1 \%2 \%3) 2.0)) - (sqrt (* s (- s \%1) (- s \%2) (- s \%3))) - } - - In both examples, the \%1..3 variables are the normal Kermit macro - arguments, referenced by the normal escaping mechanism. For increased - readability, we can also assign the macro arguments \%1, \%2, and \%3 - to the letters a, b, and c corresponding to our formula: - -def newarea { - (let a \%1 b \%2 c \%3) - (let s (/ (+ a b c) 2.0)) - (sqrt (* s (- s a) (- s b) (- s c))) -} - - And now the Kermit function reads almost like the original formula. - Here Kermit behaves more like a regular programming language. In an - S-Expression, macro names need not be escaped when they are used as - the names of numeric variables. - - [ [482]Top ] [ [483]Contents ] [ [484]C-Kermit Home ] [ [485]Kermit - Home ] - _________________________________________________________________ - - 9.1. What is an S-Expression? - - The S-Expression concept is borrowed from the Lisp programming - language. "S-Expression" is short for Symbolic Expression (itself - sometimes shortened to SEXP). S-Expressions provide a kind of - Alternative Mini-Universe within the Kermit command language when the - regular rules don't apply, a universe enclosed in parentheses. - - C-Kermit does not pretend to be a full Lisp interpreter; only the - arithmetic parts of Lisp have been incorporated: S-Expressions that - operate on numbers and return numeric values (plus extensibility - features described in [486]Section 9.8, which allow some degree of - string processing). - - An S-Expression is a list of zero or more items, separated by spaces, - within parentheses. Examples: - - () - (1) - (a) - (+ a 1) - (* 2 a b) - - If the S-Expression is empty, it has the NIL (empty) value. If it is - not empty and the first item is an operator (such as + or *), there - can be zero or more subsequent items, called the operands: - - (+ 1 2) - - Here the operator is "+" and the operands are "1" and "2", and the - value of the S-Expression is the value of the operation (in this case - 3). The operator always comes first, which is different from the - familiar algebraic notation; this because S-Expression operators can - have different numbers of operands: - - (+ 1) - (+ 1 2) - (+ 1 2 3 4 5 6 7 8 9) - - If the first item in the S-Expression is not an operator, then it must - be a variable or a number (or a macro; see [487]Section 9.8), and the - S-Expression can only contain one item; in this case, the - S-Expression's value is the value of the variable or number: - - (a) - (3) - - Operands can be numbers, variables that have numeric values, functions - that return numbers, or other S-Expressions. To illustrate an - S-Expression within an S-Expression, observe that: - - (+ 1 2) - - is equivalent to any of the following (plus an infinite number of - others): - - (+ 1 (+ 1 1)) - (+ (- 3 2) (/ 14 (+ 3 4))) - - S-Expressions can be nested to any reasonable level; for example, the - value of the following S-Expression is 64: - - (- (* (+ 2 (* 3 4)) (- 9 (* 2 2))) 6) - - Operators have no precedence, implied or otherwise, since they can't - be mixed. The only exceptions are unary + and -, which simply indicate - the sign of a number: - - (* 3 -1) - - Order of evaluation is specified entirely by parentheses, which are - required around each operator and its operands: (+ a (* b c)) instead - of (a + b * c). - - S-Expressions provide a simple and isolated environment in which - Kermit's macro names can be used without the \m(...) escaping that is - normally required. Given: - - define a 1 - define b 2 - define c 3 - - Then: - - (+ \m(a) \m(b) \m(c)) - - is equivalent to: - - (+ a b c) - - Within an S-Expression, as in other strictly numeric contexts - ([488]Section 8.2), any operand that starts with a letter is treated - as a Kermit macro name. In this context, abbreviations are not - accepted; variable names must be spelled out in full. Alphabetic case - is not significant; "a" and "A" are the same variable, but both are - different from "area". - - Of course, regular Kermit variables and functions can be used in - S-Expressions in the normal ways: - - (* \v(math_pi) (^ \%r 2)) ; Area of a circle with radius \%r - (+ \fjoin(&a)) ; Sum of all elements of array \&a[] - - [ [489]Top ] [ [490]Contents ] [ [491]C-Kermit Home ] [ [492]Kermit - Home ] - _________________________________________________________________ - - 9.2. Integer and Floating-Point-Arithmetic - - Normally, if all numbers in an S-Expression are integers, the result - is an integer: - - (+ 1 1) ; Result is 2 - (/ 9 3) ; Result is 3 - - If any of the operands is floating point, however, the result is also - floating point: - - (+ 1 1.0) ; Result is 2.0 - (/ 9.0 3) ; Result is 3.0 - - If all the operands are integers but the result has a fractional part, - the result is floating point: - - (/ 10 3) ; Result is 3.333333333333333 - - To force an integer result in such cases, use the TRUNCATE operator: - - (truncate (/ 10 3)) ; Result is 3 - - Similarly, to force a computation to occur in floating point, you can - coerce one of its operands to FLOAT: - - (+ 1 (float 1)) ; Result is 2.0 - - The result is also floating point if the magnitude of any integer - operand, intermediate result, or the result itself, is larger than the - maximum for the underlying machine architecture: - - (^ 100 100) - - If the result is too large even for floating-point representation, - "Infinity" is printed; if it is too small to be distinguished from 0, - 0.0 is returned. - - Large numbers can be used and large results generated, but they are - accurate only to the precision of the underlying machine. For example, - the result of: - - (+ 111111111111111111111 222222222222222222222) - - should be 333333333333333333333, but 333333333333333300000.0 is - produced instead if the machine is accurate to only about 16 decimal - digits, even with coercion to floating-point. The order of magnitude - is correct but the least significant digits are wrong. The imprecise - nature of the result is indicated by the ".0" at the end. Contrast - with: - - (+ 111111111 222222222) - - which produces an exact integer result. - - [ [493]Top ] [ [494]Contents ] [ [495]C-Kermit Home ] [ [496]Kermit - Home ] - _________________________________________________________________ - - 9.3. How to Use S-Expressions - - S-Expressions may be given as commands to C-Kermit. Any command whose - first character is "(" (left parenthesis) is interpreted as an - S-Expression. - - If you enter an S-Expression at the C-Kermit> prompt, its result is - printed: - - C-Kermit>(/ 10.0 3) - 3.333333333333333 - C-Kermit> - - If an S-Expression is executed within a macro or command file, its - value is not printed. However, you can control the printing action - with: - - SET SEXPRESSION ECHO { AUTO, ON, OFF } - AUTO is the default, meaning print the value at top level only; - ON means always print the value; OFF means never print it. - - In any case, the value of the most recent S-Expression (and the - S-Expression itself) may be accessed programmatically through the - following variables: - - \v(sexpression) - The S-Expression most recently executed. - - \v(svalue) - The value of the S-Expression most recently executed. - - Besides issuing S-Expressions as commands in themselves, you can also - execute them anywhere within a Kermit command, but in this case they - must be enclosed in a function call (otherwise they are taken - literally): - - \fsexpression(s) - The argument "s" is an S-Expression; the outer parentheses may - be omitted. The value of the S-Expression is returned. Note - that since S-Expressions usually contain spaces, some form of - grouping or quoting might be needed in some contexts: - - echo \fsexpression((+ 1 1)) ; Outer parentheses may be included - echo \fsexpr(+ 1 1) ; Outer parentheses may be omitted - echo Value = "\fsexp(+ 1 a)" ; Can be embedded in strings - echo Value = \&a[\fsexp(/ b 2)] ; Can be used in array subscripts - if = {\fsexp(+ 1 1)} 2 { ; Braces needed here for grouping - echo One plus one still equals two - } - - The IF statement illustrates how to use S-Expressions as (or in) IF or - WHILE conditions: - - * Although S-Expressions and IF conditions are similar in - appearance, they are not interchangeable. Therefore you must use - \fsexpr() to let Kermit know it's an S-Expression rather than a - regular IF condition, or a boolean or algebraic expression within - an IF condition. - * In contexts where a single "word" is expected, you must enclose - the \fsexp() invocation in braces if the S-Expression contains - spaces (and most of them do). - - If an S-Expression is the last command executed in a macro, its value - becomes the return value of the macro; no RETURN command is needed. - Example: - - def newarea { - (let s (/ (+ \%1 \%2 \%3) 2.0)) - (sqrt (* s (- s \%1) (- s \%2) (- s \%3))) - } - - This is equivalent to (but more efficient than): - - def newarea { - (let s (/ (+ \%1 \%2 \%3) 2.0)) - return \fsexp(sqrt (* s (- s \%1) (- s \%2) (- s \%3))) - } - - When an S-Expression is entered as a command -- that is, the first - nonblank character of the command is a left parenthesis -- then it is - allowed to span multiple lines, as many as you like, until the first - left parenthesis is matched: - - (let s (/ - (+ - \%1 - \%2 - \%3 - ) - 2.0 - ) - ) - (sqrt (* - s - (- s \%1) - (- s \%2) - (- s \%3) - ) - ) - - The S-Expression concept lends itself easily to embedding and - recursion, but the depth to which recursion can occur is limited by - the resources of the computer (memory size, address space, swap space - on disk) and other factors. There is no way that C-Kermit can know - what this limit is, since it varies not only from computer to - computer, but also from moment to moment. If resources are exhausted - by recursion, C-Kermit simply crashes; there's no way to trap this - error. However, you can set a depth limit on S-Expressions: - - SET SEXPRESSION DEPTH-LIMIT number - Limits the number of times the S-Expression reader can invoke - itself without returning to the given number. The default limit - is 1000. This limit applies to S-Expressions embedded within - other S-Expressions as well as to S-Expressions that invoke - recursive macros. If the limit is exceeded, Kermit prints - "?S-Expression depth limit exceeded" and returns to its prompt. - More about recursion in [497]Section 9.8. - - You can also test the depth programmatically: - - \v(sdepth) - The current S-Expression invocation depth. The depth includes - both nesting level and recursion. For example, in: - (foo (foo (foo (foo (foo))))), the innermost (foo) is at depth - 5. - - Help, completion, and syntax checking are not available within an - S-Expression. If you type ? within an S-Expression, it says: - - C-Kermit>(? S-Expression ("help sexp" for details) - - As it says, typing "help sexp" will display a brief help text. - - The SHOW SEXPRESSION command displays current SET SEXPRESSION settings - and related information. - - [ [498]Top ] [ [499]Contents ] [ [500]C-Kermit Home ] [ [501]Kermit - Home ] - _________________________________________________________________ - - 9.4. Summary of Built-in Constants and Operators - - Three constants are built in: - - * PI, whose value is the value of pi (the quotient of circumference - of any circle and its diameter, 3.141592653...) to the underlying - machine's precision; - * T, which always has the value 1, which signifies truth in Kermit - logical expressions or S-Expressions; - * NIL, which always has the empty value, and can serve as a False - truth value. - - These constants are specific to S-Expressions and are not visible - outside them. They may not be used as the target of an assignment. So, - for example: - - (setq t 0) Fails - assign t 0 Succeeds but this is not the same T! - - E (the base of natural logarithms, 2.7182818184...) is not built in - since it is not intrinsic in most Lisp dialects. If you want E to be - the base of natural logarithms you can: - - (setq e (exp 1)) - - Operators are either symbols (such as "+") or words. Words must be - spelled out in full, not abbreviated. Differences of alphabetic case - are ignored. - - The most basic operation in S-Expressions is evaluation: - - EVAL [ s-expression or variable or number [ another [ another ... ] ] - ] - Evaluates its operands and returns the value of the last one - evaluated. Examples: - - (eval) 0 - (eval 1) 1 - (eval a) value of a - (eval (+ 1 a)) value of a+1 - (eval (setq a 1) (setq b (+ a 0.5))) value of b (= a+0.5) - - You can use "." as a shorthand for EVAL: - - (.) - (. 1) - (. a) - (. (+ 1 a)) - (. (setq a 1) (setq b (+ a 0.5))) - - Opposite of EVAL is the operator that suppresses evaluation of its - operand: - - QUOTE item - The value (quote item) is "item". If the item is itself an - S-Expression, the result is the S-Expression with the outer - parentheses stripped. Examples: - - (quote) (illegal) - (quote a) a - (quote hello) hello - (quote (this is a string)) this is a string - (quote this is a string) (illegal) - - A shorthand notation is also accepted for quoting: - 'a is equivalent to (quote a). And therefore: - '(a b c) is equivalent to (quote (a b c)). - More about quoting in [502]Section 9.8. - - STRING item - Is a combination of EVAL and QUOTE. It evaluates the item as an - S-Expression, and then puts quotes around the result (more - about this in [503]Section 9.8). - - The following operators assign values to variables: - - SETQ [ variable [ value [ variable [ value [ ... ] ] ] ] ] - Applies to global variables. For each variable given: if a - value is not given, the variable is undefined. If a value is - given, assigns the value to the variable. The value may be a - number, a variable, or anything that resolves to a number - including an S-Expression. Returns the value of the last - assignment. Examples: - - (setq) Does nothing, returns NIL. - (setq a) Undefines a, returns NIL. - (setq a 1) Assigns 1 to a, returns 1. - (setq a 1 b 2) Assigns 1 to a, 2 to b, returns 2. - (setq a 1 b 2 c) Assigns 1 to a, 2 to b, undefines c, returns NIL. - - To undefine a variable that is not the final one in the list, give it - a value of "()" or NIL: - - (setq a () b 2) Undefines a, assigns 2 to b, returns 2. - (setq a nil b 2) Ditto. - - Note that a variable can be used right away once it has a value: - - (setq a 1 b a) Assigns 1 to a, the value of a (1) to b, returns 1. - - The results of SETQ (when used with macro names) can be checked - conveniently with SHOW MACRO, e.g: - - show mac a b c - - LET [ variable [ value [ variable [ value [ ... ] ] ] ] ] - Like SETQ, but applies to local variables. Note that "local" is - used in the Kermit sense, not the Lisp sense; it applies to the - current Kermit command level, not to the current S-Expression. - - If you want to use SETQ or LET to assign a value to a backslash - variable such as \%a or \&a[2], you must double the backslash: - - (setq \\%a 3) - (setq \\%b (+ \%a 1)) - (setq \\&a[2] (setq (\\%c (+ \%a \%b)))) - - In other words: - - * Double the backslash when you want to indicate the variable's - NAME; - * Don't double the backslash when you want its VALUE. - - See [504]Section 9.6 for a fuller explanation of variable syntax and - scope. - - Here's a summary table of arithmetic operators; in the examples, a is - 2 and b is -1.3: - - Operator Description Example Result - + Adds all operands (0 or more) (+ a b) 0.7 - - Subtracts all operands (0 or more) (- 9 5 2 1) 1 - * Multiplies all operands (0 or more) (* a (+ b 1) 3) -1.80 - / Divides all operands (2 or more) (/ b a 2) -0.325 - ^ Raise given number to given power (^ 3 2) 9 - ++ Increments variables (++ a 1.2) 3.2 - -- Decrements variables (-- a) 1 - ABS Absolute value of 1 operand (abs (* a b 3)) 7.8 - MAX Maximum of all operands (1 or more) (max 1 2 3 4) 4 - MIN Minimum of all operands (1 or more) (min 1 2 3 4) 1 - MOD (%) Modulus of all operands (1 or more) (mod 7 4 2) 1 - FLOAT Convert an integer to floating-point (float 1) 1.0 - TRUNCATE Integer part of floating-point operand (truncate 3.333) 3 - CEILING Ceiling of floating-point operand (ceiling 1.25) 2 - FLOOR Floor of floating-point operand (floor 1.25) 1 - ROUND Operand rounded to nearest integer (round 1.75) 2 - SQRT Square root of 1 operand (sqrt 2) 1.414.. - EXP e (2.71828..) to the given power (exp -1) 0.367.. - SIN Sine of angle-in-radians (sin (/ pi 2)) 1.0 - COS Cosine of angle-in-radians (cos pi) -1.0 - TAN Tangent of angle-in-radians (tan pi) 0.0 - LOG Natural log (base e) of given number (log 2.7183) 1.000.. - LOG10 Log base 10 of given number (log10 1000) 3.0 - - The ++ and -- operators are also assignment operators and work just - like SETQ and LET in their interpretations of operators and operands, - but: - - * Each target variable must already be defined and have a numeric - value; - * The assignment value is the amount by which to increment or - decrement the variable. - * If an assignment value is not given, 1 is used. - - If you include more than one variable-value pair in a ++ or -- - expression, every variable (except, optionally, the last) must be - followed by a value. Examples: - - (++ a) Equivalent to (setq a (+ a 1)) and to (++ a 1) - (++ a 2) Equivalent to (setq a (+ a 2)) - (-- a (* 2 pi)) Equivalent to (setq a (- a (* 2 pi))) - (++ a 1 b 1 c 1 d) Equivalent to four SETQs incrementing a,b,c,d by 1. - - Another group of operators forms the predicates. These return a "truth - value", in which 0 (or NIL) is false, and 1 or any other nonzero - number is true. - - Operator Description Example Result - = (or ==) Operands are equal (= 1 1.0) 1 - != Operands are not equal (!= 1 1.0) 0 - < Operands in strictly ascending order (< 1 2 3) 1 - <= Operands in ascending order (<= 1 1 2 3) 1 - > Operands in strictly descending order (> 3 2 1) 1 - >= Operands in descending order (<= 3 3 2 1) 1 - AND (&&) Operands are all true (and 1 1 1 1 0) 0 - OR (||) At least one operand is true (or 1 1 1 1 0) 1 - XOR Logical Exclusive OR (xor 3 1) 0 - NOT (!) Reverses truth value of operand (not 3) 0 - - The Exclusive OR of two values is true if one value is true and the - other value is false. - - And another group operates on bits within an integer word: - - Operator Description Example Result - & Bitwise AND (& 7 2) 2 - | Bitwise OR (| 1 2 3 4) 7 - # Bitwise Exclusive OR (# 3 1) 2 - ~ Reverses all bits (~ 3) -4 - - These operators coerce their operands to integer by truncation if - necessary. The result of bit reversal is hardware dependent. - - The final category of operator works on truth values: - - Operator Description Example Result - IF Conditional evaluation (if (1) 2 3) 2 - - IF (predicate) (s1) [ (s2) ] - The IF operator is similar to Kermit's IF command. If the - predicate is true (i.e. evaluates to a nonzero number), the - first S-Expression (s1) is evaluated and its value is returned. - Otherwise, if (s2) is given, it is evaluated and its value - returned; if (s2) is not given, nothing happens and the NIL - (empty) value is returned. - - You can group multiple expressions in the s1 and s2 expressions using - EVAL (or "."): - - (if (< a 0) (eval (setq x 0) (setq y 0)) (eval (setq x a) (setq y b))) - - or equivalently: - - (if (< a 0) (. (setq x 0) (setq y 0)) (. (setq x a) (setq y b))) - - Each operator has its own requirement as to number and type of - operands. In the following table, "number" means any kind of number -- - integer or floating-point -- or a variable, function, macro, or - S-Expression that returns a number; "vname" means variable name, - "fpnumber" means a floating-point number (or anything that resolves to - one), and "integer" means integer (or anything that resolves to one). - "truthvalue" means anything that resolves to a value of zero or an - empty value (which indicates false) or a nonzero value (which - indicates true). "any" means any kind of value, including none at all. - - Operator Number of operands Type of operands Returns - EVAL (.) 0 or more S-Expression Last value (default NIL) - STRING 1 S-Expression string - QUOTE (') 1 word string - SETQ 0 or more vname value pairs Last value (default NIL) - LET 0 or more vname value pairs Last value (default NIL) - + 0 or more number number (default 0) - - 0 or more number number (default 0) - * 0 or more number number (see note (1)) - / 2 or more number number - ^ 2 or more number number - ++ 1 or more vname value pairs Result of last increment - -- 1 or more vname value pairs Result of last decrement - ABS 1 number number - MAX 1 or more number number - MIN 1 or more number number - MOD (%) 2 number number - FLOAT 1 number fpnumber - TRUNCATE 1 number integer - CEILING 1 number integer - FLOOR 1 number integer - ROUND 1 number integer - SQRT 1 number fpnumber - EXP 1 number fpnumber - SIN 1 number fpnumber - COS 1 number fpnumber - TAN 1 number fpnumber - LOG 1 number fpnumber - LOG10 1 number fpnumber - = (==) 1 or more number truthvalue - != 1 or more number truthvalue - < 1 or more number truthvalue - <= 1 or more number truthvalue - > 1 or more number truthvalue - >= 1 or more number truthvalue - AND (&&) 1 or more truthvalue truthvalue - OR (||) 1 or more truthvalue truthvalue - XOR 2 truthvalue truthvalue - NOT (!) 1 truthvalue truthvalue - & 1 or more number (see note 2) integer - | 1 or more number (see note 2) integer - # 2 number (see note 2) integer - ~ 1 number (see note 2) integer - IF 2 or 3 truthvalue,any,any any - - Operators that don't require any arguments return the default values - shown. - - 1. The value of "*", when used as an operator, is initially "1" and - the value of the most recent S-Expression thereafter, as in Franz - Lisp. This is handy when doing a series of calculations by hand: - C-Kermit>(* 13272.42 0.40) - 5308.968 - C-Kermit>(/ * 2) - 2654.4840 - C-Kermit> - 2. The bitwise operators coerce their operands to integer by - truncation. - - [ [505]Top ] [ [506]Contents ] [ [507]C-Kermit Home ] [ [508]Kermit - Home ] - _________________________________________________________________ - - 9.5. Variables - - As noted elsewhere in this discussion, all backslash items (variables - such as \%a, macro parameters such as \%1, array elements such as - \&a[\%i], built-in variables such as \v(ndate), built-in functions - such as \fjoin(), macro names enclosed in \m(), \s(), or \:(), etc) - are evaluated at "top level" before the S-Expression is sent to the - S-Expression reader. To use a backslash variable as the target of an - assignment (e.g. by SETQ, LET, ++, or --), you must double the - backslash, e.g. (setq \\%r 1234). This is discussed at greater length - in the next section. - - Thus S-Expression reader generally deals only with macro names (not - backslash items) as variables. It is important to understand how the - reader handles macro names. There are fundamentally two kinds of - S-Expressions: those that contain a single element, such as: - - (foo) - - and those that contain more than one element: - - (foo a b c) - - If an S-Expression contains only one element, and it is the name of a - macro, the macro's definition is examined. If the definition is a - number (integer or floating-point, positive or negative), then this - becomes the value of the expression. If the definition starts with ' - (apostrophe), then the quoted word or string is the value of the - expression (explained in [509]Section 9.8). Otherwise, the macro is - assumed to be composed of Kermit commands (possibly including - S-Expressions), which are executed. If the macro has a RETURN value, - or it executes an S-Expression as its last command, the result becomes - the value of the S-Expression; otherwise the result is empty. - - For S-Expressions that contain more than one element, and the first - element is the name of a macro, then this macro is executed with the - arguments that are given, after the arguments are evaluated by the - S-Expression reader. Likewise, If the first element is a built-in - operator, then it is applied to the operands after they are evaluated. - In both cases, each operand is fed to the S-Expression reader - recursively for evaluation. If an operand is a number or a quoted - string, it is used as-is. But if it's a macro name, this degenerates - into the first case, and the previous paragraph applies. - - Examples: - - define foo 123 - (foo) Result: 123 - define foo 'abc - (foo) Result: abc - define foo '(one two three) - (foo) Result: one two three - define foo return \frandom(1000) - (foo) Result: 713 (or other number) - define foo (+ a b) - (foo) Result: The sum of a and b - - A more difficult example: - - define foo abc - (foo) Result: ??? - - The result in the last example depends on the definition of abc: - - * If it has no definition, an error occurs; otherwise: - * If the definition is an S-Expression, the result is the - S-Expression's value; otherwise: - * If the definition consists of Kermit commands, they are executed. - But in this case "(foo)" produces the empty result, because it - doesn't RETURN anything. - - The use of macros as S-Expression operators is described in - [510]Section 9.8. - - [ [511]Top ] [ [512]Contents ] [ [513]C-Kermit Home ] [ [514]Kermit - Home ] - _________________________________________________________________ - - 9.6. Assignments and Scope - - The assignment operators SETQ and LET apply to global and local - variables, respectively. SETQ and LET are standard Lisp operators - adapted to Kermit scoping rules. When the operands are numeric or - arithmetic, SETQ is equivalent to Kermit's EVALUATE command: - - (setq a (+ 1 2)) - evaluate a 1 + 2 - - When the operand is a string, SETQ is equivalent to DEFINE: - - (setq a '(this is a string)) - define a this is a string - - In the first case, both statements create a macro named "a" with a - value of 3. But in neither case is the macro "a" necessarily global. - If either of these commands executes in an environment (i.e. macro - invocation level) where a "local a" command has been given, the "a" - macro is global to that environment, but is not visible outside it. - - LET is equivalent to the Kermit LOCAL command, followed by the - corresponding EVALUATE: - - (let a (+ 1 2)) - - is equivalent to: - - local a - evaluate a 1 + 2 - - Again, "local" in this context applies to the Kermit macro invocation - stack, not to the S-Expression nesting level. To illustrate, recall - our "newarea" macro: - -def newarea { - (let a \%1 b \%2 c \%3) - (let s (/ (+ a b c) 2.0)) - (sqrt (* s (- s a) (- s b) (- s c))) -} - - Because SETQ and LET expressions return a value, they can be placed - within a larger S-Expression. In this case we can replace the first - reference to the "s" variable by its defining expression: - -def newarea { - (let a \%1 b \%2 c \%3) - (sqrt (* (let s (/ (+ a b c) 2.0)) (- s a) (- s b) (- s c))) -} - - This would not work if LET were local to the S-Expression, but it - works nicely in the context of Kermit macros. The previous definition - is equivalent to: - -def newarea { - local a b c s - (setq a \%1 b \%2 c \%3) - (sqrt (* (setq s (/ (+ a b c) 2.0)) (- s a) (- s b) (- s c))) -} - - In both cases, the variables a, b, c, and s are local to the "newarea" - macro, and global within it. - - Multiple assignments can be handled in several ways. Here is the - obvious way to initialize a series of variables to the same value: - - (setq a 0) - (setq b 0) - (setq c 0) - (setq s 0) - - Here is a more compact and efficient way of doing the same thing: - - (setq a 0 b 0 c 0 s 0) - - However, in case the value was more complex, it's better to put only - one copy of it in the S-Expression; in this case we rely on the fact - that SETQ returns the value of its last assignment: - - (setq a (setq b (setq c (setq s (* x (^ y 2)))))) - - Similarly, to set a series of variables to x, x+1, x+2, ... - - (setq c (+ (setq b (+ (setq a (+ (setq s x) 1)) 1)) 1)) - - In the last example, you can see why "last" does not always correspond - to "rightmost" (the leftmost variable "c" is assigned last). - - If you are working with backslash variables like \%a or array elements - like \&a[1], remember two rules: - 1. Don't put spaces inside array brackets. - 2. You must double the backslash when using SETQ, LET, ++, or -- to - assign a value to a backslash variable. - - Examples of assigning to a backslash variable: - - (setq x 1) - (setq \\%a 0) - (setq \\&a[x+1] 1) - (++ \\%x) - (-- \\&a[x+2]) - - Examples of referring to a backslash variable's value: - - (setq a (+ \%a 1)) - (setq b (+ \%a \&a[1])) - (++ a \%x) - (-- b \&a[1]) - - The special notation is required because all backslashed items (\%x - variables, array elements, built-in \v(xxx) variables, and \fxxx() - function invocations) are evaluated in a single pass BEFORE the - S-Expression is executed; any other approach would result in - unacceptable performance. So, for example, in: - - declare \&a[] = 1 2 3 - define \%x 4 - define \%y 0 - (setq \\%y (+ \%x \&a[1])) - - the S-Expression becomes: - - (setq \%y (+ 4 1)) - - before it is sent to the S-Expression evaluator. If the backslash had - not been doubled on the assignment target, the result would have been: - - (setq 0 (+ 4 1)) - - which is illegal because you can't assign a value to a number. - Conversely, if backslashes were doubled on right-hand-side values: - - (setq \\%y (+ \\%x \\&a[1]) - - this too, would give an error (not numeric - "\%x"). - - If you omit the double backslash in the assignment target, the result - depends on whether the variable already has a value: - - (setq \%a (* 3 3)) - - If \%a has a non-numeric single-word value, then this becomes the name - of the variable that is assigned by SETQ. To illustrate: - - define \%a foo - echo \%a - foo - (setq \%a (* 3 3)) - echo \%a - foo - show macro foo - foo = 9 - - If \%a has no value, a numeric value, or a multiword value, an - "invalid assignment" error occurs. - - [ [515]Top ] [ [516]Contents ] [ [517]C-Kermit Home ] [ [518]Kermit - Home ] - _________________________________________________________________ - - 9.7. Conditional Expressions - - The IF operator provides a compact form of decision-making within - S-Expressions. An IF expression can stand wherever a number might - stand, as long is it returns a number. Here's a quick way to obtain - the average value of all the elements in an array that contains only - numbers: - - (/ (+ \fjoin(&a)) (float \fdim(&a))) - - This results in a "Divide by zero" error if the array is empty. If you - want to define the average value of an empty array to be 0 instead of - getting an error, you can use IF to check the array size: - - (if \fdim(&a) (/ (+ \fjoin(&a)) (float \fdim(&a))) 0) - - or equivalently: - - (if (not \fdim(&a)) 0 (/ (+ \fjoin(&a)) (float \fdim(&a)))) - - Of course, IF can fit anywhere else into an S-Expression: - - (setq a (+ b (if (< c 0) 0 c))) - - and the IF expression can be as complex as you like: - - (setq a (+ b (if (and (or (> x 0) (> y 0)) (< c 0) (> d 1) (!= e 0)) 1 0))) - - and the "then" and "else" parts can contain multiple S-Expressions - enclosed within (EVAL ...): - - (if x (eval (...) (...) (...)) (eval (...) (...) (...))) - - AND and OR operators are guaranteed to "short circuit". If any operand - of AND is false, none of the subsequent operands is evaluated; - likewise, if an OR operand is true, no further operands are evaluated. - - Bear in mind that the S-Expression IF is not the same as Kermit IF; - the condition is only allowed to be an S-Expression or a variable or - number, not the whole list of possibilities you see when you type "if - ?" at the C-Kermit> prompt. But keep reading... - - [ [519]Top ] [ [520]Contents ] [ [521]C-Kermit Home ] [ [522]Kermit - Home ] - _________________________________________________________________ - - 9.8. Extensibility - - To extend the capabilities of S-Expressions, you can use Kermit macro - names as operators, with the following limitations: - - * The macro must not have the same name as a built-in operator. - * You must use the full macro name, not an abbreviation. - - And with the following enhancement: - - * If the last statement executed by the macro is an S-Expression, - its value is returned automatically. In other words: - - define bump (++ \%1) - - is equivalent to: - - define bump return \fsexpression(++ \%1) - - Here's an example in which we define a FIBONACCI operator that returns - the nth element, n >= 0, of the Fibonacci series, 0 1 1 2 3 5 8 13 21 - 34 55, . . ., in which the first element is 0, the second is 1, and - each subsequent element is the sum of the two before it. This series - was devised by Leonardo Pisano, Filius Bonacci (Fibonacci for short) - in 1202 to describe how fast rabbits can breed, and also forms the - basis for the Golden Mean, the branching behavior of plants, the - spiral of a nautilus shell, etc. (Thanks to [523]Dat Thuc Nguyen for - December 2003 corrections to this section!) - - We can write a FIBONACCI function as a macro easily with - S-Expressions: - - define FIBONACCI { - (if (== \%1 0) 0 - (if (== \%1 1) 1 (+ (fibonacci (- \%1 2)) (fibonacci (- \%1 1))))) - } - - You can read this as: - - If the argument (\%1) is 0, return a result of 0; if it is 1, - return 1; otherwise: - return the sum of fibonacci(argument - 2) and fibonacci(argument - - 1) - - Note that a RETURN statement is not needed, since S-Expressions - automatically set the return value of their containing macros. - - For comparison, here's how it would be coded without S-Expressions: - - define FIBONACCI { - if == \%1 0 { - return 0 - } else if == \%1 1 { - return 1 - } else { - return \feval(\fexec(fibonacci \feval(\%1-2)) - - + \fexec(fibonacci \feval(\%1-1))) - } - } - - Now we can use the FIBONACCI function (whichever way you write it) - just as if it were a built-in operator: - - (fibonacci 6) - - Or: - - (setq a 10) - (fibonacci a) - - Within S-Expressions only (not outside them), S-Expressions themselves - can be used as macro arguments: - - (setq a 2 b 4) - (setq x (fibonacci (* a b ))) - - The value of the S-Expression (in this case "8"), and not the - S-Expression itself, is sent to the macro. - - Your macro is responsible for argument validation and error handling. - A robust Fibonacci macro would be more like this: - - define FIBONACCI { - if < \v(argc) 2 end 1 ?\%0: Missing argument - if > \v(argc) 2 end 1 ?\%0: Too many arguments - if not integer \%1 end 1 ?\%0: Integers only - if < \%1 1 end 1 ?\%0: Argument out of range - (if (== \%1 0) 0 - (if (== \%1 1) 1 (+ (fibonacci (- \%1 2)) (fibonacci (- \%1 1))))) - } - - Recall that "END nonzero-number [ message ]" causes a macro invocation - to fail. When the macro is the operator in an S-Expression, this makes - the S-Expression fail too. Also note that our Fibonacci macro is just - an illustration, not a practical example. Since it is recursive (calls - itself), it won't work for large arguments because the call stack can - exceed available memory. See [524]Section 9.9.2 for a practical - alternative. - - Kermit macros, when used as S-Expression operators, can do anything at - all except initiate file transfers: they can print messages on the - screen, read and write files, interact with the user, and so on. For - example, here's a macro ASKME that asks you to enter a number, makes - sure that you did, and then returns its value for use in the - S-Expression: - - define ASKME { - local \%n - while true { - ask \%n { Number: } - if not def \%n continue - if not numeric \%n { - echo Not numeric - "\%n" - continue - } - break - } - return \%n - } - (setq a (* 2 (askme))) ; Get number from user, double it, assign result to a. - - Here's a macro you can use to validate that a number is in a given - range: - - define inrange { - if != \v(argc) 4 end 1 ?\%0: Wrong number of arguments - if ( < \%1 \%2 || > \%1 \%3 ) return 0 - return 1 - } - - The first argument is the number to be checked, the second is the - minimum acceptable value, the third is the maximum. You can use this - (for example) in IF conditions: - - define yes echo \%1 IS OK - define no echo \%1 IS NOT OK - - (setq a -1 b 999) - (if (inrange a 0 100) (yes a) (no a)) - (if (inrange b -1000 +1000) (yes b) (no b)) - - This is just an illustration, of course; there's already a built-in - operator to let you do range checking without help from macros: - - (if (<= 0 a 100) (yes a) (no a)) - (if (<= -1000 b +1000) (yes b) (no b)) - - To send string parameters to a macro, some kind of quoting is required - to tell the S-Expression parser to take a given "word" literally - rather than replacing it by its value. For this we use the Lisp QUOTE - operator: - - define length return \flength(\%1) - (length (quote abcdefghijklmnopqrstuvwxyz)) - 26 - - This causes the string "abcdefghijklmnopqrstuvwxyz" to be sent - literally to the LENGTH macro. Kermit, like Lisp, also offers a - shortcut for QUOTE, that lets us quote a word by prefixing it with a - single quote (') character, also called apostophe (ASCII 39): - - (length 'abcdefghijklmnopqrstuvwxyz) - 26 - - The two forms are equivalent. - - How the macro treats its arguments is up to the macro. In the example - above, the argument is treated as a literal string. However, it can - also be treated as a variable name: - - define string This is a string - define length return \flength(\m(\%1)) - (length 'string) - 16 - - Note the construct \m(\%1). This means "the value of the macro whose - name is the value of - \%1". The value of \%1 in this case is the word "string", and the - value of the macro whose name is "string" is "This is a string". - - What if the macro takes multiple arguments, or a variable number of - them? Here's a simple macro that prints a phrase that includes its - arguments: - - define complain echo It's too \%*! - - (Recall that \%* means "all arguments".) - - It can be called in the traditional way: - - complain hot Result: "It's too hot!" - complain cold and wet Result: "It's too cold and wet!" - - Or from an S-Expression if you quote the arguments: - - (complain 'hot) Result: "It's too hot!" - (complain 'cold 'and 'wet) Result: "It's too cold and wet!" - - To group multiple words into a single argument, use parentheses: - - (complain (quote (cold and wet))) Result: "It's too cold and wet!" - (complain '(cold and wet)) Result: "It's too cold and wet!" - - Note the difference: - - (complain 'cold 'and 'wet) Three arguments - (complain '(cold and wet)) One argument - - Since the COMPLAIN macro uses \%* to refer to all its arguments, no - matter how many, it doesn't care which form you use. But it makes a - difference in cases where the macro refers to its arguments - individually. - - To illustrate, let's consider a macro that receives the name of a - macro and its argument list and executes it with its arguments, - without knowing how many arguments there are. The following LOOP macro - is used to execute the given macro with the given argument list the - requested number of times: - - def loop { local i, for i 1 \%1 1 do \%2 \%3 } - - Within the LOOP macro, the first argument (\%1) is the loop count, \%2 - is the macro name, and \%3 is the argument list. When the LOOP macro - is invoked traditionally like this: - - loop 3 complain hot - - it prints "It's too hot!" three times. To invoke it from an - S-Expression, you must quote both the macro name as well as the - argument, since in this case the macro name itself is an argument: - - (loop 3 'complain 'hot) - - Now what if you need to send different or variable numbers of - arguments to the LOOP macro? The LOOP macro can handle it already, - provided you group the arguments into LOOP's third argument (\%3). In - Kermit syntax, without grouping: - - loop 3 complain cold and wet - - prints "It's too cold!" three times ("and wet" is lost); but with - grouping (either of the following two forms): - - loop 3 complain {cold and wet} - loop 3 complain "cold and wet" - - the LOOP macro prints "It's too cold and wet!" three times as desired. - - To do the same thing in an S-Expression, just use the Lisp forms of - quoting instead of the Kermit forms; the following two are equivalent: - - (loop 3 'complain (quote (cold and wet))) - (loop 3 'complain '(cold and wet)) - - Here's a similar example in which we write a macro that shows both the - name and the value of one or more other macros, whose names are given - as arguments (similar to "show macro"): - - define display { - local \%i - for \%i 1 \v(argc)-1 1 { - echo \&_[\%i] = \m(\&_[\%i]) - } - } - - (Recall that \&_[] is the macro's argument vector array, equivalent to - \%1, \%2, ...) The DISPLAY macro can be used in S-Expressions like - this: - - (setq a 1 b 2 c 3) - (display 'a 'b 'c 'd) - - which prints: - - a = 1 - b = 2 - c = 3 - d = - - The names must be quoted to prevent their evaluation before they are - sent to the macro. This ability to pass variables "by name" to macros, - rather than by value, lets you write macros that change the values of - argument variables. For example, here's a macro that doubles the value - of its argument variable: - - define double (++ \%1 \%1) - - which you can call like this: - - (setq a 12) - (double 'a) - - In the macro, \%1 is replace by the variable name "a"; "(++ a a)" adds - "a" to itself, and sets the value of "a" to the result. - - There are no built-in operators other than QUOTE, ', and STRING for - handling strings in S-Expressions, but using just these, plus macros - that use Kermit's regular string-handling features, you can easily - extend S-Expressions to do string manipulation: - - define len return \flen(\%1) Returns length of argument string - define cap return \fupper(\%1) Uppercase argument string - define rev return \freverse(\%1) Reverses argument string - define sub return \fsubstr(\%1,\%2,\%3) Returns substring of arg string - - (len '(this is a string)) Result: 16 - (rev '(this is a string)) Result: gnirts a si siht - (rev (cap '(this is a string))) Result: GNIRTS A SI SIHT - (sub (rev (cap '(this is a string))) 5 9) Result: TS A SI S - - You can assign a string to a macro name as follows: - - (setq foo '(this is a string)) - (setq foo (quote (this is a string))) - - The two are exactly equivalent. In both cases, the macro "foo" has the - value: - - '(this is a string) - - so when it is retrieved it can be identified as a string rather than a - number or commands to be executed. Thus: - - (setq foo (quote (this is a string))) - show macro foo - foo = '(this is a string) - (foo) - this is a string - - Note the different results for "show macro foo" and "(foo)". The - former shows the internal definition; the latter evaluates the - variable, which removes the quoting. And perhaps more important, note - that if the apostrophe and surrounding parentheses were not stored as - part of the definition, (foo) would try to execute "this is a string" - as a command. - - Given the assignment above, the following work as expected: - - (len foo) Result: 16 - (rev foo) Result: gnirts a si siht - (rev (cap foo)) Result: GNIRTS A SI SIHT - (sub (rev (cap foo)) 5 8) Result: TS A SI S - - Note that, unlike built-in S-Expression operators that return numbers - or truth values, these operators return strings. If you want to assign - their return values to other variables, you can do so: - - (setq bar (rev (cap foo))) Result: GNIRTS A SI SIHT - - But now the S-Expression processor doesn't know the value of "bar" is - supposed to be a string, rather than a macro to execute. For this you - need one final special operator, STRING. The STRING operator takes an - S-Expression as an operand, evaluates it, and then returns its value - enclosed in '(), so you can use the value as a string is subsequent - S-Expressions. Use STRING for referencing macros that return strings: - - (setq bar (string (rev (cap foo)))) Result: '(GNIRTS A SI SIHT) - - STRING is like QUOTE, except that it evaluates its operand before - applying the quoting, rather than taking the operand literally. - - To reference backslash variables or functions that return string - values, you must use the regular quoting mechanisms: - - (setq time '(\v(time))) - (setq date '(\v(date))) - assign \%r this is a string - (setq s1 '(\%r)) - - That's because backslash items are evaluated BEFORE the S-Expression - parser ever sees them, and the values of \v(time) and so on are not - valid S-Expressions, so STRING won't like them. - - Finally a brief word on the touchy topic of quoting. Suppose you want - to include (say) literal parentheses in a string that will later be - processed by the S-Expression reader (or \fsplit() or \fword()). - Normally, you can't do this because parentheses are meaningful in - these contexts. To defeat the normal parsing rules, you can quote the - parentheses with backslash. However, due to the many levels of string - processing involved, a surprisingly large amount of backslashes might - be required, for example: - - (setq s '(a b (c d) \\\\\\\\\\\\\\\\(e f (g h) x\\\\\\\\\\\\\\\\) j k)) - - This is nearly impossible to explain(*). Instead, just remember two - points: - - * In situations like this, it's better to use DEFINE to create the - string, rather than SETQ. The example above requires only double - backslashes when DEFINE is used: - define s '(a b (c d) \\(e f (g h) x\\) j k) - * The level of quoting depends on how many levels of evaluation the - string must pass through, which is not always obvious. However, - the number of backslashes required in any given situation is - always a power of 2. So if 1 doesn't work, try 2; if 2 doesn't - work, try 4; if 4 doesn't work, try 8, 16, 32, and so on. - - Considerations like this apply in any scripting language (shell, Tcl, - Perl, Python, etc). The situation is known as "Quoting Hell". - - (*) If you really want an explanation, here it is: - - * Every SEXP has its backslash items evaluated in a single pass at - top level before being passed to the SEXP reader, so \%1, - \v(ftime), etc, can be evaluated up front, freeing the SEXP reader - of having to know about such things, which in turn makes it much - more efficient. Therefore one level of quoting is lost right away, - and therefore you must double each backslash that is to be used as - a quote. - * When the SEXP reader sees '\', it treats it as a quote; discards - it and keeps the next character. Thus '\\' becomes '\'. This would - be the end of it, except that: - * The SEXP reader must call itself recursively on its operands, so - we must double any quotes in the operands: 2^2 = 4. - * If the result is to be passed as an argument to a macro, the - backslashes must again be doubled, because the macro processor - evaluates the arguments before sending them to the macro: 2^3 = 8. - * If the macro itself is to see the quotes, rather than just the - result of the quoting, the quotes must be doubled again: 2^4 = 16. - - Moral: To create string constants in which grouping characters must be - quoted, use DEFINE rather than SETQ. - - [ [525]Top ] [ [526]Contents ] [ [527]C-Kermit Home ] [ [528]Kermit - Home ] - _________________________________________________________________ - - 9.9. Examples - - 9.9.1. Statistics - - The following program computes statistics -- means, maxima, mimima, - variance, standard deviation, and correlation -- from data stored in - parallel arrays, \&x[] and \&y[], which can contain any mixture of - integer and floating-point numbers: positive, negative, or zero. Array - setup and validation are not shown. Except for the traditional FOR - loop and printing the results at the end, the entire computation is - done with S-Expressions: - -; Initialize sums, maxima, minima, and number of elements - - (setq xsum 0 ysum 0 xsum2 0 ysum2 0 xysum 0) - (setq xmin (setq xmax \&x[1]) ymin (setq ymax \&y[1])) - (setq n \fdim(&x)) - -; Loop through elements and accumulate sums, maxima, and minima - - for i 1 n 1 { - (setq x \&x[i] y \&y[i]) ; Notational convenience - (setq xmax (max xmax x) ymax (max ymax y)) ; X and Y maxima - (setq xmin (min xmin x) ymin (min ymin y)) ; X and Y minima - (++ xsum x ysum y) ; X and Y sums - (++ xsum2 (^ x 2) ysum2 (^ y 2)) ; Sum of X and Y squares - (++ xysum (* x y)) ; Sum of XY products - } - -; Calculate results - - (setq xmean (/ xsum n) ymean (/ ysum n)) ; Mean X and Y - (setq xss (- xsum2 (/ (^ xsum 2) n))) ; Intermediate values - (setq yss (- ysum2 (/ (^ ysum 2) n))) - (setq xyss (- xysum (/ (* xsum ysum) n))) - (setq xvar (/ xss n) yvar (/ yss n)) ; X and Y variance - (setq sdx (sqrt xvar) sdy (sqrt yvar)) ; Std deviation in X and Y - (setq tmp (* xss yss)) - (setq cc (if tmp (/ xyss (sqrt tmp)) 1.0)) ; Correlation coefficient - show macro xmean ymean xvar yvar sdx sdy cc ; Print the results - - The final "if tmp" check accounts for the possibility that both arrays - contain all 0's. Results can also be printed with "echo CC = \m(cc)", - or any other desired way. Interestingly, if we had not needed the sum - of the squares and products, we could have obtained the sums, maxima, - and minima of the X's and Y's without a loop like this: - - (setq xsum (+ \fjoin(&x)) ysum (+ \fjoin(&y))) - (setq xmax (max \fjoin(&x)) ymax (max \fjoin(&y))) - (setq xmin (min \fjoin(&x)) ymin (min \fjoin(&y))) - - Any Kermit function that returns numbers or lists of numbers can be - included in an S-Expression as an operand. - _________________________________________________________________ - - 9.9.2. Practical Fibonacci Series - - The recursive Fibonacci example given previously is simple and - elegant, but not very useful since it causes memory occupation to grow - each time it calls itself, until eventually both physical memory and - disk swap space are filled and the program crashes. Even for small - arguments, like 17, execution time can be prohibitive: - - (setq t1 \v(ftime)) - (setq result (fibonacci 17)) - (setq t2 (- \v(ftime) t1)) - echo FIBONACCI(17) = \m(result): TIME = \ffpround(t2,3) - - prints (on a certain rather slow computer): - - FIBONACCI(17) = 1597: TIME = 5.861 - - Any recursive function can be recoded iteratively. The result is not - as pretty, but execution is far less expensive: - - define FIBITER { - (if (== \%3 0) (\%2) (fibiter (+ \%1 \%2) \%1 (- \%3 1))) - } - define FIBONACCI { - (fibiter 1 0 \%1) - } - - Here's the result on the same computer for the same argument of 17: - - FIBONACCI(17) = 1597: TIME = 0.015 - - (47 times faster.) Execution time increases proportionally to the size - of the argument in the iterative case, whereas in the recursive case - it goes up geometrically, quickly reaching infinity. - - [ [529]Top ] [ [530]Contents ] [ [531]C-Kermit Home ] [ [532]Kermit - Home ] - _________________________________________________________________ - - 9.10. Differences from Algebraic Notation - - In C-Kermit: - - * Algebraic notation uses infix operators and normal rules of - operator precedence, with parentheses used to force exceptions to - the rules; many operations can be included in an expression. - S-Expressions use prefix operators with no intrinsic precedence; - each operation is enclosed in parentheses, and the arrangement of - parentheses determines precedence. - * Algebraic infix operators require two operands; S-Expression - prefix operators can accept a variable number of operands. - * You can use algebraic notation anywhere that C-Kermit accepts a - number, e.g. "echo \&a[((1+1)*2-1]", but you can use S-Expressions - only as top-level commands. You can, however, use either algebraic - or S-Expressions anywhere at all by enclosing them in \fevaluate() - or \fsexpression(), respectively. - * You can use any mixture of integer and floating-point numbers in - S-Expressions, but only integers are permitted in algebraic - expressions. Outside of S-Expressions, floating point arithmetic - is supported only by \ffp...() function calls. - * Operators and operands in S-Expressions must be separated by - spaces, e.g. "(+ a b)". Spaces are not required in algebraic - expressions: "((a+b)*c)". - * When assigning values to backslash variables (such as \%x or - \&a[2]) using SETQ or LET, you must double the backslash. - - [ [533]Top ] [ [534]Contents ] [ [535]C-Kermit Home ] [ [536]Kermit - Home ] - _________________________________________________________________ - - 9.11. Differences from Lisp - - * Kermit has a lot of built-in operators not found in Lisp: ++, ^, - etc. - * Most dialects of real Lisp do not allow S-Expressions that don't - start with an operator, for example: - (a) - This expression can cause an error in Lisp (even if "a" has a - value), but is acceptable in Kermit, where it returns the value of - the variable "a". Similarly, (1) returns the value "1". - * In real Lisp, EVAL requires exactly one operand. In Kermit, it can - have 0, 1, 2, or more operands. It returns the value of the last - operand evaluated. - * Real Lisp SETQ and LET usually require an even number of operands. - Kermit allows an odd number, in which case the last (or only) - variable is undefined (i.e. deleted, destroyed). - * Kermit does not support ratios such as "7/8". Some Lisp dialects - accept ratios as numbers, and generate ratios when told to divide - two integers whose quotient is not a whole number; e.g. in Common - Lisp: - [13] USER(37): (/ (+ 1 2 3 4) 3) - 10/3 - [13] USER(38): - * The result of (/ 10 3) is 3.333.... Some Lisp dialects truncate - the result to 3 since both operands are integers, some don't; some - give the result as a ratio. C-Kermit always gives a floating point - result when there is a fractional part. If you want an integer - result, you can use TRUNCATE, FLOOR, or CEILING, e.g. (truncate (/ - 10 3)). - * There is currently no "bignum" support. Large numbers can be used - and large results generated, but (as noted in [537]Section 9.2) - they are accurate only to the precision of the underlying machine. - \v(math_precision) gives the machine precision as a number of - decimal digits, e.g. 16. - * Scientific notation for floating-point numbers is not supported. - If the magnitude of a number is greater than the precision of the - underlying hardware, the less-significant digits are shown but - their values are meaningless. If it the number is too small to be - represented internally, it is shown as "0.0". - * Many Lisp features are omitted: List processing (CAR, CDR, etc), - DEFUN, Lisp-specific control structures, and so on. - - [ [538]Top ] [ [539]Contents ] [ [540]C-Kermit Home ] [ [541]Kermit - Home ] - __________________________________________________________________________ - -10. FILE TRANSFER - - New commands and switches: - - SET TRANSFER REPORT { OFF, ON } - Enables or disables the (new) one-line message printed by - Kermit after a remote-mode file transfer to indicate the source - and destination file, complete with path, to let you know where - the file went. - - SEND /TYPE:{TEXT,BINARY} - Sends only files of the given type (see [542]Section 4). - - SEND /NOFOLLOWLINKS: - (UNIX only) Skip over symbolic links rather than following them - (default). This applies to wildcard and/or recursive SENDs; if - a single filename is given, and it happens to be a symbolic - link, the file it points to is sent. - - SEND /FOLLOWLINKS: - (UNIX only) Follow (resolve) symbolic links. Watch out for - circular links, endless loops, etc. - - SET SEND I-PACKETS { OFF, ON } - When sending commands to a Kermit server, this tells whether - command packets should be preceded by an I (information) - packet, which is used to synchronize parameters prior to - executing the command. Normally ON. The only reason to set this - OFF is for communicating with buggy Kermit servers that - misbehave when an I packet is sent to them. There is also a SET - RECEIVE I-PACKETS command, but presently it has no effect. - - SET TRANSFER MESSAGE [ text ] - Sets an initial message to be shown in the Last Message field - of the fullscreen file-transfer display. - - SET TRANSFER TRANSLATION { ON, OFF } - Inhibits or re-enables text-file transfer character-set - translation globally. - - { SEND, MSEND, GET, RECEIVE } /TRANSPARENT - Inhibits character-set translation for this transfer only. - - { GET, RECEIVE } /PIPES:{ON,OFF} - Overrides global TRANSFER PIPES setting for this transfer only; - ON allows incoming files with names like "!tar xf -" to be - opened as pipelines rather than regular files. - - The following new "hot keys" are available when Kermit's file-transfer - display is visible: - - D: Turn on debugging, open "debug.log" if not already open. - d: Turn off debugging but leave log open (if it was open). - T: Turn on debug-log timestamps. - t: Turn off debug-log timestamps. - - Other improvements: - * SET FILE DOWNLOAD-DIRECTORY now works for external protocols (e.g. - sz/rz) too. - * Improved automatic per-file text/binary switching, described in - [543]Section 4. - * When sending a file group (e.g. "send *.*"), failure to open a - file is no longer fatal; now C-Kermit simply goes ahead to the - next file. - * Transaction log entries are now made for external protocols too. - - [ [544]Top ] [ [545]Contents ] [ [546]C-Kermit Home ] [ [547]Kermit - Home ] - __________________________________________________________________________ - -11. MODEMS AND DIALING - - In C-Kermit 8.0, the default modem type for dialing has changed from - NONE (= DIRECT, meaning no modem) to GENERIC. This change should have - no impact on direct connections. For dialing, it means that, unless - you SET MODEM TYPE to a specific type, such as USROBOTICS or CONEXANT, - Kermit assumes: - - 1. The modem uses the Hayes AT command set. - 2. The modem supports error correction, data compression, and - hardware flow control and is already configured to use them. - - In fact, Kermit assumes the modem is completely configured, and - therefore does not send it an initialization string or any - configuration commands. Instead, it sends only the simplest and most - portable commands: - - ATQ0V1 Give dial result codes. - ATDTnumber Dial the number. - - (or ATD or ATDP, as appropriate). - - The new defaults work for direct connections and for most modern - modems on most platforms, and they work much faster than - "full-treatment" dialing. If the new defaults don't work for you, or - if you need to perform explicit modem configuations or interactions, - then set a specific modem type and use the SET MODEM and SET DIAL - commands as documented in Using C-Kermit. - - WARNING: Don't use the generic modem on hosts that do not support - RTS/CTS flow control. If Xon/Xoff is in use on the serial port, - you'll need to select a particular modem type so Kermit knows what - command to give it to enable Xon/Xoff flow control between itself - and your serial port. - - The following new modem types were added in C-Kermit 8.0: - - lucent: Lucent Venus chipset - pctel: PCTel V.90 chipset - conexant: Conexant (ex-Rockwell) modem family - zoom-v32bis: New name for "Zoom" - zoom-v34 Zoom V.34 - zoom-v90 Zoom V.90 56K - zoom-v92: Zoom V.92 with V.44 data compression - zoltrix-v34: New name for "zoltrix" - zoltrix-hsp-v90: Synonym for PCTel - zoltrix-hcf-v90: Synonym for ITU-T-V250 - smartlink-v90: Synonym for usrobotics (same chipset) - acer-v90: Synonym for Rockwell-v90 - - New DIAL-related variables: - - \v(dm_hf): Dial modifier: Wait for Hook-Flash. - \v(dm_wb): Dial modifier: Wait for Bong. - - Finally, if dialing fails, Kermit now prints a context-sensitive hint - suggesting possible reasons and remedies. - - Added in C-Kermit 8.0.201: Rudimentary support for Caller ID, for - use with the ANSWER command. If the modem reports Caller ID - information, Kermit stores it in variables that you can access after - the call is answered: - - \v(callid_date) The date of the call - \v(callid_time) The time of the call - \v(callid_name) The name of the caller - \v(callid_nmbr) The telephone number of the caller - \v(callid_mesg) A message - - The format of these items depends on the originating and answering - phone companies and the modems and their configuration. - - Not very many modems support Caller ID, and those that do (a) tend to - have it disabled by default, and (b) use different commands to enable - it. A quick survey shows of some current models shows: - - - USR V.90: No - - ITU-T V.250: No - - Lucent Venus: No - - Diamond Supra: #CID=1 - - Rockwell 56K: #CID=1 - - PCTEL: #CID=1 - - Zoltrix: +VCID=1 - - Conexant: +VCID=1 - - To use Kermit's Caller ID feature, you have to set the modem to wait - for at least two rings before answering, and you have to give the - command to enable Caller ID; for example (after choosing a modem with - SET MODEM TYPE): - - set modem command autoanswer on ATS0=2#CID=1\{13} - set modem command autoanswer on ATS0=2+VCID=1\{13} - - These commands can be undone with: - - set modem command autoanswer on ATS0=1#CID=0\{13} - set modem command autoanswer on ATS0=1+VCID=0\{13} - - Kermit presently has no built-in knowledge of the Caller ID - capabilities or commands of the modems in its database. - - Since the variables can be accessed only after the call is answered, - the only way to refuse a call is to answer it, inspect the variables, - and then hang it up if desired. - - [ [548]Top ] [ [549]Contents ] [ [550]C-Kermit Home ] [ [551]Kermit - Home ] - __________________________________________________________________________ - -12. TERMINAL CONNECTION - - Now that 7-bit connections are no longer the norm, the default - terminal bytesize (also called "data size" or "word size") in C-Kermit - 8.0 is 8 bits, rather than 7 bits as it was in C-Kermit 7.0 and - earlier: - - SET ESCAPE character - This command, which specifies your CONNECT-mode escape - character, allows you to specify any ASCII control character in - a variety of formats. C-Kermit 8.0.201 now also lets you - specify any 8-bit value, 128-255, as the escape character. In - the SET ESCAPE command, you can type the 8-bit character - literally or you can enter its numeric code. Here are examples - that you can enter from a terminal or console that uses the ISO - Latin-1 character set: - - C-Kermit> set escape à - C-Kermit> set escape 195 - C-Kermit> show escape - Escape character: Code 195 (Ã): enabled - C-Kermit> - - Both of these commands set the escape character value to 195 - (decimal), which happens to be uppercase letter A with Tilde in - Latin-1. SHOW ESCAPE and SHOW TERMINAL show the value, as does - the CONNECT message. - - SET TERMINAL AUTODOWNLOAD ERROR { STOP, CONTINUE } - When Kermit has a terminal connection to another computer, and - a file transfer is initiated automatically because a Kermit - packet was received in CONNECT mode (i.e. in the terminal - screen), this command tells what Kermit should do if the - transfer fails. The default is to STOP, which leaves Kermit in - command mode with its file-transfer display showing, so you can - see that the transfer failed and why. If you SET TERMINAL - AUTODOWNLOAD ERROR CONTINUE, this causes Kermit to return - automatically to its terminal screen (i.e. resume its CONNECT - session) as if the transfer had succeeded; this can be - desirable if the entire session is under control of a - host-based script. - - SET TERMINAL BYTESIZE { 7, 8 } - The byte size to use during CONNECT and INPUT command - execution, which can be more restrictive than the bytesize - implied by the current PARITY setting, but not less - restrictive. In C-Kermit 7.0 and earlier, the terminal bytesize - was 7 by default to protect against the likelihood that parity - was in use on the connection without the user's knowledge. When - the terminal bytesize is 8 (as it is in C-Kermit 8.0 and - later), the user will see garbage in this (increasingly - unlikely) situation. Note that 8 data bits are required for - most character sets other than ASCII: Latin-1, UTF-8, and so - on. - - A new command has been added to produce timestamped session logs: - - SET TERMINAL SESSION-LOG TIMESTAMPED-TEXT - Records the terminal session in text mode (like SET TERMINAL - SESSION-LOG TEXT) but adds a timestamp at the beginning of each - line. The timestamp format is hh:mm:ss.nnn, and indicates the - time at which the first character of the line appeared. - - In most UNIX versions (those built with the select()-capable CONNECT - module -- pretty much all the ones that have or could have TELNET - included), an idle timeout feature has been added: - - SET TERMINAL IDLE-TIMEOUT number - If the number is not 0, then Kermit is to take an action when - the given amount of time passes with no activity during CONNECT - mode. If the number is positive it is the maximum number of - idle seconds; if number is negative it represents milliseconds - (thousandths of seconds). If 0 is given as the number, there - are no idle timeouts. Synonym: SET TERMINAL IDLE-LIMIT. - - SET TERMINAL IDLE-ACTION { RETURN, HANGUP, EXIT, OUTPUT [ string ] } - The action to be taken upon an idle timeout in CONNECT mode. - RETURN to the prompt, HANGUP the connection, EXIT from Kermit, - or OUTPUT the given string (if no string is given, a NUL (ASCII - 0) character is sent). - - SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT } - Actions that can be selected on Telnet connections only, that - might be useful if idle limits are enforced by the Telnet - server or in the TCP/IP protocol: TELNET-NOP sends a "NO - Operation" (do-nothing) command, which causes no response from - the server; TELNET-AYT sends an "Are You There" message to the - server, which should make the server send back a message. - Neither of these actions interferes with your remote session. - - SET TERMINAL IDLE-ACTION is useful for connections to hosts or - services that automatically log you out after a certain amount of idle - time, e.g.: - - set term idle-timeout 300 - set term idle-action output \32 - - sends a space (as if you had pressed the space bar) every 300 seconds - (five minutes) while there is no activity (32 is the ASCII code for - space). - - When C-Kermit returns from CONNECT to command mode, the reason for the - transition is given in a new variable, \v(cx_status): - - 0 No CONNECT command given yet. - 1 User escaped back manually. - 2 A trigger string was encountered. - 3 IKSD entered server mode. - 4 Application Program Command received from host. - 5 Idle timeout. - 6 Telnet protocol error. - 7 Keystroke macro. - 8 Time limit exceeded. - 100 Internal error. - 101 Carrier required by not detected. - 102 I/O error on connection. - 103 Disconnected by host. - 104 Disconnected by user. - 105 Session limit exceeded. - 106 Rejected due to Telnet policy. - 107 Received kill signal. - - Values 100 and above indicate there is no connection. - - [ [552]Top ] [ [553]Contents ] [ [554]C-Kermit Home ] [ [555]Kermit - Home ] - __________________________________________________________________________ - -13. CHARACTER SETS - - See the section on [556]file scanning above, and the section on - character-set conversion in [557]FTP. Also: - - * True support for CP1252 (rather than treating it as Latin-1). - * Proper handling of C1 values when converting ISO 8-bit text to - UTF-8. - * TYPE /CHARACTER-SET: /TRANSLATE-TO: allows specific translations. - * The TRANSLATE command now works on multiple files. - * K_CHARSET environment variable to set the file character-set. - * SET TRANSFER TRANSLATION OFF. - * FTP client character-set translation ([558]Section 3.7). - - [ [559]Top ] [ [560]Contents ] [ [561]C-Kermit Home ] [ [562]Kermit - Home ] - __________________________________________________________________________ - -14. DIALOUT FROM TELNET TERMINAL SERVERS - - For years, C-Kermit has supported dialing out from Telnet modem - servers (also called reverse terminal servers or access servers), but - until now there was no way for Kermit to control the communication - parameters (speed, parity, etc) on the serial port of the terminal - server; it had to use whatever was there. - - But now, if you make a connection to a server that supports the Telnet - Com Port Control Option, [563]RFC 2217, you have the same degree of - control as you would have over a serial port on the computer where - Kermit is running: SET SPEED, SET FLOW, SET PARITY, SET STOP-BITS, - SHOW COMM, WAIT, SET CARRIER-WATCH, the modem-signal variables, - sending Break, and so on, apply to the connection between the terminal - server and the modem. - - For example, using a Cisco Access Server 2509, where specifying a TCP - port in the 6000's selects a serial port that can be used for dialing - out: - - set host xxx 6001 ; xxx is the IP hostname or address of the server - (log in if necessary) ; With a script or by hand - set modem type usr ; Tell Kermit what kind of modem it has - set speed 57600 ; This affects the server's port - set flow rts/cts ; Ditto - dial 7654321 - - The modem server might or might not require a login sequence. It might - also allow for automatic authentication, e.g. via Kerberos tickets. - NOTE: If the modem server requires a login sequence, then REDIAL might - not work as expected. - - When you have a Telnet Com Port connection, your SET SPEED and SET - FLOW options change automatically to reflect the capabilities of the - server, rather than those of your local computer. - - See the configuration manual for your server for additional - information. For example, how to set up the server to drop the Telnet - connection automatically when the telephone call is hung up (e.g. - "autohangup" on Cisco models). - - For a Linux-based Telnet Com-Port server, click the Srdird link: - - [ [564]Top ] [ [565]Contents ] [ [566]Sredird ] [ [567]C-Kermit Home ] - [ [568]Kermit Home ] - __________________________________________________________________________ - -15. COPING WITH BROKEN KERMIT PARTNERS - - There are lots of faulty Kermit protocol implementations out there, - found mainly in 3rd-party products ranging from communications - software packages to file-transfer functions imbedded within devices. - This topic is covered [569]HERE for C-Kermit 7.0, but C-Kermit 8.0 - adds some additional tricks. - - SET ATTRIBUTE RECORD-FORMAT { ON, OFF } - Allows control of the Kermit's Record-Format attribute. Set - this to OFF in case incoming file are refused due to unknown or - invalid record formats if you want to accept the file anyway. - - SET SEND I-PACKETS { ON, OFF } - A Kermit server is supposed to accept I-packets; this is how - the client lets the server know its capabilities and - preferences before sending a command. Apparently there is at - least one Kermit server implementation that does not accept - I-packets, and does not properly respond with an Error packet - if it gets one. To get around such situations in C-Kermit 8.0, - you can use SET SEND I-PACKETS OFF to inhibit the sending of I - packets. In this case, the client must be able to adjust to the - server's configuration, rather than the other way around as we - are used to. - - SET PROTOCOL KERMIT {} {} {} - C-Kermit 6.0 and later automatically send "autoupload" and - "autodownload" commands when in local mode and you give a file - transfer command. For example, if you tell kermit to "send - oofa.txt", Kermit sends "kermit -r" and a carriage return, in - case you had forgotten to start Kermit on the far end and told - it to receive a file. If a Kermit program had already been - started on the far end, it should harmlessly absorb this - string. However, some Kermit programs violate the Kermit - protocol definition and treat such strings as Kermit packets - even though they are not. In such cases, give this command to - set the Kermit protocol autoupload and download strings to - nothing, which tells Kermit not to send them. (This is not a - new feature, but it was not previously included in the "Coping" - section of the documentation.) - - [ [570]Top ] [ [571]Contents ] [ [572]C-Kermit Home ] [ [573]Kermit - Home ] - __________________________________________________________________________ - -16. NEW COMMAND-LINE OPTIONS - - kermit -h Now prints a complete listing of its command-line options, - rather than an abbreviated list squeezed into a 24x80 space. - - -dd Debug, like -d but adds timestamps - --version Shows C-Kermit version number. - --noperms Equivalent to SET ATTRIBUTE PROTECTION OFF. - - Kermit now accepts a selection of URLs (Universal Resource Locators) - as its first command-line argument. These are: - - telnet:hostname - Makes a Telnet connection to the given host (IP hostname or - address). - - ftp://[user[:password]@]hostname[/path...] - Makes an FTP connection to the given host (IP hostname or - address). If a username is given, Kermit tries to log you in; - if a password is given, it is used; if not, you are prompted - for one. If no username is given, an anonymous login is - performed. If a pathname is included, Kermit tries to GET the - given file. See [574]Section 3.1.3 for details. - - ftps://[user[:password]@]hostname[/path...] - Makes a secure FTP connection over SSL. - - telnets://[user[:password]@]hostname - Makes a secure Telnet connection over SSL. - - kermit://[user[:password]@]hostname[/path...] - Makes a connection to an [575]Internet Kermit Server. - - http://[user[:password]@]hostname[/path...] - Makes a connection to Web server. - - https://[user[:password]@]hostname[/path...] - Makes a connection to secure Web server. - - [ [576]Top ] [ [577]Contents ] [ [578]C-Kermit Home ] [ [579]Kermit - Home ] - __________________________________________________________________________ - -17. LOGS - - In C-Kermit 8.0, we make an effort to keep passwords out of the debug - log. This can never be 100% effective, but it's better than before, - when there were no precautions at all. Whenever Kermit knows it's - prompting for, parsing, or transmitting a password, it temporarily - turns off logging and then turns it back on afterwards. This keeps the - debug log password-free in most common cases, but there can be no - guarantees. - - As noted elsewhere, the new "-dd" command-line option selects a - timestamped debug log (equivalent to "set debug timestamps on", "log - debug debug.log"). - - C-Kermit 8.0 also supports a new timestamped session log via "set - session-log timestamped-text", "log session". - - There have been requests for other kinds of logs, for example a - command log. These might be added at some point. One person wanted to - be able to log commands with timestamps, but only commands issued at - the prompt, not commands from files or macros, and also wanted a - header line at the beginning showing the date, user, and host. This - can be done as follows: - - .filename := \v(home)commands.log ; (for example) - fopen /write \%c \m(filename) - if success { - fwrite /line \%c \v(date): User=\v(user) Host=\v(host) - fclose \%c - set debug timestamps on - log debug {| grep "CMD(P)" >> \m(filename)} append - } - - [ [580]Top ] [ [581]Contents ] [ [582]C-Kermit Home ] [ [583]Kermit - Home ] - _________________________________________________________________ - - C-Kermit 8.0 Update Notes / [584]The Kermit Project / Columbia - University / 15 Dec 2003 - -References - - 1. http://www.columbia.edu/kermit/ckermit80.html#contents - 2. http://www.columbia.edu/kermit/ckermit.html - 3. http://www.columbia.edu/kermit/index.html - 4. http://www.columbia.edu/kermit/ckermit80.html - 5. mailto:kermit-support@columbia.edu - 6. http://www.columbia.edu/kermit/ - 7. http://www.kermit-project.org/ - 8. http://www.columbia.nyc.ny.us/kermit/ - 9. ftp://kermit.columbia.edu/kermit/f/COPYING.TXT - 10. ftp://kermit.columbia.edu/kermit/f/ckcmai.c - 11. http://www.columbia.edu/kermit/ckermit80.html#xv - 12. http://www.columbia.edu/kermit/ck60manual.html - 13. http://www.columbia.edu/kermit/ckermi70.html - 14. ftp://kermit.columbia.edu/kermit/f/ckermit70.txt - 15. http://www.columbia.edu/kermit/ckututor.html - 16. ftp://kermit.columbia.edu/kermit/f/ckuker.nr - 17. http://www.columbia.edu/kermit/security.htm - 18. http://www.columbia.edu/kermit/telnet.htm - 19. http://www.columbia.edu/kermit/ftpscripts.html - 20. http://www.columbia.edu/kermit/ckcbwr.html - 21. ftp://kermit.columbia.edu/kermit/f/ckcbwr.txt - 22. http://www.columbia.edu/kermit/ckubwr.html - 23. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt - 24. http://www.columbia.edu/kermit/ckvbwr.html - 25. ftp://kermit.columbia.edu/kermit/f/ckvbwr.txt - 26. http://www.columbia.edu/kermit/ckuins.html - 27. ftp://kermit.columbia.edu/kermit/f/ckuins.txt - 28. http://www.columbia.edu/kermit/ckvins.html - 29. ftp://kermit.columbia.edu/kermit/f/ckvins.txt - 30. http://www.columbia.edu/kermit/ckccfg.html - 31. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt - 32. http://www.columbia.edu/kermit/ckcplm.html - 33. ftp://kermit.columbia.edu/kermit/f/ckcplm.txt - 34. http://www.columbia.edu/kermit/iksd.html - 35. http://www.columbia.edu/kermit/skermit.html - 36. http://www.columbia.edu/kermit/ckermit80.html#top - 37. http://www.columbia.edu/kermit/ckermit.html - 38. http://www.columbia.edu/kermit/index.html - 39. http://www.columbia.edu/kermit/ckermit80.html#x0 - 40. http://www.columbia.edu/kermit/ckermit80.html#x1 - 41. http://www.columbia.edu/kermit/ckermit80.html#x2 - 42. http://www.columbia.edu/kermit/ckermit80.html#x2.1 - 43. http://www.columbia.edu/kermit/ckermit80.html#x2.2 - 44. http://www.columbia.edu/kermit/ckermit80.html#x2.2.1 - 45. http://www.columbia.edu/kermit/ckermit80.html#x2.2.2 - 46. http://www.columbia.edu/kermit/ckermit80.html#x2.2.3 - 47. http://www.columbia.edu/kermit/ckermit80.html#x2.2.4 - 48. http://www.columbia.edu/kermit/ckermit80.html#x2.2.5 - 49. http://www.columbia.edu/kermit/ckermit80.html#x2.2.6 - 50. http://www.columbia.edu/kermit/ckermit80.html#x3 - 51. http://www.columbia.edu/kermit/ckermit80.html#x3.1 - 52. http://www.columbia.edu/kermit/ckermit80.html#x3.1.1 - 53. http://www.columbia.edu/kermit/ckermit80.html#x3.1.2 - 54. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3 - 55. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4 - 56. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 57. http://www.columbia.edu/kermit/ckermit80.html#x3.3 - 58. http://www.columbia.edu/kermit/ckermit80.html#x3.4 - 59. http://www.columbia.edu/kermit/ckermit80.html#x3.5 - 60. http://www.columbia.edu/kermit/ckermit80.html#x3.5.1 - 61. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2 - 62. http://www.columbia.edu/kermit/ckermit80.html#x3.5.3 - 63. http://www.columbia.edu/kermit/ckermit80.html#x3.6 - 64. http://www.columbia.edu/kermit/ckermit80.html#x3.6.1 - 65. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2 - 66. http://www.columbia.edu/kermit/ckermit80.html#x3.6.3 - 67. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 68. http://www.columbia.edu/kermit/ckermit80.html#x3.7.1 - 69. http://www.columbia.edu/kermit/ckermit80.html#x3.7.2 - 70. http://www.columbia.edu/kermit/ckermit80.html#x3.8 - 71. http://www.columbia.edu/kermit/ckermit80.html#x3.9 - 72. http://www.columbia.edu/kermit/ckermit80.html#x3.10 - 73. http://www.columbia.edu/kermit/ckermit80.html#x3.10.1 - 74. http://www.columbia.edu/kermit/ckermit80.html#x3.10.2 - 75. http://www.columbia.edu/kermit/ckermit80.html#x3.10.3 - 76. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 77. http://www.columbia.edu/kermit/ckermit80.html#x4 - 78. http://www.columbia.edu/kermit/ckermit80.html#x5 - 79. http://www.columbia.edu/kermit/ckermit80.html#x6 - 80. http://www.columbia.edu/kermit/ckermit80.html#x6.1 - 81. http://www.columbia.edu/kermit/ckermit80.html#x6.2 - 82. http://www.columbia.edu/kermit/ckermit80.html#x6.3 - 83. http://www.columbia.edu/kermit/ckermit80.html#x6.4 - 84. http://www.columbia.edu/kermit/ckermit80.html#x6.5 - 85. http://www.columbia.edu/kermit/ckermit80.html#x6.6 - 86. http://www.columbia.edu/kermit/ckermit80.html#x7 - 87. http://www.columbia.edu/kermit/ckermit80.html#x8 - 88. http://www.columbia.edu/kermit/ckermit80.html#x8.1 - 89. http://www.columbia.edu/kermit/ckermit80.html#x8.2 - 90. http://www.columbia.edu/kermit/ckermit80.html#x8.3 - 91. http://www.columbia.edu/kermit/ckermit80.html#x8.4 - 92. http://www.columbia.edu/kermit/ckermit80.html#x8.5 - 93. http://www.columbia.edu/kermit/ckermit80.html#x8.6 - 94. http://www.columbia.edu/kermit/ckermit80.html#x8.7 - 95. http://www.columbia.edu/kermit/ckermit80.html#x8.8 - 96. http://www.columbia.edu/kermit/ckermit80.html#x8.9 - 97. http://www.columbia.edu/kermit/ckermit80.html#x8.10 - 98. http://www.columbia.edu/kermit/ckermit80.html#x8.11 - 99. http://www.columbia.edu/kermit/ckermit80.html#x8.12 - 100. http://www.columbia.edu/kermit/ckermit80.html#x8.13 - 101. http://www.columbia.edu/kermit/ckermit80.html#x8.14 - 102. http://www.columbia.edu/kermit/ckermit80.html#x9 - 103. http://www.columbia.edu/kermit/ckermit80.html#x9.1 - 104. http://www.columbia.edu/kermit/ckermit80.html#x9.2 - 105. http://www.columbia.edu/kermit/ckermit80.html#x9.3 - 106. http://www.columbia.edu/kermit/ckermit80.html#x9.4 - 107. http://www.columbia.edu/kermit/ckermit80.html#x9.5 - 108. http://www.columbia.edu/kermit/ckermit80.html#x9.6 - 109. http://www.columbia.edu/kermit/ckermit80.html#x9.7 - 110. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 111. http://www.columbia.edu/kermit/ckermit80.html#x9.9 - 112. http://www.columbia.edu/kermit/ckermit80.html#x9.10 - 113. http://www.columbia.edu/kermit/ckermit80.html#x9.11 - 114. http://www.columbia.edu/kermit/ckermit80.html#x10 - 115. http://www.columbia.edu/kermit/ckermit80.html#x11 - 116. http://www.columbia.edu/kermit/ckermit80.html#x12 - 117. http://www.columbia.edu/kermit/ckermit80.html#x13 - 118. http://www.columbia.edu/kermit/ckermit80.html#x14 - 119. http://www.columbia.edu/kermit/ckermit80.html#x15 - 120. http://www.columbia.edu/kermit/ckermit80.html#x16 - 121. http://www.columbia.edu/kermit/ckermit80.html#x17 - 122. http://www.columbia.edu/kermit/ckermit80.html#top - 123. http://www.columbia.edu/kermit/ckermit.html - 124. http://www.columbia.edu/kermit/index.html - 125. http://www.columbia.edu/kermit/ckuins.html#x5 - 126. http://www.columbia.edu/kermit/ckuins.html - 127. http://www.columbia.edu/kermit/ckermit80.html#x5 - 128. http://www.columbia.edu/kermit/ckermit80.html#x2.2 - 129. http://www.columbia.edu/kermit/ckermit80.html#contents - 130. http://www.columbia.edu/kermit/ckermit80.html#x15 - 131. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 132. http://www.columbia.edu/kermit/ckermit80.html#ftpdates - 133. http://www.columbia.edu/kermit/ckermit80.html#ftpcheck - 134. http://www.columbia.edu/kermit/ckermit80.html#ftpnamelist - 135. http://www.columbia.edu/kermit/ckermit80.html#srvrename - 136. http://www.columbia.edu/kermit/ckermit80.html#ftpvdir - 137. http://www.columbia.edu/kermit/ckermit80.html#setftptype - 138. http://www.columbia.edu/kermit/ckermit80.html#x3.6 - 139. http://www.columbia.edu/kermit/ckermit80.html#x15 - 140. http://www.columbia.edu/kermit/ckermit80.html#x8.7 - 141. http://www.columbia.edu/kermit/ckermit80.html#x2.1 - 142. http://www.columbia.edu/kermit/ckermit80.html#x2.2 - 143. http://www.columbia.edu/kermit/ckermit80.html#x8.14 - 144. http://www.columbia.edu/kermit/ckermit80.html#x8.13 - 145. http://www.columbia.edu/kermit/ckermit80.html#x8.13 - 146. http://www.columbia.edu/kermit/ckututor.html - 147. http://www.columbia.edu/kermit/ckuins.html - 148. http://www.columbia.edu/kermit/skermit.html - 149. http://www.columbia.edu/kermit/ckermit80.html#setlocus - 150. http://www.columbia.edu/kermit/ckermit80.html#lcommands - 151. http://www.columbia.edu/kermit/ckermit80.html#ftpuser - 152. http://www.columbia.edu/kermit/ckermit80.html#showvar - 153. http://www.columbia.edu/kermit/ckermit80.html#callerid - 154. http://www.columbia.edu/kermit/ckermit80.html#x6.6 - 155. http://www.columbia.edu/kermit/ckermit80.html#x0 - 156. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 157. http://www.columbia.edu/kermit/ckermit80.html#top - 158. http://www.columbia.edu/kermit/ckermit80.html#contents - 159. http://www.columbia.edu/kermit/ckermit.html - 160. http://www.columbia.edu/kermit/index.html - 161. http://www.columbia.edu/kermit/ckermit80.html#x0 - 162. http://www.columbia.edu/kermit/ckermit80.html#top - 163. http://www.columbia.edu/kermit/ckermit80.html#contents - 164. http://www.columbia.edu/kermit/ckermit.html - 165. http://www.columbia.edu/kermit/index.html - 166. http://www.columbia.edu/kermit/k95.html - 167. http://www.columbia.edu/kermit/sshclient.html - 168. http://www.columbia.edu/kermit/skermit.html - 169. http://www.columbia.edu/kermit/skermit.html - 170. http://www.columbia.edu/kermit/sshclien.htm - 171. http://www.columbia.edu/kermit/ckermit80.html#x3 - 172. ftp://ftp.isi.edu/in-notes/rfc1738.txt - 173. http://www.columbia.edu/kermit/ckermit80.html#x2.2.2 - 174. http://www.columbia.edu/kermit/ckermit80.html#x2.2.1 - 175. ftp://ftp.isi.edu/in-notes/rfc2396.txt - 176. ftp://ftp.isi.edu/in-notes/rfc2616.txt - 177. http://www.columbia.edu/kermit/ckermit80.html#x2.2.3 - 178. ftp://ftp.isi.edu/in-notes/rfc2616.txt - 179. http://www.columbia.edu/kermit/ckermit80.html#x8.13.7 - 180. http://www.columbia.edu/kermit/security.htm#x5.4 - 181. http://www.columbia.edu/kermit/security.htm#x15 - 182. http://www.columbia.edu/kermit/security.htm#x6.2 - 183. http://www.columbia.edu/kermit/security.html - 184. http://www.columbia.edu/kermit/ckermit80.html#x16 - 185. http://www.columbia.edu/kermit/ckermit80.html#top - 186. http://www.columbia.edu/kermit/ckermit80.html#contents - 187. http://www.columbia.edu/kermit/ckermit.html - 188. http://www.columbia.edu/kermit/index.html - 189. http://www.columbia.edu/kermit/ckermit80.html#x3.1 - 190. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 191. http://www.columbia.edu/kermit/ckermit80.html#x3.3 - 192. http://www.columbia.edu/kermit/ckermit80.html#x3.4 - 193. http://www.columbia.edu/kermit/ckermit80.html#x3.5 - 194. http://www.columbia.edu/kermit/ckermit80.html#x3.6 - 195. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 196. http://www.columbia.edu/kermit/ckermit80.html#x3.8 - 197. http://www.columbia.edu/kermit/ckermit80.html#x3.9 - 198. http://www.columbia.edu/kermit/ckermit80.html#x3.10 - 199. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 200. http://www.columbia.edu/kermit/security.htm - 201. http://www.columbia.edu/kermit/security.htm#servers - 202. http://www.columbia.edu/kermit/ckcsets.html - 203. http://www.columbia.edu/kermit/unicode.html - 204. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4 - 205. http://www.columbia.edu/kermit/case10.html - 206. http://www.columbia.edu/kermit/ckermit80.html#x4 - 207. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 208. http://www.columbia.edu/kermit/ftpscripts.html - 209. http://www.columbia.edu/kermit/ckermit80.html#top - 210. http://www.columbia.edu/kermit/ckermit80.html#ftp - 211. http://www.columbia.edu/kermit/ftpclient.html - 212. http://www.columbia.edu/kermit/ftpscripts.html - 213. http://www.columbia.edu/kermit/ckermit.html - 214. http://www.columbia.edu/kermit/index.html - 215. http://www.columbia.edu/kermit/ckermit80.html#x3.1.1 - 216. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3 - 217. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4 - 218. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3 - 219. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3 - 220. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 221. http://www.columbia.edu/kermit/ckermit80.html#x3.5 - 222. http://www.columbia.edu/kermit/ckermit80.html#x3.6 - 223. http://www.columbia.edu/kermit/ftpscripts.html - 224. http://www.columbia.edu/kermit/ckb2.htm - 225. http://www.columbia.edu/kermit/ckermit80.html#ftpautolog - 226. http://www.columbia.edu/kermit/ckermit80.html#ftpuser - 227. http://www.columbia.edu/kermit/ckermit80.html#x3.8 - 228. http://www.columbia.edu/kermit/ckermit80.html#x3.8 - 229. http://www.columbia.edu/kermit/ckermit80.html#top - 230. http://www.columbia.edu/kermit/ckermit80.html#ftp - 231. http://www.columbia.edu/kermit/ckermit.html - 232. http://www.columbia.edu/kermit/index.html - 233. http://www.columbia.edu/kermit/ibm_ie.html - 234. http://www.columbia.edu/kermit/ckermit80.html#x3.10 - 235. http://www.columbia.edu/kermit/ckermit80.html#top - 236. http://www.columbia.edu/kermit/ckermit80.html#ftp - 237. http://www.columbia.edu/kermit/ckermit.html - 238. http://www.columbia.edu/kermit/index.html - 239. http://www.columbia.edu/kermit/ck60manual.html - 240. http://www.columbia.edu/kermit/ckermit70.html#x4.17 - 241. http://www.columbia.edu/kermit/ckermit70.html - 242. http://www.columbia.edu/kermit/ckermit80.html#x3.6 - 243. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 244. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4 - 245. http://www.columbia.edu/kermit/security.html - 246. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 247. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 248. http://www.columbia.edu/kermit/ckermit80.html#x8.13.4 - 249. http://www.columbia.edu/kermit/ckermit80.html#permswitch - 250. http://www.columbia.edu/kermit/ckermit80.html#ftpchmod - 251. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2 - 252. http://www.columbia.edu/kermit/ckermit80.html#x4 - 253. http://www.columbia.edu/kermit/ckermit80.html#top - 254. http://www.columbia.edu/kermit/ckermit80.html#ftp - 255. http://www.columbia.edu/kermit/ckermit.html - 256. http://www.columbia.edu/kermit/index.html - 257. http://www.columbia.edu/kermit/ckermit80.html#x7 - 258. http://www.columbia.edu/kermit/ckermit80.html#x3.8 - 259. http://www.columbia.edu/kermit/ckermit80.html#x3.8 - 260. http://www.columbia.edu/kermit/ckb2.htm - 261. http://www.columbia.edu/kermit/ckermit80.html#x3.10 - 262. http://www.columbia.edu/kermit/ckermit80.html#x3.10 - 263. http://www.columbia.edu/kermit/ckermit80.html#x3.6 - 264. http://www.columbia.edu/kermit/ckermit80.html#setftptype - 265. http://www.columbia.edu/kermit/ckermit80.html#top - 266. http://www.columbia.edu/kermit/ckermit80.html#ftp - 267. http://www.columbia.edu/kermit/ckermit.html - 268. http://www.columbia.edu/kermit/index.html - 269. http://www.columbia.edu/kermit/ckermit70.html#x4.9 - 270. http://www.columbia.edu/kermit/ckermit80.html#x3.5.1 - 271. http://www.columbia.edu/kermit/ckermit80.html#erroraction - 272. http://www.columbia.edu/kermit/ckermit70.html#x1.5 - 273. http://www.columbia.edu/kermit/ckermit70.html#x4.7 - 274. http://www.columbia.edu/kermit/ckermit70.html#x1.6 - 275. http://www.columbia.edu/kermit/ckermit80.html#x8.13 - 276. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4 - 277. http://www.columbia.edu/kermit/ckermi70.htm - 278. http://www.columbia.edu/kermit/ckermit80.html#x4 - 279. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 280. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2 - 281. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 282. http://www.columbia.edu/kermit/ckermit80.html#erroraction - 283. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2 - 284. http://www.columbia.edu/kermit/ckermit80.html#erroraction - 285. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames - 286. http://www.columbia.edu/kermit/ckermit80.html#ftpperms - 287. http://www.columbia.edu/kermit/ckermit80.html#ftpunique - 288. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames - 289. http://www.columbia.edu/kermit/ckermit80.html#note_utc - 290. http://www.columbia.edu/kermit/ckermit80.html#note_date - 291. http://www.columbia.edu/kermit/ckermit80.html#x3.6 - 292. http://www.boulder.nist.gov/timefreq/faq/faq.htm#10: - 293. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 294. http://www.columbia.edu/kermit/ckermit80.html#top - 295. http://www.columbia.edu/kermit/ckermit80.html#ftp - 296. http://www.columbia.edu/kermit/ckermit.html - 297. http://www.columbia.edu/kermit/index.html - 298. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 299. http://www.columbia.edu/kermit/ckermi70.htm#x4.3 - 300. http://www.columbia.edu/kermit/ckermit70.html - 301. http://www.columbia.edu/kermit/ckermit80.html#x5 - 302. http://www.columbia.edu/kermit/ckermit80.html#x3.6.3 - 303. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames - 304. http://www.columbia.edu/kermit/ckermi70.htm#x4.1 - 305. http://www.columbia.edu/kermit/ckermi70.htm#x4.2.2 - 306. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4 - 307. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2 - 308. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 309. http://www.columbia.edu/kermit/ckermit80.html#x3.11 - 310. http://www.columbia.edu/kermit/ckermit80.html#srvrename - 311. http://www.columbia.edu/kermit/ckermi70.htm#x4.1 - 312. http://www.columbia.edu/kermit/ckermi70.htm - 313. http://www.columbia.edu/kermit/ckb2.htm - 314. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames - 315. http://www.columbia.edu/kermit/ckermit80.html#x3.5.3 - 316. http://www.proftpd.net/ - 317. http://www.columbia.edu/kermit/ckermit80.html#top - 318. http://www.columbia.edu/kermit/ckermit80.html#ftp - 319. http://www.columbia.edu/kermit/ckermit.html - 320. http://www.columbia.edu/kermit/index.html - 321. http://www.columbia.edu/kermit/ckb2.htm - 322. http://www.columbia.edu/kermit/ckcsets.html - 323. http://www.columbia.edu/kermit/unicode.html - 324. http://www.columbia.edu/kermit/ckcsets.html - 325. http://www.columbia.edu/kermit/ckcsets.html - 326. http://www.columbia.edu/kermit/ckermit80.html#x4 - 327. http://www.columbia.edu/kermit/utf8.html - 328. http://www.columbia.edu/kermit/ckcsets.html - 329. http://www.columbia.edu/kermit/ckermit80.html#x4 - 330. ftp://ftp.isi.edu/in-notes/rfc2640.txt - 331. http://www.columbia.edu/kermit/ckermit80.html#top - 332. http://www.columbia.edu/kermit/ckermit80.html#ftp - 333. http://www.columbia.edu/kermit/ckermit.html - 334. http://www.columbia.edu/kermit/index.html - 335. http://www.columbia.edu/kermit/ckermit80.html#top - 336. http://www.columbia.edu/kermit/ckermit80.html#ftp - 337. http://www.columbia.edu/kermit/ckermit.html - 338. http://www.columbia.edu/kermit/index.html - 339. http://www.columbia.edu/kermit/ckermit80.html#top - 340. http://www.columbia.edu/kermit/ckermit80.html#ftp - 341. http://www.columbia.edu/kermit/ckermit.html - 342. http://www.columbia.edu/kermit/index.html - 343. http://www.columbia.edu/kermit/ftpscripts.html - 344. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 345. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 346. ftp://ftp.isi.edu/in-notes/rfc959.txt - 347. http://www.columbia.edu/kermit/ckscripts.html - 348. http://www.columbia.edu/kermit/ckermit80.html#top - 349. http://www.columbia.edu/kermit/ckermit80.html#ftp - 350. http://www.columbia.edu/kermit/ftpscript.html - 351. http://www.columbia.edu/kermit/ckermit.html - 352. http://www.columbia.edu/kermit/index.html - 353. http://www.columbia.edu/kermit/ckermit80.html#x3.11.1 - 354. http://www.columbia.edu/kermit/ckermit80.html#x3.11.2 - 355. http://www.columbia.edu/kermit/ckermit80.html#x3.11.3 - 356. http://www.columbia.edu/kermit/ckermit80.html#x3.11.4 - 357. http://www.columbia.edu/kermit/ckermit80.html#x3.11.5 - 358. http://www.columbia.edu/kermit/ckermit.html - 359. http://www.columbia.edu/kermit/k95.html - 360. http://www.columbia.edu/kermit/ckermit80.html#x3.11.5 - 361. ftp://ftp.isi.edu/in-notes/rfc959.txt - 362. ftp://ftp.isi.edu/in-notes/rfc2389.txt - 363. http://www.ietf.org/internet-drafts/draft-ietf-ftpext-mlst-16.txt - 364. http://www.columbia.edu/kermit/ftpclient.html - 365. http://www.columbia.edu/kermit/ckermit80.html#top - 366. http://www.columbia.edu/kermit/ckermit80.html#ftp - 367. http://www.columbia.edu/kermit/ckermit.html - 368. http://www.columbia.edu/kermit/index.html - 369. http://www.columbia.edu/kermit/ckermit80.html#x3 - 370. http://www.columbia.edu/kermit/ckermit80.html#ucs2 - 371. http://www.columbia.edu/kermit/ckermit80.html#top - 372. http://www.columbia.edu/kermit/ckermit80.html#contents - 373. http://www.columbia.edu/kermit/ckermit.html - 374. http://www.columbia.edu/kermit/index.html - 375. http://www.columbia.edu/kermit/ckermit80.html#top - 376. http://www.columbia.edu/kermit/ckermit80.html#contents - 377. http://www.columbia.edu/kermit/ckermit.html - 378. http://www.columbia.edu/kermit/index.html - 379. http://www.columbia.edu/kermit/ckb2.htm - 380. http://www.columbia.edu/kermit/ckermit80.html#top - 381. http://www.columbia.edu/kermit/ckermit80.html#contents - 382. http://www.columbia.edu/kermit/ckermit.html - 383. http://www.columbia.edu/kermit/index.html - 384. http://www.columbia.edu/kermit/ckermit80.html#x4 - 385. http://www.columbia.edu/kermit/ckermit80.html#x4 - 386. http://www.columbia.edu/kermit/ckermit80.html#x8.12 - 387. http://www.columbia.edu/kermit/ckermit80.html#x8.1 - 388. http://www.columbia.edu/kermit/ckermit80.html#x12 - 389. http://www.columbia.edu/kermit/ckermit80.html#x8.12 - 390. http://www.columbia.edu/kermit/ckermit80.html#top - 391. http://www.columbia.edu/kermit/ckermit80.html#contents - 392. http://www.columbia.edu/kermit/ckermit.html - 393. http://www.columbia.edu/kermit/index.html - 394. http://www.columbia.edu/kermit/ckermit80.html#x8.14 - 395. http://www.columbia.edu/kermit/ckermit80.html#top - 396. http://www.columbia.edu/kermit/ckermit80.html#contents - 397. http://www.columbia.edu/kermit/ckermit.html - 398. http://www.columbia.edu/kermit/index.html - 399. http://www.columbia.edu/kermit/ckermit80.html#x9 - 400. http://www.columbia.edu/kermit/ckermit80.html#top - 401. http://www.columbia.edu/kermit/ckermit80.html#contents - 402. http://www.columbia.edu/kermit/ckermit.html - 403. http://www.columbia.edu/kermit/index.html - 404. http://www.columbia.edu/kermit/ckermit80.html#x8.6 - 405. http://www.columbia.edu/kermit/ckermit80.html#top - 406. http://www.columbia.edu/kermit/ckermit80.html#contents - 407. http://www.columbia.edu/kermit/ckermit.html - 408. http://www.columbia.edu/kermit/index.html - 409. http://www.columbia.edu/kermit/ckermit80.html#top - 410. http://www.columbia.edu/kermit/ckermit80.html#contents - 411. http://www.columbia.edu/kermit/ckermit.html - 412. http://www.columbia.edu/kermit/index.html - 413. http://www.columbia.edu/kermit/ckermit80.html#top - 414. http://www.columbia.edu/kermit/ckermit80.html#contents - 415. http://www.columbia.edu/kermit/ckermit.html - 416. http://www.columbia.edu/kermit/index.html - 417. http://www.columbia.edu/kermit/ckermit80.html#fjoin - 418. http://www.columbia.edu/kermit/ckermit80.html#fsplit - 419. http://www.columbia.edu/kermit/ckermit80.html#x8.10 - 420. http://www.columbia.edu/kermit/ckermit80.html#top - 421. http://www.columbia.edu/kermit/ckermit80.html#contents - 422. http://www.columbia.edu/kermit/ckermit.html - 423. http://www.columbia.edu/kermit/index.html - 424. http://www.columbia.edu/kermit/ckermit80.html#x9 - 425. http://www.columbia.edu/kermit/ckermit80.html#x9 - 426. http://www.columbia.edu/kermit/ckermit80.html#x9 - 427. http://www.columbia.edu/kermit/ckermit80.html#x3 - 428. http://www.columbia.edu/kermit/ckermit80.html#x3 - 429. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 430. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 431. http://www.columbia.edu/kermit/ckermit80.html#x3.8 - 432. http://www.columbia.edu/kermit/ckermit80.html#x3 - 433. http://www.columbia.edu/kermit/ckermit80.html#x3 - 434. http://www.columbia.edu/kermit/ckermit80.html#x3 - 435. http://www.columbia.edu/kermit/ckermit80.html#x3.2 - 436. http://www.columbia.edu/kermit/ckermit80.html#x3 - 437. http://www.columbia.edu/kermit/ckermit80.html#x8.13 - 438. http://www.columbia.edu/kermit/ckermit80.html#x8.13 - 439. http://www.columbia.edu/kermit/ckermit80.html#x9 - 440. http://www.columbia.edu/kermit/ckermit80.html#x8.10 - 441. http://www.columbia.edu/kermit/ckermit80.html#x8.7.4 - 442. http://www.columbia.edu/kermit/ckermit80.html#top - 443. http://www.columbia.edu/kermit/ckermit80.html#contents - 444. http://www.columbia.edu/kermit/ckermit.html - 445. http://www.columbia.edu/kermit/index.html - 446. http://www.columbia.edu/kermit/ckermit80.html#top - 447. http://www.columbia.edu/kermit/ckermit80.html#contents - 448. http://www.columbia.edu/kermit/ckermit.html - 449. http://www.columbia.edu/kermit/index.html - 450. http://www.columbia.edu/kermit/ckermit80.html#top - 451. http://www.columbia.edu/kermit/ckermit80.html#contents - 452. http://www.columbia.edu/kermit/ckermit.html - 453. http://www.columbia.edu/kermit/index.html - 454. http://www.columbia.edu/kermit/ckermit80.html#x8.7 - 455. http://www.columbia.edu/kermit/ckermit80.html#top - 456. http://www.columbia.edu/kermit/ckermit80.html#contents - 457. http://www.columbia.edu/kermit/ckermit.html - 458. http://www.columbia.edu/kermit/index.html - 459. http://www.columbia.edu/kermit/ckermit80.html#scriptedit - 460. http://www.columbia.edu/kermit/ckermit80.html#top - 461. http://www.columbia.edu/kermit/ckermit80.html#contents - 462. http://www.columbia.edu/kermit/ckermit.html - 463. http://www.columbia.edu/kermit/index.html - 464. http://www.columbia.edu/kermit/ckermit80.html#top - 465. http://www.columbia.edu/kermit/ckermit80.html#contents - 466. http://www.columbia.edu/kermit/ckermit.html - 467. http://www.columbia.edu/kermit/index.html - 468. ftp://ftp.isi.edu/in-notes/rfc2822.txt - 469. ftp://ftp.isi.edu/in-notes/rfc2822.txt - 470. ftp://ftp.isi.edu/in-notes/rfc2822.txt - 471. ftp://ftp.isi.edu/in-notes/rfc2822.txt - 472. http://www.columbia.edu/kermit/ckermit80.html#top - 473. http://www.columbia.edu/kermit/ckermit80.html#contents - 474. http://www.columbia.edu/kermit/ckermit.html - 475. http://www.columbia.edu/kermit/index.html - 476. http://www.columbia.edu/kermit/ckermit80.html#x8.1 - 477. http://www.columbia.edu/kermit/ckermit80.html#top - 478. http://www.columbia.edu/kermit/ckermit80.html#contents - 479. http://www.columbia.edu/kermit/ckermit.html - 480. http://www.columbia.edu/kermit/index.html - 481. http://www.columbia.edu/kermit/ckermit80.html#x8.2 - 482. http://www.columbia.edu/kermit/ckermit80.html#top - 483. http://www.columbia.edu/kermit/ckermit80.html#contents - 484. http://www.columbia.edu/kermit/ckermit.html - 485. http://www.columbia.edu/kermit/index.html - 486. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 487. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 488. http://www.columbia.edu/kermit/ckermit80.html#x8.2 - 489. http://www.columbia.edu/kermit/ckermit80.html#top - 490. http://www.columbia.edu/kermit/ckermit80.html#contents - 491. http://www.columbia.edu/kermit/ckermit.html - 492. http://www.columbia.edu/kermit/index.html - 493. http://www.columbia.edu/kermit/ckermit80.html#top - 494. http://www.columbia.edu/kermit/ckermit80.html#contents - 495. http://www.columbia.edu/kermit/ckermit.html - 496. http://www.columbia.edu/kermit/index.html - 497. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 498. http://www.columbia.edu/kermit/ckermit80.html#top - 499. http://www.columbia.edu/kermit/ckermit80.html#contents - 500. http://www.columbia.edu/kermit/ckermit.html - 501. http://www.columbia.edu/kermit/index.html - 502. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 503. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 504. http://www.columbia.edu/kermit/ckermit80.html#x9.6 - 505. http://www.columbia.edu/kermit/ckermit80.html#top - 506. http://www.columbia.edu/kermit/ckermit80.html#contents - 507. http://www.columbia.edu/kermit/ckermit.html - 508. http://www.columbia.edu/kermit/index.html - 509. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 510. http://www.columbia.edu/kermit/ckermit80.html#x9.8 - 511. http://www.columbia.edu/kermit/ckermit80.html#top - 512. http://www.columbia.edu/kermit/ckermit80.html#contents - 513. http://www.columbia.edu/kermit/ckermit.html - 514. http://www.columbia.edu/kermit/index.html - 515. http://www.columbia.edu/kermit/ckermit80.html#top - 516. http://www.columbia.edu/kermit/ckermit80.html#contents - 517. http://www.columbia.edu/kermit/ckermit.html - 518. http://www.columbia.edu/kermit/index.html - 519. http://www.columbia.edu/kermit/ckermit80.html#top - 520. http://www.columbia.edu/kermit/ckermit80.html#contents - 521. http://www.columbia.edu/kermit/ckermit.html - 522. http://www.columbia.edu/kermit/index.html - 523. mailto:thucdat@hotmail.com - 524. http://www.columbia.edu/kermit/ckermit80.html#x9.9.2 - 525. http://www.columbia.edu/kermit/ckermit80.html#top - 526. http://www.columbia.edu/kermit/ckermit80.html#contents - 527. http://www.columbia.edu/kermit/ckermit.html - 528. http://www.columbia.edu/kermit/index.html - 529. http://www.columbia.edu/kermit/ckermit80.html#top - 530. http://www.columbia.edu/kermit/ckermit80.html#contents - 531. http://www.columbia.edu/kermit/ckermit.html - 532. http://www.columbia.edu/kermit/index.html - 533. http://www.columbia.edu/kermit/ckermit80.html#top - 534. http://www.columbia.edu/kermit/ckermit80.html#contents - 535. http://www.columbia.edu/kermit/ckermit.html - 536. http://www.columbia.edu/kermit/index.html - 537. http://www.columbia.edu/kermit/ckermit80.html#x9.2 - 538. http://www.columbia.edu/kermit/ckermit80.html#top - 539. http://www.columbia.edu/kermit/ckermit80.html#contents - 540. http://www.columbia.edu/kermit/ckermit.html - 541. http://www.columbia.edu/kermit/index.html - 542. http://www.columbia.edu/kermit/ckermit80.html#x4 - 543. http://www.columbia.edu/kermit/ckermit80.html#x4 - 544. http://www.columbia.edu/kermit/ckermit80.html#top - 545. http://www.columbia.edu/kermit/ckermit80.html#contents - 546. http://www.columbia.edu/kermit/ckermit.html - 547. http://www.columbia.edu/kermit/index.html - 548. http://www.columbia.edu/kermit/ckermit80.html#top - 549. http://www.columbia.edu/kermit/ckermit80.html#contents - 550. http://www.columbia.edu/kermit/ckermit.html - 551. http://www.columbia.edu/kermit/index.html - 552. http://www.columbia.edu/kermit/ckermit80.html#top - 553. http://www.columbia.edu/kermit/ckermit80.html#contents - 554. http://www.columbia.edu/kermit/ckermit.html - 555. http://www.columbia.edu/kermit/index.html - 556. http://www.columbia.edu/kermit/ckermit80.html#x4 - 557. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 558. http://www.columbia.edu/kermit/ckermit80.html#x3.7 - 559. http://www.columbia.edu/kermit/ckermit80.html#top - 560. http://www.columbia.edu/kermit/ckermit80.html#contents - 561. http://www.columbia.edu/kermit/ckermit.html - 562. http://www.columbia.edu/kermit/index.html - 563. ftp://ftp.isi.edu/in-notes/rfc2217.txt - 564. http://www.columbia.edu/kermit/ckermit80.html#top - 565. http://www.columbia.edu/kermit/ckermit80.html#contents - 566. ftp://kermit.columbia.edu/kermit/sredird/ - 567. http://www.columbia.edu/kermit/ckermit.html - 568. http://www.columbia.edu/kermit/index.html - 569. http://www.columbia.edu/kermit/ckermi70.htm#x4.22 - 570. http://www.columbia.edu/kermit/ckermit80.html#top - 571. http://www.columbia.edu/kermit/ckermit80.html#contents - 572. http://www.columbia.edu/kermit/ckermit.html - 573. http://www.columbia.edu/kermit/index.html - 574. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3 - 575. http://www.columbia.edu/kermit/cuiksd.html - 576. http://www.columbia.edu/kermit/ckermit80.html#top - 577. http://www.columbia.edu/kermit/ckermit80.html#contents - 578. http://www.columbia.edu/kermit/ckermit.html - 579. http://www.columbia.edu/kermit/index.html - 580. http://www.columbia.edu/kermit/ckermit80.html#top - 581. http://www.columbia.edu/kermit/ckermit80.html#contents - 582. http://www.columbia.edu/kermit/ckermit.html - 583. http://www.columbia.edu/kermit/index.html - 584. http://www.columbia.edu/kermit/index.html diff --git a/.pc/060_speeling.patch/ckuker.nr b/.pc/060_speeling.patch/ckuker.nr deleted file mode 100644 index 7b0af7c..0000000 --- a/.pc/060_speeling.patch/ckuker.nr +++ /dev/null @@ -1,1827 +0,0 @@ -.\" @(#) kermit.1 8.0.211 2004/04/10 Columbia University -.TH KERMIT 1 "APRIL 2004" "User Manuals" -.na -.SH NAME -kermit \- -.B C\(hyKermit 8.0: -transport\(hy and platform\(hyindependent -interactive and scriptable communications software. -.IP - -This document is intended to give the beginner sufficient information to make -basic (if not advanced) use of C\(hyKermit 8.0. Although it might be rather long -for a Unix manual page, it's still far shorter than the C\(hyKermit manual, which -should be consulted for advanced topics such as customization, character\(hysets, -scripting, etc. We also attempt to provide a clear structural overview of -C\(hyKermit's many capabilities, functional areas, states, and modes and their -interrelation, that should be helpful to beginners and veterans alike, as well -as to those upgrading to version 8.0 from earlier releases. -.PP -This document is also available as a Web page at: -.IP -http://www.columbia.edu/kermit/ckututor.html -.SH DESCRIPTION -C\(hyKermit is an all\(hypurpose communications software package from the Kermit -Project at Columbia University that: -.PP -.nf -\(bu Is portable to many platforms, Unix and non\(hyUnix alike. -.br -\(bu Can make both serial and network connections. -.br -\(bu Can conduct interactive terminal sessions over its connection. -.br -\(bu Can transfer text or binary files over the same connection. -.br -\(bu Can convert character sets in the terminal session. -.br -\(bu Can convert character sets during text\(hyfile file transfer. -.br -\(bu Is customizable in every aspect of its operation. -.fi -.PP -C\(hyKermit is a modem program, a Telnet client, an Rlogin client, an FTP -client, an HTTP client, and on selected platforms, also an X.25 client. It -can make its own secure Internet connections using IETF\(hyapproved security -methods including Kerberos IV, Kerberos V, SSL/TLS, and SRP and it can also -make SSH connections through your external SSH client application. It can -be the far\(hyend file\(hytransfer or client/server partner of your desktop -Kermit client. It can also accept incoming dialed and network connections. -It can even be installed as an Internet service on its own standard TCP -socket, 1649 [RFC2839, RFC2840]. -.PP -And perhaps most important, everything you can do "by hand" (interactively) -with C\(hyKermit, can be "scripted" (automated) using its built\(hyin -cross\(hyplatform transport\(hyindependent script programming language, which -happens to be identical to its interactive command language. -.PP -This manual page offers an overview of C\(hyKermit 8.0 for Unix ("Unix" is an -operating system family that includes AIX, DG/UX, FreeBSD, HP\(hyUX, IRIX, -Linux, Mac OS X, NetBSD, OpenBSD, Open Server, Open Unix, QNX, Solaris, -SunOS, System V R3, System V R4, Tru64 Unix, Unixware, Xenix, and many -others). For thorough coverage, please consult the published C\(hyKermit -manual and supplements (see DOCUMENTATION below). For further information -about C\(hyKermit, Kermit software for other platforms, and Kermit manuals, -visit the Kermit Project website: -.PP - http://www.columbia.edu/kermit/ -.PP -This is a longer\(hythan\(hyaverage manual page, and yet it barely scratches the -surface. Don't be daunted. C\(hyKermit is a large and complex package, -evolving over decades of practice and experience, but that doesn't mean -it's hard to learn or use. Its most commonly used functions are explained -here with pointers to additional information elsewhere. -.SH SYNOPSIS -.B kermit [ -.I filename -.B ] [ -.I options -.B ] [ {=,\-\-,+} -.I text -.B ] ] -.PP -or: -.PP -.B kermit -.I URL -.PP -If the first command\(hyline argument is the name of a file, interactive\(hymode -commands are executed from the file. The '=' (or "\-\-") argument tells -Kermit not to parse the remainder of the command line, but to make the -words following '=' available as \e%1, \e%2, ... \e%9. The "+" argument is -like "=" but for use in "kerbang scripts" (explained below). A second -command\(hyline format allows the one and only argument to be a Telnet, FTP, -HTTP, or IKSD URL. -.PP -Order of execution: -.TP - 1. -The command file (if any). -.TP -.nf - 2. -The initialization file, if any, unless suppressed with \-Y. -.fi -.TP - 3. -The customization file (if it is executed by the initialization file). -.TP - 4. -The command\(hyline URL (if any, and if so, execution stops here). -.TP - 5. -Command\(hyline options (if any). -.TP - 6. -Interactive commands. -.PP -Some command\(hyline options can cause actions (such as \-s to send a file); -others just set parameters. If any action options are included on the -command line, Kermit exits when finished unless also given the \-S ("stay") -option. If no action options are given, no initialization or command files -contained an EXIT or QUIT command, and no fatal errors occurred, Kermit -issues its prompt and waits for you to type commands. -.IP -Bear in mind that C\(hyKermit can be built with selected features -disabled, and also that certain features are not available on all -platforms. For example, C\(hyKermit can't be built with TCP/IP -support on a platform that does not have TCP/IP header files and -libraries (and even if Kermit does include TCP/IP support, it -can't be used to make TCP/IP connections on a computer that does -not have a TCP/IP stack installed). If your version of lacks -C\(hyKermit a feature mentioned here, use its SHOW FEATURES command to -see what might have been excluded. -.PP -C\(hyKermit has three kinds of commands: regular single\(hyletter command\(hyline -options, extended\(hyformat command\(hyline options, and interactive commands. -.PP -Like most Unix commands, C\(hyKermit can be be given options on the command -line. But C\(hyKermit also can be used interactively by giving it commands -composed of words, which are more intuitive than cryptic command\(hyline -options, and more flexible too. In other words, you don't have to use -C\(hyKermit's command\(hyline options, but they are available if you want to. (By -the same token, you don't have to use its interactive commands either \(hy\(hy -you can use either or both in any combination.) -.PP -C\(hyKermit is generally installed in the PATH as "kermit", and therefore is -invoked by typing the word "kermit" (lowercase) at the shell prompt, and -then pressing the Return or Enter key. If you wish to include command\(hyline -options, put them after the word "kermit" but before pressing Return or -Enter, separated by spaces, for example: -.PP - $ kermit \-s ckermit.tar.gz -.PP -('$' is the shell prompt; "kermit \-s ckermit.tar.gz" is what you type, -followed by Return or Enter.) -.SH OPTIONS -Here is a list of C\(hyKermit's single\(hyletter command\(hyline options, which -start with a single dash (\-), in ASCII ("alphabetical") order. Alphabetic -case is significant (\-A is not the same as \-a). Action options are -tagged "ACTION". -.TP -\-0 -(digit zero) 100% transparent Connect state for -"in\(hythe\(hymiddle" operation: 8 bits, no parity, no -escape character, everything passes through. -.TP -\-8 -(digit eight) Connection is 8\(hybit clean (this is the -default in C\(hyKermit 8.0). Equivalent to the EIGHTBIT -command, which in turn is a shortcut for SET TERMINAL -BYTESIZE 8, SET COMMAND BYTESIZE 8, SET PARITY NONE. -.TP -\-9 arg -(digit nine) Make a connection to an FTP server. -Equivalent to the FTP OPEN command. -Argument: IP\(hyaddress\(hyor\(hyhostname[:optional\(hyTCP\(hyport]. -NOTE: C\(hyKermit also has a separate FTP command\(hyline -personality, with regular FTP\(hylike command\(hyline -syntax. More about this below. -.TP -\-A -Kermit is to be started as an Internet service (IKSD) -(only from inetd.conf). -.TP -\-B -Kermit is running in Batch or Background (no -controlling terminal). To be used in case Kermit -doesn't automatically sense its background status. -Equivalent to the SET BACKGROUND ON command. -.TP -\-C arg -Interactive\(hymode Commands to be executed. -Argument: Commands separated by commas, list in -doublequotes. -.TP -\-D arg -Delay before starting to send in Remote mode. -Equivalent to the SET DELAY command. -Argument: Number of seconds. -.TP -\-E -Exit automatically when connection closes. Equivalent -to SET EXIT ON\-DISCONNECT ON. -.TP -\-F arg -Use an open TCP connection. -Argument: Numeric file descriptor of open TCP -connection. -Also see: \-j, \-J. -.TP -\-G arg -(ACTION) Get file(s) from server, send contents to standard -output, which normally would be piped to another -process. -Argument: Remote file specification, in quotes if it -contains metacharacters. -Also see: \-g, \-k. -.TP -\-H -Suppress program startup Herald and greeting. -.TP -\-I -Tell Kermit it has a reliable connection, to force streaming to be used where -it normally would not be. Equivalent to the SET RELIABLE ON command. -.TP -\-J arg -(ACTION) "Be like Telnet." Like \-j but implies \-E. Argument: IP -hostname/address optionally followed by service. NOTE: C\(hyKermit also has a -separate Telnet command\(hyline personality, with regular Telnet\(hylike -command\(hyline syntax. More about this below. -.TP -\-L -Recursive directory descent for files in \-s option. -.TP -\-M arg -My user name (for use with Telnet, Rlogin, FTP, etc). -Equivalent to the SET LOGIN USER command. -Argument: Username string. -.TP -\-O -(ACTION) (Uppercase letter O) Be a server for One command only. -Also see: \-x. -.TP -\-P -Don't convert file (Path) names of transferred files. -Equivalent to SET FILE NAMES LITERAL. -.TP -\-Q -Quick Kermit protocol settings. Equivalent to the FAST -command. This is the default in C\(hyKermit 7.0 and later. -.TP -\-R -Remote\(hyonly (this just makes IF REMOTE true). -.TP -\-S -Stay (enter command parser after action options). -.TP -\-T -Force Text mode for file transfer; implies \-V. -Equivalent to SET TRANSFER MODE MANUAL, SET FILE TYPE TEXT. -.TP -\-V -Disable automatic per\(hyfile text/binary switching. -Equivalent to SET TRANSFER MODE MANUAL. -.TP -\-Y -Skip (don't execute) the initialization file. -.TP -\-a arg -As\(hyname for file(s) in \-s, \-r, or \-g. -Argument: As\(hyname string (alternative filename). When -receiving files, this can be a directory name. -.TP -\-b arg -Speed for serial device. Equivalent to SET SPEED. -Argument: Numeric Bits per second for serial -connections. -.TP -\-c -(ACTION) Enter Connect state before transferring files. -.TP -\-d -Create a debug.log file with detailed debugging -information (a second \-d adds timestamps). Equivalent -to LOG DEBUG but takes effect sooner. -.TP -\-e arg -Maximum length for incoming Kermit file\(hytransfer -packets. Equivalent to SET RECEIVE PACKET\-LENGTH. -Argument: Length in bytes. -.TP -\-f -(ACTION) Send a FINISH command to a Kermit server. -.TP -\-g arg -Get file(s) from a Kermit server. -Argument: File specification on other computer, in -quotes if it contains metacharacters. Equivalent to -GET. Also see: \-a, \-G, \-r. -.TP -\-h -(ACTION) Print Help text for single\(hyletter command\(hyline options -(pipe thru 'more' to prevent scrolling). -.TP -\-i -Force binary (Image) mode for file transfer; implies -\-V. Equivalent to SET TRANSFER MODE MANUAL, SET FILE -TYPE BINARY. -.TP -\-j arg -Make a TCP/IP connection. -Argument: IP host name/address and optional service -name or number. Equivalent to the TELNET command. -Also see: \-J, \-F. -.TP -\-k -(ACTION) Receive file(s) to standard output, which normally -would be piped to another process. -Also see: \-r, \-G. -.TP -\-l arg -(Lowercase letter L) Make a connection on the given -serial communications device. Equivalent to the SET -LINE (SET PORT) command. -Argument: Serial device name, e.g. /dev/ttyS0. -.TP -\-m arg -Modem type for use with the \-l device. Equivalent to -the SET MODEM TYPE command. -Argument: Modem name as in SET MODEM TYPE command, -e.g. "usrobotics". -.TP -\-n -(ACTION) Enter Connect state after transferring files (historical). -.TP -\-p arg -Parity. Equivalent to the SET PARITY command. -Argument: One of the following: e(ven), o(dd), m(ark), -n(one), s(pace). -.TP -\-q -Quiet (suppress most messages). Equivalent to SET QUIET ON. -.TP -\-r -(ACTION) Receive file(s). Equivalent to the RECEIVE command. -Argument: (none, but see \-a) -.TP -\-s arg -Send file(s). -Argument: One or more local file specifications. -Equivalent to the SEND command. -Also see: \-a. -.TP -\-t -(Historical) Xon (Ctrl\-Q) Turnaround character for -half\(hyduplex connections (used on serial linemode -connections to old mainframes). Equivalent to SET -DUPLEX HALF, SET HANDSHAKE XON. -.TP -\-v arg -Window size for Kermit protocol (ignored when -streaming). Equivalanet to SET WINDOW\-SIZE. -Argument: Number, 1 to 32. -.TP -\-w -Incoming files Write over existing files. Equivalent -to SET FILE COLLISION OVERWRITE. -.TP -\-x -(ACTION) Enter server mode. Equivalent to the SERVER command. -Also see: \-O. -.TP -\-y arg -Alternative initialization file. -Argument: Filename. -.TP -\-z -Force foreground behavior. To be used in case Kermit -doesn't automatically sense its foreground status. -Equivalent to the SET BACKGROUND OFF command. -.PP -Extended command\(hyline options (necessary because single\(hyletter ones are -about used up) start with two dashes (\-\-), with words rather than single -letters as option names. If an extended option takes an argument, it is -separated from the option word by a colon (:). Extended options include: - -.TP - \-\-bannerfile:filename -File to display upon startup or IKSD login. -.TP - \-\-cdfile:filename -File to be sent for display to the client when -server changes directory (filename is relative to -the changed\(hyto directory). -.TP - \-\-cdmessage:{on,off} -Enable/disable the server CD message feature. -.TP - \-\-help -Prints usage message for extended options. -.TP - \-\-helpfile:filename -Designates a file containing custom text to -replace the top\(hylevel HELP command. -.TP - \-\-nointerrupts -Disables keyboard interrupts. -.TP - \-\-noperms -Disables the Kermit protocol file Permissions -attribute, to prevent transmission of file -permissions (protection) from sender to receiver. -.TP - \-\-version -(ACTION) C\(hyKermit prints its version number. -.PP -Plus several other IKSD\(hyOnly options described at: -.PP - http://www.columbia.edu/kermit/iksd.html -.PP -See the file\(hytransfer section for examples of command\(hyline invocation. -.SH COMMAND LANGUAGE -C\(hyKermit's interactive command language is the subject of a 622\(hypage book -and another several hundred pages of updates, far too much for a manual -page. But it's not hard to get started. At the shell prompt, just type -"kermit" to get C\(hyKermit's interactive command prompt: -.PP -.nf - $ kermit - (/current/directory) C\-Kermit> -.fi -.PP -Begin by typing "help" (and then press the Return or Enter key) for a -top\(hylevel overview, read it, and go from there. Your second command should -probably be "intro" (introduction). Note the prompt shows your current -directory (unless you tell Kermit to prompt you with something else). -.PP -Interactive commands are composed mainly of regular English words, usually -in the form of imperative sentences, such as: -.PP - send oofa.txt -.PP -which tells Kermit to send (transfer) the file whose name is oofa.txt, or: -.PP - set transfer mode automatic -.PP -which sets Kermit's "transfer mode" to "automatic" (whatever that means). -.PP -While typing commands, you can abbreviate, ask for help (by pressing the -"?" key anywhere in a command), complete keywords or filenames (with the -Tab or Esc key), and edit your typing with Backspace or Delete, Ctrl\-W, -Ctrl\-U, etc. You can also recall previous commands, save your command -history, and who knows what else. Give the INTRO command for details. -.PP -C\(hyKermit has hundreds of commands, and they can be issued in infinite -variety and combinations, including commands for: -.nf -.PP -\(bu Making connections (SET LINE, DIAL, TELNET, SSH, FTP, ...) -.br -\(bu Breaking connections (HANGUP, CLOSE) -.br -\(bu Transferring files (SEND, GET, RECEIVE, MOVE, RESEND, ...) -.br -\(bu Establishing preferences (SET) -.br -\(bu Displaying preferences (SHOW) -.br -\(bu Managing local files (CD, DELETE, MKDIR, DIR, RENAME, TYPE, ...) -.br -\(bu Managing remote files (RCD, RDEL, RMKDIR, RDIR, ...) -.br -\(bu Using local files (FOPEN, FCLOSE, FREAD, FWRITE) -.br -\(bu Programming (TAKE, DEFINE, IF, FOR, WHILE, SWITCH, DECLARE, ...) -.br -\(bu Interacting with the user (ECHO, ASK, ...) -.br -\(bu Interacting with a remote computer (INPUT, OUTPUT, ...) -.br -\(bu Interacting with local programs (RUN, EXEC, PTY, ...) -.br -\(bu Logging things (LOG SESSION, LOG PACKETS, LOG DEBUG, ...) -.PP -.fi -And of course QUIT or EXIT to get out and HELP to get help, and for -programmers: loops, decision making, variables, arrays, associative arrays, -integer and floating point arithmetic, macros, built\(hyin and user\(hydefined -functions, string manipulation, pattern matching, block structure, scoping, -recursion, and all the rest. To get a list of all C\(hyKermit's commands, type -a question mark (?) at the prompt. To get a description of any command, -type HELP followed by the name of the command, for example: -.PP - help send -.PP -The command interruption character is Ctrl\-C (hold down the Ctrl key and -press the C key). -.PP -The command language "escape character", used to introduce variable names, -function invocations, and so on, is backslash (\). If you need to include a -literal backslash in a command, type two of them, e.g.: -.PP - get c:\ek95\ek95custom.ini -.SS Command Files, Macros, and Scripts -A file containing Kermit commands is called a Kermit command file or Kermit -script. It can be executed with Kermit's TAKE command: -.PP - (/current/dir) C\-Kermit> take commandfile -.PP -(where "commandfile" is the name of the command file). Please don't pipe a -command file into Kermit's standard input (which might or might not work); -if you have Kermit commands in a file, tell Kermit to TAKE the file. -.PP -In Unix only, a Kermit command file can also be executed directly by -including a "kerbang" line as the first line of the file: -.PP - #!/usr/local/bin/kermit + -.PP -That is, a top line that starts with "#!", followed immediately by the full -path of the Kermit executable, and then, if the Kermit script is to be -given arguments on the command line, a space and a plus sign. The script -file must also have execute permission: -.PP - chmod +x commandfile -.PP -Except for the " +" part, this is exactly the same as you would do for a -shell script, a Perl script, etc. Here's a simple but useless example -script that regurgitates its arguments (up to three of them): -.PP - #!/usr/local/bin/kermit + - if defined \e%1 echo "Argument 1: \e%1" - if defined \e%2 echo "Argument 2: \e%2" - if defined \e%3 echo "Argument 3: \e%3" - if defined \e%4 echo "etc..." - exit -.PP -If this file is stored in your current directory as "commandfile", then: -.PP - ./commandfile one two three four five -.PP -prints: -.PP - Argument 1: one - Argument 2: two - Argument 3: three - etc... -.PP -This illustrates the basic structure of a standalone Kermit script: the -"kerbang line", then some commands. It should end with "exit" unless you -want the Kermit prompt to appear when it is finished. \e%1 is the first -argument, \e%2 the second, and so on. -.PP -You can also create your own commands by defining named macros composed of -other Kermit commands (or macros). For example: -.PP -.nf - define mydelete { - local trash - assign trash \ev(home)trashcan/ - if not defined \e%1 end 1 "Delete what?" - if wild \e%1 { - end 1 "Deleting multiple files is too scary" - } - if not exist \e%1 end 1 "I can't find \e%1" - if not directory \em(trash) { - mkdir \em(trash) - if fail end 1 "No trash can" - } - rename /list \e%1 \em(trash) - } - define myundelete { - local trash - assign trash \ev(home)trashcan/ - if not defined \e%1 end 1 "Undelete what?" - if wild \e%1 { - end 1 "Undeleting multiple files is too hard" - } - if not directory \em(trash) end 1 "No trash can" - if not exist \em(trash)\e%1 { - end 1 "I can't find \e%1 in trash can" - } - rename /list \em(trash)\e%1 . - } -.PP -.fi -These sample macros are not exactly production quality (they don't handle -filenames that include path segments, they don't handle multiple files, -etc), but you get the idea: you can pass arguments to macros, and they can -check them and make other kinds of decisions. If you put the above lines -into your initialization or customization file (explained below), you'll -have MYDELETE and MYUNDELETE commands available every time you start -Kermit, at least as long as you don't suppress execution of the -initialization file. (Exercise for the reader: Make these macros generally -useful: remove limitations, add trashcan display, browsing, emptying, etc.) -.PP -Kerbang scripts execute without the initialization file. This to keep them -portable and also to make them start faster. If you want to write Kerbang -scripts that depend on the initialization file, include the command -.PP - take \ev(home).kermrc -.PP -at the desired spot in the script. By the way, \ev(xxx) is a built\(hyin -variable (xxx is the variable name, "home" in this case). To see what -built\(hyin variables are available, type "show variables" at the C\(hyKermit -prompt. To see what else you can show, type "show ?". \em(xxx) is a user -defined variable (strictly speaking, it is a macro used as a variable). -.SS Command List -C\(hyKermit has more than 200 top\(hylevel commands, and some of these, such as -SET, branch off into hundreds of subcommands of their own, so it's not -practical to describe them all here. Instead, here's a concise list of the -most commonly used top\(hylevel commands, grouped by category. To learn about -each command, type "help" followed by the command name, e.g. "help set". -Terms such as Command state and Connect state are explained in subsequent -sections. -.PP -Optional fields are shown in [ brackets ]. "filename" means the -name of a single file. filespec means a file specification that is allowed -to contain wildcard characters like '*' to match groups of files. options -are (optional) switches like /PAGE, /NOPAGE, /QUIET, etc, listed in the -HELP text for each command. Example: -.PP -.nf - send /recursive /larger:10000 /after:\-1week /except:*.txt * -.fi -.PP -which can be read as "send all the files in this directory and all the ones -underneath it that are larger than 10000 bytes, no more than one week old, -and whose names don't end with ".txt". -.SS -Basic Commands -.RS -.TP -HELP -Requests top\(hylevel help. -.TP -HELP command -Requests help about the given command. -.TP -INTRODUCTION -Requests a brief introduction to C\(hyKermit. -.TP -LICENSE -Displays the C\(hyKermit software copyright and license. -.TP -VERSION -Displays C\(hyKermit's version number. -.TP -EXIT [ number ] -Exits from Kermit with the given -status code. Synonyms: QUIT, E, Q. -.TP -TAKE filename [ parameters... ] -Executes commands from the given -.TP -LOG item [ filename ] -Keeps a log of the given item in the given file. -.TP -[ DO ] macro [ parameters... ] -Executes commands from the given macro. -.TP -SET parameter value -Sets the given parameter to the given value. -.TP -SHOW category -Shows settings in a given category. -.TP -STATUS -Tells whether previous command succeeded or failed. -.TP -DATE [ date\(hyand/or\(hytime ] -Shows current date\(hytime or interprets given date\(hytime. -.TP -RUN [ extern\(hycommand [ parameters... ] -Runs the given external command. Synonym: !. -.TP -EXEC [ extern\(hycommand [ params... ] -Kermit overlays itself with the given command. -.TP -SUSPEND -Stops Kermit and puts it in the background. Synonym: Z. -.RE -.SS -Local File Management -.RS -.TP -TYPE [ options ] filename -Displays the contents of the given file. -.TP -MORE [ options ] filename -Equivalent to TYPE /PAGE (pause after each screenful). -.TP -CAT [ options ] filename -Equivalent to TYPE /NOPAGE. -.TP -HEAD [ options ] filename -Displays the first few lines of a given file. -.TP -TAIL [ options ] filename -Displays the last few lines of a given file. -.TP -GREP [ options ] pattern filespec -Displays lines from files that match -the pattern. Synonym: FIND. -.TP -DIRECTORY [ options ] [filespec ] -Lists files (built\(hyin, many options). -.TP -LS [ options ] [ filespec ] -Lists files (runs external "ls" command). -.TP -DELETE [ options ] [ filespec ] -Deletes files. Synonym: RM. -.TP -PURGE [ options ] [ filespec ] -Removes backup (*.~n~) files. -.TP -COPY [ options ] [ filespecs... ] -Copies files. Synonym: CP. -.TP -RENAME [ options ] [ filespecs... ] -Renames files. Synonym: MV. -.TP -CHMOD [ options ] [ filespecs... ] -Changes permissions of files. -.TP -TRANSLATE filename charsets [ filename ] -Converts file's character set. Synonym: XLATE. -.TP -CD -Changes your working directory to your home directory. -.TP -CD directory -Changes your working directory to the one given. -.TP -CDUP -Changes your working directory one level up. -.TP -PWD -Displays your working directory. -.TP -BACK -Returns to your previous working directory. -.TP -MKDIR [ directory ] -Creates a directory. -.TP -RMDIR [ directory ] -Removes a directory. -.RE -.SS -Making Connections -.RS -.TP -SET LINE [ options ] devicename -Opens the named serial port. Synonym: SET PORT. -.TP -OPEN LINE [ options ] devicename -Same as SET LINE. Synonym: OPEN PORT. -.TP -SET MODEM TYPE [ name ] -Tells Kermit what kind of modem is on the port. -.TP -DIAL [ number ] -Tells Kermit to dial the given phone number with the modem. -.TP -REDIAL -Redials the most recently dialed phone number. -.TP -ANSWER -Waits for and answers an incoming call on the modem. -.TP -AUTHENTICATE [ parameters... ] -Performs secure authentication on a TCP/IP connection. -.TP -SET NETWORK TYPE { TCP/IP, X.25, ... } -Selects network type for subsequent SET HOST commands. -.TP -SET HOST [ options ] host [ port ] -Opens a network connection to the given host and port. -.TP -SET HOST * port -Waits for an incoming TCP/IP connection on the given port. -.TP -TELNET [ options ] host -Opens a Telnet connection to the host and enters Connect state. -.TP -RLOGIN [ options ] host -Opens an Rlogin connection to the host and enters Connect state. -.TP -IKSD [ options ] host -Opens a connection to an Internet Kermit Service. -.TP -SSH [ options ] host -Opens an SSH connection to the host and enters Connect state. -.TP -FTP OPEN host [ options ] -Opens an FTP connection to the host. -.TP -HTTP [ options ] OPEN host -Opens an HTTP connection to the host. -.TP -PTY external\(hycommand -Runs the command on a pseudoterminal as if it were a connection. -.TP -PIPE external\(hycommand -Runs the command through a pipe as if it were a connection. -.RE -.SS -Using Connections -.RS -.TP -CONNECT [ options ] -Enters Connect (terminal) state. Synonym: C. -.TP -REDIRECT command -Redirects the given external command over the connection. -.TP -TELOPT command -Sends a Telnet protocol command (Telnet connections only). -.TP -Ctrl\-\eC -"Escapes back" from Connect state to Command state. -.TP -Ctrl\-\eB -(In Connect state) Sends a BREAK signal (serial or Telnet). -.TP -Ctrl\-\e! -(In Connect state) Enters inferior shell; "exit" to return. -.TP -Ctrl\-\e? -(In Connect state) Shows a menu of other escape\(hylevel options. -.TP -Ctrl\-\eCtrl\-\e -(In Connect state) Type two -Ctrl\-Backslashes to send one of them. -.TP -SET ESCAPE [ character ] -Changes Kermit's Connect\(hystate escape character. -.RE -.SS -Closing Connections -.RS -.TP -HANGUP -Hangs up the currently open -serial\(hyport or network connection. -.TP -CLOSE -Closes the currently open -serial\(hyport or network connection. -.TP -SET LINE (with no devicename) -Closes the currently open -serial\(hyport or network connection. -.TP -SET HOST (with no hostname) -Closes the currently open serial\(hyport or network connection. -.TP -FTP CLOSE -Closes the currently open FTP connection. -.TP -HTTP CLOSE -Closes the currently open HTTP connection. -.TP -EXIT -Also closes all connections. Synonym: QUIT. -.TP -SET EXIT WARNING OFF -Suppresses warning about open connections on exit or close. -.RE -.SS -File Transfer -.RS -.TP -SEND [ options ] filename [ as\(hyname ] -Sends the given file. Synonym: S. -.TP -SEND [ options ] filespec -Sends all files that match. -.TP -RESEND [ options ] filespec -Resumes an interupted SEND from the point of failure. -.TP -RECEIVE [ options ] [ as\(hyname ] -Waits passively for files to arrive. Synonym: R. -.TP -LOG TRANSACTIONS [ filename ] -Keeps a record of file transfers. -.TP -FAST -Use fast file\(hytransfer settings (default). -.TP -CAUTIOUS -Use cautious and less fast file\(hytransfer settings. -.TP -ROBUST -Use ultra\(hyconservative and slow file\(hytransfer settings. -.TP -STATISTICS [ options ] -Gives statistics about the most recent file transfer. -.TP -WHERE -After transfer: "Where did my files go?". -.TP -TRANSMIT [ options ] [ofilename ] -Sends file without protocol. Synonym: XMIT. -.TP -LOG SESSION [ filename ] -Captures remote text or files without protocol. -.TP -SET PROTOCOL [ name... ] -Tells Kermit to use an external file\(hytransfer protocol. -.TP -FTP { PUT, MPUT, GET, MGET, ... } -FTP client commands. -.TP -HTTP { PUT, GET, HEAD, POST, ... } -HTTP client commands. -.RE -.SS -Kermit Server -.RS -.TP -ENABLE, DISABLE -Controls which server features can be used by clients. -.TP -SET SERVER -Sets parameters prior to entering Server state. -.TP -SERVER -Enters Server state. -.RE -.SS -Client of Kermit or FTP Server -.RS -.TP -[ REMOTE ] LOGIN [ user password ] -Logs in to a Kermit server or IKSD that requires it. -.TP -[ REMOTE ] LOGOUT -Logs out from a Kermit server or IKSD. -.TP -SEND [ options ] filename [ as\(hyname ] -Sends the given file to the server. Synonyms: S, PUT. -.TP -SEND [ options ] filespec -Sends all files that match. -.TP -RESEND [ options ] filespec -Resumes an interupted SEND from the point of failure. -.TP -GET [ options ] remote\(hyfilespec -Asks the server to send the given files. Synonym: G. -.TP -REGET [ options ] remote\(hyfilespec -Resumes an interrupted GET from the point of failure. -.TP -REMOTE CD [ directory ] -Asks server to change its working -directory. Synonym: RCD. -.TP -REMOTE PWD [ directory ] -Asks server to display its working directory. Synonym: RPWD. -.TP -REMOTE DIRECTORY [ filespec... ] -Asks server to send a directory listing. Synonym: RDIR. -.TP -REMOTE DELETE [ filespec... ] -Asks server to delete files. Synonym: RDEL. -.TP -REMOTE [ command... ] -(Many other commands: "remote ?" for a list). -.TP -MAIL [ options ] filespec -Sends file(s) to be delivered as e\(hymail (Kermit only). -.TP -FINISH -Asks the server to exit server state (Kermit only). -.TP -BYE -Asks the server to log out and close the connection. -.RE -.SS -Script Programming -.PP -.RS -DEFINE, DECLARE, UNDEFINE, UNDECLARE, ASSIGN, EVALUATE, SEXPRESSION, -ARRAY, SORT, INPUT, OUTPUT, IF, FOR, WHILE, SWITCH, GOTO, ECHO, ASK, -GETC, GETOK, ASSERT, WAIT, SLEEP, FOPEN, FREAD, FWRITE, FCLOSE, STOP, -END, RETURN, LEARN, SHIFT, TRACE, VOID, INCREMENT, DECREMENT, ... For -these and many more you'll need to consult the manual and supplements, -and/or visit the Kermit Script Library, which also includes a brief -tutorial. Hint: HELP LEARN to find out how to get Kermit to write -simple scripts for you. -.RE -.PP -Many of Kermit's commands have synonyms, variants, relatives, and so on. -For example, MSEND is a version of SEND that accepts a list of file -specifications to be sent, rather than just one file specification, and -MPUT is a synonym of MSEND. MOVE means to SEND and then DELETE the source -file if successful. MMOVE is like MOVE, but accepts a list of filespecs, -and so on. These are described in the full documentation. -.PP -Use question mark to feel your way through an unfamiliar command, as in -this example: -.PP -.nf - C\-Kermit> remote ? One of the following: - assign directory kermit print rmdir - cd exit login pwd set - copy help logout query space - delete host mkdir rename type - C\-Kermit> remote set ? One of the following: - attributes file retry transfer - block\-check receive server window - C\-Kermit> remote set file ? One of the following: - character\-set incomplete record\-length - collision names type - C\-Kermit> remote set file names ? One of the following: - converted literal - C\-Kermit> remote set file names literal - C\-Kermit> -.PP -.fi -This is called menu on demand: you get a menu when you want one, but menus -are not forced on you even when know what you're doing. Note that you can -also abbreviate most keywords, and you can complete them with the Tab or -Esc key. Also note that ? works for filenames too, and that you can use it -in the middle of a keyword or filename, not just at the beginning. For -example, "send x?" lists all the files in the current directory whose names -start with 'x'. -.SH INITIALIZATION FILE -In its default configuration, C\(hyKermit executes commands from a file -called .kermrc in your home directory when it starts, unless it is given the -\-Y or \-y command\(hyline option. Custom configurations might substitute a shared -system\(hywide initialization file. The SHOW FILE command tells what -initialization file, if any, was used. The standard initialization file -"chains" to an individual customization file, .mykermc, in the home directory, -in which each user can establish her/his own preferences, define macros, and -so on. -.PP -Since execution of the initialization file (at least the standard one) -makes C\(hyKermit take longer to start, it might be better not to have an -initialization file, especially now that Kermit's default startup -configuration is well attuned to modern computing and networking \(hy\(hy in -other words, you no longer have do anything special to make Kermit -transfers go fast. So instead of having an initialization file that is -executed every time Kermit starts, you might consider making one or more -kerbang scripts (with names other that .kermrc) that do NOT include an -"exit" command, and invoke those when you need the settings, macro -definitions, and/or scripted actions they contain, and invoke C\(hyKermit -directly when you don't. -.PP -To put it another way... We still distribute the standard initialization -file since it's featured in the manual and backwards compatibility is -important to us. But there's no harm in not using it if you don't need the -stuff that's in it (services directory, dialing directory, network -directory, and associated macro definitions). On the other hand, if there -are settings or macros you want in effect EVERY time you use Kermit, the -initialization file (or the customization file it chains to) is the place -to put them, because that's the only place Kermit looks for them -automatically each time you start it. -.SH MODES OF OPERATION -Kermit is said to be in Local mode if it has made a connection to another -computer, e.g. by dialing it or establishing a Telnet connection to it. The -other computer is remote, so if you start another copy of Kermit on the -remote computer, it is said to be in Remote mode (as long as it has not -made any connections of its own). The local Kermit communicates over the -communications device or network connection, acting as a conduit between -the the remote computer and your keyboard and screen. The remote Kermit is -the file\(hytransfer partner to the local Kermit and communicates only through -its standard input and output. -.PP -At any moment, a Kermit program can be in any of the following states. It's -important to know what they are and how to change from one to the other. -.TP -Command state -In this state, Kermit reads commands from: -.sp -\(bu Your keyboard; or: -.br -\(bu A file, or: -.br -\(bu A macro definition. -.sp -You can exit from Command state back to Unix with the EXIT or QUIT -command (same thing). You can enter Connect state with any of various -commands (CONNECT, DIAL, TELNET, etc). You can enter file transfer -state with commands like SEND, RECEIVE, and GET. You can enter Server -state with the SERVER command. The TAKE command tells Kermit to read -and execute commands from a file. The (perhaps implied) DO command -tells Kermit to read and execute commands from a macro definition. -While in Command state, you can interrupt any command, macro, or -command file by typing Ctrl\-C (hold down the Ctrl key and press the C -key); this normally brings you back to the prompt. -.TP -Shell state -You can invoke an inferior shell or external command from the Kermit -command prompt by using the PUSH, RUN (!), EDIT, or BROWSE command. -While the inferior shell or command is active, Kermit is suspended and -does nothing. Return to Kermit Command state by exiting from the -inferior shell or application. -.TP -Connect state -In this state, which can be entered only when in Local mode (i.e. when -Kermit has made a connection to another computer), Kermit is acting as -a terminal to the remote computer. Your keystrokes are sent to the -remote computer and characters that arrive over the communication -connection are displayed on your screen. This state is entered when -you give a CONNECT, DIAL, TELNET, RLOGIN, or IKSD command. You can -return to command state by logging out of the remote computer, or by -typing: -.sp - Ctrl\-\ec -.sp -That is: Hold down the Ctrl key and press the backslash key, then let -go of the Ctrl key and press the C key. This is called escaping back. -Certain other escape\(hylevel commands are also provided; type Ctrl\-\e? -for a list. For example, you can enter Shell state with: -.sp - Ctrl\-\e! -.sp -To send a Ctrl\-\e to the host while in Connect state, type two of them -in a row. See HELP CONNECT and HELP SET ESCAPE for more info. -.TP -Local file\(hytransfer state -In this state, Kermit is sending packets back and forth with the other -computer in order to transfer a file or accomplish some other -file\(hyrelated task. And at the same time, it is displaying its progress -on your screen and watching your keyboard for interruptions. In this -state, the following single\(hykeystroke commands are accepted: -.sp -.RS -.TP -X -Interrupt the current file and go on to the next (if any). -.TP -Z -Interrupt the current file and skip all the rest. -.TP -E -Like Z but uses a "stronger" protocol (use if X or Z don't work). -.TP -Ctrl\-C -Interrupt file\(hytransfer mode (use if Z or E don't work). -.sp -.RE -Kermit returns to its previous state (Command or Connect) when the -transfer is complete or when interrupted successfully by X, Z, E, or -Ctrl\-C (hold down the Ctrl key and press the C key). -.TP -Remote file\(hytransfer state -In this state, Kermit is exchanging file\(hytransfer packets with its -local partner over its standard i/o. It leaves this state -automatically when the transfer is complete. In case you find your -local Kermit in Connect state and the remote one in File\(hytransfer -state (in which it seems to ignore your keystrokes), you can usually -return it to command state by typing three Ctrl\-C's in a row. If that -doesn't work, return your local Kermit to Command state (Ctrl\-\e C) and -type "e\(hypacket" and then press the Return or Enter key; this forces a -fatal Kermit protocol error. -.TP -Remote Server state -This is like Remote File\(hytransfer state, except it never returns -automatically to Command state. Rather, it awaits further instructions -from the client program; that is, from your Local Kermit program. You -can return the Remote Server to its previous state by issuing a -"finish" command to the client, or if you are in Connect state, by -typing three Ctrl\-C's in a row. You can tell the server job to log out -and break the connection by issuing a "bye" command to the client. -.TP -Local Server state -Like Remote\(hyServer state, but in local mode, and therefore with its -file\(hytransfer display showing, and listening for single\(hykey commands, -as in Local File\(hytransfer state. Usually this state is entered -automatically when a remote Kermit program gives a GET command. -.sp -C\(hyKermit, Kermit 95, and MS\(hyDOS Kermit all can switch automatically from -Connect state to Local File\(hytransfer state when you initiate a file -transfer from the remote computer by starting Kermit and telling it to send -or get a file, in which case, Connect state is automatically resumed after -the file transfer is finished. -.sp -Note that C\(hyKermit is not a terminal emulator. It is a communications -application that you run in a terminal window (e.g. console or Xterm). The -specific emulation, such as VT100, VT220, Linux Console, or Xterm, is -provided by the terminal window in which you are running C\(hyKermit. Kermit -95 and MS\(hyDOS Kermit, on the other hand, are true terminal emulators. Why -is C\(hyKermit not a terminal emulator? CLICK HERE to read about it. -.SH MAKING CONNECTIONS -Here is how to make different kinds of connections using interactive Kermit -commands (as noted above, you can also make connections with command\(hyline -options). Note that you don't have to make connections with Kermit. It can -also be used on the far end of a connection as the remote file transfer and -management partner of your local communications software. -.TP -Making a Telnet Connection -At the C\(hyKermit command prompt, simply type: -.sp -.nf - telnet foo.bar.com -.fi -.sp -(substituting desired hostname or address). -You can also include a port number: -.sp -.nf - telnet xyzcorp.com 3000 ; -.fi -.sp -If the connection is successful, Kermit automically enters Connect -state. When you logout from the remote host, Kermit automatically -returns to its prompt. More info: HELP TELNET, HELP SET TELNET, HELP -SET TELOPT. Also see the IKSD section below. -.TP -Making an Rlogin connection -This is just like Telnet, except you have to be root to do it because -Rlogin uses a privileged TCP port: -.sp -.nf - rlogin foo.bar.com -.fi -.sp -More info: HELP RLOGIN. -.TP -Making an SSH Connection -Unlike Telnet and Rlogin, SSH connections are not built\(hyin, but -handled by running your external SSH client through a pseudoterminal. -Using C\(hyKermit to control the SSH client gives you all of Kermit's -features (file transfer, character\(hyset conversion, scripting, etc) -over SSH. -.sp - ssh foo.bar.com -.sp -More info: HELP SSH, HELP SET SSH. -.TP -Dialing with a Modem -If it's an external modem, make sure it is connected to a usable -serial port on your computer with a regular (straight\(hythrough) modem -cable, and to the telephone jack with a telephone cable, and that it's -turned on. Then use these commands: -.sp -.nf - set modem type usrobotics ; Or other supported type - set line /dev/ttyS0 ; Specify device name - set speed 57600 ; Or other desired speed - set flow rts/cts ; Most modern modems support this - set dial method tone ; (or pulse) - dial 7654321 ; Dial the desired number -.fi -.sp -Type "set modem type ?" for a list of supported modem types. If you -omit the SET MODEM TYPE command, the default type is -"generic\(hyhigh\(hyspeed", which should work for most modern AT\(hycommand\(hyset -modems. If the line is busy, Kermit redials automatically. If the call -does not succeed, use "set dial display on" and try it again to watch -what happens. If the call succeeds, Kermit enters Connect state -automatically and returns to its prompt automatically when you log out -from the remote computer or the connection is otherwise lost. -.sp -You can also dial from a modem that is accessible by Telnet, e.g. to a -reverse terminal server. In this case the command sequence is: -.sp -.nf - set host ts.xxx.com 2000 ; Terminal\(hyserver and port - set modem type usrobotics ; Or other supported type - set dial method tone ; (or pulse) - dial 7654321 ; Dial the desired number -.fi -.sp -If the terminal server supports the Telnet Com Port Option, RFC 2217, -you can also give serial\(hyport related commands such as SET SPEED, SET -PARITY, and so on, and Kermit relays them to the terminal server using -the protocol specified in the RFC. -.sp -More info: HELP SET MODEM, HELP SET LINE, HELP SET SPEED, HELP SET -FLOW, HELP DIAL, HELP SET DIAL, HELP SET MODEM, HELP SET -CARRIER\-WATCH, SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL. -.TP -Direct Serial Port -Connect the two computers, A and B, with a null modem cable (or two -modem cables interconnected with a null\(hymodem adapter or modem -eliminator). From Computer A: -.sp -.nf - set modem type none ; There is no modem - set line /dev/ttyS0 ; Specify device name - set carrier\-watch off ; If DTR CD are not cross\(hyconnected - set speed 57600 ; Or other desired speed - set flow rts/cts ; If RTS and CTS are cross\(hyconnected - set parity even ; (or "mark" or "space", if necessary) - set stop\-bits 2 ; (rarely necessary) - set flow xon/xoff ; If you can't use RTS/CTS - connect ; Enter Connect (terminal) state -.fi -.sp -This assumes Computer B is set up to let you log in. If it isn't, you -can run a copy of Kermit on Computer B and follow approximately the -same directions. More info: As above plus HELP CONNECT. -.PP -With modems or direct serial connections, you might also have to "set -parity even" (or "mark" or "space") if it's a 7\(hybit connection. -.PP -Of the connection types listed above, only one can be open at a time. -However, any one of these can be open concurrently with an FTP or HTTP -session. Each connection type can be customized to any desired degree, -scripted, logged, you name it. See the manual. -.PP -NOTE: On selected platforms, C\(hyKermit also can make X.25 connections. See -the manual for details. -.SH TRANSFERRING FILES WITH KERMIT -There is a widespread and persistent belief that Kermit is a slow protocol. -This is because, until recently, it used conservative tuning by default to -make sure file transfers succeeded, rather than failing because they -overloaded the connection. Some extra commands (or command\(hyline options, -like \-Q) were needed to make it go fast, but nobody bothered to find out -about them. Also, it takes two to tango: most non\(hyKermit\(hyProject Kermit -protocol implementations really ARE slow. The best file\(hytransfer partners -for C\(hyKermit are: another copy of C\(hyKermit (7.0 or later) and Kermit 95. -These combinations work well and they work fast by default. MS\(hyDOS Kermit -is good too, but you have to tell it to go fast (by giving it the FAST -command). -.PP -Furthermore, all three of these Kermit programs support "autodownload" and -"autoupload", meaning that when they are in Connect state and a Kermit -packet comes in from the remote, they automatically switch into file -transfer mode. -.PP -And plus, C\(hyKermit and K95 also switch automatically between text and -binary mode for each file, so there is no need to "set file type binary" or -"set file type text", or to worry about files being corrupted because they -were transferred in the wrong mode. -.PP -What all of these words add up to is that now, when you use up\(hyto\(hydate -Kermit software from the Kermit Project, file transfer is not only fast, -it's ridiculously easy. You barely have to give any commands at all. -.TP -Downloading Files -Let's say you have Kermit 95, C\(hyKermit, or MS\(hyDOS Kermit on your -desktop computer, with a connection to a Unix computer that has -C\(hyKermit installed as "kermit". To download a file (send it from Unix -to your desktop computer), just type the following command at your -Unix shell prompt: -.sp - kermit \-s oofa.txt -.sp -(where oofa.txt is the filename). If you want to send more than one -file, you can put as many filenames as you want on the command line, -and they can be any combination of text and binary: -.sp - kermit \-s oofa.txt oofa.zip oofa.html oofa.tar.gz -.sp -and/or you can use wildcards to send groups of files: -.sp - kermit \-s oofa.* -.sp -If you want to send a file under an assumed name, use: -.sp - kermit \-s friday.txt \-a today.txt -.sp -This sends the file friday.txt but tells the receiving Kermit that its -name is today.txt. In all cases, as noted, when the file transfer is -finished, your desktop Kermit returns automatically to Connect state. -No worries about escaping back, re\(hyconnecting, text/binary mode -switching. Almost too easy, right? -.TP -Uploading Files -To upload files (send them from your desktop computer to the remote -Unix computer) do the same thing, but use the \-g (GET) option instead -of \-s: -.sp - kermit \-g oofa.txt -.sp -This causes your local Kermit to enter server mode; then the remote -Kermit program requests the named file and the local Kermit sends it -and returns automatically to Connect state when done. -.sp -If you want to upload multiple files, you have have use shell quoting -rules, since these aren't local files: -.sp -.nf - kermit \-g "oofa.txt oofa.zip oofa.html oofa.tar.gz" - kermit \-g "oofa.*" -.fi -.sp -If you want to upload a file but store it under a different name, use: -.sp - kermit \-g friday.txt \-a today.txt -.TP -Kermit Transfers the Old\(hyFashioned Way -If your desktop communications software does not support autoupload or -autodownload, or it does not include Kermit server mode, the procedure -requires more steps. -.sp -To download a file, type: -.sp - kermit \-s filename -.sp -on the host as before, but if nothing happens automatically in -response to this command, you have to switch your desktop -communications software into Kermit Receive state. This might be done -by escaping back using keyboard characters or hot keys (Alt\-x is -typical) and/or with a command (like RECEIVE) or a menu. When the file -transfer is complete, you have to go back to Connect state, Terminal -emulation, or whatever terminology applies to your desktop -communications software. -.sp -To upload a file, type: -.sp - kermit \-r -.sp -on the host (rather than "kermit \-g"). This tells C\(hyKermit to wait -passively for a file to start arriving. Then regain the attention of -your desktop software (Alt\-x or whatever) and instruct it to send the -desired file(s) with Kermit protocol. When the transfer is finished, -return to the Connect or Terminal screen. -.TP -If File Transfer Fails -Although every aspect of Kermit's operation can be finely tuned, there -are also three short and simple "omnibus tuning" commands you can use -for troubleshooting: -.RS -.TP -FAST -Use fast file\(hytransfer settings. This has been the default since -C\(hyKermit 7.0 now that most modern computers and connections -support it. If transfers fail with fast settings, try . . . -.TP -CAUTIOUS -Use cautious but not paranoid settings. File transfers, if they -work, will go at medium speed. If not, try . . . -.TP -ROBUST -Use the most robust, resilient, conservative, safe, and reliable -settings. File transfers will almost certainly work, but they -will be quite slow (of course this is a classic tradeoff; ROBUST -was C\(hyKermit's default tuning in versions 6.0 and earlier, which -made everybody think Kermit protocol was slow). If ROBUST doesn't -do the trick, try again with SET PARITY SPACE first in case it's -not an 8\(hybit connection. -.RE -.sp -Obviously the success and performance of a file transfer also depends -on C\(hyKermit's file transfer partner. Up\(hyto\(hydate, real Kermit Project -partners are recommended because they contain the best Kermit protocol -implementations and because we can support them in case of trouble. -.sp -If you still have trouble, consult Chapter 10 of Using C\(hyKermit, or -send email to kermit\(hysupport@columbia.edu. -.TP -Advanced Kermit File\(hyTransfer Features -Obviously there is a lot more to Kermit file transfer, including all -sorts of interactive commands, preferences, options, logging, -debugging, troubleshooting, and anything else you can imagine but -that's what the manual and updates are for. Here are a few topics you -can explore if you're interested by Typing HELP for the listed -commands: -.RS -.TP -Logging transfers: -LOG TRANSACTIONS (HELP LOG) -.TP -Automatic per\(hyfile text/binary mode switching: -SET TRANSFER MODE { AUTOMATIC, MANUAL } (HELP SET TRANSFER). -.TP -Cross\(hyplatform recursive directory tree transfer: -SEND /RECURSIVE, GET /RECURSIVE (HELP SEND, HELP GET). -.TP -File collision options: -SET FILE COLLISION { OVERWRITE, BACKUP, DISCARD, ... } (HELP SET FILE). -.TP -Update: Transfer only files that changed since last time: -SET FILE COLLISION UPDATE (HELP SET FILE). -.TP -Filename selection patterns: -(HELP WILDCARD). -.TP -Flexible file selection: -SEND (or GET) /BEFORE /AFTER /LARGER /SMALLER /TYPE /EXCEPT, ... -.TP -Character\(hyset conversion: -SET { FILE, TRANSFER } CHARACTER\-SET, ASSOCIATE, ... -.TP -File/Pathname control: -SET { SEND, RECEIVE } PATHNAMES, SET FILE NAMES. -.TP -Atomic file movement: -SEND (or GET) /DELETE /RENAME /MOVE\-TO -.TP -Transferring to/from standard i/o of other commands: -SEND (or GET) /COMMAND -.TP -Recovery of interrupted transfer from point of failure: -RESEND, REGET (HELP RESEND, HELP REGET). -.RE -.TP -Non\(hyKermit File Transfer -You can also use C\(hyKermit to transfer files with FTP or HTTP Internet -protocols; see below. -.sp -On a regular serial or Telnet connection where the other computer -doesn't support Kermit protocol at all, you have several options. For -example, if your desktop communications software supports Zmodem, use -"rz" and "sz" on the host rather than Kermit. But if Kermit is your -desktop software, and you are using it to make calls or network -connections to other computers that don't support Kermit protocol (or -that don't have a good implementation of it), then if your computer -also has external X, Y, or Zmodem programs that are redirectable, -Kermit can use them as external protocols. HELP SET PROTOCOL for -details. -.sp -You can also capture "raw" data streams from the other computer with -LOG SESSION (HELP LOG and HELP SET SESSION\-LOG for details), and you -can upload files without any protocol at all with TRANSMIT (HELP -TRANSMIT, HELP SET TRANSMIT). -.SH KERMIT'S BUILT\(hyIN FTP AND HTTP CLIENTS -Kermit's FTP client is like the regular Unix FTP client that you're used -to, but with some differences: -.TP -\(bu -It has lots more commands and features. -.TP -\(bu -Each FTP command must be prefixed with "ftp", for example "ftp open", -"ftp get", "ftp bye", etc (this is not strictly true, but until you're -more familiar with it, it's best to follow this rule). -.TP -\(bu -Commands like "cd", "directory", etc, execute locally, not on the -server. Use "ftp cd", "ftp dir", etc, to have them act on the server. -.TP -\(bu -You can have an FTP session and a regular Kermit serial or Telnet -session open at the same time. -.TP -\(bu -FTP sessions can be fully automated. -.PP -Pending publication of the next edition of the manual, the Kermit FTP -client is thoroughly documented at the Kermit Project website: -.sp - http://www.columbia.edu/kermit/ftpclient.html -.sp -You also can use HELP FTP and HELP SET FTP to get descriptions of Kermit's -FTP\(hyrelated commands. -.PP -The HTTP client is similar to the FTP one, except you prefix each command -with HTTP instead of FTP: HTTP OPEN, HTTP GET, HTTP PUT, HTTP CLOSE, etc. -Type HELP HTTP for details, or visit the to view the manual supplements. -HTTP connections can be open at the same time as regular serial or Telnet -connections and FTP connections. So Kermit can manage up to three types -connections simultaneously. -.SH INTERNET KERMIT SERVICE -C\(hyKermit can be configured and run as an Internet service (called IKSD), -similar to an FTP server (FTPD) except you can (but need not) interact with -it directly, plus it does a lot more than an FTP server can do. The TCP -port for IKSD is 1649. It uses Telnet protocol. C\(hyKermit can be an Internet -Kermit Server, or it can be a client of an IKSD. You can make connections -from C\(hyKermit to an IKSD with any of the following commands: -.sp -.nf - telnet foo.bar.edu 1649 - telnet foo.bar.edu kermit ; if "kermit" is listed in /etc/services - iksd foo.bar.edu -.fi -.sp -The IKSD command is equivalent to a TELNET command specifying port 1649. -For more information about making and using connections to an IKSD, see: -.sp - http://www.columbia.edu/kermit/cuiksd.html -.sp -You can run an Internet Kermit Service on your own computer too (if you are -the system administrator). For instructions, see: -.sp - http://www.columbia.edu/kermit/iksd.html -.SH SECURITY -All of C\(hyKermit's built\(hyin TCP/IP networking methods (Telnet, Rlogin, IKSD, -FTP, and HTTP) can be secured by one or more of the following IETF\(hyapproved -methods: -.PP -\(bu MIT Kerberos IV -.br -\(bu MIT Kerberos V -.br -\(bu SSL/TLS -.br -\(bu Stanford SRP -.PP -For complete instructions see: -.PP - http://www.columbia.edu/kermit/security.html -.PP -And as noted previously, you can also make SSH connections with C\(hyKermit if -you already have an SSH client installed. -.SH ALTERNATIVE COMMAND\(hyLINE PERSONALITIES -When invoked as "kermit" or any other name besides "ftp" or "telnet", -C\(hyKermit has the command\(hyline options described above in the OPTIONS -section. However, if you invoke C\(hyKermit as "telnet" or "ftp", it changes -its command\(hyline personality to match. This can be done (among other ways) -with symbolic links (symlinks). For example, if you want C\(hyKermit to be -your regular Telnet client, or the Telnet helper of your Web browser, you -can create a link like the following in a directory that lies in your PATH -ahead of the regular telnet program: -.sp - ln \-s /usr/local/bin/kermit telnet -.sp -Now when you give a "telnet" command, you are invoking Kermit instead, but -with its Telnet command\(hyline personality so, for example: -.sp - telnet xyzcorp.com -.sp -Makes a Telnet connection to xyzcorp.com, and Kermit exits automatically -when the connection is closed (just like the regular Telnet client). Type -"telnet \-h" to get a list of Kermit's Telnet\(hypersonality command\(hyline -options, which are intended to be as compatible as possible with the -regular Telnet client. -.PP -Similarly for FTP: -.sp - ln \-s /usr/local/bin/kermit ftp -.sp -And now type "ftp \-h" to see its command\(hyline options, and command lines -just like you would give your regular FTP client: -.sp - ftp xyzcorp.com -.sp -but with additional options allowing an entire session to be specified on -the command line. Finally, if Kermit's -first command\(hyline option is a Telnet, FTP, IKSD, or HTTP URL, Kermit -automatically makes the appropriate kind of connection and, if indicated by -the URL, takes the desired action: -.TP -kermit telnet:xyzcorp.com -Opens a Telnet session -.TP -kermit telnet://olga@xyzcorp.com -Ditto for user olga -.TP -kermit ftp://olga@xyzcorp.com/public/oofa.zip -Downloads a file -.TP -kermit kermit://kermit.columbia.edu/kermit/f/READ.ME -Ditto for IKSD -.TP -kermit iksd://kermit.columbia.edu/kermit/f/READ.ME -(This works too) -.TP -kermit http://www.columbia.edu/kermit/index.html -Grabs a web page -.fi -.SH LICENSE -C\(hyKermit has an unusual license, but a fair and sensible one since the -Kermit Project must support itself out of revenue: it's not a BSD license, -not GPL, not Artistic, not commercial, not shareware, not freeware. It can -be summed up like this: if you want C\(hyKermit for your own use, you can -download and use it without cost or license (but we'd appreciate it if you -would purchase the manual). But if you want to sell C\(hyKermit or bundle it -with a product or otherwise distribute it in a commercial setting EXCEPT -WITH AN OPEN\(hySOURCE OPERATING SYSTEM DISTRIBUTION such as Linux, FreeBSD, -NetBSD, or OpenBSD, you must license it. To see the complete license, give -the LICENSE command at the prompt, or see the COPYING.TXT file distributed -with C\(hyKermit 7.0 or later, or download it from -.sp - ftp://kermit.columbia.edu/kermit/c\-kermit/COPYING.TXT -.sp -Send licensing inquiries to kermit@columbia.edu. -.SH BUGS -See the following files for listings of known bugs, limitations, -workarounds, hints and tips: -.TP -ckcbwr.txt -General C\(hyKermit bugs, hints, tips. -.TP -ckubwr.txt -Unix\(hyspecific C\(hyKermit bugs, hints, tips. -.PP -Report bugs and problems by email to: -.sp - kermit\-support@columbia.edu. -.sp -Before requesting technical support, please read the hints here: -.sp - http://www.columbia.edu/kermit/support.html -.sp -and also read the C\(hyKermit Frequently Asked Questions: -.sp - http://www.columbia.edu/kermit/ckfaq.html -.SH OTHER TOPICS -There's way more to C\(hyKermit than we've touched on here \(hy\(hy troubleshooting, -customization, character sets, dialing directories, sending pages, script -writing, and on and on, all of which are covered in the manual and updates -and supplements. For the most up\(hyto\(hydate information on documentation (or -updated documentation itself) visit the Kermit Project website: -.sp - http://www.columbia.edu/kermit/ -.PP -There you will also find Kermit software packages for other platforms: -different Unix varieties, Windows, DOS, VMS, IBM mainframes, and many -others: 20+ years' worth. -.SH DOCUMENTATION AND UPDATES -The manual for C\(hyKermit is: -.TP -.I -Using C\(hyKermit -Frank da Cruz and Christine M. Gianone, -Second Edition, Digital Press / Butterworth\(hyHeinemann, Woburn, MA, 1997, 622 -pages, ISBN 1\-55558\-164\-1. This is a printed book. It covers C\(hyKermit 6.0. -.TP -The C\(hyKermit 7.0 Supplement -http://www.columbia.edu/kermit/ckermit2.html -.TP -The C\(hyKermit 8.0 Supplement -http://www.columbia.edu/kermit/ckermit3.html -.PP -Visit C\(hyKermit home page: -.sp - http://www.columbia.edu/kermit/ckermit.html -.sp -to learn about new versions, Beta tests, and other news; to -read case studies and tutorials; to download source code, install packages, -and prebuilt binaries for many platforms. Also visit: -.TP -http://www.columbia.edu/kermit/scriptlib.html -The Kermit script library and tutorial -.TP -http://www.columbia.edu/kermit/newfaq.html -The Kermit FAQ (Frequently Asked Questions about Kermit) -.TP -http://www.columbia.edu/kermit/ckfaq.html -The C\(hyKermit FAQ (Frequently Asked Questions about C\(hyKermit) -.TP -http://www.columbia.edu/kermit/telnet.html -C\(hyKermit Telnet client documentation -.TP -http://www.columbia.edu/kermit/security.html -C\(hyKermit security documentation (Kerberos, SSL/TLS, etc) -.TP -http://www.columbia.edu/kermit/cuiksd.html -Internet Kermit Service user documentation -.TP -http://www.columbia.edu/kermit/iksd.html -Internet Kermit Service administrator documentation -.TP -http://www.columbia.edu/kermit/studies.html -Case studies. -.TP -http://www.columbia.edu/kermit/support.html -Technical support. -.TP -http://www.columbia.edu/kermit/k95tutorial.html -Kermit 95 tutorial. -.TP -comp.protocols.kermit.misc -The Kermit newsgroup (unmoderated). -.SH FILES -.TP -COPYING.TXT -C\(hyKermit license. -.TP -~/.kermrc -Initialization file. -.TP -~/.mykermrc -Customization file. -.TP -~/.kdd -Kermit dialing directory (see manual). -.TP -~/.knd -Kermit network directory (see manual). -.TP -~/.ksd -Kermit services directory (see manual). -.TP -ca_certs.pem -Certificate Authority certifcates used for SSL connections. -.TP -ckuins.txt -Installation instructions for Unix. Also at -http://www.columbia.edu/kermit/ckuins.html. -.TP -ckcbwr.txt -General C\(hyKermit bugs, hints, tips. -.TP -ckubwr.txt -Unix\(hyspecific C\(hyKermit bugs, hints, tips. -.TP -ckcplm.txt -C\(hyKermit program logic manual. -.TP -ckccfg.txt -C\(hyKermit compile\(hytime configuration options. -.TP -ssh -(in your PATH) SSH connection helper. -.TP -rz, sz, etc. -(in your PATH) external protocols for XYZmodem. -.TP -/var/spool/locks (or whatever) -UUCP lockfile for dialing out (see installation instructions). -.SH AUTHORS -.TP -Software -Frank da Cruz and Jeffrey E Altman, -.br -1985\(hypresent, with contributions from hundreds of others all over the -world. -.TP -Documentation -Frank da Cruz and Christine M Gianone -.TP -Address -.nf -The Kermit Project \(hy Columbia Univerity -612 West 115th Street -New York NY 10025\-7799 -USA -.fi -.TP -E\(hyMail -kermit@columbia.edu -.TP -Web -http://www.columbia.edu/kermit/ -.fi -.br diff --git a/.pc/060_speeling.patch/ckututor.txt b/.pc/060_speeling.patch/ckututor.txt deleted file mode 100644 index 9448126..0000000 --- a/.pc/060_speeling.patch/ckututor.txt +++ /dev/null @@ -1,1959 +0,0 @@ - -C-KERMIT 8.0 UNIX MANUAL PAGE AND TUTORIAL - - Frank da Cruz, Christine M. Gianone - [1]The Kermit Project, [2]Columbia University - - [ [3]PDF version ] [ [4]Nroff version ] - - This document is intended to give the beginner sufficient - information to make basic (if not advanced) use of C-Kermit 8.0. - Although it might be rather long for a Unix manual page (about 1600 - lines), it's still far shorter than the C-Kermit manual, which - should be consulted for advanced topics such as customization, - character-sets, scripting, etc. We also attempt to provide a clear - structural overview of C-Kermit's many capabilities, functional - areas, states, and modes and their interrelation, that should be - helpful to beginners and veterans alike, as well as to those - upgrading to the new release. - - Most recent update: 24 October 2002 - ________________________________________________________________________ - - CONTENTS - * [5]DESCRIPTION - * [6]SYNOPSIS - * [7]OPTIONS - * [8]COMMAND LANGUAGE - * [9]INITIALIZATION FILE - * [10]MODES OF OPERATION - * [11]MAKING CONNECTIONS - * [12]TRANSFERRING FILES WITH KERMIT - * [13]KERMIT CLIENT/SERVER CONNECTIONS - * [14]KERMIT'S BUILT-IN FTP AND HTTP CLIENTS - * [15]INTERNET KERMIT SERVICE - * [16]SECURITY - * [17]ALTERNATIVE COMMAND-LINE PERSONALITIES - * [18]LICENSE - * [19]OTHER TOPICS - * [20]DOCUMENTATION AND UPDATES - * [21]FILES - * [22]AUTHORS - _________________________________________________________________ - - DESCRIPTION [ [23]Top ] [ [24]Contents ] [ [25]Next ] - - [26]C-Kermit is an all-purpose communications software package from - the [27]Kermit Project at [28]Columbia University that: - - * Is portable to many platforms, Unix and non-Unix alike. - * Can make both serial and network connections. - * Can conduct interactive terminal sessions over its connection. - * Can transfer text or binary files over the same connection. - * Can convert text-file character sets in terminal mode or file - transfer. - * Is customizable in every aspect of its operation. - - C-Kermit is a modem program, a Telnet client, an Rlogin client, an FTP - client, an HTTP client, and on selected platforms, also an X.25 - client. It can make its own secure Internet connections using - IETF-approved security methods including Kerberos IV, Kerberos V, - SSL/TLS, and SRP and it can also make SSH (Secure Shell) connections - through your external SSH client application. It can be the far-end - file-transfer or client/server partner of your desktop Kermit client. - It can also accept incoming dialed and network connections. It can - even be installed as an Internet service on its own standard TCP - socket, 1649 [[29]RFC2839, [30]RFC2840]. - - And perhaps most important, everything you can do "by hand" - (interactively) with C-Kermit, can be "scripted" (automated) using its - built-in cross-platform transport-independent script programming - language, which happens to be identical to its interactive command - language. - - This manual page offers an overview of C-Kermit 8.0 for Unix ("Unix" - is an operating system family that includes AIX, DG/UX, FreeBSD, - HP-UX, IRIX, Linux, Mac OS X, NetBSD, OpenBSD, Open Server, Open Unix, - QNX, Solaris, SunOS, System V R3, System V R4, Tru64 Unix, Unixware, - Xenix, and many others). For thorough coverage, please consult the - published C-Kermit manual and supplements (see [31]DOCUMENTATION - below). For further information about C-Kermit, Kermit software for - other platforms, and Kermit manuals, visit the Kermit Project website: - - [32]http://www.columbia.edu/kermit/ - - This is a longer-than-average manual page, and yet it barely scratches - the surface. Don't be daunted. C-Kermit is a large and complex - package, evolving over decades of practice and experience, but that - doesn't mean it's hard to learn or use. Its most commonly used - functions are explained here with pointers to additional information - elsewhere. - - [ [33]Kermit Home ] [ [34]C-Kermit Home ] [ [35]C-Kermit FAQ ] - ________________________________________________________________________ - - SYNOPSIS [ [36]Top ] [ [37]Contents ] [ [38]Next ] [ [39]Previous ] - - Usage: kermit [filename] [-x arg [-x arg]...[-yyy]..] [ {=,--,+} text - ] ] - Or: kermit URL - - * -x is an option requiring an argument; - * -y is an option with no argument. - - If the first command-line argument is the name of a file, - interactive-mode commands are executed from the file. The '=' (or - "--") argument tells Kermit not to parse the remainder of the command - line, but to make the words following '=' available as \%1, \%2, ... - \%9. The "+" argument is like "=" but for use in "kerbang scripts" - (explained [40]below). A second command-line format allows the one and - only argument to be a [41]Telnet, FTP, HTTP, or IKSD URL. - - Order of execution: - - 1. [42]The command file (if any). - 2. [43]The initialization file, if any, unless suppressed with -Y. - 3. [44]The customization file (if it is executed by the - initialization file). - 4. [45]The command-line URL (if any, and if so, execution stops - here). - 5. [46]Command-line options (if any). - 6. [47]Interactive commands. - - Some command-line options can cause actions (such as -s to send a - file); others just set parameters. If any action options are included - on the command line, Kermit exits when finished unless also given the - -S ("stay") option. If no action options are given, no initialization - or command files contained an EXIT or QUIT command, and no fatal - errors occurred, Kermit issues its prompt and waits for you to type - commands. - - Bear in mind that C-Kermit can be built with selected features - disabled, and also that certain features are not available on all - platforms. For example, C-Kermit can't be built with TCP/IP support - on a platform that does not have TCP/IP header files and libraries - (and even if Kermit does include TCP/IP support, it can't be used - to make TCP/IP connections on a computer that does not have a - TCP/IP stack installed). If your version of C-Kermit lacks a - feature mentioned here, use its SHOW FEATURES command to see what - might have been excluded. - - C-Kermit has three kinds of commands: regular single-letter - command-line options, extended-format command-line options, and - interactive commands. - - [ [48]Kermit Home ] [ [49]C-Kermit Home ] [ [50]C-Kermit FAQ ] - ________________________________________________________________________ - - OPTIONS [ [51]Top ] [ [52]Contents ] [ [53]Next ] [ [54]Previous ] - - Like most Unix commands, C-Kermit can be be given options on the - command line. But C-Kermit also can be used interactively by giving it - [55]commands composed of words, which are more intuitive than cryptic - command-line options, and more flexible too. In other words, you don't - have to use C-Kermit's command-line options, but they are available if - you want to. (By the same token, you don't have to use its interactive - commands either -- you can use either or both in any combination.) - - C-Kermit is generally installed in the PATH as "kermit", and therefore - is invoked by typing the word "kermit" (lowercase) at the shell - prompt, and then pressing the Return or Enter key. If you wish to - include command-line options, put them after the word "kermit" but - before pressing Return or Enter, separated by spaces, for example: - - $ kermit -s ckermit.tar.gz - - ('$' is the shell prompt; "kermit -s ckermit.tar.gz" is what you type, - followed by Return or Enter.) - - Here is a list of C-Kermit's single-letter command-line options, which - start with a single dash (-), in ASCII ("alphabetical") order. - Alphabetic case is significant (-A is not the same as -a). The Action? - column contains Y for action options and N for non-action options. - Option Action? Description - -0 N (digit zero) 100% transparent Connect state for "in-the-middle" - operation: 8 bits, no parity, no escape character, everything passes - through. - -8 N (digit eight) Connection is 8-bit clean (this is the default in - C-Kermit 8.0). Equivalent to the EIGHTBIT command, which in turn is a - shortcut for SET TERMINAL BYTESIZE 8, SET COMMAND BYTESIZE 8, SET - PARITY NONE. - -9 arg N (digit nine) Make a connection to an FTP server. Equivalent - to the FTP OPEN command. - Argument: IP-address-or-hostname[:optional-TCP-port]. - NOTE: C-Kermit also has a separate FTP command-line personality, with - regular FTP-like command-line syntax. [56]More about this below. - -A N Kermit is to be started as an Internet service (IKSD) (only from - inetd.conf). - -B N Kermit is running in Batch or Background (no controlling - terminal). To be used in case Kermit doesn't automatically sense its - background status. Equivalent to the SET BACKGROUND ON command. - -C arg N Interactive-mode Commands to be executed. - Argument: Commands separated by commas, list in doublequotes. - -D arg N Delay before starting to send in Remote mode. Equivalent to - the SET DELAY command. - Argument: Number of seconds. - -E N Exit automatically when connection closes. Equivalent to SET EXIT - ON-DISCONNECT ON. - -F arg N Use an open TCP connection. - Argument: Numeric file descriptor of open TCP connection. - Also see: -j, -J. - -G arg Y Get file(s) from server, send contents to standard output, - which normally would be piped to another process. - Argument: Remote file specification, in quotes if it contains - metacharacters. - Also see: -g, -k. - -H N Suppress program startup Herald and greeting. - -I N Tell Kermit it has a reliable connection, to force streaming to - be used where it normally would not be. Equivalent to the SET RELIABLE - ON command. - -J arg N "Be like Telnet." Like -j but implies -E. - Argument: IP hostname/address optionally followed by service. - NOTE: C-Kermit also has a separate Telnet command-line personality, - with regular Telnet-like command-line syntax. [57]More about this - below. - -L N Recursive directory descent for files in -s option. - -M arg N My user name (for use with Telnet, Rlogin, FTP, etc). - Equivalent to the SET LOGIN USER command. - Argument: Username string. - -O Y (Uppercase letter O) Be a server for One command only. Also see: - -x. - -P N Don't convert file (Path) names of transferred files. Equivalent - to SET FILE NAMES LITERAL. - -Q N Quick Kermit protocol settings. Equivalent to the FAST command. - This is the default in C-Kermit 7.0 and later. - -R N Remote-only (this just makes IF REMOTE true). - -S N Stay (enter command parser after action options). - -T N Force Text mode for file transfer; implies -V. Equivalent to SET - TRANSFER MODE MANUAL, SET FILE TYPE TEXT. - -V N Disable automatic per-file text/binary switching. Equivalent to - SET TRANSFER MODE MANUAL. - -Y N Skip (don't execute) the initialization file. - -a arg N As-name for file(s) in -s, -r, or -g. - Argument: As-name string (alternative filename). When receiving files, - this can be a directory name. - -b arg N Speed for serial device. Equivalent to SET SPEED. - Argument: Numeric Bits per second for serial connections. - -c Y Enter Connect state before transferring files. - -d N Create a debug.log file with detailed debugging information (a - second -d adds timestamps). Equivalent to LOG DEBUG but takes effect - sooner. - -e arg N Maximum length for incoming Kermit file-transfer packets. - Equivalent to SET RECEIVE PACKET-LENGTH. - Argument: Length in bytes. - -f Y Send a FINISH command to a Kermit server. - -g arg N Get file(s) from a Kermit server. - Argument: File specification on other computer, in quotes if it - contains metacharacters. Equivalent to GET. - Also see: -a, -G, -r. - -h Y Print Help text for single-letter command-line options (pipe thru - 'more' to prevent scrolling). - -i N Force binary (Image) mode for file transfer; implies -V. - Equivalent to SET TRANSFER MODE MANUAL, SET FILE TYPE BINARY. - -j arg N Make a TCP/IP connection. - Argument: IP host name/address and optional service name or number. - Equivalent to the TELNET command. - Also see: -J, -F. - -k Y Receive file(s) to standard output, which normally would be piped - to another process. - Also see: -r, -G. - -l arg N (Lowercase letter L) Make a connection on the given serial - communications device. Equivalent to the SET LINE (SET PORT) command. - Argument: Serial device name, e.g. /dev/ttyS0. - -m arg N Modem type for use with the -l device. Equivalent to the SET - MODEM TYPE command. - Argument: Modem name as in SET MODEM TYPE command, e.g. "usrobotics". - -n Y Enter Connect state after transferring files (historical). - -p arg N Parity. Equivalent to the SET PARITY command. - Argument: One of the following: e(ven), o(dd), m(ark), n(one), - s(pace). - -q N Quiet (suppress most messages). Equivalent to SET QUIET ON. - -r Y Receive file(s). Equivalent to the RECEIVE command. - Argument: (none, but see -a) - -s arg N Send file(s). - Argument: One or more local file specifications. Equivalent to the - SEND command. - Also see: -a. - -t N (Historical) Xon (Ctrl-Q) Turnaround character for half-duplex - connections (used on serial linemode connections to old mainframes). - Equivalent to SET DUPLEX HALF, SET HANDSHAKE XON. - -v arg N Window size for Kermit protocol (ignored when streaming). - Equivalanet to SET WINDOW-SIZE. - Argument: Number, 1 to 32. - -w N Incoming files Write over existing files. Equivalent to SET FILE - COLLISION OVERWRITE. - -x Y Enter server mode. Equivalent to the SERVER command. Also see: - -O. - -y arg N Alternative initialization file. - Argument: Filename. - -z N Force foreground behavior. To be used in case Kermit doesn't - automatically sense its foreground status. Equivalent to the SET - BACKGROUND OFF command. - - Extended command-line options (necessary because single-letter ones - are about used up) start with two dashes (--), with words rather than - single letters as option names. If an extended option takes an - argument, it is separated from the option word by a colon (:). - Extended options include: - Option Description - --bannerfile:filename File to display upon startup or IKSD login. - --cdfile:filename File to be sent for display to the client when - server changes directory (filename is relative to the changed-to - directory). - --cdmessage:{on,off} Enable/disable the server CD message feature. - --help Prints usage message for extended options. - --helpfile:filename Designates a file containing custom text to - replace the top-level HELP command. - --nointerrupts Disables keyboard interrupts. - --noperms Disables the Kermit protocol file Permissions attribute, to - prevent transmission of file permissions (protection) from sender to - receiver. - - Plus several other [58]IKSD-Only options. - - See the [59]file-transfer section for examples of command-line - invocation. - ________________________________________________________________________ - - COMMAND LANGUAGE [ [60]Top ] [ [61]Contents ] [ [62]Next ] [ [63]Previous ] - - * [64]Command Files, Macros, and Scripts - * [65]Command List - - C-Kermit's interactive command language is the subject of a - [66]622-page book and another several hundred pages of updates, far - too much for a manual page. But it's not hard to get started. At the - shell prompt, just type "kermit" to get C-Kermit's interactive command - prompt: - - $ kermit - (/current/directory) C-Kermit> - - Begin by typing "help" (and then press the Return or Enter key) for a - top-level overview, read it, and go from there. Your second command - should probably be "intro" (introduction). Note the prompt shows your - current directory (unless you tell Kermit to prompt you with something - else). - - Interactive commands are composed mainly of regular English words, - usually in the form of imperative sentences, such as: - - send oofa.txt - - which tells Kermit to send (transfer) the file whose name is oofa.txt, - or: - - set transfer mode automatic - - which sets Kermit's "transfer mode" to "automatic" (whatever that - means). - - While typing commands, you can abbreviate, ask for help (by pressing - the "?" key anywhere in a command), complete keywords or filenames - (with the Tab or Esc key), and edit your typing with Backspace or - Delete, Ctrl-W, Ctrl-U, etc. You can also recall previous commands, - save your command history, and who knows what else. Give the INTRO - command for details. - - C-Kermit has hundreds of commands, and they can be issued in infinite - variety and combinations, including commands for: - - * Making connections (SET LINE, DIAL, TELNET, SSH, FTP, CONNECT, - ...) - * Breaking connections (HANGUP, CLOSE) - * Transferring files (SEND, GET, RECEIVE, MOVE, RESEND, ...) - * Establishing preferences (SET) - * Displaying preferences (SHOW) - * Managing local files (CD, DELETE, MKDIR, DIRECTORY, RENAME, TYPE, - ...) - * Managing remote files (RCD, RDEL, RMKDIR, RDIR, ...) - * Using local files (FOPEN, FCLOSE, FREAD, FWRITE) - * Programming (TAKE, DEFINE, IF, FOR, WHILE, SWITCH, DECLARE, ...) - * Interacting with the user (ECHO, ASK, ...) - * Interacting with a remote computer (INPUT, OUTPUT, ...) - * Interacting with local programs (RUN, EXEC, PTY, ...) - * Logging things (LOG SESSION, LOG PACKETS, LOG DEBUG, ...) - - And of course QUIT or EXIT to get out and HELP to get help, and for - programmers: loops, decision making, variables, arrays, associative - arrays, integer and floating point arithmetic, macros, built-in and - user-defined functions, string manipulation, pattern matching, block - structure, scoping, recursion, and all the rest. To get a list of all - C-Kermit's commands, type a question mark (?) at the prompt. To get a - description of any command, type HELP followed by the name of the - command, for example: - - help send - - The command interruption character is Ctrl-C (hold down the Ctrl key - and press the C key). - - The command language "escape character", used to introduce variable - names, function invocations, and so on, is backslash (\). If you need - to include a literal backslash in a command, type two of them, e.g.: - - get c:\\k95\\k95custom.ini - - Command Files, Macros, and Scripts - - A file containing Kermit commands is called a Kermit command file or - Kermit script. It can be executed with Kermit's TAKE command: - - (/current/dir) C-Kermit> take commandfile - - (where "commandfile" is the name of the command file). Please don't - pipe a command file into Kermit's standard input (which might or might - not work); if you have Kermit commands in a file, tell Kermit to TAKE - the file. - - In Unix only, a Kermit command file can also be executed directly by - including a "kerbang" line as the first line of the file: - - #!/usr/local/bin/kermit + - - That is, a top line that starts with "#!", followed immediately by the - full path of the Kermit executable, and then, if the Kermit script is - to be given arguments on the command line, a space and a plus sign. - The script file must also have execute permission: - - chmod +x commandfile - - Except for the " +" part, this is exactly the same as you would do for - a shell script, a Perl script, etc. Here's a simple but useless - example script that regurgitates its arguments (up to three of them): - - #!/usr/local/bin/kermit + - if defined \%1 echo "Argument 1: \%1" - if defined \%2 echo "Argument 2: \%2" - if defined \%3 echo "Argument 3: \%3" - if defined \%4 echo "etc..." - exit - - If this file is stored in your current directory as "commandfile", - then: - - ./commandfile one two three four five - - prints: - - Argument 1: one - Argument 2: two - Argument 3: three - etc... - - This illustrates the basic structure of a standalone Kermit script: - the "kerbang line", then some commands. It should end with "exit" - unless you want the Kermit prompt to appear when it is finished. \%1 - is the first argument, \%2 the second, and so on. - - You can also create your own commands by defining named macros - composed of other Kermit commands (or macros). Here's a simple - example: - - define mydial { - set modem type usrobotics - set port /dev/ttyS0 - if fail end 1 - set speed 57600 - dial \%1 - if success connect - } - - This shows how you can combine many commands into one command, - "mydial" in this case (you can use any name you like, provided it does - not clash with the name of a built-in command). When this macro - definition is in effect, you can type commands like: - - mydial 7654321 - - and it executes all the commands in macro definition, substituting the - first operand ("7654321") for the formal parameter ("\%1") in the - definition. This saves you from having to type lots of commands every - time you want to make a modem call. - - One way to have the macro definition in effect is to type the - definition at the Kermit prompt. Another way is to store the - definition in a file and TAKE the file. If you want the the definition - to be in effect automatically every time you start Kermit, put the - definition in your initialization or customization file (explained - [67]below). - - Here's a somewhat more ambitious example: - - define mydelete { - local trash - assign trash \v(home)trashcan/ - if not defined \%1 end 1 "Delete what?" - if wild \%1 end 1 "Deleting multiple files is too scary" - if not exist \%1 end 1 "I can't find \%1" - if not directory \m(trash) { - mkdir \m(trash) - if fail end 1 "No trash can" - } - rename /list \%1 \m(trash) - } - define myundelete { - local trash - assign trash \v(home)trashcan/ - if not defined \%1 end 1 "Undelete what?" - if wild \%1 end 1 "Undeleting multiple files is too hard" - if not directory \m(trash) end 1 "No trash can" - if not exist \m(trash)\%1 end 1 "I can't find \%1 in trash can" - rename /list \m(trash)\%1 . - } - - These macros are not exactly production quality (they don't handle - filenames that include path segments, they don't handle multiple - files, etc), but you get the idea: you can pass arguments to macros, - they can check them and make other kinds of decisions, and the - commands themselves are relatively intuitive and intelligible. - - If you put the above lines into your initialization or customization - file, you'll have MYDELETE and MYUNDELETE commands available every - time you start Kermit, at least as long as you don't suppress - execution of the initialization file. (Exercise for the reader: Make - these macros generally useful: remove limitations, add trashcan - display, browsing, emptying, etc.) - - Kerbang scripts execute without the initialization file. This to keep - them portable and also to make them start faster. If you want to write - Kerbang scripts that depend on the initialization file, include the - command - - take \v(home).kermrc - - at the desired spot in the script. By the way, \v(xxx) is a built-in - variable (xxx is the variable name, "home" in this case). To see what - built-in variables are available, type "show variables" at the - C-Kermit prompt. To see what else you can show, type "show ?". \m(xxx) - is a user defined variable (strictly speaking, it is a macro used as a - variable). - - Command List - - C-Kermit has more than 200 top-level commands, and some of these, such - as SET, branch off into hundreds of subcommands of their own, so it's - not practical to describe them all here. Instead, here's a concise - list of the most commonly used top-level commands, grouped by - category. To learn about each command, type "help" followed by the - command name, e.g. "help set". Terms such as Command state and Connect - state are explained in subsequent sections. - - Optional fields are shown in [ italicized brackets ]. filename means - the name of a single file. filespec means a file specification that is - allowed to contain wildcard characters like '*' to match groups of - files. options are (optional) switches like /PAGE, /NOPAGE, /QUIET, - etc, listed in the HELP text for each command. Example: - - send /recursive /larger:10000 /after:-1week /except:*.txt * - - which can be read as "send all the files in this directory and all the - ones underneath it that are larger than 10000 bytes, no more than one - week old, and whose names don't end with ".txt". - - Basic Commands - HELP Requests top-level help. - HELP command Requests help about the given command. - INTRODUCTION Requests a brief introduction to C-Kermit. - LICENSE Displays the C-Kermit software copyright and license. - VERSION Displays C-Kermit's version number. - EXIT [ number ] Exits from Kermit with the given status code. - Synonyms: QUIT, E, Q. - TAKE filename [ parameters... ] Executes commands from the - given file. - LOG item [ filename ] Keeps a log of the given item in the - given file. - [ DO ] macro [ parameters... ] Executes commands from the - given macro. - SET parameter value Sets the given parameter to the given - value. - SHOW category Shows settings in a given category. - STATUS Tells whether previous command succeeded or failed. - DATE [ date-and/or-time ] Shows current date-time or interprets - given date-time. - RUN [ extern-command [ parameters... ] Runs the given external - command. Synonym: !. - EXEC [ extern-command [ params... ] Kermit overlays itself with - the given command. - SUSPEND Stops Kermit and puts it in the background. Synonym: Z. - - Local File Management - TYPE [ options ] filename Displays the contents of the given - file. - MORE [ options ] filename Equivalent to TYPE /PAGE (pause after - each screenful). - CAT [ options ] filename Equivalent to TYPE /NOPAGE. - HEAD [ options ] filename Displays the first few lines of a - given file. - TAIL [ options ] filename Displays the last few lines of a - given file. - GREP [ options ] pattern filespec Displays lines from files - that match the pattern. Synonym: FIND. - DIRECTORY [ options ] [ filespec ] Lists files (built-in, many - options). - LS [ options ] [ filespec ] Lists files (runs external "ls" - command). - DELETE [ options ] [ filespec ] Deletes files. Synonym: RM. - PURGE [ options ] [ filespec ] Removes backup (*.~n~) files. - COPY [ options ] [ filespecs... ] Copies files. Synonym: CP. - RENAME [ options ] [ filespecs... ] Renames files. Synonym: MV. - CHMOD [ options ] [ filespecs... ] Changes permissions of - files. - TRANSLATE filename charsets filename ] Converts file's - character set. Synonym: XLATE. - CD Changes your working directory to your home directory. - CD directory Changes your working directory to the one given. - CDUP Changes your working directory one level up. - PWD Displays your working directory. - BACK Returns to your previous working directory. - MKDIR [ directory ] Creates a directory. - RMDIR [ directory ] Removes a directory. - - Making Connections - SET LINE [ options ] devicename Opens the named serial - port. Synonym: SET PORT. - OPEN LINE [ options ] devicename Same as SET LINE. Synonym: - OPEN PORT. - SET MODEM TYPE [ name ] Tells Kermit what kind of modem is on - the port. - DIAL [ number ] Tells Kermit to dial the given phone number - with the modem. - REDIAL Redials the most recently dialed phone number. - ANSWER Waits for and answers an incoming call on the modem. - AUTHENTICATE [ parameters... ] Performs secure authentication - on a TCP/IP connection. - SET NETWORK TYPE { TCP/IP, X.25, ... } Selects network type for - subsequent SET HOST commands. - SET HOST [ options ] host [ port ] Opens a network connection - to the given host and port. - SET HOST [ options ] * port Waits for an incoming TCP/IP - connection on the given port. - TELNET [ options ] host Opens a Telnet connection to the host - and enters Connect state. - RLOGIN [ options ] host Opens an Rlogin connection to the host - and enters Connect state. - IKSD [ options ] host Opens a connection to an Internet Kermit - Service. - SSH [ options ] host Opens an SSH connection to the host and - enters Connect state. - FTP OPEN host [ options ] Opens an FTP connection to the host. - HTTP [ options ] OPEN host Opens an HTTP connection to the - host. - PTY external-command Runs the command on a pseudoterminal as if - it were a connection. - PIPE external-command Runs the command through a pipe as if it - were a connection. - - Using Connections - CONNECT [ options ] Enters Connect - (terminal) state. Synonym: C. - REDIRECT command Redirects the given external command over the - connection. - TELOPT command Sends a Telnet protocol command (Telnet - connections only). - Ctrl-\C "Escapes back" from Connect state to Command state. - Ctrl-\B (In Connect state) Sends a BREAK signal (serial or - Telnet). - Ctrl-\! (In Connect state) Enters inferior shell; "exit" to - return. - Ctrl-\? (In Connect state) Shows a menu of other escape-level - options. - Ctrl-\Ctrl-\ (In Connect state) Type two Ctrl-Backslashes to - send one of them. - SET ESCAPE [ character ] Changes Kermit's Connect-state escape - character. - - Closing Connections - HANGUP Hangs up the currently open serial-port or network - connection. - CLOSE Closes the currently open serial-port or network - connection. - SET LINE (with no devicename) Closes the currently - open serial-port or network connection. - SET HOST (with no hostname) Closes the currently open - serial-port or network connection. - FTP CLOSE Closes the currently open FTP connection. - HTTP CLOSE Closes the currently open HTTP connection. - EXIT Also closes all connections. Synonym: QUIT. - SET EXIT WARNING OFF Suppresses warning about open connections - on exit or close. - - File Transfer - SEND [ options ] filename [ as-name ] Sends the given file. - Synonym: S. - SEND [ options ] filespec Sends all files that match. - RESEND [ options ] filespec Resumes an interupted SEND from the - point of failure. - RECEIVE [ options ] [ as-name ] Waits passively for files to - arrive. Synonym: R. - LOG TRANSACTIONS [ filename ] Keeps a record of file transfers. - FAST Use fast file-transfer settings (default). - CAUTIOUS Use cautious and less fast file-transfer settings. - ROBUST Use ultra-conservative and slow file-transfer settings. - STATISTICS [ options ] Gives statistics about the most recent - file transfer. - WHERE After transfer: "Where did my files go?". - TRANSMIT [ options ] [ filename ] Sends file without protocol. - Synonym: XMIT. - LOG SESSION [ filename ] Captures remote text or files without - protocol. - SET PROTOCOL [ name... ] Tells Kermit to use an external - file-transfer protocol. - FTP { PUT, MPUT, GET, MGET, ... } FTP client commands. - HTTP { PUT, GET, HEAD, POST, ... } HTTP client commands. - - Kermit Server - ENABLE, DISABLE Controls which features - can be used by clients. - SET SERVER Sets parameters prior to entering Server state. - SERVER Enters Server state. - - Client of Kermit or FTP Server - [ REMOTE ] LOGIN [ user password ] Logs in to a Kermit server - or IKSD that requires it. - [ REMOTE ] LOGOUT Logs out from a Kermit server or IKSD. - SEND [ options ] filename [ as-name ] Sends the given file to - the server. Synonyms: S, PUT. - SEND [ options ] filespec Sends all files that match. - RESEND [ options ] filespec Resumes an interupted SEND from the - point of failure. - GET [ options ] remote-filespec Asks the server to send the - given files. Synonym: G. - REGET [ options ] remote-filespec Resumes an interrupted GET - from the point of failure. - REMOTE CD [ directory ] Asks server to change its working - directory. Synonym: RCD. - REMOTE PWD [ directory ] Asks server to display its working - directory. Synonym: RPWD. - REMOTE DIRECTORY [ filespec... ] Asks server to send a - directory listing. Synonym: RDIR. - REMOTE DELETE [ filespec... ] Asks server to delete files. - Synonym: RDEL. - REMOTE [ command... ] (Many other commands: "remote ?" for a - list). - MAIL [ options ] filespec Sends file(s) to be delivered as - e-mail (Kermit only). - FINISH Asks the server to exit server state (Kermit only). - BYE Asks the server to log out and close the connection. - - Script Programming - DEFINE, DECLARE, UNDEFINE, UNDECLARE, ASSIGN, EVALUATE, - SEXPRESSION, ARRAY, SORT, INPUT, OUTPUT, IF, FOR, WHILE, - SWITCH, GOTO, ECHO, ASK, GETC, GETOK, ASSERT, WAIT, SLEEP, - FOPEN, FREAD, FWRITE, FCLOSE, STOP, END, RETURN, LEARN, SHIFT, - TRACE, VOID, INCREMENT, DECREMENT, ... For these and many more - you'll need to consult the [68]manual and supplements, and/or - visit the [69]Kermit Script Library, which also includes a - brief tutorial. Hint: HELP LEARN to find out how to get Kermit - to write simple scripts for you. - - Many of Kermit's commands have synonyms, variants, relatives, and so - on. For example, MSEND is a version of SEND that accepts a list of - file specifications to be sent, rather than just one file - specification, and MPUT is a synonym of MSEND. MOVE means to SEND and - then DELETE the source file if successful. MMOVE is like MOVE, but - accepts a list of filespecs, and so on. These are described in the - [70]full documentation. - - Use question mark to feel your way through an unfamiliar command, as - in this example (the part you type is underlined): - - C-Kermit> remote ? One of the following: - assign delete help login print rename space - cd directory host logout pwd rmdir type - copy exit kermit mkdir query set who - C-Kermit> remote set ? One of the following: - attributes file retry transfer - block-check receive server window - C-Kermit> remote set file ? One of the following: - character-set incomplete record-length - collision names type - C-Kermit> remote set file names ? One of the following: - converted literal - C-Kermit> remote set file names literal - C-Kermit> - - This is called menu on demand: you get a menu when you want one, but - menus are not forced on you even when know what you're doing. Note - that you can also abbreviate most keywords, and you can complete them - with the Tab or Esc key. Also note that ? works for filenames too, and - that you can use it in the middle of a keyword or filename, not just - at the beginning. For example, "send x?" lists all the files in the - current directory whose names start with 'x'. - - [ [71]Kermit Home ] [ [72]C-Kermit Home ] [ [73]C-Kermit FAQ ] - ________________________________________________________________________ - - INITIALIZATION FILE [ [74]Top ] [ [75]Contents ] [ [76]Next ] [ [77]Previous - ] - - In its default configuration, C-Kermit executes commands from a file - called .kermrc in your home directory when it starts, unless it is - given the -Y or -y command-line option. Custom configurations might - substitute a shared system-wide initialization file. The SHOW FILE - command tells what initialization file, if any, was used. The standard - initialization file "chains" to an individual customization file, - .mykermc, in the home directory, in which each user can establish - her/his own preferences, define macros, and so on. - - Since execution of the initialization file (at least the standard one) - makes C-Kermit take longer to start, it might be better not to have an - initialization file, especially now that Kermit's default startup - configuration is well attuned to modern computing and networking -- in - other words, you no longer have do anything special to make Kermit - transfers go fast. So instead of having an initialization file that is - executed every time Kermit starts, you might consider making one or - more kerbang scripts (with names other that .kermrc) that do NOT - include an "exit" command, and invoke those when you need the - settings, macro definitions, and/or scripted actions they contain, and - invoke C-Kermit directly when you don't. - - To put it another way... We still distribute the standard - initialization file since it's featured in the manual and backwards - compatibility is important to us. But there's no harm in not using it - if you don't need the stuff that's in it (services directory, dialing - directory, network directory, and associated macro definitions). On - the other hand, if there are settings or macros you want in effect - EVERY time you use Kermit, the initialization file (or the - customization file it chains to) is the place to put them, because - that's the only place Kermit looks for them automatically each time - you start it. - - [ [78]Kermit Home ] [ [79]C-Kermit Home ] [ [80]C-Kermit FAQ ] - ________________________________________________________________________ - - MODES OF OPERATION [ [81]Top ] [ [82]Contents ] [ [83]Next ] [ [84]Previous ] - - Kermit is said to be in Local mode if it has made a connection to - another computer, e.g. by dialing it or establishing a Telnet - connection to it. The other computer is remote, so if you start - another copy of Kermit on the remote computer, it is said to be in - Remote mode (as long as it has not made any connections of its own). - The local Kermit communicates over the communications device or - network connection, acting as a conduit between the the remote - computer and your keyboard and screen. The remote Kermit is the - file-transfer partner to the local Kermit and communicates only - through its standard input and output. - - At any moment, a Kermit program can be in any of the following states. - It's important to know what they are and how to change from one to the - other. - - Command state - - In this state, Kermit reads commands from: - - + Your keyboard; or: - + A file, or: - + A macro definition. - - You can exit from Command state back to Unix with the EXIT or - QUIT command (same thing). You can enter Connect state with any - of various commands (CONNECT, DIAL, TELNET, etc). You can enter - file transfer state with commands like SEND, RECEIVE, and GET. - You can enter Server state with the SERVER command. The TAKE - command tells Kermit to read and execute commands from a file. - The (perhaps implied) DO command tells Kermit to read and - execute commands from a macro definition. While in Command - state, you can interrupt any command, macro, or command file by - typing Ctrl-C (hold down the Ctrl key and press the C key); - this normally brings you back to the prompt. - - Shell state - - You can invoke an inferior shell or external command from the - Kermit command prompt by using the PUSH, RUN (!), EDIT, or - BROWSE command. While the inferior shell or command is active, - Kermit is suspended and does nothing. Return to Kermit Command - state by exiting from the inferior shell or application. - - Connect state - - In this state, which can be entered only when in Local mode - (i.e. when Kermit has made a connection to another computer), - Kermit is acting as a terminal to the remote computer. Your - keystrokes are sent to the remote computer and characters that - arrive over the communication connection are displayed on your - screen. This state is entered when you give a CONNECT, DIAL, - TELNET, RLOGIN, or IKSD command. You can return to command - state by logging out of the remote computer, or by typing: - - Ctrl-\c - - That is: Hold down the Ctrl key and press the backslash key, - then let go of the Ctrl key and press the C key. This is called - escaping back. Certain other escape-level commands are also - provided; type Ctrl-\? for a list. For example, you can enter - Shell state with: - - Ctrl-\! - - To send a Ctrl-\ to the host while in Connect state, type two - of them in a row. See HELP CONNECT and HELP SET ESCAPE for more - info. - - Local file-transfer state - - In this state, Kermit is sending packets back and forth with - the other computer in order to transfer a file or accomplish - some other file-related task. And at the same time, it is - displaying its progress on your screen and watching your - keyboard for interruptions. In this state, the following - single-keystroke commands are accepted: - - X Interrupt the current file and go on to the next (if any). - Z Interrupt the current file and skip all the rest. - E Like Z but uses a "stronger" protocol (use if X or Z don't - work). - Ctrl-C Interrupt file-transfer mode (use if Z or E don't - work). - - Kermit returns to its previous state (Command or Connect) when - the transfer is complete or when interrupted successfully by X, - Z, E, or Ctrl-C (hold down the Ctrl key and press the C key). - - Remote file-transfer state - - In this state, Kermit is exchanging file-transfer packets with - its local partner over its standard i/o. It leaves this state - automatically when the transfer is complete. In case you find - your local Kermit in Connect state and the remote one in - File-transfer state (in which it seems to ignore your - keystrokes), you can usually return it to command state by - typing three Ctrl-C's in a row. If that doesn't work, return - your local Kermit to Command state (Ctrl-\ C) and type - "e-packet" and then press the Return or Enter key; this forces - a fatal Kermit protocol error. - - Remote Server state - - This is like Remote File-transfer state, except it never - returns automatically to Command state. Rather, it awaits - further instructions from the client program; that is, from - your Local Kermit program. You can return the Remote Server to - its previous state by issuing a "finish" command to the client, - or if you are in Connect state, by typing three Ctrl-C's in a - row. You can tell the server job to log out and break the - connection by issuing a "bye" command to the client. - - Local Server state - - Like Remote-Server state, but in local mode, and therefore with - its file-transfer display showing, and listening for single-key - commands, as in Local File-transfer state. Usually this state - is entered automatically when a remote Kermit program gives a - GET command. - - C-Kermit, Kermit 95, and MS-DOS Kermit all can switch automatically - from Connect state to Local File-transfer state when you initiate a - file transfer from the remote computer by starting Kermit and telling - it to send or get a file, in which case, Connect state is - automatically resumed after the file transfer is finished. - - Note that C-Kermit is not a terminal emulator. It is a communications - application that you run in a terminal window (e.g. console or Xterm). - The specific emulation, such as VT100, VT220, Linux Console, or Xterm, - is provided by the terminal window in which you are running C-Kermit. - Kermit 95 and MS-DOS Kermit, on the other hand, are true terminal - emulators. Why is C-Kermit not a terminal emulator? [85]CLICK HERE to - read about it. - - [ [86]Kermit Home ] [ [87]C-Kermit Home ] [ [88]C-Kermit FAQ ] - ________________________________________________________________________ - - MAKING CONNECTIONS [ [89]Top ] [ [90]Contents ] [ [91]Next ] [ [92]Previous ] - - Here is how to make different kinds of connections using interactive - Kermit commands (as noted above, you can also make connections with - command-line options). Note that you don't have to make connections - with Kermit. It can also be used on the far end of a connection as the - remote file transfer and management partner of your local - communications software. - - Making a Telnet Connection - - At the C-Kermit command prompt, simply type: - - telnet foo.bar.com ; Substitute desired host name or address. - telnet xyzcorp.com 3000 ; You can also include a port number. - - If the connection is successful, Kermit automically enters - Connect state. When you logout from the remote host, Kermit - automatically returns to its prompt. More info: HELP TELNET, - HELP SET TELNET, HELP SET TELOPT. Also see the [93]IKSD section - below. - - Making an Rlogin connection - - This is just like Telnet, except you have to be root to do it - because Rlogin uses a privileged TCP port: - - rlogin foo.bar.com ; Substitute desired host name or address. - - More info: HELP RLOGIN. - - Making an SSH Connection - - Unlike Telnet and Rlogin, SSH connections are not built-in, but - handled by running your external SSH client through a - pseudoterminal. Using C-Kermit to control the SSH client gives - you all of Kermit's features (file transfer, character-set - conversion, scripting, etc) over SSH. - - ssh foo.bar.com ; Substitute desired host name or address. - - More info: HELP SSH, HELP SET SSH. - - Dialing with a Modem - - If it's an external modem, make sure it is connected to a - usable serial port on your computer with a regular - (straight-through) modem cable, and to the telephone jack with - a telephone cable, and that it's turned on. Then use these - commands: - - set modem type usrobotics ; Or other supported type - set line /dev/ttyS0 ; Specify device name - set speed 57600 ; Or other desired speed - set flow rts/cts ; Most modern modems support this - set dial method tone ; (or pulse) - dial 7654321 ; Dial the desired number - - Type "set modem type ?" for a list of supported modem types. If - you omit the SET MODEM TYPE command, the default type is - "generic-high-speed", which should work for most modern - AT-command-set modems. If the line is busy, Kermit redials - automatically. If the call does not succeed, use "set dial - display on" and try it again to watch what happens. If the call - succeeds, Kermit enters Connect state automatically and returns - to its prompt automatically when you log out from the remote - computer or the connection is otherwise lost. - - You can also dial from a modem that is accessible by Telnet, - e.g. to a reverse terminal server. In this case the command - sequence is: - - set host ts.xxx.com 2000 ; Terminal-server and port - set modem type usrobotics ; Or other supported type - set dial method tone ; (or pulse) - dial 7654321 ; Dial the desired number - - If the terminal server supports the Telnet Com Port Option, - [94]RFC 2217, you can also give serial-port related commands - such as SET SPEED, SET PARITY, and so on, and Kermit relays - them to the terminal server using the protocol specified in the - RFC. - - More info: HELP SET MODEM, HELP SET LINE, HELP SET SPEED, HELP - SET FLOW, HELP DIAL, HELP SET DIAL, HELP SET MODEM, HELP SET - CARRIER-WATCH, SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL. - - Direct Serial Port - - Connect the two computers, A and B, with a null modem cable (or - two modem cables interconnected with a null-modem adapter or - modem eliminator). From Computer A: - - set modem type none ; There is no modem - set line /dev/ttyS0 ; Specify device name - set carrier-watch off ; If DTR and CD are not cross-connected - set speed 57600 ; Or other desired speed - set flow rts/cts ; If RTS and CTS are cross-connected - set flow xon/xoff ; If you can't use RTS/CTS - set parity even ; (or "mark" or "space", if necessary) - set stop-bits 2 ; (rarely necessary) - connect ; Enter Connect (terminal) state - - This assumes Computer B is set up to let you log in. If it - isn't, you can run a copy of Kermit on Computer B and follow - approximately the same directions. More info: As above plus - HELP CONNECT. - - With modems or direct serial connections, you might also have to "set - parity even" (or "mark" or "space") if it's a 7-bit connection. - - Of the connection types listed above, only one can be open at a time. - However, any one of these can be open concurrently with an [95]FTP or - HTTP session. Each connection type can be customized to any desired - degree, scripted, logged, you name it. See the manual. - - NOTE: On selected platforms, C-Kermit also can make X.25 connections. - See the manual for details. - - [ [96]Kermit Home ] [ [97]C-Kermit Home ] [ [98]C-Kermit FAQ ] - ________________________________________________________________________ - - TRANSFERRING FILES WITH KERMIT [ [99]Top ] [ [100]Contents ] [ [101]Next ] [ - [102]Previous ] - - * [103]Downloading Files - * [104]Uploading Files - * [105]Kermit Transfers the Old-Fashioned Way - * [106]If File Transfer Fails - * [107]Advanced Kermit File Transfer Features - * [108]Non-Kermit File Transfer - - There is a [109]widespread and persistent belief that Kermit is a slow - protocol. This is because, until recently, it used conservative tuning - by default to make sure file transfers succeeded, rather than failing - because they overloaded the connection. Some extra commands (or - command-line options, like -Q) were needed to make it go fast, but - nobody bothered to find out about them. Also, it takes two to tango: - most non-Kermit-Project Kermit protocol implementations really ARE - slow. The best file-transfer partners for C-Kermit are: another copy - of [110]C-Kermit (7.0 or later) and [111]Kermit 95. These combinations - work well and they work fast by default. MS-DOS Kermit is good too, - but you have to tell it to go fast (by giving it the FAST command). - - Furthermore, all three of these Kermit programs support "autodownload" - and "autoupload", meaning that when they are in Connect state and a - Kermit packet comes in from the remote, they automatically switch into - file transfer mode. - - And plus, C-Kermit and K95 also switch automatically between text and - binary mode for each file, so there is no need to "set file type - binary" or "set file type text", or to worry about files being - corrupted because they were transferred in the wrong mode. - - What all of these words add up to is that now, when you use up-to-date - Kermit software from the Kermit Project, file transfer is not only - fast, it's ridiculously easy. You barely have to give any commands at - all. - - Downloading Files - - Let's say you have [112]Kermit 95, [113]C-Kermit, or - [114]MS-DOS Kermit on your desktop computer, with a connection - to a Unix computer that has C-Kermit installed as "kermit". To - download a file (send it from Unix to your desktop computer), - just type the following command at your Unix shell prompt: - - kermit -s oofa.txt - - (where oofa.txt is the filename). If you want to send more than - one file, you can put as many filenames as you want on the - command line, and they can be any combination of text and - binary: - - kermit -s oofa.txt oofa.zip oofa.html oofa.tar.gz - - and/or you can use wildcards to send groups of files: - - kermit -s oofa.* - - If you want to send a file under an assumed name, use: - - kermit -s friday.txt -a today.txt - - This sends the file friday.txt but tells the receiving Kermit - that its name is today.txt. In all cases, as noted, when the - file transfer is finished, your desktop Kermit returns - automatically to Connect state. No worries about escaping back, - re-connecting, text/binary mode switching. Almost too easy, - right? - - Uploading Files - - To upload files (send them from your desktop computer to the - remote Unix computer) do the same thing, but use the -g (GET) - option instead of -s: - - kermit -g oofa.txt - - This causes your local Kermit to enter server mode; then the - remote Kermit program requests the named file and the local - Kermit sends it and returns automatically to Connect state when - done. - - If you want to upload multiple files, you have have use shell - quoting rules, since these aren't local files: - - kermit -g "oofa.txt oofa.zip oofa.html oofa.tar.gz" - kermit -g "oofa.*" - - If you want to upload a file but store it under a different - name, use: - - kermit -g friday.txt -a today.txt - - Kermit Transfers the Old-Fashioned Way - - If your desktop communications software does not support - autoupload or autodownload, or it does not include Kermit - server mode, the procedure requires more steps. - - To download a file, type: - - kermit -s filename - - on the host as before, but if nothing happens automatically in - response to this command, you have to switch your desktop - communications software into Kermit Receive state. This might - be done by escaping back using keyboard characters or hot keys - (Alt-x is typical) and/or with a command (like RECEIVE) or a - menu. When the file transfer is complete, you have to go back - to Connect state, Terminal emulation, or whatever terminology - applies to your desktop communications software. - - To upload a file, type: - - kermit -r - - on the host (rather than "kermit -g"). This tells C-Kermit to - wait passively for a file to start arriving. Then regain the - attention of your desktop software (Alt-x or whatever) and - instruct it to send the desired file(s) with Kermit protocol. - When the transfer is finished, return to the Connect or - Terminal screen. - - If File Transfer Fails - - Although every aspect of Kermit's operation can be finely - tuned, there are also three short and simple "omnibus tuning" - commands you can use for troubleshooting: - - FAST - Use fast file-transfer settings. This has been the - default since C-Kermit 7.0 now that most modern computers - and connections support it. If transfers fail with fast - settings, try . . . - - CAUTIOUS - Use cautious but not paranoid settings. File transfers, - if they work, will go at medium speed. If not, try . . . - - ROBUST - Use the most robust, resilient, conservative, safe, and - reliable settings. File transfers will almost certainly - work, but they will be quite slow (of course this is a - classic tradeoff; ROBUST was C-Kermit's default tuning in - versions 6.0 and earlier, which made everybody think - Kermit protocol was slow). If ROBUST doesn't do the - trick, try again with SET PARITY SPACE first in case it's - not an 8-bit connection. - - Obviously the success and performance of a file transfer also - depends on C-Kermit's file transfer partner. Up-to-date, real - [115]Kermit Project partners are recommended because they - contain the best Kermit protocol implementations and because - [116]we can support them in case of trouble. - - If you still have trouble, consult Chapter 10 of [117]Using - C-Kermit, or send email to [118]kermit-support@columbia.edu. - - Advanced Kermit File-Transfer Features - - Obviously there is a lot more to Kermit file transfer, - including all sorts of interactive commands, preferences, - options, logging, debugging, troubleshooting, and anything else - you can imagine but that's what the [119]manual and updates are - for. Here are a few topics you can explore if you're interested - by Typing HELP for the listed commands: - - Logging transfers: - LOG TRANSACTIONS (HELP LOG) - - Automatic per-file text/binary mode switching: - SET TRANSFER MODE { AUTOMATIC, MANUAL } (HELP SET - TRANSFER). - - Cross-platform recursive directory tree transfer: - SEND /RECURSIVE, GET /RECURSIVE (HELP SEND, HELP GET). - - File collision options: - SET FILE COLLISION { OVERWRITE, BACKUP, DISCARD, ... } - (HELP SET FILE). - - Update mode (only transfer files that changed since last time): - SET FILE COLLISION UPDATE (HELP SET FILE). - - Filename selection patterns: - (HELP WILDCARD). - - Flexible file selection: - SEND (or GET) /BEFORE /AFTER /LARGER /SMALLER /TYPE - /EXCEPT, ... - - Character-set conversion: - SET { FILE, TRANSFER } CHARACTER-SET, ASSOCIATE, ... - - File/Pathname control: - SET { SEND, RECEIVE } PATHNAMES, SET FILE NAMES. - - Atomic file movement: - SEND (or GET) /DELETE /RENAME /MOVE-TO - - Transferring to/from standard i/o of other commands: - SEND (or GET) /COMMAND - - Recovery of interrupted transfer from point of failure: - RESEND, REGET (HELP RESEND, HELP REGET). - - Non-Kermit File Transfer - - You can also use C-Kermit to transfer files with FTP or HTTP - Internet protocols; [120]see below. - - On a regular serial or Telnet connection where the other - computer doesn't support Kermit protocol at all, you have - several options. For example, if your desktop communications - software supports Zmodem, use "rz" and "sz" on the host rather - than Kermit. But if Kermit is your desktop software, and you - are using it to make calls or network connections to other - computers that don't support Kermit protocol (or that don't - have a good implementation of it), then if your computer also - has external X, Y, or Zmodem programs that are redirectable, - Kermit can use them as external protocols. HELP SET PROTOCOL - for details. - - You can also capture "raw" data streams from the other computer - with LOG SESSION (HELP LOG and HELP SET SESSION-LOG for - details), and you can upload files without any protocol at all - with TRANSMIT (HELP TRANSMIT, HELP SET TRANSMIT). - - [ [121]Kermit Home ] [ [122]C-Kermit Home ] [ [123]C-Kermit FAQ ] - ________________________________________________________________________ - - KERMIT CLIENT/SERVER CONNECTIONS [ [124]Top ] [ [125]Contents ] [ [126]Next ] - [ [127]Previous ] - - On any kind of connection you can make with Kermit -- serial, TCP/IP, - X.25, etc -- you can set up a convenient client/server relationship - between your Kermit client (the one that made the connection) and the - Kermit program on the far end of the connection (the remote Kermit) by - putting the remote Kermit in server mode. This is normally done by - giving it a SERVER command, or by starting it with the -x command-line - option. In some cases ([128]Internet Kermit Service, SSH connections - to a Kermit subsystem, or specially configured hosts), there is - already a Kermit server waiting on the far end. Here is a quick - synopsis of the commands you can give to the client for interacting - with the server: - - SEND [ switches ] filename - Sends the named file to the server. The filename can include - wildcards. Lots of switches are available for file selection, - etc. Type HELP SEND at the client prompt for details. - - GET [ switches ] filename - Asks the server to send the named file. The filename can - include wildcards. Type HELP GET at the client prompt for - details. - - BYE - Terminates the server and closes your connection to it. - - FINISH - Terminates the server. If you started the server yourself, this - leaves the remote host at its shell prompt. If it was a - dedicated server (such as IKSD or an SSH subsystem), FINISH is - equivalent to BYE. - - SET LOCUS { LOCAL, REMOTE, AUTO } - (C-Kermit 8.0.201 and later, K95 1.1.21 and later) This tells - the client whether file-management commands like CD, PWD, - DIRECTORY, DELETE, MKDIR, etc, should be executed locally or by - the server. In this type of connection, the default is LOCAL. - Use SET LOCUS REMOTE if you want Kermit to behave like an FTP - client, in which case these commands are executed remotely, and - their local versions must have an L prefix: LCD, LPWD, - LDIRECTORY, etc. When LOCUS is LOCAL, then the remote versions - must have an R prefix: RCD, RPWD, RDIRECTORY, etc. HELP SET - LOCUS for details. SHOW COMMAND to see current locus. - - The following commands are affected by SET LOCUS: - - CD, LCD, RCD - Change (working, current) directory. HELP CD for details. - - CDUP, LCDUP, RCDUP - CD one level up. - - DIRECTORY, LDIRECTORY, RDIRECTORY - Produce a directory listing. Many options are available for local - listings. HELP DIRECTORY for details. - - DELETE, LDELETE, RDELETE - Deletes files or directories. Many options available, HELP DELETE. - - RENAME, LRENAME, RRENAME - Renames files or directories. Many options available, HELP RENAME. - - MKDIR, LMKDIR, RMKDIR - Creates a directory. HELP MKDIR. - - RMDIR, LRMDIR, RRMDIR - Removes a directory. HELP RMDIR. There are dozens -- maybe hundreds -- - of other commands, described in the built-in help, on the website, - and/or in the published or online manuals. But even if you don't have - access to documentation, you can "set locus remote" and then use - pretty much the same commands you would use with any FTP client. - - [ [129]Kermit Home ] [ [130]C-Kermit Home ] [ [131]C-Kermit FAQ ] - ________________________________________________________________________ - - KERMIT'S BUILT-IN FTP AND HTTP CLIENTS [ [132]Top ] [ [133]Contents ] [ - [134]Next ] [ [135]Previous ] - - Kermit's FTP client is like the regular Unix FTP client that you're - used to, but with some differences: - - * It has lots more commands and features. - * You can have an FTP session and a regular Kermit serial or Telnet - session open at the same time. - * FTP sessions can be fully automated. - - By default Kermit's FTP client tries its best to present the same user - interface as a regular FTP client: PUT, GET, DIR, CD, BYE, etc, should - work the same, even though some of these commands have different - meaning in Kermit-to-Kermit connections; for example, CD, DIR, RENAME, - etc, in Kermit act locally, whereas in FTP they are commands for the - server. This might cause some confusion, but as in all things Kermit, - you have total control: - - * The [136]SET LOCUS command lets you specify where file management - commands should be executed -- locally or remotely -- for any kind - of connection. - * Any FTP command can be prefixed with the word "FTP" to remove any - ambiguity. - - Pending publication of the next edition of the manual, the Kermit FTP - client is thoroughly documented at the Kermit Project website: - - [137]http://www.columbia.edu/kermit/ftpclient.html - - You also can use HELP FTP and HELP SET FTP to get descriptions of - Kermit's FTP-related commands. - - The HTTP client is similar to the FTP one, except you prefix each - command with HTTP instead of FTP: HTTP OPEN, HTTP GET, HTTP PUT, HTTP - CLOSE, etc. Type HELP HTTP for details, or visit the to view the - [138]manual supplements. HTTP connections can be open at the same time - as regular serial or Telnet connections and FTP connections. So Kermit - can manage up to three types connections simultaneously. - - [ [139]Kermit Home ] [ [140]C-Kermit Home ] [ [141]C-Kermit FAQ ] [ - [142]FTP Client ] [ [143]HTTP Client ] - ________________________________________________________________________ - - INTERNET KERMIT SERVICE [ [144]Top ] [ [145]Contents ] [ [146]Next ] [ - [147]Previous ] - - C-Kermit can be configured and run as an Internet service (called - IKSD), similar to an FTP server (FTPD) except you can (but need not) - interact with it directly, plus it does a lot more than an FTP server - can do. The TCP port for IKSD is 1649. It uses Telnet protocol. - C-Kermit can be an Internet Kermit Server, or it can be a client of an - IKSD. You can make connections from C-Kermit to an IKSD with any of - the following commands: - - telnet foo.bar.edu 1649 - telnet foo.bar.edu kermit ; if "kermit" is listed in /etc/services - iksd foo.bar.edu - - The IKSD command is equivalent to a TELNET command specifying port - 1649. For more information about making and using connections to an - IKSD, see: - - [148]http://www.columbia.edu/kermit/cuiksd.html - - You can run an Internet Kermit Service on your own computer too (if - you are the system administrator). For instructions, see: - - [149]http://www.columbia.edu/kermit/iksd.html - - [ [150]Kermit Home ] [ [151]C-Kermit Home ] [ [152]C-Kermit FAQ ] - ________________________________________________________________________ - - SECURITY [ [153]Top ] [ [154]Contents ] [ [155]Next ] [ [156]Previous ] - - All of C-Kermit's built-in TCP/IP networking methods (Telnet, Rlogin, - IKSD, FTP, and HTTP) can be secured by one or more of the following - IETF-approved methods: - - * MIT Kerberos IV - * MIT Kerberos V - * SSL/TLS - * Stanford SRP - - For complete instructions see: - - [157]http://www.columbia.edu/kermit/security.html - - And as noted previously, you can also make SSH connections with - C-Kermit if you already have an SSH client installed. - - [ [158]Kermit Home ] [ [159]C-Kermit Home ] [ [160]C-Kermit FAQ ] - ________________________________________________________________________ - - ALTERNATIVE COMMAND-LINE PERSONALITIES [ [161]Top ] [ [162]Contents ] [ - [163]Next ] [ [164]Previous ] - - When invoked as "kermit" or any other name besides any of the special - ones, C-Kermit has the command-line options described above in the - [165]OPTIONS section. However, if you invoke C-Kermit using any of the - following names: - - telnet Telnet client - ftp FTP client - http HTTP client - https Secure HTTP client - - Kermit's command-line personality changes to match. This can be done - (among other ways) with symbolic links (symlinks). For example, if you - want C-Kermit to be your regular Telnet client, or the Telnet helper - of your Web browser, you can create a link like the following in a - directory that lies in your PATH ahead of the regular telnet program: - - ln -s /usr/local/bin/kermit telnet - - Now when you give a "telnet" command, you are invoking Kermit instead, - but with its Telnet command-line personality so, for example: - - telnet xyzcorp.com - - Makes a Telnet connection to xyzcorp.com, and Kermit exits - automatically when the connection is closed (just like the regular - Telnet client). Type "telnet -h" to get a list of Kermit's - Telnet-personality command-line options, which are intended to be as - compatible as possible with the regular Telnet client. - - Similarly for FTP: - - ln -s /usr/local/bin/kermit ftp - - And now type "ftp -h" to see its command-line options, and use command - lines just like you would give your regular FTP client: - - ftp -n xyzcorp.com - - but with additional options allowing an entire session to be specified - on the command line, as explained in the C-Kermit [166]FTP client - documentation. - - And similarly for HTTP: - - ln -s /usr/local/bin/kermit http - ./http -h - ./http www.columbia.edu -g kermit/index.html - - Finally, if Kermit's first command-line option is a Telnet, FTP, IKSD, - or HTTP URL, Kermit automatically makes the appropriate kind of - connection and, if indicated by the URL, takes the desired action: - - kermit telnet:xyzcorp.com ; Opens a Telnet session - kermit telnet://olga@xyzcorp.com ; Ditto for user olga - kermit ftp://olga@xyzcorp.com/public/oofa.zip ; Downloads a file - kermit kermit://kermit.columbia.edu/kermit/f/READ.ME ; Ditto for IKSD - kermit iksd://kermit.columbia.edu/kermit/f/READ.ME ; (This works too) - kermit http://www.columbia.edu/kermit/index.html ; Grabs a web page - kermit https://wwws.xyzcorp.com/secret/plan.html ; Grabs a secure web pag -e - - [ [167]Kermit Home ] [ [168]C-Kermit Home ] [ [169]C-Kermit FAQ ] - ________________________________________________________________________ - - LICENSE [ [170]Top ] [ [171]Contents ] [ [172]Next ] [ [173]Previous ] - - C-Kermit has an unusual license, but a fair and sensible one given - that the Kermit Project must support itself out of revenue: it's not a - BSD license, not GPL, not Artistic, not commercial, not shareware, not - freeware. It can be summed up like this: if you want C-Kermit for your - own use, you can download and use it without cost or license (but we'd - appreciate it if you would purchase the manual). But if you want to - sell C-Kermit or bundle it with a product or otherwise distribute it - in a commercial setting EXCEPT WITH AN OPEN-SOURCE OPERATING SYSTEM - DISTRIBUTION such as Linux, FreeBSD, NetBSD, or OpenBSD, you must - license it. To see the complete license, give the LICENSE command at - the prompt, or see the COPYING.TXT file distributed with C-Kermit 7.0 - or later, or download it from - [174]ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT. Send - licensing inquiries to [175]kermit@columbia.edu. - - [ [176]Kermit Home ] [ [177]C-Kermit Home ] [ [178]C-Kermit FAQ ] - ________________________________________________________________________ - - OTHER TOPICS [ [179]Top ] [ [180]Contents ] [ [181]Next ] [ [182]Previous ] - - There's way more to C-Kermit than we've touched on here -- - troubleshooting, customization, character sets, dialing directories, - sending pages, script writing, and on and on, all of which are covered - in the manual and updates and supplements. For the most up-to-date - information on documentation (or updated documentation itself) visit - the Kermit Project website: - - [183]http://www.columbia.edu/kermit/ - - There you will also find [184]Kermit software packages for other - platforms: different Unix varieties, Windows, DOS, VMS, IBM - mainframes, and many others: 20+ years' worth. - - [ [185]Kermit Home ] [ [186]C-Kermit Home ] [ [187]C-Kermit FAQ ] - ________________________________________________________________________ - - DOCUMENTATION AND UPDATES [ [188]Top ] [ [189]Contents ] [ [190]Next ] [ - [191]Previous ] - - The manual for C-Kermit is: - - 1. Frank da Cruz and Christine M. Gianone, [192]Using C-Kermit, - Second Edition, Digital Press / Butterworth-Heinemann, Woburn, MA, - 1997, 622 pages, ISBN 1-55558-164-1. This is a printed book. It - covers C-Kermit 6.0. - 2. The C-Kermit 7.0 Supplement: - [193]http://www.columbia.edu/kermit/ckermit70.html - 3. The C-Kermit 8.0 Supplement: - [194]http://www.columbia.edu/kermit/ckermit80.html - - The C-Kermit home page is here: - - [195]http://www.columbia.edu/kermit/ckermit.html - - Visit this page to learn about new versions, Beta tests, and other - news; to read case studies and tutorials; to download source code, - install packages, and [196]prebuilt binaries for many platforms. Also - visit: - - [197]http://www.columbia.edu/kermit/scriptlib.html - The Kermit script library and tutorial - - [198]http://www.columbia.edu/kermit/newfaq.html - The Kermit FAQ (Frequently Asked Questions about Kermit) - - [199]http://www.columbia.edu/kermit/ckfaq.html - The C-Kermit FAQ (Frequently Asked Questions about C-Kermit) - - [200]http://www.columbia.edu/kermit/security.html - The Kermit security reference. - - [201]http://www.columbia.edu/kermit/telnet.html - C-Kermit Telnet client documentation. - - [202]http://www.columbia.edu/kermit/studies.html - Case studies. - - [203]http://www.columbia.edu/kermit/ckcbwr.html - General C-Kermit Hints and Tips. - - [204]http://www.columbia.edu/kermit/ckubwr.html - Unix C-Kermit Hints and Tips. - - [205]http://www.columbia.edu/kermit/ckvbwr.html - VMS C-Kermit Hints and Tips. - - [206]http://www.columbia.edu/kermit/ckuins.html - Unix C-Kermit Installation Instructions - - [207]http://www.columbia.edu/kermit/ckvins.html - VMS C-Kermit Installation Instructions - - [208]http://www.columbia.edu/kermit/support.html - Technical support. - - [209]http://www.columbia.edu/kermit/k95tutorial.html - Kermit 95 tutorial (this document). - - [210]comp.protocols.kermit.misc - The Kermit newsgroup (unmoderated). - - [ [211]Kermit Home ] [ [212]C-Kermit Home ] [ [213]C-Kermit FAQ ] - ________________________________________________________________________ - - FILES [ [214]Top ] [ [215]Contents ] [ [216]Next ] [ [217]Previous ] - - [218]COPYING.TXT - C-Kermit license. - - [219]~/.kermrc - Initialization file. - - [220]~/.mykermrc - Customization file. - - ~/.kdd - Kermit dialing directory (see manual). - - ~/.knd - Kermit network directory (see manual). - - ~/.ksd - Kermit services directory (see manual). - - [221]ckuins.html - Installation instructions for Unix. - - [222]ckcbwr.html - General C-Kermit bugs, hints, tips. - - [223]ckubwr.html - Unix-specific C-Kermit bugs, hints, tips. - - [224]ckcplm.html - C-Kermit program logic manual. - - [225]ckccfg.html - C-Kermit compile-time configuration options. - - ssh - (in your PATH) SSH connection helper. - - rz, sz, etc. - (in your PATH) external protocols for XYZmodem. - - /var/spool/locks (or whatever) - UUCP lockfile for dialing out (see [226]installation - instructions). - - [ [227]Kermit Home ] [ [228]C-Kermit Home ] [ [229]C-Kermit FAQ ] - ________________________________________________________________________ - - AUTHORS [ [230]Top ] [ [231]Contents ] [ [232]Previous ] - - Frank da Cruz and Jeffrey E Altman - The Kermit Project - Columbia Univerity - 612 West 115th Street - New York NY 10025-7799 - USA - - 1985-present, with contributions from hundreds of others all over the - world. - _________________________________________________________________ - - - C-Kermit 8.0 Unix Manual Page and Tutorial / - [233]kermit@columbia.edu / 24 October 2002 - -References - - 1. http://www.columbia.edu/kermit/ - 2. http://www.columbia.edu/ - 3. http://www.columbia.edu/kermit/ckututor.pdf - 4. ftp://kermit.columbia.edu/kermit/test/text/ckuker.nr - 5. http://www.columbia.edu/kermit/ckututor.html#description - 6. http://www.columbia.edu/kermit/ckututor.html#synopsis - 7. http://www.columbia.edu/kermit/ckututor.html#options - 8. http://www.columbia.edu/kermit/ckututor.html#commands - 9. http://www.columbia.edu/kermit/ckututor.html#initfile - 10. http://www.columbia.edu/kermit/ckututor.html#modes - 11. http://www.columbia.edu/kermit/ckututor.html#connections - 12. http://www.columbia.edu/kermit/ckututor.html#transfer - 13. http://www.columbia.edu/kermit/ckututor.html#server - 14. http://www.columbia.edu/kermit/ckututor.html#ftp - 15. http://www.columbia.edu/kermit/ckututor.html#iksd - 16. http://www.columbia.edu/kermit/ckututor.html#security - 17. http://www.columbia.edu/kermit/ckututor.html#personae - 18. http://www.columbia.edu/kermit/ckututor.html#license - 19. http://www.columbia.edu/kermit/ckututor.html#other - 20. http://www.columbia.edu/kermit/ckututor.html#documentation - 21. http://www.columbia.edu/kermit/ckututor.html#files - 22. http://www.columbia.edu/kermit/ckututor.html#authors - 23. http://www.columbia.edu/kermit/ckututor.html#top - 24. http://www.columbia.edu/kermit/ckututor.html#contents - 25. http://www.columbia.edu/kermit/ckututor.html#synopsis - 26. http://www.columbia.edu/kermit/ckermit.html - 27. http://www.columbia.edu/kermit/ - 28. http://www.columbia.edu/ - 29. ftp://ftp.isi.edu/in-notes/rfc2839.txt - 30. ftp://ftp.isi.edu/in-notes/rfc2840.txt - 31. http://www.columbia.edu/kermit/ckututor.html#documentation - 32. http://www.columbia.edu/kermit/ - 33. http://www.columbia.edu/kermit/ - 34. http://www.columbia.edu/kermit/ckermit.html - 35. http://www.columbia.edu/kermit/ckfaq.html - 36. http://www.columbia.edu/kermit/ckututor.html#top - 37. http://www.columbia.edu/kermit/ckututor.html#contents - 38. http://www.columbia.edu/kermit/ckututor.html#options - 39. http://www.columbia.edu/kermit/ckututor.html#synopsis - 40. http://www.columbia.edu/kermit/ckututor.html#kerbang - 41. http://www.columbia.edu/kermit/ckututor.html#personae - 42. http://www.columbia.edu/kermit/ckututor.html#kerbang - 43. http://www.columbia.edu/kermit/ckututor.html#initfile - 44. http://www.columbia.edu/kermit/ckututor.html#initfile - 45. http://www.columbia.edu/kermit/ckututor.html#personae - 46. http://www.columbia.edu/kermit/ckututor.html#options - 47. http://www.columbia.edu/kermit/ckututor.html#commands - 48. http://www.columbia.edu/kermit/ - 49. http://www.columbia.edu/kermit/ckermit.html - 50. http://www.columbia.edu/kermit/ckfaq.html - 51. http://www.columbia.edu/kermit/ckututor.html#top - 52. http://www.columbia.edu/kermit/ckututor.html#contents - 53. http://www.columbia.edu/kermit/ckututor.html#commands - 54. http://www.columbia.edu/kermit/ckututor.html#description - 55. http://www.columbia.edu/kermit/ckututor.html#commands - 56. http://www.columbia.edu/kermit/ckututor.html#personae - 57. http://www.columbia.edu/kermit/ckututor.html#personae - 58. http://www.columbia.edu/kermit/ckututor.html#iksd - 59. http://www.columbia.edu/kermit/ckututor.html#transfer - 60. http://www.columbia.edu/kermit/ckututor.html#top - 61. http://www.columbia.edu/kermit/ckututor.html#contents - 62. http://www.columbia.edu/kermit/ckututor.html#initfile - 63. http://www.columbia.edu/kermit/ckututor.html#options - 64. http://www.columbia.edu/kermit/ckututor.html#kerbang - 65. http://www.columbia.edu/kermit/ckututor.html#cmdlist - 66. http://www.columbia.edu/kermit/ckututor.html#documentation - 67. http://www.columbia.edu/kermit/ckututor.html#initfile - 68. http://www.columbia.edu/kermit/ckututor.html#documentation - 69. http://www.columbia.edu/kermit/ckscripts.html - 70. http://www.columbia.edu/kermit/ckututor.html#documentation - 71. http://www.columbia.edu/kermit/ - 72. http://www.columbia.edu/kermit/ckermit.html - 73. http://www.columbia.edu/kermit/ckfaq.html - 74. http://www.columbia.edu/kermit/ckututor.html#top - 75. http://www.columbia.edu/kermit/ckututor.html#contents - 76. http://www.columbia.edu/kermit/ckututor.html#modes - 77. http://www.columbia.edu/kermit/ckututor.html#commands - 78. http://www.columbia.edu/kermit/ - 79. http://www.columbia.edu/kermit/ckermit.html - 80. http://www.columbia.edu/kermit/ckfaq.html - 81. http://www.columbia.edu/kermit/ckututor.html#top - 82. http://www.columbia.edu/kermit/ckututor.html#contents - 83. http://www.columbia.edu/kermit/ckututor.html#connections - 84. http://www.columbia.edu/kermit/ckututor.html#initfile - 85. http://www.columbia.edu/kermit/ckfaq.html#term - 86. http://www.columbia.edu/kermit/ - 87. http://www.columbia.edu/kermit/ckermit.html - 88. http://www.columbia.edu/kermit/ckfaq.html - 89. http://www.columbia.edu/kermit/ckututor.html#top - 90. http://www.columbia.edu/kermit/ckututor.html#contents - 91. http://www.columbia.edu/kermit/ckututor.html#transfer - 92. http://www.columbia.edu/kermit/ckututor.html#modes - 93. http://www.columbia.edu/kermit/ckututor.html#iksd - 94. ftp://ftp.isi.edu/in-notes/rfc2217.txt - 95. http://www.columbia.edu/kermit/ckututor.html#ftp - 96. http://www.columbia.edu/kermit/ - 97. http://www.columbia.edu/kermit/ckermit.html - 98. http://www.columbia.edu/kermit/ckfaq.html - 99. http://www.columbia.edu/kermit/ckututor.html#top - 100. http://www.columbia.edu/kermit/ckututor.html#contents - 101. http://www.columbia.edu/kermit/ckututor.html#server - 102. http://www.columbia.edu/kermit/ckututor.html#connections - 103. http://www.columbia.edu/kermit/ckututor.html#download - 104. http://www.columbia.edu/kermit/ckututor.html#upload - 105. http://www.columbia.edu/kermit/ckututor.html#oldfashioned - 106. http://www.columbia.edu/kermit/ckututor.html#trouble - 107. http://www.columbia.edu/kermit/ckututor.html#advanced - 108. http://www.columbia.edu/kermit/ckututor.html#nonkermit - 109. http://www.columbia.edu/kermit/kermit.html#notslow - 110. http://www.columbia.edu/kermit/ckermit.html - 111. http://www.columbia.edu/kermit/k95.html - 112. http://www.columbia.edu/kermit/k95.html - 113. http://www.columbia.edu/kermit/ckermit.html - 114. http://www.columbia.edu/kermit/mskermit.html - 115. http://www.columbia.edu/kermit/ - 116. http://www.columbia.edu/kermit/support.html - 117. http://www.columbia.edu/kermit/ckmanual.html - 118. mailto:kermit-support@columbia.edu - 119. http://www.columbia.edu/kermit/ckututor.html#documentation - 120. http://www.columbia.edu/kermit/ckututor.html#ftp - 121. http://www.columbia.edu/kermit/ - 122. http://www.columbia.edu/kermit/ckermit.html - 123. http://www.columbia.edu/kermit/ckfaq.html - 124. http://www.columbia.edu/kermit/ckututor.html#top - 125. http://www.columbia.edu/kermit/ckututor.html#contents - 126. http://www.columbia.edu/kermit/ckututor.html#ftp - 127. http://www.columbia.edu/kermit/ckututor.html#transfer - 128. http://www.columbia.edu/kermit/ckututor.html#iksd - 129. http://www.columbia.edu/kermit/ - 130. http://www.columbia.edu/kermit/ckermit.html - 131. http://www.columbia.edu/kermit/ckfaq.html - 132. http://www.columbia.edu/kermit/ckututor.html#top - 133. http://www.columbia.edu/kermit/ckututor.html#contents - 134. http://www.columbia.edu/kermit/ckututor.html#iksd - 135. http://www.columbia.edu/kermit/ckututor.html#transfer - 136. http://www.columbia.edu/kermit/ckututor.html#server - 137. http://www.columbia.edu/kermit/ftpclient.html - 138. http://www.columbia.edu/kermit/ckututor.html#documentation - 139. http://www.columbia.edu/kermit/ - 140. http://www.columbia.edu/kermit/ckermit.html - 141. http://www.columbia.edu/kermit/ckfaq.html - 142. http://www.columbia.edu/kermit/ckermit3.html#x3 - 143. http://www.columbia.edu/kermit/ckermit3.html#x2.2 - 144. http://www.columbia.edu/kermit/ckututor.html#top - 145. http://www.columbia.edu/kermit/ckututor.html#contents - 146. http://www.columbia.edu/kermit/ckututor.html#security - 147. http://www.columbia.edu/kermit/ckututor.html#ftp - 148. http://www.columbia.edu/kermit/cuiksd.html - 149. http://www.columbia.edu/kermit/iksd.html - 150. http://www.columbia.edu/kermit/ - 151. http://www.columbia.edu/kermit/ckermit.html - 152. http://www.columbia.edu/kermit/ckfaq.html - 153. http://www.columbia.edu/kermit/ckututor.html#top - 154. http://www.columbia.edu/kermit/ckututor.html#contents - 155. http://www.columbia.edu/kermit/ckututor.html#personae - 156. http://www.columbia.edu/kermit/ckututor.html#iksd - 157. http://www.columbia.edu/kermit/security.html - 158. http://www.columbia.edu/kermit/ - 159. http://www.columbia.edu/kermit/ckermit.html - 160. http://www.columbia.edu/kermit/ckfaq.html - 161. http://www.columbia.edu/kermit/ckututor.html#top - 162. http://www.columbia.edu/kermit/ckututor.html#contents - 163. http://www.columbia.edu/kermit/ckututor.html#license - 164. http://www.columbia.edu/kermit/ckututor.html#iksd - 165. http://www.columbia.edu/kermit/ckututor.html#options - 166. http://www.columbia.edu/kermit/ckermit3.html#x3.1.2 - 167. http://www.columbia.edu/kermit/ - 168. http://www.columbia.edu/kermit/ckermit.html - 169. http://www.columbia.edu/kermit/ckfaq.html - 170. http://www.columbia.edu/kermit/ckututor.html#top - 171. http://www.columbia.edu/kermit/ckututor.html#contents - 172. http://www.columbia.edu/kermit/ckututor.html#other - 173. http://www.columbia.edu/kermit/ckututor.html#personae - 174. ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT - 175. mailto:kermit@columbia.edu - 176. http://www.columbia.edu/kermit/ - 177. http://www.columbia.edu/kermit/ckermit.html - 178. http://www.columbia.edu/kermit/ckfaq.html - 179. http://www.columbia.edu/kermit/ckututor.html#top - 180. http://www.columbia.edu/kermit/ckututor.html#contents - 181. http://www.columbia.edu/kermit/ckututor.html#documentation - 182. http://www.columbia.edu/kermit/ckututor.html#license - 183. http://www.columbia.edu/kermit/ - 184. http://www.columbia.edu/kermit/howtoget.html - 185. http://www.columbia.edu/kermit/ - 186. http://www.columbia.edu/kermit/ckermit.html - 187. http://www.columbia.edu/kermit/ckfaq.html - 188. http://www.columbia.edu/kermit/ckututor.html#top - 189. http://www.columbia.edu/kermit/ckututor.html#contents - 190. http://www.columbia.edu/kermit/ckututor.html#files - 191. http://www.columbia.edu/kermit/ckututor.html#other - 192. http://www.columbia.edu/kermit/ckmanual.html - 193. http://www.columbia.edu/kermit/ckermit70.html - 194. http://www.columbia.edu/kermit/ckermit80.html - 195. http://www.columbia.edu/kermit/ckermit.html - 196. http://www.columbia.edu/kermit/ck80binaries.html - 197. http://www.columbia.edu/kermit/scriptlib.html - 198. http://www.columbia.edu/kermit/newfaq.html - 199. http://www.columbia.edu/kermit/ckfaq.html - 200. http://www.columbia.edu/kermit/security.html - 201. http://www.columbia.edu/kermit/telnet.html - 202. http://www.columbia.edu/kermit/studies.html - 203. http://www.columbia.edu/kermit/ckcbwr.html - 204. http://www.columbia.edu/kermit/ckubwr.html - 205. http://www.columbia.edu/kermit/ckvbwr.html - 206. http://www.columbia.edu/kermit/ckuins.html - 207. http://www.columbia.edu/kermit/ckvins.html - 208. http://www.columbia.edu/kermit/support.html - 209. http://www.columbia.edu/kermit/k95tutorial.html - 210. news:comp.protocols.kermit.misc - 211. http://www.columbia.edu/kermit/ - 212. http://www.columbia.edu/kermit/ckermit.html - 213. http://www.columbia.edu/kermit/ckfaq.html - 214. http://www.columbia.edu/kermit/ckututor.html#top - 215. http://www.columbia.edu/kermit/ckututor.html#contents - 216. http://www.columbia.edu/kermit/ckututor.html#authors - 217. http://www.columbia.edu/kermit/ckututor.html#documentation - 218. ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT - 219. ftp://kermit.columbia.edu/kermit/c-kermit/ckermit.ini - 220. ftp://kermit.columbia.edu/kermit/c-kermit/ckermod.ini - 221. http://www.columbia.edu/kermit/ckuins.html - 222. http://www.columbia.edu/kermit/ckcbwr.html - 223. http://www.columbia.edu/kermit/ckubwr.html - 224. http://www.columbia.edu/kermit/ckcplm.html - 225. http://www.columbia.edu/kermit/ckccfg.html - 226. http://www.columbia.edu/kermit/ckuins.html - 227. http://www.columbia.edu/kermit/ - 228. http://www.columbia.edu/kermit/ckermit.html - 229. http://www.columbia.edu/kermit/ckfaq.html - 230. http://www.columbia.edu/kermit/ckututor.html#top - 231. http://www.columbia.edu/kermit/ckututor.html#contents - 232. http://www.columbia.edu/kermit/ckututor.html#files - 233. mailto:kermit@columbia.edu diff --git a/.pc/060_speeling.patch/ckuus2.c b/.pc/060_speeling.patch/ckuus2.c deleted file mode 100644 index 1290763..0000000 --- a/.pc/060_speeling.patch/ckuus2.c +++ /dev/null @@ -1,13838 +0,0 @@ -#ifdef SSHTEST -#define SSHBUILTIN -#endif /* SSHTEST */ - -/* C K U U S 2 -- User interface strings & help text module for C-Kermit */ - -/* - Authors: - Frank da Cruz , - 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 module contains HELP command and other long text strings. - - IMPORTANT: Character string constants longer than about 250 are not portable. - Longer strings should be broken up into arrays of strings and accessed with - hmsga() rather than hmsg(). -*/ -#include "ckcsym.h" -#include "ckcdeb.h" -#include "ckcnet.h" -#include "ckcasc.h" -#include "ckcker.h" -#include "ckuusr.h" -#include "ckcxla.h" -#ifdef OS2 -#ifdef NT -#include -#else /* not NT */ -#define INCL_KBD -#ifdef OS2MOUSE -#define INCL_MOU -#endif /* OS2MOUSE */ -#define INCL_DOSMISC -#define INCL_DOSDEVICES -#include /* This pulls in a whole load of stuff */ -#undef COMMENT -#endif /* NT */ -#include "ckocon.h" -#include "ckokvb.h" -#include "ckokey.h" -#endif /* OS2 */ - -extern xx_strp xxstring; -extern char * ccntab[]; -/* - hlptok contains the string for which the user requested help. This is - useful for distinguishing synonyms, in case different help text is needed - depending on which synonym was given. -*/ -extern char * hlptok; - -#ifndef NOIKSD - extern int inserver; -#endif /* IKSD */ - -#ifndef NOICP -extern int cmflgs; - -#ifdef DCMDBUF -extern char *cmdbuf, *atmbuf; -#else -extern char cmdbuf[], atmbuf[]; -#endif /* DCMDBUF */ -#endif /* NOICP */ - -extern char *xarg0; -extern int nrmt, nprm, dfloc, local, parity, escape; -extern int turn, flow; -extern int binary, quiet, keep; -extern int success, xaskmore; -#ifdef OS2 -extern int tt_rows[], tt_cols[]; -#else /* OS2 */ -extern int tt_rows, tt_cols; -#endif /* OS2 */ -extern int cmd_rows, cmd_cols; - -extern long speed; -extern char *dftty, *versio, *ckxsys; -#ifndef NOHELP -extern char *helpfile; -#endif /* NOHELP */ -extern struct keytab prmtab[]; -#ifndef NOXFER -extern struct keytab remcmd[]; -#endif /* NOXFER */ - -#ifndef NOICP - -/* Interactive help strings */ - -/* Top-level HELP text. IMPORTANT: Also see tophlpi[] for IKSD. */ - -static char *tophlp[] = { -"Trustees of Columbia University in the City of New York.\n", - -#ifndef NOHELP -" Type EXIT to exit.", -#ifdef OS2 -" Type INTRO for a brief introduction to the Kermit Command screen.", -" Type LICENSE to see the Kermit 95 license.", -#else -" Type INTRO for a brief introduction to C-Kermit.", -" Type LICENSE to see the C-Kermit license.", -#endif /* OS2 */ -" Type HELP followed by a command name for help about a specific command.", -#ifndef NOPUSH -#ifdef UNIX -" Type MANUAL to access the C-Kermit manual page.", -#else -#ifdef VMS -" Type MANUAL to access the C-Kermit help topic.", -#else -#ifdef OS2 -" Type MANUAL to access the K95 manual.", -#else -" Type MANUAL to access the C-Kermit manual.", -#endif /* OS2 */ -#endif /* VMS */ -#endif /* UNIX */ -#endif /* NOPUSH */ -" Type NEWS for news about new features.", -" Type SUPPORT to learn how to get technical support.", -" Press ? (question mark) at the prompt, or anywhere within a command,", -" for a menu (context-sensitive help, menu on demand).", -#else -"Press ? for a list of commands; see documentation for detailed descriptions.", -#endif /* NOHELP */ - -#ifndef NOCMDL -#ifndef NOHELP -" ", -" Type HELP OPTIONS for help with command-line options.", -#endif /* NOHELP */ -#endif /* NOCMDL */ -" ", -#ifndef OS2 -#ifdef MAC -"Documentation for Command Window: \"Using C-Kermit\" by Frank da Cruz and", -"Christine M. Gianone, Digital Press, 1997, ISBN: 1-55558-164-1. To order,", -"call +1 212 854-3703 or +1 800 366-2665.", -#else -"DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,", -"2nd Edition, Digital Press / Butterworth-Heinemann 1997, ISBN 1-55558-164-1,", -"plus supplements at http://www.columbia.edu/kermit/ckermit.html.", -#endif /* MAC */ -#endif /* OS2 */ -#ifdef MAC -" ", -"Also see the Mac Kermit Doc and Bwr files on the Mac Kermit diskette.\n", -#else -#ifdef HPUX10 -" ", -"See the files in /usr/share/lib/kermit/ for additional information.", -#endif /* HPUX10 */ -#endif /* MAC */ -"" -}; - -#ifndef NOIKSD -static char *tophlpi[] = { /* Top-level help for IKSD */ - -"Trustees of Columbia University in the City of New York.\n", - -#ifndef NOHELP -" Type INTRO for a brief introduction to Kermit commands.", -" Type VERSION for version and copyright information.", -" Type HELP followed by a command name for help about a specific command.", -" Type SUPPORT to learn how to get technical support.", -" Type LOGOUT (or EXIT) to log out.", -" Press ? (question mark) at the prompt, or anywhere within a command,", -" for a menu (context-sensitive help, menu on demand).", -#else -"Press ? for a list of commands; see documentation for detailed descriptions.", -#endif /* NOHELP */ -" ", -"DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,", -"2nd Edition, Digital Press / Butterworth-Heinemann 1997, ISBN 1-55558-164-1.", -"To order: +1 212 854-3703 or +1 800 366-2665. More info at the Kermit", - -"Project website, http://www.columbia.edu/kermit/.", -"" -}; -#endif /* NOIKSD */ - -#ifndef NOHELP -char *newstxt[] = { -#ifdef OS2 -"Welcome to Kermit 95 2.1.3. Major new features include:", -#else -"Welcome to C-Kermit 8.0.206. Major new features include:", -#endif /* OS2 */ -#ifdef NT -#ifdef KUI -" . Runs in GUI window", -#else -" . GUI version available", -#endif /* KUI */ -#endif /* NT */ -#ifdef SSHBUILTIN -" . New built-in SSH v1 and v2 clients", -#endif /* SSHBUILTIN */ -#ifdef NEWFTP -" . A new built-in FTP client", -#endif /* NEWFTP */ -#ifndef NOHTTP -" . A new HTTP 1.1 client", -#endif /* NOHTTP */ -#ifdef TN_COMPORT -" . Telnet Com Port Option for dialing from Telnet modem servers", -#endif /* TN_COMPORT */ -" . File scanning for automatic text/binary determination", -#ifdef CKLEARN -#ifndef OS2 -" . Learned scripts", -#endif /* OS2 */ -#endif /* CKLEARN */ -#ifndef NOSPL -#ifndef NOSEXP -" . LISP-like S-Expressions and natural floating-point arithmetic", -#endif /* NOSEXP */ -" . Lots of script programming improvements", -#endif /* NOSPL */ -" . Performance improvements and bug fixes", -" ", -"Documentation:", -" 1. \"Using C-Kermit\", second edition (1997), current with C-Kermit 6.0.", -" 2. http://www.columbia.edu/kermit/ckermit70.html", -" which documents the new features of C-Kermit 7.0.", -" 3. http://www.columbia.edu/kermit/ckermit80.html", -" which documents the new features of C-Kermit 8.0.", -" ", -"If the release date shown by the VERSION command is long past, be sure to", -"check with the Kermit Project to see if there have been updates.", -"" -}; -#endif /* NOHELP */ - -#ifndef NOHELP -char *introtxt[] = { -#ifdef OS2 -"Welcome to K-95, Kermit communications software for:", -#else -#ifdef UNIX -#ifdef HPUX -"Welcome to HP-UX C-Kermit communications software for:", -#else -"Welcome to UNIX C-Kermit communications software for:", -#endif /* HPUX */ -#else -#ifdef VMS -"Welcome to VMS C-Kermit communications software for:", -#else -#ifdef VOS -"Welcome to VOS C-Kermit communications software for:", -#else -#ifdef MAC -"Welcome to Mac Kermit communications software for:", -#else -"Welcome to C-Kermit communications software for:", -#endif /* MAC */ -#endif /* VOS */ -#endif /* VMS */ -#endif /* UNIX */ -#endif /* OS2 */ -#ifndef NOXFER -" . Error-free and efficient file transfer", -#endif /* NOXFER */ -#ifndef NOLOCAL -#ifdef OS2 -" . VT320/220/102/100/52, ANSI, Wyse, Linux, Televideo, and other emulations", -#else -#ifdef MAC -" . VT220 terminal emulation", -#else -" . Terminal connection", -#endif /* MAC */ -#endif /* OS2 */ -#endif /* NOLOCAL */ -#ifndef NOSPL -" . Script programming", -#endif /* NOSPL */ -#ifndef NOICS -" . International character set conversion", -#endif /* NOICS */ -#ifndef NODIAL -#ifndef NOSPL -" . Numeric and alphanumeric paging", -#endif /* NOSPL */ -#endif /* NODIAL */ - -#ifndef NOLOCAL -" ", -"Supporting:", -" . Serial connections, direct or dialed.", -#ifndef NODIAL -" . Automatic modem dialing", -#endif /* NODIAL */ -#ifdef TCPSOCKET -" . TCP/IP network connections:", -#ifdef TNCODE -" - Telnet sessions", -#endif /* TNCODE */ -#ifdef SSHBUILTIN -" - SSH v1 and v2 connections", -#else -#ifdef ANYSSH -" - SSH connections via external agent", -#endif /* ANYSSH */ -#endif /* SSHBUILTIN */ -#ifdef RLOGCODE -" - Rlogin sessions", -#endif /* RLOGCODE */ -#ifdef NEWFTP -" - FTP sessions", -#endif /* NEWFTP */ -#ifdef CKHTTP -" - HTTP 1.1 sessions", -#endif /* CKHTTP */ -#ifdef IKSD -" - Internet Kermit Service", -#endif /* IKSD */ -#endif /* TCPSOCKET */ -#ifdef ANYX25 -" . X.25 network connections", -#endif /* ANYX25 */ -#ifdef OS2 -#ifdef DECNET -" . DECnet/PATHWORKS LAT Ethernet connections", -#endif /* DECNET */ -#ifdef SUPERLAT -" . Meridian Technologies' SuperLAT connections", -#endif /* SUPERLAT */ -#ifdef NPIPE -" . Named-pipe connections", -#endif /* NPIPE */ -#ifdef CK_NETBIOS -" . NETBIOS connections", -#endif /* CK_NETBIOS */ -#endif /* OS2 */ -#endif /* NOLOCAL */ - -" ", -"While typing commands, you may use the following special characters:", -" . DEL, RUBOUT, BACKSPACE, CTRL-H: Delete the most recent character typed.", -" . CTRL-W: Delete the most recent word typed.", -" . CTRL-U: Delete the current line.", -" . CTRL-R: Redisplay the current line.", - -#ifdef CK_RECALL -#ifdef OS2 -" . Uparrow: Command recall - go backwards in command recall buffer.", -" . Downarrow: Command recall - go forward in command recall buffer.", -#ifndef NOIKSD -" (Note: Arrow keys can be used only on the PC's physical keyboard.)", -#endif /* NOIKSD */ -#endif /* OS2 */ -" . CTRL-P: Command recall - go backwards in command recall buffer.", -" . CTRL-B: Command recall - same as Ctrl-P.", -" . CTRL-N: Command recall - go forward in command recall buffer.", -#endif /* CK_RECALL */ - -" . ? (question mark) Display a menu for the current command field." -, -" . ESC (or TAB) Attempt to complete the current field.", -" . \\ (backslash) include the following character literally", -#ifndef NOSPL -" or introduce a backslash code, variable, or function.", -#else -" or introduce a numeric backslash code.", -#endif /* NOSPL */ -" ", - -"IMPORTANT: Since backslash (\\) is Kermit's command-line escape character,", -"you must enter DOS, Windows, or OS/2 pathnames using either forward slash (/)" -, -"or double backslash (\\\\) as the directory separator in most contexts.", -"Examples: C:/TMP/README.TXT, C:\\\\TMP\\\\README.TXT.", -" ", - -"Command words other than filenames can be abbreviated in most contexts.", -" ", - -"Basic commands:", -" EXIT Exit from Kermit", -" HELP Request general help", -" HELP command Request help about the given command", -" TAKE Execute commands from a file", -" TYPE Display a file on your screen", -" ORIENTATION Explains directory structure", -" ", - -#ifndef NOXFER -"Commands for file transfer:", -" SEND Send files", -" RECEIVE Receive files", -" GET Get files from a Kermit server", -#ifdef CK_RESEND -" RESEND Recover an interrupted send", -" REGET Recover an interrupted get from a server", -#endif /* CK_RESEND */ -#ifndef NOSERVER -" SERVER Be a Kermit server", -#endif /* NOSERVER */ -" ", -"File-transfer speed selection:", -" FAST Use fast settings -- THIS IS THE DEFAULT", -" CAUTIOUS Use slower, more cautious settings", -" ROBUST Use extremely slow and cautious settings", -" ", -"File-transfer performance fine tuning:", -" SET RECEIVE PACKET-LENGTH Kermit packet size", -" SET WINDOW Number of sliding window slots", -" SET PREFIXING Amount of control-character prefixing", -#endif /* NOXFER */ - -#ifndef NOLOCAL -" ", -"To make a direct serial connection:", -#ifdef OS2 -#ifdef NT -#ifdef CK_TAPI -" SET PORT TAPI Select TAPI communication device", -#endif /* CK_TAPI */ -" SET PORT Select serial communication device", -#else -" SET PORT Select serial communication port or server", -#endif /* NT */ -#else -" SET LINE Select serial communication device", -#endif /* OS2 */ -" SET SPEED Select communication speed", -" SET PARITY Communications parity (if necessary)", -#ifdef CK_RTSCTS -" SET FLOW Communications flow control, such as RTS/CTS", -#else -" SET FLOW Communications flow control, such as XON/XOFF", -#endif /* CK_RTSCTS */ -" CONNECT Begin terminal connection", - -#ifndef NODIAL -" ", -"To dial out with a modem:", -" SET DIAL DIRECTORY Specify dialing directory file (optional)", -" SET DIAL COUNTRY-CODE Country you are dialing from (*)", -" SET DIAL AREA-CODE Area-code you are dialing from (*)", -" LOOKUP Lookup entries in your dialing directory (*)", -" SET MODEM TYPE Select modem type", -#ifdef OS2 -#ifdef NT -#ifdef CK_TAPI -" SET PORT TAPI Select TAPI communication device", -#endif /* CK_TAPI */ -" SET PORT Select serial communication device", -#else -" SET PORT Select serial communication port or server", -#endif /* NT */ -#else -" SET LINE Select serial communication device", -#endif /* OS2 */ -" SET SPEED Select communication speed", -" SET PARITY Communications parity (if necessary)", -" DIAL Dial the phone number", -" CONNECT Begin terminal connection", -" ", -#ifdef OS2 -"Further info: HELP DIAL, HELP SET MODEM, HELP SET PORT, HELP SET DIAL", -#else -"Further info: HELP DIAL, HELP SET MODEM, HELP SET LINE, HELP SET DIAL", -#endif /* OS2 */ -"(*) (For use with optional dialing directory)", -#endif /* NODIAL */ - -#ifdef NETCONN -" ", -"To make a network connection:", -#ifndef NODIAL -" SET NETWORK DIRECTORY Specify a network services directory (optional)", -" LOOKUP Lookup entries in your network directory", -#endif /* NODIAL */ -" SET NETWORK TYPE Select network type (if more than one available)", -" SET HOST Make a network connection but stay in command mode", -" CONNECT Begin terminal connection", -#ifdef TNCODE -" TELNET Select a Telnet host and CONNECT to it", -#endif /* TNCODE */ -#ifdef RLOGCODE -" RLOGIN Select an Rlogin host and CONNECT to it", -#endif /* RLOGCODE */ -#ifdef ANYSSH -" SSH [ OPEN ] Select an SSH host and CONNECT to it", -#endif /* ANYSSH */ -#ifdef NEWFTP -" FTP [ OPEN ] Make an FTP connection", -#endif /* NEWFTP */ -#ifdef CKHTTP -" HTTP OPEN Make an HTTP connection", -#endif /* CKHTTP */ -#endif /* NETCONN */ - -#ifdef NT -" ", -"To return from the terminal window to the K-95> prompt:", -#else -#ifdef OS2 -" ", -"To return from the terminal window to the K/2> prompt:", -#else -" ", -"To return from a terminal connection to the C-Kermit prompt:", -#endif /* OS2 */ -#endif /* NT */ -#ifdef OS2 -" \ -Press the key or key-combination shown after \"Command:\" in the status line", -" (such as Alt-x) or type your escape character followed by the letter C.", -#else -" Type your escape character followed by the letter C.", -#endif /* OS2 */ -" ", -"To display your escape character:", -" SHOW ESCAPE", -" ", -"To display other settings:", -" SHOW COMMUNICATIONS, SHOW TERMINAL, SHOW FILE, SHOW PROTOCOL, etc.", -#else /* !NOLOCAL */ -" ", -"To display settings:", -" SHOW COMMUNICATIONS, SHOW FILE, SHOW PROTOCOL, etc.", -#endif /* NOLOCAL */ -" ", -#ifdef OS2 -"For a Kermit 95 tutorial, visit:", -" http://www.columbia.edu/kermit/k95tutor.html", -" ", -#endif /* OS2 */ -"For a C-Kermit tutorial, visit:", -" http://www.columbia.edu/kermit/ckututor.html", -" ", -"To learn about script programming and automation:", -" Read the manual, \"Using C-Kermit\". For a brief tutorial, visit:", -" http://www.columbia.edu/kermit/ckscripts.html", -" ", -"For further information about a particular command, type HELP xxx,", -"where xxx is the name of the command. For documentation, news of new", -"releases, and information about other Kermit software, contact:", -" ", -" The Kermit Project E-mail: kermit@columbia.edu", -" Columbia University Web: http://www.columbia.edu/kermit/", -" 612 West 115th Street Voice: +1 (212) 854-3703", -" New York NY 10025-7799 Fax: +1 (212) 662-6442", -" USA", -"" -}; - -static char * hmxymatch[] = { -"SET MATCH { DOTFILE, FIFO } { ON, OFF }", -" Tells whether wildcards should match dotfiles (files whose names begin", -" with period) or UNIX FIFO special files. MATCH FIFO default is OFF.", -" MATCH DOTFILE default is OFF in UNIX, ON elsewhere.", -"" -}; - -#ifdef OS2 -#ifdef KUI -static char * hmxygui[] = { -"SET GUI DIALOGS { ON, OFF }", -" ON means that popups, alerts, use GUI dialogs; OFF means to use", -" text-mode popups or prompts. ON by default.", -" ", -"SET GUI FONT name size", -" Chooses the font and size. Type \"set gui font ?\" to see the list of", -" choices. The size can be a whole number or can contain a decimal point", -" and a fraction (which is rounded to the nearest half point).", -" ", -"SET GUI RGBCOLOR colorname redvalue greenvalue bluevalue", -" Specifies the red-green-blue mixture to be used to render the given", -" color name. Type \"set gui rgbcolor\" to see a list of colornames.", -" the RGB values are whole numbers from 0 to 255.", -" ", -"SET GUI WINDOW POSITION x y", -" Moves the K95 window to the given X,Y coordinates, pixels from top left.", -" (Not yet implemented -- use command-line options to do this.)", -" ", -"SET GUI WINDOW RESIZE-MODE { CHANGE-DIMENSIONS, SCALE-FONT }", -" Default is CHANGE-DIMENSIONS.", -"", -"SET GUI WINDOW RUN-MODE { MAXIMIZE, MINIMIZE, RESTORE }", -" Changes the run mode state of the GUI window.", -"" -}; -#endif /* KUI */ -#endif /* OS2 */ - -#ifdef ANYSSH -static char * hmxxssh[] = { -#ifdef SSHBUILTIN -"Syntax: SSH { ADD, AGENT, CLEAR, KEY, [ OPEN ], V2 } operands...", -" Performs an SSH-related action, depending on the keyword that follows:", -" ", -"SSH ADD LOCAL-PORT-FORWARD local-port host port", -" Adds a port forwarding triplet to the local port forwarding list.", -" The triplet specifies a local port to be forwarded and the hostname /", -" ip-address and port number to which the port should be forwarded from", -" the remote host. Port forwarding is activated at connection", -" establishment and continues until the connection is terminated.", -" ", -"SSH ADD REMOTE-PORT-FORWARD remote-port host port", -" Adds a port forwarding triplet to the remote port forwarding list.", -" The triplet specifies a remote port to be forwarded and the", -" hostname/ip-address and port number to which the port should be", -" forwarded from the local machine. Port forwarding is activated at", -" connection establishment and continues until the connection is", -" terminated.", -" ", -"SSH AGENT ADD [ identity-file ]", -" Adds the contents of the identity-file (if any) to the SSH AGENT", -" private key cache. If no identity-file is specified, all files", -" specified with SET SSH IDENTITY-FILE are added to the cache.", -" ", -"SSH AGENT DELETE [ identity-file ]", -" Deletes the contents of the identity-file (if any) from the SSH AGENT", -" private key cache. If no identity-file is specified, all files", -" specified with SET SSH IDENTITY-FILE are deleted from the cache.", -" ", -"SSH AGENT LIST [ /FINGERPRINT ]", -" Lists the contents of the SSH AGENT private key cache. If /FINGERPRINT", -" is specified, the fingerprint of the private keys are displayed instead", -" of the keys.", -" ", -"SSH CLEAR LOCAL-PORT-FORWARD", -" Clears the local port forwarding list.", -" ", -"SSH CLEAR REMOTE-PORT-FORWARD", -" Clears the remote port forwarding list.", -" ", -"SSH KEY commands:", -" The SSH KEY commands create and manage public and private key pairs", -" (identities). There are three forms of SSH keys. Each key pair is", -" stored in its own set of files:", -" ", -" Key Type Private Key File Public Key File", -" v1 RSA keys \\v(appdata)ssh/identity \\v(appdata)ssh/identity.pub", -" v2 RSA keys \\v(appdata)ssh/id_rsa \\v(appdata)ssh/id_rsa.pub", -" v2 DSA keys \\v(appdata)ssh/id_dsa \\v(appdata)ssh/id_dsa.pub", -" ", -" Keys are stored using the OpenSSH keyfile format. The private key", -" files can be (optionally) protected by specifying a passphrase. A", -" passphrase is a longer version of a password. English text provides", -" no more than 2 bits of key data per character. 56-bit keys can be", -" broken by a brute force attack in approximately 24 hours. When used,", -" private key files should therefore be protected by a passphrase of at", -" least 40 characters (about 80 bits).", -" ", -" To install a public key file on the host, you must transfer the file", -" to the host and append it to your \"authorized_keys\" file. The file", -" permissions must be 600 (or equivalent).", -" ", -"SSH KEY CHANGE-PASSPHRASE [ /NEW-PASSPHRASE:passphrase", -" /OLD-PASSPHRASE:passphrase ] filename", -" This re-encrypts the specified private key file with a new passphrase.", -" The old passphrase is required. If the passphrases (and filename) are", -" not provided Kermit prompts your for them.", -" ", -"SSH KEY CREATE [ /BITS:bits /PASSPHRASE:passphrase", -" /TYPE:{ V1-RSA, V2-DSA, V2-RSA } /V1-RSA-COMMENT:comment ] filename", -" This command creates a new private/public key pair. The defaults are:", -" BITS:1024 and TYPE:V2-RSA. The filename is the name of the private", -" key file. The public key is created with the same name with .pub", -" appended to it. If a filename is not specified Kermit prompts you for", -" it. V1 RSA key files may have an optional comment, which is ignored", -" for other key types.", -" ", -"SSH KEY DISPLAY [ /FORMAT:{FINGERPRINT,IETF,OPENSSH,SSH.COM} ] filename", -" This command displays the contents of a public or private key file.", -" The default format is OPENSSH.", -" ", -"SSH KEY V1 SET-COMMENT filename comment", -" This command replaces the comment associated with a V1 RSA key file.", -" ", -"SSH [ OPEN ] host [ port ] [ /COMMAND:command /USER:username", -" /PASSWORD:pwd /VERSION:{ 1, 2 } /X11-FORWARDING:{ ON, OFF } ]", -" This command establishes a new connection using SSH version 1 or", -" version 2 protocol. The connection is made to the specified host on", -" the SSH port (you can override the port by including a port name or", -" number after the host name). Once the connection is established the", -" authentication negotiations begin. If the authentication is accepted,", -" the local and remote port forwarding lists are used to establish the", -" desired connections. If X11 Forwarding is active, this results in a", -" remote port forwarding between the X11 clients on the remote host and", -" X11 Server on the local machine. If a /COMMAND is provided, the", -" command is executed on the remote host in place of your default shell.", -" ", -" An example of a /COMMAND to execute C-Kermit in SERVER mode is:", -" SSH OPEN hostname /COMMAND:{kermit -x -l 0}", -" ", -"SSH V2 REKEY", -" Requests that an existing SSH V2 connection generate new session keys.", -#else /* SSHBUILTIN */ -"Syntax: SSH [ options ] [ command ]", -" Makes an SSH connection using the external ssh program via the SET SSH", -" COMMAND string, which is \"ssh -e none\" by default. Options for the", -" external ssh program may be included. If the hostname is followed by a", -" command, the command is executed on the host instead of an interactive", -" shell.", -#endif /* SSHBUILTIN */ -"" -}; - -static char *hmxyssh[] = { -#ifdef SSHBUILTIN -"SET SSH AGENT-FORWARDING { ON, OFF }", -" If an authentication agent is in use, setting this value to ON", -" results in the connection to the agent being forwarded to the remote", -" computer. The default is OFF.", -" ", -"SET SSH CHECK-HOST-IP { ON, OFF }", -" Specifies whether the remote host's ip-address should be checked", -" against the matching host key in the known_hosts file. This can be", -" used to determine if the host key changed as a result of DNS spoofing.", -" The default is ON.", -" ", -"SET SSH COMPRESSION { ON, OFF }", -" Specifies whether compression will be used. The default is ON.", -" ", -"SET SSH DYNAMIC-FORWARDING { ON, OFF }", -" Specifies whether Kermit is to act as a SOCKS4 service on port 1080", -" when connected to a remote host via SSH. When Kermit acts as a SOCKS4", -" service, it accepts connection requests and forwards the connections", -" through the remote host. The default is OFF.", -" ", -"SET SSH GATEWAY-PORTS { ON, OFF }", -" Specifies whether Kermit should act as a gateway for forwarded", -" connections received from the remote host. The default is OFF.", -" ", -"SET SSH GSSAPI DELEGATE-CREDENTIALS { ON, OFF }", -" Specifies whether Kermit should delegate GSSAPI credentials to ", -" the remote host after authentication. Delegating credentials allows", -" the credentials to be used from the remote host. The default is OFF.", -" ", -"SET SSH HEARTBEAT-INTERVAL ", -" Specifies a number of seconds of idle time after which an IGNORE", -" message will be sent to the server. This pulse is useful for", -" maintaining connections through HTTP Proxy servers and Network", -" Address Translators. The default is OFF (0 seconds).", -" ", -"SET SSH IDENTITY-FILE filename [ filename [ ... ] ]", -" Specifies one or more files from which the user's authorization", -" identities (private keys) are to be read when using public key", -" authorization. These are files used in addition to the default files:", -" ", -" \\v(appdata)ssh/identity V1 RSA", -" \\v(appdata)ssh/id_rsa V2 RSA", -" \\v(appdata)ssh/id_dsa V2 DSA", -" ", -"SET SSH KERBEROS4 TGT-PASSING { ON, OFF }", -" Specifies whether Kermit should forward Kerberos 4 TGTs to the host.", -" The default is OFF.", -" ", -"SET SSH KERBEROS5 TGT-PASSING { ON, OFF }", -" Specifies whether Kermit should forward Kerberos 5 TGTs to to the", -" host. The default is OFF.", -" ", -"SET SSH PRIVILEGED-PORT { ON, OFF }", -" Specifies whether a privileged port (less than 1024) should be used", -" when connecting to the host. Privileged ports are not required except", -" when using SSH V1 with Rhosts or RhostsRSA authorization. The default", -" is OFF.", -" ", -"SET SSH QUIET { ON, OFF }", -" Specifies whether all messages generated in conjunction with SSH", -" protocols should be suppressed. The default is OFF.", -" ", -"SET SSH STRICT-HOST-KEY-CHECK { ASK, ON, OFF }", -" Specifies how Kermit should behave if the the host key check fails.", -" When strict host key checking is OFF, the new host key is added to the", -" protocol-version-specific user-known-hosts-file. When strict host key", -" checking is ON, the new host key is refused and the connection is", -" dropped. When set to ASK, Kermit prompt you to say whether the new", -" host key should be accepted. The default is ASK.", -" ", -" Strict host key checking protects you against Trojan horse attacks.", -" It depends on you to maintain the contents of the known-hosts-file", -" with current and trusted host keys.", -" ", -"SET SSH USE-OPENSSH-CONFIG { ON, OFF }", -" Specifies whether Kermit should parse an OpenSSH configuration file", -" after applying Kermit's SET SSH commands. The configuration file", -" would be located at \\v(home)ssh/ssh_config. The default is OFF.", -" ", -"SET SSH V1 CIPHER { 3DES, BLOWFISH, DES }", -" Specifies which cipher should be used to protect SSH version 1", -" connections. The default is 3DES.", -" ", -"SET SSH V1 GLOBAL-KNOWN-HOSTS-FILE filename", -" Specifies the location of the system-wide known-hosts file. The", -" default is:", -" ", -" \v(common)ssh_known_hosts", -" ", -"SET SSH V1 USER-KNOWN-HOSTS-FILE filename", -" Specifies the location of the user-known-hosts-file. The default", -" location is:", -" ", -" \\v(appdata)ssh/known_hosts", -" ", -"SET SSH V2 AUTHENTICATION { EXTERNAL-KEYX, GSSAPI, HOSTBASED, ", -" KEYBOARD-INTERACTIVE, PASSWORD, PUBKEY, SRP-GEX-SHA1 } [ ... ]", -" Specifies an ordered list of SSH version 2 authentication methods to", -" be used when connecting to the remote host. The default list is:", -" ", -" external-keyx gssapi hostbased publickey srp-gex-sha1 publickey", -" keyboard-interactive password none", -" ", -"SET SSH V2 AUTO-REKEY { ON, OFF }", -" Specifies whether Kermit automatically issues rekeying requests", -" once an hour when SSH version 2 in in use. The default is ON.", -" ", -"SET SSH V2 CIPHERS { 3DES-CBC, AES128-CBC AES192-CBC AES256-CBC", -" ARCFOUR BLOWFISH-CBC CAST128-CBC RIJNDAEL128-CBC RIJNDAEL192-CBC", -" RIJNDAEL256-CBC }", -" Specifies an ordered list of SSH version ciphers to be used to encrypt", -" the established connection. The default list is:", -" ", -" aes128-cbc 3des-cbc blowfish-cbc cast128-cbc arcfour aes192-cbc", -" aes256-cbc", -" ", -" \"rijndael\" is an alias for \"aes\".", -" ", -"SET SSH V2 GLOBAL-KNOWN-HOSTS-FILE filename", -" Specifies the location of the system-wide known-hosts file. The default", -" location is:", -" ", -" \\v(common)ssh/known_hosts2", -" ", -"SET SSH V2 HOSTKEY-ALGORITHMS { SSH-DSS, SSH-RSA }", -" Specifies an ordered list of hostkey algorithms to be used to verify", -" the identity of the host. The default list is", -" ", -" ssh-rsa ssh-dss", -" ", -"SET SSH V2 MACS { HMAC-MD5 HMAC-MD5-96 HMAC-RIPEMD160 HMAC-SHA1", -" HMAC-SHA1-96 }", -" Specifies an ordered list of Message Authentication Code algorithms to", -" be used for integrity protection of the established connection. The", -" default list is:", -" ", -" hmac-md5 hmac-sha1 hmac-ripemd160 hmac-sha1-96 hmac-md5-96", -" ", -"SET SSH V2 USER-KNOWN-HOSTS-FILE filename", -" Specifies the location of the user-known-hosts file. The default", -" location is:", -" ", -" \\v(appdata)ssh/known_hosts2", -" ", -"SET SSH VERBOSE level", -" Specifies how many messages should be generated by the OpenSSH engine.", -" The level can range from 0 to 7. The default value is 2.", -" ", -"SET SSH VERSION { 1, 2, AUTOMATIC }", -" Specifies which SSH version should be negotiated. The default is", -" AUTOMATIC which means use version 2 if supported; otherwise to fall", -" back to version 1.", -" ", -"SET SSH X11-FORWARDING { ON, OFF }", -" Specifies whether X Windows System Data is to be forwarded across the", -" established SSH connection. The default is OFF. When ON, the DISPLAY", -" value is either set using the SET TELNET ENV DISPLAY command or read", -" from the DISPLAY environment variable.", -" ", -"SET SSH XAUTH-LOCATION filename", -" Specifies the location of the xauth executable (if provided with the", -" X11 Server software.)", -#else /* SSHBUILTIN */ -"Syntax: SET SSH COMMAND command", -" Specifies the external command to be used to make an SSH connection.", -" By default it is \"ssh -e none\" (ssh with no escape character).", -#endif /* SSHBUILTIN */ -"" -}; -#endif /* ANYSSH */ - -#ifdef NEWFTP -static char *hmxygpr[] = { -"Syntax: SET GET-PUT-REMOTE { AUTO, FTP, KERMIT}", -" Tells Kermit whether GET, PUT, and REMOTE commands should be directed", -" at a Kermit server or an FTP server. The default is AUTO, meaning that", -" if you have only one active connection, the appropriate action is taken", -" when you give a GET, PUT, or REMOTE command. SET GET-PUT-REMOTE FTP forces" -, -" Kermit to treat GET, PUT, and REMOTE as FTP client commands; setting this", -" to KERMIT forces these commands to be treated as Kermit client commands.", -" NOTE: PUT includes SEND, MPUT, MSEND, and all other similar commands.", -" Also see HELP REMOTE, HELP SET LOCUS, HELP FTP.", -"" -}; -#endif /* NEWFTP */ - -#ifdef LOCUS -static char *hmxylocus[] = { -#ifdef KUI -"Syntax: SET LOCUS { ASK, AUTO, LOCAL, REMOTE }", -#else -"Syntax: SET LOCUS { AUTO, LOCAL, REMOTE }", -#endif /* KUI */ -" Specifies whether unprefixed file management commands should operate", -" locally or (when there is a connection to a remote FTP or Kermit", -" server) sent to the server. The affected commands are: CD (CWD), PWD,", -" CDUP, DIRECTORY, DELETE, RENAME, MKDIR, and RMDIR. To force any of", -" these commands to be executed locally, give it an L-prefix: LCD, LDIR,", -" etc. To force remote execution, use the R-prefix: RCD, RDIR, and so", -" on. SHOW COMMAND shows the current Locus.", -" ", -" By default, the Locus for file management commands is switched", -" automatically whenever you make or close a connection: if you make an", -" FTP connection, the Locus becomes REMOTE; if you close an FTP connection", -" or make any other kind of connection, the Locus becomes LOCAL.", -#ifdef KUI -" ", -" There are two kinds of automatic switching: ASK (the default) which", -" asks you if it's OK to switch, and AUTO, which switches without asking.", -#endif /* KUI */ -" ", -" If you give a SET LOCUS LOCAL or SET LOCUS REMOTE command, this sets", -" the locus as indicated and disables automatic switching.", -#ifdef KUI -" SET LOCUS AUTO or SET LOCUS ASK restores automatic switching.", -" You can also change Locus switching and behavior in the Actions menu.", -#else -" SET LOCUS AUTO restores automatic switching.", -#endif /* KUI */ -"", -}; -#endif /* LOCUS */ - -static char *hmxxtak[] = { -"Syntax: TAKE filename [ arguments ]", -" Tells Kermit to execute commands from the named file. Optional argument", -" words, are automatically assigned to the macro argument variables \\%1", -" through \\%9. Kermit command files may themselves contain TAKE commands,", -" up to any reasonable depth of nesting.", -"" -}; - -#ifdef TCPSOCKET -static char *hmxxfirew[] = { -#ifdef OS2 -"Firewall Traversal in Kermit 95", -#else -"Firewall Traversal in C-Kermit", -#endif -" ", -#ifndef NEWFTP -#ifndef CKHTTP -#ifndef CK_SOCKS -#define NOFIREWALL -#endif -#endif -#endif -#ifdef NOFIREWALL -"This version of Kermit was built with no support for firewall traversal", -"protocols. Kermit can be built with support for HTTP Proxy Servers,", -"SOCKS authorized firewall traversal, and FTP Passive connection modes.", -" ", -#else /* NOFIREWALL */ -#ifdef CKHTTP -"The simplist form of firewall traversal is the HTTP CONNECT command. The", -"CONNECT command was implemented to allow a public web server which usually", -"resides on the boundary between the public and private networks to forward", -"HTTP requests from clients on the private network to public web sites. To", -"allow secure web connections, the HTTP CONNECT command authenticates the", -"client with a username/password and then establishes a tunnel to the", -"desired host.", - -" ", - -"Web servers that support the CONNECT command can be configured to allow", -"outbound connections for authenticated users to any TCP/IP hostname-port", -"combination accessible to the Web server. HTTP CONNECT can be used only", -"with TCP-based protocols. Protocols such as Kerberos authentication that", -"use UDP/IP cannot be tunneled using HTTP CONNECT.", - -" ", - -"SET TCP HTTP-PROXY [switches] [[:]]", -" If a hostname or ip-address is specified, Kermit uses the given", -" proxy server when attempting outgoing TCP connections. If no hostnamer", -" or ip-address is specified, any previously specified Proxy server is", -" removed. If no port number is specified, the \"http\" service is used.", -" [switches] can be one or more of:", -" /AGENT: /USER: /PASSWORD:", -" Switch parameters are used when connecting to the proxy server and", -" override any other values associated with the connection.", -" ", - -#endif /* CKHTTP */ -#ifdef CK_SOCKS - -"In the early 1990s as firewalls were becoming prevalent, David Koblas", -"developed the SOCKS protocol for TCP/IP firewall traversal. Two versions", -"of SOCKS are currently in use: Version 4.2 lets TCP/IP client applications", -"traverse firewalls, similar to HTTP CONNECT, except that the SOCKS client", -"is aware of the public source IP address and port, which can be used within", -"the application protocol to assist in securing the connection (e.g. FTP", -"sessions secured with GSSAPI Kerberos 5).", - -" ", - -"In 1995 the IETF issued SOCKS Protocol Version 5 (RFC 1928), which is", -"significantly more general than version 4. Besides supporting client-", -"to-server TCP/IP connections, it also includes:", - -" ", -" . Authenticated firewall traversal of UDP/IP packets.", -" . Authenticated binding of incoming public ports on the firewall.", -" ", - -"This lets a service on the private network offer public services. It also", -"lets client applications like FTP establish a temporary public presence", -"that can be used by the FTP server to create a data channel. By allowing", -"the client to bind to a public port on the firewall and be aware of the", -"public address, SOCKS 5 lets the application protocol communicate this", -"information to the server.", - -" ", - -#ifdef OS2 -#ifdef NT -"Kermit 95 supports SOCKS 4.2. The SOCKS Server is specified with:", -" ", -" SET TCP SOCKS-SERVER hostname/ip-address", -" ", -"The SOCKS.CONF file is found by examining the ETC environment variable;", -"searching in \\WINDOWS on Windows 95/98/ME; or the", -"\\WINDOWS\\SYSTEM\\DRIVERS\\ETC directory on NT\\2000\\XP systems.", - -#else /* NT */ - -"Kermit/2 provides support for SOCKS 4.2 servers when using IBM TCP/IP 2.0,", -"IBM OS/2 WARP, or a compatible protocol stack. SOCKS is one popular means", -"of implementing a firewall between a private network and the Internet.", -" ", -"Kermit/2 shares the same SOCKS environment variables as IBM Gopher. It also", -"supports the use of local SOCKS configuration files.", -" ", -"To specify the default SOCKS Server, add SET SOCKS_SERVER= to your", -"CONFIG.SYS file.", -" ", -"If you must use a SOCKS Distributed Name Server, add SET SOCKS_NS= to your", -"CONFIG.SYS file.", -" ", - -"If you must use a specific with your SOCKS server, be sure to add SET USER=", -"to your CONFIG.SYS file. Otherwise, \"os2user\" is used by default.", - -" ", - -"The SOCKS configuration file must be placed in the directory pointed to by", -"the ETC environment variable as declared in your CONFIG.SYS file. The name", -"should be SOCKS.CONF. On a FAT file system, use SOCKS.CNF.", - -" ", -"The format of the lines in the SOCKS configuration file are as follows:", -" ", -" . # comments", -" . deny [*=userlist] dst_addr dst_mask [op port]", -" . direct [*=userlist] dst_addr dst_mask [op port]", -" . sockd [@=serverlist] [*=userlist] dst_addr dst_mask [op port]", -" ", - -"op must be one of 'eq', 'neq', 'lt', 'gt', 'le', or 'ge'. dst_addr,", -"dst_mask, and port may be either numeric or name equivalents.", - -" ", - -"Kermit/2 ignores the [*=userlist] and [@=serverlist] fields. Matches are", -"determined on a first match not a best match basis. Addresses for which no", -"match is found default to \"sockd\".", - -" ", - -"For completeness: Fields in square brackets are optional. The optional", -"@=serverlist field with a 'sockd' line specifies the list of SOCKS servers", -"the client should try (in the given order) instead of the default SOCKS", -"server. If the @=serverlist part is omitted, then the default SOCKS server", -"is used. Commas are used in the userlist and serverlist as separators, no", -"white spaces are allowed.", - -#endif /* NT */ - -" ", - -#else /* OS2 */ -#ifdef CK_SOCKS5 -"This version of C-Kermit supports SOCKS version 5.", -#else /* CK_SOCKS5 */ -"This version of C-Kermit supports SOCKS version 4.", -#endif /* CK_SOCKS5 */ - -"See the man page (or other system documentation) for information on", -"configuring the SOCKS library via the /etc/socks.conf file.", - -#endif /* OS2 */ -" ", -#endif /* CK_SOCKS */ - -#ifdef NEWFTP - -"FTP is one of the few well-known Internet services that requires", -"multiple connections. As described above, FTP originally required the", -"server to establish the data connection to the client using a destination", -"address and port provided by the client. This doesn't work with port", -"filtering firewalls.", - -" ", - -"Later, FTP protocol added a \"passive\" mode, in which connections for", -"the data channels are created in the reverse direction. Instead of the", -"server establishing a connection to the client, the client makes a second", -"connection with the server as the destination. This works just fine as", -"long as the client is behind the firewall and the server is in public", -"address space. If the server is behind a firewall then the traditional", -"active mode must be used. If both the client and server are behind their", -"own port filtering firewalls then data channels cannot be established.", - -" ", - -"In Kermit's FTP client, passive mode is controlled with the command:", - -" ", -" SET FTP PASSIVE-MODE { ON, OFF }", -" ", - -"The default is ON, meaning to use passive mode.", - -#endif /* NEWFTP */ -#endif /* NOFIREWALL */ - -"" -}; -#endif /* TCPSOCKET */ - -static char *hmxxsave[] = { -"Syntax: SAVE item filename { NEW, APPEND }", -" Saves the requested material in the given file. A new file is created", -" by default; include APPEND at the end of the command to append to an", -" existing file. Items:", -#ifndef NOSETKEY -" KEYMAP Saves the current key settings.", -#endif /* NOSETKEY */ -#ifdef CK_RECALL -" COMMAND HISTORY Saves the current command recall (history) buffer", -#endif /* CK_RECALL */ -#ifdef OS2 -" COMMAND SCROLLBACK Saves the current command-screen scrollback buffer", -" TERMINAL SCROLLBACK Saves the current terminal-screen scrollback buffer", -#endif /* OS2 */ -"" -}; - -#ifdef CKROOT -static char *hmxxchroot[] = { -"Syntax: SET ROOT directoryname", -" Sets the root for file access to the given directory and disables access", -" to system and shell commands and external programs. Once this command", -" is given, no files or directories outside the tree rooted by the given", -" directory can be opened, read, listed, deleted, renamed, or accessed in", -" any other way. This command can not be undone by a subsequent SET ROOT", -" command. Primarily for use with server mode, to restrict access of", -" clients to a particular directory tree. Synonym: CHROOT.", -"" -}; -#endif /* CKROOT */ - -static char *hmxxscrn[] = { -"Syntax: SCREEN { CLEAR, CLEOL, MOVE row column }", -#ifdef OS2 -" Performs screen-formatting actions.", -#else -" Performs screen-formatting actions. Correct operation of these commands", -" depends on proper terminal setup on both ends of the connection -- mainly", -" that the host terminal type is set to agree with the kind of terminal or", -" the emulation you are viewing C-Kermit through.", -#endif /* OS2 */ -" ", -"SCREEN CLEAR", -" Moves the cursor to home position and clears the entire screen.", -#ifdef OS2 -" Synonyms: CLS, CLEAR SCREEN, CLEAR COMMAND-SCREEN ALL", -#else -" Synonyms: CLS, CLEAR SCREEN.", -#endif /* OS2 */ -" ", -"SCREEN CLEOL", -" Clears from the current cursor position to the end of the line.", -#ifdef OS2 -" Synonym: CLEAR COMMAND-SCREEN EOL", -#endif /* OS2 */ -" ", -"SCREEN MOVE row column", -" Moves the cursor to the indicated row and column. The row and column", -" numbers are 1-based so on a 24x80 screen, the home position is 1 1 and", -" the lower right corner is 24 80. If a row or column number is given that", -" too large for what Kermit or the operating system thinks is your screen", -" size, the appropriate number is substituted.", -" ", -"Also see:", -#ifdef OS2 -" HELP FUNCTION SCRNCURX, HELP FUNCTION SCRNCURY, HELP FUNCTION SCRSTR,", -#endif /* OS2 */ -" SHOW VARIABLE TERMINAL, SHOW VARIABLE COLS, SHOW VAR ROWS, SHOW COMMAND.", -"" -}; - -#ifndef NOSPL -static char *hmfword[] = { -"\\fword(s1,n1,s2,s3,n2,n3) - Extract word from string.", -" s1 = source string", -" n1 = word number (1-based)", -" s2 = optional break set.", -" s3 = optional include set.", -" n2 = optional grouping mask.", -" n3 = optional separator flag:", -" 0 = collapse adjacent separators", -" 1 = don't collapse adjacent separators.", -" ", -" Default break set is all characters except ASCII letters and digits.", -" ASCII (C0) control characters are always treated as break characters.", -" Default include set is null.", -" ", -" If grouping mask given and nonzero, words can be grouped by quotes or", -" brackets selected by the sum of the following:", -" ", -" 1 = doublequotes: \"a b c\"", -" 2 = braces: {a b c}", -" 4 = apostrophes: 'a b c'", -" 8 = parentheses: (a b c)", -" 16 = square brackets: [a b c]", -" 32 = angle brackets: ", -" ", -" Nesting is possible with {}()[]<> but not with quotes or apostrophes.", -" ", -"Returns string:", -" Word number n, if there is one, otherwise an empty string.", -"" -}; - -static char *hmxxprompt[] = { -"Syntax: PROMPT [ text ]", -" Enters interactive command level from within a script in such a way that", -" the script can be continued with an END or RETURN command. STOP, EXIT,", -" SHOW STACK, TRACE, and Ctrl-C all have their normal effects. The PROMPT", -" command allows variables to be examined or changed, or any other commands", -" to be given, in any number, prior to returning to the script, allowing", -" Kermit to serve as its own debugger; adding the PROMPT command to a script", -" is like setting a breakpoint. If the optional text is included, it is", -" used as the new prompt for this level, e.g. \"prompt Breakpoint_1>\".", -"" -}; - -static char *hxxinp[] = { -"Syntax: INPUT [ /NOMATCH ] { number-of-seconds, time-of-day } [ text ]", -"Example: INPUT 5 Login: or INPUT 23:59:59 RING", -" Waits up to the given number of seconds, or until the given time of day,", -" for the given text to arrive on the connection. If no text is given,", -" INPUT waits for any character. If the /NOMATCH switch is included, INPUT", -" does not attempt to match any characters, but continues reading from the", -" communication connection until the timeout interval expires. If the", -" timeout interval is 0, the INPUT command does not wait; i.e. the given", -" text must already be available for reading for the INPUT command to", -" succeed. If the interval is negative, the INPUT command waits forever.", -" For use in script programs with IF FAILURE and IF SUCCESS. Also see", -" MINPUT, REINPUT, SET INPUT. See HELP PAUSE for details on time-of-day", -" format. The text, if given, can be a \\pattern() invocation, in which", -" case it is treated as a pattern rather than a literal string (HELP", -" PATTERNS for details).", -""}; - -static char *hxxout[] = { -"Syntax: OUTPUT text", -" Sends the text out the communications connection, as if you had typed it", -" during CONNECT mode. The text may contain backslash codes, variables,", -" etc, plus the following special codes:", -" ", -" \\N - Send a NUL (ASCII 0) character (you can't use \\0 for this).", -" \\B - Send a BREAK signal.", -" \\L - Send a Long BREAK signal.", -" ", -"Also see SET OUTPUT.", -"" }; -#endif /* NOSPL */ - -static char *hxypari[] = { -"SET PARITY NONE", -" Chooses 8 data bits and no parity.", -" ", -"SET PARITY { EVEN, ODD, MARK, SPACE }", -" Chooses 7 data bits plus the indicated kind of parity.", -" Forces 8th-bit prefixing during file transfer.", -" ", -#ifdef HWPARITY -"SET PARITY HARDWARE { EVEN, ODD }", -" Chooses 8 data bits plus the indicated kind of parity.", -" ", -"Also see SET TERMINAL BYTESIZE, SET SERIAL, and SET STOP-BITS.", -#else -"Also see SET TERMINAL BYTESIZE and SET SERIAL.", -#endif /* HWPARITY */ -""}; - -#ifndef NOLOCAL -static char *hxyesc[] = { -#ifdef OS2 -"Syntax: SET ESCAPE number", -" Decimal ASCII value for escape character during CONNECT, normally 29", -" (Control-]). Type the escape character followed by C to get back to the", -" C-Kermit prompt or followed by ? to see other options, or use the \\Kexit", -" keyboard verb, normally assigned to Alt-x.", -#else -#ifdef NEXT -"Syntax: SET ESCAPE number", -" Decimal ASCII value for escape character during CONNECT, normally 29", -" (Control-]). Type the escape character followed by C to get back to the", -" C-Kermit prompt or followed by ? to see other options.", -#else -"Syntax: SET ESCAPE number", -" Decimal ASCII value for escape character during CONNECT, normally 28", -" (Control-\\). Type the escape character followed by C to get back to the", -" C-Kermit prompt or followed by ? to see other options.", -#endif /* NEXT */ -#endif /* OS2 */ -" ", -"You may also enter the escape character as ^X (circumflex followed by a", -"letter or one of: @, ^, _, [, \\, or ], to indicate a control character;", -"for example, SET ESC ^_ sets your escape character to Ctrl-Underscore.", -" ", -"You can also specify an 8-bit character (128-255) as your escape character,", -"either by typing it literally or by entering its numeric code.", -"" }; -#endif /* NOLOCAL */ - -#ifndef NOSPL -static char *hxyout[] = { -"SET OUTPUT PACING ", -" How many milliseconds to pause after sending each OUTPUT character,", -" normally 0.", -" ", -"SET OUTPUT SPECIAL-ESCAPES { ON, OFF }", -" Whether to process the special OUTPUT-only escapes \\B, \\L, and \\N.", -" Normally ON (they are processed).", -"" }; - -static char *hxyinp[] = { -"Syntax: SET INPUT parameter value", -" ", -#ifdef CK_AUTODL -"SET INPUT AUTODOWNLOAD { ON, OFF }", -" Controls whether autodownloads are allowed during INPUT command execution.", -" ", -#endif /* CK_AUTODL */ -"SET INPUT BUFFER-LENGTH number-of-bytes", -" Removes the old INPUT buffer and creates a new one with the given length.", -" ", -"SET INPUT CANCELLATION { ON, OFF }", -" Whether an INPUT in progress can be can interrupted from the keyboard.", -" ", -"SET INPUT CASE { IGNORE, OBSERVE }", -" Tells whether alphabetic case is to be significant in string comparisons.", -" This setting is local to the current macro or command file, and is", -" inherited by subordinate macros and take files.", -" ", -"SET INPUT ECHO { ON, OFF }", -" Tells whether to display arriving characters read by INPUT on the screen.", -" ", -#ifdef CKFLOAT -"SET INPUT SCALE-FACTOR ", -" A number to multiply all INPUT timeouts by, which may include a fractional", -" part, e.g. 2.5. All INPUT commands that specify a timeout in seconds", -" (as opposed to a specific time of day) have their time limit adjusted", -" automatically by this factor, which is also available in the built-in", -" read-only variable \\v(inscale). The default value is 1.0.", -" ", - -#endif /* CKFLOAT */ - -"SET INPUT SILENCE ", -" The maximum number to seconds of silence (no input at all) before the", -" INPUT command times out, 0 for no maximum.", -" ", -#ifdef OS2 -"SET INPUT TERMINAL { ON, OFF }", -" Determines whether the data received during an INPUT command is displayed", -" in the terminal window. Default is ON.", -" ", -#endif /* OS2 */ -"SET INPUT TIMEOUT-ACTION { PROCEED, QUIT }", -" Tells whether to proceed or quit from a script program if an INPUT command", -" fails. PROCEED (default) allows use of IF SUCCESS / IF FAILURE commands.", -" This setting is local to the current macro or command file, and is", -" inherited by subordinate macros and take files.", -"" }; - -static char *hxyfunc[] = { -"SET FUNCTION DIAGNOSTICS { ON, OFF }", -" Whether to issue diagnostic messages for illegal function calls and", -" references to nonexistent built-in variables. ON by default.", -" ", -"SET FUNCTION ERROR { ON, OFF }", -" Whether an illegal function call or reference to a nonexistent built-in", -" variable should cause a command to fail. OFF by default.", -"" }; -#endif /* NOSPL */ - -static char *hxyxyz[] = { -#ifdef CK_XYZ -#ifdef XYZ_INTERNAL - -/* This is for built-in protocols */ - -"Syntax: SET PROTOCOL { KERMIT, XMODEM, YMODEM, ZMODEM } [ s1 s2 [ s3 ] ]", -" Selects protocol to use for transferring files. String s1 is a command to", -" send to the remote host prior to SENDing files with this protocol in", -" binary mode; string s2 is the same thing but for text mode. Use \"%\" in", -" any of these strings to represent the filename(s). If the protocol is", -" KERMIT, you may also specify a string s3, the command to start a Kermit", -" server on the remote host when you give a GET, REGET, REMOTE, or other", -" client command. Use { braces } if any command contains spaces. Examples:", -" ", -" set proto xmodem {rx %s} {rx -a %s}", -" set proto kermit {kermit -YQir} {kermit -YQTr} {kermit -YQx}", - -#else /* This is for when non-Kermit protocols are external */ - -"Syntax: \ -SET PROTOCOL { KERMIT, XMODEM, YMODEM, ZMODEM } [ s1 s2 s3 s4 s5 s6 ]", -" Selects protocol to use for transferring files. s1 and s2 are commands to", -" output prior to SENDing with this protocol, to automatically start the", -" RECEIVE process on the other end in binary or text mode, respectively.", -" If the protocol is KERMIT, s3 is the command to start a Kermit server on", -" the remote computer, and there are no s4-s6 commands. Otherwise, s3 and", -" s4 are commands used on this computer for sending files with this protocol", -" in binary or text mode, respectively; s5 and s6 are the commands for", -" receiving files with this protocol. Use \"%s\" in any of these strings", -" to represent the filename(s). Use { braces } if any command contains", -" spaces. Examples:", -" ", -" set proto kermit {kermit -YQir} {kermit -YQTr} {kermit -YQx}", -" set proto ymodem rb {rb -a} {sb %s} {sb -a %s} rb rb", -" ", -"External protocols require REDIRECT and external file transfer programs that", -"use redirectable standard input/output.", -#endif /* XYZ_INTERNAL */ -#else -"Syntax: \ -SET PROTOCOL KERMIT [ s1 [ s2 [ s3 ] ] ]", -" Lets you specify the autoupload binary, autoupload text, and autoserver", -" command strings to be sent to the remote system in advance of any SEND", -" or GET commands. By default these are \"kermit -ir\", \"kermit -r\", and", -" \"kermit -x\". Use { braces } around any command that contains spaces.", -" Example:", -" ", -" set proto kermit {kermit -Yir} {kermit -YTr} {kermit -Yx}", -#endif /* CK_XYZ */ -" ", -" SHOW PROTOCOL displays the current settings.", -""}; - -static char *hmxxbye = "Syntax: BYE\n\ - Shut down and log out a remote Kermit server"; - -#ifdef CK_PERMS -#ifdef UNIX -static char *hmxxchmod[] = { -"Syntax: CHMOD [ switches ] code filespec", -" UNIX only. Changes permissions of the given file(s) to the given code,", -" which must be an octal number such as 664 or 775. Optional switches:", -" ", -" /FILES Only change permissions of regular files.", -" /DIRECTORIES Only change permissions of directory files.", -" /TYPE:BINARY Only change permissions of binary files.", -" /TYPE:TEXT Only change permissions of text files.", -" /DOTFILES Include files whose names begin with dot (.).", -" /RECURSIVE Change permissions in subdirectories too.", -" /LIST List each file (synonym: /VERBOSE).", -" /NOLIST Operate silently (synonym: /QUIET).", -" /PAGE When listing, pause at end of each screen (implies /LIST).", -" /NOPAGE When listing, don't pause at end of each screen.", -" /SIMULATE Show what would be done but don't actually do it.", -"" -}; -#endif /* UNIX */ -#endif /* CK_PERMS */ - -#ifndef NOSPL -#ifndef NOSEXP -static char *hmxxsexp[] = { -"Syntax: (operation operand [ operand [ ... ] ])", -" ", -" C-Kermit includes a simple LISP-like S-Expression parser operating on", -" numbers only. An S-Expression is always enclosed in parentheses. The", -" parentheses can contain (a) a number, (b) a variable, (c) a function that", -" returns a number, or (d) an operator followed by one or more operands.", -" Operands can be any of (a) through (c) or an S-Expression. Numbers can be", -" integers or floating-point. Any operand that is not a number and does not", -" start with backslash (\\) is treated as a Kermit macro name. Operators:", -" ", -" Operator Action Example Value", -" EVAL (.) Returns the contained value (6) 6", -" QUOTE (') Inhibits evaluation of following value (quote a) a", -" SETQ Assigns a value to a global variable (setq a 2) 2", -" LET Assigns a value to a local variable (let b -1.3) -1.3", -" + Adds all operands (1 or more) (+ a b) 0.7", -" - Subtracts all operands (1 or more) (- 9 5 2 1) 1", -" * Multiplies all operands (1 or more) (* a (+ b 1) 3) -1.8", -" / Divides all operands (1 or more) (/ b a 2) -0.325", -" ^ Raise given number to given power (^ 3 2) 9", -" ++ Increments a variable (++ a 1.2) 3.2", -" -- Decrements a variable (-- a) 1", -" ABS Absolute value of 1 operand (abs (* a b 3)) 7.8", -" MAX Maximum of all operands (1 or more) (max 1 2 3 4) 4", -" MIN Minimum of all operands (1 or more) (min 1 2 3 4) 1", -" MOD Modulus of all operands (1 or more) (mod 7 4 2) 1", -" TRUNCATE Integer part of floating-point operand (truncate 1.333) 1", -" CEILING Ceiling of floating-point operand (ceiling 1.25) 2", -" FLOOR Floor of floating-point operand (floor 1.25) 1", -" ROUND Operand rounded to nearest integer (round 1.75) 2", -" SQRT Square root of 1 operand (sqrt 2) 1.414..", -" EXP e (2.71828..) to the given power (exp -1) 0.367..", -" SIN Sine of angle expressed in radians (sin (/ pi 2)) 1.0", -" COS Cosine of given number (cos pi) -1.0", -" TAN Tangent of given number (tan pi) 0.0", -" LOG Natural log (base e) of given number (log 2.7183) 1.000..", -" LOG10 Log base 10 of given number (log10 1000) 3.0", -" ", -"Predicate operators return 0 if false, 1 if true, and if it is the outermost", -"operator, sets SUCCESS or FAILURE accordingly:", -" ", -" < Operands in strictly descending order (< 6 5 4 3 2 1) 1", -" <= Operands in descending order (<= 6 6 5 4 3 2) 1", -" != Operands are not equal (!= 1 1 1.0) 0", -" = (==) All operands are equal (= 3 3 3 3) 1", -" > Operands in strictly ascending order (> 1 2 3 4 5 6) 1", -" >= Operands in ascending order (> 1 1 2 3 4 5) 1", -" AND (&&) Operands are all true (and 1 1 1 1 0) 0", -" OR (||) At least one operand is true (or 1 1 1 1 0) 1", -" XOR Logical Exclusive OR (xor 3 1) 0", -" NOT (!) Reverses truth value of operand (not 3) 0", -" ", -"Bit-oriented operators:", -" ", -" & Bitwise AND (& 7 2) 2", -" | Bitwise OR (| 1 2 3 4) 7", -" # Bitwise Exclusive OR (# 3 1) 2", -" ~ Reverses all bits (~ 3) -4", -" ", -"Operators that work on truth values:", -" ", -" IF Conditional evaluation (if (1) 2 3) 2", -" ", -"Operators can also be names of Kermit macros that return either numeric", -"values or no value at all.", -" ", -"Built-in constants are:", -" ", -" t True (1)", -" nil False (empty)", -" pi The value of Pi (3.1415926...)", -" ", -"If SET SEXPRESSION ECHO-RESULT is AUTO (the default), the value of the", -"S-Expression is printed if the S-Expression is given at top level; if ON,", -"it is printed at any level; if OFF it is not printed. At all levels, the", -"variable \\v(sexpression) is set to the most recent S-Expression, and", -"\\v(svalue) is set to its value. You can use the \\fsexpresssion() function", -"to evaluate an S-Expression anywhere in a Kermit command.", -"" -}; -#endif /* NOSEXP */ -#endif /* NOSPL */ - -static char *hmxxgrep[] = { -#ifdef UNIXOROSK -"Syntax: GREP [ options ] pattern filespec", -#else -"Syntax: FIND [ options ] pattern filespec", -#endif /* UNIXOROSK */ -" Searches through the given file or files for the given character string", -" or pattern. In the normal case, all lines containing any text that matches" -, -" the pattern are printed. Pattern syntax is as described in HELP PATTERNS", -" except that '*' is implied at the beginning unless the pattern starts with", -" '^' and also at the end unless the pattern ends with '$'. Therefore,", -" \"grep something *.txt\" lists all lines in all *.txt files that contain", -" the word \"something\", but \"grep ^something *.txt\" lists only the lines", -" that START with \"something\". The command succeeds if any of the given", -" files contained any lines that match the pattern, otherwise it fails.", -#ifdef UNIXOROSK -" Synonym: FIND.", -#else -" Synonym: GREP.", -#endif /* UNIXOROSK */ -" ", -"File selection options:", -" /NOBACKUPFILES", -" Excludes backup files (like oofa.txt.~3~) from the search.", -" /DOTFILES", -" Includes files whose names start with dot (.) in the search.", -" /NODOTFILES", -" Excludes files whose names start with dot (.) from the search.", -#ifdef RECURSIVE -" /RECURSIVE", -" Searches through files in subdirectories too.", -#endif /* RECURSIVE */ -" /TYPE:TEXT", -" Search only text files (requires FILE SCAN ON).", -" /TYPE:BINARY", -" Search only binary files (requires FILE SCAN ON).", -" ", -"Pattern-matching options:", -" /NOCASE", -" Ignores case of letters (ASCII only) when comparing.", -" /NOMATCH", -" Searches for lines that do NOT match the pattern.", -" ", -"Display options:", -" /COUNT:variable-name", -" For each file, prints only the filename and a count of matching lines", -" and assigns the total match count to the variable, if one is given.", -" /NAMEONLY", -" Prints the name of each file that contains at least one matching line,", -" one name per line, rather than showing each matching line.", -" /NOLIST", -" Doesn't print anything (but sets SUCCESS or FAILURE appropriately).", -" /LINENUMBERS", -" Precedes each file line by its line number within the file.", -" /PAGE", -" Pauses after each screenful.", -" /NOPAGE", -" Doesn't pause after each screenful.", -" /OUTPUT:name", -" Sends results to the given file. If this switch is omitted, the", -" results appear on your screen. This switch overrides any express or", -" implied /PAGE switch.", -""}; - -static char *hmxxdir[] = { -#ifdef DOMYDIR -"Syntax: DIRECTORY [ switches ] [ filespec [ filespec [ ... ] ] ]", -#ifdef LOCUS -" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,", -" this command is equivalent to REMOTE DIRECTORY (RDIR). Otherwise:", -" ", -#endif /* LOCUS */ -" Lists local files. The filespec may be a filename, possibly containing", -" wildcard characters, or a directory name. If no filespec is given, all", -" files in the current directory are listed. If a directory name is given,", -" all the files in it are listed. Multiple filespecs can be given.", -" Optional switches:", -" ", -" /BRIEF List filenames only.", -#ifdef CK_PERMS -" /VERBOSE + Also list permissions, size, and date.", -#else -" /VERBOSE + Also list date and size.", -#endif /* CK_PERMS */ -" /FILES Show files but not directories.", -" /DIRECTORIES Show directories but not files.", -" /ALL + Show both files and directories.", -" /ARRAY:&a Store file list in specified array (e.g. \\%a[]).", -" /PAGE Pause after each screenful.", -" /NOPAGE Don't pause after each screenful.", -#ifdef UNIXOROSK -" /DOTFILES Include files whose names start with dot (period).", -" /NODOTFILES + Don't include files whose names start with dot.", -" /FOLLOWLINKS Follow symbolic links.", -" /NOFOLLOWLINKS + Don't follow symbolic links.", -" /BACKUP + Include backup files (names end with .~n~).", -" /NOBACKUPFILES Don't include backup files.", -#endif /* UNIXOROSK */ -" /OUTPUT:file Store directory listing in the given file.", -" /HEADING Include heading and summary.", -" /NOHEADING + Don't include heading or summary.", -" /SUMMARY Print only count and total size of matching files.", -" /XFERMODE Show pattern-based transfer mode (T=Text, B=Binary).", -" /TYPE: Show only files of the specified type (text or binary).", -" /MESSAGE:text Add brief message to each listing line.", -" /NOMESSAGE + Don't add message to each listing line.", -" /NOXFERMODE + Don't show pattern-based transfer mode", -" /ISODATE + In verbose listings, show date in ISO 8061 format.", -" /ENGLISHDATE In verbose listings, show date in \"English\" format.", -#ifdef RECURSIVE -" /RECURSIVE Descend through subdirectories.", -" /NORECURSIVE + Don't descend through subdirectories.", -#endif /* RECURSIVE */ -" /SORT:key Sort by key, NAME, DATE, or SIZE; default key is NAME.", -" /NOSORT + Don't sort.", -" /ASCENDING + If sorting, sort in ascending order.", -" /REVERSE If sorting, sort in reverse order.", -" ", -"Factory defaults are marked with +. Default for paging depends on SET", -"COMMAND MORE-PROMPTING. Use SET OPTIONS DIRECTORY [ switches ] to change", -"defaults; use SHOW OPTIONS to display customized defaults.", -#else -"Syntax: DIRECTORY [ filespec ]", -" Lists the specified file or files. If no filespec is given, all files", -" in the current directory are listed.", -#endif /* DOMYDIR */ -""}; - - -#ifndef NOSPL -static char *hmxxkcd[] = { -"Syntax: KCD symbolic-directory-name", -" Kermit Change Directory: Like CD (q.v.) but (a) always acts locally, and", -" (b) takes a symbolic directory name rather than an actual directory name.", -" The symbolic names correspond to Kermit's directory-valued built-in", -" variables, such as \\v(download), \\v(exedir), and so on. Here's the list:" -, -" ", -#ifdef NT -" appdata Your personal Kermit 95 application data directory", -" common Kermit 95's application data directory for all users", -" desktop Your Windows desktop", -#endif /* NT */ -" download Your download directory (if any)", -#ifdef OS2ORUNIX -" exedir The directory where the Kermit executable resides", -#endif /* OS2ORUNIX */ -" home Your home, login, or default directory", -" inidir The directory where Kermit's initialization was found", -#ifdef UNIX -" lockdir The UNIX UUCP lockfile directory on this computer", -#endif /* UNIX */ -#ifdef NT -" personal Your \"My Documents\" directory", -#endif /* NT */ -" startup Your current directory at the time Kermit started", -" textdir The directory where Kermit text files reside, if any", -" tmpdir Your temporary directory", -" ", -" Also see CD, SET FILE DOWNLOAD, SET TEMP-DIRECTORY.", -"" -}; -#endif /* NOSPL */ - -static char *hmxxcwd[] = { -#ifdef LOCUS -" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,", -" this command is equivalent to REMOTE CD (RCD). Otherwise:", -" ", -#endif /* LOCUS */ -#ifdef vms -"Syntax: CD [ directory or device:directory ]", -" Change Working Directory. Equivalent to VMS SET DEFAULT command.", -#else -#ifdef datageneral -"Change Working Directory, equivalent to AOS/VS 'dir' command.", -#else -#ifdef OS2 -"Syntax: CD [ disk or directory name ]", -" Change Disk or Directory. If a disk or directory name is not specified,", -" your current directory becomes the one specified by HOME environment", -" variable, if any. A disk letter must be followed by a colon.", -#else -"Syntax: CD [ directory name ]", -" Change Directory. Changes your current, working, default directory to the", -" one given, so that future non-absolute filename references are relative to", -" this directory. If the directory name is omitted, your home (login)", -" directory is supplied.", -#endif /* OS2 */ -#endif /* datageneral */ -#endif /* vms */ -" C-Kermit's default prompt shows your current directory.", -" Synonyms: LCD, CWD.", -#ifdef LOCUS -" Also see: SET LOCUS, PWD, CDUP, BACK, REMOTE CD (RCD), SET CD, SET PROMPT.", -#else -" Also see: PWD, CDUP, BACK, REMOTE CD (RCD), SET CD, SET PROMPT.", -#endif /* LOCUS */ -#ifndef NOSPL -" And see: HELP KCD.", -#endif /* NOSPL */ -" Relevant environment variables: CDPATH, HOME.", -""}; - -static char *hmxxdel[] = { -"Syntax: DELETE [ switches... ] filespec", -#ifdef LOCUS -" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,", -" this command is equivalent to REMOTE DELETE (RDELETE). Otherwise:", -" ", -#endif /* LOCUS */ -" Deletes a file or files on the computer where C-Kermit is running.", -" The filespec may denote a single file or can include wildcard characters", -" to match multiple files. RM is a synonym for DELETE. Switches include:", -" ", -"/AFTER:date-time", -#ifdef VMS -" Specifies that only those files created after the given date-time are", -#else -" Specifies that only those files modified after the given date-time are", -#endif /* VMS */ -" to be deleted. HELP DATE for info about date-time formats.", -" ", -"/BEFORE:date-time", -#ifdef VMS -" Specifies that only those files modified before the given date-time", -#else -" Specifies that only those files modified before the given date-time", -#endif /* VMS */ -" are to be deleted.", -" ", -"/NOT-AFTER:date-time", -#ifdef VMS -" Specifies that only those files modified at or before the given date-time", -#else -" Specifies that only those files modified at or before the given date-time", -#endif /* VMS */ -" are to be deleted.", -" ", -"/NOT-BEFORE:date-time", -#ifdef VMS -" Specifies that only those files modified at or after the given date-time", -#else -" Specifies that only those files modified at or after the given date-time", -#endif /* VMS */ -" are to be deleted.", -" ", -"/LARGER-THAN:number", -" Specifies that only those files longer than the given number of bytes are", -" to be deleted.", -" ", -"/SMALLER-THAN:number", -" Specifies that only those files smaller than the given number of bytes are", -" to be sent.", -" ", -"/EXCEPT:pattern", -" Specifies that any files whose names match the pattern, which can be a", -" regular filename or may contain wildcards, are not to be deleted. To", -" specify multiple patterns (up to 8), use outer braces around the group", -" and inner braces around each pattern:", -" ", -" /EXCEPT:{{pattern1}{pattern2}...}", -" ", -#ifdef UNIXOROSK -"/DOTFILES", -" Include (delete) files whose names begin with \".\".", -" ", -"/NODOTFILES", -" Skip (don't delete) files whose names begin with \".\".", -" ", -#endif /* UNIXOROSK */ -"/TYPE:TEXT", -" Delete only regular text files (requires FILE SCAN ON)", -" ", -"/TYPE:BINARY", -" Delete only regular binary files (requires FILE SCAN ON)", -" ", -"/DIRECTORIES", -" Include directories. If this switch is not given, only regular files", -" are deleted. If it is given, Kermit attempts to delete any directories", -" that match the given file specification, which succeeds only if the", -" directory is empty.", -" ", -#ifdef RECURSIVE -"/RECURSIVE", -" The DELETE command applies to the entire directory tree rooted in the", -" current or specified directory. When the /DIRECTORIES switch is also", -" given, Kermit deletes all the (matching) files in each directory before", -" attempting to delete the directory itself.", -" ", -#endif /* RECURSIVE */ -#ifdef UNIX -#ifdef RECURSIVE -"/ALL", -" This is a shortcut for /RECURSIVE /DIRECTORIES /DOTFILES.", -#else -"/ALL", -" This is a shortcut for /DIRECTORIES /DOTFILES.", -#endif /* RECURSIVE */ -#else /* !UNIX */ -#ifdef RECURSIVE -"/ALL", -" This is a shortcut for /RECURSIVE /DIRECTORIES.", -#else -"/ALL", -" This is a synonym for /DIRECTORIES.", -#endif /* RECURSIVE */ -#endif /* UNIX */ -" ", -"/LIST", -" List each file and tell whether it was deleted. Synonyms: /LOG, /VERBOSE.", -" ", -"/NOLIST", -" Don't list files while deleting. Synonyms: /NOLOG, /QUIET.", -" ", -"/HEADING", -" Print heading and summary information.", -" ", -"/NOHEADING", -" Don't print heading and summary information.", -" ", -"/SUMMARY", -" Like /HEADING /NOLIST, but only prints the summary line.", -" ", -"/PAGE", -" If listing, pause after each screenful.", -" ", -"/NOPAGE", -" Don't pause after each screenful.", -" ", -"/ASK", -" Interactively ask permission to delete each file. Reply Yes or OK to", -" delete it, No not to delete it, Quit to cancel the DELETE command, and", -" Go to go ahead and delete all the rest of the files without asking.", -" ", -"/NOASK", -" Delete files without asking permission.", -" ", -"/SIMULATE", -" Preview files selected for deletion without actually deleting them.", -" Implies /LIST.", -" ", -"Use SET OPTIONS DELETE to make selected switches effective for every DELETE", -"command \ -unless you override them; use SHOW OPTIONS to see selections currently", -#ifdef LOCUS -"in effect. Also see HELP SET LOCUS, HELP PURGE, HELP WILDCARD.", -#else -"in effect. Also see HELP PURGE, HELP WILDCARD.", -#endif /* LOCUS */ -""}; - -#ifndef NOHTTP -static char *hmxxhttp[] = { -"Syntax:", -#ifdef CK_SSL -"HTTP [ ] OPEN [{ /SSL, /TLS }] ", -#else -"HTTP [ ] OPEN ", -#endif /*CK_SSL */ -" Instructs Kermit to open a new connection for HTTP communication with", -" the specified host on the specified port. The default port is \"http\".", -#ifdef CK_SSL -" If /SSL or /TLS are specified or if the service is \"https\" or port 443,", -" a secure connection will be established using the current authentication", -" settings. See HELP SET AUTH for details.", -#endif /* CK_SSL */ -" If are specified, they are applied to all subsequent HTTP", -" actions (GET, PUT, ...) until an HTTP CLOSE command is executed.", -" A URL can be included in place of the hostname and service or port.", -" ", -"HTTP CLOSE", -" Instructs Kermit to close any open HTTP connection and clear any saved", -" switch values.", -" ", -"HTTP [ ] CONNECT [:]", -" Instructs the server to establish a connection with the specified host", -" and to redirect all data transmitted between Kermit and the host for the", -" life of the connection.", -" ", -"HTTP [ ] GET [ ]", -" Retrieves the named file on the currently open HTTP connection. The", -" default local filename is the same as the remote filename, but with any", -" path stripped. If you want the file to be displayed on the screen instead", -" of stored on disk, include the /TOSCREEN switch and omit the local", -" filename. If you give a URL instead of a remote filename, this commands", -" opens the connection, GETs the file, and closes the connection; the same", -" is true for the remaining HTTP commands for which you can specify a", -" remote filename, directory name, or path.", -" ", -"HTTP [ ] HEAD [ ]", -" Like GET except without actually getting the file; instead it gets only", -" the headers, storing them into the given file (if a local filename is", -" specified), one line per header item as shown in the /ARRAY: switch", -" description.", -" ", -"HTTP [ ] INDEX [ ]", -" Retrieves the file listing for the given server directory.", -" NOTE: This command is not supported by most Web servers, and even when", -" the server understand it, there is no stardard response format.", -" ", -"HTTP [ ] POST [ /MIME-TYPE: ] ", -" [ ]", -" Used to send a response as if it were sent from a form. The data to be", -" posted must be read from a file.", -" ", -"HTTP [ ] PUT [ /MIME-TYPE: ] ", -" [ ]", -" Uploads the given local file to server file. If the remote filename is", -" omitted, the local name is used, but with any path stripped.", -" ", -"HTTP [ ] DELETE ", -" Instructs the server to delete the specified filename.", -" ", -"where are:", -"/AGENT:", -" Identifies the client to the server; \"C-Kermit\" or \"Kermit-95\"", -" by default.", -" ", -"/HEADER:", -" Used for specifying any optional headers. A list of headers is provided", -" using braces for grouping:", -" ", -" /HEADER:{{:}{:}...}", -" ", -" For a listing of valid value and formats see RFC 1945:", -" \"Hypertext Transfer Protocol -- HTTP/1.0\". A maximum of eight headers", -" may be specified.", -" ", -"/TOSCREEN", -" Display server responses on the screen.", -" ", -"/USER:", -" In case a page requires a username for access.", -" ", -"/PASSWORD:", -" In case a page requires a password for access.", -" ", -"/ARRAY:", -" Tells Kermit to store the response headers in the given array, one line", -" per element. The array need not be declared in advance. Example:", -" ", -" http /array:c get kermit/index.html", -" show array c", -" Dimension = 9", -" 1. Date: Fri, 26 Nov 1999 23:12:22 GMT", -" 2. Server: Apache/1.3.4 (Unix)", -" 3. Last-Modified: Mon, 06 Sep 1999 22:35:58 GMT", -" 4. ETag: \"bc049-f72-37d441ce\"", -" 5. Accept-Ranges: bytes", -" 6. Content-Length: 3954", -" 7. Connection: close ", -" 8. Content-Type: text/html", -" ", -"As you can see, the header lines are like MIME e-mail header lines:", -"identifier, colon, value. The /ARRAY switch is the only method available", -"to a script to process the server responses for a POST or PUT command.", -" ", -"" -}; -#endif /* NOHTTP */ - -#ifdef CK_KERBEROS -static char *hmxxauth[] = { -"Syntax:", -"AUTHENTICATE { KERBEROS4, KERBEROS5 [ switches ] } [ switches ]", -" Obtains or destroys Kerberos tickets and lists information about them.", -" Actions are INITIALIZE, DESTROY, and LIST-CREDENTIALS. KERBEROS4 can be", -" abbreviated K4 or KRB4; KERBEROS5 can be abbreviated K5 or KRB5. Use ? to", -" see which keywords, switches, or other quantities are valid at each point", -" in the command.", -" ", -" The actions are INITIALIZE, DESTROY, and LIST-CREDENTIALS:", -" ", -" AUTH { K4, K5 } { INITIALIZE [switches], DESTROY,", -" LIST-CREDENTIALS [switches] }", -" ", -" The INITIALIZE action is the most complex, and its format is different", -" for Kerberos 4 and Kerberos 5. The format for Kerberos 4 is:", -" ", -" AUTH K4 INITIALIZE [ /INSTANCE: /LIFETIME: -", -" /PASSWORD: /PREAUTH /REALM: ]", -" ", -" All switches are optional. Kerberos 4 INITIALIZE switches are:", -" ", -" /INSTANCE:", -" Allows an Instance (such as a hostname) to be specified.", -" ", -" /LIFETIME:", -" Specifies the requested lifetime in minutes for the ticket. If no", -" lifetime is specified, 600 minutes is used. If the lifetime is greater", -" than the maximum supported by the ticket granting service, the resulting", -" lifetime is shortened accordingly.", -" ", -" /NOT-PREAUTH", -" Instructs Kermit to send a ticket getting ticket (TGT) request to the", -" KDC without any preauthentication data.", -" ", -" /PASSWORD:", -" Allows a password to be included on the command line or in a script", -" file. If no /PASSWORD switch is included, you are prompted on a separate" -, -" line. The password switch is provided on a use-at-your-own-risk basis", -" for use in automated scripts. WARNING: Passwords should not be stored in" -, -" files.", -" ", -" /PREAUTH", -" Instructs Kermit to send a preauthenticated Ticket-Getting Ticket (TGT)", -" request to the KDC instead of a plaintext request. The default when", -" supported by the Kerberos libraries.", -" ", -" /REALM:", -" Allows a realm to be specified (overriding the default realm).", -" ", -" ", -" Your identity in the given or default Kerberos realm, of the form:", -" userid[.instance[.instance]]@[realm] ", -" Can be omitted if it is the same as your username or SET LOGIN USERID", -" value on the client system.", -" ", -" The format for Kerberos 5 is as follows:", -" ", -" AUTH K5 [ /CACHE: ] { INITIALIZE [ switches ], DESTROY,", -" LIST-CREDENTIALS ...}", -" ", -"The INITIALIZE command for Kerberos 5 can include a number of switches;", -"all are optional:", -" ", -"AUTH K5 [ /CACHE: ] INITITIALIZE [ /ADDRESSES:", -" /FORWARDABLE /KERBEROS4 /LIFETIME: /PASSWORD:", -" /POSTDATE: /PROXIABLE /REALM: /RENEW /RENEWABLE:", -" /SERVICE: /VALIDATE ]", -" ", -" All Kerberos 5 INITIALIZE switches are optional:", -" ", -" /ADDRESSES:{list of ip-addresses}", -" Specifies a list of IP addresses that should be placed in the Ticket", -" Getting Ticket in addition to the local machine addresses.", -" ", -" /FORWARDABLE", -" Requests forwardable tickets.", -" ", -" /INSTANCE:", -" Allows an Instance (such as a hostname) to be specified.", -" ", -" /KERBEROS4", -" Instructs Kermit to get Kerberos 4 tickets in addition to Kerberos 5", -" tickets. If Kerberos 5 tickets are not supported by the server, a", -" mild warning is printed and Kerberos 4 tickets are requested.", -" ", -" /LIFETIME:", -" Specifies the requested lifetime in minutes for the ticket. If no", -" lifetime is specified, 600 minutes is used. If the lifetime is greater", -" than the maximum supported by the ticket granting service, the resulting", -" lifetime is shortened.", -" ", -" /NO-KERBEROS4", -" Instructs Kermit to not attempt to retrieve Kerberos 4 credentials.", -" ", -" /NOT-FORWARDABLE", -" Requests non-forwardable tickets.", -" ", -" /NOT-PROXIABLE", -" Requests non-proxiable tickets.", -" ", -" /PASSWORD:", -" Allows a password to be included on the command line or in a script", -" file. If no /PASSWORD switch is included, you are prompted on a separate" -, -" line. The password switch is provided on a use-at-your-own-risk basis", -" for use in automated scripts. WARNING: Passwords should not be stored in" -, -" files.", -" ", -" /POSTDATE:", -" Requests a postdated ticket, valid starting at . Postdated", -" tickets are issued with the invalid flag set, and need to be fed back to", -" the KDC before use with the /VALIDATE switch. Type HELP DATE for info", -" on date-time formats.", -" ", -" /PROXIABLE", -" Requests proxiable tickets.", -" ", -" /REALM:", -" Allows an alternative realm to be specified.", -" ", -" /RENEW", -" Requests renewal of a renewable Ticket-Granting Ticket. Note that ", -" an expired ticket cannot be renewed even if it is within its renewable ", -" lifetime.", -" ", -" /RENEWABLE:", -" Requests renewable tickets, with a total lifetime of minutes.", -" ", -" /SERVICE:", -" Allows a service other than the ticket granting service to be specified.", -" ", -" /VALIDATE", -" Requests that the Ticket Granting Ticket in the cache (with the invalid", -" flag set) be passed to the KDC for validation. If the ticket is within", -" its requested time range, the cache is replaced with the validated", -" ticket.", -" ", -" ", -" Your identity in the given or default Kerberos realm, of the form:", -" userid[/instance][@realm] ", -" Can be omitted if it is the same as your username or SET LOGIN USERID", -" value on the client system.", -" ", -" Note: Kerberos 5 always attempts to retrieve a Ticket-Getting Ticket (TGT)", -" using the preauthenticated TGT request.", -" ", -" AUTHORIZE K5 LIST-CREDENTIALS [ /ADDRESSES /FLAGS /ENCRYPTION ]", -" ", -" Shows start time, expiration time, service or principal name, plus", -" the following additional information depending the switches:", -" ", -" /ADDRESSES displays the hostnames and/or IP addresses embedded within", -" the tickets.", -" ", -" /FLAGS provides the following information (if applicable) for each ticket:", -" F - Ticket is Forwardable", -" f - Ticket was Forwarded", -" P - Ticket is Proxiable", -" p - Ticket is a Proxy", -" D - Ticket may be Postdated", -" d - Ticket has been Postdated", -" i - Ticket is Invalid", -" R - Ticket is Renewable", -" I - Ticket is the Initial Ticket", -" H - Ticket has been authenticated by Hardware", -" A - Ticket has been Pre-authenticated", -" ", -" /ENCRYPTION displays the encryption used by each ticket (if applicable):", -" DES-CBC-CRC", -" DES-CBC-MD4", -" DES-CBC-MD5", -" DES3-CBC-SHA", -"" -}; -#endif /* CK_KERBEROS */ - -#ifndef NOCSETS -static char *hmxxassoc[] = { -"ASSOCIATE FILE-CHARACTER-SET ", -" Tells C-Kermit that whenever the given file-character set is selected, and", -" SEND CHARACTER-SET (q.v.) is AUTOMATIC, the given transfer character-set", -" is selected automatically.", -" ", -"ASSOCIATE XFER-CHARACTER-SET ", -" Tells C-Kermit that whenever the given transfer-character set is selected,", -" either by command or by an announcer attached to an incoming text file,", -" and SEND CHARACTER-SET is AUTOMATIC, the specified file character-set is", -" to be selected automatically. Synonym: ASSOCIATE TRANSFER-CHARACTER-SET.", -" ", -"Use SHOW ASSOCIATIONS to list the current character-set associations, and", -"SHOW CHARACTER-SETS to list the current settings.", -"" -}; -#endif /* NOCSETS */ - -static char *hmxxpat[] = { -"A \"pattern\" is notation used in a search string when searching through", -"text. C-Kermit uses three kinds of patterns: floating patterns, anchored", -"patterns, and wildcards. Wildcards are anchored patterns that are used to", -"match file names; type HELP WILDCARD to learn about them.", -" ", -"In a pattern, certain characters are special:", -" ", -"* Matches any sequence of zero or more characters. For example, \"k*t\"", -" matches all strings that start with \"k\" and end with \"t\" including", -" \"kt\", \"kit\", \"knight\", or \"kermit\".", -" ", -#ifdef VMS -"% Matches any single character. For example, \"k%%%%t\" matches all strings", -#else -"? Matches any single character. For example, \"k????t\" matches all strings", -#endif /* VMS */ -" that are exactly 6 characters long and start with \"k\" and end with", -#ifdef VMS -" with \"t\".", -#else -" with \"t\". When typing commands at the prompt, you must precede any", -" question mark to be used for matching by a backslash (\\) to override the", -" normal function of question mark, which is providing menus and file lists.", -#endif /* VMS */ -" ", -#ifdef OS2ORUNIX -#ifdef CKREGEX -"[abc]", -" Square brackets enclosing a list of characters matches any character in", -" the list. Example: h[aou]t matches hat, hot, and hut.", -" ", -"[a-z]", -" Square brackets enclosing a range of characters matches any character in", -" the range; a hyphen (-) separates the low and high elements of the range.", -" For example, [a-z] matches any character from a to z.", -" ", -"[acdm-z]", -" Lists and ranges may be combined. This example matches a, c, d, or any", -" letter from m through z.", -" ", -"{string1,string2,...}", -" Braces enclose a list of strings to be matched. For example:", -" ker{mit,nel,beros} matches kermit, kernel, and kerberos. The strings", -" may themselves contain *, ?, [abc], [a-z], or other lists of strings.", -#endif /* CKREGEX */ -#endif /* OS2ORUNIX */ -#ifndef NOSPL -" ", -"To force a special pattern character to be taken literally, precede it with", -"a backslash, e.g. [a\\-z] matches a, hyphen, and z rather than a through z.", -" ", -"A floating pattern can also include the following special characters:", -" ", -"^ (First character of pattern) Anchors the pattern at the beginning.", -"$ (Last character of pattern) Anchors the pattern at the end.", -" ", -"If a floating pattern does not start with \"^\", the pattern can match", -"anywhere in the string instead of only at the beginning; in other words, a", -"leading \"*\" is assumed. Similarly, if the pattern doesn't end with \"$\",", -"a trailing \"*\" is assumed.", -" ", -"The following commands and functions use floating patterns:", -" GREP [ ] ", -" TYPE /MATCH: ", -" \\farraylook(,)", -" \\fsearch(,[,])", -" \\frsearch(,[,])", -" The /EXCEPT: clause in SEND, GET, DELETE, etc.", -" ", -"Example:", -" \\fsearch(abc,xxabcxxx) succeeds because xxabcxx contains abc.", -" \\fsearch(^abc,xxabcxx) fails because xxabcxx does not start with abc.", -" ", -"All other commands and functions that use patterns use anchored patterns,", -"meaning that ^ and $ are not treated specially, and * is not assumed at the", -"beginning or end of the pattern. This is true mainly of filename patterns", -"(wildcards), since you would not want a command like \"delete x\" to delete", -"all files whose names contained \"x\"!", -" ", -"You can use anchored patterns not only in filenames, but also in SWITCH", -"case labels, in the INPUT and MINPUT commands, and in file binary- and", -"text-patterns for filenames. The IF MATCH pattern is also anchored.", -#endif /* NOSPL */ -"" }; - -static char *hmxxwild[] = { - -"A \"wildcard\" is a notation used in a filename to match multiple files.", -"For example, in \"send *.txt\" the asterisk is a wildcard. Kermit commands", -"that accept filenames also accepts wildcards, except commands that are", -"allowed to operate on only one file, such as TRANSMIT.", -"This version of Kermit accepts the following wildcards:", -" ", -"* Matches any sequence of zero or more characters. For example, \"ck*.c\"", -" matches all files whose names start with \"ck\" and end with \".c\"", -" including \"ck.c\".", -" ", -#ifdef VMS -"% Matches any single character. For example, \"ck%.c\" matches all files", -#else -"? Matches any single character. For example, \"ck?.c\" matches all files", -#endif /* VMS */ -" whose names are exactly 5 characters long and start with \"ck\" and end", -#ifdef VMS -" with \".c\".", -#else -" with \".c\". When typing commands at the prompt, you must precede any", -" question mark to be used for matching by a backslash (\\) to override the", -" normal function of question mark, which is providing menus and file lists.", -#endif /* VMS */ -" ", -#ifdef OS2ORUNIX -#ifdef CKREGEX -"[abc]", -" Square brackets enclosing a list of characters matches any character in", -" the list. Example: ckuusr.[ch] matches ckuusr.c and ckuusr.h.", -" ", -"[a-z]", -" Square brackets enclosing a range of characters matches any character in", -" the range; a hyphen (-) separates the low and high elements of the range.", -" For example, [a-z] matches any character from a to z.", -" ", -"[acdm-z]", -" Lists and ranges may be combined. This example matches a, c, d, or any", -" letter from m through z.", -" ", -"{string1,string2,...}", -" Braces enclose a list of strings to be matched. For example:", -" ck{ufio,vcon,cmai}.c matches ckufio.c, ckvcon.c, or ckcmai.c. The strings", -" may themselves contain *, ?, [abc], [a-z], or other lists of strings.", -#endif /* CKREGEX */ -#endif /* OS2ORUNIX */ -" ", -"To force a special pattern character to be taken literally, precede it with", -"a backslash, e.g. [a\\-z] matches a, hyphen, and z rather than a through z.", -" ", -#ifndef NOSPL -"Similar notation can be used in general-purpose string matching. Type HELP", -"PATTERNS for details. Also see HELP SET MATCH.", -#endif /* NOSPL */ -"" }; - -#ifndef NOXFER -static char *hmxxfast[] = { -"FAST, CAUTIOUS, and ROBUST are predefined macros that set several", -"file-transfer parameters at once to achieve the desired file-transfer goal.", -"FAST chooses a large packet size, a large window size, and a fair amount of", -"control-character unprefixing at the risk of possible failure on some", -"connections. FAST is the default tuning in C-Kermit 7.0 and later. In case", -"FAST file transfers fail for you on a particular connection, try CAUTIOUS.", -"If that fails too, try ROBUST. You can also change the definitions of each", -"macro with the DEFINE command. To see the current definitions, type", -"\"show macro fast\", \"show macro cautious\", or \"show macro robust\".", -"" -}; -#endif /* NOXFER */ - -#ifdef VMS -static char * hmxxpurge[] = { -"Syntax: PURGE [ switches ] [ filespec ]", -" Runs the DCL PURGE command. Switches and filespec are not parsed or", -" verified by Kermit, but passed directly to DCL.", -"" -}; -#else -#ifdef CKPURGE -static char * hmxxpurge[] = { -"Syntax: PURGE [ switches ] [ filespec ]", -" Deletes backup files; that is, files whose names end in \".~n~\", where", -" n is a number. PURGE by itself deletes all backup files in the current", -" directory. Switches:", - -" ", -"/AFTER:date-time", -#ifdef VMS -" Specifies that only those files created after the given date-time are", -#else -" Specifies that only those files modified after the given date-time are", -#endif /* VMS */ -" to be purged. HELP DATE for info about date-time formats.", -" ", -"/BEFORE:date-time", -#ifdef VMS -" Specifies that only those files modified before the given date-time", -#else -" Specifies that only those files modified before the given date-time", -#endif /* VMS */ -" are to be purged.", -" ", -"/NOT-AFTER:date-time", -#ifdef VMS -" Specifies that only those files modified at or before the given date-time", -#else -" Specifies that only those files modified at or before the given date-time", -#endif /* VMS */ -" are to be purged.", -" ", -"/NOT-BEFORE:date-time", -#ifdef VMS -" Specifies that only those files modified at or after the given date-time", -#else -" Specifies that only those files modified at or after the given date-time", -#endif /* VMS */ -" are to be purged.", -" ", -"/LARGER-THAN:number", -" Specifies that only those files longer than the given number of bytes are", -" to be purged.", -" ", -"/SMALLER-THAN:number", -" Specifies that only those files smaller than the given number of bytes are", -" to be purged.", -" ", -"/EXCEPT:pattern", -" Specifies that any files whose names match the pattern, which can be a", -" regular filename or may contain wildcards, are not to be purged. To", -" specify multiple patterns (up to 8), use outer braces around the group", -" and inner braces around each pattern:", -" ", -" /EXCEPT:{{pattern1}{pattern2}...}", -" ", -#ifdef UNIXOROSK -"/DOTFILES", -" Include (purge) files whose names begin with \".\".", -" ", -"/NODOTFILES", -" Skip (don't purge) files whose names begin with \".\".", -" ", -#endif /* UNIXOROSK */ -#ifdef RECURSIVE -"/RECURSIVE", -" Descends through the current or specified directory tree.", -" ", -#endif /* RECURSIVE */ -"/KEEP:n", -" Retain the 'n' most recent (highest-numbered) backup files for each file.", -" By default, none are kept. If /KEEP is given without a number, 1 is used.", -" ", -"/LIST", -" Display each file as it is processed and say whether it is purged or kept.", -" Synonyms: /LOG, /VERBOSE.", -" ", -"/NOLIST", -" The PURGE command should operate silently (default).", -" Synonyms: /NOLOG, /QUIET.", -" ", -"/HEADING", -" Print heading and summary information.", -" ", -"/NOHEADING", -" Don't print heading and summary information.", -" ", -"/PAGE", -" When /LIST is in effect, pause at the end of each screenful, even if", -" COMMAND MORE-PROMPTING is OFF.", -" ", -"/NOPAGE", -" Don't pause, even if COMMAND MORE-PROMPTING is ON.", -" ", -"/ASK", -" Interactively ask permission to delete each backup file.", -" ", -"/NOASK", -" Purge backup files without asking permission.", -" ", -"/SIMULATE", -" Inhibits the actual deletion of files; use to preview which files would", -" actually be deleted. Implies /LIST.", -" ", -"Use SET OPTIONS PURGE [ switches ] to change defaults; use SHOW OPTIONS to", -"display customized defaults. Also see HELP DELETE, HELP WILDCARD.", -"" -}; -#endif /* CKPURGE */ -#endif /* VMS */ - -static char *hmxxclo[] = { -"Syntax: CLOSE [ item ]", -" Close the indicated item. The default item is CONNECTION, which is the", -" current SET LINE or SET HOST connection. The other items are:", -" ", -#ifdef CKLOGDIAL -" CX-LOG (connection log, opened with LOG CX)", -#endif /* CKLOGDIAL */ -#ifndef NOLOCAL -" SESSION-LOG (opened with LOG SESSION)", -#endif /* NOLOCAL */ -#ifdef TLOG -" TRANSACTION-LOG (opened with LOG TRANSACTIONS)", -#endif /* TLOG */ -" PACKET-LOG (opened with LOG PACKETS)", -#ifdef DEBUG -" DEBUG-LOG (opened with LOG DEBUG)", -#endif /* DEBUG */ -#ifndef NOSPL -" READ-FILE (opened with OPEN READ)", -" WRITE-FILE (opened with OPEN WRITE or OPEN APPEND)", -#endif /* NOSPL */ -" ", -"Type HELP LOG and HELP OPEN for further info.", -"" -}; - -#ifdef CKLEARN -static char * hmxxlearn[] = { -"Syntax: LEARN [ /ON /OFF /CLOSE ] [ filename ]", -" Records a login script. If you give a filename, the file is opened for", -" subsequent recording. If you don't give any switches, /ON is assumed.", -" /ON enables recording to the current file (if any); /OFF disables", -" recording. /CLOSE closes the current file (if any). After LEARN /CLOSE", -" or exit from Kermit, your script is available for execution by the TAKE", -" command.", -"" -}; -#endif /* CKLEARN */ - -#ifdef CK_MINPUT -static char *hmxxminp[] = { -"Syntax: MINPUT n [ string1 [ string2 [ ... ] ] ]", -"Example: MINPUT 5 Login: {Username: } {NO CARRIER} BUSY RING", -" For use in script programs. Waits up to n seconds for any one of the", -" strings to arrive on the communication device. If no strings are given,", -" the command waits for any character at all to arrive. Strings are", -" separated by spaces; use { braces } for grouping. If any of the strings", -" is encountered within the timeout interval, the command succeeds and the", -" \\v(minput) variable is set to the number of the string that was matched:", -" 1, 2, 3, etc. If none of the strings arrives, the command times out,", -" fails, and \\v(minput) is set to 0. If the timeout interval is 0 the", -" MINPUT command does not wait; i.e. the given text must already be", -" available for reading for the MINPUT command to succeed. If the interval", -" is negative, the MINPUT command waits forever.", -" ", -"Also see: INPUT, REINPUT, SET INPUT.", -"" }; -#endif /* CK_MINPUT */ - -#ifndef NOLOCAL -static char *hmxxcon[] = { -"Syntax: CONNECT (or C, or CQ) [ switches ]", -" Connect to a remote computer via the serial communications device given in", -#ifdef OS2 -" the most recent SET PORT command, or to the network host named in the most", -#else -" the most recent SET LINE command, or to the network host named in the most", -#endif /* OS2 */ -" recent SET HOST command. Type the escape character followed by C to get", -" back to the C-Kermit prompt, or followed by ? for a list of CONNECT-mode", -#ifdef OS2 -" escape commands. You can also assign the \\Kexit verb to the key or", -" key-combination of your choice; by default it is assigned to Alt-x.", -#else -" escape commands.", -" ", -"Include the /QUIETLY switch to suppress the informational message that", -"tells you how to escape back, etc. CQ is a synonym for CONNECT /QUIETLY.", -#endif /* OS2 */ -" ", -"Other switches include:", -#ifdef CK_TRIGGER -" ", -"/TRIGGER:string", -" One or more strings to look for that will cause automatic return to", -" command mode. To specify one string, just put it right after the", -" colon, e.g. \"/TRIGGER:Goodbye\". If the string contains any spaces, you", -" must enclose it in braces, e.g. \"/TRIGGER:{READY TO SEND...}\". To", -" specify more than one trigger, use the following format:", -" ", -" /TRIGGER:{{string1}{string2}...{stringn}}", -" ", -" Upon return from CONNECT mode, the variable \\v(trigger) is set to the", -" trigger string, if any, that was actually encountered. This value, like", -" all other CONNECT switches applies only to the CONNECT command with which", -" it is given, and overrides (temporarily) any global SET TERMINAL TRIGGER", -" string that might be in effect.", -#endif /* CK_TRIGGER */ -#ifdef OS2 -" ", -"/IDLE-LIMIT:number", -" The number of seconds of idle time, after which Kermit returns", -" automatically to command mode; default 0 (no limit).", -" ", -"/IDLE-INTERVAL:number", -" The number of seconds of idle time, after which Kermit automatically", -" transmits the idle string.", -" ", -"/IDLE-STRING:string", -" The string to transmit whenever the idle interval has passed.", -" ", -"/TIME-LIMIT:number", -" The maximum number of seconds for which the CONNECT session may last.", -" The default is 0 (no limit). If a nonzero number is given, Kermit returns", -" automatically to command mode after this many seconds.", -#endif /* OS2 */ -"" }; -#endif /* NOLOCAL */ - -static char *hmxxmget[] = { -"Syntax: MGET [ switches... ] remote-filespec [ remote-filespec ... ]", -" ", -"Just like GET (q.v.) except allows a list of remote file specifications,", -"separated by spaces.", -"" -}; - -static char *hmxxget[] = { -"Syntax: GET [ switches... ] remote-filespec [ as-name ]", -" Tells the other Kermit, which must be in (or support autoswitching into)", -" server mode, to send the named file or files. If the remote-filespec or", -" the as-name contain spaces, they must be enclosed in braces. If as-name", -" is the name of an existing local directory, incoming files are placed in", -" that directory; if it is the name of directory that does not exist, Kermit", -" tries to create it. Optional switches include:", -" ", -"/AS-NAME:text", -" Specifies \"text\" as the name to store the incoming file under, or", -" directory to store it in. You can also specify the as-name as the second", -" filename on the GET command line.", -" ", -"/BINARY", -" Performs this transfer in binary mode without affecting the global", -" transfer mode.", -" ", -"/COMMAND", -" Receives the file into the standard input of a command, rather than saving", -" it on disk. The /AS-NAME or the second \"filename\" on the GET command", -" line is interpreted as the name of a command.", -" ", -"/DELETE", -" Asks the other Kermit to delete the file (or each file in the group)", -" after it has been transferred successfully.", -" ", -"/EXCEPT:pattern", -" Specifies that any files whose names match the pattern, which can be a", -" regular filename, or may contain \"*\" and/or \"?\" metacharacters,", -" are to be refused. To specify multiple patterns (up to 8), use outer", -" braces around the group, and inner braces around each pattern:", -" ", -" /EXCEPT:{{pattern1}{pattern2}...}", -" ", -"/FILENAMES:{CONVERTED,LITERAL}", -" Overrides the global SET FILE NAMES setting for this transfer only.", -" ", -"/FILTER:command", -" Causes the incoming file to passed through the given command (standard", -" input/output filter) before being written to disk.", -" ", -#ifdef VMS -"/IMAGE", -" Transfer in image mode.", -" ", -#endif /* VMS */ -#ifdef CK_LABELED -"/LABELED", -" VMS and OS/2 only: Specifies labeled transfer mode.", -" ", -#endif /* CK_LABELED */ - -"/MOVE-TO:directory-name", -" Specifies that each file that arrives should be moved to the specified", -" directory after, and only if, it has been received successfully.", -" ", -"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}", -" Overrides the global SET RECEIVE PATHNAMES setting for this transfer.", -" ", -"/PIPES:{ON,OFF}", -" Overrides the TRANSFER PIPES setting for this command only. ON allows", -" reception of files with names like \"!tar xf -\" to be automatically", -" directed to a pipeline.", -" ", -"/QUIET", -" When sending in local mode, this suppresses the file-transfer display.", -" ", -"/RECOVER", -" Used to recover from a previously interrupted transfer; GET /RECOVER", -" is equivalent REGET. Works only in binary mode.", -" ", -"/RECURSIVE", -" Tells the server to descend through the directory tree when locating", -" the files to be sent.", -" ", -"/RENAME-TO:string", -" Specifies that each file that arrives should be renamed as specified", -" after, and only if, it has been received successfully. The string should", -" normally contain variables like \\v(filename) or \\v(filenum).", -" ", -"/TEXT", -" Performs this transfer in text mode without affecting the global", -" transfer mode.", -" ", -"/TRANSPARENT", -" Inhibits character-set translation of incoming text files for the duration", -" of the GET command without affecting subsequent commands.", -" ", -"Also see HELP MGET, HELP SEND, HELP RECEIVE, HELP SERVER, HELP REMOTE.", -""}; - -static char *hmxxlg[] = { -"Syntax: LOG (or L) log-type [ filename [ { NEW, APPEND } ] ]", -" ", -"Record information in a log file:", -" ", -#ifdef CKLOGDIAL -"CX", -" Connections made with SET LINE, SET PORT, SET HOST, DIAL, TELNET, etc.", -" The default filename is CX.LOG in your home directory and APPEND is the", -" default mode for opening.", -" ", -#endif /* CKLOGDIAL */ -#ifdef DEBUG -"DEBUG", -" Debugging information, to help track down bugs in the C-Kermit program.", -" The default log name is debug.log in current directory.", -" ", -#endif /* DEBUG */ -"PACKETS", -" Kermit packets, to help with protocol problems. The default filename is", -" packet.log in current directory.", -" ", -#ifndef NOLOCAL -"SESSION", -" Records your CONNECT session (default: session.log in current directory).", -" ", -#endif /* NOLOCAL */ -#ifdef TLOG -"TRANSACTIONS", -" Names and statistics about files transferred (default: transact.log in", -" current directory; see HELP SET TRANSACTION-LOG for transaction-log format", -" options.)", -" ", -#endif /* TLOG */ -"If you include the APPEND keyword after the filename, the existing log file,", -"if any, is appended to; otherwise a new file is created (except APPEND is", -"the default for the connection log). Use CLOSE to stop logging.", -#ifdef OS2ORUNIX -" ", -"Note: The filename can also be a pipe, e.g.:", -" ", -" log transactions |lpr", -" log debug {| grep \"^TELNET\" > debug.log}", -" ", -"Braces are required if the pipeline or filename contains spaces.", -#endif /* OS2ORUNIX */ -"" }; - -#ifndef NOSCRIPT -static char *hmxxlogi[] = { "\ -Syntax: SCRIPT text", -" A limited and cryptic \"login assistant\", carried over from old C-Kermit", -" releases for comptability, but not recommended for use. Instead, please", -" use the full script programming language described in chapters 17-19 of", -" \"Using C-Kermit\".", -" ", -" Login to a remote system using the text provided. The login script", -" is intended to operate similarly to UNIX uucp \"L.sys\" entries.", -" A login script is a sequence of the form:", -" ", -" expect send [expect send] . . .", -" ", -" where 'expect' is a prompt or message to be issued by the remote site, and", -" 'send' is the names, numbers, etc, to return. The send may also be the", -" keyword EOT to send Control-D, or BREAK (or \\\\b) to send a break signal.", -" Letters in send may be prefixed by ~ to send special characters:", -" ", -" ~b backspace, ~s space, ~q '?', ~n linefeed, ~r return, ~c don\'t", -" append a return, and ~o[o[o]] for octal of a character. As with some", -" UUCP systems, sent strings are followed by ~r unless they end with ~c.", -" ", -" Only the last 7 characters in each expect are matched. A null expect,", -" e.g. ~0 or two adjacent dashes, causes a short delay. If you expect", -" that a sequence might not arrive, as with uucp, conditional sequences", -" may be expressed in the form:", -" ", -" -send-expect[-send-expect[...]]", -" ", -" where dashed sequences are followed as long as previous expects fail.", -"" }; -#endif /* NOSCRIPT */ - -#ifndef NOFRILLS -static char * hmxxtyp[] = { -"Syntax: TYPE [ switches... ] file", -" Displays a file on the screen. Pauses automatically at end of each", -" screenful if COMMAND MORE-PROMPTING is ON. Optional switches:", -" ", -" /PAGE", -" Pause at the end of each screenful even if COMMAND MORE-PROMPTING OFF.", -" Synonym: /MORE", -" /NOPAGE", -" Don't pause at the end of each screen even if COMMAND MORE-PROMPTING ON." -, -" /HEAD:n", -" Only type the first 'n' lines of the file.", -" /TAIL:n", -" Only type the last 'n' lines of the file.", -" /MATCH:pattern", -" Only type lines that match the given pattern. HELP WILDCARDS for info", -" info about patterns. /HEAD and /TAIL apply after /MATCH.", -" /PREFIX:string", -" Print the given string at the beginning of each line.", -" /NUMBER", -" Add line numbers (conflicts with /PREFIX)", -" /WIDTH:number", -" Truncate each line at the given column number before printing.", -#ifdef KUI -" Or when combined with /GUI specifies the width of the dialog box.", -" /HEIGHT:number", -" When combined with /GUI specifies the height of the dialog box.", -" /GUI:string", -" Specifies the title to use for the dialog box.", -#endif /* KUI */ -" /COUNT", -" Count lines (and matches) and print the count(s) but not the lines.", -#ifdef UNICODE -" /CHARACTER-SET:name", -" Translates from the named character set.", -#ifndef OS2 -" /TRANSLATE-TO:name", -" Translates to the named character set (default = current file charset).", -#endif /* OS2 */ -" /TRANSPARENT", -" Inhibits character-set translation.", -#endif /* UNICODE */ -" /OUTPUT:name", -" Sends results to the given file. If this switch is omitted, the", -" results appear on your screen. This switch overrides any express or", -" implied /PAGE switch.", -" ", -"You can use SET OPTIONS TYPE to set the defaults for /PAGE or /NOPAGE and", -"/WIDTH. Use SHOW OPTIONS to see current TYPE options.", -"" -}; - -static char * hmxxcle[] = { -"Syntax: CLEAR [ item-name ]", -" ", -"Clears the named item. If no item is named, DEVICE-AND-INPUT is assumed.", -" ", -" ALARM Clears any pending alarm (see SET ALARM).", -#ifdef CK_APC -" APC-STATUS Clears Application Program Command status.", -#endif /* CK_APC */ -#ifdef PATTERNS -" BINARY-PATTERNS Clears the file binary-patterns list.", -#endif /* PATTERNS */ -#ifdef OS2 -" COMMAND-SCREEN Clears the current command screen.", -#endif /* OS2 */ -" DEVICE Clears the current port or network input buffer.", -" DEVICE-AND-INPUT Clears both the device and the INPUT buffer.", -" DIAL-STATUS Clears the \\v(dialstatus) variable.", -" \ -INPUT Clears the INPUT-command buffer and the \\v(input) variable.", -" KEYBOARD-BUFFER Clears the command terminal keyboard input buffer.", -#ifdef OS2 -" \ -SCROLLBACK empties the scrollback buffer including the current screen.", -#endif /* OS2 */ -" SEND-LIST Clears the current SEND list (see ADD).", -#ifdef OS2 -" \ -TERMINAL-SCREEN Clears the current screen a places it into the scrollback.", -" buffer.", -#endif /* OS2 */ -#ifdef PATTERNS -" TEXT-PATTERNS Clears the file text-patterns list.", -#endif /* PATTERNS */ -""}; -#endif /* NOFRILLS */ - -static char * hmxxdate[] = { -"Syntax: DATE [ date-time [ timezone ] ] [ delta-time ]", -" Prints a date-time in standard format: yyyymmdd_hh:mm:ss.", -" Various date-time formats are accepted:", -" ", -" . The date, if given, must precede the time.", -" . The year must be four digits or else a 2-digit format dd mmm yy,", -" in which case if (yy < 50) yyyy = yy + 2000; else yyyy = yy + 1900.", -" . If the year comes first, the second field is the month.", -" . The day, month, and year may be separated by spaces, /, -, or underscore." -," . The date and time may be separated by spaces or underscore.", -" . The month may be numeric (1 = January) or spelled out or abbreviated in", -" English.", -" . The time may be in 24-hour format or 12-hour format.", -" . If the hour is 12 or less, AM is assumed unless AM or PM is included.", -" . If the date is omitted but a time is given, the current date is supplied." -, -" . If the time is given but date omitted, 00:00:00 is supplied.", -" . If both the date and time are omitted, the current date and time are", -" supplied.", -" ", -" The following shortcuts can also be used in place of dates:", -" ", -" TODAY", -" Today's date, optionally followed by a time; 00:00:00 if no time given.", -" ", -" YESTERDAY", -" Yesterday's date, optionally followed by a time (default 00:00:00).", -" ", -" TOMORROW", -" Tomorrows's date, optionally followed by a time (default 00:00:00).", -" ", -" Timezone specifications are similar to those used in e-mail and HTTP", -" headers, either a USA timezone name, e.g. EST or a signed four-digit", -" timezone offset, {+,-}hhmm, e.g., -0500; it is used to convert date-time," -, -" a local time in that timezone, to GMT which is then converted to the", -" local time at the host. If no timezone is given, the date-time is local." -, -" ", -" Delta times are given as {+,-}[number date-units][hh[:mm[:ss]]]", -" A date in the future/past relative to the date-time; date-units may be", -" DAYS, WEEKS, MONTHS, YEARS: +3days, -7weeks, +3:00, +1month 8:00.", -" ", -"All the formats shown above are acceptable as arguments to date-time switches" -, -"such as /AFTER: or /BEFORE:, and to functions such as \\fcvtdate(),", -"\\fdiffdate(), and \\futcdate(), that take date-time strings as arguments.", -"" -}; - - -#ifndef NOXFER -static char * hmxxsen[] = { -"Syntax: SEND (or S) [ switches...] [ filespec [ as-name ] ]", -" Sends the file or files specified by filespec. If the filespec is omitted", -" the SEND-LIST is used (HELP ADD for more info). The filespec may contain", -" wildcard characters. An 'as-name' may be given to specify the name(s)", -" the files(s) are sent under; if the as-name is omitted, each file is", -" sent under its own name. Also see HELP MSEND, HELP WILDCARD.", -" Optional switches include:", -" ", -#ifndef NOSPL -"/ARRAY:", -" Specifies that the data to be sent comes from the given array, such as", -" \\&a[]. A range may be specified, e.g. SEND /ARRAY:&a[100:199]. Leave", -" the brackets empty or omit them altogether to send the whole 1-based array." -, -" Include /TEXT to have Kermit supply a line terminator at the end of each", -" array element (and translate character sets if character-set translations", -" are set up), or /BINARY to treat the array as one long string of characters" -, -" to be sent as-is. If an as-name is not specified, the array is sent with", -" the name _ARRAY_X_, where \"X\" is replaced by actual array letter.", -" ", -#endif /* NOSPL */ - -"/AS-NAME:", -" Specifies as the name to send the file under instead of its real", -" name. This is equivalent to giving an as-name after the filespec.", -" ", -"/BINARY", -" Performs this transfer in binary mode without affecting the global", -" transfer mode.", -" ", -"/TEXT", -" Performs this transfer in text mode without affecting the global", -" transfer mode.", -" ", -"/TRANSPARENT", -" Inhibits character-set translation for text files for the duration of", -" the SEND command without affecting subsequent commands.", -" ", -"/NOBACKUPFILES", -" Skip (don't send) Kermit or EMACS backup files (files with names that", -" end with .~n~, where n is a number).", -" ", -#ifdef UNIXOROSK -"/DOTFILES", -" Include (send) files whose names begin with \".\".", -" ", -"/NODOTFILES", -" Don't send files whose names begin with \".\".", -" ", -"/FOLLOWLINKS", -" Send files that are pointed to by symbolic links.", -" ", -"/NOFOLLOWLINKS", -" Skip over symbolic links (default).", -" ", -#endif /* UNIXOROSK */ - -#ifdef VMS -"/IMAGE", -" Performs this transfer in image mode without affecting the global", -" transfer mode.", -" ", -#endif /* VMS */ -#ifdef CK_LABELED -"/LABELED", -" Performs this transfer in labeled mode without affecting the global", -" transfer mode.", -" ", -#endif /* CK_LABELED */ -"/COMMAND", -" Sends the output from a command, rather than the contents of a file.", -" The first \"filename\" on the SEND command line is interpreted as the name", -" of a command; the second (if any) is the as-name.", -" ", -"/FILENAMES:{CONVERTED,LITERAL}", -" Overrides the global SET FILE NAMES setting for this transfer only.", -" ", -"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE}", -" Overrides the global SET SEND PATHNAMES setting for this transfer.", -" ", -"/FILTER:command", -" Specifies a command \ -(standard input/output filter) to pass the file through", -" before sending it.", -" ", -"/DELETE", -" Deletes the file (or each file in the group) after it has been sent", -" successfully (applies only to real files).", -" ", -"/QUIET", -" When sending in local mode, this suppresses the file-transfer display.", -" ", -"/RECOVER", -" Used to recover from a previously interrupted transfer; SEND /RECOVER", -" is equivalent RESEND (use in binary mode only).", -" ", -"/RECURSIVE", -" Tells C-Kermit to look not only in the given or current directory for", -" files that match the filespec, but also in all its subdirectories, and", -" all their subdirectories, etc.", -" ", -"/RENAME-TO:name", -" Tells C-Kermit to rename each source file that is sent successfully to", -" the given name (usually you should include \\v(filename) in the new name,", -" which is replaced by the original filename.", -" ", -"/MOVE-TO:directory", -" Tells C-Kermit to move each source file that is sent successfully to", -" the given directory.", -" ", -"/STARTING:number", -" Starts sending the file from the given byte position.", -" SEND /STARTING:n filename is equivalent to PSEND filename n.", -" ", -"/SUBJECT:text", -" Specifies the subject of an email message, to be used with /MAIL. If the", -" text contains spaces, it must be enclosed in braces.", -" ", -"/MAIL:address", -" Sends the file as e-mail to the given address; use with /SUBJECT:.", -" ", -"/PRINT:options", -" Sends the file to be printed, with optional options for the printer.", -" ", -#ifdef CK_XYZ -"/PROTOCOL:name", -" Uses the given protocol to send the file (Kermit, Zmodem, etc) for this", -" transfer without changing global protocol.", -" ", -#endif /* CK_XYZ */ -"/AFTER:date-time", -#ifdef VMS -" Specifies that only those files created after the given date-time are", -#else -" Specifies that only those files modified after the given date-time are", -#endif /* VMS */ -" to be sent. HELP DATE for info about date-time formats.", -" ", -"/BEFORE:date-time", -#ifdef VMS -" Specifies that only those files modified before the given date-time", -#else -" Specifies that only those files modified before the given date-time", -#endif /* VMS */ -" are to be sent.", -" ", -"/NOT-AFTER:date-time", -#ifdef VMS -" Specifies that only those files modified at or before the given date-time", -#else -" Specifies that only those files modified at or before the given date-time", -#endif /* VMS */ -" are to be sent.", -" ", -"/NOT-BEFORE:date-time", -#ifdef VMS -" Specifies that only those files modified at or after the given date-time", -#else -" Specifies that only those files modified at or after the given date-time", -#endif /* VMS */ -" are to be sent.", -" ", -"/LARGER-THAN:number", -" Specifies that only those files longer than the given number of bytes are", -" to be sent.", -" ", -"/SMALLER-THAN:number", -" Specifies that only those files smaller than the given number of bytes are", -" to be sent.", -" ", -"/EXCEPT:pattern", -" Specifies that any files whose names match the pattern, which can be a", -" regular filename, or may contain \"*\" and/or \"?\" metacharacters,", -" are not to be sent. To specify multiple patterns (up to 8), use outer", -" braces around the group, and inner braces around each pattern:", -" ", -" /EXCEPT:{{pattern1}{pattern2}...}", -" ", -"/TYPE:{ALL,TEXT,BINARY}", -" Send only files of the given type (see SET FILE SCAN).", -" ", -"/LISTFILE:filename", -" Specifies the name of a file that contains the list of names of files", -" that are to be sent. The filenames should be listed one name per line", -" in this file (but a name can contain wildcards).", -" ", -"Also see HELP RECEIVE, HELP GET, HELP SERVER, HELP REMOTE.", -""}; - -static char *hmxxrc[] = { -"Syntax: RECEIVE (or R) [ switches... ] [ as-name ]", -" Wait for a file to arrive from the other Kermit, which must be given a", -" SEND command. If the optional as-name is given, the incoming file or", -" files are stored under that name, otherwise it will be stored under", -#ifndef CK_TMPDIR -" the name it arrives with.", -#else -#ifdef OS2 -" the name it arrives with. If the filespec denotes a disk and/or", -" directory, the incoming file or files will be stored there.", -#else -" the name it arrives with. If the filespec denotes a directory, the", -" incoming file or files will be placed in that directory.", -#endif /* OS2 */ -#endif /* CK_TMPDIR */ -" ", -"Optional switches include:", -" ", -"/AS-NAME:text", -" Specifies \"text\" as the name to store the incoming file under.", -" You can also specify the as-name as a filename on the command line.", -" ", -"/BINARY", -" Skips text-mode conversions unless the incoming file arrives with binary", -" attribute", -" ", -"/COMMAND", -" Receives the file into the standard input of a command, rather than saving", -" it on disk. The /AS-NAME or the \"filename\" on the RECEIVE command line", -" is interpreted as the name of a command.", -" ", -"/EXCEPT:pattern", -" Specifies that any files whose names match the pattern, which can be a", -" regular filename, or may contain \"*\" and/or \"?\" metacharacters,", -" are to be refused. To specify multiple patterns (up to 8), use outer", -" braces around the group, and inner braces around each pattern:", -" ", -" /EXCEPT:{{pattern1}{pattern2}...}", -" ", -"/FILENAMES:{CONVERTED,LITERAL}", -" Overrides the global SET FILE NAMES setting for this transfer only.", -" ", -"/FILTER:command", -" Causes the incoming file to passed through the given command (standard", -" input/output filter) before being written to disk.", -" ", -#ifdef VMS -"/IMAGE", -" Receives the file in image mode.", -" ", -#endif /* VMS */ -#ifdef CK_LABELED -"/LABELED", -" Specifies labeled transfer mode.", -" ", -#endif /* CK_LABELED */ - -"/MOVE-TO:directory-name", -" Specifies that each file that arrives should be moved to the specified", -" directory after, and only if, it has been received successfully.", -" ", -"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}", -" Overrides the global SET RECEIVE PATHNAMES setting for this transfer.", -" ", -"/PIPES:{ON,OFF}", -" Overrides the TRANSFER PIPES setting for this command only. ON allows", -" reception of files with names like \"!tar xf -\" to be automatically", -" directed to a pipeline.", -" ", -"/PROTOCOL:name", -" Use the given protocol to receive the incoming file(s).", -" ", -"/QUIET", -" When sending in local mode, this suppresses the file-transfer display.", -" ", -"/RECURSIVE", -" Equivalent to /PATHNAMES:RELATIVE.", -" ", -"/RENAME-TO:string", -" Specifies that each file that arrives should be renamed as specified", -" after, and only if, it has been received successfully. The string should", -" normally contain variables like \\v(filename) or \\v(filenum).", -" ", -"/TEXT", -" Forces text-mode conversions unless the incoming file has the binary", -" attribute", -" ", -"/TRANSPARENT", -" Inhibits character-set translation of incoming text files for the duration", -" of the RECEIVE command without affecting subsequent commands.", -" ", -"Also see HELP SEND, HELP GET, HELP SERVER, HELP REMOTE.", -"" }; - -#ifndef NORESEND -static char *hmxxrsen = "\ -Syntax: RESEND filespec [name]\n\n\ - Resend the file or files, whose previous transfer was interrupted.\n\ - Picks up from where previous transfer left off, IF the receiver was told\n\ - to SET FILE INCOMPLETE KEEP. Only works for binary-mode transfers.\n\ - Requires the other Kermit to have RESEND capability."; - -static char *hmxxrget = "\ -Syntax: REGET filespec\n\n\ - Ask a server to RESEND a file to C-Kermit."; - -static char *hmxxpsen = "\ -Syntax: PSEND filespec position [name]\n\n\ - Just like SEND, except sends the file starting at the given byte position."; -#endif /* NORESEND */ - -#ifndef NOMSEND -static char *hmxxmse[] = { -"Syntax: MSEND [ switches... ] filespec [ filespec [ ... ] ]", -" Sends the files specified by the filespecs. One or more filespecs may be", -" listed, separated by spaces. Any or all filespecs may contain wildcards", -" and they may be in different directories. Alternative names cannot be", -" given. Switches include /BINARY /DELETE /MAIL /PROTOCOL /QUIET /RECOVER", -" /TEXT /TYPE; see HELP SEND for descriptions.", -"" -}; -#endif /* NOMSEND */ - -static char *hmxxadd[] = { -#ifndef NOMSEND -"ADD SEND-LIST filespec [ [ ] ]", -" Adds the specified file or files to the current SEND list. Use SHOW", -" SEND-LIST and CLEAR SEND-LIST to display and clear the list; use SEND", -" by itself to send the files from it.", -" ", -#endif /* NOMSEND */ -#ifdef PATTERNS -"ADD BINARY-PATTERNS [ [ ... ] ]", -" Adds the pattern(s), if any, to the SET FILE BINARY-PATTERNS list.", -" ", -"ADD TEXT-PATTERNS [ [ ... ] ]", -" Adds the pattern(s), if any, to the SET FILE TEXT-PATTERNS list.", -" Use SHOW PATTERNS to see the lists. See HELP SET FILE for further info.", -#endif /* PATTERNS */ -""}; - -static char *hmxxremv[] = { -#ifdef PATTERNS -"REMOVE BINARY-PATTERNS [ [ ... ] ]", -" Removes the pattern(s), if any, from the SET FILE BINARY-PATTERNS list", -" ", -"REMOVE TEXT-PATTERNS [ [ ... ] ]", -" Removes the given patterns from the SET FILE TEXT-PATTERNS list.", -" Use SHOW PATTERNS to see the lists. See HELP SET FILE for further info.", -#endif /* PATTERNS */ -""}; -#endif /* NOXFER */ - -#ifndef NOSERVER -static char *hmxxser = "Syntax: SERVER\n\ - Enter server mode on the current connection. All further commands\n\ - are taken in packet form from the other Kermit program. Use FINISH,\n\ - BYE, or REMOTE EXIT to get C-Kermit out of server mode."; -#endif /* NOSERVER */ - -static char *hmhset[] = { -" The SET command establishes communication, file, scripting, or other", -" parameters. The SHOW command can be used to display the values of", -" SET parameters. Help is available for each individual parameter;", -" type HELP SET ? to see what's available.", -"" }; - -#ifndef NOSETKEY -static char *hmhskey[] = { -"Syntax: SET KEY k text", -"Or: SET KEY CLEAR", -" Configure the key whose \"scan code\" is k to send the given text when", -" pressed during CONNECT mode. SET KEY CLEAR restores all the default", -" key mappings. If there is no text, the default key binding is restored", -#ifndef NOCSETS -" for the key k. SET KEY mappings take place before terminal character-set", -" translation.", -#else -" the key k.", -#endif /* NOCSETS */ -#ifdef OS2 -" ", -" The text may contain \"\\Kverbs\" to denote actions, to stand for DEC", -" keypad, function, or editing keys, etc. For a list of available keyboard", -" verbs, type SHOW KVERBS.", -#endif /* OS2 */ -" ", -" To find out the scan code and mapping for a particular key, use the", -" SHOW KEY command.", -""}; -#endif /* NOSETKEY */ - -static char *hmxychkt[] = { "Syntax: SET BLOCK-CHECK type", -" ", -" Type of packet block check to be used for error detection, 1, 2, 3, or", -" BLANK-FREE-2. Type 1 is standard, and catches most errors. Types 2 and 3", -" specify more rigorous checking at the cost of higher overhead. The", -" BLANK-FREE-2 type is the same as Type 2, but is guaranteed to contain no", -" blanks.", -"" }; - -static char * hmxydeb[] = { -"Syntax: SET DEBUG { SESSION, ON, OFF, TIMESTAMP }", -" ", -"SET DEBUG ON", -#ifdef DEBUG -" Opens a debug log file named debug.log in the current directory.", -" Use LOG DEBUG if you want specify a different log file name or path.", -#else -" (Has no effect in this version of Kermit.)", -#endif /* DEBUG */ -" ", -"SET DEBUG OFF", -" Stops debug logging and session debugging.", -" ", -"SET DEBUG SESSION", -#ifndef NOLOCAL -" Displays control and 8-bit characters symbolically during CONNECT mode.", -" Equivalent to SET TERMINAL DEBUG ON.", -#else -" (Has no effect in this version of Kermit.)", -#endif /* NOLOCAL */ -" ", -"SET DEBUG TIMESTAMP { ON, OFF }", -" Enables/Disables timestamps on debug log entries.", -"" }; - -#ifdef CK_SPEED -static char *hmxyqctl[] = { -"Syntax: SET CONTROL-CHARACTER { PREFIXED, UNPREFIXED } { ..., ALL }", -" ", -" is the numeric ASCII code for a control character 1-31,127-159,255." -, -" The word \"ALL\" means all characters in this range.", -" ", -" PREFIXED means the given control character must be converted to a", -" printable character and prefixed, the default for all control characters.", -" ", -" UNPREFIXED means you think it is safe to send the given control", -" character as-is, without a prefix. USE THIS OPTION AT YOUR OWN RISK!", -" ", -" SHOW CONTROL to see current settings. SET CONTROL PREFIXED ALL is", -" recommended for safety. You can include multiple values in one", -" command, separated by spaces.", -"" }; -#endif /* CK_SPEED */ - -#ifndef NODIAL -static char *hxymodm[] = { -"Syntax: SET MODEM ...", -" ", -"Note: Many of the SET MODEM parameters are configured automatically when", -"you SET MODEM TYPE, according to the modem's capabilities. SHOW MODEM to", -"see them. Also see HELP DIAL and HELP SET DIAL.", -" ", -"SET MODEM TYPE ", - -" Tells Kermit which kind of modem you have, so it can issue the", -" appropriate modem-specific commands for configuration, dialing, and", -" hanging up. For a list of the modem types known to Kermit, type \"set", -" modem type ?\". The default modem type is GENERIC, which should work", -" with any AT command-set modem that is configured for error correction,", -" data compression, and hardware flow control. Use SET MODEM TYPE NONE", -" for direct serial, connections. Use SET MODEM TYPE USER-DEFINED to use", -" a type of modem that is not built in to Kermit, and then use SET MODEM", -" CAPABILITIES, SET MODEM, DIAL-COMMAND, and SET MODEM COMMAND to tell", -" Kermit how to configure and control it.", - -" ", - -"SET MODEM CAPABILITIES ", -" Use this command for changing Kermit's idea of your modem's capabilities,", -" for example, if your modem is supposed to have built-in error correction", -" but in fact does not. Also use this command to define the capabilities", -" of a USER-DEFINED modem. Capabilities are:", -" ", -" AT AT-commands", -" DC data-compression", -" EC error-correction", -" HWFC hardware-flow", -" ITU v25bis-commands", -" SWFC software-flow", -" KS kermit-spoof", -" SB speed-buffering", -" TB Telebit", -" ", -"SET MODEM CARRIER-WATCH { AUTO, ON, OFF }", -" Synonym for SET CARRIER-WATCH (q.v.)", -" ", -"SET MODEM COMPRESSION { ON, OFF }", -" Enables/disables the modem's data compression feature, if any.", -" ", -"SET MODEM DIAL-COMMAND ", -" The text replaces Kermit's built-in modem dialing command. It must", -" include '%s' (percent s) as a place-holder for the telephone numbers", -" given in your DIAL commands.", -" ", -"SET MODEM ERROR-CORRECTION { ON, OFF }", -" Enables/disables the modem's error-correction feature, if any.", -" ", -"SET MODEM ESCAPE-CHARACTER number", -" Numeric ASCII value of modem's escape character, e.g. 43 for '+'.", -" For Hayes-compatible modems, Kermit uses three copies, e.g. \"+++\".", -" ", -"SET MODEM FLOW-CONTROL {AUTO, NONE, RTS/CTS, XON/XOFF}", -" Selects the type of local flow control to be used by the modem.", -" ", -"SET MODEM HANGUP-METHOD { MODEM-COMMAND, RS232-SIGNAL, DTR }", -" How hangup operations should be done. MODEM-COMMAND means try to", -" escape back to the modem's command processor and give a modem-specific", -" hangup command. RS232-SIGNAL means turn off the DTR signal. DTR is a", -" synonym for RS232-SIGNAL.", -" ", -"SET MODEM KERMIT-SPOOF {ON, OFF}", -" If the selected modem type supports the Kermit protocol directly,", -" use this command to turn its Kermit protocol function on or off.", -" ", -"SET MODEM MAXIMUM-SPEED ", -" Specify the maximum interface speed for the modem.", -" ", -"SET MODEM NAME ", -" Descriptive name for a USER-DEFINED modem.", -" ", -"SET MODEM SPEAKER {ON, OFF}", -" Turns the modem's speaker on or off during dialing.", -" ", -"SET MODEM SPEED-MATCHING {ON, OFF}", -" ON means that C-Kermit changes its serial interface speed to agree with", -" the speed reported by the modem's CONNECT message, if any. OFF means", -" Kermit should not change its interface speed.", -" ", -"SET MODEM VOLUME {LOW, MEDIUM, HIGH}", -" Selects the desired modem speaker volume for when the speaker is ON.", -" ", -"SET MODEM COMMAND commands are used to override built-in modem commands for", -"each modem type, or to fill in commands for the USER-DEFINED modem type.", -"Omitting the optional [ text ] restores the built-in modem-specific command,", -"if any:", -" ", -"SET MODEM COMMAND AUTOANSWER {ON, OFF} [ text ]", -" Modem commands to turn autoanswer on and off.", -" ", -"SET MODEM COMMAND COMPRESSION {ON, OFF} [ text ]", -" Modem commands to turn data compression on and off.", -" ", -"SET MODEM COMMAND ERROR-CORRECTION {ON, OFF} [ text ]", -" Modem commands to turn error correction on and off.", -" ", -"SET MODEM COMMAND HANGUP [ text ]", -" Command that tells the modem to hang up the connection.", -" ", -"SET MODEM COMMAND IGNORE-DIALTONE [ text ]", -" Command that tells the modem not to wait for dialtone before dialing.", -" ", -"SET MODEM COMMAND INIT-STRING [ text ]", -" The 'text' is a replacement for C-Kermit's built-in initialization command", -" for the modem.", -" ", -"SET MODEM COMMAND PREDIAL-INIT [ text ]", -" A second INIT-STRING that is to be sent to the modem just prior to \ -dialing.", -" ", -"SET MODEM COMMAND HARDWARE-FLOW [ text ]", -" Modem command to enable hardware flow control (RTS/CTS) in the modem.", -" ", -"SET MODEM COMMAND SOFTWARE-FLOW [ text ]", -" Modem command to enable local software flow control (Xon/Xoff) in modem.", -" ", -"SET MODEM COMMAND SPEAKER { ON, OFF } [ text ]", -" Modem command to turn the modem's speaker on or off.", -" ", -"SET MODEM COMMAND NO-FLOW-CONTROL [ text ]", -" Modem command to disable local flow control in the modem.", -" ", -"SET MODEM COMMAND PULSE [ text ]", -" Modem command to select pulse dialing.", -" ", -"SET MODEM COMMAND TONE [ text ]", -" Modem command to select tone dialing.", -" ", -"SET MODEM COMMAND VOLUME { LOW, MEDIUM, HIGH } [ text ]", -" Modem command to set the modem's speaker volume.", -""}; - -static char *hmxydial[] = { -"The SET DIAL command establishes or changes all parameters related to", -"dialing the telephone. Also see HELP DIAL and HELP SET MODEM. Use SHOW", -"DIAL to display all of the SET DIAL values.", -" ", -"SET DIAL COUNTRY-CODE ", -" Tells Kermit the telephonic country-code of the country you are dialing", -" from, so it can tell whether a portable-format phone number from your", -" dialing directory will result in a national or an international call.", -" Examples: 1 for USA, Canada, Puerto Rico, etc; 7 for Russia, 39 for Italy,", -" 351 for Portugal, 47 for Norway, 44 for the UK, 972 for Israel, 81 for", -" Japan, ...", -" ", -" If you have not already set your DIAL INTL-PREFIX and LD-PREFIX, then this", -" command sets default values for them: 011 and 1, respectively, for country", -" code 1; 00 and 0, respectively, for all other country codes. If these are", -" not your true international and long-distance dialing prefixes, then you", -" should follow this command by DIAL INTL-PREFIX and LD-PREFIX to let Kermit", -" know what they really are.", -" ", -"SET DIAL AREA-CODE [ ]", -" Tells Kermit the area or city code that you are dialing from, so it can", -" tell whether a portable-format phone number from the dialing directory is", -" local or long distance. Be careful not to include your long-distance", -" dialing prefix as part of your area code; for example, the area code for", -" central London is 171, not 0171.", -" ", -"SET DIAL CONFIRMATION {ON, OFF}", -" Kermit does various transformations on a telephone number retrieved from", -" the dialing directory prior to dialing (use LOOKUP to see them).", -" In case the result might be wrong, you can use SET DIAL CONFIRM ON to have", -" Kermit ask you if it is OK to dial the number, and if not, to let you type", -" in a replacement.", -" ", -"SET DIAL CONNECT { AUTO, ON, OFF }", -" Whether to CONNECT (enter terminal mode) automatically after successfully", -" dialing. ON means to do this; OFF means not to. AUTO (the default) means", -" do it if the DIAL command was given interactively, but don't do it if the", -" DIAL command was issued from a macro or command file. If you specify ON", -" or AUTO, you may follow this by one of the keywords VERBOSE or QUIET, to", -" indicate whether the verbose 4-line 'Connecting...' message is to be", -" displayed if DIAL succeeds and Kermit goes into CONNECT mode.", -" ", -"SET DIAL CONVERT-DIRECTORY {ASK, ON, OFF}", -" The format of Kermit's dialing directory changed in version 5A(192). This", -" command tells Kermit what to do when it encounters an old-style directory:", -" ASK you whether to convert it, or convert it automatically (ON), or leave", -" it alone (OFF). Old-style directories can still be used without", -" conversion, but the parity and speed fields are ignored.", -" ", -"SET DIAL DIRECTORY [ filename [ filename [ filename [ ... ] ] ] ]", -" The name(s) of your dialing directory file(s). If you do not supply any", -" filenames, the dialing directory feature is disabled and all numbers are", -" dialed literally as given in the DIAL command. If you supply more than", -" one directory, all of them are searched.", -" ", -"SET DIAL SORT {ON, OFF}", -" When multiple entries are obtained from your dialing directory, they are", -" sorted in \"cheapest-first\" order. If this does not produce the desired", -" effect, SET DIAL SORT OFF to disable sorting, and the numbers will be", -" dialed in the order in which they were found.", -" ", -"SET DIAL DISPLAY {ON, OFF}", -" Whether to display dialing progress on the screen; default is OFF.", -" ", -"SET DIAL HANGUP {ON, OFF}", -" Whether to hang up the phone prior to dialing; default is ON.", -" ", -"SET DIAL IGNORE-DIALTONE {ON, OFF}", -" Whether to ignore dialtone when dialing; default is OFF.", -" ", -#ifndef NOSPL -"SET DIAL MACRO [ name ]", -" Specify the name of a macro to execute on every phone number dialed, just", -" prior to dialing it, in order to perform any last-minute alterations.", -" ", -#endif /* NOSPL */ -"SET DIAL METHOD {AUTO, DEFAULT, TONE, PULSE}", -" Whether to use the modem's DEFAULT dialing method, or to force TONE or", -" PULSE dialing. AUTO (the default) means to choose tone or pulse dialing", -" based on the country code. (Also see SET DIAL TONE-COUNTRIES and SET DIAL", -" PULSE-COUNTRIES.)", -" ", -"SET DIAL PACING number", -" How many milliseconds to pause between sending each character to the modem", -" dialer. The default is -1, meaning to use the number from the built-in", -" modem database.", -" ", -"SET DIAL PULSE-COUNTRIES [ cc [ cc [ ... ] ] ]", -" Sets the list of countries in which pulse dialing is required. Each cc", -" is a country code.", -" ", -"SET DIAL TEST { ON, OFF }", -" OFF for normal dialing. Set to ON to test dialing procedures without", -" actually dialing.", -" ", -"SET DIAL TONE-COUNTRIES [ cc [ cc [ ... ] ] ]", -" Sets the list of countries in which tone dialing is available. Each cc", -" is a country code.", -" ", -"SET DIAL TIMEOUT number", -" How many seconds to wait for a dialed call to complete. Use this command", -" to override the DIAL command's automatic timeout calculation. A value", -" of 0 turns off this feature and returns to Kermit's automatic dial", -" timeout calculation.", -" ", -"SET DIAL RESTRICT { INTERNATIONAL, LOCAL, LONG-DISTANCE, NONE }", -" Prevents placing calls of the type indicated, or greater. For example", -" SET DIAL RESTRICT LONG prevents placing of long-distance and international", -" calls. If this command is not given, there are no restrictions. Useful", -" when dialing a list of numbers fetched from a dialing directory.", -" ", -"SET DIAL RETRIES ", -" How many times to redial each number if the dialing result is busy or no", -" no answer, until the call is succesfully answered. The default is 0", -" because automatic redialing is illegal in some countries.", -" ", -"SET DIAL INTERVAL ", -" How many seconds to pause between automatic redial attempts; default 10.", -" ", -"The following commands apply to all phone numbers, whether given literally", -"or found in the dialing directory:", -" ", -"SET DIAL PREFIX [ text ]", -" Establish a prefix to be applied to all phone numbers that are dialed,", -" for example to disable call waiting.", -" ", -"SET DIAL SUFFIX [ text ]", -" Establish a suffix to be added after all phone numbers that are dialed.", -" ", -"The following commands apply only to portable-format numbers obtained from", -"the dialing directory; i.e. numbers that start with a \"+\" sign and", -"country code, followed by area code in parentheses, followed by the phone", -"number.", -" ", -"SET DIAL LC-AREA-CODES [ ]", -" Species a list of area codes to which dialing is local, i.e. does not", -" require the LD-PREFIX. Up to 32 area codes may be listed, separated by", -" spaces. Any area codes in this list will be included in the final dial", -" string so do not include your own area code if it should not be dialed.", -" ", -"SET DIAL LC-PREFIX [ ]", -" Specifies a prefix to be applied to local calls made from portable dialing", -" directory entries. Normally no prefix is used for local calls.", -" ", -"SET DIAL LC-SUFFIX [ ]", -" Specifies a suffix to be applied to local calls made from portable dialing", -" directory entries. Normally no suffix is used for local calls.", -" ", -"SET DIAL LD-PREFIX [ ]", -" Your long-distance dialing prefix, to be used with portable dialing", -" directory entries that result in long-distance calls.", -" ", -"SET DIAL LD-SUFFIX [ ]", -" Long-distance dialing suffix, if any, to be used with portable dialing", -" directory entries that result in long-distance calls. This would normally", -" be used for appending a calling-card number to the phone number.", -" ", -"SET DIAL FORCE-LONG-DISTANCE { ON, OFF }", -" Whether to force long-distance dialing for calls that normally would be", -" local. For use (e.g.) in France.", -" ", -"SET DIAL TOLL-FREE-AREA-CODE [ [ [ ... ] ] ]", -" Tells Kermit the toll-free area code(s) in your country.", -" ", -"SET DIAL TOLL-FREE-PREFIX [ ]", -" You toll-free dialing prefix, in case it is different from your long-", -" distance dialing prefix.", -" ", -"SET DIAL INTL-PREFIX ", -" Your international dialing prefix, to be used with portable dialing", -" directory entries that result in international calls.", -" ", -"SET DIAL INTL-SUFFIX ", -" International dialing suffix, if any, to be used with portable dialing", -" directory entries that result in international calls.", -" ", -"SET DIAL PBX-OUTSIDE-PREFIX ", -" Use this to tell Kermit how to get an outside line when dialing from a", -" Private Branch Exchange (PBX).", -" ", -"SET DIAL PBX-EXCHANGE [ [ ... ] ]", -" If PBX-OUTSIDE-PREFIX is set, then you can use this command to tell Kermit", -" the leading digits of one or more local phone numbers that identify it as", -" being on your PBX, so it can make an internal call by deleting those digits" -, -" from the phone number.", -" ", -"SET DIAL PBX-INTERNAL-PREFIX ", -" If PBX-EXCHANGE is set, and Kermit determines from it that a call is", -" internal, then this prefix, if any, is added to the number prior to", -" \ -dialing. Use this if internal calls from your PBX require a special prefix.", -"" }; -#endif /* NODIAL */ - -static char *hmxyflo[] = { "Syntax: SET FLOW [ switch ] value", -" ", -#ifndef NOLOCAL -" Selects the type of flow control to use during file transfer, terminal", -" connection, and script execution.", -#else -" Selects the type of flow control to use during file transfer.", -#endif /* NOLOCAL */ -" ", -" Switches let you associate a particular kind of flow control with each", -" kind of connection: /REMOTE, /MODEM, /DIRECT-SERIAL, /TCPIP, etc; type", -" \"set flow ?\" for a list of available switches. Then whenever you make", -" a connection, the associated flow-control is chosen automatically.", -" The flow-control values are NONE, KEEP, XON/XOFF, and possibly RTS/CTS", -" and some others; again, type \"set flow ?\" for a list. KEEP tells Kermit", -" not to try to change the current flow-control method for the connection.", -" ", -" If you omit the switch and simply supply a value, this value becomes the", -" current flow control type, overriding any default value that might have", -" been chosen in your most recent SET LINE, SET PORT, or SET HOST, or other", -" connection-establishment command.", -" ", -" Type SHOW FLOW-CONTROL to see the current defaults for each connection type" -, -" as well as the current connection type and flow-control setting. SHOW", -" COMMUNICATIONS also shows the current flow-control setting.", -""}; - -static char *hmxyf[] = { -"Syntax: SET FILE parameter value", -" ", -"Sets file-related parameters. Use SHOW FILE to view them. Also see SET", -"(and SHOW) TRANSFER and PROTOCOL.", -" ", -#ifdef VMS -"SET FILE TYPE { TEXT, BINARY, IMAGE, LABELED }", -#else -#ifdef STRATUS -"SET FILE TYPE { TEXT, BINARY, LABELED }", -#else -#ifdef MAC -"SET FILE TYPE { TEXT, BINARY, MACBINARY }", -#else -"SET FILE TYPE { TEXT, BINARY }", -#endif /* STRATUS */ -#endif /* MAC */ -#endif /* VMS */ -" How file contents are to be treated during file transfer in the absence", -" of any other indication. TYPE can be TEXT for conversion of record format", -" and character set, which is usually needed when transferring text files", -" between unlike platforms (such as UNIX and Windows), or BINARY for no", -" conversion if TRANSFER MODE is MANUAL, which is not the default. Use", -" BINARY with TRANSFER MODE MANUAL for executable programs or binary data or", -" whenever you wish to duplicate the original contents of the file, byte for" -, -" byte. In most modern Kermit programs, the file sender informs the receiver" -, -" of the file type automatically. However, when sending files from C-Kermit", -" to an ancient or non-Columbia Kermit implementation, you might need to set", -" the corresponding file type at the receiver as well.", -" ", -#ifdef VMS -" FILE TYPE settings of TEXT and BINARY have no effect when sending files,", -" since VMS C-Kermit determines each file's type automatically from its", -" record format: binary for fixed, text for others. For incoming files,", -" these settings are effective only in the absence of a file-type indication", -" from the sender.", -" ", -" You may include an optional record-format after the word BINARY. This may", -" be FIXED (the default) or UNDEFINED. UNDEFINED is used when you need to", -" receive binary files in binary mode and have them stored with UNDEFINED", -" record format, which is required by certain VMS applications.", -" ", -" Two additional VMS file types are also supported: IMAGE and LABELED.", -" IMAGE means raw block i/o, no interference from RMS, applies to file", -" transmission only, and overrides the normal automatica file type", -" determination. LABELED means to send or interpret RMS attributes", -" with the file.", -" ", -#else -" When TRANSFER MODE is AUTOMATIC (as it is by default), various automatic", -" methods (depending on the platform) are used to determine whether a file", -" is transferred in text or binary mode; these methods (which might include", -" content scan (see SET FILE SCAN below), filename pattern matching (SET FILE" -, -" PATTERNS), client/server \"kindred-spirit\" recognition, or source file", -" record format) supersede the FILE TYPE setting but can, themselves, be", -" superseded by including a /BINARY or /TEXT switch in the SEND, GET, or", -" RECEIVE command.", -" ", -" When TRANSFER MODE is MANUAL, the automatic methods are skipped for sending" -, -" files; the FILE TYPE setting is used instead, which can be superseded on", -" a per-command basis with a /TEXT or /BINARY switch.", -#endif /* VMS */ -" ", - -#ifndef NOXFER - -"SET FILE BYTESIZE { 7, 8 }", -" Normally 8. If 7, Kermit truncates the 8th bit of all file bytes.", -" ", -#ifndef NOCSETS -"SET FILE CHARACTER-SET name", -" Tells the encoding of the local file, ASCII by default.", -" The names ITALIAN, PORTUGUESE, NORWEGIAN, etc, refer to 7-bit ISO-646", -" national character sets. LATIN1 is the 8-bit ISO 8859-1 Latin Alphabet 1", -" for Western European languages.", -" NEXT is the 8-bit character set of the NeXT workstation.", -" The CPnnn sets are for PCs. MACINTOSH-LATIN is for the Macintosh.", -#ifndef NOLATIN2 -" LATIN2 is ISO 8859-2 for Eastern European languages that are written with", -" Roman letters. Mazovia is a PC code page used in Poland.", -#endif /* NOLATIN2 */ -#ifdef CYRILLIC -" KOI-CYRILLIC, CYRILLIC-ISO, and CP866 are 8-bit Cyrillic character sets.", -" SHORT-KOI is a 7-bit ASCII coding for Cyrillic. BULGARIA-PC is a PC code", -" page used in Bulgaria", -#endif /* CYRILLIC */ -#ifdef HEBREW -" HEBREW-ISO is ISO 8859-8 Latin/Hebrew. CP862 is the Hebrew PC code page.", -" HEBREW-7 is like ASCII with the lowercase letters replaced by Hebrew.", -#endif /* HEBREW */ -#ifdef GREEK -" GREEK-ISO is ISO 8859-7 Latin/Greek. CP869 is the Greek PC code page.", -" ELOT-927 is like ASCII with the lowercase letters replaced by Greek.", -#endif /* GREEK */ -#ifdef KANJI -" JAPANESE-EUC, JIS7-KANJI, DEC-KANJI, and SHIFT-JIS-KANJI are Japanese", -" Kanji character sets.", -#endif /* KANJI */ -#ifdef UNICODE -" UCS-2 is the 2-byte form of the Universal Character Set.", -" UTF-8 is the serialized form of the Universal Character Set.", -#endif /* UNICODE */ -" Type SET FILE CHAR ? for a complete list of file character sets.", -" ", -"SET FILE DEFAULT 7BIT-CHARACTER-SET", -" When automatically switching among different kinds of files while sending", -" this tells the character set to be used for 7-bit text files.", -" ", -"SET FILE DEFAULT 8BIT-CHARACTER-SET", -" This tells the character set to be used for 8-bit text files when", -" switching automatically among different kinds of files.", -" ", -#endif /* NOCSETS */ - -"SET FILE COLLISION option", -" Tells what to do when a file arrives that has the same name as", -" an existing file. The options are:", -" BACKUP (default) - Rename the old file to a new, unique name and store", -" the incoming file under the name it was sent with.", -" OVERWRITE - Overwrite (replace) the existing file.", -" APPEND - Append the incoming file to the end of the existing file.", -" DISCARD - Refuse and/or discard the incoming file.", -" RENAME - Give the incoming file a unique name.", -" UPDATE - Accept the incoming file only if newer than the existing file.", -" ", - -"SET FILE DESTINATION { DISK, PRINTER, SCREEN, NOWHERE }", -" DISK (default): Store incoming files on disk.", -" PRINTER: Send incoming files to SET PRINTER device.", -" SCREEN: Display incoming files on screen (local mode only).", -" NOWHERE: Do not put incoming files anywhere (use for calibration).", -" ", -"SET FILE DISPLAY option", -" Selects the format of the file transfer display for local-mode file", -" transfer. The choices are:", -" ", -" BRIEF A line per file, showing size, mode, status, and throughput.", -" SERIAL One dot is printed for every K bytes transferred.", -" CRT Numbers are continuously updated on a single screen line.", -" This format can be used on any video display terminal.", -#ifdef CK_CURSES -" FULLSCREEN A fully formatted 24x80 screen showing lots of information.", -" This requires a terminal or terminal emulator.", -#endif /* CK_CURSES */ -" NONE No file transfer display at all.", -" ", - -"SET FILE DOWNLOAD-DIRECTORY [ ]", -" The directory into which all received files should be placed. By default,", -" received files go into your current directory.", -" ", -#endif /* NOXFER */ - -#ifdef CK_CTRLZ -"SET FILE EOF { CTRL-Z, LENGTH }", -" End-Of-File detection method, normally LENGTH. Applies only to text-mode", -" transfers. When set to CTRL-Z, this makes the file sender treat the first", -" Ctrl-Z in the input file as the end of file (EOF), and it makes the file", -" receiver tack a Ctrl-Z onto the end of the output file if it does not", -" already end with Ctrl-Z.", -" ", -#endif /* CK_CTRLZ */ - -"SET FILE END-OF-LINE { CR, CRLF, LF }", -" Use this command to specify nonstandard line terminators for text files.", -" ", - -#ifndef NOXFER -"SET FILE INCOMPLETE { AUTO, KEEP, DISCARD }", -" What to do with an incompletely received file: KEEP, DISCARD, or AUTO.", -" AUTO (the default) means DISCARD if transfer is in text mode, KEEP if it", -" is in binary mode.", -" ", -#ifdef VMS -"SET FILE LABEL { ACL, BACKUP-DATE, NAME, OWNER, PATH } { ON, OFF }", -" Tells which items to include (ON) or exclude (OFF) in labeled file", -" transfers", -" ", -#else -#ifdef OS2 -"SET FILE LABEL { ARCHIVE, READ-ONLY, HIDDEN, SYSTEM, EXTENDED } { ON, OFF }", -" Tells which items to include (ON) or exclude (OFF) in labeled file", -" transfers.", -" ", -#endif /* OS2 */ -#endif /* VMS */ - -#ifdef UNIX -#ifdef DYNAMIC -"SET FILE LISTSIZE number", -" Changes the size of the internal wildcard expansion list. Use SHOW FILE", -" to see the current size. Use this command to increase the size if you get", -" a \"?Too many files\" error. Also see SET FILE STRINGSPACE.", -" ", -#endif /* DYNAMIC */ -#endif /* UNIX */ - -"SET FILE NAMES { CONVERTED, LITERAL }", -" File names are normally CONVERTED to \"common form\" during transmission", -" (e.g. lowercase to uppercase, extra periods changed to underscore, etc).", -" LITERAL means use filenames literally (useful between like systems). Also", -" see SET SEND PATHNAMES and SET RECEIVE PATHNAMES.", -" ", - -#ifdef UNIX -"SET FILE OUTPUT { { BUFFERED, UNBUFFERED } [ size ], BLOCKING, NONBLOCKING }", -" Lets you control the disk output buffer for incoming files. Buffered", -" blocking writes are normal. Nonblocking writes might be faster on some", -" systems but might also be risky, depending on the underlying file service.", -" Unbuffered writes might be useful in critical applications to ensure that", -" cached disk writes are not lost in a crash, but will probably also be", -" slower. The optional size parameter after BUFFERED or UNBUFFERED lets you", -" change the disk output buffer size; this might make a difference in", -" performance.", -" ", -#endif /* UNIX */ - -#ifdef PATTERNS -"SET FILE PATTERNS { ON, OFF, AUTO }", -" ON means to use filename pattern lists to determine whether to send a file", -" in text or binary mode. OFF means to send all files in the prevailing", -" mode. AUTO (the default) is like ON if the other Kermit accepts Attribute", -" packets and like OFF otherwise. FILE PATTERNS are used only if FILE SCAN", -" is OFF (see SET FILE SCAN).", -" ", -"SET FILE BINARY-PATTERNS [ [ ... ] ]", -" Zero or more filename patterns which, if matched, cause a file to be sent", -" in binary mode when FILE PATTERNS are ON. HELP WILDCARDS for a description" -, -" of pattern syntax. SHOW PATTERNS to see the current file pattern lists.", -" ", -"SET FILE TEXT-PATTERNS [ [ ... ] ]", -" Zero or more filename patterns which, if matched, cause a file to be sent", -" in text mode when FILE PATTERNS is ON; if a file does not match a text or", -" binary pattern, the prevailing SET FILE TYPE is used.", -" ", -#endif /* PATTERNS */ - -#ifdef VMS -"SET FILE RECORD-LENGTH number", -" Sets the record length for received files of type BINARY. Use this to", -" receive VMS BACKUP savesets or other fixed-format files that do not use", -" the default record length of 512.", -" ", -#endif /* VMS */ - -"SET FILE SCAN { ON [ size ], OFF }", -" If TRANSFER MODE is AUTOMATIC and FILE SCAN is ON (as it is by default)", -" Kermit peeks at the file's contents to see if it's text or binary. Use", -" SET FILE SCAN OFF to disable file peeking, while still keeping TRANSFER", -" MODE automatic to allow name patterns and other methods. The optional", -" size is the number of file bytes to scan, 49152 by default. -1 means to", -" scan the whole file. Also see SET FILE PATTERNS.", -" ", - -#ifdef UNIX -#ifdef DYNAMIC -"SET FILE STRINGSPACE number", -" Changes the size (in bytes) of the internal buffer that holds lists of", -" filenames such as wildcard expansion lists. Use SHOW FILE to see the", -" current size. Use this command to increase the size if you get a", -" \"?String space exhausted\" error. Also see SET FILE LISTSIZE.", -" ", -#endif /* DYNAMIC */ -#endif /* UNIX */ - -#ifdef UNICODE -"SET FILE UCS BOM { ON, OFF }", -" Whether to write a Byte Order Mark when creating a UCS-2 file.", -" ", -"SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }", -" Byte order to use when creating UCS-2 files, and to use when reading UCS-2", -" files that do not start with a Byte Order Mark.", -" ", -#endif /* UNICODE */ - -"SET FILE WARNING { ON, OFF }", -" SET FILE WARNING is superseded by the newer command, SET FILE", -" COLLISION. SET FILE WARNING ON is equivalent to SET FILE COLLISION RENAME", -" and SET FILE WARNING OFF is equivalent to SET FILE COLLISION OVERWRITE.", -#endif /* NOXFER */ -"" }; - -static char *hmxyhsh[] = { -"Syntax: SET HANDSHAKE { NONE, XON, LF, BELL, ESC, CODE number }", -" Character to use for half duplex line turnaround handshake during file", -" transfer. C-Kermit waits for this character from the other computer", -" before sending its next packet. Default is NONE; you can give one of the", -" other names like BELL or ESC, or use SET HANDSHAKE CODE to specify the", -" numeric code value of the handshake character. Type SET HANDSH ? for a", -" complete list of possibilities.", -"" }; - -#ifndef NOSERVER -static char *hsetsrv[] = { -"SET SERVER CD-MESSAGE {ON,OFF}", -" Tells whether the server, after successfully executing a REMOTE CD", -" command, should send the contents of the new directory's READ.ME", -" (or similar) file to your screen.", -" ", -"SET SERVER CD-MESSAGE FILE name", -" Tells the name of the file to be displayed as a CD-MESSAGE, such as", -" READ.ME (SHOW SERVER tells the current CD-MESSAGE FILE name).", -" To specify more than one filename to look for, use {{name1}{name2}..}.", -" Synonym: SET CD MESSAGE FILE .", -" ", -"SET SERVER DISPLAY {ON,OFF}", -" Tells whether local-mode C-Kermit during server operation should put a", -" file transfer display on the screen. Default is OFF.", -" ", -"SET SERVER GET-PATH [ directory [ directory [ ... ] ] ]", -" Tells the C-Kermit server where to look for files whose names it receives", -" from client GET commands when the names are not fully specified pathnames.", -" Default is no GET-PATH, so C-Kermit looks only in its current directory.", -" ", -"SET SERVER IDLE-TIMEOUT seconds", -" Idle time limit while in server mode, 0 for no limit.", -#ifndef OS2 -" NOTE: SERVER IDLE-TIMEOUT and SERVER TIMEOUT are mutually exclusive.", -#endif /* OS2 */ -" ", -"SET SERVER KEEPALIVE {ON,OFF}", -" Tells whether C-Kermit should send \"keepalive\" packets while executing", -" REMOTE HOST commands, which is useful in case the command takes a long", -" time to produce any output and therefore might cause the operation to time", -" out. ON by default; turn it OFF if it causes trouble with the client or", -" slows down the server too much.", -" ", -"SET SERVER LOGIN [ username [ password [ account ] ] ]", -" Sets up a username and optional password which must be supplied before", -" the server will respond to any commands other than REMOTE LOGIN. The", -" account is ignored. If you enter SET SERVER LOGIN by itself, then login", -" is no longer required. Only one SET SERVER LOGIN command can be in effect", -" at a time; C-Kermit does not support multiple user/password pairs.", -" ", -"SET SERVER TIMEOUT n", -" Server command wait timeout interval, how often the C-Kermit server issues", -" a NAK while waiting for a command packet. Specify 0 for no NAKs at all.", -" Default is 0.", -"" -}; -#endif /* NOSERVER */ - -static char *hmhrmt[] = { -#ifdef NEWFTP -"The REMOTE command sends file management instructions or other commands", -"to a Kermit or FTP server. If you have a single connection, the command is", -"directed to the server you are connected to; if you have multiple connections" -, -"the command is directed according to your GET-PUT-REMOTE setting.", -#else -"The REMOTE command sends file management instructions or other commands", -"to a Kermit server. There should already be a Kermit running in server", -"mode on the other end of the connection.", -#endif /* NEWFTP */ -"Type REMOTE ? to see a list of available remote commands. Type HELP REMOTE", -"xxx to get further information about a particular remote command xxx.", -" ", -"All REMOTE commands except LOGIN and LOGOUT have R-command shortcuts;", -"for example, RDIR for REMOTE DIR, RCD for REMOTE CD, etc.", -" ", -#ifdef NEWFTP -#ifdef LOCUS -"Also see: HELP SET LOCUS, HELP FTP, HELP SET GET-PUT-REMOTE.", -#else -"Also see: HELP FTP, HELP SET GET-PUT-REMOTE.", -#endif /* LOCUS */ -#else -#ifdef LOCUS -"Also see: HELP SET LOCUS.", -#endif /* LOCUS */ -#endif /* NEWFTP */ -"" }; - -#ifndef NOSPL -static char *ifhlp[] = { "Syntax: IF [NOT] condition commandlist", -" ", -"If the condition is (is not) true, do the commandlist. The commandlist", -"can be a single command, or a list of commands separated by commas and", -"enclosed in braces. The condition can be a single condition or a group of", -"conditions separated by AND (&&) or OR (||) and enclosed in parentheses.", -"If parentheses are used they must be surrounded by spaces. Examples:", -" ", -" IF EXIST oofa.txt ", -" IF ( EXIST oofa.txt || = \\v(nday) 3 ) ", -" IF ( EXIST oofa.txt || = \\v(nday) 3 ) { , , ... }", -" ", -"The conditions are:", -" ", -" SUCCESS - The previous command succeeded", -" OK - Synonym for SUCCESS", -" FAILURE - The previous command failed", -" ERROR - Synonym for FAILURE", -" FLAG - Succeeds if SET FLAG ON, fails if SET FLAG OFF", -" BACKGROUND - C-Kermit is running in the background", -#ifdef CK_IFRO -" FOREGROUND - C-Kermit is running in the foreground", -" REMOTE-ONLY - C-Kermit was started with the -R command-line option", -#else -" FOREGROUND - C-Kermit is running in the foreground", -#endif /* CK_IFRO */ -" KERBANG - A Kerbang script is running", -" ALARM - SET ALARM time has passed", -" ASKTIMEOUT - The most recent ASK, ASKQ, GETC, or GETOK timed out", -" EMULATION - Succeeds if executed while in CONNECT mode", -#ifdef OS2 -" TAPI - Current connection is via a Microsoft TAPI device", -#endif /* OS2 */ -" ", -" MS-KERMIT - Program is MS-DOS Kermit", -" C-KERMIT - Program is C-Kermit", -" K-95 - Program is Kermit 95", -" GUI - Program runs in a GUI window", -" ", -" AVAILABLE CRYPTO - Encryption is available", -" AVAILABLE KERBEROS4 - Kerberos 4 authentication is available", -" AVAILABLE KERBEROS5 - Kerberos 5 authentication is available", -" AVAILABLE NTLM - NTLM authentication is available", -" AVAILABLE SRP - SRP authentication is available", -" AVAILABLE SSL - SSL/TLS authentication is available", -" MATCH string pattern - Succeeds if string matches pattern", -#ifdef CKFLOAT -" FLOAT number - Succeeds if floating-point number", -#endif /* CKFLOAT */ -" COMMAND word - Succeeds if word is built-in command", -" DEFINED variablename or macroname - The named variable or macro is defined", -" DECLARED arrayname - The named array is declared", -" NUMERIC variable or constant - The variable or constant is numeric", -" EXIST filename - The named file exists", -" ABSOLUTE filename - The filename is absolute, not relative", -#ifdef CK_TMPDIR -" DIRECTORY string - The string is the name of a directory", -#endif /* CK_TMPDIR */ -" READABLE filename - Succeeds if the file is readable", -" WRITEABLE filename - Succeeds if the file is writeable", -#ifdef ZFCDAT -" NEWER file1 file2 - The 1st file is newer than the 2nd one", -#endif /* ZFCDAT */ -" OPEN { READ-FILE,SESSION-LOG,...} - The given file or log is open", -#ifndef NOLOCAL -" OPEN CONNECTION - A connection is open", -#endif /* NOLOCAL */ -" KBHIT - A key has been pressed", -" ", -" VERSION - equivalent to \"if >= \\v(version) ...\"", -" COUNT - subtract one from COUNT, execute the command if the result is", -" greater than zero (see SET COUNT)", -" ", -" EQUAL s1 s2 - s1 and s2 (character strings or variables) are equal", -" LLT s1 s2 - s1 is lexically (alphabetically) less than s2", -" LGT s1 s1 - s1 is lexically (alphabetically) greater than s2", -" ", -" = n1 n2 - n1 and n2 (numbers or variables containing numbers) are equal", -" < n1 n2 - n1 is arithmetically less than n2", -" <= n1 n2 - n1 is arithmetically less than or equal to n2", -" > n1 n2 - n1 is arithmetically greater than n2", -" >= n1 n2 - n1 is arithmetically greater than or equal to n2", -" ", -" (number by itself) - fails if the number is 0, succeeds otherwise", -" ", -" TRUE - always succeeds", -" FALSE - always fails", -" ", -"The IF command may be followed on the next line by an ELSE command. Example:", -" ", -" IF < \\%x 10 ECHO It's less", -" ELSE echo It's not less", -" ", -"It can also include an ELSE part on the same line if braces are used:", -" ", -" IF < \\%x 10 { ECHO It's less } ELSE { ECHO It's not less }", -" ", -"Also see HELP WILDCARD (for IF MATCH pattern syntax).", -"" }; - -static char *hmxxeval[] = { "Syntax: EVALUATE variable expression", -" Evaluates the expression and assigns its value to the given variable.", -" The expression can contain numbers and/or numeric-valued variables or", -" functions, combined with mathematical operators and parentheses in", -" traditional notation. Operators include +-/*(), etc. Example:", -" EVALUATE \\%n (1+1) * (\\%a / 3).", -" ", -" NOTE: Prior to C-Kermit 7.0, the syntax was \"EVALUATE expression\"", -" (no variable), and the result was printed. Use SET EVAL { OLD, NEW }", -" to choose the old or new behavior, which is NEW by default.", -" ", -"Alse see: HELP FUNCTION EVAL.", -"" }; -#endif /* NOSPL */ - -static char *hmxxexit[] = { -"Syntax: EXIT (or QUIT) [ number [ text ] ]", -" Exits from the Kermit program, closing all open files and devices.", -" If a number is given it becomes Kermit's exit status code. If text is", -" included, it is printed. Also see SET EXIT.", -"" }; - -#ifndef NOSPL -static char *ifxhlp[] = { "\ -Syntax: XIF condition { commandlist } [ ELSE { commandlist } ]", -" Obsolete. Same as IF (see HELP IF).", -"" }; - -static char *forhlp[] = { "\ -Syntax: FOR variablename initial-value final-value increment { commandlist }", -" FOR loop. Execute the comma-separated commands in the commandlist the", -" number of times given by the initial value, final value and increment.", -" Example: FOR \\%i 10 1 -1 { pause 1, echo \\%i }", "" }; - -static char *whihlp[] = { "\ -Syntax: WHILE condition { commandlist }", -" WHILE loop. Execute the comma-separated commands in the bracketed", -" commandlist while the condition is true. Conditions are the same as for", -" IF commands.", -"" }; - -static char *swihlp[] = { -"Syntax: SWITCH { case-list }", -" Selects from a group of commands based on the value of a variable.", -" The case-list is a series of lines like these:", -" ", -" :x, command, command, ..., break", -" ", -" where \"x\" is a possible value for the variable. At the end of the", -" case-list, you can put a \"default\" label to catch when the variable does", -" not match any of the labels:", -" ", -" :default, command, command, ...", -" ", -"The case label \"x\" can be a character, a string, a variable, a function", -"invocation, a pattern, or any combination of these. See HELP WILDCARDS", -"for information about patterns.", -""}; - -static char *openhlp[] = { -"Syntax: OPEN mode filename", -" For use with READ and WRITE commands. Open the local file in the", -" specified mode: READ, WRITE, or APPEND. !READ and !WRITE mean to read", -" from or write to a system command rather than a file. Examples:", -" ", -" OPEN READ oofa.txt", -" OPEN !READ sort foo.bar", -"" }; - -static char *hxxask[] = { -"Syntax: ASK [ switches ] variablename [ prompt ]", -"Example: ASK \\%n { What is your name\\? }", -" Issues the prompt and defines the variable to be whatever is typed in", -" response, up to the terminating carriage return. Use braces to preserve", -" leading and/or trailing spaces in the prompt.", -" ", -"Syntax: ASKQ [ switches ] variablename [ prompt ]", -"Example: ASKQ \\%p { Password:}", -" Like ASK except the response does not echo on the screen.", -" ", -"Switches:", -" /DEFAULT:text", -" Text to supply if the user enters a blank response or the /TIMEOUT", -" limit expired with no response.", -" ", -#ifdef OS2 -" /POPUP", -" The prompt and response dialog takes place in a text-mode popup.", -" K95 only; in C-Kermit this switch is ignored.", -" ", -#ifdef KUI -" /GUI", -" The prompt and response dialog takes place in a GUI popup.", -" K95 GUI version only; in C-Kermit and the K95 console version,", -" this switch is ignored.", -" ", -#endif /* KUI */ -#endif /* OS2 */ -" /TIMEOUT:number", -" If the response is not entered within the given number of seconds, the", -" command fails. This is equivalent to setting ASK-TIMER to a positive", -" number, except it applies only to this command. Also see SET ASK-TIMER.", -" NOTE: If a /DEFAULT: value was also given, it is supplied automatically", -" upon timeout and the command does NOT fail.", - -" ", -" /QUIET", -" Suppresses \"?Timed out\" message when /TIMEOUT is given and user doesn't", -" respond within the time limit.", -""}; -static char *hxxgetc[] = { -"Syntax: GETC variablename [ prompt ]", -"Example: GETC \\%c { Type any character to continue...}", -" Issues the prompt and sets the variable to the first character you type.", -" Use braces to preserve leading and/or trailing spaces in the prompt.", -" ", -"Also see SET ASK-TIMER.", -""}; - -static char *hmxytimer[] = { -"Syntax: SET ASK-TIMER number", -" For use with ASK, ASKQ, GETOK, and GETC. If ASK-TIMER is set to a number", -" greater than 0, these commands will time out after the given number of", -" seconds with no response. This command is \"sticky\", so to revert to", -" \ -untimed ASKs after a timed one, use SET ASK-TIMER 0. Also see IF ASKTIMEOUT.", -""}; - -static char *hxxdot[] = { -"Syntax: . ", -" Assigns the value to the variable in the manner indicated by the", -" assignment operator:", -" = Copies without evaluation (like DEFINE).", -" := Copies with evaluation (like ASSIGN).", -" ::= Copies with arithmetic evaluation (like EVALUATE).", -""}; - -static char *hxxdef[] = { -"Syntax: DEFINE name [ definition ]", -" Defines a macro or variable. Its value is the definition, taken", -" literally. No expansion or evaluation of the definition is done. Thus", -" if the definition includes any variable or function references, their", -" names are included, rather than their values (compare with ASSIGN). If", -" the definition is omitted, then the named variable or macro is undefined.", -" ", -"A typical macro definition looks like this:", -" ", -" DEFINE name command, command, command, ...", -" ", -"for example:", -" ", -" DEFINE vax set parity even, set duplex full, set flow xon/xoff", -" ", -"which defines a Kermit command macro called 'vax'. The definition is a", -"comma-separated list of Kermit commands. Use the DO command to execute", -"the macro, or just type its name, followed optionally by arguments.", -" ", -"The definition of a variable can be anything at all, for example:", -" ", -" DEFINE \\%a Monday", -" DEFINE \\%b 3", -" ", -"These variables can be used almost anywhere, for example:", -" ", -" ECHO Today is \\%a", -" SET BLOCK-CHECK \\%b", -"" }; - -static char *hxxass[] = { -"Syntax: ASSIGN variablename string.", -"Example: ASSIGN \\%a My name is \\%b.", -" Assigns the current value of the string to the variable (or macro).", -" The definition string is fully evaluated before it is assigned, so that", -" the values of any variables that are contained are used, rather than their", -" names. Compare with DEFINE. To illustrate the difference, try this:", -" ", -" DEFINE \\%a hello", -" DEFINE \\%x \\%a", -" ASSIGN \\%y \\%a", -" DEFINE \\%a goodbye", -" ECHO \\%x \\%y", -" ", -" This prints 'goodbye hello'.", "" }; - -static char *hxxdec[] = { -"Syntax: DECREMENT variablename [ number ]", -" Decrement (subtract one from) the value of a variable if the current value", -" is numeric. If the number argument is given, subtract that number", -" instead.", -" ", -"Examples: DECR \\%a, DECR \\%a 7, DECR \\%a \\%n", "" }; - -static char *hxxinc[] = { -"Syntax: INCREMENT variablename [ number ]", -" Increment (add one to) the value of a variable if the current value is", -" numeric. If the number argument is given, add that number instead.", -" ", -"Examples: INCR \\%a, INCR \\%a 7, INCR \\%a \\%n", "" }; -#endif /* NOSPL */ - -#ifdef ANYX25 -#ifndef IBMX25 -static char *hxxpad[] = { -"Syntax: PAD command", -"X.25 PAD commands:", -" ", -" PAD CLEAR - Clear the virtual call", -" PAD STATUS - Return the status of virtual call", -" PAD RESET - Send a reset packet", -" PAD INTERRUPT - Send an interrupt packet", -""}; -#endif /* IBMX25 */ - -static char *hxyx25[] = { -"Syntax: SET X.25 option { ON [ data ], OFF }", -" ", -"X.25 call options:", -" CLOSED-USER-GROUP { ON index, OFF }", -" Enable or disable closed user group call, where index is the group", -" index, 0 to 99.", -" REVERSE-CHARGE { ON, OFF }", -" Tell whether you want to reverse the charges for the call.", -" CALL-USER-DATA { ON string, OFF }", -" Specify call user-data for the X.25 call.", -""}; -#endif /* ANYX25 */ - -static char *hxyprtr[] = { -#ifdef PRINTSWI -"Syntax: SET PRINTER [ switches ] [ name ]", -" ", -" Specifies the printer to be used for transparent-print, autoprint, and", -" screen-dump material during terminal emulation, as well as for the PRINT", -" command, plus various options governing print behavior.", -" ", -"Switches for specifying the printer by type:", -" ", -"/NONE", -" Include this switch to specify that all printer actions should simply be", -" skipped. Use this, for example, if you have no printer.", -" ", -"/DOS-DEVICE[:name]", -" Include this to declare a DOS printer and to specify its name, such as", -" PRN, LPT1, etc.", -" ", -#ifdef NT -"/WINDOWS-QUEUE[:[queue-name]]", -" Include this to declare a Windows printer and specify its queue name.", -" Type question mark (?) after the colon (:) to see a list of known queue", -" names. If the colon is absent, the switch indicates the currently", -" selected printer is a Windows Print Queue. If the colon is provided", -" and the name is absent, the Windows Print Queue chosen as the Default", -" Printer is selected.", -" ", -#endif /* NT */ -"/FILE[:name]", -" Specifies that all printer material is to be appended to the named file,", -" rather than being sent to a printer. If the file does not exist, it is", -" created the first time any material is to be printed.", -" ", -"/PIPE[:name]", -" Specifies that all printer material is to be sent as standard input to", -" the program or command whose name is given. Example:", -" ", -" SET PRINTER /PIPE:{textps > lpt1}", -" ", -"If you give a printer name without specifying any of these switches, then it", -"is assumed to be a DOS printer device or filename unless the name given", -"(after removing enclosing braces, if any) starts with \"|\", \ -in which case it", -"is a pipe. Examples:", -" ", -" SET PRINTER LPT1 <-- DOS device", -" SET PRINTER {| textps > lpt1} <-- Pipe", -" ", -"The next group of switches tells whether the printer is one-way or", -"bidirectional (two-way):", -" ", -"/OUTPUT-ONLY", -" Include this to declare the printer capable only of receiving material to", -" be printed, but not sending anything back. This is the normal kind of", -" printer, Kermit's default kind, and the opposite of /BIDIRECTIONAL.", -" ", -"/BIDIRECTIONAL", -" Include this to declare the printer bidirectional. This is the opposite ", -" of /OUTPUT-ONLY. You can also use this option with serial printers, even", -" if they aren't bidirectional, in case you need to specify speed, flow", -" control, or parity.", -" ", -"The next group applies only to bidirectional and/or serial printers:", -" ", -"/FLOW-CONTROL:{NONE,XON/XOFF,RTS/CTS,KEEP}", -" Flow control to use with a serial bidirectional printer, default KEEP;", -#ifdef NT -" i.e. use whatever the Windows driver for the port normally uses.", -#else -" i.e. use whatever the OS/2 driver for the port normally uses.", -#endif /* NT */ -" ", -"/PARITY:{NONE,EVEN,ODD,SPACE,MARK}", -" Parity to use with a serial printer, default NONE; i.e. use 8 data bits", -" and no parity. If you omit the colon and the keyword, NONE is selected.", -" ", -"/SPEED:number", -" Interface speed, in bits per second, to use with a serial printer, such as", -" 2400, 9600, 19200, etc. Type SET PRINTER /SPEED:? for a list of possible", -" speeds.", -" ", -"The next group deals with print jobs -- how to identify them, how to start", -"them, how to terminate them:", -" ", -"/TIMEOUT[:number]", -" Used with host-directed transparent or auto printing, this is the number", -" of seconds to wait after the host closes the printer before terminating", -" the print job if the printer is not opened again during the specified", -" amount of time.", -" ", -"/JOB-HEADER-FILE[:filename]", -" The name of a file to be sent to the printer at the beginning of each", -" print job, as a burst page, or to configure the printer. Normally no file", -" is is sent.", -" ", -"/END-OF-JOB-STRING[:string]", -" String of characters to be sent to the printer at the end of the print", -" job, usually used to force the last or only page out of the printer. When", -" such a string is needed, it usually consists of a single formfeed: \"set", -" printer /end-of-job:{\\12}\". No end-of-job string is sent unless you", -" specify one with this option. If the string contains any spaces or", -" control characters (even in backslash notation, as above), enclose it in", -" braces.", -" ", -"The next group is for use with printers that print only PostScript:", -" ", -"/POSTSCRIPT or /PS", -" Indicates that K95 should convert all text to PostScript before sending", -" it to the printer. The fixed-pitch Courier-11 font is used.", -" ", -"/WIDTH:number", -" Specifies the width of the page in characters. If this switch is not", -" given, 80 is used.", -" ", -"/HEIGHT:number", -" Specifies the height of the page in lines. If this switch is not given", -" 66 is used.", -" ", -"/NOPOSTSCRIPT or /NOPS", -" Indicates that K95 should not convert all text to PostScript before", -" sending it to the printer.", -" ", -"The final switch is for use with AutoPrint mode and Screen Dumps", -" ", -"/CHARACTER-SET:", -" Specifies the character set used by the printer which may be different", -" from both the character set used by the host and by the local computer.", -" The default value is CP437.", -" ", -"SHOW PRINTER displays your current printer settings.", -#else -#ifdef UNIX -"Syntax: SET PRINTER [ { |command, filename } ]", -" Specifies the command (such as \"|lpr\") or filename to be used by the", -" PRINT command. If a filename is given, each PRINT command appends to the", -" given file. If the SET PRINTER argument contains spaces, it must be", -" enclosed in braces, e.g. \"set printer {| lpr -Plaser}\". If the argument", -" is omitted the default value is restored. SHOW PRINTER lists the current", -" printer. See HELP PRINT for further info.", -#else -"Sorry, SET PRINTER not available yet.", -#endif /* UNIX */ -#endif /* PRINTSWI */ -""}; - -#ifdef OS2 -#ifdef BPRINT -static char *hxybprtr[] = { -"Syntax: SET BPRINTER [ portname speed [ parity [ flow-control ] ] ]", -" (Obsolete, replaced by SET PRINTER /BIDIRECTIONAL.)", -""}; -#endif /* BPRINT */ -#endif /* OS2 */ - -static char *hxyexit[] = { -"Syntax: SET EXIT HANGUP { ON, OFF }", -" When ON (which is the default), C-Kermit executes an implicit HANGUP and", -" CLOSE command on the communications device or connection when it exits.", -" When OFF, Kermit skips this sequence.", -" ", -"Syntax: SET EXIT ON-DISCONNECT { ON, OFF }", -" When ON, C-Kermit EXITs automatically when a network connection", -" is terminated either by the host or by issuing a HANGUP command.", -" ", -"Syntax: SET EXIT STATUS number", -#ifdef NOSPL -" Set C-Kermit's program return code to the given number.", -#else -" Set C-Kermit's program return code to the given number, which can be a", -" constant, variable, function result, or arithmetic expression.", -#endif /* NOSPL */ -" ", -"Syntax: SET EXIT WARNING { ON, OFF, ALWAYS }", -" When EXIT WARNING is ON, issue a warning message and ask for confirmation", -" before EXITing if a connection to another computer might still be open.", -" When EXIT WARNING is ALWAYS, confirmation is always requested. When OFF", -" it is never requested. The default is ON.", -"" }; - -#ifndef NOSPL -static char *hxxpau[] = { -"Syntax: PAUSE [ { number-of-seconds, hh:mm:ss } ]", -"Example: PAUSE 3 or PAUSE 14:52:30", -" Do nothing for the specified number of seconds or until the given time of", -" day in 24-hour hh:mm:ss notation. If the time of day is earlier than the", -" current time, it is assumed to be tomorrow. If no argument given, one", -" second is used. The pause can be interrupted by typing any character on", -" the keyboard unless SLEEP CANCELLATION is OFF. If interrupted, PAUSE", -" fails, otherwise it succeeds. Synonym: SLEEP.", -"" }; - -static char *hxxmsl[] = { -"Syntax: MSLEEP [ number ]", -"Example: MSLEEP 500", -" Do nothing for the specified number of milliseconds; if no number given,", -" 100 milliseconds.","" }; -#endif /* NOSPL */ - -#ifndef NOPUSH -extern int nopush; -static char *hxxshe[] = { -"Syntax: !, @, RUN, PUSH, or SPAWN, optionally followed by a command.", -" Gives the command to the local operating system's command processor, and", -" displays the results on the screen. If the command is omitted, enters the", -" system's command line interpreter or shell; exit from it (the command for", -" this is usually EXIT or QUIT or LOGOUT) to return to Kermit.", -"" -}; -#endif /* NOPUSH */ - -#ifndef NOXMIT -static char *hxxxmit[] = { -"Syntax: TRANSMIT [ switches ] filename", -" Sends the contents of a file, without any error checking or correction,", -" to the computer on the other end of your SET LINE or SET HOST connection", -" (or if C-Kermit is in remote mode, displays it on the screen). The", -" filename is the name of a single file (no wildcards) to be sent or, if", -" the /PIPE switch is included, the name of a command whose output is to be", -" sent.", -" ", -" The file is sent according to your current FILE TYPE setting (BINARY or", -" TEXT), which you can override with a /BINARY or /TEXT switch without", -" changing the global setting. In text mode, it is sent a line at a time,", -" with carriage return at the end of each line (as if you were typing it at", -" your keyboard), and C-Kermit waits for a linefeed to echo before sending", -" the next line; use /NOWAIT to eliminate the feedback requirement. In", -" binary mode, it is sent a character at a time, with no feedback required.", -" ", -" Normally the transmitted material is echoed to your screen. Use SET", -" TRANSMIT ECHO OFF or the /NOECHO switch to suppress echoing. Note that", -" TRANSMIT /NOECHO /NOWAIT /BINARY is a special case, that more or less", -" blasts the file out at full speed.", -" ", -#ifndef NOCSETS -" Character sets are translated according to your current FILE and TERMINAL", -" CHARACTER-SET settings when TRANSMIT is in text mode. Include /TRANSPARENT" -, -" to disable character-set translation in text mode (/TRANSPARENT implies", -" /TEXT).", -" ", -#endif /* NOCSETS */ -" There can be no guarantee that the other computer will receive the file", -" correctly and completely. Before you start the TRANSMIT command, you", -" must put the other computer in data collection mode, for example by", -" starting a text editor. TRANSMIT may be interrupted by Ctrl-C. Synonym:", -" XMIT. See HELP SET TRANSMIT for further information.", -"" }; -#endif /* NOXMIT */ - -#ifndef NOCSETS -static char *hxxxla[] = { -"Syntax: TRANSLATE file1 cs1 cs2 [ file2 ]", -" Translates file1 from the character set cs1 into the character set cs2", -" and stores the result in file2. The character sets can be any of", -" C-Kermit's file character sets. If file2 is omitted, the translation", -" is displayed on the screen. An appropriate intermediate character-set", -" is chosen automatically, if necessary. Synonym: XLATE. Example:", -" ", -" TRANSLATE lasagna.lat latin1 italian lasagna.nrc", -" ", -" Multiple files can be translated if file2 is a directory or device name,", -" rather than a filename, or if file2 is omitted.", -"" }; -#endif /* NOCSETS */ - -#ifndef NOSPL -static char *hxxwai[] = { -"Syntax: WAIT { number-of-seconds, hh:mm:ss } [ ]", -" ", -"Examples:", -" wait 5 cd cts", -" wait 23:59:59 cd", -" ", -" Waits up to the given number of seconds or the given time of day for the", -" specified item or event, which can be FILE, the name(s) of one or more", -" modem signals, or nothing. If nothing is specified, WAIT acts like SLEEP.", -" If one or more modem signal names are given, Kermit waits for the specified" -, -" modem signals to appear on the serial communication device.", -" Sets FAILURE if the signals do not appear in the given time or interrupted", -" from the keyboard during the waiting period.", -" ", -"Signals:", -" cd = Carrier Detect;", -" dsr = Dataset Ready;", -" cts = Clear To Send;", -" ri = Ring Indicate.", -" ", -"If you want Kermit to wait for a file event, then the syntax is:", -" ", -" WAIT