OSDN Git Service

Prepare for release of 1.98e.
[ffftp/ffftp.git] / contrib / putty / DOC / UDP.BUT
diff --git a/contrib/putty/DOC/UDP.BUT b/contrib/putty/DOC/UDP.BUT
deleted file mode 100644 (file)
index 6635654..0000000
+++ /dev/null
@@ -1,389 +0,0 @@
-\# This file is so named for tradition's sake: it contains what we\r
-\# always used to refer to, before they were written down, as\r
-\# PuTTY's `unwritten design principles'. It has nothing to do with\r
-\# the User Datagram Protocol.\r
-\r
-\define{versionidudp} \versionid $Id: udp.but 5525 2005-03-19 02:29:57Z jacob $\r
-\r
-\A{udp} PuTTY hacking guide\r
-\r
-This appendix lists a selection of the design principles applying to\r
-the PuTTY source code. If you are planning to send code\r
-contributions, you should read this first.\r
-\r
-\H{udp-portability} Cross-OS portability\r
-\r
-Despite Windows being its main area of fame, PuTTY is no longer a\r
-Windows-only application suite. It has a working Unix port; a Mac\r
-port is in progress; more ports may or may not happen at a later\r
-date.\r
-\r
-Therefore, embedding Windows-specific code in core modules such as\r
-\cw{ssh.c} is not acceptable. We went to great lengths to \e{remove}\r
-all the Windows-specific stuff from our core modules, and to shift\r
-it out into Windows-specific modules. Adding large amounts of\r
-Windows-specific stuff in parts of the code that should be portable\r
-is almost guaranteed to make us reject a contribution.\r
-\r
-The PuTTY source base is divided into platform-specific modules and\r
-platform-generic modules. The Unix-specific modules are all in the\r
-\c{unix} subdirectory; the Mac-specific modules are in the \c{mac}\r
-subdirectory; the Windows-specific modules are in the \c{windows}\r
-subdirectory.\r
-\r
-All the modules in the main source directory - notably \e{all} of\r
-the code for the various back ends - are platform-generic. We want\r
-to keep them that way.\r
-\r
-This also means you should stick to what you are guaranteed by\r
-ANSI/ISO C (that is, the original C89/C90 standard, not C99). Try\r
-not to make assumptions about the precise size of basic types such\r
-as \c{int} and \c{long int}; don't use pointer casts to do\r
-endianness-dependent operations, and so on.\r
-\r
-(There are one or two aspects of ANSI C portability which we\r
-\e{don't} care about. In particular, we expect PuTTY to be compiled\r
-on 32-bit architectures \e{or bigger}; so it's safe to assume that\r
-\c{int} is at least 32 bits wide, not just the 16 you are guaranteed\r
-by ANSI C.  Similarly, we assume that the execution character\r
-encoding is a superset of the printable characters of ASCII, though\r
-we don't assume the numeric values of control characters,\r
-particularly \cw{'\\n'} and \cw{'\\r'}.)\r
-\r
-\H{udp-multi-backend} Multiple backends treated equally\r
-\r
-PuTTY is not an SSH client with some other stuff tacked on the side.\r
-PuTTY is a generic, multiple-backend, remote VT-terminal client\r
-which happens to support one backend which is larger, more popular\r
-and more useful than the rest. Any extra feature which can possibly\r
-be general across all backends should be so: localising features\r
-unnecessarily into the SSH back end is a design error. (For example,\r
-we had several code submissions for proxy support which worked by\r
-hacking \cw{ssh.c}. Clearly this is completely wrong: the\r
-\cw{network.h} abstraction is the place to put it, so that it will\r
-apply to all back ends equally, and indeed we eventually put it\r
-there after another contributor sent a better patch.)\r
-\r
-The rest of PuTTY should try to avoid knowing anything about\r
-specific back ends if at all possible. To support a feature which is\r
-only available in one network protocol, for example, the back end\r
-interface should be extended in a general manner such that \e{any}\r
-back end which is able to provide that feature can do so. If it so\r
-happens that only one back end actually does, that's just the way it\r
-is, but it shouldn't be relied upon by any code.\r
-\r
-\H{udp-globals} Multiple sessions per process on some platforms\r
-\r
-Some ports of PuTTY - notably the in-progress Mac port - are\r
-constrained by the operating system to run as a single process\r
-potentially managing multiple sessions.\r
-\r
-Therefore, the platform-independent parts of PuTTY never use global\r
-variables to store per-session data. The global variables that do\r
-exist are tolerated because they are not specific to a particular\r
-login session: \c{flags} defines properties that are expected to\r
-apply equally to \e{all} the sessions run by a single PuTTY process,\r
-the random number state in \cw{sshrand.c} and the timer list in\r
-\cw{timing.c} serve all sessions equally, and so on. But most data\r
-is specific to a particular network session, and is therefore stored\r
-in dynamically allocated data structures, and pointers to these\r
-structures are passed around between functions.\r
-\r
-Platform-specific code can reverse this decision if it likes. The\r
-Windows code, for historical reasons, stores most of its data as\r
-global variables. That's OK, because \e{on Windows} we know there is\r
-only one session per PuTTY process, so it's safe to do that. But\r
-changes to the platform-independent code should avoid introducing\r
-global variables, unless they are genuinely cross-session.\r
-\r
-\H{udp-pure-c} C, not C++\r
-\r
-PuTTY is written entirely in C, not in C++.\r
-\r
-We have made \e{some} effort to make it easy to compile our code\r
-using a C++ compiler: notably, our \c{snew}, \c{snewn} and\r
-\c{sresize} macros explicitly cast the return values of \cw{malloc}\r
-and \cw{realloc} to the target type. (This has type checking\r
-advantages even in C: it means you never accidentally allocate the\r
-wrong size piece of memory for the pointer type you're assigning it\r
-to. C++ friendliness is really a side benefit.)\r
-\r
-We want PuTTY to continue being pure C, at least in the\r
-platform-independent parts and the currently existing ports. Patches\r
-which switch the Makefiles to compile it as C++ and start using\r
-classes will not be accepted. Also, in particular, we disapprove of\r
-\cw{//} comments, at least for the moment. (Perhaps once C99 becomes\r
-genuinely widespread we might be more lenient.)\r
-\r
-The one exception: a port to a new platform may use languages other\r
-than C if they are necessary to code on that platform. If your\r
-favourite PDA has a GUI with a C++ API, then there's no way you can\r
-do a port of PuTTY without using C++, so go ahead and use it. But\r
-keep the C++ restricted to that platform's subdirectory; if your\r
-changes force the Unix or Windows ports to be compiled as C++, they\r
-will be unacceptable to us.\r
-\r
-\H{udp-security} Security-conscious coding\r
-\r
-PuTTY is a network application and a security application. Assume\r
-your code will end up being fed deliberately malicious data by\r
-attackers, and try to code in a way that makes it unlikely to be a\r
-security risk.\r
-\r
-In particular, try not to use fixed-size buffers for variable-size\r
-data such as strings received from the network (or even the user).\r
-We provide functions such as \cw{dupcat} and \cw{dupprintf}, which\r
-dynamically allocate buffers of the right size for the string they\r
-construct. Use these wherever possible.\r
-\r
-\H{udp-multi-compiler} Independence of specific compiler\r
-\r
-Windows PuTTY can currently be compiled with any of four Windows\r
-compilers: MS Visual C, Borland's freely downloadable C compiler,\r
-the Cygwin / \cw{mingw32} GNU tools, and \cw{lcc-win32}.\r
-\r
-This is a really useful property of PuTTY, because it means people\r
-who want to contribute to the coding don't depend on having a\r
-specific compiler; so they don't have to fork out money for MSVC if\r
-they don't already have it, but on the other hand if they \e{do}\r
-have it they also don't have to spend effort installing \cw{gcc}\r
-alongside it. They can use whichever compiler they happen to have\r
-available, or install whichever is cheapest and easiest if they\r
-don't have one.\r
-\r
-Therefore, we don't want PuTTY to start depending on which compiler\r
-you're using. Using GNU extensions to the C language, for example,\r
-would ruin this useful property (not that anyone's ever tried it!);\r
-and more realistically, depending on an MS-specific library function\r
-supplied by the MSVC C library (\cw{_snprintf}, for example) is a\r
-mistake, because that function won't be available under the other\r
-compilers. Any function supplied in an official Windows DLL as part\r
-of the Windows API is fine, and anything defined in the C library\r
-standard is also fine, because those should be available\r
-irrespective of compilation environment. But things in between,\r
-available as non-standard library and language extensions in only\r
-one compiler, are disallowed.\r
-\r
-(\cw{_snprintf} in particular should be unnecessary, since we\r
-provide \cw{dupprintf}; see \k{udp-security}.)\r
-\r
-Compiler independence should apply on all platforms, of course, not\r
-just on Windows.\r
-\r
-\H{udp-small} Small code size\r
-\r
-PuTTY is tiny, compared to many other Windows applications. And it's\r
-easy to install: it depends on no DLLs, no other applications, no\r
-service packs or system upgrades. It's just one executable. You\r
-install that executable wherever you want to, and run it.\r
-\r
-We want to keep both these properties - the small size, and the ease\r
-of installation - if at all possible. So code contributions that\r
-depend critically on external DLLs, or that add a huge amount to the\r
-code size for a feature which is only useful to a small minority of\r
-users, are likely to be thrown out immediately.\r
-\r
-We do vaguely intend to introduce a DLL plugin interface for PuTTY,\r
-whereby seriously large extra features can be implemented in plugin\r
-modules. The important thing, though, is that those DLLs will be\r
-\e{optional}; if PuTTY can't find them on startup, it should run\r
-perfectly happily and just won't provide those particular features.\r
-A full installation of PuTTY might one day contain ten or twenty\r
-little DLL plugins, which would cut down a little on the ease of\r
-installation - but if you really needed ease of installation you\r
-\e{could} still just install the one PuTTY binary, or just the DLLs\r
-you really needed, and it would still work fine.\r
-\r
-Depending on \e{external} DLLs is something we'd like to avoid if at\r
-all possible (though for some purposes, such as complex SSH\r
-authentication mechanisms, it may be unavoidable). If it can't be\r
-avoided, the important thing is to follow the same principle of\r
-graceful degradation: if a DLL can't be found, then PuTTY should run\r
-happily and just not supply the feature that depended on it.\r
-\r
-\H{udp-single-threaded} Single-threaded code\r
-\r
-PuTTY and its supporting tools, or at least the vast majority of\r
-them, run in only one OS thread.\r
-\r
-This means that if you're devising some piece of internal mechanism,\r
-there's no need to use locks to make sure it doesn't get called by\r
-two threads at once. The only way code can be called re-entrantly is\r
-by recursion.\r
-\r
-That said, most of Windows PuTTY's network handling is triggered off\r
-Windows messages requested by \cw{WSAAsyncSelect()}, so if you call\r
-\cw{MessageBox()} deep within some network event handling code you\r
-should be aware that you might be re-entered if a network event\r
-comes in and is passed on to our window procedure by the\r
-\cw{MessageBox()} message loop.\r
-\r
-Also, the front ends (in particular Windows Plink) can use multiple\r
-threads if they like. However, Windows Plink keeps \e{very} tight\r
-control of its auxiliary threads, and uses them pretty much\r
-exclusively as a form of \cw{select()}. Pretty much all the code\r
-outside \cw{windows/winplink.c} is \e{only} ever called from the one\r
-primary thread; the others just loop round blocking on file handles\r
-and send messages to the main thread when some real work needs\r
-doing. This is not considered a portability hazard because that bit\r
-of \cw{windows/winplink.c} will need rewriting on other platforms in\r
-any case.\r
-\r
-One important consequence of this: PuTTY has only one thread in\r
-which to do everything. That \q{everything} may include managing\r
-more than one login session (\k{udp-globals}), managing multiple\r
-data channels within an SSH session, responding to GUI events even\r
-when nothing is happening on the network, and responding to network\r
-requests from the server (such as repeat key exchange) even when the\r
-program is dealing with complex user interaction such as the\r
-re-configuration dialog box. This means that \e{almost none} of the\r
-PuTTY code can safely block.\r
-\r
-\H{udp-keystrokes} Keystrokes sent to the server wherever possible\r
-\r
-In almost all cases, PuTTY sends keystrokes to the server. Even\r
-weird keystrokes that you think should be hot keys controlling\r
-PuTTY. Even Alt-F4 or Alt-Space, for example. If a keystroke has a\r
-well-defined escape sequence that it could usefully be sending to\r
-the server, then it should do so, or at the very least it should be\r
-configurably able to do so.\r
-\r
-To unconditionally turn a key combination into a hot key to control\r
-PuTTY is almost always a design error. If a hot key is really truly\r
-required, then try to find a key combination for it which \e{isn't}\r
-already used in existing PuTTYs (either it sends nothing to the\r
-server, or it sends the same thing as some other combination). Even\r
-then, be prepared for the possibility that one day that key\r
-combination might end up being needed to send something to the\r
-server - so make sure that there's an alternative way to invoke\r
-whatever PuTTY feature it controls.\r
-\r
-\H{udp-640x480} 640\u00D7{x}480 friendliness in configuration panels\r
-\r
-There's a reason we have lots of tiny configuration panels instead\r
-of a few huge ones, and that reason is that not everyone has a\r
-1600\u00D7{x}1200 desktop. 640\u00D7{x}480 is still a viable\r
-resolution for running Windows (and indeed it's still the default if\r
-you start up in safe mode), so it's still a resolution we care\r
-about.\r
-\r
-Accordingly, the PuTTY configuration box, and the PuTTYgen control\r
-window, are deliberately kept just small enough to fit comfortably\r
-on a 640\u00D7{x}480 display. If you're adding controls to either of\r
-these boxes and you find yourself wanting to increase the size of\r
-the whole box, \e{don't}. Split it into more panels instead.\r
-\r
-\H{udp-makefiles-auto} Automatically generated \cw{Makefile}s\r
-\r
-PuTTY is intended to compile on multiple platforms, and with\r
-multiple compilers. It would be horrifying to try to maintain a\r
-single \cw{Makefile} which handled all possible situations, and just\r
-as painful to try to directly maintain a set of matching\r
-\cw{Makefile}s for each different compilation environment.\r
-\r
-Therefore, we have moved the problem up by one level. In the PuTTY\r
-source archive is a file called \c{Recipe}, which lists which source\r
-files combine to produce which binaries; and there is also a script\r
-called \cw{mkfiles.pl}, which reads \c{Recipe} and writes out the\r
-real \cw{Makefile}s. (The script also reads all the source files and\r
-analyses their dependencies on header files, so we get an extra\r
-benefit from doing it this way, which is that we can supply correct\r
-dependency information even in environments where it's difficult to\r
-set up an automated \c{make depend} phase.)\r
-\r
-You should \e{never} edit any of the PuTTY \cw{Makefile}s directly.\r
-They are not stored in our source repository at all. They are\r
-automatically generated by \cw{mkfiles.pl} from the file \c{Recipe}.\r
-\r
-If you need to add a new object file to a particular binary, the\r
-right thing to do is to edit \c{Recipe} and re-run \cw{mkfiles.pl}.\r
-This will cause the new object file to be added in every tool that\r
-requires it, on every platform where it matters, in every\r
-\cw{Makefile} to which it is relevant, \e{and} to get all the\r
-dependency data right.\r
-\r
-If you send us a patch that modifies one of the \cw{Makefile}s, you\r
-just waste our time, because we will have to convert it into a\r
-change to \c{Recipe}. If you send us a patch that modifies \e{all}\r
-of the \cw{Makefile}s, you will have wasted a lot of \e{your} time\r
-as well!\r
-\r
-(There is a comment at the top of every \cw{Makefile} in the PuTTY\r
-source archive saying this, but many people don't seem to read it,\r
-so it's worth repeating here.)\r
-\r
-\H{udp-ssh-coroutines} Coroutines in \cw{ssh.c}\r
-\r
-Large parts of the code in \cw{ssh.c} are structured using a set of\r
-macros that implement (something close to) Donald Knuth's\r
-\q{coroutines} concept in C.\r
-\r
-Essentially, the purpose of these macros are to arrange that a\r
-function can call \cw{crReturn()} to return to its caller, and the\r
-next time it is called control will resume from just after that\r
-\cw{crReturn} statement.\r
-\r
-This means that any local (automatic) variables declared in such a\r
-function will be corrupted every time you call \cw{crReturn}. If you\r
-need a variable to persist for longer than that, you \e{must} make\r
-it a field in one of the persistent state structures: either the\r
-local state structures \c{s} or \c{st} in each function, or the\r
-backend-wide structure \c{ssh}.\r
-\r
-See\r
-\W{http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}\c{http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html}\r
-for a more in-depth discussion of what these macros are for and how\r
-they work.\r
-\r
-\H{udp-compile-once} Single compilation of each source file\r
-\r
-The PuTTY build system for any given platform works on the following\r
-very simple model:\r
-\r
-\b Each source file is compiled precisely once, to produce a single\r
-object file.\r
-\r
-\b Each binary is created by linking together some combination of\r
-those object files.\r
-\r
-Therefore, if you need to introduce functionality to a particular\r
-module which is only available in some of the tool binaries (for\r
-example, a cryptographic proxy authentication mechanism which needs\r
-to be left out of PuTTYtel to maintain its usability in\r
-crypto-hostile jurisdictions), the \e{wrong} way to do it is by\r
-adding \cw{#ifdef}s in (say) \cw{proxy.c}. This would require\r
-separate compilation of \cw{proxy.c} for PuTTY and PuTTYtel, which\r
-means that the entire \cw{Makefile}-generation architecture (see\r
-\k{udp-makefiles-auto}) would have to be significantly redesigned.\r
-Unless you are prepared to do that redesign yourself, \e{and}\r
-guarantee that it will still port to any future platforms we might\r
-decide to run on, you should not attempt this!\r
-\r
-The \e{right} way to introduce a feature like this is to put the new\r
-code in a separate source file, and (if necessary) introduce a\r
-second new source file defining the same set of functions, but\r
-defining them as stubs which don't provide the feature. Then the\r
-module whose behaviour needs to vary (\cw{proxy.c} in this example)\r
-can call the functions defined in these two modules, and it will\r
-either provide the new feature or not provide it according to which\r
-of your new modules it is linked with.\r
-\r
-Of course, object files are never shared \e{between} platforms; so\r
-it is allowable to use \cw{#ifdef} to select between platforms. This\r
-happens in \cw{puttyps.h} (choosing which of the platform-specific\r
-include files to use), and also in \cw{misc.c} (the Windows-specific\r
-\q{Minefield} memory diagnostic system). It should be used\r
-sparingly, though, if at all.\r
-\r
-\H{udp-perfection} Do as we say, not as we do\r
-\r
-The current PuTTY code probably does not conform strictly to \e{all}\r
-of the principles listed above. There may be the occasional\r
-SSH-specific piece of code in what should be a backend-independent\r
-module, or the occasional dependence on a non-standard X library\r
-function under Unix.\r
-\r
-This should not be taken as a licence to go ahead and violate the\r
-rules. Where we violate them ourselves, we're not happy about it,\r
-and we would welcome patches that fix any existing problems. Please\r
-try to help us make our code better, not worse!\r