X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=ckcplm.txt;fp=ckcplm.txt;h=9829987ac6d28d65ae357d7071157286a9a5512b;hb=d67a876428f8c6dec71b4fe76d75f3994abc031c;hp=0000000000000000000000000000000000000000;hpb=c8091b603419995c9b3d1b7b1d2904c917415af0;p=ckermit.git diff --git a/ckcplm.txt b/ckcplm.txt new file mode 100644 index 0000000..9829987 --- /dev/null +++ b/ckcplm.txt @@ -0,0 +1,3046 @@ + + [1]The Columbia Crown The Kermit Project | Columbia University + 612 West 115th Street, New York NY 10025 USA o [2]kermit@columbia.edu + ...since 1981 + [3]Home [4]Kermit 95 [5]C-Kermit [6]Scripts [7]Current [8]New [9]FAQ + [10]Support + +C-Kermit Program Logic Manual + + Frank da Cruz + [11]The Kermit Project + [12]Columbia University + + As of: C-Kermit 9.0.300, 30 June 2011 + Last update: Tue Jun 28 08:59:18 2011 + + IF YOU ARE READING A PLAIN-TEXT version of this document, note that + this file is a plain-text dump of a Web page. You can visit the + original (and possibly more up-to-date) Web page here: + + [13]http://www.columbia.edu/kermit/ckcplm.html + + [ [14]C-Kermit Home ] [ [15]Kermit Home ] + +CONTENTS + + 1. [16]INTRODUCTION + 2. [17]FILES + 3. [18]SOURCE CODE PORTABILITY AND STYLE + 4. [19]MODULES + 4.A. [20]Group A: Library Routines + 4.B. [21]Group B: Kermit File Transfer + 4.C. [22]Group C: Character-Set Conversion + 4.D. [23]Group D: User Interface + 4.E. [24]Group E: Platform-Dependent I/O + 4.F. [25]Group F: Network Support + 4.G. [26]Group G: Formatted Screen Support + 4.H. [27]Group H: Pseudoterminal Support + 4.I. [28]Group I: Security + I. [29]APPENDIX I: FILE PERMISSIONS + +1. INTRODUCTION + + The Kermit Protocol is specified in the book Kermit, A File Transfer + Protocol by Frank da Cruz, Digital Press / Butterworth Heinemann, + Newton, MA, USA (1987), 379 pages, ISBN 0-932376-88-6. It is assumed + the reader is familiar with the Kermit protocol specification. + + This file describes the relationship among the modules and functions of + C-Kermit 5A and later, and other programming considerations. C-Kermit + is designed to be portable to any kind of computer that has a C + compiler. The source code is broken into many files that are grouped + according to their function, as shown in the [30]Contents. + + C-Kermit has seen constant development since 1985. Throughout its + history, there has been a neverending tug-of-war among: + + a. Functionality: adding new features, fixing bugs, improving + performance. + b. Adding support for new platforms. + c. "Buzzword 1.0 compliance". + + The latter category is the most frustrating, since it generally + involves massive changes just to keep the software doing what it did + before in some new setting: e.g. the K&R-to-ANSIC conversion (which had + to be done, of course, without breaking K&R); Y2K (not a big deal in + our case); the many and varied UNIX and other API "standards"; IPv6. + + [ [31]Contents ] [ [32]C-Kermit ] [ [33]Kermit Home ] + +2. FILES + + C-Kermit source files begin with the two letters "ck", for example + ckutio.c. Filenames are kept short (6.3) for maximum portability and + (obviously I hope) do not contain spaces or more than one period. The + third character in the name denotes something about the function group + and the expected level of portability: + + a General descriptive material and documentation (text) + b BOO file encoders and decoders (obsolete) + c All platforms with C compilers (*) + d Data General AOS/VS + e Reserved for "ckermit" files, like ckermit.ini, ckermit2.txt + f (reserved) + g (reserved) + h (reserved) + i Commodore Amiga (Intuition) + j (unused) + k (unused) + l Stratus VOS + m Macintosh with Mac OS 1-9 + n Microsoft Windows NT/2000/XP + o OS/2 and/or Microsoft Windows 9x/ME/NT/2000/XP + p Plan 9 from Bell Labs + q (reserved) + r DEC PDP-11 with RSTS/E (never used, open for reassigment) + s Atari ST GEMDOS (last supported in version 5A(189)) + t DEC PDP-11 with RT-11 (never used, open for reassigment) + u Unix-based operating systems (*) + v VMS and OpenVMS + w Wart (Lex-like preprocessor, platform independent) + x (reserved) + y (reserved) + z (reserved) + 0-3 (reserved) + 4 IBM AS/400 + 5-8 (reserved) + 9 Microware OS-9 + _ Encryption modules + + (*) In fact there is little distinction between the ckc*.* and cku*.* + categories. It would make more sense for all cku*.* modules to be + ckc*.* ones, except ckufio.c, ckutio.c, ckucon.c, ckucns.c, and + ckupty.c, which truly are specific to Unix. The rest (ckuus*.c, + ckucmd.c, etc) are quite portable. + + One hint before proceeding: functions are scattered all over the ckc*.c + and cku*.c modules, where function size has begun to take precedence + over the desirability of grouping related functions together, the aim + being to keep any particular module from growing disproportionately + large. The easiest way (in UNIX) to find out in what source file a + given function is defined is like this (where the desired function is + foo()...): + + grep ^foo\( ck*.c + + This works because the coding convention has been to make function + names always start on the left margin with their contents indented, for + example: + +static char * +foo(x,y) int x, y; { + ... +} + + Also note the style for bracket placement. This allows bracket-matching + text editors (such as EMACS) to help you make sure you know which + opening bracket a closing bracket matches, particularly when the + opening bracket is above the visible screen, and it also makes it easy + to find the end of a function (search for '}' on the left margin). + + Of course EMACS tags work nicely with this format too: + + $ cd kermit-source-directory + $ etags ck[cu]*.c + $ emacs + Esc-X Visit-Tags-Table + + (but remember that the source file for ckcpro.c is [34]ckcpro.w!) + + Also: + + * Tabs should be set every 8 spaces, as on a VT100. + * All lines must no more than 79 characters wide after tab expansion. + * Note the distinction between physical tabs (ASCII 9) and the + indentation conventions, which are: 4 for block contents, 2 for + most other stuff (obviously this is not a portability issue, just + style). + + [ [35]Contents ] [ [36]C-Kermit ] [ [37]Kermit Home ] + +3. SOURCE CODE PORTABILITY AND STYLE + + C-Kermit was designed in 1985 as a platform-independent replacement for + the earlier Unix Kermit. c-Kermit's design was expected to promote + portability, and judging from the number of platforms to which it has + been adapted since then, the model is effective, if not ideal + (obviously if we had it all to do over, we'd change a few things). To + answer the oft-repeated question: "Why are there so many #ifdefs?", + it's because: + + * Many of them are related to feature selection and program size, and + so need to be there anyway. + * Those that treat compiler, library, platform, header-file, and + similar differences have built up over time as hundreds of people + all over the world adapted C-Kermit to their particular + environments and sent back their changes. There might be more + politically-correct ways to achieve portability, but this one is + natural and proven. The basic idea is to introduce changes that can + be selected by defining a symbol, which, if not defined, leaves the + program exactly as it was before the changes. + * Although it might be possible to "clean up" the "#ifdef mess", + nobody has access to all the hundreds of platforms served by the + #ifdefs to check the results. + + And to answer the second-most-oft-repeated question: "Why don't you + just use GNU autoconfig / automake / autowhatever instead of + hard-coding all those #ifdefs?" Answers: + + * The GNU tools are not available on all the platforms where C-Kermit + must be built and I wouldn't necessarily trust them if they were. + * Each platform is a moving target, so the tools themselves would + need to updated before Kermit could be updated. + * It would only add another layer of complexity to an already complex + process. + * Conversion at this point would not be practical unless there was a + way to test the results on all the hundreds of platforms where + C-Kermit is supposed to build. + + When writing code for the system-indendent C-Kermit modules, please + stick to the following coding conventions to ensure portability to the + widest possible variety of C preprocessors, compilers, and linkers, as + well as certain network and/or email transports. The same holds true + for many of the "system dependent" modules too; particularly the Unix + ones, since they must be buildable by a wide variety of compilers and + linkers, new and old. + + This list does not purport to be comprehensive, and although some items + on it might seem far-fetched, they would not be listed unless I had + encountered them somewhere, some time. I wish I had kept better records + so I could cite specific platforms and compilers. + + * Try to keep variable and function names unique within 6 characters, + especially if they are used across modules, since 6 is the maximum + for some old linkers (actually, this goes back to TOPS-10 and -20 + and other old DEC OS's where C-Kermit never ran anyway; a more + realistic maximum is probably somewhere between 8 and 16). We know + for certain that VAX C has a 31-character max because it complains + -- others might not complain, but just silently truncate, thus + folding two or more routines/variables into one. + * Keep preprocessor symbols unique within 8 characters; that's the + max for some preprocessors (sorry, I can't give a specific example, + but in 1988 or thereabouts, I had to change character-set symbols + like TC_LATIN1 and TC_LATIN2 to TC_1LATIN and TC_2LATIN because the + digits were being truncated and ignored on a platform where I + actually had to build C-Kermit 5A; unfortunately I didn't note + which platform -- maybe some early Ultrix version?) + * Don't create preprocessor symbols, or variable or function names, + that start with underscore (_). These are usually reserved for + internal use by the compiler and header files. + * Don't put #include directives inside functions or { blocks }. + * Don't use the #if or #elif preprocessor constructions, only use + #ifdef, #ifndef, #define, #undef, and #endif. + * Put tokens after #endif in comment brackets, e.g. #endif /* FOO */. + * Don't indent preprocessor statements - # must always be first char + on line. + * Don't put whitespace after # in preprocessor statements. + * Don't use #pragma, even within #ifdefs -- it makes some + preprocessors give up. + * Same goes for #module, #if, etc - #ifdefs do NOT protect them. + * Don't use logical operators in preprocessor constructions. + * Avoid #ifdefs inside argument list to function calls (I can't + remember why this one is here, but probably needn't be; we do this + all the time). + * Always cast strlen() in expressions to int: + if ((int)strlen(foo) < x)... + * Any variable whose value might exceed 16383 should be declared as + long, or if that is not possible, then as unsigned. + * Avoid typedefs; they might be portable but they are very confusing + and there's no way to test for their presence or absence at compile + time. Use preprocessor symbols instead if possible; at least you + can test their definitions. + * Unsigned long is not portable; use a preprocessor symbol (Kermit + uses ULONG for this). + * Long long is not portable. If you really need it, be creative. + * Similarly 1234LL is not portable, nor almost any other constant + modifier other than L. + * Unsigned char is not portable, use CHAR (a preprocessor symbol + defined in the Kermit header files) and always take precautions + against character signage (more about this [38]below). + * Don't use initializers with automatic arrays or structs: it's not + portable. + * Don't use big automatic arrays or structs in functions that might + be called recursively; some platforms have fixed-size stacks (e.g. + Windows 9x: 256K) and recursive functions crash with stack + overflow. Even when there is not a compiler limitation, this causes + memory to be consumed without bound, and can end up filling swap + space. + * Don't assume that struct assignment performs a copy, or that it + even exists. + * Don't use sizeof to get the size of an array; someone might come + along later and and change it from static to malloc'd. Always use a + symbol to refer to the array's size. + * Don't put prototypes for static functions into header files that + are used by modules that don't contain that function; the link step + can fail with unresolved references (e.g. on AOS/VS). + * Avoid the construction *++p (the order of evaluation varies; it + shouldn't but at least one compiler had a bug that made me include + this item). + * Don't use triple assignments, like a = b = c = 0; (or quadruple, + etc). Some compilers generate bad code for these, or crash, etc + (some version of DEC C as I recall). + * Some compilers don't allow structure members to have the same names + as other identifiers. Try to give structure members unique names. + * Don't assume anything about order of evaluation in boolean + expressions, or that they will stop early if a required condition + is not true, e.g.: + if (i > 0 && p[i-1] == blah) + + can still dump core if i == 0 (hopefully this is not true of any + modern compiler, but I would not have said this if it did not + actually happen somewhere). + * Don't have a switch() statement with no cases (e.g. because of + #ifdefs); this is a fatal error in some compilers. + * Don't put lots of code in a switch case; move it out to a separate + function; some compilers run out of memory when presented with a + huge switch() statement -- it's not the number of cases that + matters; it's the overall amount of code. + * Some compilers might also limit the number of switch() cases, e.g. + to 254. + * Don't put anything between "switch() {" and "case:" -- switch + blocks are not like other blocks. + * Don't jump into or out of switches. + * Don't make character-string constants longer than about 250 bytes. + Longer strings should be broken up into arrays of strings. + * Don't write into character-string constants (obviously). Even when + you know you are not writing past the end; the compiler or linker + might have put them into read-only and/or shared memory, and/or + coalesced multiple equal constants so if you change one you change + them all. + * Don't depend on '\r' being carriage return. + * Don't depend on '\n' being linefeed or for that matter any SINGLE + character. + * Don't depend on '\r' and '\n' being different (e.g. as separate + switch() cases). + * In other words, don't use \n or \r to stand for specific + characters; use \012 and \015 instead. + * Don't code for "buzzword 1.0 compliance", unless "buzzword" is K&R + and "1.0" is the first edition. + * Don't use or depend on anything_t (size_t, pid_t, etc), except + time_t, without #ifdef protection (time_t is the only one I've + found that is accepted everywhere). This is a tough one because the + same function might require (say) a size_t arg on one platform, + whereas size_t is unheard of on another; or worse, it might require + a totally different data type, like int or long or some other + typedef'd thing. It has often proved necessary to define a symbol + to stand for the type of a particular argument to a particular + library or system function to get around this problem. + * Don't use or depend on internationalization ("i18n") features, + wchar_t, locales, etc, in portable code; they are not portable. + Anyway, locales are not the right model for Kermit's + multi-character-set support. Kermit does all character-set + conversion itself and does not use any external libraries or + functions. + * In particular, don't use any library functions that deal with wide + characters or Unicode in any form. These are not only nonportable, + but a constantly shifting target (e.g. the ones in glibc). + * Don't make any assumption about signal handler type. It can be + void, int, long, or anything else. Always declare signal handlers + as SIGTYP (see definition in ckcdeb.h and augment it if necessary) + and always use SIGRETURN at exit points from signal handlers. + * Signals should always be re-armed to be used again (this barely + scratches the surface -- the differences between BSD/V7 and System + V and POSIX signal handling are numerous, and some platforms do not + even support signals, alarms, or longjmps correctly or at all -- + avoid all of this if you can). + * On the other hand, don't assume that signals are disarmed after + being raised. In some platforms you have to re-arm them, in others + they stay armed. + * Don't call malloc() and friends from a signal handler; don't do + anything but setting integer global variables in a signal handler. + * malloc() does not initialize allocated memory -- it never said it + did. Don't expect it to be all 0's. + * Did You Know: malloc() can succeed and the program can still dump + core later when it attempts to use the malloc'd memory? (This + happens when allocation is deferred until use and swap space is + full.) + * memset(), memmove(), and memcpy() are not portable, don't use them + without protecting them in ifdefs (we have USE_MEMCPY for this). + bzero()/bcopy() too, except we're guaranteed to have + bzero()/bcopy() when using the sockets library (not really). See + examples in the source. + * Don't assume that strncpy() stops on the first null byte -- most + versions always copy the number of bytes given in arg 3, padding + out with 0's and overwriting whatever was there before. Use + C-Kermit ckstrncpy() if you want predictable non-padding behavior, + guaranteed NUL-termination, and a useful return code. + * DID YOU KNOW.. that some versions of inet_blah() routines return IP + addresses in network byte order, while others return them local + machine byte order? So passing them to ntohs() or whatever is not + always the right thing to do. + * Don't use ANSI-format function declarations without #ifdef + CK_ANSIC, and always provide an #else for the non-ANSI case. + * Use the Kermit _PROTOTYP() macro for declaring function prototypes; + it works in both the ANSI and non-ANSI cases. + * Don't depend on any other ANSI preprocessor features like "pasting" + -- they are often missing or nonoperational. + * Don't assume any C++ syntax or semantics. + * Don't use // as a comment introducer. C is not C++. + * Don't declare a string as "char foo[]" in one module and "extern + char * foo" in another, or vice-versa: this causes core dumps. + * With compiler makers falling all over themselves trying to outdo + each other in ANSI strictness, it has become increasingly necessary + to cast EVERYTHING. This is increasingly true for char vs unsigned + char. We need to use unsigned chars if we want to deal with 8-bit + character sets, but most character- and string-oriented APIs want + (signed) char arguments, so explicit casts are necessary. It would + be nice if every compiler had a -funsigned-char option (as gcc + does), but they don't. + * a[x], where x is an unsigned char, can produce a wild memory + reference if x, when promoted to an int, becomes negative. Cast it + to (unsigned), even though it ALREADY IS unsigned. + * Be careful how you declare functions that have char or long + arguments; for ANSI compilers you MUST use ANSI declarations to + avoid promotion problems, but you can't use ANSI declarations with + non-ANSI compilers. Thus declarations of such functions must be + hideously entwined in #ifdefs. Example: latter: + int /* Put character in server command buffer */ + #ifdef CK_ANSIC + putsrv(char c) + #else + putsrv(c) char c; + #endif /* CK_ANSIC */ + /* putsrv */ { + *srvptr++ = c; + *srvptr = '\0'; /* Make sure buffer is null-terminated */ + return(0); + } + + * Be careful how you return characters from functions that return int + values -- "getc-like functions" -- in the ANSI world. Unless you + explicitly cast the return value to (unsigned), it is likely to be + "promoted" to an int and have its sign extended. + * At least one compiler (the one on DEC OSF/1 1.3) treats "/*" and + "*/" within string constants as comment begin and end. No amount of + #ifdefs will get around this one. You simply can't put these + sequences in a string constant, e.g. "/usr/local/doc/*.*". + * Avoid putting multiple macro references on a single line, e.g.: + putchar(BS); putchar(SP); putchar(BS) + + This overflows the CPP output buffer of more than a few C preprocessors + (this happened, for example, with SunOS 4.1 cc, which evidently has a + 1K macro expansion buffer). + + C-Kermit needs constant adjustment to new OS and compiler releases. + Every new OS release shuffles header files or their contents, or + prototypes, or data types, or levels of ANSI strictness, etc. Every + time you make an adjustment to remove a new compilation error, BE VERY + CAREFUL to #ifdef it on a symbol unique to the new configuration so + that the previous configuration (and all other configurations on all + other platforms) remain as before. + + Assume nothing. Don't assume header files are where they are supposed + to be, that they contain what you think they contain, that they define + specific symbols to have certain values -- or define them at all! Don't + assume system header files protect themselves against multiple + inclusion. Don't assume that particular system or library calls are + available, or that the arguments are what you think they are -- order, + data type, passed by reference vs value, etc. Be conservative when + attempting to write portable code. Avoid all advanced features. + + If you see something that does not make sense, don't assume it's a + mistake -- it might be there for a reason, and changing it or removing + is likely to cause compilation, linking, or runtime failures sometime, + somewhere. Some huge percentage of the code, especially in the + platform-dependent modules, is workarounds for compiler, linker, or API + bugs. + + But finally... feel free to violate any or all of these rules in + platform-specific modules for environments in which the rules are + certain not to apply. For example, in VMS-specific code, it is OK to + use #if, because VAX C, DEC C, and VMS GCC all support it. + + [ [39]Contents ] [ [40]C-Kermit ] [ [41]Kermit Home ] + +3.1. Memory Leaks + + The C language and standard C library are notoriously inadequate and + unsafe. Strings are arrays of characters, usually referenced through + pointers. There is no native string datatype. Buffers are fixed size, + and C provides no runtime bounds checking, thus allowing overwriting of + other data or even program code. With the popularization of the + Internet, the "buffer exploit" has become a preferred method for + hackers to hijack privileged programs; long data strings are fed to a + program in hopes that it uses unsafe C library calls such as strcpy() + or sprintf() to copy strings into automatic arrays, thus overwriting + the call stack, and therefore the routine's return address. When such a + hole is discovered, a "string" can be constructed that contains machine + code to hijack the program's privileges and penetrate the system. + + This problem is partially addressed by the strn...() routines, which + should always be used in preference to their str...() equivalents + (except when the copy operation has already been prechecked, or there + is a good reason for not using them, e.g. the sometimes undesirable + side effect of strncpy() zeroing the remainder of the buffer). The most + gaping whole, however, is sprintf(), which performs no length checking + on its destination buffer, and is not easy to replace. Although + snprintf() routines are starting to appear, they are not yet + widespread, and certainly not universal, nor are they especially + portable, or even full-featured. + + For these reasons, we have started to build up our own little library + of C Library replacements, ckclib.[ch]. These are safe and highly + portable primitives for memory management and string manipulation, such + as: + + ckstrncpy() + Like strncpy but returns a useful value, doesn't zero buffer. + + ckitoa() + Opposite of atoi() + + ckltoa() + Opposite of atol() + + ckctoa() + Returns character as string + + ckmakmsg() + Used with ck?to?() as a safe sprintf() replacement for up to 4 + items + + ckmakxmsg() + Like ckmakmsg() but accepts up to 12 items + + More about library functions in [42]Section 4.A. + + [ [43]Contents ] [ [44]C-Kermit ] [ [45]Kermit Home ] + +3.2. The "char" vs "unsigned char" Dilemma + + This is one of the most aggravating and vexing characteristics of the C + language. By design, chars (and char *'s) are SIGNED. But in the modern + era, however, we need to process characters that can have (or include) + 8-bit values, as in the ISO Latin-1, IBM CP 850, or UTF-8 character + sets, so this data must be treated as unsigned. But some C compilers + (such as those based on the Bell UNIX V7 compiler) do not support + "unsigned char" as a data type. Therefore we have the macro or typedef + CHAR, which we use when we need chars to be unsigned, but which, + unfortunately, resolves itself to "char" on those compilers that don't + support "unsigned char". AND SO... We have to do a lot of fiddling at + runtime to avoid sign extension and so forth. + + Some modern compilers (e.g. IBM, DEC, Microsoft) have options that say + "make all chars be unsigned" (e.g. GCC "-funsigned-char") and we use + them when they are available. Other compilers don't have this option, + and at the same time, are becoming increasingly strict about type + mismatches, and spew out torrents of warnings when we use a CHAR where + a char is expected, or vice versa. We fix these one by one using casts, + and the code becomes increasingly ugly. But there remains a serious + problem, namely that certain library and kernel functions have + arguments that are declared as signed chars (or pointers to them), + whereas our character data is unsigned. Fine, we can can use casts here + too -- but who knows what happens inside these routines. + + [ [46]Contents ] [ [47]C-Kermit ] [ [48]Kermit Home ] + +4. MODULES + + When C-Kermit is on the far end of a connection, it is said to be in + remote mode. When C-Kermit has made a connection to another computer, + it is in local mode. (If C-Kermit is "in the middle" of a multihop + connection, it is still in local mode.) + + On another axis, C-Kermit can be in any of several major states: + + Command State + Reading and writing from the job's controlling terminal or + "console". In this mode, all i/o is handled by the Group E + conxxx() (console i/o) routines. + + Protocol State + Reading and writing from the communicatons device. In this mode, + all i/o is handled by the Group E ttxxx() (terminal i/o) + routines. + + Terminal State + Reading from the keyboard with conxxx() routines and writing to + the communications device with ttxxx() routines AND vice-versa. + + When in local mode, the console and communications device are distinct. + During file transfer, Kermit may put up a file-transfer display on the + console and sample the console for interruption signals. + + When in remote mode, the console and communications device are the + same, and therefore there can be no file-transfer display on the + console or interruptions from it (except for "in-band" interruptions + such as ^C^C^C). + + [ [49]Contents ] [ [50]C-Kermit ] [ [51]Kermit Home ] + +4.A. Group A: Library Functions + + Library functions, strictly portable, can be used by all modules on all + platforms: [52]ckclib.h, [53]ckclib.c. + + (To be filled in... For now, see [54]Section 3.1 and the comments in + ckclib.c.) + + [ [55]Contents ] [ [56]C-Kermit ] [ [57]Kermit Home ] + +4.B. Group B: Kermit File Transfer + + The Kermit protocol kernel. These files, whose names start with "ckc + are supposed to be totally portable C, and are expected to compile + correctly on any platform with any C compiler. "Portable" does not mean + the same as as "ANSI" -- these modules must compile on 10- and 20-year + old computers, with C preprocessors, compilers, and/or linkers that + have all sorts of restrictions. The Group B modules do not include any + header files other than those that come with Kermit itself. They do not + contain any library calls except from the standard C library (e.g. + printf()). They most certainly do not contain any system calls. Files: + + [58]ckcsym.h + For use by C compilers that don't allow -D on the command line. + + [59]ckcasc.h + ASCII character symbol definitions. + + [60]ckcsig.h + System-independent signal-handling definitions and prototypes. + + [61]ckcdeb.h + Originally, debugging definitions. Now this file also contains + all definitions and prototypes that are shared by all modules in + all groups. + + [62]ckcker.h + Kermit protocol symbol definitions. + + [63]ckcxla.h + Character-set-related symbol definitions (see next section). + + [64]ckcmai.c + The main program. This module contains the declarations of all + the protocol-related global variables that are shared among the + other modules. + + [65]ckcpro.w + The protocol module itself, written in "wart", a lex-like + preprocessor that is distributed with Kermit under the name + CKWART.C. + + [66]ckcfns.c, [67]ckcfn2.c, [68]ckcfn3.c + The protocol support functions used by the protocol module. + + [69]Group B modules may call upon functions from [70]Group E, but not + from [71]Group D modules (with the single exception that the main + program invokes the user interface, which is in Group D). (This last + assertion is really only a conjecture.) + + [ [72]Contents ] [ [73]C-Kermit ] [ [74]Kermit Home ] + +4.C. Group C: Character-Set Conversion + + Character set translation tables and functions. Used by the [75]Group + B, protocol modules, but may be specific to different computers. (So + far, all character character sets supported by C-Kermit are supported + in [76]ckuxla.c and [77]ckuxla.h, including Macintosh and IBM character + sets). These modules should be completely portable, and not rely on any + kind of system or library services. + + [78]ckcxla.h + Character-set definitions usable by all versions of C-Kermit. + + ck?xla.h + Character-set definitions for computer "?", e.g. [79]ckuxla.h + for UNIX, [80]ckmxla.h for Macintosh. + + [81]ck?xla + Character-set translation tables and functions for computer "?", + For example, CKUXLA.C for UNIX, CKMXLA.C for Macintosh. So far, + these are the only two such modules. The UNIX module is used for + all versions of C-Kermit except the Macintosh version. + + [82]ckcuni.h + Unicode definitions + + [83]ckcuni.c + Unicode module + + Here's how to add a new file character set in the original (non-Unicode + modules). Assuming it is based on the Roman (Latin) alphabet. Let's + call it "Barbarian". First, in ck?xla.h, add a definition for FC_BARBA + (8 chars maximum length) and increase MAXFCSETS by 1. Then, in + ck?xla.c: + + * Add a barbarian entry into the fcsinfo array. + * Add a "barbarian" entry to file character set keyword table, + fcstab. + * Add a "barbarian" entry to terminal character set keyword table, + ttcstab. + * Add a translation table from Latin-1 to barbarian: yl1ba[]. + * Add a translation table from barbarian to Latin-1: ybal1[]. + * Add a translation function from Barbarian to ASCII: xbaas(). + * Add a translation function from Barbarian to Latin-1: xbal1(). + * Add a translation function from Latin-1 to Barbarian: xl1ba(). + * etc etc for each transfer character set... + * Add translation function pointers to the xls and xlr tables. + + Other translations involving Barbarian (e.g. from Barbarian to + Latin-Cyrillic) are performed through these tables and functions. See + ckuxla.h and ckuxla.c for extensive examples. + + To add a new Transfer Character Set, e.g. Latin Alphabet 9 (for the + Euro symbol), again in the "old" character-set modules: + + In ckcxla.h: + + + Add a TC_xxxx definition and increase MAXTCSETS accordingly. + + In ck?xla.h (since any transfer charset is also a file charset): + + + Add an FC_xxxx definition and increase MAXFCSETS accordingly. + + In ck?xla.c: + + + Add a tcsinfo[] entry. + + Make a tcstab[] keyword table entry. + + Make an fcsinfo[] table entry. + + Make an fcstab[] keyword table entry. + + Make a tcstab[] keyword table entry. + + If necessary, make a langinfo[] table entry. + + Make entries in the function pointer arrays. + + Provide any needed functions. + + As of C-Kermit 7.0, character sets are also handled in parallel by the + new (and very large) Unicode module, ckcuni.[ch]. Eventually we should + phase out the old way, described just above, and operate entirely in + (and through) Unicode. The advantages are many. The disadvantages are + size and performance. To add a character to the Unicode modules: + + In ckcuni.h: + + + (To be filled in...) + + In ckcuni.c: + + + (To be filled in...) + + [ [84]Contents ] [ [85]C-Kermit ] [ [86]Kermit Home ] + +4.D. Group D: User Interface + + This is the code that communicates with the user, gets her commands, + informs her of the results. It may be command-line oriented, + interactive prompting dialog, menus and arrow keys, windows and mice, + speech recognition, telepathy, etc. The one provided is command-and + prompt, with the ability to read commands from various sources: the + console keyboard, a file, or a macro definition. The user interface has + three major functions: + + 1. Sets the parameters for the file transfer and then starts it. This + is done by setting certain (many) global variables, such as the + protocol machine start state, the file specification, file type, + communication parameters, packet length, window size, character + set, etc. + 2. Displays messages on the user's screen during the file transfer, + using the screen() function, which is called by the group-1 + modules. + 3. Executes any commands directly that do not require Kermit protocol, + such as the CONNECT command, local file management commands, + parameter-setting commands, FTP client commands, etc. + + If you plan to imbed the [87]Group B, files into a program with a + different user interface, your interface must supply an appropriate + screen() function, plus a couple related ones like chkint() and + intmsg() for handling keyboard (or mouse, etc) interruptions during + file transfer. The best way to find out about this is to link all the + C-Kermit modules together except the ckuu*.o and ckucon.o modules, and + see which missing symbols turn up. + + C-Kermit's character-oriented user interface (as opposed to the + Macintosh version's graphical user interface) consists of the following + modules. C-Kermit can be built with an interactive command parser, a + command-line-option-only parser, a graphical user interface, or any + combination, and it can even be built with no user interface at all (in + which case it runs as a remote-mode Kermit server). + + [88]ckucmd.h + [89]ckucmd.c + The command parsing primitives used by the interactive command + parser to parse keywords, numbers, filenames, etc, and to give + help, complete fields, supply defaults, allow abbreviations and + editing, etc. This package is totally independent of Kermit, but + does depend on the [90]Group E functions. + + [91]ckuusr.h + Definitions of symbols used in Kermit's commands. + + ckuus*.c + Kermit's interactive command parser, including the script + programming language: [92]ckuusr.c (includes top-level keyword + tables); [93]ckuus2.c (HELP command text); [94]ckuus3.c (most of + the SET command); [95]ckuus4.c (includes variables and + functions); ckuus[567].c (miscellaneous); + + [96]ckuusy.c + The command-line-option parser. + + [97]ckuusx.c + User interface functions common to both the interactive and + command-line parsers. + + [98]ckuver.h + Version heralds for different implementations. + + [99]ckuscr.c + The (old, uucp-like) SCRIPT command + + [100]ckudia.c + The DIAL command. Includes specific knowledge of many types of + modems. + + Note that none of the above files is actually Unix-specific. Over time + they have proven to be portable among all platforms where C-Kermit is + built: Unix, VMS, AOS/VS, Amiga, OS-9, VOS, etc etc. Thus the third + letter should more properly be "c", but changing it would be too + confusing. + + ck?con.c, ckucns.c + The CONNECT command. Terminal connection, and in some cases + (Macintosh, Windows) also terminal emulation. NOTE: As of + C-Kermit 7.0, there are two different CONNECT modules for UNIX: + [101]ckucon.c -- the traditional, portable, fork()-based version + -- and [102]ckucns.c, a new version that uses select() rather + than forks so it can handle encryption. ckucns.c is the + preferred version for Unix; ckucon.c is not likely to keep pace + with it in terms of upgrades, etc. However, since select() is + not portable to every platform, ckucon.c will be kept + indefinitely for those platforms that can't use ckucns.c. NOTE: + SunLink X.25 support is available only in ckucon.c. + + ck_*.*, ckuat*.* + Modules having to do with authentication and encryption. Since + the relaxation of USA export laws, they are included with the + general source-code distribution. Secure C-Kermit binaries can + be built using special targets in the standard makefile. + However, secure prebuilt binaries may not be distributed. + + For other implementations, the files may, and probably do, have + different names. For example, the Macintosh graphical user interface + filenames start with "ckm". Kermit 95 uses the ckucmd and ckuus* + modules, but has its own CONNECT command modules. And so on. + + Here is a brief description of C-Kermit's "user interface interface", + from ckuusr.c. It is nowhere near complete; in particular, hundreds of + global variables are shared among the many modules. These should, some + day, be collected into classes or structures that can be passed around + as needed; not only for purity's sake, but also to allow for multiple + simultaneous communication sessions and or user interfaces. Our list of + things to do is endless, and reorganizing the source is almost always + at the bottom. + + The ckuus*.c modules (like many of the ckc*.c modules) depend on the + existence of C library features like fopen, fgets, feof, (f)printf, + argv/argc, etc. Other functions that are likely to vary among operating + systems -- like setting terminal modes or interrupts -- are invoked via + calls to functions that are defined in the [103]Group E + platform-dependent modules, ck?[ft]io.c. The command line parser + processes any arguments found on the command line, as passed to main() + via argv/argc. The interactive parser uses the facilities of the cmd + package (developed for this program, but, in theory, usable by any + program). Any command parser may be substituted for this one. The only + requirements for the Kermit command parser are these: + + 1. Set parameters via global variables like duplex, speed, ttname, + etc. See [104]ckcmai.c for the declarations and descriptions of + these variables. + 2. If a command can be executed without the use of Kermit protocol, + then execute the command directly and set the sstate (start state) + variable to 0. Examples include SET commands, local directory + listings, the CONNECT command. + 3. If a command requires the Kermit protocol, set the following + variables: + sstate string data + 'x' (enter server mode) (none) + 'r' (send a 'get' command) cmarg, cmarg2 + 'v' (enter receive mode) cmarg2 + 'g' (send a generic command) cmarg + 's' (send files) nfils, cmarg & cmarg2 OR cmlist + 'c' (send a remote host command) cmarg + + + cmlist is an array of pointers to strings. + cmarg, cmarg2 are pointers to strings. + nfils is an integer (hmmm, probably should be an unsigned long). + + cmarg can be: + A filename string (possibly wild), or: + a pointer to a prefabricated generic command string, or: + a pointer to a host command string. + + cmarg2 is: + The name to send a single file under, or: + the name under which to store an incoming file; must not + be wild. + If it's the name for receiving, a null value means to + store the file under the name it arrives with. + + cmlist is: + A list of nonwild filenames, such as passed via argv. + + nfils is an integer, interpreted as follows: + -1: filespec (possibly wild) in cmarg, must be expanded + internally. + 0: send from stdin (standard input). + >0: number of files to send, from cmlist. + + The screen() function is used to update the screen during file + transfer. The tlog() function writes to a transaction log (if TLOG is + defined). The debug() function writes to a debugging log (if DEBUG is + defined). The intmsg() and chkint() functions provide the user i/o for + interrupting file transfers. + + [ [105]Contents ] [ [106]C-Kermit ] [ [107]Kermit Home ] + +4.E. Group E: Platform-Dependent I/O + + Platform-dependent function definitions. All the Kermit modules, + including the command package, call upon these functions, which are + designed to provide system-independent primitives for controlling and + manipulating devices and files. For Unix, these functions are defined + in the files [108]ckufio.c (files), [109]ckutio.c (communications), and + [110]ckusig.c (signal handling). + + For VMS, the files are [111]ckvfio.c, ckvtio.c, and [112]ckusig.c (VMS + can use the same signal handling routines as Unix). It doesn't really + matter what the files are called, except for Kermit distribution + purposes (grouping related files together alphabetically), only that + each function is provided with the name indicated, observes the same + calling and return conventions, and has the same type. + + The Group E modules contain both functions and global variables that + are accessed by modules in the other groups. These are now described. + + (By the way, I got this list by linking all the C-Kermit modules + together except ckutio and ckufio. These are the symbols that ld + reported as undefined. But that was a long time ago, probably circa + Version 6.) + +4.E.1. Global Variables + + char *DELCMD; + Pointer to string containing command for deleting files. + Example: char *DELCMD = "rm -f "; (UNIX) + Example: char *DELCMD = "delete "; (VMS) + Note trailing space. Filename is concatenated to end of this + string. NOTE: DELCMD is used only in versions that do not + provide their own built-in DELETE command. + + char *DIRCMD; + Pointer to string containing command for listing files when a + filespec is given. + Example: char *DIRCMD = "/bin/ls -l "; (UNIX) + Example: char *DIRCMD = "directory "; (VMS) + Note trailing space. Filename is concatenated to end of this + string. NOTE: DIRCMD is used only in versions that do not + provide their own built-in DIRECTORY command. + + char *DIRCM2; + Pointer to string containing command for listing files when a + filespec is not given. (currently not used, handled in another + way.) + Example: char *DIRCMD2 = "/bin/ls -ld *"; + NOTE: DIRCMD2 is used only in versions that do not provide their + own built-in DIRECTORY command. + + char *PWDCMD; + Pointer to string containing command to display current + directory. + Example: char *PWDCMD = "pwd "; + NOTE: PWDCMD is used only in versions that do not provide their + own built-in PWD command. + + char *SPACMD; + Pointer to command to display free disk space in current + device/directory. + Example: char *SPACMD = "df ."; + NOTE: SPACMD is used only in versions that do not provide their + own built-in SPACE command. + + char *SPACM2; + Pointer to command to display free disk space in another + device/directory. + Example: char *SPACM2 = "df "; + Note trailing space. Device or directory name is added to this + string. NOTE: SPACMD2 is used only in versions that do not + provide their own built-in SPACE command. + + char *TYPCMD; + Pointer to command for displaying the contents of a file. + Example: char *TYPCMD = "cat "; + Note trailing space. Device or directory name is added to this + string. NOTE: TYPCMD is used only in versions that do not + provide their own built-in TYPE command. + + char *WHOCMD; + Pointer to command for displaying logged-in users. + Example: char *WHOCMD = "who "; + Note trailing space. Specific user name may be added to this + string. + + int backgrd = 0; + Flag for whether program is running in foreground (0) or + background (nonzero). Background operation implies that screen + output should not be done and that all errors should be fatal. + + int ckxech; + Flag for who is to echo console typein: + 1: The program (system is not echoing). + 0: The OS, front end, terminal, etc (not this program). + + char *ckxsys; + Pointer to string that names the computer and operating system. + Example: char *ckxsys = " NeXT Mach 1.0"; + Tells what computer system ckxv applies to. In UNIX Kermit, this + variable is also used to print the program herald, and in the + SHOW VERSION command. + + char *ckxv; + Pointer to version/edit info of ck?tio.c module. + Example: char *ckxv = "UNIX Communications Support, 6.0.169, 6 + Sep 96"; + Used by SHOW VERSION command. + + char *ckzsys; + Like ckxsys, but briefer. + Example: char *ckzsys = " 4.3 BSD"; + Tells what platform ckzv applies to. Used by the SHOW VERSION + command. + + char *ckzv; + Pointer to version/edit info of ck?fio.c module. + Example: char *ckzv = "UNIX File support, 6.0.113, 6 Sep 96"; + Used by SHOW VERSION command. + + int dfflow; + Default flow control. 0 = none, 1 = Xon/Xoff, ... (see FLO_xxx + symbols in ckcdeb.h) + Set by Group E module. Used by [113]ckcmai.c to initialize flow + control variable. + + int dfloc; + Default location. 0 = remote, 1 = local. Set by Group E module. + Used by ckcmai.c to initialize local variable. Used in various + places in the user interface. + + int dfprty; + Default parity. 0 = none, 'e' = even, 'o' = odd, 'm' = mark, 's' + = space. Set by Group E module. Used by ckcmai.c to initialize + parity variable. + + char *dftty; + Default communication device. Set by Group E module. Used in + many places. This variable should be initialized the the symbol + CTTNAM, which is defined in ckcdeb.h, e.g. as "/dev/tty" for + UNIX, "TT:" for VMS, etc. Example: char *dftty = CTTNAM; + + char *mtchs[]; + Array of string pointers to filenames that matched the most + recent wildcard match, i.e. the most recent call to zxpand(). + Used (at least) by command parsing package for partial filename + completion. + + int tilde_expand; + Flag for whether to attempt to expand leading tildes in + directory names (used in UNIX only, and then only when the + symbol DTILDE is defined. + + int ttnproto; + The protocol being used to communicate over a network device. + Values are defined in ckcnet.h. Example: NP_TELNET is network + protocol "telnet". + + int maxnam; + The maximum length for a filename, exclusive of any device or + directory information, in the format of the host operating + system. + + int maxpath; + The maximum length for a fully specified filename, including + device designator, directory name, network node name, etc, in + the format of the host operating system, and including all + punctuation. + + int ttyfd; + File descriptor of the communication device. -1 if there is no + open or usable connection, including when C-Kermit is in remote + mode. Since this is not implemented everywhere, references to it + are in #ifdef CK_TTYFD..#endif. + + [ [114]Contents ] [ [115]C-Kermit ] [ [116]Kermit Home ] + +4.E.2. Functions + + These are divided into three categories: file-related functions (B.1), + communication functions (B.2), and miscellaneous functions (B.3). + +4.E.2.1. File-Related Functions + + In most implementations, these are collected together into a module + called ck?fio.c, where ? = "u" ([117]ckutio.c for Unix), "v" + ([118]ckvtio.c for VMS), [119]etc. To be totally platform-independent, + C-Kermit maintains its own file numbers, and provides the functions + described in this section to deal with the files associated with them. + The file numbers are referred to symbolically, and are defined as + follows in ckcker.h: + + #define ZCTERM 0 /* Console terminal */ + #define ZSTDIO 1 /* Standard input/output */ + #define ZIFILE 2 /* Current input file for SEND command */ + #define ZOFILE 3 /* Current output file for RECEIVE command */ + #define ZDFILE 4 /* Current debugging log file */ + #define ZTFILE 5 /* Current transaction log file */ + #define ZPFILE 6 /* Current packet log file */ + #define ZSFILE 7 /* Current session log file */ + #define ZSYSFN 8 /* Input from a system function (pipe) */ + #define ZRFILE 9 /* Local file for READ command */ (NEW) + #define ZWFILE 10 /* Local file for WRITE command */ (NEW) + #define ZMFILE 11 /* Auxilliary file for internal use */ (NEW) + #define ZNFILS 12 /* How many defined file numbers */ + + In the descriptions below, fn refers to a filename, and n refers to one + of these file numbers. Functions are of type int unless otherwise + noted, and are listed mostly alphabetically. + + int + chkfn(n) int n; + Checks the file number n. Returns: + -1: File number n is out of range + 0: n is in range, but file is not open + 1: n in range and file is open + + int + iswild(filspec) char *filespec; + Checks if the file specification is "wild", i.e. contains + metacharacters or other notations intended to match multiple + filenames. Returns: + 0: not wild + 1: wild. + + int + isdir(string) char *string; + Checks if the string is the name of an existing directory. The + idea is to check whether the string can be "cd'd" to, so in some + cases (e.g. DOS) it might also indicate any file structured + device, such as a disk drive (like A:). Other nonzero returns + indicate system-dependent information; e.g. in VMS + isdir("[.FOO]") returns 1 but isdir("FOO.DIR;1") returns 2 to + indicate the directory-file name is in a format that needs + conversion before it can be combined with a filename. Returns: + 0: not a directory (including any kind of error) + 1: it is an existing directory + + char * + zfcdat(name) char *name; + Returns modification (preferably, otherwise creation) date/time + of file whose name is given in the argument string. Return value + is a pointer to a string of the form yyyymmdd hh:mm:ss, for + example 19931231 23:59:59, which represents the local time (no + timezone or daylight savings time finagling required). Returns + the null string ("") on failure. The text pointed to by the + string pointer might be in a static buffer, and so should be + copied to a safe place by the caller before any subsequent calls + to this function. + + struct zfnfp * + zfnqfp(fn, buflen, buf) char * fn; int buflen; char * buf; + Given the filename fn, the corresponding fully qualified, + absolute filename is placed into the buffer buf, whose length is + buflen. On failure returns a NULL pointer. On success returns a + pointer to a struct zfnfp containing pointers to the full + pathname and to just the filename, and an int giving the length + of the full pathname. All references to this function in + mainline code must be protected by #ifdef ZFNQFP..#endif, + because it is not present in all of the ck*fio.c modules. So if + you implement this function in a version that did not have it + before, be sure to add #define ZFNQFP in the appropriate spot in + ckcdeb.h or in the build-procedure CFLAGS. + + int + zcmpfn(s1,s2) char * s2, * s2; + Compares two filenames to see if they refer to the same. + Internally, the arguments can be converted to fully qualified + pathnames, e.g. with zfnqfp(), realpath(), or somesuch. In Unix + or other systems where symbolic links exist, the link should be + resolved before making the comparison or looking at the inodes. + Returns: + 0: Files are not identical. + 1: Files are identical. + + int + zfseek(pos) long pos; + Positions the input pointer on the current input file to the + given position. The pos argument is 0-based, the offset + (distance in bytes) from beginning of the file. Needed for + RESEND, PSEND, and other recovery operations. This function is + not necessarily possible on all systems, e.g. record-oriented + systems. It should only be used on binary files (i.e. files we + are sending in binary mode) and stream-oriented file systems. + Returns: + -1: on failure. + 0: On success. + + int + zchdir(dirnam) char *dirnam; + Changes current or default directory to the one given in dirnam. + Returns: + 0: On failure. + 1: on success. + + long + zchki(fn) char *fn; + Check to see if file with name fn is a regular, readable, + existing file, suitable for Kermit to send -- not a directory, + not a symbolic link, etc. Returns: + -3: if file exists but is not accessible (e.g. read-protected); + -2: if file exists but is not of a readable type (e.g. a + directory); + -1: on error (e.g. file does not exist, or fn is garbage); + >=0: (length of file) if file exists and is readable. + Also see isdir(), zgetfs(). + + int + zchkpid(pid) unsigned long pid; + Returns: + 1: If the given process ID (e.g. pid in UNIX) is valid and + active + 0: otherwise. + + long + zgetfs(fn) char *fn; + Gets the size of the given file, regardless of accessibility. + Used for directory listings. Unlike zchki(), should return the + size of any kind of file, even a directory. zgetfs() also should + serve as a mini "get file info" function that can be used until + we design a better one, by also setting some global variables: + int zgfs_link = 1/0 = file is (not) a symbolic link. + int zgfs_dir = 1/0 = file is (not) a directory. + char linkname[] = if zgfs_link != 0, name of file link points + to. + Returns: + -1: on error (e.g. file does not exist, or fn is garbage); + >=0: (length of file) if file exists and is readable. + + int + zchko(fn) char *fn; + Checks to see if a file of the given name can be created. + Returns: + -1: if file cannot be created, or on any kind of error. + 0: if file can be created. + + int + zchkspa(fn,len) char *f; long len; + Checks to see if there is sufficient space to store the file + named fn, which is len bytes long. If you can't write a function + to do this, then just make a dummy that always returns 1; higher + level code will recover from disk-full errors. The receiving + Kermit uses this function to refuse an incoming file based on + its size, via the attribute mechanism. Returns: + -1: on error. + 0: if there is not enough space. + 1: if there is enough space. + + int + zchin(n,c) int n; int *c; + Gets a character from file number n, return it in c (call with + &c). Returns: + -1: on failure, including EOF. + 0: on success with character in c. + + int + zchout(n,c) int n; char c; + Writes the character c to file number n. Returns: + -1: on error. + 0: on success. + + int + zclose(n) int n; + Closes file number n. Returns: + -1: on error. + 1: on success. + + int + zdelet(fn) char *name; + Attempts to delete (remove, erase) the named file. Returns: + -1: on error. + 1: if file was deleted successfully. + + char * + zgperm(char * f) + Returns a pointer to the system-dependent numeric + permissions/protection string for file f, or NULL upon failure. + Used if CK_PERMS is defined. + + char * + ziperm(char * f) + Returns a pointer to the system-dependent symbolic + permissions/protection string for file f, or NULL upon failure. + Used if CK_PERMS is defined. Example: In UNIX zgperm(f) might + return "100770", but ziperm() might return "-rwxrwx---". In VMS, + zgperm() would return a hexadecimal string, but ziperm() would + return something like "(RWED,RWED,RE,)". + + char * + zgtdir() + Returns a pointer to the name of the current directory, folder, + etc, or a NULL pointer if the current directory cannot be + determined. If possible, the directory specification should be + (a) fully specified, e.g. as a complete pathname, and (b) be + suitable for appending a filename. Thus, for example, Unix + directory names should end with '/'. VMS directory names should + look like DEV:[NAME] (rather than, say, NAME.DIR;1). + + char * + zhome() + Returns a pointer to a string containing the user's home + directory, or NULL upon error. Should be formatted like zgtdir() + (q.v.). + + int + zinfill() + Fill buffer from input file. This function is used by the macro + zminchar(), which is defined in ckcker.h. zminchar() manages its + own buffer, and calls zinfill() to fill it whenever it becomes + empty. It is used only for sending files, and reads characters + only from file number ZIFILE. zinfill() returns -1 upon end of + file, -2 upon fatal error, and -3 upon timeout (e.g. when + reading from a pipe); otherwise it returns the first character + from the buffer it just read. + + int + zkself() + Kills the current job, session, process, etc, logs out, + disappears. Used by the Kermit server when it receives a BYE + command. On failure, returns -1. On success, does not return at + all! This function should not be called until all other steps + have been taken to close files, etc. + + VOID + zstrip(fn,&fn2) char *fn1, **fn2; + Strips device and directory, etc, from file specification fn, + leaving only the filename (including "extension" or "filetype" + -- the part after the dot). For example DUA0:[PROGRAMS]OOFA.C;3 + becomes OOFA.C, or /usr/fdc/oofa.c becomes oofa.c. Returns a + pointer to result in fn2. + + int + zsetperm(char * file, unsigned int code) + Set permissions of file to given system-dependent code. 0: On + failure. + 1: on success. + + int + zsetroot(char * dir) + Sets the root for the user's file access, like Unix chroot(), + but does not require privilege. In Unix, this must be + implemented entirely by Kermit's own file access routines. + Returns: + 1: Success + -1: Invalid argument + -2: + -3: Internal error + -4: Access to given directory denied + -5: New root not within old root + + int + zinroot(char * file) + If no root is set (zsetroot()), returns 1. + Otherwise, if given file is in the root, returns 1. + Otherwise, returns 0. + + VOID + zltor(fn,fn2) char *fn1, *fn2; + Local-To-Remote filename translation. OBSOLETE: replaced by + nzltor() (q.v.). Translates the local filename fn into a format + suitable for transmission to an arbitrary type of computer, and + copies the result into the buffer pointed to by fn2. Translation + may involve (a) stripping the device and/or directory/path name, + (b) converting lowercase to uppercase, (c) removing spaces and + strange characters, or converting them to some innocuous + alphabetic character like X, (d) discarding or converting extra + periods (there should not be more than one). Does its best. + Returns no value. name2 is a pointer to a buffer, furnished by + the caller, into which zltor() writes the resulting name. No + length checking is done. + + #ifdef NZLTOR + VOID + nzltor(fn,fn2,convert,pathnames,max) char *fn1,*fn2; int + convert,pathnames,max; + Replaces zltor(). This new version handles pathnames and checks + length. fn1 and fn2 are as in zltor(). This version is called + unconditionally for each file, rather than only when filename + conversion is enabled. Pathnames can have the following values: + + PATH_OFF: Pathname, if any, is to be stripped + PATH_REL: The relative pathname is to be included + PATH_ABS: The full pathname is to be included + + After handling pathnames, conversion is done to the result as in + the zltor() description if convert != 0; if relative or absolute + pathnames are included, they are converted to UNIX format, i.e. + with slash (/) as the directory separator. The max parameter + specifies the maximum size of fn2. If convert > 0, the regular + conversions are done; if convert < 0, minimal conversions are + done (we skip uppercasing the letters, we allow more than one + period, etc; this can be used when we know our partner is UNIX + or similar). + + #endif /* NZLTOR */ + + int + nzxpand(fn,flags) char *fn; int flags; + Replaces zxpand(), which is obsolete as of C-Kermit 7.0. + Call with: + fn = Pointer to filename or pattern. + flags = option bits: + flags & ZX_FILONLY Match regular files + flags & ZX_DIRONLY Match directories + flags & ZX_RECURSE Descend through directory tree + flags & ZX_MATCHDOT Match "dot files" + flags & ZX_NOBACKUP Don't match "backup files" + flags & ZX_NOLINKS Don't follow symlinks. + + Returns the number of files that match fn, with data structures + set up so the first file (if any) will be returned by the next + znext() call. If ZX_FILONLY and ZX_DIRONLY are both set, or + neither one is set, files and directories are matched. Notes: + + 1. It is essential that the number returned by nzxpand() reflect + the actual number of filenames that will be returned by + znext() calls. In other words: + for (n = nzxpand(string,flags); n > 0; n--) { + znext(buf); + printf("%s\n", buf); + } + + should print all the file names; no more, no less. + 2. In UNIX, DOS, OS-9, etc, where directories contain entries for + themselves (.) and the superior directory (..), these should + NOT be included in the list under any circumstances, including + when ZX_MATCHDOT is set. + 3. Additional option bits might be added in the future, e.g. for + sorting (sort by date/name/size, reverse/ascending, etc). + Currently this is done only in higher level code (through a + hack in which the nzxpand() exports its filename array, which + is not portable because not all OS's can use this mechanism). + + int + zmail(addr,fn) char *addr, fn; + Send the local, existing file fn as e-mail to the address addr. + Returns: + 0: on success + 2: if mail delivered but temp file can't be deleted + -2: if mail can't be delivered + + int + zmkdir(path) char *path; + The path can be a file specification that might contain + directory information, in which the filename is expected to be + included, or an unambiguous directory specification (e.g. in + UNIX it must end with "/"). This routine attempts to create any + directories in the given path that don't already exist. Returns + 0 or greater success: no directories needed creation, or else + all directories that needed creation were created successfully; + the return code is the number of directories that were created. + Returns -1 on failure to create any of the needed directories. + + int + zrmdir(path) char *path; + Attempts to remove the given directory. Returns 0 on success, -1 + on failure. The detailed semantics are open -- should it fail if + the directory contains any files or subdirectories, etc. It is + probably best for this routine to behave in whatever manner is + customary on the underlying platform; e.g. in UNIX, VMS, DOS, + etc, where directories can not be removed unless they are empty. + + VOID + znewn(fn,s) char *fn, **s; + Transforms the name fn into a filename that is guaranteed to be + unique. If the file fn does not exist, then the new name is the + same as fn; Otherwise, it's different. this function does its + best, returns no value. New name is created in caller's space. + Call like this: znewn(old,&new);. The second parameter is a + pointer to the new name. This pointer is set by znewn() to point + to a static string in its own space, so be sure to the result to + a safe place before calling this function again. + + int + znext(fn) char *fn; + Copies the next file name from a file list created by zxpand() + into the string pointed to by fn (see zxpand). If no more files, + then the null string is placed there. Returns 0 if there are no + more filenames, with 0th element the array pointed to by fn set + to NUL. If there is a filename, it is stored in the array + pointed to by fn and a positive number is returned. NOTE: This + is a change from earlier definitions of this function + (pre-1999), which returned the number of files remaining; thus 0 + was the return value when returning the final file. However, no + mainline code ever depended on the return value, so this change + should be safe. + + int + zopeni(n,fn) int n; char *fn; + Opens the file named fn for input as file number n. Returns: + 0: on failure. + 1: on success. + + int + zopeno(n,fn,zz,fcb) int n; char *name; struct zattr *zz; struct + filinfo *fcb; + Attempts to open the named file for output as file number n. zz + is a Kermit file attribute structure as defined in ckcdeb.h, + containing various information about the file, including its + size, creation date, and so forth. This function should attempt + to honor as many of these as possible. fcb is a "file control + block" in the traditional sense, defined in ckcdeb.h, containing + information relevant to complicated file systems like VMS (RMS), + IBM MVS, etc, like blocksize, record length, organization, + record format, carriage control, etc. Returns: + 0: on failure. + 1: on success. + + int + zoutdump() + Dumps a file output buffer. Used with the macro zmchout() + defined in ckcker.h. Used only with file number ZOFILE, i.e. the + file that is being received by Kermit during file transfer. + Returns: + -1: on failure. + 0: on success. + + int + zprint(p,fn) char *p, *f; + Prints the file with name fn on a local printer, with options p. + Returns: + 0: on success + 3: if file sent to printer but can't be deleted + -3: if file can't be printed + + int + zrename(fn,fn2) char *fn, *fn2; + Changes the name of file fn to fn2. If fn2 is the name of an + existing directory, or a file-structured device, then file fn is + moved to that directory or device, keeping its original name. If + fn2 lacks a directory separator when passed to this function, an + appropriate one is supplied. Returns: + -1: on failure. + 0: on success. + + int + zcopy(source,dest) char * source, * dest; + Copies the source file to the destination. One file only. No + wildcards. The destination string may be a filename or a + directory name. Returns: + 0: on success. + <0: on failure: + -2: source file is not a regular file. + -3: source file not found. + -4: permission denied. + -5: source and destination are the same file. + -6: i/o error. + -1: other error. + + char * + zlocaltime(char *) + Call with: "yyyymmdd hh:mm:ss" GMT/UTC date-time. Returns + pointer to local date-time string "yyyymmdd hh:mm:ss" on + success, NULL on failure. + + VOID + zrtol(fn,fn2) char *fn, *fn2; + Remote-To-Local filename translation. OBSOLETE: replaced by + nzrtol(). Translates a "standard" filename to a local filename. + For example, in Unix this function might convert an + all-uppercase name to lowercase, but leave lower- or mix-case + names alone. Does its best, returns no value. New name is in + string pointed to by fn2. No length checking is done. + + #ifdef NZLTOR + int + nzrtol(fn,fn2,convert,pathnames,max) char *fn1,*fn2; int + convert,pathnames,max; + Replaces zrtol. Like zrtol but handles pathnames and checks + length. See nzltor for detailed description of parameters. + + #endif /* NZLTOR */ + + int + zsattr(xx) struct zattr *xx; + Fills in a Kermit file attribute structure for the file which is + to be sent, namely the currently open ZIFILE. Note that this is + not a very good design, but we're stuck with it. Callers must + ensure that zsattr() is called only on real files, not on pipes, + internally generated file-like objects such as server REMOTE + command responses, etc. Returns: + -1: on failure. + 0: on success with the structure filled in. + If any string member is null, it should be ignored by the + caller. + If any numeric member is -1, it should be ignored by the caller. + + int + zshcmd(s) char *s; + s contains to pointer to a command to be executed by the host + computer's shell, command parser, or operating system. If the + system allows the user to choose from a variety of command + processors (shells), then this function should employ the user's + preferred shell. If possible, the user's job (environment, + process, etc) should be set up to catch keyboard interruption + signals to allow the user to halt the system command and return + to Kermit. The command must run in ordinary, unprivileged user + mode. If possible, this function should return -1 on failure to + start the command, or else it should return 1 if the command + succeeded and 0 if it failed. + + int + pexitstatus + zshcmd() and zsyscmd() should set this to the command's actual + exit status code if possible. + + int + zsyscmd(s) char *s; + s contains to pointer to a command to be executed by the host + computer's shell, command parser, or operating system. If the + system allows the user to choose from a variety of command + processors (shells), then this function should employ the system + standard shell (e.g. /bin/sh for Unix), so that the results will + always be the same for everybody. If possible, the user's job + (environment, process, etc) should be set up to catch keyboard + interruption signals to allow the user to halt the system + command and return to Kermit. The command must run in ordinary, + unprivileged user mode. If possible, this function should return + -1 on failure to start the command, or else it should return 1 + if the command succeeded and 0 if it failed. + + VOID + z_exec(s,args) char * s; char * args[]; + This one executes the command s (which is searched for using the + system's normal searching mechanism, such as PATH in UNIX), with + the given argument vector, which follows the conventions of UNIX + argv[]: the name of the command pointed to by element 0, the + first arg by element 1, and so on. A null args[] pointer + indicates the end of the arugment list. All open files must + remain open so the exec'd process can use them. Returns only if + unsuccessful. + + int + zsinl(n,s,x) int n, x; char *s; + Reads a line from file number n. Writes the line into the + address s provided by the caller. Writing terminates when + newline is read, but with newline discarded. Writing also + terminates upon EOF or if length x is exhausted. Returns: + -1: on EOF or error. + 0: on success. + + int + zsout(n,s) int n; char *s; + Writes the string s out to file number n. Returns: + -1: on failure. + 0: on success. + + int + zsoutl(n,s) int n; char *s; + Writes the string s out to file number n and adds a line + (record) terminator (boundary) appropriate for the system and + the file format. Returns: + -1: on failure. + 0: on success. + + int + zsoutx(n,s,x) int n, x; char *s; + Writes exactly x characters from string s to file number n. If s + has fewer than x characters, then the entire string s is + written. Returns: + -1: on failure. + >= 0: on success, the number of characters actually written. + + int + zstime(fn,yy,x) char *fn; struct zattr *yy; int x; + Sets the creation date (and other attributes) of an existing + file, or compares a file's creation date with a given date. Call + with: + + fn: pointer to name of existing file. + yy: Pointer to a Kermit file attribute structure in which yy->date.val + is a date of the form yyyymmdd hh:mm:ss, e.g. 19900208 13:00:00, which + is to be used for setting or comparing the file date. Other attributes + in the struct can also be set, such as the protection/permission (See + [120]Appendix I), when it makes sense (e.g. "yy->lprotect.val" can be + set if the remote system ID matches the local one). + x: A function code: 0 means to set the file's creation date as given. + 1 means compare the date from the yy struct with the file's date. + + Returns: + -1: on any kind of error. + 0: if x is 0 and the file date was set successfully. + 0: if x is 1 and date from attribute structure > file creation + date. + 1: if x is 1 and date from attribute structure <= file + creation date. + + VOID + zstrip(name,name2) char *name, **name2; + Strips pathname from filename "name". Constructs the resulting + string in a static buffer in its own space and returns a pointer + to it in name2. Also strips device name, file version numbers, + and other "non-name" material. + + int + zxcmd(n,s) char *s; + Runs a system command so its output can be accessed as if it + were file n. The command is run in ordinary, unprivileged user + mode. + If n is ZSTDIO or ZCTERM, returns -1. + If n is ZIFILE or ZRFILE, then Kermit reads from the command, + otherwise Kermit writes to the command. + Returns 0 on error, 1 on success. + + int + zxpand(fn) char *fn; + OBSOLETE: Replaced by nzxpand(), q.v. + + #ifdef ZXREWIND + int + zxrewind() + Returns the number of files returned by the most recent + nzxpand() call, and resets the list to the beginning so the next + znext() call returns the first file. Returns -1 if zxpand has + not yet been called. If this function is available, ZXREWIND + should be defined; otherwise it should not be referenced. + + #endif /* ZXREWIND */ + + int + xsystem(cmd) char *cmd; + Executes the system command without redirecting any of its i/o, + similar (well, identical) to system() in Unix. But before + passing the command to the system, xsystem() ensures that all + privileges are turned off, so that the system command executes + in ordinary unprivileged user mode. If possible, xsystem() + returns the return code of the command that was executed. + +4.E.2.2. IKSD Variables and Functions + + These must be implemented in any C-Kermit version that is to be + installed as an Internet Kermit Service Daemon (IKSD). IKSD is expected + to be started by the Internet Daemon (e.g. inetd) with its standard i/o + redirected to the incoming connection. + + int ckxanon; + Nonzero if anonymous logins allowed. + + extern int inserver; + Nonzero if started in IKSD mode. + + extern int isguest; + Nonzero if IKSD and user logged in anonymously. + + extern char * homdir; + Pointer to user's home directory. + + extern char * anonroot; + Pointer to file-system root for anonymous users. + + Existing functions must make "if (inserver && isguest)" checks for + actions that would not be legal for guests: zdelete(), zrmdir(), + zprint(), zmail(), etc. + + int + zvuser(name) char * name; + Verifies that user "name" exists and is allowed to log in. If + the name is "ftp" or "anonymous" and ckxanon != 0, a guest login + is set up. Returns 0 if user not allowed to log in, nonzero if + user may log in. + + int + zvpass(string) char * string; + Verifies password of the user from the most recent zvuser() + call. Returns nonzero if password is valid for user, 0 if it + isn't. Makes any appropriate system log entries (IKSD logins, + failed login attempts, etc). If password is valid, logs the user + in as herself (if real user), or sets up restricted anonymous + access if user is guest (e.g. changes file-system root to + anonroot and sets isguest = 1). + + VOID + zsyslog() + Begins any desired system logging of an IKSD session. + + VOID + zvlogout() + Terminates an IKSD session. In most cases this is simply a + wrapper for exit() or doexit(), with some system logging added. + +4.E.2.3. Privilege Functions + + These functions are used by C-Kermit to adapt itself to operating + systems where the program can be made to run in a "privileged" mode, + e.g. setuid or setgid in Unix. C-Kermit should NOT read and write files + or start subprocesses as a privileged program. This would present a + serious threat to system security. The security package has been + installed to prevent such security breaches by turning off the + program's special privileges at all times except when they are needed. + + In UNIX, the only need Kermit has for privileged status is access to + the UUCP lockfile directory, in order to read, create, and destroy + lockfiles, and to open communication devices that are normally + protected against the user (see the [121]Unix C-Kermit Installation + Instructions for discussion). Therefore, privileges should only be + enabled for these operations and disabled at all other times. This + relieves the programmer of the responsibility of putting expensive and + unreliable access checks around every file access and subprocess + creation. + + Strictly speaking, these functions are not required in all C-Kermit + implementations, because their use (so far, at least) is internal to + the Group E modules. However, they should be included in all C-Kermit + implementations for operating systems that support the notion of a + privileged program (UNIX, RSTS/E, what others?). + + int + priv_ini() + Determine whether the program is running in privileged status. + If so, turn off the privileges, in such a way that they can be + turned on again when needed. Called from sysinit() at program + startup time. Returns: + 0 on success + nonzero on failure, in which case the program should halt + immediately. + + int + priv_on() + If the program is not privileged, this function does nothing. If + the program is privileged, this function returns it to + privileged status. priv_ini() must have been called first. + Returns: + 0 on success + nonzero on failure + + int + priv_off() + Turns privileges off (if they are on) in such a way that they + can be turned back on again. Returns: + 0 on success + nonzero on failure + + int + priv_can() + Turns privileges off in such a way that they cannot be turned + back on. Returns: + 0 on success + nonzero on failure + + int + priv_chk() + Attempts to turns privileges off in such a way that they can be + turned on again later. Then checks to make sure that they were + really turned off. If they were not really turned off, then they + are cancelled permanently. Returns: + 0 on success + nonzero on failure + +4.E.2.4. Console-Related Functions + + These relate to the program's "console", or controlling terminal, i.e. + the terminal that the user is logged in on and types commands at, or on + a PC or workstation, the actual keyboard and screen. + + int + conbin(esc) char esc; + Puts the console into "binary" mode, so that Kermit's command + parser can control echoing and other treatment of characters + that the user types. esc is the character that will be used to + get Kermit's attention during packet mode; puts this in a global + place. Sets the ckxech variable. Returns: + -1: on error. + 0: on success. + + int + concb(esc) char esc; + Put console in "cbreak" (single-character wakeup) mode. That is, + ensure that each console character is available to the program + immediately when the user types it. Otherwise just like + conbin(). Returns: + -1: on error. + 0: on success. + + int + conchk() + Returns a number, 0 or greater, the number of characters waiting + to be read from the console, i.e. the number of characters that + the user has typed that have not been read yet by Kermit. + + long + congspd(); + Returns the speed ("baud rate") of the controlling terminal, if + known, otherwise -1L. + + int + congks(timo) int timo; + Get Keyboard Scancode. Reads a keyboard scan code from the + physical console keyboard. If the timo parameter is greater than + zero, then times out and returns -2 if no character appears + within the given number of seconds. Upon any other kind of + error, returns -1. Upon success returns a scan code, which may + be any positive integer. For situations where scan codes cannot + be read (for example, when an ASCII terminal is used as the + job's controlling terminal), this function is identical to + coninc(), i.e. it returns an 8-bit character value. congks() is + for use with workstations whose keyboards have Alternate, + Command, Option, and similar modifier keys, and Function keys + that generate codes greater than 255. + + int + congm() + Console get modes. Gets the current console terminal modes and + saves them so that conres() can restore them later. Returns 1 if + it got the modes OK, 0 if it did nothing (e.g. because Kermit is + not connected with any terminal), -1 on error. + + int + coninc(timo) int timo; + Console Input Character. Reads a character from the console. If + the timo parameter is greater than zero, then coninc() times out + and returns -2 if no character appears within the given number + of seconds. Upon any other kind of error, returns -1. Upon + success, returns the character itself, with a value in the range + 0-255 decimal. + + VOID + conint(f,s) SIGTYP (*f)(), (*s)(); + Sets the console to generate an interrupt if the user types a + keyboard interrupt character, and to transfer control the + signal-handling function f. For systems with job control, s is + the address of the function that suspends the job. Sets the + global variable "backgrd" to zero if Kermit is running in the + foreground, and to nonzero if Kermit is running in the + background. See ckcdeb.h for the definition of SIGTYP. No return + value. + + VOID + connoi() + Console no interrupts. Disable keyboard interrupts on the + console. No return value. + + int + conoc(c) char c; + Writes character c to the console terminal. Returns: + 0 on failure, 1 on success. + + int + conol(s) char *s; + Writes string s to the console. Returns -1 on error, 0 or + greater on success. + + int + conola(s) char *s[]; { + Writes an array of strings to the console. Returns -1 on error, + 0 or greater on success. + + int + conoll(s) char *s; + Writes string s to the console, followed by the necessary line + termination characters to put the console cursor at the + beginning of the next line. Returns -1 on error, 0 or greater on + success. + + int + conres() + Restores the console terminal to the modes obtained by congm(). + Returns: -1 on error, 0 on success. + + int + conxo(x,s) int x; char *s; + Write x characters from string s to the console. Returns 0 or + greater on success, -1 on error. + + char * + conkbg(); + Returns a pointer to the designator of the console keyboard + type. For example, on a PC, this function would return "88", + "101", etc. Upon failure, returns a pointer to the empty string. + +4.E.2.5. Communications Functions + + The communication device is the device used for terminal emulation and + file transfer. It may or may not be the same device as the console, and + it may or may not be a terminal (serial-port) device; it could also be + a network connection. For brevity, the communication device is referred + to here as the "tty". When the communication device is the same as the + console device, Kermit is said to be in remote mode. When the two + devices are different, Kermit is in local mode. + + int + ttchk() + Returns the number of characters that have arrived at the + communication device but have not yet been read by ttinc(), + ttinl(), and friends. If communication input is buffered (and it + should be), this is the sum of the number of unread characters + in Kermit's buffer PLUS the number of unread characters in the + operating system's internal buffer. The call must be + nondestructive and nonblocking, and as inexpensive as possible. + Returns: + 0: or greater on success, + 0: in case of internal error, + -1: or less when it determines the connection has been broken, + or there is no connection. + + That is, a negative return from ttchk() should reliably indicate + that there is no usable connection. Furthermore, ttchk() should + be callable at any time to see if the connection is open. When + the connection is open, every effort must be made to ensure that + ttchk returns an accurate number of characters waiting to be + read, rather than just 0 (no characters) or 1 (1 or more + characters), as would be the case when we use select(). This + aspect of ttchk's operation is critical to successful operation + of sliding windows and streaming, but "nondestructive buffer + peeking" is an obscure operating system feature, and so when it + is not available, we have to do it ourselves by managing our own + internal buffer at a level below ttinc(), ttinl(), etc, as in + the UNIX version (non-FIONREAD case). + + An external global variable, clsondisc, if nonzero, means that + if a serial connection drops (carrier on-to-off transition + detected by ttchk()), the device should be closed and released + automatically. + + int + ttclos() + Closes the communication device (tty or network). If there were + any kind of exclusive access locks connected with the tty, these + are released. If the tty has a modem connection, it is hung up. + For true tty devices, the original tty device modes are + restored. Returns: + -1: on failure. + 0: on success. + + int + ttflui() + Flush communications input buffer. If any characters have + arrived but have not yet been read, discard these characters. If + communications input is buffered by Kermit (and it should be), + this function flushes Kermit's buffer as well as the operating + system's internal input buffer. Returns: + -1: on failure. + 0: on success. + + int + ttfluo() + Flush tty output buffer. If any characters have been written but + not actually transmitted (e.g. because the system has been + flow-controlled), remove them from the system's output buffer. + (Note, this function is not actually used, but it is recommended + that all C-Kermit programmers add it for future use, even if it + is only a dummy function that returns 0 always.) + + int + ttgmdm() + Looks for the modem signals CTS, DSR, and CTS, and returns those + that are on in as its return value, in a bit mask as described + for ttwmdm, in which a bit is on (1) or off (0) according to + whether the corresponding signal is on (asserted) or off (not + asserted). Return values: + -3: Not implemented + -2: if the line does not have modem control + -1: on error + >=0: on success, with bit mask containing the modem signals. + + long + ttgspd() + Returns the current tty speed in BITS (not CHARACTERS) per + second, or -1 if it is not known or if the tty is really a + network, or upon any kind of error. On success, the speed + returned is the actual number of bits per second, like 1200, + 9600, 19200, etc. + + int + ttgwsiz() + Get terminal window size. Returns -1 on error, 0 if the window + size can't be obtained, 1 if the window size has been + successfully obtained. Upon success, the external global + variables tt_rows and tt_cols are set to the number of screen + rows and number of screen columns, respectively. As this + function is not implemented in all ck*tio.c modules, calls to it + must be wrapped in #ifdef CK_TTGWSIZ..#endif. NOTE: This + function must be available to use the TELNET NAWS feature + (Negotiate About Window Size) as well as Rlogin. + + int + tthang() + Hang up the current tty device. For real tty devices, turn off + DTR for about 1/3-1/2 second (or other length of time, depending + on the system). If the tty is really a network connection, close + it. Returns: + -1: on failure. + 0: if it does not even try to hang up. + 1: if it believes it hung up successfully. + + VOID + ttimoff() + Turns off all pending timer interrupts. + + int + ttinc(timo) int timo; (function is old, return codes are new) + Reads one character from the communication device. If timo is + greater than zero, wait the given number of seconds and then + time out if no character arrives, otherwise wait forever for a + character. Returns: + -3: internal error (e.g. tty modes set wrong) + -2: communications disconnect + -1: timeout or other error + >=0: the character that was read. + It is HIGHLY RECOMMENDED that ttinc() be internally buffered so + that calls to it are relatively inexpensive. If it is possible + to to implement ttinc() as a macro, all the better, for example + something like: + + #define ttinc(t) ( (--txbufn >= 0) ? txbuf[ttbufp++] : txbufr(t) ) + + (see description of txbufr() below) + + int + ttinl(dest,max,timo,eol,start,turn) int max,timo,turn; CHAR + *dest, eol, start; + ttinl() is Kermit's packet reader. Reads a packet from the + communications device, or up to max characters, whichever occurs + first. A line is a string of characters starting with the start + character up to and including the character given in eol or + until the length is exhausted, or, if turn != 0, until the line + turnaround character (turn) is read. If turn is 0, ttinl() + *should* use the packet length field to detect the end, to allow + for the possibility that the eol character appears unprefixed in + the packet data. (The turnaround character is for half-duplex + linemode connections.) + + If timo is greater than zero, ttinl() times out if the eol + character is not encountered within the given number of seconds + and returns -1. + + The characters that were input are copied into "dest" with their + parity bits stripped if parity is not none. The first character + copied into dest should be the start character, and the last + should be the final character of the packet (the last block + check character). ttinl() should also absorb and discard the eol + and turn characters, and any other characters that are waiting + to be read, up until the next start character, so that + subsequent calls to ttchk() will not succeed simply because + there are some terminators still sitting in the buffer that + ttinl() didn't read. This operation, if performed, MUST NOT + BLOCK (so if it can't be performed in a guaranteed nonblocking + way, don't do it). + + On success, ttinl() returns the number of characters read. + Optionally, ttinl() can sense the parity of incoming packets. If + it does this, then it should set the global variable ttprty + accordingly. ttinl() should be coded to be as efficient as + possible, since it is at the "inner loop" of packet reception. + ttinl() returns: + -1: Timeout or other possibly correctable error. + -2: Interrupted from keyboard. + -3: Uncorrectable i/o error -- connection lost, configuration + problem, etc. + >=0: on success, the number of characters that were actually + read and placed in the dest buffer, not counting the trailing + null. + + int + ttoc(c) char c; + Outputs the character c to the communication line. If the + operation fails to complete within two seconds, this function + returns -1. Otherwise it returns the number of characters + actually written to the tty (0 or 1). This function should only + be used for interactive, character-mode operations, like + terminal connection, script execution, dialer i/o, where the + overhead of the signals and alarms does not create a bottleneck. + (THIS DESCRIPTION NEEDS IMPROVEMENT -- If the operation fails + within a "certain amount of time"... which might be dependent on + the communication method, speed, etc. In particular, + flow-control deadlocks must be accounted for and broken out of + to prevent the program from hanging indefinitely, etc.) + + int + ttol(s,n) int n; char *s; + Kermit's packet writer. Writes the n characters of the string + pointed to to by s. NOTE: It is ttol's responsibility to write + ALL of the characters, not just some of them. Returns: + -1: on a possibly correctable error (so it can be retried). + -3: on a fatal error, e.g. connection lost. + >=0: on success, the actual number of characters written (the + specific number is not actually used for anything). + + int + ttopen(ttname,lcl,modem,timo) char *ttname; int *lcl, modem, + timo; + Opens a tty device, if it is not already open. ttopen must check + to make sure the SAME device is not already open; if it is, + ttopen returns successfully without doing anything. If a + DIFFERENT device is currently open, ttopen() must call ttclos() + to close it before opening the new one. + + Parameters: + + ttname: + character string - device name or network host name. + + lcl: + If called with lcl < 0, sets value of lcl as + follows: + 0: the terminal named by ttname is the job's + controlling terminal. + 1: the terminal named by ttname is not the job's + controlling terminal. + If the device is already open, or if the requested + device can't be opened, then lcl remains (and is + returned as) -1. + + modem: + Less than zero: this is the negative of the network + type, and ttname is a network host name. Network + types (from [122]ckcnet.h: + + NET_TCPB 1 TCP/IP Berkeley (socket) (implemented in [123]ckutio.c) + NET_TCPA 2 TCP/IP AT&T (streams) (not yet implemented) + NET_DEC 3 DECnet (not yet implemented) + + Zero or greater: ttname is a terminal device name. + Zero means a direct connection (don't use modem + signals). Positive means use modem signals depending + on the current setting of ttcarr (see ttscarr()). + + timo: + > 0: number of seconds to wait for open() to return + before timing out. + <=0: no timer, wait forever (e.g. for incoming + call). + For real tty devices, ttopen() attempts to gain + exclusive access to the tty device, for example in + UNIX by creating a "lockfile" (in other operating + systems, like VMS, exclusive access probably + requires no special action). + + Side effects: + Copies its arguments and the tty file descriptor to global + variables that are available to the other tty-related + functions, with the lcl value altered as described above. + Gets all parameters and settings associated with the line + and puts them in a global area, so that they can be + restored by ttres(), e.g. when the device is closed. + + Returns: + 0: on success + -5: if device is in use + -4: if access to device is denied + -3: if access to lock mechanism denied + -2: upon timeout waiting for device to open + -1: on other error + + int + ttpkt(speed,flow,parity) long speed; int flow, parity; + Puts the currently open tty device into the appropriate modes + for transmitting and receiving Kermit packets. + + Arguments: + + speed: + if speed > -1, and the device is a true tty device, + and Kermit is in local mode, ttpkt also sets the + speed. + + flow: + if in the range 0-3, ttpkt selects the corresponding + type of flow control. Currently 0 is defined as no + flow control, 1 is Xon/Xoff, and no other types are + defined. If (and this is a horrible hack, but it + goes back many years and will be hard to eradicate) + flow is 4, then the appropriate tty modes are set + for modem dialing, a special case in which we talk + to a modem-controlled line without requiring + carrier. If flow is 5, then we require carrier. + + parity: + This is simply copied into a global variable so that + other functions (like ttinl, ttinc, etc) can use it. + + Side effects: + Copies its arguments to global variables, flushes the + terminal device input buffer. + + Returns: + -1: on error. + 0: on success. + + int + ttsetflow(int) + Enables the given type of flow control on the open serial + communications device immediately. Arguments are the FLO_xxx + values from ckcdeb.h, except FLO_DIAL, FLO_DIAX, or FLO_AUTO, + which are not actual flow-control types. Returns 0 on success, + -1 on failure. + + #ifdef TTSPDLIST + long * + ttspdlist() + Returns a pointer to an array of longs, or NULL on failure. On + success, element 0 of the array contains number, n, indicating + how many follow. Elements 1-n are serial speeds, expressed in + bits per second, that are legal on this platform. The user + interface may use this list to construct a menu, keyword table, + etc. + + #endif /* TTSPDLIST */ + + int + ttres() + Restores the tty device to the modes and settings that were in + effect at the time it was opened (see ttopen). Returns: + -1: on error. + 0: on success. + + int + ttruncmd(string) char * string; + Runs the given command on the local system, but redirects its + input and output to the communication (SET LINE, SET PORT, or + SET HOST) device. Returns: + 0: on failure. + 1: on success. + + int + ttscarr(carrier) int carrier; + Copies its argument to a variable that is global to the other + tty-related functions, and then returns it. The values for + carrier are defined in ckcdeb.h: CAR_ON, CAR_OFF, CAR_AUTO. + ttopen(), ttpkt(), and ttvt() use this variable when deciding + how to open the tty device and what modes to select. The + meanings are these: + + CAR_OFF: Ignore carrier at all times. + CAR_ON: Require carrier at all times, except when dialing. This means, + for example, that ttopen() could hang forever waiting for carrier if it + is not present. + CAR_AUTO: If the modem type is zero (i.e. the connection is direct), + this is the same as CAR_OFF. If the modem type is positive, then heed + carrier during CONNECT (ttvt mode), but ignore it at other times + (packet mode, during SET LINE, etc). Compatible with pre-5A versions of + C-Kermit. This should be the default carrier mode. + + Kermit's DIAL command ignores the carrier setting, but ttopen(), + ttvt(), and ttpkt() all honor the carrier option in effect at + the time they are called. None of this applies to remote mode + (the tty device is the job's controlling terminal) or to network + host connections (modem type is negative). + + int + ttsndb() + Sends a BREAK signal on the tty device. On a real tty device, + send a real BREAK lasting approximately 275 milliseconds. If + this is not possible, simulate a BREAK by (for example) dropping + down some very low baud rate, like 50, and sending a bunch of + null characters. On a network connection, do the appropriate + network protocol for BREAK. Returns: + -1: on error. + 0: on success. + + int + ttsndlb() + Like ttsndb(), but sends a "Long BREAK" (approx 1.5 seconds). + For network connections, it is identical to ttsndb(). Currently, + this function is used only if CK_LBRK is defined (as it is for + UNIX and VMS). + + int + ttsspd(cps) int cps; + For serial devices only, set the device transmission speed to + (note carefully) TEN TIMES the argument. The argument is in + characters per second, but transmission speeds are in bits per + second. cps are used rather than bps because high speeds like + 38400 are not expressible in a 16-bit int but longs cannot be + used because keyword-table values are ints and not longs. If the + argument is 7, then the bps is 75, not 70. If the argument is + 888, this is a special code for 75/1200 split-speed operation + (75 bps out, 1200 bps in). Returns: + -1: on error, meaning the requested speed is not valid or + available. + >=0: on success (don't try to use this value for anything). + + int + ttvt(speed,flow) long speed; int flow; + Puts the currently open tty device into the appropriate modes + for terminal emulation. The arguments are interpreted as in + ttpkt(). Side effects: ttvt() stores its arguments in global + variables, and sets a flag that it has been called so that + subsequent calls can be ignored so long as the arguments are the + same as in the last effective call. Other functions, such as + ttopen(), ttclose(), ttres(), ttvt(), etc, that change the tty + device in any way must unset this flag. In UNIX Kermit, this + flag is called tvtflg. + + int + ttwmdm(mdmsig,timo) int mdmsig, timo; + Waits up to timo seconds for all of the given modem signals to + appear. mdmsig is a bit mask, in which a bit is on (1) or off + (0) according to whether the corresponding signal is to be + waited for. These symbols are defined in ckcdeb.h: + BM_CTS (bit 0) means wait for Clear To Send + BM_DSR (bit 1) means wait for Data Set Ready + BM_DCD (bit 2) means wait for Carrier Detect + Returns: + -3: Not implemented. + -2: This line does not have modem control. + -1: Timeout: time limit exceeded before all signals were + detected. + 1: Success. + + int + ttxin(n,buf) int n; CHAR *buf; + Reads x characters from the tty device into the specified buf, + stripping parity if parity is not none. This call waits forever, + there is no timeout. This function is designed to be called only + when you know that at least x characters are waiting to be read + (as determined, for example, by ttchk()). This function should + use the same buffer as ttinc(). + + int + txbufr(timo) int timo; + Reads characters into the internal communications input buffer. + timo is a timeout interval, in seconds. 0 means no timeout, wait + forever. Called by ttinc() (and possibly ttxin() and ttinl()) + when the communications input buffer is empty. The buffer should + be called ttxbuf[], its length is defined by the symbol TXBUFL. + The global variable txbufn is the number of characters available + to be read from ttxbuf[], and txbufp is the index of the next + character to be read. Should not be called if txbufn > 0, in + which case the buffer does not need refilling. This routine + returns: + -2: Communications disconnect + -1: Timeout + >=0: A character (0 - 255) On success, the first character that + was read, with the variables txbufn and txbufp set appropriately + for any remaining characters. + NOTE: Currently this routine is used internally only by the UNIX + and VMS versions. The aim is to make it available to all + versions so there is one single coherent and efficient way of + reading from the communications device or network. + +4.E.2.6. Miscellaneous system-dependent functions + + VOID + ztime(s) char **s; + Returns a pointer, s, to the current date-and-time string in s. + This string must be in the fixed-field format associated with + the C runtime asctime() function, like: "Sun Sep 16 13:23:45 + 1973\n" so that callers of this function can extract the + different fields. The pointer value is filled in by ztime, and + the data it points to is not safe, so should be copied to a safe + place before use. ztime() has no return value. As a side effect, + this routine can also fill in the following two external + variables (which must be defined in the system-dependendent + modules for each platform): + long ztusec: Fraction of seconds of clock time, microseconds. + long ztmsec: Fraction of seconds of clock time, milliseconds. + If these variables are not set by zstime(), they remain at their + initial value of -1L. + + int + gtimer() + Returns the current value of the elapsed time counter in seconds + (see rtimer), or 0 on any kind of error. + + #ifdef GFTIMER + CKFLOAT + gftimer() + Returns the current value of the elapsed time counter in + seconds, as a floating point number, capable of representing not + only whole seconds, but also the fractional part, to the + millisecond or microsecond level, whatever precision is + available. Requires a function to get times at subsecond + precision, as well as floating-point support. That's why it's + #ifdef'd. + + #endif /* GFTIMER */ + + int + msleep(m) int m; + Sleeps (pauses, does nothing) for m milliseconds (a millisecond + is one thousandth of a second). Returns: + -1: on failure. + 0: on success. + + VOID + rtimer() + Sets the elapsed time counter to zero. If you want to time how + long an operation takes, call rtimer() when it starts and gtimer + when it ends. rtimer() has no return value. + + #ifdef GFTIMER + VOID + rftimer() + Sets the elapsed time counter to zero. If you want to time how + long an operation takes, call rftimer() when it starts and + gftimer when it ends. rftimer() has no return value. Note: + rftimer() is to be used with gftimer() and rtimer() is to be + used with gtimer(). See the rftimer() description. + + #endif /* GFTIMER */ + + int + sysinit() + Does whatever needs doing upon program start. In particular, if + the program is running in any kind of privileged mode, turns off + the privileges (see priv_ini()). Returns: + -1: on error. + 0: on success. + + int + syscleanup() + Does whatever needs doing upon program exit. Returns: + -1: on error. + 0: on success. + + int + psuspend() + Suspends the Kermit process, puts it in the background so it can + be continued ("foregrounded") later. Returns: + -1: if this function is not supported. + 0: on success. + + [ [124]Contents ] [ [125]C-Kermit ] [ [126]Kermit Home ] + +4.F. Group F: Network Support + + As of version 5A, C-Kermit includes support for several networks. + Originally, this was just worked into the ttopen(), ttclos(), ttinc(), + ttinl(), and similar routines in [127]ckutio.c. But this made it + impossible to share this code with non-UNIX versions, like VMS, AOS/VS, + OS/2, etc. So as of edit 168, network code has been separated out into + its own module and header file, ckcnet.c and ckcnet.h: + + [128]ckcnet.h: Network-related symbol definitions. + [129]ckcnet.c: Network i/o (TCP/IP, X.25, etc), shared by most + platforms. + [130]cklnet.c: Network i/o (TCP/IP, X.25, etc) specific to Stratus + VOS. + + The routines and variables in these modules fall into two categories: + + 1. Support for specific network packages like SunLink X.25 and TGV + MultiNet, and: + 2. support for specific network virtual terminal protocols like CCITT + X.3 and TCP/IP Telnet. + + Category (1) functions are analogs to the tt*() functions, and have + names like netopen, netclos, nettinc, etc. Group A-D modules do not + (and must not) know anything about these functions -- they continue to + call the old Group E functions (ttopen, ttinc, etc). Category (2) + functions are protocol specific and have names prefixed by a protocol + identifier, like tn for telnet x25 for X.25. + + ckcnet.h contains prototypes for all these functions, as well as symbol + definitions for network types, protocols, and network- and protocol- + specific symbols, as well as #includes for the header files necessary + for each network and protocol. + + The following functions are to be provided for networks that do not use + normal system i/o (open, read, write, close): + + int + netopen() + To be called from within ttopen() when a network connection is + requested. Calling conventions and purpose same as Group E + ttopen(). + + int + netclos() + To be called from within ttclos() when a network connection is + being closed. Calling conventions and purpose same as Group E + ttclos(). + + int + nettchk() + To be called from within ttchk(). Calling conventions and + purpose same as Group E ttchk(). + + int + netflui() + To be called from within ttflui(). Calling conventions and + purpose same as Group E ttflui(). + + int + netbreak() + To send a network break (attention) signal. Calling conventions + and purpose same as Group E ttsndbrk(). + + int + netinc() + To get a character from the network. Calling conventions same as + Group E ttsndbrk(). + + int + nettoc() + Send a "character" (byte) to the network. Calling conventions + same as Group E ttoc(). + + int + nettol() + Send a "line" (sequence of bytes) to the network. Calling + conventions same as Group E ttol(). + + Conceivably, some systems support network connections simply by letting + you open a device of a certain name and letting you do i/o to it. + Others (like the Berkeley sockets TCP/IP library on UNIX) require you + to open the connection in a special way, but then do normal i/o (read, + write). In such a case, you would use netopen(), but you would not use + nettinc, nettoc, etc. + + VMS TCP/IP products have their own set of functions for all network + operations, so in that case the full range of netxxx() functions is + used. + + The technique is to put a test in each corresponding ttxxx() function + to see if a network connection is active (or is being requested), test + for which kind of network it is, and if necessary route the call to the + corresponding netxxx() function. The netxxx() function must also + contain code to test for the network type, which is available via the + global variable ttnet. + + [ [131]Contents ] [ [132]C-Kermit ] [ [133]Kermit Home ] + +4.F.1. Telnet Protocol + + (This section needs a great deal of updating...) + + As of edit 195, Telnet protocol is split out into its own files, since + it can be implemented in remote mode, which does not have a network + connection: + + [134]ckctel.h: Telnet protocol symbol definitions. + [135]ckctel.c: Telnet protocol. + + The Telnet protocol is supported by the following variables and + routines: + + int tn_init + Nonzero if telnet protocol initialized, zero otherwise. + + int + tn_init() + Initialize the telnet protocol (send initial options). + + int + tn_sopt() + Send a telnet option. + + int + tn_doop() + Receive and act on a telnet option from the remote. + + int + tn_sttyp() + Send terminal type using telnet protocol. + +4.F.2. FTP Protocol + + (To be filled in...) + +4.F.3. HTTP Protocol + + (To be filled in...) + +4.F.4. X.25 Networks + + These routines were written SunLink X.25 and have since been adapted to + at least on one other: IBM AIXLink/X.25. + + int + x25diag() + Reads and prints X.25 diagnostics + + int + x25oobh() + X.25 out of band signal handler + + int + x25intr() + Sends X.25 interrupt packet + + int + x25reset() + Resets X.25 virtual circuit + + int + x25clear() + Clear X.25 virtual circuit + + int + x25stat() + X.25 status + + int + setqbit() + Sets X.25 Q-bit + + int + resetqbit() + Resets X.25 Q-bit + + int + x25xin() + Reads n characters from X.25 circuit. + + int + x25inl() + Read a Kermit packet from X.25 circuit. + + [ [136]Contents ] [ [137]C-Kermit ] [ [138]Kermit Home ] + +4.F.5. Adding New Network Types + + Example: Adding support for IBM X.25 and Hewlett Packard X.25. First, + add new network type symbols for each one. There are already some + network types defined for other X.25 packages: + + NET_SX25 is the network-type ID for SunLink X.25. + NET_VX25 is the network-type ID for VOS X.25. + + So first you should new symbols for the new network types, giving them + the next numbers in the sequence, e.g.: + +#define NET_HX25 11 /* Hewlett-Packard X.25 */ +#define NET_IX25 12 /* IBM X.25 */ + + This is in ckcnet.h. + + Then we need symbols to say that we are actually compiling in the code + for these platforms. These would be defined on the cc command line: + + -DIBMX25 (for IBM) + -DHPX25 (for HP) + + So we can build C-Kermit versions for AIX and HP-UX both with and + without X.25 support (since not all AIX and IBM systems have the needed + libraries, and so an executable that was linked with them might no + load). + + Then in ckcnet.h: + +#ifdef IBMX25 +#define ANYX25 +#endif /* IBMX25 */ + +#ifdef HPX25 +#define ANYX25 +#endif /* HPX25 */ + + And then use ANYX25 for code that is common to all of them, and IBMX25 + or HPX25 for code specific to IBM or HP. + + It might also happen that some code can be shared between two or more + of these, but not the others. Suppose, for example, that you write code + that applies to both IBM and HP, but not Sun or VOS X.25. Then you add + the following definition to ckcnet.h: + +#ifndef HPORIBMX25 +#ifdef HPX25 +#define HPORIBMX25 +#else +#ifdef IBMX25 +#define HPORIBMX25 +#endif /* IBMX25 */ +#endif /* HPX25 */ +#endif /* HPORIBMX25 */ + + You can NOT use constructions like "#if defined (HPX25 || IBMX25)"; + they are not portable. + + [ [139]Contents ] [ [140]C-Kermit ] [ [141]Kermit Home ] + +4.G. Group G: Formatted Screen Support + + So far, this is used only for the fullscreen local-mode file transfer + display. In the future, it might be extended to other uses. The + fullscreen display code is in and around the routine screenc() in + [142]ckuusx.c. + + In the UNIX version, we use the curses library, plus one call from the + termcap library. In other versions (OS/2, VMS, etc) we insert dummy + routines that have the same names as curses routines. So far, there are + two methods for simulating curses routines: + + 1. In VMS, we use the Screen Management Library (SMG), and insert + stubs to convert curses calls into SMG calls. + 2. In OS/2, we use the MYCURSES code, in which the stub routines + actually emit the appropriate escape sequences themselves. + + Here are the stub routines: + + int + tgetent(char *buf, char *term) + Arguments are ignored. Returns 1 if the user has a supported + terminal type, 0 otherwise. Sets a global variable (for example, + "isvt52" or "isdasher") to indicate the terminal type. + + VOID + move(int row, int col) + Sends the escape sequence to position the cursor at the + indicated row and column. The numbers are 0-based, e.g. the home + position is 0,0. + + int + clear() + Sends the escape sequence to clear the screen. + + int + clrtoeol() + Sends the escape sequence to clear from the current cursor + position to the end of the line. + + In the MYCURSES case, code must be added to each of the last three + routines to emit the appropriate escape sequences for a new terminal + type. + + clearok(curscr), wrefresh() + In real curses, these two calls are required to refresh the + screen, for example after it was fractured by a broadcast + message. These are useful only if the underlying screen + management service keeps a copy of the entire screen, as curses + and SMG do. C-Kermit does not do this itself. + + [ [143]Contents ] [ [144]C-Kermit ] [ [145]Kermit Home ] + +4.H. Group H: Pseudoterminal Support + + (To be filled in...) + +4.I. Group I: Security + + (To be filled in...) + + [ [146]Contents ] [ [147]C-Kermit ] [ [148]Kermit Home ] + +APPENDIX I. FILE PERMISSIONS + +I.1. Format of System-Dependent File Permissions in A-Packets + + The format of this field (the "," attribute) is interpreted according + to the System ID ("." Attribute). + + For UNIX (System ID = U1), it's the familiar 3-digit octal number, the + low-order 9 bits of the filemode: Owner, Group, World, e.g. 660 = + read/write access for owner and group, none for world, recorded as a + 3-digit octal string. High-order UNIX permission bits are not + transmitted. + + For VMS (System ID = D7), it's a 4-digit hex string, representing the + 16-bit file protection WGOS fields (World,Group,Owner,System), in that + order (which is the reverse of how they're shown in a directory + listing); in each field, Bit 0 = Read, 1 = Write, 2 = Execute, 3 = + Delete. A bit value of 0 means permission is granted, 1 means + permission is denied. Sample: + + r-01-00-^A/!FWERMIT.EXE'" + s-01-00-^AE!Y/amd/watsun/w/fdc/new/wermit.exe.DV + r-02-01-^A]"A."D7""B8#119980101 18:14:05!#8531&872960,$A20B-!7(#512@ #.Y + s-02-01-^A%"Y.5! + + A VMS directory listing shows the file's protection as (E,RWED,RED,RE) + which really means (S=E,O=RWED,G=RED,W=RE), which is reverse order from + the internal storage, so (RE,RED,RWED,E). Now translate each letter to + its corresponding bit: + + RE=0101, RED=1101, RWED=1111, E=0010 + + Now reverse the bits: + + RE=1010, RED=0010, RWED=0000, E=1101 + + This gives the 16-bit quantity: + + 1010001000001101 + + This is the internal representation of the VMS file permission; in hex: + + A20B + + as shown in the sample packet above. + + The VMS format probably would also apply to RSX or any other FILES-11 + system. + +I.2. Handling of Generic Protection + + To be used when the two systems are different (and/or do not recognize + or understand each other's local protection codes). + + First of all, the book is wrong. This should not be the World + protection, but the Owner protection. The other fields should be set + according to system defaults (e.g. UNIX umask, VMS default protection, + etc), except that no non-Owner field should give more permissions than + the Owner field. + + [ [149]Top ] [ [150]Contents ] [ [151]C-Kermit Home ] [ [152]Kermit + Home ] + __________________________________________________________________ + + + C-Kermit Program Logic Manual / [153]The Kermit Project / + [154]kermit@columbia.edu / 30 June 2011 + +References + + 1. http://www.columbia.edu/ + 2. mailto:kermit@columbia.edu + 3. http://www.columbia.edu/kermit/index.html + 4. http://www.columbia.edu/kermit/k95.html + 5. http://www.columbia.edu/kermit/ckermit.html + 6. http://www.columbia.edu/kermit/ckscripts.html + 7. http://www.columbia.edu/kermit/current.html + 8. http://www.columbia.edu/kermit/whatsnew.html + 9. http://www.columbia.edu/kermit/ckfaq.html + 10. http://www.columbia.edu/kermit/support.html + 11. http://www.columbia.edu/kermit/ + 12. http://www.columbia.edu/ + 13. http://www.columbia.edu/kermit/ckcplm.html + 14. http://www.columbia.edu/kermit/ckermit.html + 15. http://www.columbia.edu/kermit/index.html + 16. http://www.columbia.edu/kermit/ckcplm.html#x1 + 17. http://www.columbia.edu/kermit/ckcplm.html#x2 + 18. http://www.columbia.edu/kermit/ckcplm.html#x3 + 19. http://www.columbia.edu/kermit/ckcplm.html#x4 + 20. http://www.columbia.edu/kermit/ckcplm.html#x4.A + 21. http://www.columbia.edu/kermit/ckcplm.html#x4.B + 22. http://www.columbia.edu/kermit/ckcplm.html#x4.C + 23. http://www.columbia.edu/kermit/ckcplm.html#x4.D + 24. http://www.columbia.edu/kermit/ckcplm.html#x4.E + 25. http://www.columbia.edu/kermit/ckcplm.html#x4.F + 26. http://www.columbia.edu/kermit/ckcplm.html#x4.G + 27. http://www.columbia.edu/kermit/ckcplm.html#x4.H + 28. http://www.columbia.edu/kermit/ckcplm.html#x4.I + 29. http://www.columbia.edu/kermit/ckcplm.html#xa1 + 30. http://www.columbia.edu/kermit/ckcplm.html#contents + 31. http://www.columbia.edu/kermit/ckcplm.html#contents + 32. http://www.columbia.edu/kermit/ckermit.html + 33. http://www.columbia.edu/kermit/index.html + 34. ftp://kermit.columbia.edu/kermit/c-kermit/ckcpro.w + 35. http://www.columbia.edu/kermit/ckcplm.html#contents + 36. http://www.columbia.edu/kermit/ckermit.html + 37. http://www.columbia.edu/kermit/index.html + 38. http://www.columbia.edu/kermit/ckcplm.html#x3.2 + 39. http://www.columbia.edu/kermit/ckcplm.html#contents + 40. http://www.columbia.edu/kermit/ckermit.html + 41. http://www.columbia.edu/kermit/index.html + 42. http://www.columbia.edu/kermit/ckcplm.html#x4.A + 43. http://www.columbia.edu/kermit/ckcplm.html#contents + 44. http://www.columbia.edu/kermit/ckermit.html + 45. http://www.columbia.edu/kermit/index.html + 46. http://www.columbia.edu/kermit/ckcplm.html#contents + 47. http://www.columbia.edu/kermit/ckermit.html + 48. http://www.columbia.edu/kermit/index.html + 49. http://www.columbia.edu/kermit/ckcplm.html#contents + 50. http://www.columbia.edu/kermit/ckermit.html + 51. http://www.columbia.edu/kermit/index.html + 52. ftp://kermit.columbia.edu/kermit/c-kermit/ckclib.h + 53. ftp://kermit.columbia.edu/kermit/c-kermit/ckclib.c + 54. http://www.columbia.edu/kermit/ckcplm.html#x3.1 + 55. http://www.columbia.edu/kermit/ckcplm.html#contents + 56. http://www.columbia.edu/kermit/ckermit.html + 57. http://www.columbia.edu/kermit/index.html + 58. ftp://kermit.columbia.edu/kermit/c-kermit/ckcsym.h + 59. ftp://kermit.columbia.edu/kermit/c-kermit/ckcasc.h + 60. ftp://kermit.columbia.edu/kermit/c-kermit/ckcsig.h + 61. ftp://kermit.columbia.edu/kermit/c-kermit/ckcdeb.h + 62. ftp://kermit.columbia.edu/kermit/c-kermit/ckcker.h + 63. ftp://kermit.columbia.edu/kermit/c-kermit/ckcxla.h + 64. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c + 65. ftp://kermit.columbia.edu/kermit/c-kermit/ckcpro.w + 66. ftp://kermit.columbia.edu/kermit/c-kermit/ckcfns.c + 67. ftp://kermit.columbia.edu/kermit/c-kermit/ckcfn2.c + 68. ftp://kermit.columbia.edu/kermit/c-kermit/ckcfn3.c + 69. http://www.columbia.edu/kermit/ckcplm.html#x4.B + 70. http://www.columbia.edu/kermit/ckcplm.html#x4.E + 71. http://www.columbia.edu/kermit/ckcplm.html#x4.D + 72. http://www.columbia.edu/kermit/ckcplm.html#contents + 73. http://www.columbia.edu/kermit/ckermit.html + 74. http://www.columbia.edu/kermit/index.html + 75. http://www.columbia.edu/kermit/ckcplm.html#x4.B + 76. ftp://kermit.columbia.edu/kermit/c-kermit/ckuxla.c + 77. ftp://kermit.columbia.edu/kermit/c-kermit/ckuxla.h + 78. ftp://kermit.columbia.edu/kermit/c-kermit/ckcxla.h + 79. ftp://kermit.columbia.edu/kermit/c-kermit/ckuxla.h + 80. ftp://kermit.columbia.edu/kermit/c-kermit/ckmxla.h + 81. ftp://kermit.columbia.edu/kermit/c-kermit/ck?xla + 82. ftp://kermit.columbia.edu/kermit/c-kermit/ckcuni.h + 83. ftp://kermit.columbia.edu/kermit/c-kermit/ckcuni.c + 84. http://www.columbia.edu/kermit/ckcplm.html#contents + 85. http://www.columbia.edu/kermit/ckermit.html + 86. http://www.columbia.edu/kermit/index.html + 87. http://www.columbia.edu/kermit/ckcplm.html#x4.B + 88. ftp://kermit.columbia.edu/kermit/c-kermit/ckucmd.h + 89. ftp://kermit.columbia.edu/kermit/c-kermit/ckucmd.c + 90. http://www.columbia.edu/kermit/ckcplm.html#x4.E + 91. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusr.h + 92. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusr.c + 93. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus2.c + 94. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus3.c + 95. ftp://kermit.columbia.edu/kermit/c-kermit/ckuus4.c + 96. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusy.c + 97. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusx.c + 98. ftp://kermit.columbia.edu/kermit/c-kermit/ckuver.h + 99. ftp://kermit.columbia.edu/kermit/c-kermit/ckuscr.c + 100. ftp://kermit.columbia.edu/kermit/c-kermit/ckudia.c + 101. ftp://kermit.columbia.edu/kermit/c-kermit/ckucon.c + 102. ftp://kermit.columbia.edu/kermit/c-kermit/ckucns.c + 103. http://www.columbia.edu/kermit/ckcplm.html#x4.E + 104. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c + 105. http://www.columbia.edu/kermit/ckcplm.html#contents + 106. http://www.columbia.edu/kermit/ckermit.html + 107. http://www.columbia.edu/kermit/index.html + 108. ftp://kermit.columbia.edu/kermit/c-kermit/ckufio.c + 109. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c + 110. ftp://kermit.columbia.edu/kermit/c-kermit/ckusig.c + 111. ftp://kermit.columbia.edu/kermit/c-kermit/ckvfio.c + 112. ftp://kermit.columbia.edu/kermit/c-kermit/ckusig.c + 113. ftp://kermit.columbia.edu/kermit/c-kermit/ckcmai.c + 114. http://www.columbia.edu/kermit/ckcplm.html#contents + 115. http://www.columbia.edu/kermit/ckermit.html + 116. http://www.columbia.edu/kermit/index.html + 117. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c + 118. ftp://kermit.columbia.edu/kermit/c-kermit/ckvtio.c + 119. http://www.columbia.edu/kermit/ckcplm.html#x2 + 120. http://www.columbia.edu/kermit/ckcplm.html#xa1 + 121. http://www.columbia.edu/kermit/ckuins.html + 122. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.h + 123. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c + 124. http://www.columbia.edu/kermit/ckcplm.html#contents + 125. http://www.columbia.edu/kermit/ckermit.html + 126. http://www.columbia.edu/kermit/index.html + 127. ftp://kermit.columbia.edu/kermit/c-kermit/ckutio.c + 128. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.h + 129. ftp://kermit.columbia.edu/kermit/c-kermit/ckcnet.c + 130. ftp://kermit.columbia.edu/kermit/c-kermit/cklnet.c + 131. http://www.columbia.edu/kermit/ckcplm.html#contents + 132. http://www.columbia.edu/kermit/ckermit.html + 133. http://www.columbia.edu/kermit/index.html + 134. ftp://kermit.columbia.edu/kermit/c-kermit/ckctel.h + 135. ftp://kermit.columbia.edu/kermit/c-kermit/ckctel.c + 136. http://www.columbia.edu/kermit/ckcplm.html#contents + 137. http://www.columbia.edu/kermit/ckermit.html + 138. http://www.columbia.edu/kermit/index.html + 139. http://www.columbia.edu/kermit/ckcplm.html#contents + 140. http://www.columbia.edu/kermit/ckermit.html + 141. http://www.columbia.edu/kermit/index.html + 142. ftp://kermit.columbia.edu/kermit/c-kermit/ckuusx.c + 143. http://www.columbia.edu/kermit/ckcplm.html#contents + 144. http://www.columbia.edu/kermit/ckermit.html + 145. http://www.columbia.edu/kermit/index.html + 146. http://www.columbia.edu/kermit/ckcplm.html#contents + 147. http://www.columbia.edu/kermit/ckermit.html + 148. http://www.columbia.edu/kermit/index.html + 149. http://www.columbia.edu/kermit/ckcplm.html#top + 150. http://www.columbia.edu/kermit/ckcplm.html#contents + 151. http://www.columbia.edu/kermit/ckermit.html + 152. http://www.columbia.edu/kermit/index.html + 153. http://www.columbia.edu/kermit/index.html + 154. mailto:kermit@columbia.edu