📄 ckcplm.doc
字号:
CKAPLM.DOC September 1996 C-KERMIT PROGRAM LOGIC MANUALAs of C-Kermit version: 6.0.192This file last updated: Fri Sep 6 23:23:04 1996Author: Frank da Cruz, Columbia UniversityE-Mail: fdc@columbia.edu Copyright (C) 1985, 1996, Trustees of Columbia University in the City of New York. The C-Kermit software may not be, in whole or in part, licensed or sold for profit as a software product itself, nor may it be included in or distributed with commercial products or otherwise distributed by commercial concerns to their clients or customers without written permission of the Office of Kermit Development and Distribution, Columbia University. This copyright notice must not be removed, altered, or obscured.DOCUMENTATIONC-Kermit 6.0 is documented in the book "Using C-Kermit" by Frank da Cruz andChristine M. Gianone, Second Edition, Digital Press / Butterworth-Heinemann,Woburn, MA, 1997, ISBN 1-55558-164-1, Price: US $39.95. To order call theKermit Project at Columbia University, +1 212 854-3703, and order with MasterCard or Visa, or call Digital Press, +1 800 366-2665, and order with MasterCard, Visa, or American Express.INTRODUCTIONThis is an attempt at describing the relationship among the modules andfunctions of C-Kermit 6.0. Before reading this file, please read thefile CKAAAA.HLP for an overview of C-Kermit file naming conventions.C-Kermit is designed to be portable to any kind of computer that has a Ccompiler. The source code is broken into many files that are groupedaccording to their function. There are several major groups: 1 (the protocolkernel), 2 (the user interface), 3 (system-dependent primitives), 4 (networksupport), and 5 (formatted screen support).FILESC-Kermit source files begin with the two letters CK (lowercase on UNIXsystems, uppercase on most others). The third character denotes somethingabout the function group and the expected level of portability. See the fileCKAAAA.HLP for details of file naming conventions and organization.One hint before proceeding: functions are scattered all over the ckc*.cand ckuu*.c modules, where function size has begun to take precedence overthe desirability of grouping related functions together, the aim being tokeep any particular module from growing disproportionately large. The easiestway (in UNIX) to find out what source file a given function is defined in islike this (where the desired function is foo()...): grep ^foo ck*.cThis works because the coding convention has been to make function namesalways start on the left margin, for example:static char *foo(x,y) int x, y; { ...}Also please note the style for bracket placement. This allowsbracket-matching text editors (such as EMACS) to help you make sure youwhich opening bracket a closing bracket matches, particularly when it isno longer visible on the screen, and it also makes it easy to find the endof a function.Of course EMACS tags work nicely with this format too.SOURCE CODE PORTABILITY GUIDEWhen writing code for the system-indendent C-Kermit modules, please stick tothe following coding conventions to ensure portability to the widest possiblevariety of C preprocessors, compilers, and linkers, as well as certain networkand/or email transports:. All lines must no more than 79 characters wide after tab expansion, and tabs should be assumed every 8 spaces.. Note the distinction between physical tabs (ASCII 9) and the indentation conventions, which are: 4 for block contents, 2 for most other stuff.. 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 linkers.. Keep preprocessor symbols unique within 8 characters.. Don't put #include directives inside functions or { blocks }.. Don't use the #if preprocessor construction, only use #ifdef, #ifndef, #undef. 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.. Always cast strlen() to int, e.g. "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 the construction *++p -- the order of evaluation varies.. Reportedly, some compilers even mess up with *(++p).. Don't use triple assignments, like a = b = c = 0; (or quadruple, etc). Some compilers generate bad code for these, or crash, etc.. Structure members may not have the same names as other identifiers.. Avoid huge switch() statements with many case:s.. Don't put anything between "switch() {" and case:. Some compilers do not treat switch blocks like other blocks.. Don't make character-string constants longer than about 250.. 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. in switch() statements).. 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 first edition.. Don't use or depend on anything_t (size_t, time_t, etc).. Don't use or depend on internationalization features ("i18n"), wchar_t, locales, etc, in portable code; they are not portable.. 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 difference 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 stuff if you can).. memset() and memcpy() are not portable, don't use them without protecting them in ifdefs. bzero() too, except we're guaranteed to have bzero() when using the sockets library. See examples in the source.. Don't assume that strncpy() stops on the first null byte -- some versions always copy the number of bytes given in arg 3. Probably also true of other strnblah() functions.. 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 htons(), etc, 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.. Don't depend on any other ANSI features like "preprocessor pasting" -- they are often missing or nonoperational.. Don't assume any C++ syntax or semantics.. Don't declare a string as "char foo[]" in one module and "extern char * foo" in another, or vice-versa.. With compiler makers falling all over themselves trying to outdo each other in ANSI strictness, it has become increasingly necessary to cast EVERYTHING.. 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.. 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.Example of the latter:int /* Put character in server command buffer */#ifdef CK_ANSICputsrv(char c)#elseputsrv(c) char c;#endif /* CK_ANSIC *//* putsrv */ { *srvptr++ = c; *srvptr = '\0'; /* Make sure buffer is null-terminated */ return(0);}(many, many more... This section needs massive filling in.)C-Kermit needs constant adjustment to new OS and compiler releases. Everynew release shuffles header files or their contents, or prototypes, or datatypes, or levels of ANSI strictness, etc. Every time you make an adjustmentto remove a new compilation error, BE VERY CAREFUL to #ifdef it on a symbolunique to the new configuration so that the previous configuration (and allother 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 specificsymbols to have certain values -- or define them at all! Don't assume systemheader files protect themselves against multiple inclusion. Don't assume thatparticular system or library calls are available, or that the arguments arewhat you think they are -- order, data type, passed by reference vs value,etc. Be very conservative when attempting to write portable code. Avoid alladvanced features. Stick with K&R First Edition, and even then you're onshaky ground.If you see something that does not make sense, don't assume it's a mistake --it is probably there for a reason, and changing it or removing is very likelyto cause compilation, linking, or runtime failures sometime, somewhere. Somehuge percentage of the code, especially in the system-dependent modules, isworkarounds for compiler, linker, or API bugs.BUT... feel free to violate any or all of these rules in system-specificmodules for environments in which the rules are certain not to apply. Forexample, in VMS-specific code, it is OK to use #if. But even then, allow fordifferent compilers or compiler versions used in that same environment,e.g. VAX C vs DEC C vs GNU C.THE "CHAR" VS "UNSIGNED CHAR" DILEMMAThis is one of the most aggravating and vexing things about C. By default,chars (and char *'s) are SIGNED. But in the modern era, we need to processcharacters that can have 8-bit values, such as ISO Latin-1, IBM CP 850, andother 8-bit (or 16-bit, etc) character sets, and so this data MUST be treatedas unsigned. BUT... Some C compilers (such as those based on the Bell UNIXV7 compiler) do not support "unsigned char" as a data type. Therefore we havethe macro or typedef CHAR, which we use when we need chars to be unsigned, butwhich, unfortunately, resolves itself to "char" on those compilers that don'tsupport "unsigned char". AND SO... We have to do a lot of fiddling atruntime to avoid sign extension and so forth. BUT THAT'S NOT ALL... Now somemodern compilers (e.g. IBM, DEC, Microsoft) have switches that say "make allchars be unsigned". We use these switches when they are available. Othercompilers don't have these, and at the same time, are becoming increasinglystrict about type mismatches, and spew out torrents of warnings when we use aCHAR where a char is expected, or vice versa. We fix these one by one usingcasts, and the code becomes increasingly ugly. But there remains a seriousproblem, namely that certain library and kernel functions have arguments thatare declared as signed chars (or pointers to them), whereas our character datais unsigned. Fine, we can can use casts here too -- BUT WHO KNOWS WHATHAPPENS inside these routines!CONTENTS: GROUP 1 System-independent file transfer protocol GROUP 1.5 Character set translation GROUP 2 User Interface GROUP 3 File & communications i/o and other system dependencies GROUP 4 Network support GROUP 5 Formatted screen supportGROUP 1:The Kermit protocol kernel. The filenames start with CKC. C means that thesefiles are supposed to be totally portable C, and are expected to compilecorrectly on any operating system. "Portable" does not mean the same as as"ANSI" -- these modules must compile on 10- and 20-year old computers, with Cpreprocessors, compilers, and/or linkers that have all sorts of restrictions.The group 1 modules do not include any header files other than those thatcome with Kermit itself. They do not contain any library calls (like printf)or any system calls (like open, close, read, write). Files: CKCSYM.H - For use by C compilers that don't allow -D on the command line. CKCASC.H - ASCII character symbol definitions. CKCSIG.H - System-independent signal-handling definitions and prototypes. CKCDEB.H - Originally, debugging definitions. Now this file also contains all definitions and prototypes that are shared by all modules in all groups. CKCKER.H - Kermit protocol symbol definitions. CKCNET.H - Network-related symbol definitions. CKCXLA.H - Character-set-related symbol definitions (see next section). CKCMAI.C - The main program. This module contains the declarations of all the protocol-related global variables that are shared among the other modules. CKCPRO.W - The protocol module itself, written in "wart", a lex-like preprocessor that is distributed with Kermit under the name CKWART.C. CKCFN*.C - The protocol support functions used by the protocol module.Group 1 modules may call upon functions from Group 3 modules, but not fromGroup 2 modules (with the single exception that the main program invokes theuser interface, which is in Group 2). (This last assertion is really only aconjecture.)GROUP 1.5Character set translation tables and functions. Used by the Group I protocolmodules, but may be specific to different computers. (So far, all charactercharacter sets supported by C-Kermit are supported in CKUXLA.C and CKUXLA.H,including Macintosh and IBM character sets). These modules should becompletely portable, and not rely on any kind of system or library services. CKCXLA.H - Character-set definitions usable by all versions of C-Kermit. CK?XLA.H - Character-set definitions for computer "?", e.g. U for UNIX. CK?XLA.C - 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. Used for file transfer (SEND, RECEIVE, GET, REMOTE, etc), TRANSMIT, CONNECT, etc. Here's how to add a new file character set. 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -