uudeview-0.5.20.orig/0000755001167100001440000000000010020741143014316 5ustar cphusers00000000000000uudeview-0.5.20.orig/doc/0000755001167100001440000000000010020741142015062 5ustar cphusers00000000000000uudeview-0.5.20.orig/doc/Makefile0000644001167100001440000000123606160521461016536 0ustar cphusers00000000000000# # $Id: Makefile,v 1.2 1996/06/15 11:49:05 fp Exp $ # DVI = library.dvi PS = ${DVI:.dvi=.ps} LATEX = latex DVIPS = dvips FIG2DEV = fig2dev .SUFFIXES: .SUFFIXES: .ltx .dvi .ps .fig .tex .eps all: $(DVI) dvi: $(DVI) ps: $(PS) library.ps: library.dvi library.dvi: library.ltx structure.tex binhex.tex clean: rm -f *.aux *.log *.toc *~ rm -f *.o td-v1 td-v2 td-v3 distclean: clean for fig in *.fig ; do \ rm -f `basename $$fig .fig`.eps ; \ rm -f `basename $$fig .fig`.tex ; \ done rm -f *.dvi *.ps .ltx.dvi: $(LATEX) $< $(LATEX) $< .dvi.ps: $(DVIPS) -f < $< > $@ .fig.tex: $(FIG2DEV) -L latex < $< > $@ .fig.eps: $(FIG2DEV) -L ps < $< > $@ uudeview-0.5.20.orig/doc/README0000644001167100001440000000162606174254653015774 0ustar cphusers00000000000000 This directory contains the documentation of the UUDeview Decoding Library programming interface. It is of interest only if you want to use the decoding/encoding functions from your own applications, and is not intended for users of the ready-made programs. The documentation is distributed in LaTeX format (requiring LaTeX version 2e). You can request Postscript and HTML formatted files from the author by email. Please understand that I cannot provide printed documentation. If you have LaTeX 2e installed, just run make to compile the text into a DVI file, which can be viewed with xdvi. Run 'make ps' to create a printable Postscript document. Even if you can't read the doc, you can take a look at the sample C files (they show the "evolution" of the "Trivial Decoder") to see how easy it is to include decoding support into your programs. Frank Pilhofer uudeview-0.5.20.orig/doc/binhex.fig0000644001167100001440000000613506160775301017051 0ustar cphusers00000000000000#FIG 3.1 Portrait Center Inches 1200 2 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 1200 1500 1350 1500 1350 1800 1200 1800 1200 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 1350 1500 2400 1500 2400 1800 1350 1800 1350 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 2400 1500 2550 1500 2550 1800 2400 1800 2400 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 2550 1500 3150 1500 3150 1800 2550 1800 2550 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 3150 1500 3750 1500 3750 1800 3150 1800 3150 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 4050 1500 4650 1500 4650 1800 4050 1800 4050 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 4650 1500 5250 1500 5250 1800 4650 1800 4650 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 3750 1500 4050 1500 4050 1800 3750 1800 3750 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 5250 1500 5550 1500 5550 1800 5250 1800 5250 1500 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 5252 2252 5552 2252 5552 2552 5252 2552 5252 2252 2 2 0 1 -1 7 0 0 -1 0.000 0 0 0 0 0 5 5252 3002 5552 3002 5552 3302 5252 3302 5252 3002 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 4500 2550 1200 2550 1200 2250 4500 2250 2 1 0 1 -1 7 0 0 -1 0.000 0 0 -1 0 0 4 4500 3300 1200 3300 1200 3000 4500 3000 2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 0 0 2 4500 2250 5250 2250 2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 0 0 2 4500 2550 5250 2550 2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 0 0 2 4500 3000 5250 3000 2 1 1 1 -1 7 0 0 -1 4.000 0 0 -1 0 0 2 4500 3300 5250 3300 4 1 -1 0 0 0 12 0.0000000 0 90 90 1275 1725 n\001 4 1 -1 0 0 0 12 0.0000000 0 135 450 1875 1725 Name\001 4 1 -1 0 0 0 12 0.0000000 0 135 90 2475 1725 0\001 4 1 -1 0 0 0 12 0.0000000 0 180 375 2850 1725 Type\001 4 1 -1 0 0 0 12 0.0000000 0 135 375 3450 1725 Auth\001 4 1 -1 0 0 0 12 0.0000000 0 135 360 4350 1725 Dlen\001 4 1 -1 0 0 0 12 0.0000000 0 135 345 4950 1725 Rlen\001 4 1 -1 0 0 0 10 0.0000000 0 75 75 1875 1425 n\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 2475 1425 1\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 2850 1425 4\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 3450 1425 4\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 3900 1425 2\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 4350 1425 4\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 4950 1425 4\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 5400 1425 2\001 4 2 -1 0 0 0 12 0.0000000 0 135 555 1125 1575 Header\001 4 2 -1 0 0 0 12 0.0000000 0 135 570 1125 1845 Section\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 1275 1425 1\001 4 1 -1 0 0 0 10 0.0000000 0 105 225 5400 1725 HC\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 5401 2176 2\001 4 2 -1 0 0 0 12 0.0000000 0 135 375 1127 2327 Data\001 4 2 -1 0 0 0 12 0.0000000 0 135 570 1127 2597 Section\001 4 1 -1 0 0 0 12 0.0000000 0 135 765 3227 2477 Data Fork\001 4 1 -1 0 0 0 10 0.0000000 0 105 300 3227 2177 Dlen\001 4 1 -1 0 0 0 10 0.0000000 0 105 210 5402 2477 DC\001 4 1 -1 0 0 0 10 0.0000000 0 105 75 5401 2926 2\001 4 2 -1 0 0 0 12 0.0000000 0 135 720 1127 3077 Resource\001 4 2 -1 0 0 0 12 0.0000000 0 135 570 1127 3347 Section\001 4 1 -1 0 0 0 12 0.0000000 0 135 1110 3227 3227 Resource Fork\001 4 1 -1 0 0 0 10 0.0000000 0 105 300 3227 2927 Rlen\001 4 1 -1 0 0 0 10 0.0000000 0 105 210 5402 3227 RC\001 4 1 -1 0 0 0 10 0.0000000 0 135 285 3900 1725 Flag\001 uudeview-0.5.20.orig/doc/library.ltx0000644001167100001440000030777110020740754017306 0ustar cphusers00000000000000\NeedsTeXFormat{LaTeX2e} \documentclass{article} \usepackage{psfig} \usepackage{times} \usepackage{a4wide} \author{Frank Pilhofer} \title{The UUDeview Decoding Library} \providecommand{\ush}{\discretionary{-}{}{\_}} \providecommand{\uuversion}{0.5} \providecommand{\uupatch}{20} % % $Id: library.ltx,v 1.28 2004/03/01 23:06:20 fp Exp $ % \begin{document} \maketitle \begin{abstract} The UUDeview library is a highly portable set of functions that provide facilities for decoding \emph{uuencoded}, \emph{xxencoded}, \emph{Base64} and \emph{BinHex}-Encoded files as well as for encoding binary files into all of these representations except BinHex. This document describes how the features of encoding and decoding can be integrated into your own applications. The information is intended for developers only, and is not required reading material for end users. It is assumed that the reader is familiar with the general issue of encoding and decoding and has some experience with the ``C'' programming language. This document describes version \uuversion{}, patchlevel \uupatch{} of the library. \end{abstract} \section{Introduction} \subsection{Background} The Internet provides us with a fast and reliable means of user-to-user message delivery, using private email or newsgroups. Both systems have originally been designed to transport plain-text messages. Over the years, some methods appeared allowing transport of arbitrary binary data by ``encoding'' the data into plain-text messages. But after these years, there are still certain problems handling the encoded data, and many recipients have difficulties decoding the messages back into their original form. It should be the job of the mail delivery agent to handle sending and rend receiving binary data transparently. However, the support of most applications is limited, and several incompatibilities among different software exists. There are three common formats for encoding binary data, called \emph{uuencoding}, \emph{Base64} and \emph{BinHex}. Issues are further complicated by slight variations of the formats, the packaging, and some broken implementations. Further problems arise with multi-part postings, where the encoding of a huge file has been split up into several individual messages to ensure proper transfer over gateways with limited message sizes. Very few software is able to properly sort and decode the parts. Even nowadays, many users are at a loss to decode these kinds of messages. This is where the UUDeview Decoding Library steps in. \subsection{The Library} The UUDeview library makes an attempt at decoding nearly all kinds of encoded files. It is supposed to decode multi-part files as well as many files simultaneously. Part numbers are evaluated, thus making it possible to re-arrange parts that aren't in their correct order. No assumptions are made on the format of the input file. Usually the input will be an email folder or newsgroup messages. If this is the case, the information found in header lines is evaluated; but plain encoded files with no surrounding information are also accepted. The input may also consist of concatenated parts and files. Decoding files is done in two passes. During the first pass, all input files are scanned. Information is gathered about each chunk of encoded data. Besides the obvious data about type, position and size of the chunk, some environmental information from the envelope of a mail message is also gathered if available. If the scanner finds a properly MIME-formatted message, a proper MIME parser steps into action. Because MIME messages include precise information about the message's contents, there is seldom doubt about its parts. For other, non-MIME messages, the ``Subject'' header line is closely examined. Two informations are extracted: the part number (usually given in parentheses) and a unique identifier, which is used to group series of postings. If the subject is, for example, ``uudeview.tgz (01/04)'', the scanner concludes that this message is the first in a series of four, and the indicated filename is an ideal key to identify each of the four parts. If the subject is incomplete (no part number) or missing, the scanner tries to make the best of the available information, but some of the advanced features won't work. For example, without any information about the part number, it must be assumed that the available parts are in correct order and can't be automatically rearranged. All the information is gathered in a linked list. An application can then examine the nodes of the list and pick individual items for decoding. The decoding functions will then visit the parts of a file in correct order and extract the binary data. Because of heavy testing of the routines against real-life data and many problem reports from users, the functions have become very robust, even against input files with few, missing or broken information. \begin{figure} \centering \makebox{\input{structure.tex}} \caption{Integration of the Library} \label{structure} \end{figure} Figure \ref{structure} displays how the library can be integrated into an application. The library does not assume any capabilities of the operating system or application language, and can thus be used in almost any environment. The few necessary interfaces must be provided by the application, which does usually know a great deal more about the target system. The idea of the ``language interface'' is to allow integration of the library services into other programming languages; if the application is itself written in C, there's no need for a separate interface, of course. Such an interface currently exists for the Tcl scripting language; other examples might be Visual Basic, Perl or Delphi. \subsection{Terminology} These are some buzzwords that will be used in the following text. \begin{itemize} \item ``Encoded data'' is binary data encoded by one of the methods ``uuencoding'', ``xxencoding'', ``Base64'' or ``BinHex''. \item ``Message'' refers to both complete email messages and Usenet news postings, including the complete headers. The format of a message is described in \cite{rfc0822}. A ``message body'' is an email message or news posting without headers. \item A ``mail folder'' is a number of concatenated messages. \item ``MIME'' refers to the standards set in \cite{rfc1521}. \item A ``multipart message'' is an entity described by the MIME standard. It is a single message divided into one or more individual parts by a unique boundary. \item A ``partial message'' is also described by the MIME standard. It is a message with an associated identifier and a part number. Large messages can be split into multiple partial messages on the sender's side. The recipient's software groups the partial messages by their identifier and composes them back into the original large message. \item The term ``partial message'' only refers to \emph{one part} of the large message. The original, partialized message is referred to as ``multi-part message'' (note the hyphen). To clarify, one part of a multi-part message is a partial message. \end{itemize} \section{Compiling the Library} On Unix systems, configuration and compilation is trivial. The script \texttt{configure} automatically checks your system and configures the library appropriately. A subsequent ``make'' compiles the modules and builds the final library. On other systems, you must manually create the configuration file and the Makefile. The configuration file \texttt{config.h} contains a set of preprocessor definitions and macros that describe the available features on your systems. \subsection{Creating \texttt{config.h} by hand} You can find all available definitions in \texttt{config.h.in}. This file undefines all possible definitions; you can create your own configuration file starting from \texttt{config.h.in} and editing the necessary differences. Most definitions are either present or absent, only a few need to have a value. If not explicitly mentioned, you can activate a definition by changing the default \texttt{undef} into \texttt{define}. The following definitions are available: \subsubsection{System Specific} \begin{description} \item[\texttt{SYSTEM\_DOS}] Define for compilation on a \emph{DOS} system. Currently unused. \item[\texttt{SYSTEM\_QUICKWIN}] Define for compilation within a \emph{QuickWin}\footnote{The Microsoft compilers offer the \emph{QuickWin} target to allow terminal-oriented programs to run in the Windows environment} program. Currently unused. \item[\texttt{SYSTEM\_WINDLL}] Causes all modules to include \texttt{} before any other include file. Makes \texttt{uulib.c} export a \texttt{Dll\-Entry\-Point} function. \item[\texttt{SYSTEM\_OS2}] Causes all modules to include \texttt{} before any other include file. \end{description} \subsubsection{Compiler Specific} \begin{description} \item[\texttt{PROTOTYPES}] Define if your compiler supports function prototypes. \item[\texttt{UUEXPORT}] This can be a declaration to all functions exported from the decoding library. Frequently needed when compiling into a shared library. \item[\texttt{TOOLEXPORT}] Similar to \texttt{TOOL\-EXPORT}, but for the helper functions from the replacement functions in \texttt{fptools.c}. \end{description} \subsubsection{Header Files} There are a number of options that define whether header files are available on your system. Don't worry if some of them are not. If a header file is present, define ``\texttt{HAVE\_}\emph{name-of-header}'': \texttt{HAVE\ush{}ERRNO\_H}, \texttt{HAVE\ush{}FCNTL\_H}, \texttt{HAVE\ush{}IO\_H}, \texttt{HAVE\ush{}MALLOC\_H}, \texttt{HAVE\ush{}MEMORY\_H}, \texttt{HAVE\ush{}UNISTD\_H} and \texttt{HAVE\ush{}SYS\_TIME\_H} (for \texttt{}). Some other include files are needed as well, but there are no macros for mandatory include files. There's also a number of header-specific definitions that do not fit into the general present-or-not-present scheme. \begin{description} \item[\texttt{STDC\_HEADERS}] Define if your header files conform to \emph{ANSI C}. This requires that \texttt{stdarg.h} is present, that \texttt{stdlib.h} is available, defining both \texttt{malloc()} and \texttt{free()}, and that \texttt{string.h} defines the memory functions family (\texttt{memcpy()} etc). \item[\texttt{HAVE\_STDARG\_H}] Implicitly set by \texttt{STDC\ush{}HEADERS}. You only need to define this one if \texttt{STDC\ush{}HEADERS} is not defined but \texttt{} is available. \item[\texttt{HAVE\_VARARGS\_H}] \emph{varargs} can be used as an alternative to \emph{stdarg}. Define if the above two values are undefined and \texttt{} is available. \item[\texttt{TIME\_WITH\_SYS\_TIME}] Define if \texttt{HAVE\ush{}SYS\ush{}TIME\_H} and if both \texttt{} and \texttt{} can be included without conflicting definitions. \end{description} \subsubsection{Functions} \begin{description} \item[\texttt{HAVE\_STDIO}] Define if standard I/O (\texttt{stdin}, \texttt{stdout} and \texttt{stderr}) is available. \item[\texttt{HAVE\_GETTIMEOFDAY}] Define if your system provides the \texttt{gettimeofday()} system call, which is needed to provide microsecond resolution to the busy callback. If this function is not available, \texttt{time()} is used. \end{description} \subsubsection{Replacement Functions} The tools library \texttt{fptools} defines many functions that aren't standard on all systems. Most of them do not differ in behavior from their originals, but might be slightly slower. But since they are usually only needed in non-speed-critical sections, the replacements are used throughout the library. For a full listing of the available replacement functions, see section \ref{chap-rf}. However, there are two functions, \texttt{strerror} and \texttt{tempnam}, that aren't fully implemented. The replacement \texttt{strerror} does not have a table of error messages and only produces the error number as string, and the ``fake'' \texttt{tempnam} does not necessarily use a proper temp directory. Because some functionality is missing, the replacement functions should \emph{only} be used if the original is not available. \begin{description} \item[\texttt{strerror}] If your system does not provide a \texttt{strerror} function of its own, define to \texttt{\_FP\_strerror}. This causes the replacement function to be used throughout the library. \item[\texttt{tempnam}] If your system does not provide a \texttt{tempnam} function of its own, define to \texttt{\_FP\_tempnam}. This causes the replacement function to be used throughout the library. Must not be defined if the function is in fact available. \end{description} \subsection{Creating the \texttt{Makefile} by hand} The \texttt{Makefile} is automatically generated by the configuration script from the template in \texttt{Makefile.in}. This section explains how the template must be edited into a proper Makefile. Just copy \texttt{Makefile.in} to \texttt{Makefile} and edit the place-holders for the following values. \begin{description} \item[\texttt{CC}] Your system's ``C'' compiler. \item[\texttt{CFLAGS}] The compilation flags to be passed to the compiler. This must include ``-I.'' so that the include files from the local directory are found, and ``\mbox{-DHAVE\_CONFIG\_H}'' to declare that a configuration file is present. \item[\texttt{RANLIB}] Set to ``ranlib'' if such a program is available on your system, or to ``:'' (colon) otherwise. \item[\texttt{VERSION}] A string holding the release number of the library, currently ``\uuversion{}'' \item[\texttt{PATCH}] A string holding the patchlevel, currently ``\uupatch{}''. \end{description} Some systems do not know Makefiles but offer the concept of a ``project''.\footnote{Actually, most project-oriented systems compile the project definitions into a Makefile for use by the back-ends.} In this case, create a new project targeting a library and add all source codes to the project. Then, make sure that the include path includes the current directory. Add options to the compiler command so that the symbol ``HAVE\_CONFIG\_H'' gets defined. Additionally, the symbol ``VERSION'' must be defined as a string holding the release number, currently ``\uuversion{}'' and ``PATCH'' must be defined as a string holding the patch level, currently ``\uupatch{}''. On 16-bit systems, the package should be compiled using the ``Large'' memory model, so that more than just 64k data space is available. \subsection{Compiling your Projects} Compiling the parts of your project that use the functions from the decoding library is pretty straightforward: \begin{itemize} \item All modules that call library functions must include the \texttt{} header file. \item Optionally, if you want to use the replacement functions to make your own application more portable, they may also include \texttt{}. \item If your compiler understands about function prototypes, define the symbol \texttt{PROTOTYPES}. This causes the library functions to be declared with a full parameter list. \item Modify the include file search path so that the compiler finds the include files (usually with the ``-I'' option). \item Link with the \texttt{libuu.a} library, usually using the ``-luu'' option. \item Make sure the library is found (usually with the ``-L'' option). \end{itemize} \section{Callback Functions} \subsection{Intro} At some points, the decoding library offers to call your custom procedures to do jobs you want to take care of yourself. Some examples are the ``Message Callback'' to print a message or the ``Busy Callback'', which is frequently called during lengthy processing of data to indicate the progress. You can hook up your functions by calling some library function with a pointer to your function as a parameter. In some cases, you will want that one of your functions receives certain data as a parameter. One reason to achieve this would be through global data; another possibility is provided through the passing of an opaque data pointer. All callback functions are declared to take an additional parameter of type \texttt{void*}. When hooking up one of your callbacks, you can specify a value that will passed whenever your function is called. Since this pointer is never touched by the library, it can be any kind of data, usually some composed structure. Some application for the Message Callback might be a \texttt{FILE*} pointer to log the messages to. For portability reasons, you should declare your callbacks with the first parameter actually being a \texttt{void*} pointer and only cast this pointer to its real type within the function body. This prevents compiler warnings about the callback setup. \subsection{Message Callback} \label{Section-Msg-Callback} For portability reasons, the library does not assume the availability of a terminal, so it does not initially know where to print messages to. The library generates some messages about its progress as well as more serious warnings and errors. An application should provide a message callback that displays them. The function might also choose to ignore informative messages and only display the fatal ones. A Message Callback takes three parameters. The first one is the opaque data pointer of type \texttt{void*}. The second one is a text message of more or less arbitrary length without line breaks. The last parameter is an indicator of the seriousness of this message. A string representation of the warning level is also prefixed to the message. \begin{description} \item[\texttt{UUMSG\_MESSAGE}] This is just a plain informative message, nothing important. The application can choose to simply ignore the message. If a log file is available, it should be logged, but the message should never result in a modal dialogue. \item[\texttt{UUMSG\_NOTE}] ``Note:'' Still an informative message, meaning that the library made a decision on its own that might interest the user. One example for a note is that the setuid bit has been stripped from a file mode for security reasons. Notes are nothing serious and may still be ignored. \item[\texttt{UUMSG\_WARNING}] ``Warning:'' A warning indicates that a non-serious problem occurred which did not stop the library from proceeding with the current action. One example is a temporary file that could not be removed. Warnings should be displayed, but an application may decide to continue even without user intervention. \item[\texttt{UUMSG\_ERROR}] ``ERROR:'' A problem occurred that caused termination of the current request, for example if the library tried to access a non-existing file. After an error has occurred, the application should closely examine the resulting return code of the operation. Error messages are usually printed in modal dialogues; another option is to save the error message string somewhere and later print the error message after the application has examined the operation's return value. \item[\texttt{UUMSG\_FATAL}] ``Fatal Error:'' This would indicate that a serious problem has occurred that prevents the library from processing any more requests. Currently unused. \item[\texttt{UUMSG\_PANIC}] ``Panic:'' Such a message would indicate a panic condition, meaning the application should terminate without further clean-up handling. Unused so far.\footnote{It is not intended that this and the previous error levels will ever be used. Currently, there's no need to include handling for them.} \end{description} \subsection{Busy Callback} \label{Section-Busy-Callback} Some library functions, like scanning of an input file or decoding an output file, can take quite some time. An application will usually want to inform the user of the progress. A custom ``Busy Callback'' can be provided to take care of this job. This function will then be called frequently while a large action is being executed within the library. It is not called when the application itself has control. Apart from the usual opaque data pointer, the Busy Callback receives a structure of type \texttt{uuprogress} with the following members: \begin{description} \item[\texttt{action}] What the library is currently doing. One of the following integer constants: \begin{description} \item[\texttt{UUACT\_IDLE}] The library is idle. This value shouldn't be seen in the Busy Callback, because the Busy Callback is never called in an idle state. \item[\texttt{UUACT\_SCANNING}] Scanning an input file. \item[\texttt{UUACT\_DECODING}] Decoding a file. \item[\texttt{UUACT\_COPYING}] Copying a file. \item[\texttt{UUACT\_ENCODING}] Encoding a file. \end{description} \item[\texttt{curfile}] The name of the file we're working on. May include the full path. Guaranteed to be 256 characters or shorter. \item[\texttt{partno}] When decoding a file, this is the current part number we're working on. May be zero. \item[\texttt{numparts}] The maximum part number of this file. Guaranteed to be positive (non-zero). \item[\texttt{percent}] The percentage of the current \emph{part} already processed. The total percentage can be calculated as $(100*partno-percent)/numparts$. \item[\texttt{fsize}] The size of the current file. The percent information is only valid if this field is \emph{positive}. Whenever the size of a file cannot be properly determined, this field is set to -1; in this case, the percent field may hold garbage. \end{description} In some cases, it is possible that the percent counter jumps backwards. This happens seldom enough not to worry about it, but the callback should take care not to crash in this case.\footnote{This happens if, in a MIME multipart posting, the final boundary cannot be found. After searching the boundary until the end-of-file, the scanner resets itself to the location of the previous boundary.} The Busy Callback is declared to return an integer value. If a \emph{non-zero} value is returned, the current operation from which the callback was called is canceled, which then aborts with a return value of \texttt{UURET\ush{}CANCEL} (see later). \subsection{File Callback} \label{Section-File-Callback} Input files are usually needed twice, first for scanning and then for decoding. If the input files are downloaded from a remote server, perhaps by \emph{NNTP}, they would have to be stored on the local disk and await further handling. However, the user may choose not to decode some files after all. If disk space is important, it is possible to install a ``File Callback''. When scanning a file, it is assigned an ``Id''. After scanning has completed, the application can delete the input file. If it should be required later on for decoding, the File Callback is called to map the Id back to a filename, possibly retrieving another copy and disposing of it afterwards. The File Callback receives four parameters. The first is the opaque data pointer, the second is the Id that was assigned to the file while scanning. The fourth parameter is an integer. If it is non-zero, then the function is supposed to retrieve the file in question, store it on local disk, and write the resulting filename into the area to which the third parameter (a \texttt{char*} pointer) points. A fourth parameter of zero indicates that the decoder is done handling the file, so that the function can decide whether or not to remove the file. The function must return \texttt{UURET\_OK} upon success, or any other appropriate error code upon failure. Since it can usually be assumed that disk space is plentily available, and storing a file is ``cheaper'' than retrieving it twice, this mechanism has not been used so far. \subsection{Filename Filter} \label{Section-FName-Filter} For portability reasons, the library does not make any assumptions of the legality of certain filenames. It will pick up a ``garbage'' file name from the encoded file and happily use it if not told otherwise. For example, on DOS systems many filenames must be truncated in order to be valid. If a ``Filename Filter'' is installed, the library will pass each potential filename to the filter and then use the filename that the filter function returns. The filter also has to remove all directory information from the filename -- the library itself does not know about directories at all. The filter function receives the potential filename as string and must return a pointer to a string with the corrected filename. It may either return a pointer to some position in the original string or a pointer to some static area, but it should not modify the source string. Two examples of filename filters can be found among the UUDeview distribution as \texttt{uufnflt.c}. The DOS filter function disposes directory information, uses only the first 8 characters of the base filename and the first three characters after the last '.'~(since a filename might have two extensions). Also, space characters are replaced by underscores. The Unix filter just returns a pointer to the filename part of the name (without directory information). The ``garbage'' filename mentioned above was just for the sake of argument. It is generally safe to assume that the input filename is not too weird; after all, it is a filename valid on \emph{some} system. Still, the user should always be granted the possibility of renaming a file before decoding it, to allow decoding of files with insane filenames. \section{The File List} \label{file-list} While scanning the input files, a linked list is built. Each node is of type \texttt{uulist} and describes one file, possibly composed of several parts. This section describes the members of the structure that may be of interest to an application. \begin{description} \item[\texttt{state}] Describes the state of this file. Either the value \texttt{UUFILE\ush{}READ}\footnote{This value should only appear internally, never to be seen by an application.} or a bitfield of the following values: \begin{description} \item[\texttt{UUFILE\_MISPART}] The file is missing at least one part. This bit is set if the part numbers are non-sequential. Usually results in incorrect decoding. \item[\texttt{UUFILE\_NOBEGIN}] No ``begin'' line was detected. Since \emph{Base64} files do not have begin lines, this bit is never set on them. For \emph{BinHex} files, the initial colon is used. \item[\texttt{UUFILE\_NOEND}] No ``end'' line was detected. Since \emph{Base64} files do not have end lines, this bit is never set on them. A missing end on \emph{uuencoded} or \emph{xxencoded} files usually means that the file is incomplete. For \emph{BinHex}, the trailing colon is used as end marker. \item[\texttt{UUFILE\_NODATA}] No encoded data was found within these parts. \item[\texttt{UUFILE\_OK}] This file appears to be okay, and decoding is likely to be successful. \item[\texttt{UUFILE\_ERROR}] A decode operation was attempted, but failed, usually because of an I/O error. \item[\texttt{UUFILE\_DECODED}] This file has already been successfully decoded. \item[\texttt{UUFILE\_TMPFILE}] The file has been decoded into a temporary file, which can be found using the \texttt{binfile} member (see below). This flag gets removed if the temporary file is deleted. \end{description} \item[\texttt{mode}] For \emph{uuencoded} and \emph{xxencoded} files, this is the file mode found on the ``begin'' line, \emph{Base64} and \emph{BinHex} files receive a default of 0644. A decode operation will try to restore this mode. \item[\texttt{uudet}] The type of encoding this file uses. May be 0 if \texttt{UUFILE\ush{}NODATA} or one of the following values: \begin{description} \item[\texttt{UU\_ENCODED}] for \emph{uuencoded} data, \item[\texttt{B64ENCODED}] for \emph{Base64} encoded data, \item[\texttt{XX\_ENCODED}] for \emph{xxencoded} data, \item[\texttt{BH\_ENCODED}] for \emph{BinHex} data, \item[\texttt{PT\_ENCODED}] for plain-text ``data'', or \item[\texttt{QT\_ENCODED}] for MIME \emph{quoted-printable} encoded text. \end{description} \item[\texttt{size}] The approximate size of the resulting file. It is an estimated value and can be a few percent off the final value, hence the suggestion to display the size in kilobytes only. \item[\texttt{filename}] The filename. For \emph{uuencoded} and \emph{xxencoded} files, it is extracted from the ``begin'' line. The name of \emph{BinHex} files is encoded in the first data bytes. \emph{Base64} files have the filename given in the ``Content-Type'' header. This field may be \texttt{NULL} if \texttt{state!=UUFILE\ush{}OK}. \item[\texttt{subfname}] A unique identifier for this group of parts, usually derived from the ``Subject'' header of each part. It is possible that two nodes with the same identifier exist in the file list: If a group of files is considered ``complete'', a new node is opened up for more parts with the same Id. \item[\texttt{mimeid}] Stores the ``id'' field from the ``Content-Type'' information if available. Actually, this Id is the first choice for grouping of files, but not surprisingly, non-MIME mails or articles do not have this information. \item[\texttt{mimetype}] Stores this part's ``Content-Type'' if available. \item[\texttt{binfile}] After decoding, this is the name of the temporary file the data was decoded to and stored in. This value is non-NULL if the flag \texttt{UUFILE\ush{}TMPFILE} is set in the state member above. \item[\texttt{haveparts}] The part numbers found for this group of files as a zero-terminated ordered integer array. Some extra care must be taken, because a file may have a zeroth part as its first part. Thus if \texttt{haveparts[0]} is zero, it indicates a zeroth part, and the list of parts continues. A file may have at most one zeroth part, so if both \texttt{haveparts[0]} and \texttt{haveparts[1]} are zero, the zeroth part is the only part of this file. No more than 256 parts are listed here. \item[\texttt{misparts}] Similar to \texttt{haveparts}; a zero-terminated ordered integer array of missing parts, or simply \texttt{NULL} if no parts are missing. Since we don't mind if a file doesn't have a zeroth part, this array does not have the above problems. \end{description} \section{Return Values} Most of the library functions return a value indicating success or the type of error occurred. The following values can be returned: \begin{description} \item[\texttt{UURET\_OK}] The action completed successfully. \item[\texttt{UURET\_IOERR}] An I/O error occurred. There may be many reasons from ``File not found'' to ``Disk full''. This return code indicates that the application should consult \texttt{errno} for more information. \item[\texttt{UURET\_NOMEM}] A \texttt{malloc()} operation returned \texttt{NULL}, indicating that memory resources are exhausted. Never seen this one in a VM system. \item[\texttt{UURET\_ILLVAL}] You tried to call some operation with invalid parameters. \item[\texttt{UURET\_NODATA}] An attempt was made to decode a file, but no encoded data was found within its parts. Also returned if decoding a \emph{uuencoded} or \emph{xxencoded} file with missing ``begin'' line. \item[\texttt{UURET\_NOEND}] A decoding operation was attempted, but the decoded data didn't have a proper ``end'' line. A similar condition can also be detected for \emph{BinHex} files (where the colon is used as end marker). \item[\texttt{UURET\_UNSUP}] You tried to encode using an unsupported communications channel, for example piping to a command on a system without pipes. \item[\texttt{UURET\_EXISTS}] The target file already exists (upon decoding), and you didn't allow to overwrite existing files. \item[\texttt{UURET\_CONT}] This is a special return code, indicating that the current operation must be continued. This return value is used only by two encoding functions, so see the documentation there. \item[\texttt{UURET\_CANCEL}] The current operation was canceled, meaning that the Busy Callback returned a non-zero value usually because of user request. The library does not produce this return value on its own, so if your Busy Callback always returns zero, there's no need to handle this ``Error''. \end{description} \section{Options} \label{Section-Options} An application program can set and query a number of options. Some of them are read-only, but others can modify the behavior quite drastically. Some of them are intended to be set by the end user via an options menu. \begin{description} \item[\texttt{UUOPT\_VERSION}] {\small (string, read-only)} \\ Retrieves the full version number of the library, composed as \emph{MA\-JOR}.\emph{MI\-NOR}\discretionary{}{}{}pl\emph{PATCH} (the major and minor version numbers and the patchlevel are integers). \item[\texttt{UUOPT\_FAST}] {\small (integer, default=0)} \\ If set to 1, the library will assume that each input file consists of exactly one email message or newsgroup posting. After finding encoded data within a file, the scanner will not continue to look for more data below. This strategy can save a lot of time, but has the drawback that files also cannot be checked for completeness -- since the scanner does not look for ``end'' lines, we don't notice them missing. This flag does not have any effect on MIME multipart messages, which are always scanned to the end (alas, the Epilogue will be skipped). Actually, with this flag set, the scanner becomes more MIME-compliant. \item[\texttt{UUOPT\_DUMBNESS}] {\small (integer, default=0)} \\ As already mentioned, the library evaluates information found in the part's ``Subject'' header line if available. The heuristics here are versatile, but cannot be guaranteed to be completely failure-proof. If false information is derived, the parts will be ordered and grouped wrong, resulting in wrong decoding. If the ``dumbness'' is set to 1, the code to derive a part number is disabled; it will then be assumed that all parts within a group appear in correct order: the first one is assigned number 1 etc. However, part numbers found in MIME-headers are still used (I haven't yet found a file where these were wrong). A dumbness of 2 also switches off the code to select a unique identifier from the subject line. This does still work with single-part files\footnote{Of course, this option wouldn't make sense with single-part files, since there's no ``grouping'' involved that might fail.} and \emph{might} work with multi-part files, as long as they're in correct order and not mixed. The filename is found on the first part and then passed on to the following parts. This option only takes effect for files scanned afterwards. \item[\texttt{UUOPT\_BRACKPOL}] {\small (integer, default=0)} \\ Series of multi-part postings on the Usenet usually have subject lines like ``You must see this! [1/3] (2/4)''. How to parse this information? Is this the second part of four in a series of three postings, or is it the first of three parts and the second in a series of four postings? The library cannot know, and simply gives numbers in () parentheses precedence over number in [] brackets. If this assumption fails, the parts will be grouped and ordered completely wrong. Setting the ``bracket policy'' to 1 changes this precedence. If now both parentheses and brackets are present, the numbers within brackets will be evaluated first. This option only takes effect for files scanned afterwards. \item[\texttt{UUOPT\_VERBOSE}] {\small (integer, default=1)} \\ If set to 0, the Message Callback will not be bothered with messages of level \texttt{UUMSG\ush{}MESSAGE} or \texttt{UUMSG\ush{}NOTE}. The default is to generate these messages. \item[\texttt{UUOPT\_DESPERATE}] {\small (integer, default=0)} \\ By default, the library refuses to decode incomplete files and generates errors. But if switched into ``desperate mode'' these kinds of errors are ignored, and all \emph{available} data is decoded. The usefulness of the resulting corrupt file depends on the type of the file. \item[\texttt{UUOPT\_IGNREPLY}] {\small (integer, default=0)} \\ If set to 1, the library will ignore email messages and news postings which were sent as ``Reply'', since they are less likely to feature useful data. There's no real reason to turn on this option any more (earlier versions got easily confused by replies). \item[\texttt{UUOPT\_OVERWRITE}] {\small (integer, default=1)} \\ When the decoder finds that the target file already exists, it is simply overwritten silently by default. If this option is set to 0, the decoder fails instead, generating a \texttt{UURET\ush{}EXIST} error. \item[\texttt{UUOPT\_SAVEPATH}] {\small (string, default=(empty))} \\ Without setting this option, files are decoded to the current directory. This ``save path'' is handled as prefix to each filename. Because the library does not know about directory layouts, the resulting filename is simply the concatenation of the save path and the target file, meaning that the path must include a final directory separator (slash, backslash, or whatever). \item[\texttt{UUOPT\_IGNMODE}] {\small (integer, default=0)} \\ Usually, the decoder tries to restore the file mode found on the ``begin'' line of \emph{uuencoded} and \emph{xxencoded} files. This is turned off if this option is set to 1. \item[\texttt{UUOPT\_DEBUG}] {\small (integer, default=0)} \\ If set to 1, all messages will be prefixed with the exact sourcecode location (filename and line number) where they were created. Might be useful if this is not clear from context. \item[\texttt{UUOPT\_ERRNO}] {\small (integer, read-only)} \\ This ``option'' can be queried after an operation failed with \texttt{UURET\ush{}IOERR} and returns the \texttt{errno} value that originally caused the problem. The ``real'' value of this variable might already be obscured by secondary problems. \item[\texttt{UUOPT\_PROGRESS}] {\small (uuprogress, read-only)} \\ Returns the progress structure. This would only make sense in multi-threaded environments where the decoder runs in one thread and is controlled from another. Although some care is taken while updating the structure's values, there might still be synchronization problems. \item[\texttt{UUOPT\_USETEXT}] {\small (integer, default=0)} \\ If this flag is true, plain text files will be presented for ``decoding''. This includes non-decodeable messages as well as plain-text parts from MIME multipart messages. Since they usually don't have associated filenames, a unique name will be created from a sequential four-digit number. \item[\texttt{UUOPT\_PREAMB}] {\small (integer, default=0)} \\ Whether to use the plain-text preamble and epilogue from MIME multipart messages. The standard defines they're supposed to be ignored, so there's no real reason to set this option. \item[\texttt{UUOPT\_TINYB64}] {\small (integer, default=0)} \\ Support for tiny Base64 data. If set to off, the scanner does not recognize stand-alone Base64 encoded data with less than 3 lines. The problem is that in some cases plain text might be misinterpreted as Base64 data, since, for example, any four-character alphanumerical string like ``Argh'' appearing on a line of its own is valid Base64 data. Since encoded files are usually longer, and there is considerable confusion about erroneous Base64 detection, this option is off by default. There's probably no need to present this option separately to the user. It's reasonable to associate it with the ``desperate mode'' described above. Note that this option only affects \emph{stand-alone} data. Input from Mime messages with the encoding type correctly specified in the ``Content-Transfer-Encoding'' header is always evaluated. There is also no problem with encoding types different than Base64, since they have an explicit notion of the beginning and end of a file, and no danger of misinterpretation exists. \item[\texttt{UUOPT\_ENCEXT}] {\small (string, default=(empty))} \\ When encoding into a file on the local disk, the target files usually receive an extension composed of the three-digit part number. This may be considered inappropriate for single-part files. If this option is set, its value is attached to the base file name as extension for the target file. A dot `.' is inserted automatically. When using uuencoding, a sensible value might be ``uue''. This option does not alter the behaviour on multi-part files, where the individual parts always receive the three-digit part number as extension. \item[\texttt{UUOPT\_REMOVE}] {\small (integer, default=0)} \\ If true, input files are deleted if data was successfully decoded from them. Be careful with this option, as the library does not care if the file contains any other useful information besides the decoded data. And it also does not and can not check the integrity of the decoded file. Therefore, if in doubt of the incoming data, you should do a confidence check first and then delete the relevant input files afterwards. But then, this option was requested by many users. \item[\texttt{UUOPT\_MOREMIME}] {\small (integer, default=0)} \\ Makes the library behave more MIME-compliant. Normally, some liberties are taken with seemingly MIME files in order to find encoded data within it, therefore also finding files within broken MIME messages. If this option is set to 1, the library is more strict in its handling of MIME files, and will for example not allow Base 64 data outside of properly tagged subparts, and will not accept ``random'' encoded data. You can also set the value of this option to 2 to enforce strict MIME adherance. If the option is 1, the library will still look into plain text attachments and try to find encoded data within it. This causes for example uuencoded files that were then sent in a MIME envelope to be recognized. With an option value of 2, the library won't even do that, trusting all MIME header information. \end{description} \section{General Functions} After describing all the framework in the previous chapters, it is time to mention some function calls. Still, the functions presented here don't actually \emph{do} anything, they just query and modify the behavior of the core functions. \begin{description} \item[\texttt{int UUInitialize (void)}] \hfill{} \\ This function initializes the library and must be called before any other decoding or encoding function. During initialization, several arrays are allocated. If memory is exhausted, \texttt{UURET\ush{}NOMEM} is returned, otherwise the initialization will return successfully with \texttt{UURET\ush{}OK}. \item[\texttt{int UUCleanUp (void)}] \hfill{} \\ Cleans up all resources that have been allocated during a program run: memory structures, temporary files and everything. No library function may be called afterwards, with the exception of \texttt{UUInitialize} to start another run. \item[\texttt{int UUGetOption (int opt, int *ival, char *cval, int len)}] \hfill{} \\ Retrieves the configuration option (see section \ref{Section-Options}) opt. If the option is integer, it is stored in \texttt{ival} (only if \texttt{ival!=NULL}) and also returned as return value. String options are copied to \texttt{cval}. Including the final nullbyte, at most \texttt{len} characters are written to \texttt{cval}. If the progress information is queried with \texttt{UUOPT\ush{}PROGRESS}, \texttt{cval} must point to a \texttt{uuprogress} structure and \texttt{len} must equal \texttt{sizeof(uuprogress)}. For integer options, \texttt{cval} may be NULL and \texttt{len} 0 and vice versa: for string options, \texttt{ival} is not evaluated. \item[\texttt{int UUSetOption (int opt, int ival, char *cval)}] \hfill{} \\ Sets one of the configuration options. Integer options are set via \texttt{ival} (\texttt{cval} may be \texttt{NULL}), and string options are copied from the null-ter\-mina\-ted string \texttt{cval} (\texttt{ival} may be 0). Returns \texttt{UURET\ush{}ILLVAL} if you try to set a read-only value, or \texttt{UURET\_OK} otherwise. \item[\texttt{char *UUstrerror (int errcode)}] \hfill{} \\ Maps the return values \texttt{UURET\_*} into error messages: \begin{description} \item[\texttt{UURET\_OK}] ``OK'' \item[\texttt{UURET\_IOERR}] ``File I/O Error'' \item[\texttt{UURET\_NOMEM}] ``Not Enough Memory'' \item[\texttt{UURET\_ILLVAL}] ``Illegal Value'' \item[\texttt{UURET\_NODATA}] ``No Data found'' \item[\texttt{UURET\_NOEND}] ``Unexpected End of File'' \item[\texttt{UURET\_UNSUP}] ``Unsupported function'' \item[\texttt{UURET\_EXISTS}] ``File exists'' \end{description} \item[\texttt{int UUSetMsgCallback (void *opaque, void (*func) ())}] \hfill{} \\ Sets the Message Callback function to \texttt{func} (see section \ref{Section-Msg-Callback}). \texttt{opaque} is the opaque data pointer that is passed untouched to the callback whenever it is called. To prevent compiler warnings, a prototype of the callback should appear before this line. Always returns \texttt{UURET\ush{}OK}. If \texttt{func==NULL}, the callback is disabled. \item[\texttt{int UUSetBusyCallback (void *, void (*func) (), long msecs)}] \hfill{} \\ Sets the Busy Callback function to \texttt{func} (see section \ref{Section-Busy-Callback}). \texttt{msecs} gives a timespan in milliseconds; the library will try to call the callback after this timespan has passed. On some systems, the time can only be queried with second resolution -- in that case, timing will be quite inaccurate. The semantics for the other two parameters are the same as in the previous function. If \texttt{func==NULL}, the busy callback is disabled. \item[\texttt{int UUSetFileCallback (void *opaque, int (*func) ())}] \hfill{} \\ Sets the File Callback function to \texttt{func} (see section \ref{Section-File-Callback}). Semantics identical to the previous two functions. There is no need to install a file callback if this feature isn't used. \item[\texttt{int UUSetFNameFilter (void *opaque, char * (*func) ())}] \hfill{} \\ Sets the Filename Filter function to \texttt{func} (see section \ref{Section-FName-Filter}). Semantics identical to the previous three functions. If no filename filter is installed, any filename is accepted. This may result in failures to write a file because of an invalid filename. \item[\texttt{char * UUFNameFilter (char *fname)}] \hfill{} \\ Calls the current filename filter on \texttt{fname}. This function is provided so that certain parts of applications do not need to know which filter is currently installed. This is handy for applications that are supposed to run on more than one system. If no filename filter is installed, the string itself is returned. Since a filename filter may return a pointer to static memory or a pointer into the parameter, the result from this function must not be written to. \end{description} \section{Decoding Functions} Now for the more useful functions. The functions within this section are everything you need to scan and decode files. \begin{description} \item[\texttt{int UULoadFile (char *fname, char *id, int delflag)}] \hfill{} \\ Scans a file for encoded data and inserts the result into the file list. Each input file must only be scanned once; it may contain many parts as well as multiple encoded files, thus it is possible that many decodeable files are found after scanning one input file. On the other hand it is also possible that \emph{no} decodeable data is found. There is no limit to the number of files.\footnote{Strictly speaking, the memory is of course limited. But try to fill a sensible amount with structures in the 100-byte region.} If \texttt{id} is non-NULL, its value is used instead of the filename, and the file callback is used to map the id back into a filename whenever this input file is needed again. If \texttt{id} \emph{is} \texttt{NULL}, then the input file must not be deleted or modified until \texttt{UUCleanUp} has been called. If \texttt{delflag} is non-zero, the input file will automatically be removed within \texttt{UUCleanUp}. This is useful when the decoder's input are also temporary files -- this way, the application can forget about them right after they're ``loaded''. The value of \texttt{delflag} is ignored, however, if \texttt{id} is non-NULL; combining both options does not make sense. The behavior of this function is influenced by some of the options, most notably \texttt{UUOPT\ush{}FAST}. The two most probable return values are \texttt{UURET\ush{}OK}, indicating successful completion, or \texttt{UURET\ush{}IOERR} in case of some error while reading the file. The other return values are less likely to appear. Note that files are even scheduled for destruction if an error \emph{did} happen during scanning (with the exception of a file that could not be opened). But error handling is slightly problematic here anyway, since it might be possible that useful data was found before the error occurred. \item[\texttt{int UULoadFileWithPartNo (char *fname, char *id, int delflag, int partno)}] \hfill{} \\ Same as above, but assigns a part number to the data in the file. This function can be used if the callee is certain of the part number and there is thus no need to depend on UUDeview's heuristics. However, it must not be used if the referenced file may contain more than one piece of encoded data. \item[\texttt{uulist * UUGetFileListItem (int num)}] \hfill{} \\ Returns a pointer to the \texttt{num}th item of the file list. The elements of this structure are described in section \ref{file-list}. The list is zero-based. If \texttt{num} is out-of-range, \texttt{NULL} is returned. Usage of this function is pretty straightforward: loop with an increasing value until \texttt{NULL} is returned. The structure must not be modified by the application itself. Also, none of the structure's value should be ``cached'' elsewhere, as they are not constant: they may change after each loaded file. \item[\texttt{int UURenameFile (uulist *item, char *newname)}] \hfill{} \\ Renames one item of the file list. The old name is discarded and replaced by \texttt{newname}. The new name is copied and may thus point to volatile memory. The name should be a local filename without any directory information, which would be stripped by the filename filter anyway. \item[\texttt{int UUDecodeToTemp (uulist *item)}] \hfill{} \\ Decodes the given item of the file list and places the decoded output into a temporary file. This is intended to allow ``previews'' of an encoded file without copying it to its final location (which would probably overwrite other files). The name of the temporary file can be retrieved afterwards by re-retrieving the node of the file list and looking at its \texttt{binfile} member. \texttt{UURET\ush{}OK} is returned upon successful completion. Most other error codes can occur, too. \texttt{UURET\ush{}NODATA} is returned if you try to decode parts without encoded data or with a missing beginning (\emph{uuencoded} and \emph{xxencoded} files only) -- of course, this condition would also have been obvious from the \texttt{state} value of the file list structure. The setting of \texttt{UUOPT\ush{}DESPERATE} changes the behavior if an unexpected end of file was found (usually meaning that one or more parts are missing). Normally, the partially-written target file is removed and the value \texttt{UURET\ush{}NOEND} is returned. In desperate mode, the same error code is returned, but the target file is not removed. The target file is removed in all other error conditions. \item[\texttt{int UURemoveTemp (uulist *item)}] \hfill{} \\ After a file has been decoded into a temporary file and is needed no longer, this function can be called to free the disk space immediately instead of having to wait until \texttt{UUCleanUp}. If a decode operation is called for later on, the file will simply be recreated. \item[\texttt{int UUDecodeFile (uulist *item, char *target)}] \hfill{} \\ This is the function you have been waiting for. The file is decoded and copied to its final location. Calling \texttt{UUDecodeToTemp} beforehand is not required. If \texttt{target} is non-NULL, then it is immediately used as filename for the target file (without prepending the save path and without passing it through the filename filter). Otherwise, if \texttt{target==NULL}, the final filename is composed by concatenating the save path and the result of the filename filter used upon the filename found in the encoded file. If the target file already exists, the value of the \texttt{UUOPT\ush{}OVERWRITE} option is checked. If it is false (zero), then the error \texttt{UURET\ush{}EXISTS} is generated and decoding fails. If the option is true, the target file is silently overwritten.\footnote{If we don't have permission to overwrite the target file, an I/O error is generated.} The file is first decoded into a temporary file, then the temporary file is copied to the final location. This is done to prevent overwriting target files with data that turns out too late to be invalid. \item[\texttt{int UUInfoFile (uulist *item, void *opaque, int (*func) ())}] \hfill{} \\ This function can be used to query information about the encoded file. This is either the zeroth part of a file if available, or the beginning of the first part up to the encoded data otherwise. Once again, a callback function is used to do the job. \texttt{func} must be a function with two parameters. The first one is an opaque data pointer (the value of \texttt{opaque}), the other is one line of info about the file (at maximum, 512 bytes). The callback is called for each line of info. The callback can return either zero, meaning that it can accept more data, or non-zero, which immediately stops retrieval of more information. Usually, the opaque pointer holds some information about a text window, so that the callback knows where to print the next line. In a terminal-oriented application, the user can be queried each 25th line and the callback can return non-zero if the user doesn't wish to continue. \item[\texttt{int UUSmerge (int pass)}] \hfill{} \\ Attempts a ``Smart Merge'' of parts that seem to belong to different files but which \emph{could} belong to the same. Occasionally, you will find a posting with parts 1 to 3 and 5 to 8 of ``picture.gif'' and part 4 of ``picure.gif'' (note the spelling). To the human, it is obvious that these parts belong together, to a machine, it is not. This function attempts to detect these conditions and merge the appropriate parts together. This function must be called repeatedly with increasing values for ``pass'': With \texttt{pass==0}, only immediate fits are merged, increasing values allow greater ``distances'' between part numbers, This function is a bunch of heuristics, and I don't really trust them. In some cases, the ``smart'' merge may do more harm than good. This function should only be called as last resort on explicit user request. The first call should be made with \texttt{pass==0}, then with \texttt{pass==1} and at last with \texttt{pass=99}. \end{description} \section{Encoding Functions} There are a couple of functions to encode data into a file. You will usually need no more than one of them, depending on the job you want to do. The functions also differ in the headers they generate. Some functions do generate full MIME-compliant headers. This may sound like the best choice, but it's not always the wisest choice. Please follow the following guidelines. \begin{itemize} \item Do not produce MIME-compliant messages if you cannot guarantee their proper handling. For example, if you create a MIME-compliant message on disk, and the user \emph{includes} this file in a text message, the headers produced for the encoded data become not part of the final message's header but are just included in the message body. The resulting message will \emph{not} be MIME-compliant! \item Take it from the author that slightly-different-than-MIME messages give the recipient much worse headaches than messages that do not try to be MIME in the first place. \item Because of that, headers should \emph{only} be generated if the application itself handles the final mailing or posting of the message. Do not rely on user actions. \item Do not encode to \emph{Base64} outside of MIME messages. Because some information like the filename is only available in the MIME-message framework, \emph{Base64} doesn't make much sense without it. \item However, if you can guarantee proper MIME handling, \emph{Base64} should be favored above the other types of encoding. Most MIME-compliant applications do not know the other encoding types. \end{itemize} All of the functions have a bunch of parameters for greater flexibility. Don't be confused by their number, usually you'll need to fill only a few of them. There's a number of common parameters which can be explained separately: \begin{description} \item[\texttt{FILE *outfile}] \hfill{} \\ The output stream, where the encoded data is written to. \item[\texttt{FILE *infile, char *infname}] \hfill{} \\ Where the input data shall be read from. Only one of both values must be specified, the other can be NULL. \item[\texttt{char *outfname}] \hfill{} \\ The name by which the recipient will receive the file. It is used on the ``begin'' line for \emph{uuencoded} and \emph{xxencoded} data, and in the headers of MIME-formatted messages. If this parameter is NULL, it defaults to \texttt{infname}. It must be specified if data is read from a stream and \texttt{infname==NULL}. \item[\texttt{int filemode}] \hfill{} \\ For \emph{uuencoded} and \emph{xxencoded} data, the file permissions are encoded into the ``begin'' line. This mode can be specified here. If the value is 0, it will be determined by performing a \texttt{stat()} call on the input file. If this call should fail, a value of 0644 is used as default. \item[\texttt{int encoding}] \hfill{} \\ The encoding to use. One of the three constants \texttt{UU\ush{}ENCODED}, \texttt{XX\ush{}ENCODED} or \texttt{B64\-ENCODED}. \end{description} Now for the functions \dots{} \begin{description} \item[\texttt{\begin{tabular}{ll}% int UUEncodeMulti & (FILE *outfile, FILE *infile, \\ & ~char *infname, int encoding, \\ & ~char *outfname, char *mimetype, \\ & ~int filemode) \\ \end{tabular}}] \hfill{} \\ Encodes data into a subpart of a MIME ``multipart'' message. Appropriate ``Content-Type'' headers are produced, followed by the encoded data. The application must provide the envelope and boundary lines. If \texttt{mimetype!=NULL}, it is used as value for the ``Content-Type'' field, otherwise, the extension from \texttt{outfname} or \texttt{infname} (if \texttt{outfname==NULL}) is used to look up the relevant type name. \item[\texttt{\begin{tabular}{ll}% int UUEncodePartial & (FILE *outfile, FILE *infile, \\ & ~char *infname, int encoding, \\ & ~char *outfname, char *mimetype, \\ & ~int filemode, int partno, \\ & ~long linperfile) \\ \end{tabular}}] \hfill{} \\ Encodes data as the body of a MIME ``message/partial'' message. This type allows message fragmentation. This function must be called repetitively until it runs out of input data. The application must provide a valid envelope with a ``message/partial'' content type and proper information about the part numbers. Each call produces \texttt{linperfile} lines of encoded output. For \emph{uuencoded} and \emph{xxencoded} files, each output line encodes 45 bytes of input data, each \emph{Base64} line encodes 57 bytes. If \texttt{linperfile==0}, this function is equivalent to \texttt{UUEncodeMulti}. Different handling is necessary when reading from an input stream (if \texttt{infile!=NULL}) compared to reading from a file (if \texttt{infname!=NULL}). In the first case, the function must be called until \texttt{feof()} becomes true on the input file, or an error occurs. In the second case, the file will be opened internally. Instead of \texttt{UURET\ush{}OK}, a value of \texttt{UURET\ush{}CONT} is returned for all but the last part. \item[\texttt{\begin{tabular}{ll}% int UUEncodeToStream & (FILE *outfile, FILE *infile, \\ & ~char *infname, int encoding, \\ & ~char *outfname, int filemode) \\ \end{tabular}}] \hfill{} \\ Encodes the input data and sends the plain output without any headers to the output stream. Be aware that for \emph{Base64}, the output does not include any information about the filename. \item[\texttt{\begin{tabular}{ll}% int UUEncodeToFile & (FILE *infile, char *infname, \\ & ~int encoding, char *outfname, \\ & ~char *diskname, long linperfile) \\ \end{tabular}}] \hfill{} \\ Encodes the input data and writes the output into one or more output files on the local disk. No headers are generated. If \texttt{diskname==NULL}, the names of the encoded files are generated by concatenating the save path (see the \texttt{UUOPT\ush{}SAVEPATH} option) and the base name of \texttt{outfname} or \texttt{infname} (if \texttt{outfname==NULL}). If \texttt{diskname!=NULL} and does not contain directory information, the target filename is the concatenation of the save path and \texttt{diskname}. If \texttt{diskname} is an absolute path name, it is used itself. From the so-generated target filename, the extension is stripped. For single-part output files, the extension set with the \texttt{UUOPT\ush{}ENCEXT} option is used. Otherwise, the three-digit part number is used as extension. If the destination file does already exist, the value of the \texttt{UUOPT\ush{}OVERWRITE} is checked; if overwriting is not allowed, encoding fails with \texttt{UURET\ush{}EXISTS}. \item[\texttt{\begin{tabular}{ll}% int UUE\_PrepSingle & (FILE *outfile, FILE *infile, \\ & ~char *infname, int encoding, \\ & ~char *outfname, int filemode, \\ & ~char *destination, char *from, \\ & ~char *subject, int isemail) \\ \end{tabular}}] \hfill{} \\ Produces a complete MIME-formatted message including all necessary headers. The output from this function is usually fed directly into a mail delivery agent which honors headers (like ``sendmail'' or ``inews''). If \texttt{from!=NULL}, it is sent as the sender's email address in the ``From'' header field. Some MDA programs are able to provide the sender's address themselves, so this value may be NULL in certain cases. If \texttt{subject!=NULL}, the text is included in the ``Subject'' header field. The subject is extended with information about the file name and part number (in this case, always ``(001/001)''). ``Destination'' must not be NULL. Depending on the ``isemail'' flag, its contents are sent either in the ``To'' or ``Newsgroups'' header field. \item[\texttt{\begin{tabular}{ll}% int UUE\_PrepPartial & (FILE *outfile, FILE *infile, \\ & ~char *infname, int encoding, \\ & ~char *outfname, int filemode, \\ & ~int partno, long linperfile, \\ & ~long filesize, \\ & ~char *destination, char *from, \\ & ~char *subject, int isemail) \\ \end{tabular}}] \hfill{} \\ Similar to \texttt{UUE\_PrepSingle}, but produces a complete MIME-formatted ``message/partial'' message including all necessary headers. The function must be called repetitively until it runs out of input data. For more explanations, see the description of the function \texttt{UUEncodePartial} above. The only additional parameter is \texttt{filesize}. Usually, this value can be 0, as the size of the input file can usually be determined by performing a \texttt{stat()} call. However, this might not be possible if \texttt{infile} refers to a pipe. In that case, the value of \texttt{filesize} is used. If the size of the input data cannot be determined, and \texttt{filesize} is 0, the function refuses encoding into multiple files and produces only a single stream of output. If data is read from a file instead from a stream (\texttt{infile==NULL}), the function opens the file internally and returns \texttt{UURET\ush{}CONT} instead of \texttt{UURET\ush{}OK} on successful completion for all but the last part. \end{description} \section{The Trivial Decoder} In this section, we implement and discuss the ``Trivial Decoder'', which illustrates the use of the decoding functions. We start with the absolute minimum and then add more features and actually end up with a limited, but useful tool. For a full-scale frontend, look at the implementation of the ``UUDeview'' program. The sample code can be found among the documentation files as \texttt{\mbox{td-v1.c}}, \texttt{\mbox{td-v2.c}} and \texttt{\mbox{td-v3.c}}. \subsection{Version 1} \begin{figure} \centering \begin{small} \rule{\textwidth}{1pt} \begin{verbatim} #include #include #include #include int main (int argc, char *argv[]) { UUInitialize (); UULoadFile (argv[1], NULL, 0); UUDecodeFile (UUGetFileListItem (0), NULL); UUCleanUp (); return 0; } \end{verbatim} \rule{\textwidth}{1pt} \end{small} \caption{The ``Trivial Decoder'', Version 1} \label{td-v1} \end{figure} The minimal decoding program is displayed in Figure \ref{td-v1}. Only four code lines are needed for the implementation. \texttt{} defines \texttt{NULL}, \texttt{} declares the decoding library functions, and \texttt{}, the library's configuration file, is needed for some configuration details\footnote{Actually, only the definition of \texttt{UUEXPORT} is needed. You could omit \texttt{} and define this value elsewhere, for example in the project definitions.}. After initialization, the file given as first command line parameter is scanned. No symbolic name is assigned to the file, so that we don't need a file callback. After the scanning, the encoded file is decoded and stored in the current directory by its native name. Of course, there is much to complain about: \begin{itemize} \item No error checking is done. For example, does the input file exist? \item Only a single file can be scanned for encoded data. \item If more than one encoded file is found, only the first one is decoded, the others are ignored. \item No checking is done if there actually \emph{is} encoded data in the file and whether this data is valid. \end{itemize} \subsection{Version 2} \begin{figure} \centering \begin{small} \rule{\textwidth}{1pt} \begin{verbatim} #include #include #include #include #include #include int main (int argc, char *argv[]) { uulist *item; int i, res; UUInitialize (); for (i=1; istate & UUFILE_OK) == 0) continue; if ((res = UUDecodeFile (item, NULL)) != UURET_OK) { fprintf (stderr, "error decoding %s: %s\n", (item->filename==NULL)?"oops":item->filename, (res==UURET_IOERR) ? strerror (UUGetOption (UUOPT_ERRNO, NULL, NULL, 0)) : UUstrerror(res)); } else { printf ("successfully decoded '%s'\n", item->filename); } } UUCleanUp (); return 0; } \end{verbatim} \rule{\textwidth}{1pt} \end{small} \caption{The ``Trivial Decoder'', Version 2} \label{td-v2} \end{figure} The second version, printed in figure \ref{td-v2}, addresses all of the above problems. The code size more than tripled, but that's largely because of the error messages. All files given on the command line are scanned\footnote{With Microsoft compilers on MS-DOS systems, don't forget to link with \texttt{setargv.obj} to properly handle wildcards}, and all encoded files are decoded. Of course, it is now also possible for an encoded file to span its parts over more than one input file. Appropriate error messages are printed upon failure of any step, and a success message is printed for successfully decoded files. Apart from the program's unfriendliness that there is no user-interaction like selective decoding of files, choice of a target directory etc., there are only three more items to complain about: \begin{itemize} \item Errors and other messages produced within the library aren't displayed because there's no message callback. \item No filename filter is installed, so decoding of files with invalid filenames will fail; this especially includes filenames with directory information. \item No information is printed for invalid encoded files, or files with missing parts (they're simply skipped). \end{itemize} \subsection{Version 3} \begin{figure} \centering \begin{small} \rule{\textwidth}{1pt} {\small\emph{\dots{} right after the \#includes}} \\ \begin{verbatim} #include void MsgCallBack (void *opaque, char *msg, int level) { fprintf (stderr, "%s\n", msg); } char * FNameFilter (void *opaque, char *fname) { static char dname[13]; char *p1, *p2; int i; if ((p1 = _FP_strrchr (fname, '/')) == NULL) p1 = fname; if ((p2 = _FP_strrchr (p1, '\\')) == NULL) p2 = p1; for (i=0, p1=dname; *p2 && *p2!='.' && i<8; i++) *p1++ = (*p2==' ')?(p2++,'_'):*p2++; while (*p2 && *p2 != '.') p2++; if ((*p1++ = *p2++) == '.') for (i=0; *p2 && *p2!='.' && i<3; i++) *p1++ = (*p2==' ')?(p2++,'_'):*p2++; *p1 = '\0'; return dname; } \end{verbatim} {\small\emph{\dots{} within \texttt{main()} after \texttt{UUInitialize}}} \\ \begin{verbatim} UUSetMsgCallback (NULL, MsgCallBack); UUSetFNameFilter (NULL, FNameFilter); \end{verbatim} {\small\emph{\dots{} replacing the main loop's \emph{else}}} \\ \begin{verbatim} else { printf ("successfully decoded '%s' as '%s'\n", item->filename, UUFNameFilter (item->filename)); } \end{verbatim} \rule{\textwidth}{1pt} \end{small} \caption{Changes for Version 3} \label{td-v3-diff} \end{figure} This last section adds a simple filename filter (targeting at a DOS system with 8.3 filenames) and a simple message callback, which just dumps messages to the console. Figure \ref{td-v3-diff} lists the changes with respect to version 2 (for the full listing, refer to the source file on disk). The message callback, a one-liner, couldn't be simpler. The filename filter will probably not win an award for good programming style, but it does its job of stripping Unix-style or DOS-style directory names and using only the first 8 characters of the base filename and the first three characters of the extension. If the filename contains space characters, they're replaced by underscores. Note that \texttt{dname}, the storage for the resulting filename, is declared static, as it must be accessible after the filter function has returned. For portability, the filename filter uses a replacement function from the \texttt{fptools} library instead of relying of a native implementation of the \texttt{strrchr} function. Both callbacks are installed right after initializing the library. Since now the filename of the decoded file may be different from the filename of the file list structure, we recreate the resulting filename by calling the filename filter ourselves for display, so that the user knows where to look for the file. \section{Replacement functions} \label{chap-rf} This section is a short reference for the replacement functions from the \texttt{fptools} library. Some of them may be useful in the application code as well. Most of these functions are pretty standard in modern systems, but there's also a few from the author's imagination. Each of the functions is tagged with information why this replacement exists: \begin{itemize} \item ``nonstandard'' (ns): this function is available on some systems, but not on others. Functions with this tag could be safely replaced with a native implementation. \item ``feature'' (f): the replacement adds some functionality with respect to the ``original''. \item ``author''(a): just a function the author considered useful. \end{itemize} \begin{description} \item[\texttt{void \_FP\_free (void *)}] {\small (f)} \\ ANSI C guarantees that \texttt{free()} can be safely called with a \texttt{NULL} argument, but some old systems dump core. This replacement just ignores a \texttt{NULL} pointer and passes anything else to the original \texttt{free()}. \item[\texttt{char *\_FP\_strdup (char *ptr)}] {\small (ns)} \\ Allocates new storage for the string \texttt{ptr} and copies the string including the final nullbyte to the new location (thus ``duplicating'' the string). Returns \texttt{NULL} if the \texttt{malloc()} call fails. \item[\texttt{char *\_FP\_strncpy (char *dest, char *src, int count)}] {\small (f)} \\ Copies text from the \texttt{src} area to the \texttt{dest} area, until either a nullbyte has been copied or \texttt{count} bytes have been copied. Differs from the original in that if \texttt{src} is longer than \texttt{count} bytes, then only \texttt{count}-1 bytes are copied, and the destination area is properly terminated with a nullbyte. \item[\texttt{void *\_FP\_memdup (void *ptr, int count)}] {\small (a)} \\ Allocates a new area of \texttt{count} bytes, which are then copied from the \texttt{ptr} area. \item[\texttt{int \_FP\_stricmp (char *str1, char *str2)}] {\small (ns)} \\ Case-insensitive equivalent of \texttt{strcmp}. \item[\texttt{int \_FP\_strnicmp (char *str1, char *str2, int count)}] {\small (ns)} \\ Case-insensitive equivalent of \texttt{strncmp}. \item[\texttt{char *\_FP\_strrchr (char *string, int chr)}] {\small (ns)} \\ Similar to \texttt{strchr}, but returns a pointer to the last occurrence of the character \texttt{chr} in \texttt{string}. \item[\texttt{char *\_FP\_strstr (char *str1, char *str2)}] {\small (ns)} \\ Returns a pointer to the first occurrence of \texttt{str2} in \texttt{str1} or \texttt{NULL} if the second string does not appear within the first. \item[\texttt{char *\_FP\_strrstr (char *str1, char *str2)}] {\small (ns)} \\ Similar to \texttt{strstr}, but returns a pointer to the last occurrence of \texttt{str2} in \texttt{str1}. \item[\texttt{char *\_FP\_stristr (char *str1, char *str2)}] {\small (a)} \\ Case-insensitive equivalent of \texttt{strstr}. \item[\texttt{char *\_FP\_strirstr (char *str1, char *str2)}] {\small (a)} \\ Case-insensitive equivalent of \texttt{strrstr}. \item[\texttt{char *\_FP\_stoupper (char *string)}] {\small (a)} \\ Converts all alphabetic characters in \texttt{string} to uppercase. \item[\texttt{char *\_FP\_stolower (char *string)}] {\small (a)} \\ Converts all alphabetic characters in \texttt{string} to lowercase. \item[\texttt{int \_FP\_strmatch (char *str, char *pat)}] {\small (a)} \\ Performs glob-style pattern matching. \texttt{pat} is a string containing regular characters and the two wildcards '?' (question mark) and '*'. The question mark matches any single character, the '*' matches any zero or more characters. If \texttt{str} is matched by \texttt{pat}, the function returns 1, otherwise 0. \item[\texttt{char *\_FP\_fgets (char *buf, int max, FILE *file)}] {\small (f)} \\ Extends the standard \texttt{fgets()}; this replacement is able to handle line terminators from various systems. DOS text files have their lines terminated by CRLF, Unix files by LF only and Mac files by CR only. This function reads a line and replaces whatever line terminator present with a single LF. \item[\texttt{char *\_FP\_strpbrk (char *str, char *accept)}] {\small (ns)} \\ Locates the first occurrence in the string \texttt{str} of any of the characters in \texttt{accept}. \item[\texttt{char *\_FP\_strtok (char *str, char *del)}] {\small (ns)} \\ Considers the string \texttt{str} to be a sequence of tokens separated by one or more of the delimiter characters given in \texttt{del}. Upon first call with \texttt{str!=NULL}, returns the first token. Later calls with \texttt{str==NULL} return the following tokens. Returns \texttt{NULL} if no more tokens are found. \item[\texttt{char *\_FP\_cutdir (char *str)}] {\small (a)} \\ Returns the filename part of \texttt{str}, meaning everything after the last slash or backslash in the string. Now replaced with the concept of the filename filter. \item[\texttt{char *\_FP\_strerror (int errcode)}] {\small (ns)} \\ A rather dumb replacement of the original one, which transforms error codes from \texttt{errno} into a human-readable error message. This function should \emph{only} be used if no native implementation exists; it just returns a string with the numerical error number. \item[\texttt{char *\_FP\_tempnam (char *dir, char *pfx)}] {\small (ns)} \\ The original is supposed to return a unique filename. The temporary file should be stored in \texttt{dir} and have a prefix of \texttt{pfx}. This replacement, too, should only be used if no native implementation exists. It just returns a temporary filename created by the standard \texttt{tmpnam()}, which not necessarily resides in a proper \texttt{TEMP} directory. The value returned by this function is an allocated memory area which must later be freed by calling \texttt{free}. \end{description} \section{Known Problems} This section mentions a few known problems with the library, which the author considers to be ``features'' rather than ``bugs'', meaning that they probably won't be ``fixed'' in the near future. \begin{itemize} \item Encoding to \emph{BinHex} is not yet supported. \item The checksums found in \emph{BinHex} files are ignored. \item If both data and resource forks in a \emph{BinHex} file are non-empty, the larger one is decoded. Non-Mac systems can only use one of them anyway (usually the ``data'' fork, the ``resource'' fork usually contains M68k or PPC machine code). \end{itemize} \begin{thebibliography}{RFC1521} \bibitem[RFC0822]{rfc0822} Crocker, D., ``Standard for the Format of ARPA Internet Text Messages'', RFC 822, Network Working Group, August 1982. \bibitem[RFC1521]{rfc1521} Borenstein, N., ``MIME (Multipurpose Internet Mail Extensions) Part One'', RFC 1521, Network Working Group, September 1993. \bibitem[RFC1741]{rfc1741} Faltstr\o{}m, P., Crocker, D. and Fair, E., ``MIME Content Type for BinHex Encoded Files'', RFC 1741, Network Working Group, December 1994. \bibitem[RFC1806]{rfc1806} Troost, R., Dorner, S., ``The Content-Disposition Header'', RFC 1806, Network Working Group, June 1995. \end{thebibliography} RFC documents (``Request for Comments'') can be downloaded from many ftp sites around the world. \newpage \begin{appendix} \section{Encoding Formats} The following sections describe the four most widely used formats for encoding binary data into plain text, \emph{uuencoding}, \emph{xxencoding}, \emph{Base64} and \emph{BinHex}. Another section shortly mentions \emph{Quoted-Printable} encoding. Other formats exist, like \emph{btoa} and \emph{ship}, but they are not mentioned here. \emph{btoa} is much less efficient than the others. \emph{ship} is slightly more efficient and will probably be supported in future. Uuencoding, xxencoding and Base 64 basically work the same. They are all ``three in four'' encodings, which means that they take three octets\footnote{The term ``octet'' is used here instead of ``byte'', since it more accurately reflects the 8-bit nature of what we usually call a ``byte''} from the input file and encode them into four characters. \begin{table} \centering \begin{tabular}{|r|c|c|c|c|c|c|c|c|}\hline Input Octet &1& & & & & & & \\ \hline Input Bit &7&6&5&4&3&2&1&0 \\ \hline\hline Output Data \#1 &5&4&3&2&1&0& & \\ \hline Output Data \#2 & & & & & & &5&4 \\ \hline\\[3mm]\hline Input Octet &2& & & & & & & \\ \hline Input Bit &7&6&5&4&3&2&1&0 \\ \hline\hline Output Data \#2 &3&2&1&0& & & & \\ \hline Output Data \#3 & & & & &5&4&3&2 \\ \hline\\[3mm]\hline Input Octet &3& & & & & & & \\ \hline Input Bit &7&6&5&4&3&2&1&0 \\ \hline\hline Output Data \#3 &1&0& & & & & & \\ \hline Output Data \#4 & & &5&4&3&2&1&0 \\ \hline \end{tabular} \caption{Bit mapping for Three-in-Four encoding} \label{tab-3-in-4} \end{table} Three bytes are 24 bits, and they are divided into 4 sections of 6 bits each. Table \ref{tab-3-in-4} describes in detail how the input bits are copied into the output data bits. 6 bits can have values from 0 to 63; each of the ``three in four'' encodings now uses a character table with 64 entries, where each possible value is mapped to a specific character. The advantage of three in four encodings is their simplicity, as encoding and decoding can be done by mere bit shifting and two simple tables (one for encoding, mapping values to characters, and one for decoding, with the reverse mapping). The disadvantage is that the encoded data is 33\% larger than the input (not counting line breaks and other information added to the encoded data). The before-mentioned \emph{ship} data is more effective; it is a so-called \emph{Base 85} encoding. Base 85 encodings take four input bytes (32 bits) and encode them into five characters. Each of this characters encode a value from 0 to 84; five characters can therefore encode a value from 0 to $85^5=4437053125$, covering the complete 32 bit range. Base 85 encodings need more ``complicated'' math and a larger character table, but result in only 25\% bigger encoded files. In order to illustrate the encodings and present some actual data, we will present the following text encoded in each of the formats: \begin{quote} \begin{small} \begin{verbatim} This is a test file for illustrating the various encoding methods. Let's make this text longer than 57 bytes to wrap lines with Base64 data, too. Greetings, Frank Pilhofer \end{verbatim} \end{small} \end{quote} \subsection{Uuencoding} A document actually describing uuencoding as a standard does not seem to exist. This is probably the reason why there are so many broken encoders and decoders around that each take their liberties with the definition. The following text describe the pretty strict rules for uuencoding that are used in the UUEnview encoding engine. The UUDeview decoding engine is much more relaxed, according to the general rule that you should be strict in all that you generate, but liberal in the data that your receive. Uuencoded data always starts with a \texttt{begin} line and continues until the \texttt{end} line. Encoded data starts on the line following the begin. Immediately before the \texttt{end} line, there must be a single \emph{empty} line (see below). \begin{quote} \begin{small} \texttt{begin} \emph{mode} \emph{filename} \\ \dots{} \emph{encoded data} \dots{} \\ \emph{``empty'' line} \\ \texttt{end} \end{small} \end{quote} \subsubsection{The \texttt{begin} Line} The \texttt{begin} line starts with the word \texttt{begin} in the first column. It is followed, all on the same line, by the \emph{mode} and the \emph{filename}. \emph{mode} is a three- or four-digit octal number, describing the access permissions of the target file. This mode value is the same as used with the Unix \texttt{chmod} command and by the \texttt{open} system call. Each of the three digits is a binary or of the values 4 (read permission), 2 (write permission) and 1 (execute permission). The first digit gives the user's permissions, the second one the permissions for the group the user is in, and the third digit describes everyone else's permissions. On DOS or other systems with only a limited concept of file permissions, only the first digit should be evaluated. If the ``2'' bit is not set, the resulting file should be read-only, the ``1'' bit should be set for COM and EXE files. Common values are \texttt{644} or \texttt{755}. \emph{filename} is the name of the file. The name \emph{should} be without any directory information. \subsubsection{Encoded Data} The basic version of uencoding simply uses the ASCII characters 32-95 for encoding the 64 values of a three in for encoding. An exception\footnote{\dots{} that is not always respected by old encoders} is the value 0, which would normally map into the space character (ASCII 32). To prevent problems with mailers that strip space characters at the beginning or end of the line, character 96 ``\,`\,'' is used instead. The encoding table is shown in table \ref{tab-uu}. \begin{table} \centering \begin{tabular}{|r||c|c|c|c|c|c|c|c|}\hline Data Value &+0&+1&+2&+3&+4&+5&+6&+7 \\ \hline\hline 0 & `& !& "&\#&\$&\%&\&& ' \\ \hline 8 & (& )& *& +& ,& -& .& / \\ \hline 16 & 0& 1& 2& 3& 4& 5& 6& 7 \\ \hline 24 & 8& 9& :& ;&\texttt{\symbol{60}}&=&\texttt{\symbol{62}}&?\\ \hline 32 & @& A& B& C& D& E& F& G \\ \hline 40 & H& I& J& K& L& M& N& O \\ \hline 48 & P& Q& R& S& T& U& V& W \\ \hline 56 & X& Y& Z& [&\texttt{\symbol{92}}&]&\symbol{94}&\_ \\ \hline \end{tabular} \caption{Encoding Table for Uuencoding} \label{tab-uu} \end{table} Each line of uuencoded data is prefixed, in the first column, with the encoded number of encoded octets on this line. The most common prefix that you'll see is `M'. By looking up `M' in table \ref{tab-uu}, we see that it represents the number 45. Therefore, this prefix means that the line contains 45 octets (which are encoded into 60 $(45/3*4)$ plain-text characters). In uuencoding, each line has the same length, normally, the length (excluding the end of line character) is 61. Only the last line of encoded data may be shorter. If the input data is not a multiple of three octets long, the last triple is filled up with (one or two) nulls. The decoder can determine the number of octets that are to go into the output file from the prefix. \subsubsection{The Empty Line} After the last line of data, there must be an \emph{empty} line, which must be a valid encoded line containing no encoded data. This is achieved by having a line with the single character ``\,`\,'' on it (which is the prefix that encodes the value of 0 octets). \subsubsection{The \texttt{end} Line} The encoded file is then ended with a line consisting of the word \texttt{end}. \subsubsection{Splitting Files} Uuencoding does not describe a mechanism for splitting a file into two or more messages for separate mailing or posting. Usually, the encoded file is simply split into parts of more or less equal line count\footnote{Of course, encoded files must be split on line boundaries instead of at a fixed byte count.}. Before the age of smart decoders, the recipient had to manually concatenate the parts and remove the headers in between, because the headers of mail messages \emph{might} just be valid uuencoded data lines, thus potentially corrupting the data. \subsubsection{Variants of Uuencoding} There are many variations of the above rules which must be taken into account in a decoder program. Here are the most frequent: \begin{itemize} \item Many old encoders do not pay attention to the special rule of encoding the 0 value, and encode it into a space character instead of the ``\,`\,'' character. This is not an ``error,'' but rather a potential problem when mailing or posting the file. \item Some encoders add a 62nd character to each encoded line: sometimes a character looping from ``a'' to ``z'' over and over again. This technique could be used to detect missing lines, but confuses some decoders. \item If the length of the input file is not a multiple of three, some encoders omit the ``unnecessary'' characters at the end of the last data line. \item Sometimes, the ``empty'' data line at the end is omitted, and at other times, the line is just completely empty (without the ``\,`\,''). \end{itemize} There is also some confusion how to properly terminate a line. Most encoders simply use the convention of the local system (DOS encoders using CRLF, Unix encoders using LF, Mac encoders using CR), but with respect to the MIME standard, the encoding library uses CRLF on all systems. This causes a slight problem with some Unix decoders, which look for ``end'' followed directly by LF (as four characters in total). Such programs report ``end not found'', but nevertheless decode the file correctly. \subsubsection{Example} This is what our sample text looks like as uuencoded data: \begin{small} \begin{verbatim} begin 600 test.txt M5&AI #include #include #include int main (int argc, char *argv[]) { UUInitialize (); UULoadFile (argv[1], NULL, 0); UUDecodeFile (UUGetFileListItem (0), NULL); UUCleanUp (); return 0; } uudeview-0.5.20.orig/doc/td-v2.c0000644001167100001440000000172106155632130016175 0ustar cphusers00000000000000#include #include #include #include #include #include int main (int argc, char *argv[]) { uulist *item; int i, res; UUInitialize (); for (i=1; istate & UUFILE_OK) == 0) continue; if ((res = UUDecodeFile (item, NULL)) != UURET_OK) { fprintf (stderr, "error decoding %s: %s\n", (item->filename==NULL)?"oops":item->filename, (res==UURET_IOERR) ? strerror (UUGetOption (UUOPT_ERRNO, NULL, NULL, 0)) : UUstrerror(res)); } else { printf ("successfully decoded '%s'\n", item->filename); } } UUCleanUp (); return 0; } uudeview-0.5.20.orig/doc/td-v3.c0000644001167100001440000000327606155632130016205 0ustar cphusers00000000000000#include #include #include #include #include #include #include void MsgCallBack (void *opaque, char *msg, int level) { fprintf (stderr, "%s\n", msg); } char * FNameFilter (void *opaque, char *fname) { static char dname[13]; char *p1, *p2; int i; if ((p1 = _FP_strrchr (fname, '/')) == NULL) p1 = fname; if ((p2 = _FP_strrchr (p1, '\\')) == NULL) p2 = p1; for (i=0, p1=dname; *p2 && *p2!='.' && i<8; i++) *p1++ = (*p2==' ')?(p2++,'_'):*p2++; while (*p2 && *p2 != '.') p2++; if ((*p1++ = *p2++) == '.') for (i=0; *p2 && *p2!='.' && i<3; i++) *p1++ = (*p2==' ')?(p2++,'_'):*p2++; *p1 = '\0'; return dname; } int main (int argc, char *argv[]) { uulist *item; int i, res; UUInitialize (); UUSetMsgCallback (NULL, MsgCallBack); UUSetFNameFilter (NULL, FNameFilter); for (i=1; istate & UUFILE_OK) == 0) continue; if ((res = UUDecodeFile (item, NULL)) != UURET_OK) { fprintf (stderr, "error decoding %s: %s\n", (item->filename==NULL)?"oops":item->filename, (res==UURET_IOERR) ? strerror (UUGetOption (UUOPT_ERRNO, NULL, NULL, 0)) : UUstrerror(res)); } else { printf ("successfully decoded '%s' as '%s'\n", item->filename, UUFNameFilter (item->filename)); } } UUCleanUp (); return 0; } uudeview-0.5.20.orig/doc/test.txt0000644001167100001440000000025406155632130016615 0ustar cphusers00000000000000This is a test file for illustrating the various encoding methods. Let's make this text longer than 57 bytes to wrap lines with Base64 data, too. Greetings, Frank Pilhofer uudeview-0.5.20.orig/COPYING0000644001167100001440000004312707307472262015401 0ustar cphusers00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. uudeview-0.5.20.orig/HISTORY0000644001167100001440000005574410020740752015426 0ustar cphusers00000000000000# # $Id: HISTORY,v 1.47 2004/03/01 23:06:18 fp Exp $ # PROGRAM HISTORY --------------- (remember that all _dates_ are dd.mm.yyyy) 0.1 (15.06.1994) ----- First release. Took less than a week of coding. Most features should work now. All files I encountered can be decoded properly. Some special cases, however, are still untested. This version was updated two or three times without upgrading the version number because that were just minor changes. 0.2 (23.06.1994) ----- DOS support! After getting some requests for a DOS version, many portions of the code have been completely rewritten so that the file data is not loaded into memory. Instead, just an index is saved. Added +e option to select file extensions. Added +i option to disable user questioning. Some special cases to evaluate the part no. of the subject line added Automatic uncompress / gunzip (need to have them installed) Tar file handling - extract files right out of a tar archive. This is done from uudeview itself, so you won't need an external tar. 0.3 (30.06.1994) ----- Getting smarter every day. After I found some postings with spelling mistakes in the subject line (namely "something.zip" instead of "something.arj"), I began to program "Smart Part Merging System" (SPMS (R)). It detects that the parts of "something.zip" are just the missing parts of "something.arj" and merges both files. This feature will still need a lot of maintenance, since there are a lot of special cases. Added a ton of features. Now you can list the files or enter commands to do anything with them (you can enter "xv $") to watch the file. Installed a signal handler for SIGINT (Ctrl-C). If the program was interrupted by the user, it left LOTS of temporary files in /usr/tmp. They will now be cleaned. Again, the user interface was changed. I did that in 0.2, so why not again in 0.3. I hope you'll agree it's a bit better now. The program now checks if gunzip has failed (it tests if the resulting file has less than 2 bytes). Fixed a bug with filenames that contained spaces at the end. Linked files in tar archives are now ignored. In 0.2 each file was decoded before the user was prompted what to do. This was quite slow on some machines. Now the files are only decoded on request. 0.3.42 -------- I'm quite lazy with documenting all the changes I made to the source code. I hope I will keep online this time. To do this, I have invented the patch- level number. Since I have made a lot of changes to the original 0.3 release, I start with patchlevel 42. 0.3.43 -------- - gets suspicious if it finds multiple begins/ends within the same post and opens up a new file record - Treats "BEGIN -- CUT HERE" line exceptionally, because it frequently looks like valid uuencoded data and fooled the program. The 4-line-safety barrier didn't catch because the real data followed immediately. 0.3.44 (25.01.1995) -------- - added lots of patches to allow for Mime Base64 decoding ... mostly because I want to decode this Lion King MPEG from alt.binaries.multimedia 0.3.45 (29.01.1995) -------- - added XX decoding scheme. Was really simple after having to change every- thing for the above MIME stuff anyway. Just another decoding table. Hope it works. 0.3.46 (01.02.1995) -------- - included groundworks for desperate mode. I don't know -- should I leave the '-d' command line option out? 0.3.47 (03.02.1995) -------- - written my own more function. previously, I just called system(), but this was (a) unstable and (b) didn't work in QuickWin - included '(i)' action to show file info; either part 0, or part 1 up to the begin line - desperate mode finished. Moved the original '-d' (decompress) option to '-x' (didn't use it anyway, and needs major rewriting) and replaced it with new desperate option 0.3.48 (04.02.1995) -------- - wrote an case-insensitive string compare function. Have migrated the extension detection to case-insensitivity - added some code to detect some common file suffixes (jpg, gif etc.) added SPMS check: parts of files will not be merged if they have different but correct suffixes (if one of the files' suffix is not recognized, it might just be spelled wrong, so this doesn't prevent merging). This should stop SMPS from merging together complete junk. - generalized Unix Makefile. Now I only have to change a version number in one place (well in three places if I consider DOS&Windows with other make files). - added multiple passes to SMPS. In first pass, only "exact fits" are merged, in second pass only files with minimal differences, in third pass, everything - stripping some boring headers in file (i)nfo - now it should also accept files with less than 4 lines of data - finally found the 'bug' that declared some final lines as invalid -- the encoder has stripped unnecessary chars. Added more checks ... 0.4 (06.02.1995) ----- - After getting no bugreports for a few weeks (either nobody uses the program or it does work after all), I renamed 0.3.48 to 0.4. There is so much dif- ferent from the original 0.3 that I simply need to indicate these changes to users. And besides, it's my birthday :-) - Deleted "ALPHA" indication from the windows version. Now fully integrated. - moved MIME check in front of UUdata check. Strongest semantics first. 0.4.1 (08.02.1995) ------- - Added additional check for a part number on the subject line: "test.gif 3 of 4" was detected to be 4, now done correctly. 0.4.2 (10.02.1995) ------- - bugfixed uudeview.c:IsKnownExtension() which would core dump on some systems due to NULL read access. Thanks to J. Wilkinson, for pointing out the problem. This isn't fatal for DOS, and also shouldn't be fatal in Windows. 0.4.3 (14.02.1995) ------- - some people couldn't compile the Unix version because I used two non-standard string functions, strrstr() and strdup(). Thought they were defined everywhere. Now I've written them on my own. - moved _FP_strnicmp() to uuutil.c 0.4.4 (24.02.1995) ------- - trimmed comments in header files because some compilers warned about "nested comments" - fixed annoying bug in CheckGlobalList() that caused infinite loops and may also have caused core dumps if more than 98 parts were missing from a posting - added another clause to the detection of a part number on the subject line after getting a file by the name of abc-1019.gif, where a part num- ber of 1019 was detected 0.4.5 (02.03.1995) ------- - Added workaround for Netscape, which completely messes up encoded data on some setups. It replaces &,<,> by their html equivalents and occasio- nally inserts some junk HREF links. Now whenever an invalid line is found, it is NetscapeCollapse()d, in the hope it's decodeable afterwards. 0.4.6 (11.04.1995) ------- - wow, I just see that it's been a long time since the last bugfix. I guess it is indeed getting better :-) - UUdeview would ignore files with double-spacing (one line of data followed by an empty line). Now, all empty lines are ignored. I just hope this doesn't add problems elsewhere. Thanks to Gary for this one. - a slight bug in the Base64 detection made the program fail to pick up the destination filename when quoted 0.4.7 (07.05.1995) ------- - the mime detection was looking for the "Content-Type" message. Now, this tag is accepted case-insensitive. - if no trailing lines were at the end of a Base64-encoded file, some data was written twice, resulting in trailing garbage data. 0.4.8 (22.05.1995) ------- - all string compares are now case insensitive, especially because I found mime headers in all kinds of variations - small bug fixed that caused uudeview to ignore some files where the first part didn't have encoded data - included checking if files exist, prompting the user whether it shall be overwritten. suggested and coded by Kevin B. York - new: the encoding engine! incorprorated into the launcher in Windows, for Dos/Unix, it's in the external 'uuenview' program. 0.4.9 (07.06.1995) ------- - allows an 'end' after the encoded data with only an _empty_ line inbetween. Previously, I expected a valid encoded line with zero data, meaning that the single character on that line is '`' (UUE) or '+' (XXE) 0.4.10 (14.06.1995) -------- - funny bug fixed: if the decoder found a valid UUencoded line in a supposed MIME-data file, it decoded the single line and exited. In my case, a MIME header triggered this. - fixed bug with more than one MIME-encoded file in a single message. - serious bug fixed when overwriting an existing file: I had forgot- ten O_TRUNC when opening the file, causing some undefined behavior. 0.4.11 (16.06.1995) -------- - renamed all variables 'this' and 'new', as some C++ compilers don't like using these keywords as names - renamed the variable 'inpfile' in uudeview.c:more(); I had a type of the same name (ec@matufia.sp.TRW.COM) 0.4.12 () -------- - more smartness (although I now can't remember where, probably everywhere) - fixed problem with multiple MIME attachments in a single mail - can now decode news articles from lynx, which were messed up similar to Netscape news files, only worse. - one appearance of strdup() in uuio.c slipped through. Now replaced by _FP_strdup() - Instead of having to choose to rename or overwrite existing files each time, you can now enter 'a' once to overwrite them all. - The Ultrix C compiler ignored hex escape sequences, which were used in uuenview.c for CRLF. Now they're in octal. - not so picky if the last line is longer than expected. some encoders (more than one!) failed to let the last line end where it was supposed to end. - complete rewrite of uuenview. It can now email and post files direcly. For the purpose of posting, a mini inews program, written by Steven Grady, , is included in the distribution - finally: manual pages! And make install works as well as make install.man! Thanks to all the people who have been bothering me for months :) - uudeview and uuenview can now behave similar to uudecode and uuencode if called like that (ln -s uudeview uudecode). Of course, you don't loose any smartness. My ultimate goal is to replace these outdated tools. - attempt to enforce stronger subject-line semantics. uuenview prints the part numbers in brackets (partno/numparts) and the file name in hard brackets [ filename.tar.gz ], and this is what the decoder looks for first. 0.4.13 (20.10.1995) -------- - after sending out so many 'beta' versions of 0.4.12 and being asked whether there's a new one available, I've decided to skip an official 0.4.12. - Scan speed greatly improved. And if you're sure you only have one article per file, you can use the undocumented "-f" option for even more speed. But then everything becomes quite unsafe, as incomplete files are only detected when decoding. - don't ignore RETries - reworked most documentation, and rearranged the rest. All packages now only include the documentation the reader really needs - Win version includes a new version of the Launcher, compiled with the new encoding routines, and also remembering its screen position and size - Oops, the Netscape repair code was partially broken and needed some repair itself. - xxdecoding was broken because of over-tolerant uudecoding - uudecoding was broken because of over-tolerant uudecoding :( 0.4.15 (20.01.1996) -------- - Implemented my own version of fgets() that allows to transparently read lines terminated either with LF (Unix), CRLF (DOS) or CR (Mac). Sadly, it's slower than the original. - in previous versions, I have very much relaxed the checking for uudecoded lines (valid_data()). Now I only allow the less strong code (meaning, allow the data look more weird, more off the specs) if I'm sure it actually _is_ uuencoded data. This should work in all cases because it was usually only the last line with was "erroneous" - included option '-b' to let part numbers in [] take precedence over () this only affects the kind of brackets uudeview looks to find a part number _first_ - fixed problems with multiple MIME attachments - got rid of the 'Ignore Replies' switch. It caused lots of confusion and didn't really help anything. - included option '-f' for fast scanning. Only works if each input file contains at most one article. Many sanity checks cannot be performed because much less data is gathered, thus many invalid files may get processed. - added e(x)tract command; but (d)ecode stays default. 0.4.16 (21.01.1996) -------- - a tiny typo, which was introduced for debugging purposes but not removed, broke 0.4.15. This was especially problematic for the Windows version. 0.4.17 (09.02.1996) -------- - once again a stupid 16 bit problem introduced in 0.4.15. In uunconc.c: uunconc(), the variable pppos, used to remember the file position, was declared as int. Because of this, on 16 bit systems, it looped over and over, but the file pointer never reached maxpos :-( This patchlevel was only released as uudv[dw]04h but not as Unix version because 32 or 64 bit systems weren't affected. 0.4.18 (not publicly released) -------- - this is an intermediate beta test version. With all the changes going on, I expect everything to settle into a 0.5 release sooner or later. - got rid of some bugs - Base64-encoded lines can now have arbitrary length (not limited to multiples of four) - support for BinHex decoding added. No encoder yet. - complete re-layout of the code. All the encoding/decoding stuff has been moved into a seperate, system-independent library, while the enveloping standalone programs uuencode and uudecode are just front- ends to this library. - another front-end has been added, uutcl, which makes the library functions available to Tcl/Tk programs - A Tcl/Tk script, xdeview, uses these functions and provides a graphical frontend - support for decompressing and tar files has been removed. They didn't work reliably, and aren't the job of a decoder anyway. - BinHex and Base64 lines may have space characters at the end of the line 0.4.19 (not publicly released) -------- - More changes everywhere. Fixed another problem with Base64 files. - Improvements everywhere :) - Added progress meter to the decoder 0.5.0 (07.06.1996) ------- - Well, thought I have to release the stuff sooner or later. - Fed the code into CVS for better revision control. 0.5.1 (10.06.1996) ------- - Fixed problem with multiple tiny Base64 files in a single message. 0.5.2 (15.06.1996) ------- - Cleaned up some code; now using size_t parameters for fread() and fwrite() and such. - Fixed problem with short BinHex files. - Use the initial and trailing colon `:' of BinHex files as `begin' and `end' markers. - Only encode to message/partial embedded messages if we really have more than one part; otherwise encode directly to toplevel MIME body. 0.5.3 (23.06.1996) ------- - Complete rewrite of the scanning routines, which have been moved to uuscan.c and grown into the largest chunks of code. - Mime files are properly treated with a pretty complete Mime par- ser. Outside of Mime messages, the scanner falls back to the old behaviour. - Offers to `decode' plain text (and quoted-printable text) files with -t option. - Intermediate preview release. 0.5.4 (21.07.1996) ------- - Rewrote encoding functions. The system-dependent stuff has moved to the outside of the library. - Minor changes not affecting the frontend. 0.5.5 (21.08.1996) ------- - Bugfixes: - Sometimes, the file pointer wasn't properly rewound to the beginning of the headers after bumping into them. - The Binhex RLE decompressor produced garbage with repetition counts greater than 127 (which were expanded into negative integers) - Stripping the last CRLF of a plain-text message was fatal if the piece was really an unhandled message/multipart part. 0.5.6 (28.08.1996) ------- - The Mime-Id buffer in uuencode.c:UUE_PrepPartial() was too small, causing it to be partially overwritten - Added code to read part number and file name from UUEnview-Style headers. Especially important for filename detection with pure Base64. I consider this an ugly hack, but users call for it. 0.5.7 (04.09.1996) ------- - Added "attach" option to uuenview: read a msg from stdin and attach one or more files using proper MIME multipart/mixed style. - Fixed configure script: we might need $x_includes for - Fixed rules for "make install" 0.5.8 (13.09.1996) ------- - Fixed output filename when encoding dotfiles - Fixed uudecode compatibilty mode (would crash when reading stdin) - Fixed bug with long header lines (was actually a bug in _FP_strncpy) - Fixed bug when mailing directly from uuenview. The recipient address length must be added when composing the command. - Added configure options --enable-sendmail and --enable-inews 0.5.9 (29.09.1996) ------- - Fixed percentage display for >20Meg files on 32bit systems, where 100*fsize becomes > MAXINT ... - Fixed problem with "--- cut here ---" lines that were misinterpreted as MIME boundaries. - A user tried to decode a file with an early truncated MIME message and another message later with the same boundary. Consequently, all data inbetween was ignored. Added check for a Content-Type with the same boundary when scanning a subpart. - Allow to specify more dumbness on UUDeview's command line to ignore subjects as well as part numbers. Fixed a problem with dumb mode as well. 0.5.10 (01.10.1996) -------- - Plugged memory leak in uucheck.c:PreProcessPart() 0.5.11 (03.10.1996) -------- - Added workaround for broken uuencoded files sent from MS Exchange. 0.5.12 (23.12.1996) -------- - Fixed bug with aborted decoding runs that the tempfile was deleted, but UUFILE_TMPFILE was still set. - Make uudeview return a more or less sensible return value: 0 if all files were decoded successfully, 99 for miscellaneous errors, 2 if all files failed to decode, or 3 if some files were decoded okay and others failed. - Added -n option to uudeview to not print progress bars. - You can now set global options for UUDeview in the UUDEVIEW environ- ment variable. Options set there may be overrridden on the command line. - Some tweaking to make some troublesome input files (for example with interleaved blank lines) decode. - Fixed bug that caused erroneously decoded data when UUencoded data looked like Base64 (because of the overlapping alphabet) 0.5.13 (09.01.1997) -------- - Fixed bug in uuscan.c. - Fixed another bug in uuscan.c which happened when a filename on the Content-Type line happened to contain a header keyword. - Fixed infinite loop when trying to descramble Netscape data; in one place we were looking for 8.0 - Do not use "dangerous" gets in minews, replace by fgets - If the file looks like MIME, be more strict when scanning "text/*" parts for encoded data. - Add +o option to never overwrite files (useful in non-interactive mode) - Add -c option to autoclear input files from which anything was decoded. Use with care - UUDeview does not care about anything else in that file. - Add -z option for improved MIME compliance on MIME messages. - Improved encoding detection, it should now be less sensitive to data that looks both like uu and Base 64. - Add -r (Reply-To:) and -f (From:) options to uuenview - Support encoding as quoted-printable - Support "encoding" as plain text - Add -t and -q options to uuenview for that - Make the encoding to be used depend on the last -ubxtq option, so that you can send plain text and binary attachments on the same command line. - Make uuenview read the $UUENVIEW command line option - Tag attachments as "text/plain" if plain text or quoted printable is used and no other mime type is appropriate. - Recognize a boundary when scanning a file in "freestyle" mode. This is similar to the AOL handling above. 0.5.16 (26.08.2001) -------- - fix handling of "x-uue" encoded MIME attachments - bug fix for file renaming 0.5.17 (06.03.2002) -------- - fix handling of quoted parameters - some support for yEnc encoding 0.5.18 (02.04.2002) -------- - fix for yEnc files in UUInfoFile - patch by Matthew Mueller: - add CRC generation and checks for yEnc - accept yEnc files where the tab character is not escaped - improved error checking for yEnc files 0.5.19 (07.10.2003) -------- - UUDeview: check validity of save path upon 'p' (in interactive mode) (Chris Hanson) - patches by Matthew Mueller: - check return code of fclose() after writing target file to detect e.g. disk full errors - check for errors reading the input file - Get suspicious about potentially uuencoded data if the line length varies - write incomplete files, hoping for some block-level recovery - Add a UULoadFileWithPartNo function, in case a user of this library is certain of the part number and doesn't need to trust UUDeview's heuristics. - fix a bug in the historic Netscape fixing code, which probably should be removed altogether sometime anyway (see log for 0.4.5 above) (Michael Newcomb) - UUDeview: Add an alternative autorenamer that adds a unique sequence number before the first dot, keeping the extension intact - UUDeview: If the filename is "." or "..", replace the first dot with an underscore to not conflict with the directory names - finally implemented RFC 1522 header decoding. The charset is ignored, though - fix some problems with decoding message/partial messages - In violation of RFC 1521, allow the [;] characters in a token. The Klez virus does that, and people who feed their virus scanners with the output from UUDeview would like to catch it. - UUDeview: replace some questionable punctuation characters in filenames with underscores. The current list is {<|">} - Stop tinkering with CFLAGS in ./configure; remove --disable-optimize. Use 'CFLAGS=-O ./configure' for non-debug builds. 0.5.20 (01.03.2004) -------- - Stop tinkering with CFLAGS in ./uulib/configure - fix bug in inews/inews.c: fgets doesn't discard the final newline (Yuri D'Elia) - fix bug in parsing of header lines - fix fgets to accept lines that are exactly of the maximum length - fix two buffer overflows uudeview-0.5.20.orig/IAFA-PACKAGE0000644001167100001440000000104010020740752015772 0ustar cphusers00000000000000Title: UUDeview, the nice and friendly decoder Version: 0.5.20 Description: Smart multi-file multi-part decoder for UUencoded, XXencoded, Base64 and BinHex encoded files. Includes a similarly powerful encoder as well. Author: Frank Pilhofer Maintained-by: Frank Pilhofer Maintained-at: http://www.fpx.de/fp/Software/UUDeview/ Platforms: Unix, Windows command line, ANSI/ISO C Copying-Policy: Freely Redistributable (GPL) Keywords: uudeview, uuenview, uudecode, decoding, MIME, xxdecode, uuencode, Base64, BinHex uudeview-0.5.20.orig/INSTALL0000644001167100001440000002443107310162305015360 0ustar cphusers00000000000000 _________________________________________________________________ Installing UUDeview for Unix The Nice and Friendly Decoder The first step, of course, is to get a copy of the source code to your hard disk. If you have not already done so, go back to the UUDeview home page at http://www.fpx.de/fp/Software/UUDeview/ and download a copy. UUDeview for Unix is available in two flavors, and there are separate installation instructions for both. * Installation instructions for the .tar.gz version * Installation instructions for the Self-Installing version. _________________________________________________________________ Installation Instructions for the .tar.gz Version _________________________________________________________________ There are four steps in order to install UUDeview for Unix. 1. Extraction of the source files. 2. Configuration. 3. Compilation. 4. Installation. If you're too lazy to type in all these commands yourself, you might want to download the Self-Installing Archive (go back to the previous page in order to download it). With that version, all you have to do is download ... and execute it! Extraction As Unix user, you should be familiar with the utilities gunzip and tar (if not, ask a friend). This step is pretty simple and straightforward. First, uncompress the source code, then unpack the archive using the two commands gunzip uudeview-n.tar.gz tar xvf uudeview-n.tar Insert UUDeview's current version number for n. If you get any errors here, the archive you've downloaded was probably corrupt. Otherwise, you should see a new subdirectory with plenty of files within it. Change to this subdirectory now, using cd uudeview-n Configuration UUDeview comes with an autoconf configuration script, which will usually set all the necessary options for your system automatically. You can invoke this script by entering ./configure However, there are some options this script can't guess, which you might have to set manually by passing parameters to the configuration script. You can receive a complete list of options with the --help parameter. Don't be overwhelmed by them, usually you won't need one of them. Here's a description of the more important options: --prefix=DIR Sets the base path where the binaries and manual pages will be installed to. Biaries will go to DIR/bin, and manuals to DIR/man. The default location is /usr/local. If you just want to keep the files in your own directories, use --prefix=$HOME. You can also set the binary and manual paths separately using --bindir and --mandir. --enable-tcl=DIR Use this option if you have Tcl installed in a non-standard location. We will need the Tcl include file in DIR/include and the Tcl library libtcl*.a in DIR/lib. --enable-tk=DIR Same for your Tk installation. --disable-tcl Use if you don't want support for the Tcl/Tk extensions. The frontend will not be built or installed. --disable-manuals If you don't want to the manual pages to be installed. --enable-sendmail=PROG Use PROG to mail messages to the internet. The program is given a list of white-space separated recipients on the command line and is fed the mail message, including headers, via standard input. One use of this option is to define a program doing certain preprocessing on the message before handing it over to the mail system. If this option is not used, the configuration script does try to locate certain common mail agents by itself, with sendmail being the first choice. You can also use --disable-sendmail to disable the mail sending facility altogether. --enable-inews=PROG Use PROG to post articles to the usenet. The program is given the parameter "-h" on the command line and is fed the article, including headers, via standard input. (The -h option usually instructs inews to honor the message's headers.) One use of this option is to define a program doing certain preprocessing on the article before handing it over to the news system. If this option is not used, the configuration script tries to locate the inews program, or configures itself to compile and use the replacement mini-inews. You can also use --disable-inews to disable the message posting facility altogether. --disable-minews If there's no news system installed on your site, a replacement inews, which is capable of posting files to a newsgroup, will be installed. Use this option if you don't want this program to be installed, or if it fails to compile (it's not quite as portable as the rest of the code). --enable-posting=server If using our replacement inews, we must have the address of a server we can route our postings to. With this option, you can specify the hostname or IP address of such a news serving host. You can always override this setting at runtime by setting the NNTPSERVER environment variable. --enable-domain=domainname If using our replacement inews, we need the name of a domain to identify ourselves. The configuration script knows of some means where to get your site's domain name from. If these tests fail, you should set the name with this parameter (otherwise, a bogus name will be configured). Note that the name of your domain does not include the hostname. The configuration script is also sensitive to a couple of environment variables. The most important ones are CC The C compiler to use. CPPFLAGS Flags to pass to the C preprocessor. CFLAGS Flags to pass to the C compiler. LDFLAGS Flags to pass to the compiler when linking. LIBS Additional libraries. You should have a look at the messages the run of ./configure generates. If you believe there's something wrong with them, you'll probably need one of the above options to correct it. Compilation This step should be a piece of cake. Just issue the following command: make This should compile everything. In the unlikely event of compiler errors, you will probably have to add some options on the call to ./configure above. Installation Installation should be just as simple as compilation. If you chose to install the programs in a system-wide directory (rather than your home directory), make sure you run the following command as root. make install This copies the binaries and manual pages to their final locations. You should now test the installation by invoking uudeview and uuenview. Both should print a short description of their command-line options. If it works, congratulations, you have successfully installed the UUDeview package. You can now go on and test whether mailing and posting from uuenview works, preferredly by emailing a file to yourself and posting to local test newsgroups. Optionally, you may also try to use the compatibility features of both uudeview and uuenview by symlinking uuencode to uuenview and uudecode to uudeview. Called like that, both tools will try to mimic their predecessors' behaviour (but of couse being much smarter). _________________________________________________________________ Installation Instructions for the SFX Version _________________________________________________________________ You can start the installation process by running sh uudeview-sfx-n.sh Insert UUDeview's current version number for n. The auto-installer will then prompt you for several installation options. Sensible defaults are provided, so that you can try to just hit return upon each prompt. These prompts are: Installation Prefix The base directory for installing UUDeview's files. Programs will be installed into the bin subdirectory, manual pages into the man subdirectory. If you are running the script from a normal user account, the default will be to install UUDeview into your home directory. The programs will therefore be in $HOME/bin. If you are running the script as superuser (root), the default installation prefix will be /usr/local Do you want manual pages You can choose to install manual pages (this is the default), or not to install them by entering "n". Add Tcl support if possible Add Tk support if possible If Tcl/Tk is available, UUDeview will add support for the graphical frontend, xdeview. The default is to check whether Tcl/Tk is available in an appropriate version. You can disable this check (therefore disabling the frontent) by answering "n". On both prompts, you can also give directories where to look for the Tcl/Tk files. Your domain If you intend to post directly from UUEnview to usenet newsgroups, you should enter your domain name here, else users will not be able to reply to your postings. After answering these questions, the auto-installer will prompt you before building and installing UUDeview, so that you can interrupt the process at any time. Afterwards, you will have installed the UUDeview package successfully. You can now go on and test whether mailing and posting from uuenview works, preferredly by emailing a file to yourself and posting to local test newsgroups. _________________________________________________________________ Frank Pilhofer Back to the Homepage Last modified: Wed Jun 6 20:33:04 2001 uudeview-0.5.20.orig/Makefile.in0000644001167100001440000001244007646123022016376 0ustar cphusers00000000000000# # # ============================================================================ # # This is the Makefile for the uudeview package, including the uudeview # decoding, the uuenview encoding program, and a mini-inews that can be # used by uuencode to post directly to the usenet. # The values here were guessed by ./configure and are probably correct. # fp@informatik.uni-frankfurt.de # # Usefull targets # all Compile the package # install Install the binaries and manual pages # clean Deletes the binaries and objects and all the # other dirty stuff. # tar Packages everything neatly into a tar.gz file # for distribution. # # ============================================================================ # # $Id: Makefile.in,v 1.12 2003/04/12 23:49:38 fp Exp $ # # your make might need this # SHELL = /bin/sh # # Source and Installation Paths # prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = @srcdir@ # # Where you want the binaries and the manual pages installed # bindir = @bindir@ mandir = @mandir@ BINDIR = $(bindir) MANDIR = $(mandir) # # install program. use our own, as AC_PROG_INSTALL doesn't work reliably # INSTALL = @srcdir@/install-sh INSTALL_PROGRAM = ${INSTALL} -c INSTALL_DATA = ${INSTALL} -c -m 644 # # If you don't have the GNU C compiler installed, set CC=cc here # CC = @CC@ # # C Compiler Options # CFLAGS = @CFLAGS@ -I@srcdir@ @CPPFLAGS@ @DEFS@ # # Libraries to link and their paths # LIBS = @LDFLAGS@ @LIBS@ # # the ranlib program # RANLIB = @RANLIB@ # # how to link files # LN = @LN_S@ # # shared library stuff, if available. not yet active. i first need to # find someone who can really explain this to me. # SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ SHLIB_VERSION = @SHLIB_VERSION@ # ############################################################################### # You shouldn't have to change anything below. ############################################################################### # # Programs to compile, Manpages to install and Versions # PROGS = @PROGS@ DOINST = @DOINST@ MPAGES = @MPAGES@ # VERSION = @VERSION@ PATCH = @PATCH@ # @SET_MAKE@ # # make stuff # .SUFFIXES: .SUFFIXES: .c .o all: $(PROGS) clean: -(cd uulib ; $(MAKE) clean) -(cd unix ; $(MAKE) clean) -(cd tcl ; $(MAKE) clean) -(cd inews ; $(MAKE) clobber) rm -f uudeview uuenview minews [Xx]deview gif2gfp rm -f *.o *.a *.so core *~ TAGS distclean: clean -(cd uulib ; $(MAKE) distclean) -(cd unix ; $(MAKE) distclean) -(cd tcl ; $(MAKE) distclean) -if test -d doc ; then (cd doc ; $(MAKE) distclean) ; fi rm -f config.status config.cache config.log rm -f uulib/config.h uulib/Makefile rm -f unix/config.h unix/Makefile rm -f tcl/config.h tcl/Makefile rm -f Makefile config.h rm -f uudeview-*tar* uudeview-sfx* realclean: distclean new: clean rm -f uudeview uuenview [Xx]deview $(MAKE) all dist: tar mv uudeview-$(VERSION).$(PATCH).tar.gz ../dist/ chmod 644 ../dist/uudeview-$(VERSION).$(PATCH).tar.gz tar: test -r ./Makefile test "x`/bin/hostname`" = "xrose" test ! -r uudeview-$(VERSION).$(PATCH) mkdir foo (cd foo ; \ cvs export -r release-`echo $(VERSION).$(PATCH) | sed -e 's/\\./-/g'` \ -d uudeview-$(VERSION).$(PATCH) uudeview) rm -rf foo/uudeview-$(VERSION).$(PATCH)/temp (cd foo ; \ tar cf ../uudeview-$(VERSION).$(PATCH).tar uudeview-$(VERSION).$(PATCH)) gzip -9 uudeview-$(VERSION).$(PATCH).tar chmod 644 uudeview-$(VERSION).$(PATCH).tar.gz rm -rf foo sfx: if test ! -r uudeview-$(VERSION).$(PATCH).tar.gz ; then \ $(MAKE) tar ; \ fi rm -f uudeview-sfx* dd if=wrapper.sh of=uudeview-sfx-$(VERSION).$(PATCH).sh bs=1k count=12 cat uudeview-$(VERSION).$(PATCH).tar.gz >> uudeview-sfx-$(VERSION).$(PATCH).sh chmod 755 uudeview-sfx* patch: if test "x$(V)" = "x" ; then \ echo usage: $(MAKE) patch V=0.1.2 ; \ exit 1 ; \ fi cvs export -r release-`echo $(V) | sed -e 's/\\./-/g'` \ -d uudeview-$(V) uudeview cvs export -r release-`echo $(VERSION).$(PATCH) | sed -e 's/\\./-/g'` \ -d uudeview-$(VERSION).$(PATCH) uudeview rm -rf uudeview-$(V)/temp rm -rf uudeview-$(VERSION).$(PATCH)/temp diff -u -r -N uudeview-$(V) uudeview-$(VERSION).$(PATCH) \ | gzip -9c > uudeview-$(V)-$(VERSION).$(PATCH).diff.gz rm -rf uudeview-$(V) rm -rf uudeview-$(VERSION).$(PATCH) chmod 644 uudeview-$(V)-$(VERSION).$(PATCH).diff.gz uudeview: unix/config.h libuu.a (cd unix ; $(MAKE)) xdeview: tcl/config.h libuu.a (cd tcl ; $(MAKE)) libuu.a: uulib/config.h (cd uulib ; $(MAKE)) minews: (cd inews; $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS)' LIBS='$(LIBS)' ) doc: (cd doc; $(MAKE) ps) install: $(DOINST) -for d in $(MPAGES) ; do \ $(INSTALL_DATA) $(srcdir)/man/$$d $(MANDIR)/man1/$$d ; \ done install-uudeview: uudeview for d in uudeview uuenview ; do \ $(INSTALL_PROGRAM) unix/$$d $(BINDIR)/$$d ; \ done install-tcl: xdeview for d in xdeview uuwish ; do \ $(INSTALL_PROGRAM) tcl/$$d $(BINDIR)/$$d ; \ done install-minews: minews for d in minews ; do \ $(INSTALL_PROGRAM) inews/$$d $(BINDIR)/$$d ; \ done links: tcl/config.h unix/config.h uulib/config.h tcl/config.h: config.h (cd tcl; rm -f config.h ; $(LN) ../config.h config.h) unix/config.h: config.h (cd unix; rm -f config.h ; $(LN) ../config.h config.h) uulib/config.h: config.h (cd uulib; rm -f config.h ; $(LN) ../config.h config.h) uudeview-0.5.20.orig/README0000644001167100001440000000472510020740752015213 0ustar cphusers00000000000000 UUDEVIEW FOR UNIX Version 0.5.20 Welcome to UUDeview, a package of a very smart decoder and an encoder for Base64 (MIME), uuencoded, xxencoded and Binhex files. Its ultimate goal is to fully replace the "standard", but dumb uudecode and uuencode utilities. Introduction If you're into emailing and reading news, you have already learned how difficult it is to distribute or receive binary files by this means. You will have noticed that you must frequently edit files before decoding them, and make sure they're in the right order. Here's a tool to free you of these permanent bothers. The package features a smart decoder, UUDeview, which allows for comfortable decoding of about anything you feed into it. It reads in a bunch of files, sorts the individual postings or emails and lets you choose which files to decode. You will also find the equally helpful UUEnview, which not only encodes binaries for sending, but automatically sends them, too. The decoder supports the four encoding methods uuencoding, xxencoding, Base64 (from the MIME standard) and BinHex, the encoder can encode to all of them except to BinHex. When encoding, you can choose the method with a command-line option, and the decoder auto-detects all of them. The frontend programs are built around a powerful decoding library, which can be easily integrated into other applications as well. You can find LaTeX documentation in the doc/ subdirectory, Postscript and HTML-formatted files can be requested from the author (email only). For more information, check out the UUDeview homepage on the WWW at http://www.fpx.de/fp/Software/UUDeview/ Also read ... INSTALL Installation Manual. Describes in detail how to configure and install the package. COPYING UUDeview is distributed under the terms of the GNU Library General Public License (GPL). Credits This piece of software wouldn't be what it is today without the help, encouragement, suggestions and bugreports from a number of people. I especially want to thank Michael Newcomb, Nico Mak, Stephane Barizien, Kris Karas and Joachim Meyn for their support. My apologies to the people I forgot to mention. _________________________________________________________________ Frank Pilhofer uudeview-0.5.20.orig/acconfig.h0000644001167100001440000000456006155632121016256 0ustar cphusers00000000000000 /* * needed for auto configuration * $Id: acconfig.h,v 1.1.1.1 1996/06/06 19:41:05 fp Exp $ */ /* * If your system is kinda special */ #undef SYSTEM_DOS #undef SYSTEM_QUICKWIN #undef SYSTEM_WINDLL #undef SYSTEM_OS2 /* * If your system has stdin/stdout/stderr */ #undef HAVE_STDIO /* * how to declare functions that are exported from the UU library */ #undef UUEXPORT /* * how to declare functions that are exported from the UUTCL library */ #undef UUTCLEXPORT /* * how to declare functions that are exported from the fptools library */ #undef TOOLEXPORT /* * how to declare functions that are interfaced with TCL */ #undef UUTCLFUNC /* * define if your compiler supports function prototypes */ #undef PROTOTYPES /* * define if you have TCL version 7.5 or later */ #undef HAVE_TCL /* * define if you HAVE_TCL and TK version 4.1 or later */ #undef HAVE_TK /* * define if your Tk can handle the Tk_CreatePhotoImageFormat hook */ #undef TK_PHOTO /* * define if Tcl_Main or Tk_Main needs Tcl_AppInit as third parameter */ #undef TMAIN_THREE /* * Replacement functions. * #define strerror _FP_strerror * #define tempnam _FP_tempnam * if you don't have these functions */ #undef strerror #undef tempnam /* * your system's directory separator (usually "/") */ #undef DIRSEPARATOR /* * your mailing program. full path and the necessary parameters. * the recepient address is added to the command line (with a leading * space) without any further options */ #undef PROG_MAILER /* * define if the mailer needs to have the subject set on the command * line with -s "Subject". Preferredly, we send the subject as a header. */ #undef MAILER_NEEDS_SUBJECT /* * define if posting is enabled. Do not edit. */ #undef HAVE_NEWS /* * your local news posting program. full path and parameters, so that * the article and all its headers are read from stdin */ #undef PROG_INEWS /* * the name of your local domain. only needed when using minews */ #undef DOMAINNAME /* * your local NNTP news server. only needed when using minews * can be overridden by $NNTPSERVER at runtime */ #undef NNTPSERVER /* * defined when we use minews, so that we know that we must define * the NNTPSERVER environment variable to be able to post */ #undef NEED_NNTPSERVER /* * whether you want to hide your hostname behind the domain. usually * undefined */ #undef HIDDENNET uudeview-0.5.20.orig/aclocal.m40000644001167100001440000001471407736140711016203 0ustar cphusers00000000000000dnl dnl originally from ncftp 2.3.0 dnl added wi_EXTRA_PDIR and wi_ANSI_C dnl $Id: aclocal.m4,v 1.2 2003/09/29 23:35:37 fp Exp $ dnl AC_DEFUN(wi_EXTRA_IDIR, [ incdir="$1" if test -r $incdir ; then case "$CPPFLAGS" in *-I${incdir}*) # echo " + already had $incdir" 1>&6 ;; *) if test "$CPPFLAGS" = "" ; then CPPFLAGS="-I$incdir" else CPPFLAGS="$CPPFLAGS -I$incdir" fi echo " + found $incdir" 1>&6 ;; esac fi ]) dnl dnl dnl dnl AC_DEFUN(wi_EXTRA_LDIR, [ libdir="$1" if test -r $libdir ; then case "$LDFLAGS" in *-L${libdir}*) # echo " + already had $libdir" 1>&6 ;; *) if test "$LDFLAGS" = "" ; then LDFLAGS="-L$libdir" else LDFLAGS="$LDFLAGS -L$libdir" fi echo " + found $libdir" 1>&6 ;; esac fi ]) dnl dnl __FP__ dnl dnl AC_DEFUN(wi_EXTRA_PDIR, [ progdir="$1" if test -r $progdir ; then case "$PATH" in *:${progdir}*) # echo " + already had $progdir" 1>&6 ;; *${progdir}:*) # echo " + already had $progdir" 1>&6 ;; *) if test "$PATH" = "" ; then PATH="$progdir" else PATH="$PATH:$progdir" fi echo " + found $progdir" 1>&6 ;; esac fi ]) dnl dnl dnl If you want to also look for include and lib subdirectories in the dnl $HOME tree, you supply "yes" as the first argument to this macro. dnl dnl If you want to look for subdirectories in include/lib directories, dnl you pass the names in argument 3, otherwise pass a dash. dnl AC_DEFUN(wi_EXTRA_DIRS, [echo "checking for extra include and lib directories..." 1>&6 ifelse([$1], yes, [dnl b1=`cd .. ; pwd` b2=`cd ../.. ; pwd` exdirs="$HOME $j $b1 $b2 $prefix $2" ],[dnl exdirs="$prefix $2" ]) subexdirs="$3" if test "$subexdirs" = "" ; then subexdirs="-" fi for subexdir in $subexdirs ; do if test "$subexdir" = "-" ; then subexdir="" else subexdir="/$subexdir" fi for exdir in $exdirs ; do if test "$exdir" != "/usr" || test "$subexdir" != ""; then incdir="${exdir}/include${subexdir}" wi_EXTRA_IDIR($incdir) libdir="${exdir}/lib${subexdir}" wi_EXTRA_LDIR($libdir) progdir="${exdir}/bin${subexdirr}" wi_EXTRA_PDIR($progdir) fi done done ]) dnl dnl dnl AC_DEFUN(wi_PROTOTYPES, [ AC_MSG_CHECKING(if the compiler supports function prototypes) AC_TRY_COMPILE(,[extern void exit(int status);],[wi_cv_prototypes=yes AC_DEFINE(PROTOTYPES)],wi_cv_prototypes=no) AC_MSG_RESULT($wi_cv_prototypes) ]) dnl dnl dnl AC_DEFUN(wi_ANSI_C, [ AC_MSG_CHECKING(ANSI-style function definitions) AC_TRY_COMPILE(,[int blubb(int x) { return 0; }],[wi_cv_ansi_funcs=yes AC_DEFINE(ANSI_FUNCS)],wi_cv_ansi_funcs=no) AC_MSG_RESULT($wi_cv_ansi_funcs) ]) dnl dnl dnl AC_DEFUN(wi_HEADER_SYS_SELECT_H, [ # See if is includable after if test "$ac_cv_header_sys_time_h" = no ; then AC_CHECK_HEADERS(sys/time.h sys/select.h) else AC_CHECK_HEADERS(sys/select.h) fi if test "$ac_cv_header_sys_select_h" = yes ; then AC_MSG_CHECKING([if is compatible with ]) selecth=yes if test "$ac_cv_header_sys_time_h" = yes ; then AC_TRY_COMPILE([#include #include ],[ fd_set a; struct timeval tmval; tmval.tv_sec = 0;],selecth=yes,selecth=no) if test "$selecth" = yes ; then AC_DEFINE(CAN_USE_SYS_SELECT_H) fi fi AC_MSG_RESULT($selecth) fi ]) dnl dnl dnl AC_DEFUN(wi_LIB_RESOLV, [ # See if we could access two well-known sites without help of any special # libraries, like resolv. AC_TRY_RUN([ #include #include #include #include main() { struct hostent *hp1, *hp2; int result; hp1 = gethostbyname("gatekeeper.dec.com"); hp2 = gethostbyname("ftp.ncsa.uiuc.edu"); result = ((hp1 != (struct hostent *) 0) && (hp2 != (struct hostent *) 0)); exit(! result); }],look_for_resolv=no,look_for_resolv=yes,look_for_resolv=yes) AC_MSG_CHECKING([if we need to look for -lresolv]) AC_MSG_RESULT($look_for_resolv) if test "$look_for_resolv" = yes ; then AC_CHECK_LIB(resolv,main) else ac_cv_lib_resolv=no fi ]) dnl dnl dnl AC_DEFUN(wi_LIB_NSL, [ AC_MSG_CHECKING(if we can use -lnsl) ac_save_LIBS="$LIBS"; LIBS="$LIBS -lnsl"; AC_CACHE_VAL(r_cv_use_libnsl, [ AC_TRY_RUN( main() { if (getpwuid(getuid())) exit(0); exit(-1); }, nc_cv_use_libnsl=yes, nc_cv_use_libnsl=no, nc_cv_use_libnsl=no) ]) if test "$nc_cv_use_libnsl" = "no"; then LIBS="$ac_save_LIBS"; fi AC_MSG_RESULT($nc_cv_use_libnsl) ])dnl dnl dnl dnl AC_DEFUN(nc_PATH_PROG_ZCAT, [ AC_PATH_PROG(GZCAT,gzcat) AC_PATH_PROG(ZCAT,zcat) if test "x$GZCAT" = x ; then if test "x$ZCAT" != x ; then # See if zcat is really gzcat. gzcat has a --version option, regular # zcat does not. AC_MSG_CHECKING(if zcat is really gzcat in disguise) if $ZCAT --version 2> /dev/null ; then AC_DEFINE_UNQUOTED(GZCAT, "$ZCAT") AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi else AC_DEFINE_UNQUOTED(GZCAT, "$GZCAT") fi if test "x$ZCAT" != x ; then AC_DEFINE_UNQUOTED(ZCAT, "$ZCAT") fi ]) dnl dnl dnl AC_DEFUN(wi_SYSV_EXTRA_DIRS, [ # Use System V because their curses extensions are required. This must # be done early so we use the -I and -L in the library checks also. # This is mostly a Solaris/SunOS hack. Note that doing this will also # use all of the other System V libraries and headers. AC_MSG_CHECKING(for alternative System V libraries) if test -f /usr/5include/curses.h ; then CPPFLAGS="$CPPFLAGS -I/usr/5include" LDFLAGS="$LDFLAGS -L/usr/5lib" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi ]) dnl dnl dnl AC_DEFUN(wi_DEFINE_UNAME, [ # Get first 127 chars of all uname information. Some folks have # way too much stuff there, so grab only the first 127. unam=`uname -a 2>/dev/null | cut -c1-127` if test "$unam" != "" ; then AC_DEFINE_UNQUOTED(UNAME, "$unam") fi ]) dnl dnl dnl AC_DEFUN(wi_READLINE_WITH_NCURSES, [ # Readline and Ncurses could both define "backspace". # Warn about this if we have both things in our definitions list. if test "$ac_cv_lib_readline" = yes && test "$ac_cv_lib_ncurses" = yes ; then AC_MSG_CHECKING(if readline and ncurses will link together) j="$LIBS" LIBS="-lreadline -lncurses" AC_TRY_LINK(,[ readline("prompt"); endwin(); ],k=yes,k=no) if test "$k" = no ; then AC_MSG_RESULT(no) # Remove '-lreadline' from LIBS. LIBS=`echo $j | sed s/-lreadline//g` ac_cv_lib_readline=no AC_WARN([The versions of GNU readline and ncurses you have installed on this system can't be used together, because they use the same symbol, backspace. If possible, recompile one of the libraries with -Dbackspace=back_space, then re-run configure.]) else AC_MSG_RESULT(yes) LIBS="$j" fi fi ]) dnl dnl dnl uudeview-0.5.20.orig/config.h.in0000644001167100001440000000673007306733555016374 0ustar cphusers00000000000000/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* * If your system is kinda special */ #undef SYSTEM_DOS #undef SYSTEM_QUICKWIN #undef SYSTEM_WINDLL #undef SYSTEM_OS2 /* * If your system has stdin/stdout/stderr */ #undef HAVE_STDIO /* * how to declare functions that are exported from the UU library */ #undef UUEXPORT /* * how to declare functions that are exported from the UUTCL library */ #undef UUTCLEXPORT /* * how to declare functions that are exported from the fptools library */ #undef TOOLEXPORT /* * how to declare functions that are interfaced with TCL */ #undef UUTCLFUNC /* * define if your compiler supports function prototypes */ #undef PROTOTYPES /* * define if you have TCL version 7.5 or later */ #undef HAVE_TCL /* * define if you HAVE_TCL and TK version 4.1 or later */ #undef HAVE_TK /* * define if Tcl_Main or Tk_Main needs Tcl_AppInit as third parameter */ #undef TMAIN_THREE /* * Replacement functions. * #define strerror _FP_strerror * #define tempnam _FP_tempnam * if you don't have these functions */ #undef strerror #undef tempnam /* * your system's directory separator (usually "/") */ #undef DIRSEPARATOR /* * your mailing program. full path and the necessary parameters. * the recepient address is added to the command line (with a leading * space) without any further options */ #undef PROG_MAILER /* * define if the mailer needs to have the subject set on the command * line with -s "Subject". Preferredly, we send the subject as a header. */ #undef MAILER_NEEDS_SUBJECT /* * define if posting is enabled. Do not edit. */ #undef HAVE_NEWS /* * your local news posting program. full path and parameters, so that * the article and all its headers are read from stdin */ #undef PROG_INEWS /* * the name of your local domain. only needed when using minews */ #undef DOMAINNAME /* * your local NNTP news server. only needed when using minews * can be overridden by $NNTPSERVER at runtime */ #undef NNTPSERVER /* * defined when we use minews, so that we know that we must define * the NNTPSERVER environment variable to be able to post */ #undef NEED_NNTPSERVER /* Define if you have the getcwd function. */ #undef HAVE_GETCWD /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY /* Define if you have the isatty function. */ #undef HAVE_ISATTY /* Define if you have the popen function. */ #undef HAVE_POPEN /* Define if you have the header file. */ #undef HAVE_DIRECT_H /* Define if you have the header file. */ #undef HAVE_ERRNO_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_IO_H /* Define if you have the header file. */ #undef HAVE_MALLOC_H /* Define if you have the header file. */ #undef HAVE_MEMORY_H /* Define if you have the header file. */ #undef HAVE_PWD_H /* Define if you have the header file. */ #undef HAVE_STDARG_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the header file. */ #undef HAVE_VARARGS_H uudeview-0.5.20.orig/configure0000755001167100001440000026404510020740752016245 0ustar cphusers00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --enable-tcl=dir looks for TCL files files below this directory" ac_help="$ac_help --enable-tk=dir looks for TK files below this directory" ac_help="$ac_help --disable-minews don't build the mini-inews" ac_help="$ac_help --enable-posting=server if using minews, sets the default name of your news server (will fall back to NNTPSERVER)" ac_help="$ac_help --enable-domain=domain if using minews, and autoconf cannot figure out your domain name, use this option to set it. Otherwise, a bogus domainname is used (causing the reply address of your postings to be invalid)" ac_help="$ac_help --enable-sendmail=prog Use prog to mail a file with recipients on the command line and the mail via stdin" ac_help="$ac_help --enable-inews=prog Use prog to post a file. -h is given on the command line, the article is piped through standard input" ac_help="$ac_help --disable-manuals disables installation of the manual pages" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=uudeview.lsm # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # # package revision # VERSION=0.5 PATCH=20 # Check whether --enable-tcl or --disable-tcl was given. if test "${enable_tcl+set}" = set; then enableval="$enable_tcl" have_tcl=$enableval else have_tcl="yes" fi # Check whether --enable-tk or --disable-tk was given. if test "${enable_tk+set}" = set; then enableval="$enable_tk" have_tk=$enableval else have_tk="yes" fi # Check whether --enable-minews or --disable-minews was given. if test "${enable_minews+set}" = set; then enableval="$enable_minews" have_minews=$enableval else have_minews=yes fi # Check whether --enable-posting or --disable-posting was given. if test "${enable_posting+set}" = set; then enableval="$enable_posting" newsserver=$enableval else newsserver="" fi # Check whether --enable-domain or --disable-domain was given. if test "${enable_domain+set}" = set; then enableval="$enable_domain" domainname=$enableval else domainname="" fi # Check whether --enable-sendmail or --disable-sendmail was given. if test "${enable_sendmail+set}" = set; then enableval="$enable_sendmail" have_sendmail=$enableval else have_sendmail=yes fi # Check whether --enable-inews or --disable-inews was given. if test "${enable_inews+set}" = set; then enableval="$enable_inews" have_inews=$enableval else have_inews=yes fi # Check whether --enable-manuals or --disable-manuals was given. if test "${enable_manuals+set}" = set; then enableval="$enable_manuals" have_manuals=$enableval else have_manuals=yes fi # # proc to look for a file in a number of places # # # Basic setup # # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:635: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:665: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:716: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:748: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 759 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:790: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:795: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:823: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:855: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:876: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:893: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:910: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking if the compiler supports function prototypes""... $ac_c" 1>&6 echo "configure:936: checking if the compiler supports function prototypes" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wi_cv_prototypes=yes cat >> confdefs.h <<\EOF #define PROTOTYPES 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* wi_cv_prototypes=no fi rm -f conftest* echo "$ac_t""$wi_cv_prototypes" 1>&6 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:962: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:991: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 echo "configure:1019: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else rm -f conftestdata if ln -s X conftestdata 2>/dev/null then rm -f conftestdata ac_cv_prog_LN_S="ln -s" else ac_cv_prog_LN_S=ln fi fi LN_S="$ac_cv_prog_LN_S" if test "$ac_cv_prog_LN_S" = "ln -s"; then echo "$ac_t""yes" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "$wi_cv_prototypes" = no ; then echo "configure: warning: Your compiler does not support function prototyping and" 1>&2 echo "configure: warning: is not able to properly compile this package. What a pity." 1>&2 echo "configure: warning: Get gcc, or any compiler that supports function prototypes." 1>&2 exit 1 fi # # ---------------------------------------------------------------------- # Prepare for setup # ---------------------------------------------------------------------- # orb_to_use= more_incs="`echo $with_includes | sed 's/:/ /g'`" more_libs="`echo $with_libs | sed 's/:/ /g'`" base_incs="`echo $CPLUS_INCLUDE_PATH | sed 's/:/ /g'` /local/include /usr/local/include /usr/include" base_libs="`echo $LIBPATH $LIBRARY_PATH $LD_LIBRARY_PATH $SHLIB_PATH | sed 's/:/ /g'` /local/lib /usr/local/lib /usr/lib" base_bins="`echo $PATH | sed 's/:/\/.. /g'` /local/bin /usr/local/bin /usr/bin" base_dirs="$prefix `echo $PATH | sed 's/:/\/.. /g'`" # # ---------------------------------------------------------------------- # Check Tcl setup # ---------------------------------------------------------------------- # if test "x$have_tcl" != "xno" ; then echo $ac_n "checking for tclConfig.sh""... $ac_c" 1>&6 echo "configure:1069: checking for tclConfig.sh" >&5 if test "x" = "x" ; then ff_name=`echo tclConfig.sh | sed 's/[-.*/ ]/_/g'` else ff_name="" fi eval $ff_name= eval ${ff_name}_dir= ff_file= ff_file_dir= for ff_dir in $have_tcl $have_tk $more_libs $base_libs $base_dirs ; do if test -f $ff_dir/tclConfig.sh ; then ff_file_dir=$ff_dir ff_file=$ff_dir/tclConfig.sh break fi for ff_subdir in lib ; do if test -f $ff_dir/$ff_subdir/tclConfig.sh ; then ff_file_dir=$ff_dir/$ff_subdir ff_file=$ff_dir/$ff_subdir/tclConfig.sh break fi done if test "x$ff_file" != "x" ; then break fi done eval ${ff_name}_dir="$ff_file_dir" eval $ff_name="$ff_file" if test "x$tclConfig_sh" = "x" ; then echo "$ac_t""not found" 1>&6 echo "configure: warning: Tcl parts disabled" 1>&2 echo "configure: warning: use --enable-tcl to locate tclConfig.sh" 1>&2 have_tcl=no else echo "$ac_t""$tclConfig_sh" 1>&6 fi fi if test "x$have_tcl" != "xno" ; then echo $ac_n "checking contents of tcl config""... $ac_c" 1>&6 echo "configure:1112: checking contents of tcl config" >&5 . $tclConfig_sh echo "$ac_t""done" 1>&6 echo $ac_n "checking tcl version""... $ac_c" 1>&6 echo "configure:1117: checking tcl version" >&5 echo "$ac_t""${TCL_VERSION}${TCL_PATCH_LEVEL}" 1>&6 if test "$TCL_MAJOR_VERSION" -lt 8 ; then echo "configure: warning: Oops, I need at least Tcl 8.0, sorry. Tcl parts disabled." 1>&2 echo "configure: warning: use --enable-tcl to locate tclConfig.sh" 1>&2 have_tcl=no fi fi if test "x$have_tcl" != "xno" ; then echo $ac_n "checking for tcl.h""... $ac_c" 1>&6 echo "configure:1129: checking for tcl.h" >&5 if test "x" = "x" ; then ff_name=`echo tcl.h | sed 's/[-.*/ ]/_/g'` else ff_name="" fi eval $ff_name= eval ${ff_name}_dir= ff_file= ff_file_dir= for ff_dir in $TCL_PREFIX $TCL_EXEC_PREFIX $TCL_SRC_DIR $have_tcl $have_tk $more_incs $base_incs $base_dirs ; do if test -f $ff_dir/tcl.h ; then ff_file_dir=$ff_dir ff_file=$ff_dir/tcl.h break fi for ff_subdir in include ; do if test -f $ff_dir/$ff_subdir/tcl.h ; then ff_file_dir=$ff_dir/$ff_subdir ff_file=$ff_dir/$ff_subdir/tcl.h break fi done if test "x$ff_file" != "x" ; then break fi done eval ${ff_name}_dir="$ff_file_dir" eval $ff_name="$ff_file" if test "x$tcl_h_dir" = "x" ; then echo "$ac_t""not found" 1>&6 echo "configure: warning: Tcl parts disabled" 1>&2 echo "configure: warning: use --enable-tcl to locate tcl.h" 1>&2 have_tcl=no else echo "$ac_t""found in $tcl_h_dir" 1>&6 fi fi if test "x$have_tcl" != "xno" ; then tcllibfile=`eval echo $TCL_LIB_FILE` tcllibpath= for item in $TCL_LIB_SPEC $TCL_BUILD_LIB_SPEC ; do case $item in -L*) tcllibpath="$tcllibpath `echo $item | sed 's/^-L//'`" ;; esac done echo $ac_n "checking for $tcllibfile""... $ac_c" 1>&6 echo "configure:1183: checking for $tcllibfile" >&5 if test "xtcl_lib" = "x" ; then ff_name=`echo $tcllibfile | sed 's/[-.*/ ]/_/g'` else ff_name="tcl_lib" fi eval $ff_name= eval ${ff_name}_dir= ff_file= ff_file_dir= for ff_dir in $tcllibpath $TCL_PREFIX $TCL_EXEC_PREFIX $TCL_SRC_DIR $have_tcl $have_tk $more_libs $base_libs $base_dirs ; do if test -f $ff_dir/$tcllibfile ; then ff_file_dir=$ff_dir ff_file=$ff_dir/$tcllibfile break fi for ff_subdir in lib unix ; do if test -f $ff_dir/$ff_subdir/$tcllibfile ; then ff_file_dir=$ff_dir/$ff_subdir ff_file=$ff_dir/$ff_subdir/$tcllibfile break fi done if test "x$ff_file" != "x" ; then break fi done eval ${ff_name}_dir="$ff_file_dir" eval $ff_name="$ff_file" if test "x$tcl_lib_dir" = "x" ; then echo "$ac_t""not found" 1>&6 echo "configure: warning: Tcl parts disabled" 1>&2 echo "configure: warning: use --enable-tcl to locate $tcllibfile" 1>&2 have_tcl="no" else echo "$ac_t""found in $tcl_lib_dir" 1>&6 fi case $TCL_DEFS in *TCL_THREADS*) CFLAGS="-D_REENTRANT $CFLAGS" ;; esac fi # # Tcl setup complete # if test "x$have_tcl" != "xno" ; then tcllibflag=`eval echo $TCL_LIB_FLAG` TCL_CPPFLAGS="-I$tcl_h_dir $TCL_CPPFLAGS" TCL_LDFLAGS="-L$tcl_lib_dir" TCL_LIBS="$tcllibflag $TCL_LIBS" cat >> confdefs.h <<\EOF #define HAVE_TCL 1 EOF cat >> confdefs.h <<\EOF #define TMAIN_THREE 1 EOF fi # # ---------------------------------------------------------------------- # Check Tk setup # ---------------------------------------------------------------------- # if test "x$have_tcl" = "xno" ; then have_tk=no fi if test "x$have_tk" != "xno" ; then echo $ac_n "checking for tkConfig.sh""... $ac_c" 1>&6 echo "configure:1265: checking for tkConfig.sh" >&5 if test "x" = "x" ; then ff_name=`echo tkConfig.sh | sed 's/[-.*/ ]/_/g'` else ff_name="" fi eval $ff_name= eval ${ff_name}_dir= ff_file= ff_file_dir= for ff_dir in $have_tcl $have_tk $more_libs $base_libs $base_dirs ; do if test -f $ff_dir/tkConfig.sh ; then ff_file_dir=$ff_dir ff_file=$ff_dir/tkConfig.sh break fi for ff_subdir in lib ; do if test -f $ff_dir/$ff_subdir/tkConfig.sh ; then ff_file_dir=$ff_dir/$ff_subdir ff_file=$ff_dir/$ff_subdir/tkConfig.sh break fi done if test "x$ff_file" != "x" ; then break fi done eval ${ff_name}_dir="$ff_file_dir" eval $ff_name="$ff_file" if test "x$tkConfig_sh" = "x" ; then echo "$ac_t""not found" 1>&6 echo "configure: warning: Tk parts disabled" 1>&2 echo "configure: warning: use --enable-tk to locate tkConfig.sh" 1>&2 have_tk=no else echo "$ac_t""$tkConfig_sh" 1>&6 fi fi if test "x$have_tk" != "xno" ; then echo $ac_n "checking contents of tk config""... $ac_c" 1>&6 echo "configure:1308: checking contents of tk config" >&5 . $tkConfig_sh echo "$ac_t""done" 1>&6 echo $ac_n "checking tk version""... $ac_c" 1>&6 echo "configure:1313: checking tk version" >&5 echo "$ac_t""${TK_VERSION}${TK_PATCH_LEVEL}" 1>&6 if test "$TK_MAJOR_VERSION" -lt 8 ; then echo "configure: warning: Oops, I need at least Tk 8.0, sorry. Tk parts disabled." 1>&2 echo "configure: warning: use --enable-tk to locate tkConfig.sh" 1>&2 have_tk=no fi fi if test "x$have_tk" != "xno" ; then echo $ac_n "checking for tk.h""... $ac_c" 1>&6 echo "configure:1325: checking for tk.h" >&5 if test "x" = "x" ; then ff_name=`echo tk.h | sed 's/[-.*/ ]/_/g'` else ff_name="" fi eval $ff_name= eval ${ff_name}_dir= ff_file= ff_file_dir= for ff_dir in $TK_PREFIX $TK_EXEC_PREFIX $TK_SRC_DIR $have_tk $have_tcl $tcl_h_dir $more_incs $base_incs $base_dirs ; do if test -f $ff_dir/tk.h ; then ff_file_dir=$ff_dir ff_file=$ff_dir/tk.h break fi for ff_subdir in include ; do if test -f $ff_dir/$ff_subdir/tk.h ; then ff_file_dir=$ff_dir/$ff_subdir ff_file=$ff_dir/$ff_subdir/tk.h break fi done if test "x$ff_file" != "x" ; then break fi done eval ${ff_name}_dir="$ff_file_dir" eval $ff_name="$ff_file" if test "x$tk_h_dir" = "x" ; then echo "$ac_t""not found" 1>&6 echo "configure: warning: Tk parts disabled" 1>&2 echo "configure: warning: use --enable-tk to locate tk.h" 1>&2 have_tk=no else echo "$ac_t""found in $tk_h_dir" 1>&6 fi fi if test "x$have_tk" != "xno" ; then tklibfile=`eval echo $TK_LIB_FILE` tcllibpath= for item in $TK_LIB_SPEC $TK_BUILD_LIB_SPEC ; do case $item in -L*) tklibpath="$tklibpath `echo $item | sed 's/^-L//'`" ;; esac done echo $ac_n "checking for $tklibfile""... $ac_c" 1>&6 echo "configure:1378: checking for $tklibfile" >&5 if test "xtk_lib" = "x" ; then ff_name=`echo $tklibfile | sed 's/[-.*/ ]/_/g'` else ff_name="tk_lib" fi eval $ff_name= eval ${ff_name}_dir= ff_file= ff_file_dir= for ff_dir in $tklibpath $TK_PREFIX $TK_EXEC_PREFIX $TK_SRC_DIR $have_tcl $have_tk $more_libs $base_libs $base_dirs ; do if test -f $ff_dir/$tklibfile ; then ff_file_dir=$ff_dir ff_file=$ff_dir/$tklibfile break fi for ff_subdir in lib unix ; do if test -f $ff_dir/$ff_subdir/$tklibfile ; then ff_file_dir=$ff_dir/$ff_subdir ff_file=$ff_dir/$ff_subdir/$tklibfile break fi done if test "x$ff_file" != "x" ; then break fi done eval ${ff_name}_dir="$ff_file_dir" eval $ff_name="$ff_file" if test "x$tk_lib_dir" = "x" ; then echo "$ac_t""not found" 1>&6 echo "configure: warning: Tk parts disabled" 1>&2 echo "configure: warning: use --enable-tk to locate $tklibfile" 1>&2 have_tk="no" else echo "$ac_t""found in $tk_lib_dir" 1>&6 fi fi # # Tk setup complete # if test "x$have_tk" != "xno" ; then tklibflag=`eval echo $TK_LIB_FLAG` TCL_CPPFLAGS="-I$tk_h_dir $TK_XINCLUDES $TCL_CPPFLAGS" TCL_LDFLAGS="-L$tk_lib_dir $TCL_LDFLAGS" TCL_LIBS="$tklibflag $TCL_LIBS" cat >> confdefs.h <<\EOF #define HAVE_TK 1 EOF fi # # we might need various libraries if we decide to go for TCL/TK # echo $ac_n "checking for sin""... $ac_c" 1>&6 echo "configure:1439: checking for sin" >&5 if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char sin(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_sin) || defined (__stub___sin) choke me #else sin(); #endif ; return 0; } EOF if { (eval echo configure:1467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_sin=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sin=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 LIBS="$LIBS -lm" fi # # these libs are needed for both TK and minews (from tk's configure.in) # and in some cases -lsocket features gettimeofday, needed for TCL # tk_checkBoth=0 echo $ac_n "checking for connect""... $ac_c" 1>&6 echo "configure:1495: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char connect(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_connect) || defined (__stub___connect) choke me #else connect(); #endif ; return 0; } EOF if { (eval echo configure:1523: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_connect=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_connect=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_checkSocket=0 else echo "$ac_t""no" 1>&6 tk_checkSocket=1 fi if test "$tk_checkSocket" = 1; then echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 echo "configure:1545: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lsocket" else echo "$ac_t""no" 1>&6 tk_checkBoth=1 fi fi if test "$tk_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" echo $ac_n "checking for accept""... $ac_c" 1>&6 echo "configure:1590: checking for accept" >&5 if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char accept(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_accept) || defined (__stub___accept) choke me #else accept(); #endif ; return 0; } EOF if { (eval echo configure:1618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_accept=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_accept=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'accept`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_checkNsl=0 else echo "$ac_t""no" 1>&6 LIBS=$tk_oldLibs fi fi echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 echo "configure:1640: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char gethostbyname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) choke me #else gethostbyname(); #endif ; return 0; } EOF if { (eval echo configure:1668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostbyname=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 echo "configure:1686: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 LIBS="$LIBS -lnsl" else echo "$ac_t""no" 1>&6 fi fi # # Look for a mailing program to be used by uuenview # case "x$have_sendmail" in xno*) MAILER="" ;; x|xyes*) # Extract the first word of "sendmail", so it can be a program name with args. set dummy sendmail; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1740: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MAILER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$MAILER" in /*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH:/sbin:/usr/lib:/usr/sbin:/usr/etc" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_MAILER="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi MAILER="$ac_cv_path_MAILER" if test -n "$MAILER"; then echo "$ac_t""$MAILER" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "x$MAILER" = "x" ; then # Extract the first word of "mailx", so it can be a program name with args. set dummy mailx; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1776: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MAILER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$MAILER" in /*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH:/sbin:/usr/lib:/usr/sbin:/usr/etc" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_MAILER="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi MAILER="$ac_cv_path_MAILER" if test -n "$MAILER"; then echo "$ac_t""$MAILER" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "x$MAILER" != "x" ; then cat >> confdefs.h <<\EOF #define MAILER_NEEDS_SUBJECT 1 EOF # mailx wants -s "subject" else # Extract the first word of "elm", so it can be a program name with args. set dummy elm; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1817: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MAILER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$MAILER" in /*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_MAILER="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi MAILER="$ac_cv_path_MAILER" if test -n "$MAILER"; then echo "$ac_t""$MAILER" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "x$MAILER" != "x" ; then cat >> confdefs.h <<\EOF #define MAILER_NEEDS_SUBJECT 1 EOF # elm wants -s "subject" else # Extract the first word of "mail", so it can be a program name with args. set dummy mail; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:1858: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MAILER'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$MAILER" in /*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_MAILER="$MAILER" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH:/sbin:/usr/lib:/usr/sbin:/usr/etc" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_MAILER="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi MAILER="$ac_cv_path_MAILER" if test -n "$MAILER"; then echo "$ac_t""$MAILER" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "x$MAILER" = "x" ; then echo "configure: warning: I haven't found a suitable mail program. You will not be" 1>&2 echo "configure: warning: able to mail files directly from uuenview." 1>&2 fi fi fi fi ;; *) echo $ac_n "checking for suitable mailer""... $ac_c" 1>&6 echo "configure:1900: checking for suitable mailer" >&5 echo "$ac_t""$have_sendmail" 1>&6 if test ! -x $have_sendmail ; then echo "configure: warning: Cannot execute $have_sendmail" 1>&2 echo "configure: warning: Make sure this prog exists when running uuenview" 1>&2 fi MAILER="$have_sendmail" ;; esac if test "x$MAILER" != "x" ; then cat >> confdefs.h <&6 echo "configure:1932: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_INEWS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$INEWS" in /*) ac_cv_path_INEWS="$INEWS" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_INEWS="$INEWS" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH:/usr/bin:/usr/news:/usr/news/bin:/usr/local/bin:/usr/local/news:/usr/local/news/bin:/usr/share/news:/usr/share/news/bin" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_INEWS="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi INEWS="$ac_cv_path_INEWS" if test -n "$INEWS"; then echo "$ac_t""$INEWS" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "x$INEWS" != "x" ; then cat >> confdefs.h <<\EOF #define HAVE_NEWS 1 EOF cat >> confdefs.h <> confdefs.h <<\EOF #define HAVE_NEWS 1 EOF # # we must cheat here to find the final location of minews. # ./configure defines the final values too late. This mimics # what autoconf 2.7 does. # eval "our_prefix=$prefix" eval "our_exec_prefix=$exec_prefix" eval "our_bindir=$bindir" if test "x$our_prefix" = "xNONE" ; then eval "our_prefix=$ac_default_prefix" fi if test "x$our_exec_prefix" = "xNONE" ; then eval "our_exec_prefix=$our_prefix" fi if test "x$our_bindir" = "xNONE/bin" ; then eval "our_bindir=$our_exec_prefix/bin" fi cat >> confdefs.h <&2 echo "configure: warning: You won't be able to post files directly from uuenview" 1>&2 have_minews=no newsserver="not_configured" domainname="not_configured" fi fi ;; *) echo $ac_n "checking for suitable inews""... $ac_c" 1>&6 echo "configure:2019: checking for suitable inews" >&5 echo "$ac_t""$have_inews" 1>&6 if test ! -x $have_inews ; then echo "configure: warning: Cannot execute $have_inews" 1>&2 echo "configure: warning: Make sure this prog exists when running uuenvew" 1>&2 fi cat >> confdefs.h <<\EOF #define HAVE_NEWS 1 EOF cat >> confdefs.h <&6 echo "configure:2045: checking for news server" >&5 if test "x$newsserver" = "x" ; then if test "x$NNTPSERVER" != "x" ; then newsserver=$NNTPSERVER else if test "x$NNTP_SRVER" != "x" ; then newsserver=$NNTP_SERVER fi fi fi if test "x$newsserver" = "x" ; then echo "$ac_t""not found" 1>&6 cat >> confdefs.h <<\EOF #define NEED_NNTPSERVER 1 EOF else echo "$ac_t""$newsserver" 1>&6 cat >> confdefs.h <&6 echo "configure:2078: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_HOSTNAME'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else case "$HOSTNAME" in /*) ac_cv_path_HOSTNAME="$HOSTNAME" # Let the user override the test with a path. ;; ?:/*) ac_cv_path_HOSTNAME="$HOSTNAME" # Let the user override the test with a dos path. ;; *) IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH:/sbin:/usr/sbin" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_HOSTNAME="$ac_dir/$ac_word" break fi done IFS="$ac_save_ifs" ;; esac fi HOSTNAME="$ac_cv_path_HOSTNAME" if test -n "$HOSTNAME"; then echo "$ac_t""$HOSTNAME" 1>&6 else echo "$ac_t""no" 1>&6 fi echo $ac_n "checking domain name""... $ac_c" 1>&6 echo "configure:2111: checking domain name" >&5 # # try /etc/resolv.conf # if test "x$domainname" = "x" ; then if test -f /etc/resolv.conf ; then # # note: Parameter for tr is # domainname=`grep '^domain' /etc/resolv.conf | tr -d ' ' | sed 's/domain//'` fi fi # # on some systems, hostname returns the FQN # if test "x$domainname" = "x" ; then if test "x$HOSTNAME" != "x" ; then if test "x`$HOSTNAME | grep "\\."`" != "x" ; then domainname=`$HOSTNAME | sed 's/[a-zA-Z0-9]*\.//'` fi fi fi if test "x$domainname" = "x" ; then echo "$ac_t""unknown" 1>&6 echo "configure: warning: Couldn't figure out your domain name. Configuring bogus" 1>&2 echo "configure: warning: domain. If you intend to post directly from uuenview," 1>&2 echo "configure: warning: rerun configure and use --enable-domain=your-domainname" 1>&2 echo "configure: warning: with your real domain name." 1>&2 domainname="i.dont.know.where.i.am" else echo "$ac_t""$domainname" 1>&6 fi cat >> confdefs.h <&6 echo "configure:2163: checking directory separator" >&5 dirseparator="/" echo "$ac_t""$dirseparator" 1>&6 cat >> confdefs.h <&6 echo "configure:2176: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2189: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:2256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:2280: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:2313: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2326: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:2393: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:2417: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:2431: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi for ac_hdr in fcntl.h unistd.h memory.h malloc.h errno.h direct.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2455: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2465: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_hdr in io.h sys/time.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2495: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2505: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in getcwd popen gettimeofday isatty do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:2534: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:2562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for tempnam""... $ac_c" 1>&6 echo "configure:2588: checking for tempnam" >&5 if eval "test \"`echo '$''{'ac_cv_func_tempnam'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char tempnam(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_tempnam) || defined (__stub___tempnam) choke me #else tempnam(); #endif ; return 0; } EOF if { (eval echo configure:2616: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_tempnam=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_tempnam=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'tempnam`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define tempnam _FP_tempnam EOF fi # # strerror might be internally defined. this would cause a # CHECK_FUNCS(strerror) to fail because it'd be called with # zero arguments. So use our own code. # echo $ac_n "checking for strerror""... $ac_c" 1>&6 echo "configure:2646: checking for strerror" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_strerror=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* cat >> confdefs.h <<\EOF #define strerror _FP_strerror EOF have_strerror=no fi rm -f conftest* echo "$ac_t""$have_strerror" 1>&6 echo $ac_n "checking for stdin""... $ac_c" 1>&6 echo "configure:2676: checking for stdin" >&5 cat > conftest.$ac_ext < char *blubb() { FILE *in, *out; in=stdin; out=stdout; return (char*)0; } int main() { (void) blubb(); ; return 0; } EOF if { (eval echo configure:2690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_stdio=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_STDIO 1 EOF have_stdio=no fi rm -f conftest* echo "$ac_t""$have_stdio" 1>&6 if test "$ac_cv_header_stdc" = "no" ; then for ac_hdr in stdarg.h varargs.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2711: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2721: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done if test "$ac_cv_header_stdarg_h" = "no" ; then if test "$ac_cv_header_varargs_h" = "no" ; then { echo "configure: error: neither stdarg.h nor varargs.h present" 1>&2; exit 1; } fi fi fi if test "$have_minews" = "yes" ; then for ac_hdr in pwd.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:2759: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:2769: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done fi # # Check whether this is a DOS-Based system. Another bogus test. # Don't even bother to print a message. This code is needed so # that autoheader includes the #undef into the final config.h # and we can change the definition by hand on a really DOS # system (where ./configure doesn't work anyway ...) # if false ; then cat >> confdefs.h <<\EOF #define SYSTEM_DOS 1 EOF cat >> confdefs.h <<\EOF #define SYSTEM_QUICKWIN 1 EOF cat >> confdefs.h <<\EOF #define SYSTEM_WINDLL 1 EOF cat >> confdefs.h <<\EOF #define SYSTEM_OS2 1 EOF fi if test "x$have_tcl" != "xno" ; then # # Hack: remove doubly-defined libs # TCL_NEW_LIBS="" for lib in $TCL_LIBS $LIBS ; do found=no for tlib in $TCL_NEW_LIBS ; do if test "x$lib" = "x$tlib" ; then found=yes break fi done if test "x$found" = "xno" ; then TK_NEW_LIBS="$TK_NEW_LIBS $lib" fi done fi # # On some systems (so far, OS2 and WINDOWS), functions that are exported # from a DLL must be declared specifically. # cat >> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <&6 echo "configure:2896: checking version number" >&5 version_number="$VERSION"pl"$PATCH" echo "$ac_t""$version_number" 1>&6 # # done # trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "Makefile tcl/Makefile unix/Makefile uulib/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@SET_MAKE@%$SET_MAKE%g s%@RANLIB@%$RANLIB%g s%@LN_S@%$LN_S%g s%@TCL_CPPFLAGS@%$TCL_CPPFLAGS%g s%@TCL_LDFLAGS@%$TCL_LDFLAGS%g s%@TCL_LIBS@%$TCL_LIBS%g s%@MAILER@%$MAILER%g s%@INEWS@%$INEWS%g s%@HOSTNAME@%$HOSTNAME%g s%@DOINST@%$DOINST%g s%@PROGS@%$PROGS%g s%@MPAGES@%$MPAGES%g s%@VERSION@%$VERSION%g s%@PATCH@%$PATCH%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 # # copy config.h into our subdirectories # #echo copying tcl/config.h #cp config.h tcl #echo copying unix/config.h #cp config.h unix #echo copying uulib/config.h #cp config.h uulib # # # goodbye # uudeview-0.5.20.orig/configure.in0000644001167100001440000004056010020740752016641 0ustar cphusers00000000000000dnl This file is an input file used by the GNU "autoconf" program to dnl generate the file "configure", which tries to guess your system dnl configuration so that no manual editing of the Makefile should be dnl necessary dnl dnl $Id: configure.in,v 1.34 2004/03/01 23:06:18 fp Exp $ dnl AC_INIT(uudeview.lsm) AC_PREREQ(2.9) AC_CONFIG_HEADER(config.h) # # package revision # VERSION=0.5 PATCH=20 AC_ARG_ENABLE(tcl, [ --enable-tcl=dir looks for TCL files files below this directory],have_tcl=$enableval,have_tcl="yes") AC_ARG_ENABLE(tk, [ --enable-tk=dir looks for TK files below this directory],have_tk=$enableval,have_tk="yes") AC_ARG_ENABLE(minews, [ --disable-minews don't build the mini-inews],have_minews=$enableval,have_minews=yes) AC_ARG_ENABLE(posting, [ --enable-posting=server if using minews, sets the default name of your news server (will fall back to NNTPSERVER)],newsserver=$enableval,newsserver="") AC_ARG_ENABLE(domain, [ --enable-domain=domain if using minews, and autoconf cannot figure out your domain name, use this option to set it. Otherwise, a bogus domainname is used (causing the reply address of your postings to be invalid)],domainname=$enableval,domainname="") AC_ARG_ENABLE(sendmail,[ --enable-sendmail=prog Use prog to mail a file with recipients on the command line and the mail via stdin],have_sendmail=$enableval,have_sendmail=yes) AC_ARG_ENABLE(inews, [ --enable-inews=prog Use prog to post a file. -h is given on the command line, the article is piped through standard input],have_inews=$enableval,have_inews=yes) AC_ARG_ENABLE(manuals, [ --disable-manuals disables installation of the manual pages],have_manuals=$enableval,have_manuals=yes) # # proc to look for a file in a number of places # AC_DEFUN(FP_FIND_FILE, [ if test "x$4" = "x" ; then ff_name=[`echo $1 | sed 's/[-.*/ ]/_/g'`] else ff_name="$4" fi eval $ff_name= eval ${ff_name}_dir= ff_file= ff_file_dir= for ff_dir in $2 ; do if test -f $ff_dir/$1 ; then ff_file_dir=$ff_dir ff_file=$ff_dir/$1 break fi for ff_subdir in $3 ; do if test -f $ff_dir/$ff_subdir/$1 ; then ff_file_dir=$ff_dir/$ff_subdir ff_file=$ff_dir/$ff_subdir/$1 break fi done if test "x$ff_file" != "x" ; then break fi done eval ${ff_name}_dir="$ff_file_dir" eval $ff_name="$ff_file" ]) # # Basic setup # AC_PROG_CC AC_PROG_CPP wi_PROTOTYPES AC_PROG_MAKE_SET dnl AC_PROG_INSTALL AC_PROG_RANLIB AC_PROG_LN_S if test "$wi_cv_prototypes" = no ; then AC_WARN([Your compiler does not support function prototyping and]) AC_WARN([is not able to properly compile this package. What a pity.]) AC_WARN([Get gcc, or any compiler that supports function prototypes.]) exit 1 fi # # ---------------------------------------------------------------------- # Prepare for setup # ---------------------------------------------------------------------- # orb_to_use= more_incs="`echo $with_includes | sed 's/:/ /g'`" more_libs="`echo $with_libs | sed 's/:/ /g'`" base_incs="`echo $CPLUS_INCLUDE_PATH | sed 's/:/ /g'` /local/include /usr/local/include /usr/include" base_libs="`echo $LIBPATH $LIBRARY_PATH $LD_LIBRARY_PATH $SHLIB_PATH | sed 's/:/ /g'` /local/lib /usr/local/lib /usr/lib" base_bins="`echo $PATH | sed 's/:/\/.. /g'` /local/bin /usr/local/bin /usr/bin" base_dirs="$prefix `echo $PATH | sed 's/:/\/.. /g'`" # # ---------------------------------------------------------------------- # Check Tcl setup # ---------------------------------------------------------------------- # if test "x$have_tcl" != "xno" ; then AC_MSG_CHECKING(for tclConfig.sh) FP_FIND_FILE(tclConfig.sh,$have_tcl $have_tk $more_libs $base_libs $base_dirs,lib) if test "x$tclConfig_sh" = "x" ; then AC_MSG_RESULT(not found) AC_MSG_WARN(Tcl parts disabled) AC_MSG_WARN(use --enable-tcl to locate tclConfig.sh) have_tcl=no else AC_MSG_RESULT($tclConfig_sh) fi fi if test "x$have_tcl" != "xno" ; then AC_MSG_CHECKING(contents of tcl config) . $tclConfig_sh AC_MSG_RESULT(done) AC_MSG_CHECKING(tcl version) AC_MSG_RESULT(${TCL_VERSION}${TCL_PATCH_LEVEL}) if test "$TCL_MAJOR_VERSION" -lt 8 ; then AC_MSG_WARN([Oops, I need at least Tcl 8.0, sorry. Tcl parts disabled.]) AC_MSG_WARN(use --enable-tcl to locate tclConfig.sh) have_tcl=no fi fi if test "x$have_tcl" != "xno" ; then AC_MSG_CHECKING(for tcl.h) FP_FIND_FILE(tcl.h,$TCL_PREFIX $TCL_EXEC_PREFIX $TCL_SRC_DIR $have_tcl $have_tk $more_incs $base_incs $base_dirs, include) if test "x$tcl_h_dir" = "x" ; then AC_MSG_RESULT(not found) AC_MSG_WARN(Tcl parts disabled) AC_MSG_WARN(use --enable-tcl to locate tcl.h) have_tcl=no else AC_MSG_RESULT(found in $tcl_h_dir) fi fi if test "x$have_tcl" != "xno" ; then tcllibfile=`eval echo $TCL_LIB_FILE` tcllibpath= for item in $TCL_LIB_SPEC $TCL_BUILD_LIB_SPEC ; do case $item in -L*) tcllibpath="$tcllibpath `echo $item | sed 's/^-L//'`" ;; esac done AC_MSG_CHECKING(for $tcllibfile) FP_FIND_FILE($tcllibfile,$tcllibpath $TCL_PREFIX $TCL_EXEC_PREFIX $TCL_SRC_DIR $have_tcl $have_tk $more_libs $base_libs $base_dirs,lib unix,tcl_lib) if test "x$tcl_lib_dir" = "x" ; then AC_MSG_RESULT(not found) AC_MSG_WARN(Tcl parts disabled) AC_MSG_WARN(use --enable-tcl to locate $tcllibfile) have_tcl="no" else AC_MSG_RESULT(found in $tcl_lib_dir) fi case $TCL_DEFS in *TCL_THREADS*) CFLAGS="-D_REENTRANT $CFLAGS" ;; esac fi # # Tcl setup complete # if test "x$have_tcl" != "xno" ; then tcllibflag=`eval echo $TCL_LIB_FLAG` TCL_CPPFLAGS="-I$tcl_h_dir $TCL_CPPFLAGS" TCL_LDFLAGS="-L$tcl_lib_dir" TCL_LIBS="$tcllibflag $TCL_LIBS" AC_DEFINE(HAVE_TCL) AC_DEFINE(TMAIN_THREE) fi AC_SUBST(TCL_CPPFLAGS) AC_SUBST(TCL_LDFLAGS) AC_SUBST(TCL_LIBS) # # ---------------------------------------------------------------------- # Check Tk setup # ---------------------------------------------------------------------- # if test "x$have_tcl" = "xno" ; then have_tk=no fi if test "x$have_tk" != "xno" ; then AC_MSG_CHECKING(for tkConfig.sh) FP_FIND_FILE(tkConfig.sh,$have_tcl $have_tk $more_libs $base_libs $base_dirs,lib) if test "x$tkConfig_sh" = "x" ; then AC_MSG_RESULT(not found) AC_MSG_WARN(Tk parts disabled) AC_MSG_WARN(use --enable-tk to locate tkConfig.sh) have_tk=no else AC_MSG_RESULT($tkConfig_sh) fi fi if test "x$have_tk" != "xno" ; then AC_MSG_CHECKING(contents of tk config) . $tkConfig_sh AC_MSG_RESULT(done) AC_MSG_CHECKING(tk version) AC_MSG_RESULT(${TK_VERSION}${TK_PATCH_LEVEL}) if test "$TK_MAJOR_VERSION" -lt 8 ; then AC_MSG_WARN([Oops, I need at least Tk 8.0, sorry. Tk parts disabled.]) AC_MSG_WARN(use --enable-tk to locate tkConfig.sh) have_tk=no fi fi if test "x$have_tk" != "xno" ; then AC_MSG_CHECKING(for tk.h) FP_FIND_FILE(tk.h,$TK_PREFIX $TK_EXEC_PREFIX $TK_SRC_DIR $have_tk $have_tcl $tcl_h_dir $more_incs $base_incs $base_dirs, include) if test "x$tk_h_dir" = "x" ; then AC_MSG_RESULT(not found) AC_MSG_WARN(Tk parts disabled) AC_MSG_WARN(use --enable-tk to locate tk.h) have_tk=no else AC_MSG_RESULT(found in $tk_h_dir) fi fi if test "x$have_tk" != "xno" ; then tklibfile=`eval echo $TK_LIB_FILE` tcllibpath= for item in $TK_LIB_SPEC $TK_BUILD_LIB_SPEC ; do case $item in -L*) tklibpath="$tklibpath `echo $item | sed 's/^-L//'`" ;; esac done AC_MSG_CHECKING(for $tklibfile) FP_FIND_FILE($tklibfile,$tklibpath $TK_PREFIX $TK_EXEC_PREFIX $TK_SRC_DIR $have_tcl $have_tk $more_libs $base_libs $base_dirs,lib unix,tk_lib) if test "x$tk_lib_dir" = "x" ; then AC_MSG_RESULT(not found) AC_MSG_WARN(Tk parts disabled) AC_MSG_WARN(use --enable-tk to locate $tklibfile) have_tk="no" else AC_MSG_RESULT(found in $tk_lib_dir) fi fi # # Tk setup complete # if test "x$have_tk" != "xno" ; then tklibflag=`eval echo $TK_LIB_FLAG` TCL_CPPFLAGS="-I$tk_h_dir $TK_XINCLUDES $TCL_CPPFLAGS" TCL_LDFLAGS="-L$tk_lib_dir $TCL_LDFLAGS" TCL_LIBS="$tklibflag $TCL_LIBS" AC_DEFINE(HAVE_TK) fi # # we might need various libraries if we decide to go for TCL/TK # AC_CHECK_FUNC(sin,, LIBS="$LIBS -lm") # # these libs are needed for both TK and minews (from tk's configure.in) # and in some cases -lsocket features gettimeofday, needed for TCL # tk_checkBoth=0 AC_CHECK_FUNC(connect, tk_checkSocket=0, tk_checkSocket=1) if test "$tk_checkSocket" = 1; then AC_CHECK_LIB(socket, connect, LIBS="$LIBS -lsocket", tk_checkBoth=1) fi if test "$tk_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" AC_CHECK_FUNC(accept, tk_checkNsl=0, [LIBS=$tk_oldLibs]) fi AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname, [LIBS="$LIBS -lnsl"])) # # Look for a mailing program to be used by uuenview # case "x$have_sendmail" in xno*) MAILER="" ;; x|xyes*) AC_PATH_PROG(MAILER,sendmail,,$PATH:/sbin:/usr/lib:/usr/sbin:/usr/etc) if test "x$MAILER" = "x" ; then AC_PATH_PROG(MAILER,mailx,,$PATH:/sbin:/usr/lib:/usr/sbin:/usr/etc) if test "x$MAILER" != "x" ; then AC_DEFINE(MAILER_NEEDS_SUBJECT) # mailx wants -s "subject" else AC_PATH_PROG(MAILER,elm,,$PATH) if test "x$MAILER" != "x" ; then AC_DEFINE(MAILER_NEEDS_SUBJECT) # elm wants -s "subject" else AC_PATH_PROG(MAILER,mail,,$PATH:/sbin:/usr/lib:/usr/sbin:/usr/etc) if test "x$MAILER" = "x" ; then AC_WARN([I haven't found a suitable mail program. You will not be]) AC_WARN([able to mail files directly from uuenview.]) fi fi fi fi ;; *) AC_MSG_CHECKING([for suitable mailer]) AC_MSG_RESULT($have_sendmail) if test ! -x $have_sendmail ; then AC_WARN([Cannot execute $have_sendmail]) AC_WARN([Make sure this prog exists when running uuenview]) fi MAILER="$have_sendmail" ;; esac if test "x$MAILER" != "x" ; then AC_DEFINE_UNQUOTED(PROG_MAILER,"$MAILER") fi # # Look for inews. If it is there, there's no need to make our own # case "x$have_inews" in xno*) INEWS="" have_minews=no newsserver="not_configured" domainname="not_configured" ;; x|xyes*) AC_PATH_PROG(INEWS,inews,,$PATH:/usr/bin:/usr/news:/usr/news/bin:/usr/local/bin:/usr/local/news:/usr/local/news/bin:/usr/share/news:/usr/share/news/bin) if test "x$INEWS" != "x" ; then AC_DEFINE(HAVE_NEWS) AC_DEFINE_UNQUOTED(PROG_INEWS,"$INEWS -h") have_minews=no newsserver="not_needed" domainname="not_needed" else if test "$have_minews" = "yes" ; then AC_DEFINE(HAVE_NEWS) # # we must cheat here to find the final location of minews. # ./configure defines the final values too late. This mimics # what autoconf 2.7 does. # eval "our_prefix=$prefix" eval "our_exec_prefix=$exec_prefix" eval "our_bindir=$bindir" if test "x$our_prefix" = "xNONE" ; then eval "our_prefix=$ac_default_prefix" fi if test "x$our_exec_prefix" = "xNONE" ; then eval "our_exec_prefix=$our_prefix" fi if test "x$our_bindir" = "xNONE/bin" ; then eval "our_bindir=$our_exec_prefix/bin" fi AC_DEFINE_UNQUOTED(PROG_INEWS,"${our_bindir}/minews -h") else AC_WARN([Couldn't find inews and you didn't want minews.]) AC_WARN([You won't be able to post files directly from uuenview]) have_minews=no newsserver="not_configured" domainname="not_configured" fi fi ;; *) AC_MSG_CHECKING([for suitable inews]) AC_MSG_RESULT([$have_inews]) if test ! -x $have_inews ; then AC_WARN([Cannot execute $have_inews]) AC_WARN([Make sure this prog exists when running uuenvew]) fi AC_DEFINE(HAVE_NEWS) AC_DEFINE_UNQUOTED(PROG_INEWS,"$have_inews -h") have_minews=no newsserver="not_needed" domainname="not_needed" ;; esac # # check for NNTPSERVER or NNTP_SERVER # if test "$have_minews" = "yes" ; then AC_MSG_CHECKING([for news server]) if test "x$newsserver" = "x" ; then if test "x$NNTPSERVER" != "x" ; then newsserver=$NNTPSERVER else if test "x$NNTP_SRVER" != "x" ; then newsserver=$NNTP_SERVER fi fi fi if test "x$newsserver" = "x" ; then AC_MSG_RESULT([not found]) AC_DEFINE(NEED_NNTPSERVER) else AC_MSG_RESULT($newsserver) AC_DEFINE_UNQUOTED(NNTPSERVER,"$newsserver") fi fi # # If we compile and use minews, we want to know our domain name # if test "$have_minews" = "yes" ; then AC_PATH_PROG(HOSTNAME,hostname,,$PATH:/sbin:/usr/sbin) AC_MSG_CHECKING([domain name]) # # try /etc/resolv.conf # if test "x$domainname" = "x" ; then if test -f /etc/resolv.conf ; then # # note: Parameter for tr is # domainname=`grep '^domain' /etc/resolv.conf | tr -d ' ' | sed 's/domain//'` fi fi # # on some systems, hostname returns the FQN # if test "x$domainname" = "x" ; then if test "x$HOSTNAME" != "x" ; then if test "x`$HOSTNAME | grep "\\."`" != "x" ; then domainname=`$HOSTNAME | sed 's/[[a-zA-Z0-9]]*\.//'` fi fi fi if test "x$domainname" = "x" ; then AC_MSG_RESULT([unknown]) AC_WARN([Couldn't figure out your domain name. Configuring bogus]) AC_WARN([domain. If you intend to post directly from uuenview,]) AC_WARN([rerun configure and use --enable-domain=your-domainname]) AC_WARN([with your real domain name.]) domainname="i.dont.know.where.i.am" else AC_MSG_RESULT($domainname) fi AC_DEFINE_UNQUOTED(DOMAINNAME,"$domainname") fi # # Check the directory separator. Because this is probably a Unix-like # system, just set it statically to "/". On other systems, change it # in config.h # AC_MSG_CHECKING([directory separator]) dirseparator="/" AC_MSG_RESULT($dirseparator) AC_DEFINE_UNQUOTED(DIRSEPARATOR,"$dirseparator") # # Checks for header files and library functions # AC_TYPE_SIZE_T AC_HEADER_STDC AC_HEADER_TIME AC_CHECK_HEADERS(fcntl.h unistd.h memory.h malloc.h errno.h direct.h) AC_CHECK_HEADERS(io.h sys/time.h) AC_CHECK_FUNCS(getcwd popen gettimeofday isatty) AC_CHECK_FUNC(tempnam,,AC_DEFINE(tempnam,_FP_tempnam)) # # strerror might be internally defined. this would cause a # CHECK_FUNCS(strerror) to fail because it'd be called with # zero arguments. So use our own code. # AC_MSG_CHECKING([for strerror]) AC_TRY_LINK([ char *blubb() { return (char *) strerror (42); } ],[ (void) blubb(); ],have_strerror=yes,AC_DEFINE(strerror,_FP_strerror) have_strerror=no) AC_MSG_RESULT($have_strerror) AC_MSG_CHECKING([for stdin]) AC_TRY_LINK([ #include char *blubb() { FILE *in, *out; in=stdin; out=stdout; return (char*)0; } ],[ (void) blubb(); ],have_stdio=yes,AC_DEFINE(HAVE_STDIO) have_stdio=no) AC_MSG_RESULT($have_stdio) if test "$ac_cv_header_stdc" = "no" ; then AC_CHECK_HEADERS(stdarg.h varargs.h) if test "$ac_cv_header_stdarg_h" = "no" ; then if test "$ac_cv_header_varargs_h" = "no" ; then AC_MSG_ERROR([neither stdarg.h nor varargs.h present]) fi fi fi if test "$have_minews" = "yes" ; then AC_CHECK_HEADERS(pwd.h) fi # # Check whether this is a DOS-Based system. Another bogus test. # Don't even bother to print a message. This code is needed so # that autoheader includes the #undef into the final config.h # and we can change the definition by hand on a really DOS # system (where ./configure doesn't work anyway ...) # if false ; then AC_DEFINE(SYSTEM_DOS) AC_DEFINE(SYSTEM_QUICKWIN) AC_DEFINE(SYSTEM_WINDLL) AC_DEFINE(SYSTEM_OS2) fi if test "x$have_tcl" != "xno" ; then # # Hack: remove doubly-defined libs # TCL_NEW_LIBS="" for lib in $TCL_LIBS $LIBS ; do found=no for tlib in $TCL_NEW_LIBS ; do if test "x$lib" = "x$tlib" ; then found=yes break fi done if test "x$found" = "xno" ; then TK_NEW_LIBS="$TK_NEW_LIBS $lib" fi done fi # # On some systems (so far, OS2 and WINDOWS), functions that are exported # from a DLL must be declared specifically. # AC_DEFINE_UNQUOTED(UUEXPORT,) AC_DEFINE_UNQUOTED(UUTCLEXPORT,) AC_DEFINE_UNQUOTED(TOOLEXPORT,) AC_DEFINE_UNQUOTED(UUTCLFUNC,) # # decide which programs and libraries to build # PROGS="uudeview" DOINST="install-uudeview" MPAGES="uudeview.1 uuenview.1" if test "x$have_minews" = "xyes" ; then PROGS="$PROGS minews" DOINST="$DOINST install-minews" fi if test "x$have_tk" != "xno" ; then PROGS="$PROGS xdeview" MPAGES="$MPAGES xdeview.1" DOINST="$DOINST install-tcl" fi if test "x$have_manuals" = "xno" ; then MPAGES="" fi AC_SUBST(DOINST) AC_SUBST(PROGS) AC_SUBST(MPAGES) # # set version number # AC_MSG_CHECKING([version number]) version_number="$VERSION"pl"$PATCH" AC_MSG_RESULT($version_number) AC_SUBST(VERSION) AC_SUBST(PATCH) # # done # AC_OUTPUT(Makefile tcl/Makefile unix/Makefile uulib/Makefile) # # copy config.h into our subdirectories # #echo copying tcl/config.h #cp config.h tcl #echo copying unix/config.h #cp config.h unix #echo copying uulib/config.h #cp config.h uulib # # # goodbye # uudeview-0.5.20.orig/install-sh0000755001167100001440000001124406155632123016337 0ustar cphusers00000000000000#! /bin/sh # # install - install a program, script, or datafile # This comes from X11R5. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. # # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" tranformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 uudeview-0.5.20.orig/mkrelease0000755001167100001440000000340006174251155016227 0ustar cphusers00000000000000#!/bin/sh # # Brand new version. Quite an effort to update all related files # $Id: mkrelease,v 1.2 1996/07/20 21:41:01 fp Exp $ # if [ $# != 1 ] ; then echo usage: $0 major.minor.pl exit 1 fi version=$1 MAJOR=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'` MINOR=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'` PATCH=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'` echo branding release $MAJOR.$MINOR.$PATCH for file in README IAFA-PACKAGE ; do if [ -r $file ] ; then echo -n "patching $file ... " sed "s/\(Version[^0-9]*\).*/\1$version/" < $file > $file.temp mv $file.temp $file echo done. fi done file=uudeview.lsm if [ -r $file ] ; then echo -n "patching $file ... " sed -e "s/\(Version[^0-9]*\).*/\1$version/" \ -e "s/uudeview-[0-9]*\.[0-9]*\.[0-9]*/uudeview-$version/" \ -e "s^\(Entered-date[^0-9]*\).*^\1`date +%x`^" \ < $file > $file.temp mv $file.temp $file echo done. fi file=HISTORY if [ -r $file ] ; then echo -n "patching $file ... " sed "s/^ $version.*/ $version (`date +%d.%m.%Y`)/" \ < $file > $file.temp mv $file.temp $file echo done. fi file=doc/library.ltx if [ -r $file ] ; then echo -n "patching $file ... " sed -e 's/^\(\\providecommand{\\uuversion}\){.*}/\1'"{$MAJOR.$MINOR}/"\ -e 's/^\(\\providecommand{\\uupatch}\){.*}/\1'"{$PATCH}/" \ < $file > $file.temp mv $file.temp $file echo done. fi for file in configure.in uulib/configure.in wrapper.sh ; do if [ -r $file ] ; then echo -n "patching $file ... " sed -e "s/^VERSION=.*/VERSION=$MAJOR.$MINOR/" \ -e "s/^PATCH=.*/PATCH=$PATCH/" < $file > $file.temp mv $file.temp $file echo done. fi done echo -n "running autoconf ... " autoheader && autoconf (cd uulib ; autoheader && autoconf ) echo done. uudeview-0.5.20.orig/uudeview.lsm0000644001167100001440000000113410020740752016674 0ustar cphusers00000000000000Begin3 Title: uudeview Version: 0.5.20 Entered-date: 03/01/04 Description: Smart multi-file multi-part decoder for uuencoded, xxencoded, Base64 and BinHex encoded files. Also includes a similarly powerful encoder. Keywords: uudeview, uuenview, uudecode, decoding, MIME, xxdecode, uuencode, Base64, BinHex Author: fp@fpx.de (Frank Pilhofer) Maintained-by: fp@fpx.de (Frank Pilhofer) Primary-site: http://www.fpx.de/fp/Software/UUDeview/ Original-site: http://www.fpx.de/fp/Software/UUDeview/ Platform: Unix, Windows command line Copying-policy: GPL End uudeview-0.5.20.orig/wrapper.sh0000644001167100001440000003230710020740752016344 0ustar cphusers00000000000000#! /bin/sh # # This is a super-duper do-it-all SFX-install script for uudeview. # $Id: wrapper.sh,v 1.21 2004/03/01 23:06:18 fp Exp $ # VERSION=0.5 PATCH=20 # echo echo ---------------------------------------------------------------------- echo UUDeview for Unix Installation echo ---------------------------------------------------------------------- echo echo You are about to install UUDeview for Unix, the friendly decoding echo software. Usually, this works absolutely painlessly, but still you echo should be ready to answer a few questions about you and your system. echo /bin/echo -n "Do you want to continue [y] " read cont if test "x$cont" != "x" && test "x$cont" != "xy" && test "x$cont" != "xyes" ; then echo echo Very well. Installation aborted. echo exit 0 fi rm -f uudeview.tgz if test ! -r uudeview.tgz ; then echo /bin/echo -n extracting source ... dd if=$0 of=uudeview.tgz bs=1k skip=12 2> /dev/null if test ! -s uudeview.tgz ; then echo error echo echo Oops, couldn\'t extract source. The archive is probably broken. Please echo download this file once more and try again. Sorry. echo exit 1 fi echo " done." fi # # test if we have gunzip # /bin/echo -n checking for gunzip ... if gzip --version > /dev/null 2> /dev/null ; then echo " ok." else echo " not found." echo echo It appears that you don\'t have gunzip installed. We need gunzip echo to extract the UUDeview archive. I strongly suggest to install echo the gunzip program. echo Or if you are sure that gunzip is installed, make sure it can echo be found in the \$PATH echo echo I\'m sorry, I cannot continue installation without gunzip. echo rm -rf uudeview.tgz uudeview.tar uudeview-"$VERSION"."$PATCH" exit 1 fi /bin/echo -n uncompressing source ... rm -f uudeview.tar gzip -dc uudeview.tgz > uudeview.tar if test "$?" != "0" || test ! -r uudeview.tar ; then echo " error." echo echo Oops, uncompressing the source code failed. The archive is echo probably broken. Please download this file once more and echo try again. echo echo Sorry, I cannot continue the installation. echo rm -rf uudeview.tgz uudeview.tar uudeview-* exit 1 else echo " done." fi /bin/echo -n extracting files from archive ... tar xf uudeview.tar if test "$?" != "0" || test ! -d uudeview-"$VERSION"."$PATCH" ; then echo " error." echo echo Oops, couldn\'t extract the archive file. This is weird. echo Please download this file once more and try again. echo echo Sorry, I cannot continue the installation. echo rm -rf uudeview.tgz uudeview.tar uudeview-"$VERSION"."$PATCH" exit 1 else rm -f uudeview.tar echo " done." fi cd uudeview-"$VERSION"."$PATCH" if test "$?" != "0" ; then echo echo OOps. Could not change directory to uudeview-"$VERSION"."$PATCH". Weird. echo echo Sorry, I cannot continue the installation. echo rm -rf uudeview.tgz uudeview.tar uudeview-"$VERSION"."$PATCH" exit 1 fi if test ! -x ./configure ; then echo echo OOps. Could not find ./configure. Weird. echo echo Sorry, I cannot continue the installation. echo cd .. rm -rf uudeview.tgz uudeview.tar uudeview-"$VERSION"."$PATCH" exit 1 fi echo echo ---------------------------------------------------------------------- echo We will now configure UUDeview for your needs. echo ---------------------------------------------------------------------- echo # # check whether we are root # if test "x$LOGNAME" != "x" ; then whoami=$LOGNAME else whoami=`id | sed 's/[^(]*(\([^)]*\)).*/\1/' 2>/dev/null` if test "x$whoami" = "x" ; then whoami=unknown fi fi if test "$whoami" = "root" ; then echo You are logged in as root. We should thus attempt a global echo installation of UUDeview. The default installation prefix echo is /usr/local, causing the binaries to go to /usr/local/bin echo and the manual pages to /usr/local/man. echo /bin/echo -n "Installation prefix [/usr/local] " read prefix if test "x$prefix" = "x" ; then prefix=/usr/local fi else echo echo You are logged in as a plain user. You will probably want echo to install UUDeview locally, in your home directory. The echo installation prefix thus defaults to \$HOME, causing the echo binaries to go to \$HOME/bin and the manual pages to echo \$HOME/man. You can also choose not to install the manual echo pages. echo /bin/echo -n "Installation prefix [$HOME] " read prefix if test "x$prefix" = "x" ; then prefix=$HOME fi /bin/echo -n "Do you want manual pages [y] " read manuals if test "x$manuals" != "x" && test "x$manuals" != "xy" && test "x$manuals" != "xyes" ; then manopt="--disable-manuals" fi fi echo echo If you have Tcl/Tk version 8.0 or greater installed, we can try to echo build the graphical frontend for UUDeview, xdeview. echo echo Usually, the configuration script finds out by itself where and if you echo have these two packages installed. On the following prompts, you can echo either accept the default [y], which means to add support if available, echo \'no\' or \'none\' to disable support, or you can give a base directory echo where the package can be found \(we will need DIR/include for the echo include files and DIR/lib for the libraries\). echo /bin/echo -n "Add Tcl support if possible [y] " read tcl if test "x$tcl" = "x" || test "x$tcl" = "xy" || test "x$tcl" = "xyes" ; then tclopt="" tkopt="y" else if test "x$tcl" = "xn" || test "x$tcl" = "xno" || test "x$tcl" = "xnone" ; then tclopt="--disable-tcl" tkopt="--disable-tk" else tclopt="--enable-tcl=$tcl" tkopt="$tcl" fi fi if test "x$tkopt" != "x--disable-tk" ; then /bin/echo -n "Add Tk support if possible [$tkopt] " read tk if test "x$tk" = "x" ; then tk=$tkopt fi if test "x$tk" = "xy" || test "x$tk" = "xyes" ; then tkopt="" else if test "x$tk" = "xn" || test "x$tk" = "xno" || test "x$tk" = "xnone" ; then tkopt="--disable-tk" else tkopt="$tk" fi fi fi # # get domain name # domainname=`grep '^domain' /etc/resolv.conf | tr -d ' ' | sed 's/domain//'` echo echo If you want to post directly from uuenview, we might need to know echo the internet domain you are in. The \"domain\" is the fully qualified echo name of your host minus the hostname. For example, if your host is echo bogus.cs.cms.edu, then the domain is cs.cms.edu. If you do not con- echo figure a domain name, a bogus default will be used. In that case, echo users will not be able to reply to your postings. echo /bin/echo -n "Your domain [$domainname] " read domain if test "x$domain" != "x" ; then domopt="--enable-domain=$domain" fi echo echo We will now complete the configuration. This might take a while. echo ./configure --prefix=$prefix $manopt $tclopt $tkopt echo echo ---------------------------------------------------------------------- echo Configuration finished. Building UUDeview. echo ---------------------------------------------------------------------- echo echo The package is now configured and ready to build. Do you want to /bin/echo -n "build UUDeview now [y] " read build if test "x$build" != "x" && test "x$build" != "xy" && test "x$build" != "xyes" ; then echo echo Very well. Installation aborted. echo echo You can compile the package later by changing to `pwd` echo and running first \"make\", then \"make install\". echo exit 0 fi echo echo building UUDeview. This might take a while. echo make if test ! -x ./unix/uudeview || test ! -x ./unix/uuenview ; then echo echo Compilation failed. Please examine the error messages above echo and try to figure out what\'s wrong. Sorry, can\'t help you echo here. echo exit 1 fi if test ! -w $prefix && test "$whoami" != "root" ; then echo echo You want to install UUDeview globally but aren\'t logged in as echo root. I cannot install the package now. Please log in as root, echo change to `pwd` and enter the command \"make install\" to echo complete the installation. echo exit 0 fi echo echo ---------------------------------------------------------------------- echo Building finished. Installing UUDeview. echo ---------------------------------------------------------------------- echo echo I am now ready to install UUdeview. Do you want to complete /bin/echo -n "the Installation now [y] " read install if test "x$install" != "x" && test "x$install" != "xy" && test "x$install" != "xyes" ; then echo echo Very well. Installation aborted. You can later install the package echo by running \"make install\" from `pwd`. echo exit 0 fi echo echo Installing Package. echo make install cd .. echo echo ---------------------------------------------------------------------- echo Installation finished. Removing source files. echo ---------------------------------------------------------------------- echo /bin/echo -n "Do you want the source to be removed [y] " read rem if test "x$rem" = "x" || test "x$rem" = "xy" || test "x$rem" = "xyes" ; then rm -rf uudeview.tgz uudeview.tar uudeview-"$VERSION"."$PATCH" fi echo echo Congratulations, you should now have a complete installation of echo UUDeview. Now make sure that the binary directory $prefix/bin echo is in your \$PATH. Then I suggest reading the manual pages. echo Have fun! echo exit 0 ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# ################# Padding characters to fill 12 Kilobytes ################# uudeview-0.5.20.orig/inews/0000755001167100001440000000000010020741142015442 5ustar cphusers00000000000000uudeview-0.5.20.orig/inews/Makefile0000644001167100001440000000170006155632123017114 0ustar cphusers00000000000000# Makefile for NN version of mini inews. # # $RCSfile: Makefile,v $ $Revision: 1.1.1.1 $ # # $Author: fp $ $Date: 1996/06/06 19:41:07 $ # # $State: Exp $ $Locker: $ # # $Log: Makefile,v $ # Revision 1.1.1.1 1996/06/06 19:41:07 fp # UUDeview put under revision control # # Revision 1.3 89/12/21 17:59:52 news # Added kit processing, cleanups. # # This makefile needs the definitions of NNTPSERVER, DOMAIN and HIDDENNET # on the make command line. __FP__ # TARGET = minews BINDIR = . SHELL = /bin/sh SRCS = inews.c clientlib.c version.c OBJS = inews.o clientlib.o version.o CFLAGS = -DNNTPSERVER=\"$(NNTPSERVER)\" -DDOMAIN=\"$(DOMAIN)\" \ -DHIDDENNET=$(HIDDENNET) $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS) all: $(TARGET) clean: rm -f $(OBJS) core lint tags *~ clobber: clean rm -f $(TARGET) Make.Log Manifest $(KIT) install: $(TARGET) ../inst inews $(TARGET) # install -o news -g news -m 511 -s -c $(TARGET) $(BINDIR) uudeview-0.5.20.orig/inews/README0000644001167100001440000000573606155632123016351 0ustar cphusers00000000000000 This is a "pseudo" inews which allows remote posting using the NNTP server. Essentially it takes a bunch of arguments and ignores ones starting with "-", expecting to find at least one which is a file name. If no files are specified, it uses standard input as the input file. ============================================================================ This release has been modified from the original to match the uudeview distribution. Some configuration options not needed in this context have been removed. The original, or what I consider to be the original, is packaged with the 'lynx' source code distribution. I also renamed the program 'minews' to distinguish it from the real inews. Most of the many changes in the source are tagged with __FP__. fp@informatik.uni-frankfurt.de ============================================================================ It then opens a connection to the NNTP server on the remote machine and blasts the article across. It then closes the connection. If it doesn't find a From: or Path: line, it inserts them, in the default format From: login@hostname.DOMAIN (Full_name) Path: hostname!login where DOMAIN is a #define in ./conf.h, and should be changed to reflect your system. A good choice is "UUCP" if you are not a member of the Internet. "Full_name" understands the & hack in password files. If "HIDDENNET" is defined in ./conf.h, DOMAIN is used as the complete host name, and the format used is From: login@DOMAIN (Full_name) Path: login "hostname" is figured out by what you've #defined in ../config.h. If you have defined GHNAME, it uses the gethostname() call. If you've defined UUNAME, it figured it out from the file /etc/uucpname. Finally, if neither is defined it gets it from /usr/include/whoami.h. If you have GHNAME defined and your gethostname() returns your fully-qualified Internet name, undefine DOMAIN. The point here is that the thing looks like inews to any program which would care to post something (e.g., Pnews, postnews, what have you). The difference is that the article will look like it was posted on the remote end, not on the local end. Please note that "postnews" (nor any of the other standard news programs) is not required for rrn/nntp on client machines. The "test*" files in this directory provide some good test material for inews; you can just redirect inews to take input from them or whatever. Thanks to Steven Grady for writing this, and for wasting a lot of his valuable time dealing with the can-o'-worms that is the real inews. BUGS: This version of inews doesn't handle real inews options. As a result, some posting programs (notably the Gnumacs front end) will fail if they use this program. In the interests of simplicity, I have no plans for modifying mini-inews to handle real-inews options. However, if you'd like to send me diffs I'll be more than happy to install them for the next release. uudeview-0.5.20.orig/inews/clientlib.c0000644001167100001440000002666206155632123017603 0ustar cphusers00000000000000#ifndef lint static char *sccsid = "@(#)clientlib.c 1.11 (Berkeley) 10/27/89"; #endif /* * NNTP client routines. */ /* * Include configuration parameters only if we're made in the nntp tree. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include #ifndef FOR_NN #include #endif #include #ifdef FOR_NN #if !defined(NETWORK_DATABASE) || defined(NETWORK_BYTE_ORDER) #include #endif #else #include #endif #ifndef EXCELAN # include #endif /* * __FP__ includes */ #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef EXCELAN # define IPPORT_NNTP 119 #endif #ifdef DECNET #include #include #endif #include "nntp.h" FILE *ser_rd_fp = NULL; FILE *ser_wr_fp = NULL; /* * getserverbyfile Get the name of a server from a named file. * Handle white space and comments. * Use NNTPSERVER environment variable if set. * * Parameters: "file" is the name of the file to read. * * Returns: Pointer to static data area containing the * first non-ws/comment line in the file. * NULL on error (or lack of entry in file). * * Side effects: None. */ char * getserverbyfile(file) char *file; { register FILE *fp; register char *cp; static char buf[256]; if (cp = getenv("NNTPSERVER")) { (void) strcpy(buf, cp); return (buf); } if (cp = getenv("NNTP_SERVER")) { (void) strcpy (buf, cp); return (buf); } /* * may define NNTPSERVER at compile time __FP__ */ #ifdef NNTPSERVER if (NNTPSERVER[0]) { (void) strcpy (buf, NNTPSERVER); return buf; } #endif if (file == NULL) return (NULL); fp = fopen(file, "r"); if (fp == NULL) return (NULL); while (fgets(buf, sizeof (buf), fp) != NULL) { if (*buf == '\n' || *buf == '#') continue; cp = strchr(buf, '\n'); if (cp) *cp = '\0'; (void) fclose(fp); return (buf); } (void) fclose(fp); return (NULL); /* No entry */ } /* * server_init Get a connection to the remote news server. * * Parameters: "machine" is the machine to connect to. * * Returns: -1 on error * server's initial response code on success. * * Side effects: Connects to server. * "ser_rd_fp" and "ser_wr_fp" are fp's * for reading and writing to server. */ server_init(machine) char *machine; { int sockt_rd, sockt_wr; char line[256]; #ifdef DECNET char *cp; cp = strchr(machine, ':'); if (cp && cp[1] == ':') { *cp = '\0'; sockt_rd = get_dnet_socket(machine); } else sockt_rd = get_tcp_socket(machine); #else sockt_rd = get_tcp_socket(machine); #endif if (sockt_rd < 0) return (-1); /* * Now we'll make file pointers (i.e., buffered I/O) out of * the socket file descriptor. Note that we can't just * open a fp for reading and writing -- we have to open * up two separate fp's, one for reading, one for writing. */ if ((ser_rd_fp = fdopen(sockt_rd, "r")) == NULL) { perror("server_init: fdopen #1"); return (-1); } sockt_wr = dup(sockt_rd); if ((ser_wr_fp = fdopen(sockt_wr, "w")) == NULL) { perror("server_init: fdopen #2"); ser_rd_fp = NULL; /* from above */ return (-1); } /* Now get the server's signon message */ (void) get_server(line, sizeof(line)); return (atoi(line)); } /* * get_tcp_socket -- get us a socket connected to the news server. * * Parameters: "machine" is the machine the server is running on. * * Returns: Socket connected to the news server if * all is ok, else -1 on error. * * Side effects: Connects to server. * * Errors: Printed via perror. */ get_tcp_socket(machine) char *machine; { int s; struct sockaddr_in sin; #ifndef EXCELAN struct servent *getservbyname(), *sp; struct hostent *gethostbyname(), *hp; #ifdef h_addr int x = 0; register char **cp; #endif if ((sp = getservbyname("nntp", "tcp")) == NULL) { fprintf(stderr, "nntp/tcp: Unknown service.\n"); return (-1); } /* * Name resolution doesn't quite go as far as it should. Take things * one stage further to allow nnn.nnn.nnn.nnn addresses if all else * fails. */ if( (hp = gethostbyname( machine ) ) == NULL ) { unsigned long inet_addr(); static struct hostent def; static struct in_addr defaddr; static char *alist[1]; static char namebuf[ 256 ]; defaddr.s_addr = inet_addr( machine ); if( defaddr.s_addr != -1 ) { strcpy( namebuf, machine ); def.h_name = namebuf; #ifdef h_addr def.h_addr_list = alist; #endif def.h_addr = (char *)&defaddr; def.h_length = sizeof( struct in_addr ); def.h_addrtype = AF_INET; def.h_aliases = 0; hp = &def; } } if (hp == NULL) { fprintf(stderr, "%s: Unknown host.\n", machine); return (-1); } memset (&sin, '\0', sizeof(sin)); sin.sin_family = hp->h_addrtype; sin.sin_port = sp->s_port; #else memset (&sin, '\0', sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(IPPORT_NNTP); #endif /* * The following is kinda gross. The name server under 4.3 * returns a list of addresses, each of which should be tried * in turn if the previous one fails. However, 4.2 hostent * structure doesn't have this list of addresses. * Under 4.3, h_addr is a #define to h_addr_list[0]. * We use this to figure out whether to include the NS specific * code... */ #ifdef h_addr /* get a socket and initiate connection -- use multiple addresses */ for (cp = hp->h_addr_list; cp && *cp; cp++) { s = socket(hp->h_addrtype, SOCK_STREAM, 0); if (s < 0) { perror("socket"); return (-1); } memcpy ((char *)&sin.sin_addr, *cp, hp->h_length); /* bcopy(*cp, (char *)&sin.sin_addr, hp->h_length);*/ if (x < 0) fprintf(stderr, "trying %s\n", inet_ntoa(sin.sin_addr)); x = connect(s, (struct sockaddr *)&sin, sizeof (sin)); if (x == 0) break; fprintf(stderr, "connection to %s: ", inet_ntoa(sin.sin_addr)); perror(""); (void) close(s); } if (x < 0) { fprintf(stderr, "giving up...\n"); return (-1); } #else /* no name server */ #ifdef EXCELAN if ((s = rresvport(SO_KEEPALIVE)) < 0) { /* Get the socket */ perror("socket"); return (-1); } /* set up addr for the connect */ sin.sin_addr.s_addr = rhost(machine); if (sin.sin_addr.s_addr < 0){ fprintf(stderr, "%s: Unknown host.\n", machine); return (-1); } /* And then connect */ if (connect(s, &sin) < 0) { perror("connect"); (void) close(s); return (-1); } #else if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return (-1); } /* And then connect */ /* bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length);*/ memcpy ((char *)&sin.sin_addr, hp->h_addr, hp->h_length); if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) { perror("connect"); (void) close(s); return (-1); } #endif #endif return (s); } #ifdef DECNET /* * get_dnet_socket -- get us a socket connected to the news server. * * Parameters: "machine" is the machine the server is running on. * * Returns: Socket connected to the news server if * all is ok, else -1 on error. * * Side effects: Connects to server. * * Errors: Printed via nerror. */ get_dnet_socket(machine) char *machine; { int s, area, node; struct sockaddr_dn sdn; struct nodeent *getnodebyname(), *np; memset (&sdn, '\0', sizeof(sdn)); switch (s = sscanf( machine, "%d%*[.]%d", &area, &node )) { case 1: node = area; area = 0; case 2: node += area*1024; sdn.sdn_add.a_len = 2; sdn.sdn_family = AF_DECnet; sdn.sdn_add.a_addr[0] = node % 256; sdn.sdn_add.a_addr[1] = node / 256; break; default: if ((np = getnodebyname(machine)) == NULL) { fprintf(stderr, "%s: Unknown host.\n", machine); return (-1); } else { /* bcopy(np->n_addr, (char *) sdn.sdn_add.a_addr, np->n_length); */ memcpy ((char *) sdn.sdn_add.a_addr, np->n_addr, np->n_length); sdn.sdn_add.a_len = np->n_length; sdn.sdn_family = np->n_addrtype; } break; } sdn.sdn_objnum = 0; sdn.sdn_flags = 0; sdn.sdn_objnamel = strlen("NNTP"); /* bcopy("NNTP", &sdn.sdn_objname[0], sdn.sdn_objnamel); */ memcpy (&sdn.sdn_objname[0], "NNTP", sdn.sdn_objnamel); if ((s = socket(AF_DECnet, SOCK_STREAM, 0)) < 0) { nerror("socket"); return (-1); } /* And then connect */ if (connect(s, (struct sockaddr *) &sdn, sizeof(sdn)) < 0) { nerror("connect"); close(s); return (-1); } return (s); } #endif /* * handle_server_response * * Print some informative messages based on the server's initial * response code. This is here so inews, rn, etc. can share * the code. * * Parameters: "response" is the response code which the * server sent us, presumably from "server_init", * above. * "server" is the news server we got the * response code from. * * Returns: -1 if the error is fatal (and we should exit). * 0 otherwise. * * Side effects: None. */ handle_server_response(response, server) int response; char *server; { switch (response) { case OK_NOPOST: /* fall through */ printf( "NOTE: This machine does not have permission to post articles.\n"); printf( " Please don't waste your time trying.\n\n"); case OK_CANPOST: return (0); break; case ERR_ACCESS: printf( "This machine does not have permission to use the %s news server.\n", server); return (-1); break; default: printf("Unexpected response code from %s news server: %d\n", server, response); return (-1); break; } /*NOTREACHED*/ } /* * put_server -- send a line of text to the server, terminating it * with CR and LF, as per ARPA standard. * * Parameters: "string" is the string to be sent to the * server. * * Returns: Nothing. * * Side effects: Talks to the server. * * Note: This routine flushes the buffer each time * it is called. For large transmissions * (i.e., posting news) don't use it. Instead, * do the fprintf's yourself, and then a final * fflush. */ void put_server(string) char *string; { #ifdef DEBUG fprintf(stderr, ">>> %s\n", string); #endif fprintf(ser_wr_fp, "%s\r\n", string); (void) fflush(ser_wr_fp); } /* * get_server -- get a line of text from the server. Strips * CR's and LF's. * * Parameters: "string" has the buffer space for the * line received. * "size" is the size of the buffer. * * Returns: -1 on error, 0 otherwise. * * Side effects: Talks to server, changes contents of "string". */ get_server(string, size) char *string; int size; { register char *cp; if (fgets(string, size, ser_rd_fp) == NULL) return (-1); if ((cp = strchr(string, '\r')) != NULL) *cp = '\0'; else if ((cp = strchr(string, '\n')) != NULL) *cp = '\0'; #ifdef DEBUG fprintf(stderr, "<<< %s\n", string); #endif return (0); } /* * close_server -- close the connection to the server, after sending * the "quit" command. * * Parameters: None. * * Returns: Nothing. * * Side effects: Closes the connection with the server. * You can't use "put_server" or "get_server" * after this routine is called. */ void close_server() { char ser_line[256]; if (ser_wr_fp == NULL || ser_rd_fp == NULL) return; put_server("QUIT"); (void) get_server(ser_line, sizeof(ser_line)); (void) fclose(ser_wr_fp); (void) fclose(ser_rd_fp); } uudeview-0.5.20.orig/inews/clientlib.h0000644001167100001440000000034606155632123017577 0ustar cphusers00000000000000/* * Definitions for NNTP client routines. * * @(#)clientlib.h 1.1 (Berkeley) 1/9/88 */ extern char *getserverbyfile(); extern int server_init(); extern void put_server(); extern int get_server(); extern void close_server(); uudeview-0.5.20.orig/inews/conf.h0000644001167100001440000000675506155632123016571 0ustar cphusers00000000000000/* * Configuration file for nn version of nntp inews. Written by * Steve Simmons (scs@lokkur.dexter.mi.us), Dec 19, 1989. Placed * in the public domain by the author. This file rationalizes * the stock NNTP release of inews with the definitions for NN. * The rationalization was done as of NN version 6.3.10 and NNTP * version 1.5.7. * * You must edit this file to reflect your local configuration * and environment. * * Follow the instructions given in the comments. See the file * README for more comments. * * $RCSfile: conf.h,v $ $Revision: 1.1.1.1 $ * * $Author: fp $ $Date: 1996/06/06 19:41:07 $ * * $State: Exp $ $Locker: $ * * $Log: conf.h,v $ * Revision 1.1.1.1 1996/06/06 19:41:07 fp * UUDeview put under revision control * * Revision 1.1 89/12/20 17:43:03 news * Initial revision * * May 1st, 1990, Kim Storm * Modifications to get hostname for free (see README.NN) */ #ifndef NNINEWSCONF_H #define NNINEWSCONF_H /* #include "config.h" */ /* * added by Montulli@ukanaix.cc.ukans.edu * to replace the need for config.h */ #include #include /* * Define NNTP_SERVER to the name of a file containing the name of the * nntp server. * * It is vital that both the nnmaster and all nn users on a machine * uses the same nntp server, because the nn database is synchronized * with a specific news active file. * * If the file name does not start with a slash, it is relative to * LIB_DIRECTORY defined below. * NOTE: If you plan to use the included inews, it MUST be a full pathname */ #define NNTP_SERVER "/usr/local/etc/nntpserver" /* #define NNTP_SERVER "/usr/lib/nntp_server" */ #ifndef NNTP /* WHY DO YOU WANT TO MAKE MINI-INEWS WHEN YOU DONT USE NNTP */ #endif /* * Define your local domain name. You *must* define something, either * here, in config.h, or elsewhere according to your local standards. * See comment below on HIDDENNET. * * You are not strictly *required* to have a domain name; nonetheless * it's a good idea. If you are on the Internet or otherwise have a * valid domain name, use it (except see HIDDENNET below). If you're * a uucp-only site, use ".uucp" for now and go get a real name. * * Note that if you imbed your domain name in the hostname and you don't * use HIDDENNET, you may get a period on the end of your fully qualified * domian name (FQDN) in postings. In that case, use HIDDENNET and * define DOMAIN to be your FQDN. */ #ifndef DOMAIN #define DOMAIN "UUEnview.Default.Domain" #endif /* * If you define this, the hostname will not appear in the posting * data except on the path. Items will be from user@DOMAIN (with * DOMAIN as defined above). If you don't want this, comment it out. */ #ifndef HIDDENNET /* #define HIDDENNET 1 */ #endif /* * You shouldn't need to touch anything below this line. */ /* * This is the code needed to get the proper hostname. * * nn provides a gethostname function for generic use. * we fake uname() for inews.c using this: */ #define uname(str) gethostname(str, sizeof(str)) /* * Stock nntp inews and nn use some different #define names for the * same general functions. This synchronises them. */ #define SERVER_FILE NNTP_SERVER /* * Reverse engineering (nn got this the other way around).... */ /* * Sanity checks (You know. Checks you get from Sanity Claus) */ #ifdef HIDDENNET #ifndef DOMAIN YOU_BLEW_IT READ_THE_INSTRUCTIONS_AGAIN #endif #endif #endif /* of ifdef NNINEWSCONF_H */ uudeview-0.5.20.orig/inews/inews.c0000644001167100001440000001776610006066173016764 0ustar cphusers00000000000000#ifndef lint static char *sccsid = "@(#)inews.c 1.16 (Berkeley) 8/27/89"; #endif /* * Itty-bitty inews for talking to remote server. * Simply accept input on stdin (or via a named file) and dump this * to the server; add a From: and Path: line if missing in the original. * Print meaningful errors from the server. * Limit .signature files to MAX_SIGNATURE lines. * No processing of command line options. * * Original by Steven Grady , with thanks from * Phil Lapsley * Send bug reports to Stan Barber */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include #include #ifdef HAVE_PWD_H #include #endif /* * standard defines __FP__ */ #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #include "conf.h" #include "nntp.h" #define MAX_SIGNATURE 6 extern FILE *ser_wr_fp; char host_name[256]; main(argc, argv) int argc; char *argv[]; { char line[NNTP_STRLEN], s[NNTP_STRLEN]; int seen_fromline, in_header, seen_header; int response; char *server; char *getserverbyfile(); register char *cp; ++argv; while (argc > 1) if (*argv[0] == '-') { ++argv; --argc; } else break; if (argc > 1) { if (freopen(*argv, "r", stdin) == NULL) { perror(*argv); exit(1); } } uname(host_name); server = getserverbyfile(SERVER_FILE); if (server == NULL) { fprintf(stderr, "Can't get the name of the news server from %s.\n", SERVER_FILE); fprintf(stderr, "Either fix this file, or put NNTPSERVER in your enviroment.\n"); exit(1); } response = server_init(server); if (response < 0) { printf("Couldn't connect to %s news server, try again later.\n", server); exit(1); } if (handle_server_response(response, server) < 0 || response == OK_NOPOST) { close_server(); exit(1); } put_server("POST"); (void) get_server(line, sizeof(line)); if (*line != CHAR_CONT) { if (atoi(line) == ERR_NOPOST) { close_server(); fprintf(stderr, "Sorry, you can't post from this machine.\n"); exit(1); } else { close_server(); fprintf(stderr, "Remote error: %s\n", line); exit(1); } } in_header = 1; seen_header = 0; seen_fromline = 0; while (fgets(s, NNTP_STRLEN, stdin) != NULL) { while (s[0] && (s[strlen(s)-1] == '\r' || s[strlen(s)-1] == '\n')) s[strlen(s)-1] = '\0'; if (s[0] == '.') /* Single . is eof, so put in extra one */ (void) fputc('.', ser_wr_fp); if (in_header && strneql(s, "From:", sizeof("From:")-1)) { seen_header = 1; seen_fromline = 1; } if (in_header && s[0] == '\0') { if (seen_header) { in_header = 0; if (!seen_fromline) gen_frompath(); } else { continue; } } else if (in_header) { if (valid_header(s)) seen_header = 1; else continue; } fprintf(ser_wr_fp, "%s\r\n", s); } append_signature(); fprintf(ser_wr_fp, ".\r\n"); (void) fflush(ser_wr_fp); (void) get_server(line, sizeof(line)); if (*line != CHAR_OK) { if (atoi(line) == ERR_POSTFAIL) { close_server(); printf("Article not accepted by server; not posted.\n"); for (cp = line + 4; *cp && *cp != '\r'; cp++) if (*cp == '\\') putchar('\n'); else putchar(*cp); exit(1); } else { close_server(); fprintf(stderr, "Remote error: %s\n", line); exit(1); } } /* * Close server sends the server a * "quit" command for us, which is why we don't send it. */ close_server(); exit(0); } /* * append_signature -- append the person's .signature file if * they have one. Limit .signature to MAX_SIGNATURE lines. * The rn-style DOTDIR environmental variable is used if present. */ append_signature() { char line[256], sigfile[256]; char *cp; struct passwd *passwd; FILE *fp; int count = 0; char *dotdir; passwd = getpwuid(getuid()); if (passwd == NULL) return; #ifdef DO_DOTDIR if ((dotdir = getenv("DOTDIR")) == NULL) #endif { dotdir = passwd->pw_dir; } if (dotdir[0] == '~') { (void) strcpy(sigfile, passwd->pw_dir); (void) strcat(sigfile, &dotdir[1]); } else { (void) strcpy(sigfile, dotdir); } (void) strcat(sigfile, "/"); (void) strcat(sigfile, ".signature"); #ifdef DEBUG fprintf(stderr,"sigfile = '%s'\n", sigfile); #endif fp = fopen(sigfile, "r"); if (fp == NULL) return; #ifdef DEBUG fprintf(stderr,"sigfile opened OK\n"); #endif fprintf(ser_wr_fp, "--\r\n"); while (fgets(line, sizeof (line), fp)) { count++; if (count > MAX_SIGNATURE) { fprintf(stderr, "Warning: .signature files should be no longer than %d lines.\n", MAX_SIGNATURE); fprintf(stderr, "(Only %d lines of your .signature were posted.)\n", MAX_SIGNATURE); break; } if (cp = strchr(line, '\n')) *cp = '\0'; fprintf(ser_wr_fp, "%s\r\n", line); } (void) fclose(fp); #ifdef DEBUG printf(".signature appended (from %s)\n", sigfile); #endif } /* * gen_frompath -- generate From: and Path: lines, in the form * * From: user@host.domain (full_name) * Path: host!user * * This routine should only be called if the message doesn't have * a From: line in it. */ gen_frompath() { char *full_name; char *cp; struct passwd *passwd; passwd = getpwuid(getuid()); full_name = getenv("NAME"); if (full_name == NULL) { full_name = passwd->pw_gecos; if ((cp = strchr(full_name, ','))) *cp = '\0'; } /* * changed from #ifdef HIDDENNET __FP__ */ #ifdef DOMAINNAME #ifdef HIDDENNET fprintf(ser_wr_fp, "From: %s@%s (", passwd->pw_name, DOMAINNAME); #else /* A heuristic to see if we should tack on a domain */ cp = strchr(host_name, '.'); if (cp) fprintf(ser_wr_fp, "From: %s@%s (", passwd->pw_name, host_name); else fprintf(ser_wr_fp, "From: %s@%s.%s (", passwd->pw_name, host_name, DOMAINNAME); #endif #else fprintf(ser_wr_fp, "From: %s@%s (", passwd->pw_name, host_name); #endif for (cp = full_name; *cp != '\0'; ++cp) if (*cp != '&') putc(*cp, ser_wr_fp); else { /* Stupid & hack. God damn it. */ putc(toupper(passwd->pw_name[0]), ser_wr_fp); fprintf(ser_wr_fp, passwd->pw_name+1); } fprintf(ser_wr_fp, ")\r\n"); #ifdef HIDDENNET /* Only the login name - nntp server will add uucp name */ fprintf(ser_wr_fp, "Path: %s\r\n", passwd->pw_name); #else fprintf(ser_wr_fp, "Path: %s!%s\r\n", host_name, passwd->pw_name); #endif } /* * strneql -- determine if two strings are equal in the first n * characters, ignoring case. * * Parameters: "a" and "b" are the pointers * to characters to be compared. * "n" is the number of characters to compare. * * Returns: 1 if the strings are equal, 0 otherwise. * * Side effects: None. */ strneql(a, b, n) register char *a, *b; int n; { char lower(); while (n && lower(*a) == lower(*b)) { if (*a == '\0') return (1); a++; b++; n--; } if (n) return (0); else return (1); } /* * lower -- convert a character to lower case, if it's * upper case. * * Parameters: "c" is the character to be * converted. * * Returns: "c" if the character is not * upper case, otherwise the lower * case eqivalent of "c". * * Side effects: None. */ char lower(c) register char c; { if (isascii(c) && isupper(c)) c = c - 'A' + 'a'; return(c); } /* * valid_header -- determine if a line is a valid header line * * Parameters: "h" is the header line to be checked. * * Returns: 1 if valid, 0 otherwise * * Side Effects: none * */ int valid_header(h) register char *h; { char *colon, *space; /* * blank or tab in first position implies this is a continuation header */ if (h[0] == ' ' || h[0] == '\t') return (1); /* * just check for initial letter, colon, and space to make * sure we discard only invalid headers */ colon = strchr (h, ':'); space = strchr (h, ' '); if (isalpha(h[0]) && colon && space == colon + 1) return (1); /* * anything else is a bad header -- it should be ignored */ return (0); } uudeview-0.5.20.orig/inews/nntp.h0000644001167100001440000000474206155632124016616 0ustar cphusers00000000000000/* * Response codes for NNTP server * * @(#)nntp.h 1.7 (Berkeley) 1/11/88 * * First digit: * * 1xx Informative message * 2xx Command ok * 3xx Command ok so far, continue * 4xx Command was correct, but couldn't be performed * for some specified reason. * 5xx Command unimplemented, incorrect, or a * program error has occured. * * Second digit: * * x0x Connection, setup, miscellaneous * x1x Newsgroup selection * x2x Article selection * x3x Distribution * x4x Posting */ #define CHAR_INF '1' #define CHAR_OK '2' #define CHAR_CONT '3' #define CHAR_ERR '4' #define CHAR_FATAL '5' #define INF_HELP 100 /* Help text on way */ #define INF_DEBUG 199 /* Debug output */ #define OK_CANPOST 200 /* Hello; you can post */ #define OK_NOPOST 201 /* Hello; you can't post */ #define OK_SLAVE 202 /* Slave status noted */ #define OK_GOODBYE 205 /* Closing connection */ #define OK_GROUP 211 /* Group selected */ #define OK_GROUPS 215 /* Newsgroups follow */ #define OK_ARTICLE 220 /* Article (head & body) follows */ #define OK_HEAD 221 /* Head follows */ #define OK_BODY 222 /* Body follows */ #define OK_NOTEXT 223 /* No text sent -- stat, next, last */ #define OK_NEWNEWS 230 /* New articles by message-id follow */ #define OK_NEWGROUPS 231 /* New newsgroups follow */ #define OK_XFERED 235 /* Article transferred successfully */ #define OK_POSTED 240 /* Article posted successfully */ #define CONT_XFER 335 /* Continue to send article */ #define CONT_POST 340 /* Continue to post article */ #define ERR_GOODBYE 400 /* Have to hang up for some reason */ #define ERR_NOGROUP 411 /* No such newsgroup */ #define ERR_NCING 412 /* Not currently in newsgroup */ #define ERR_NOCRNT 420 /* No current article selected */ #define ERR_NONEXT 421 /* No next article in this group */ #define ERR_NOPREV 422 /* No previous article in this group */ #define ERR_NOARTIG 423 /* No such article in this group */ #define ERR_NOART 430 /* No such article at all */ #define ERR_GOTIT 435 /* Already got that article, don't send */ #define ERR_XFERFAIL 436 /* Transfer failed */ #define ERR_XFERRJCT 437 /* Article rejected, don't resend */ #define ERR_NOPOST 440 /* Posting not allowed */ #define ERR_POSTFAIL 441 /* Posting failed */ #define ERR_COMMAND 500 /* Command not recognized */ #define ERR_CMDSYN 501 /* Command syntax error */ #define ERR_ACCESS 502 /* Access to server denied */ #define ERR_FAULT 503 /* Program fault, command not performed */ /* RFC 977 defines this; don't change it. */ #define NNTP_STRLEN 512 uudeview-0.5.20.orig/inews/version.c0000644001167100001440000000014406155632124017307 0ustar cphusers00000000000000/* * Provide the version number of this release. */ char nntp_version[] = "1.5.8 (11 March 90)"; uudeview-0.5.20.orig/man/0000755001167100001440000000000010020741142015070 5ustar cphusers00000000000000uudeview-0.5.20.orig/man/uudeview.10000644001167100001440000003403507646117305017036 0ustar cphusers00000000000000.\" $Id: uudeview.1,v 1.14 2003/04/12 23:18:29 fp Exp $ " .TH UUDEVIEW 1 "June 2001" .SH NAME UUDeview \- a powerful decoder for binary files .SH SYNOPSIS .B "uudeview [options] [@\fIfile\fP] \fIfile(s)\fP" .SH DESCRIPTION .I UUDeview is a smart decoder for attachments that you have received in encoded form via electronic mail or from the usenet. It is similar to the standard .BR uudecode (1) command, yet with more comfort and flexibility. .I UUDeview supports the .I uuencoding, xxencoding, Base64, yEncoding and .I BinHex encoding methods, and is able to handle split-files (which have been sent in multiple parts) as well as multiple files at once, thus greatly simplifying the decoding process. Usually, you will not have to manually edit files to prepare them for decoding. .PP After invoking .B uudeview, it will scan all given files for encoded data, sort them and their parts and then present you with the list of files that seem like they can be decoded properly. You can then pick files individually for decoding. .SH OPTIONS .SS BEHAVIOR .TP .B -i Disables interactivity. After scanning the files and sorting everything out, the program will not promt you for whether a file shall be decoded or not, but batch-decodes all available files. This is the default when reading from standard input. .TP .B -a Autorename option. If a target file already exists, and this option is given, a dot and a unique sequence number is appended to the file name. I.e., foo.gif becomes foo.gif.1 if decoded a second time. .TP .B +a An alternative incarnation of autorename. If a target file already exists, an underscore and a unique sequence number is inserted into the filename before the first dot, i.e., foo.gif becomes foo_1.gif. .TP .B -o Gives the OK to overwrite existing files when decoding. In interactive mode, the default is to prompt the user whether to overwrite, rename or skip the file. This option takes precedence over .B -a. In non-interactive mode (using .B -f ), the default is to overwrite files without asking. .TP .B +o Says it's not OK to overwrite files. This is useful in non-interactive mode, so that existing files are untouched. This has lesser precedence than -a. .TP .B -c Autoclear. Remove all input files that were successfully decoded. Use with care! UUDeview only checks if any data was decoded from an input file, but does not care about any other contents of that input file, or whether a file also held an incomplete attachment. .TP .BI -p " path" Sets the path where decoded files shall be written to. This must be a valid pathname, or you'll get errors when trying to decode anything. Defaults to the current working directory. .TP .B -m Ignore file mode. Uuencoded and xxencoded files have the original file permissions stored on the begin line. Unless this option is given, .I UUDeview will restore them without checking if they are sensible. With this option, the permissions are reset to a default of 0666. .SS TWEAKING .TP .B -z Enforces stricter MIME adherance. Normally, the program tries to find encoded data even in "text/plain" plaintext parts of MIME messages. With this option given, .I UUDeview will limit this capability, and will not accept apparently incomplete encoded messages (for example, seemingly uuencoded data without begin or end lines). You can tighten this option even more by using it twice, or by using .B -z2. Then, .I UUDeview will not check plaintext sections of MIME messages for encoded data at all and behave fully MIME-compliant. Neither option affects the behavior on non-MIME input files. This option needs a better name, but I'm slowly running out of option letters. .TP .B -f Uses fast mode for file scanning. The program assumes that each input file holds at most one part, which is usually true for files in a news spool directory. This option .B breaks decoding of input files with multiple articles. Also, certain sanity checks are disabled, probably causing erroneous files to be presented for decoding. Sometimes you'll get error messages when decoding, sometimes you'll just receive invalid files. Don't use .B -f if you can't live with these problems. .TP .B -r Ignore reply messages, i.e. all messages whose subject starts with Re: .TP .B -t Use plaintext messages. Usually, UUDeview only presents encoded data for decoding. Plaintext messages are only shown if they have an associated file name. With this option set, unnamed text parts from .I MIME messages and non-encoded messages are also offered. Unnamed messages are assigned a unique name in the form of a sequential four-digit number. .TP .B -d Sets the program into desperate mode. It will then offer you to decode incomplete files. This is useful if you are missing the last part of a 50-parts posting, but in most cases the desperately-decoded files will simply be corrupt and unusable. The degree of usefulness of an incomplete file depends on the file type. .TP .B -b This changes .I UUDeview's "bracket policy." .I UUDeview looks at a message's subject line, and reads numbers in brackets as the part number, as in (3/7), which is read as the third message in a series of seven. By default, numbers in parentheses () are preferred over numbers in brackets []. You can change this using either .B -b or, for clarity .BI -b []. .TP .B -s Read "minus smartness". This option turns off automatic part number detection from the subject line. Try this option if .I UUDeview fails to parse the subject line correctly and makes errors at guessing part numbers, resulting in incorrect ordering of the parts. With this option, parts are always put together sequentially (so the parts must be correctly ordered in the input file). Also, with this option, the program cannot detect that parts are missing. .B Note: The correct part number found in proper .I MIME files is still evaluated. If this option is given twice, the subject itself is ignored, too, and won't be used to group parts. Use if the messages that the parts come delivered in have different subject lines. .SS OTHER OPTIONS .TP .B -q (Quiet) Disables verbosity. Normally, the program prints some status messages while reading the input files, which can be very helpful if something should go wrong. Use if these messages disturb you. .TP .B -n No progress bars. Normally, UUDeview prints ASCII bars crawling up to 100 percent, but does not check if your terminal is capable of displaying them. Use this switch if your terminal isn't, or if you find the bars annoying. .TP .BI +e " exts" Selects only the files with the given extensions for decoding, others will be ignored. .BI +e " .gif.jpg" would decode all gif and jpeg files, but not tif or other files. The list of extensions works case-insensitive. .TP .BI -e " exts" The reverse of the above. .PP You will experience unwanted results if you try to mix \+e and \-e options on the command line. .SS INPUT OPTIONS .TP .I file(s) The files to be scanned for encoded files. You can also give a single hyphen \'\-\' to read from standard input. Any number of files may be given, but there is usually a limitation of 128 options imposed by the shell. If you are composing the list of files with wildcards, make sure you don't accidentally feed the program with binary files. This will result in undefined behaviour. .TP .BI @ file Makes .I UUDeview read further options from the file. Each line of the file must hold exactly one option. The file .B is erased after the program finishes. This feature may be used to specify an unlimited number of files to be scanned. Combined with the powers of .BR find (1), entire directory trees (like the news spool directory) can be processed. .PP Options may also be set in the $UUDEVIEW environment variable, which is read before processing the options on the command line. .SH DECODING After all input files have been scanned, you are asked for each file what do do with it. Of course, the usual answer is to decode it, but there are other possibilities. You can use the following commands (each command is a single letter): .TP .B d (D)ecode the file and write the decoded file to disk, with the given name. .TP .B y (Y)es does the same as (d). .TP .B x E(x)tract also decodes the file. .TP .B a Decodes all remaining files without prompting. .TP .B n Skips this file without decoding it. .TP .B b Steps back to the previous file. .TP .B r Rename. You can choose a different name for the file in order to save it under this new name. .TP .B p Set the path where decoded files shall be written to. This path can also be set with the -p command line option. .TP .B i Displays info about the file, if present. If a multipart posting had a zeroeth part, it is printed, otherwise the first part up to the encoded data is printed. .TP .B e Execute a command. You can enter any arbitrary command, possibly using the current file as an argument. All dollar signs '$' in this command line are replaced with the filename of the current file (speaking correctly, the name of a temporary file). You should not background processes using this temporary file, as programs might get confused if their input file suddenly disappears. .TP .B l List a file. Use this command only if you know that the file in question is a textfile, otherwise, you'll get a load of junk. .TP .B q Quits the program immediately. .TP .B ? Prints a short description of all these commands. .PP If you don't enter a command and simply hit return at the prompt, the default command, decoding the file, is used. .SH RUNTIME MESSGAGES In verbose mode (that is, if you didn't disable verbosity with the -v option), progress messages will appear. They are extremely helpful in tracing what the program does, and can be used to figure out the reason why files cannot be decoded, if you understand them. This section explains how to interpret them. Understanding this section is not essential to operate the program. .PP First, there are "Loading" messages, which begin with the string "Loaded". Each line should feature the following items: .TP .B Source File The first item is the source file from which a part was loaded. Many parts can be detected within a single file. .TP .B Subject Line The complete subject is reproduced in single quotes. .TP .B Identifier The program derives a unique identification for this thread from the subject line, for grouping articles that look like they belong to the same file. The result of this algorithm is presented in braces. .TP .B Filename If a filename was detected on the subject line or within the data (for example, on a begin line, or as part of the Content-Type information). .TP .B Part Number The part number derived from the subject line, or, in the case of properly MIME-formatted messages, from the "part" information. .TP .B Begin/End If a "begin" or "end" token was detected, it is printed here. .TP .B Encoding Type If encoded data was detected within this part, either "UUdata", "Base64", "XXdata" or "Binhex" is printed here. .PP More messages are printed after scanning has completed. A single line will be printed for each group of articles. The contents of this line are best understood by looking at an example. Here is one: .PP .B Found 'mailfile.gz' State 16 UUData Parts begin 1 2 3 4 5 end 6 OK .PP This indicates that the file .I mailfile.gz has been found. The file was uuencoded ("UUData") and consists of 6 parts. The "begin" token was found in the first part, and the "end" token was found in the sixth part. Because it looks like everything's there, this file is tagged as being "OK". The .I State is a set of bits, where the following values may be or'ed: .TP .B 1 Missing Part .TP .B 2 No Begin .TP .B 4 No End .TP .B 8 No encoded data found. .TP .B 16 File looks Ok .TP .B 32 An error occured during decoding of the file. .TP .B 64 File was successfully decoded. .SH NOTES Because the program cannot receive terminal input when a file is being read from standard input, interactivity is automatically disabled in this case. .PP UUDeview is aware of MIME messages, but normally ignores strict MIME compliance in favor of finding unproperly encoded data within them, e.g. to succeed when individual parts of a uuencoded file have been sent with a MIME mailer as MIME messages. For that, it subjects all "text/plain" parts of a message to encoding detection. You can use the .B -z option (see above) for more strict RFC2045 compliance. .PP The scanner tends to ignore short Base64 data (less than four lines) outside of MIME messages. Some checks for this condition are used in desperate mode, but they may cause misdetection of encoded data, resulting in some invalid files. .PP Files are always decoded into a temporary file first, then this file is copied to the final location. This is to prevent accidentally overwriting existing files with data that turns out too late to be undecodeable. Thus be careful to have twice the necessary space available. Also, when reading from standard input, all the data is dumped to a temporary file before starting the usual scanning process on that file. .PP .B uudeview tries to derive all necessary information from the Subject: line if present. If it holds garbage, or if the program fails to find a unique identification and the part number there, .B uudeview might still be able to decode the file using other heuristics, but you'll need major luck then. .PD 0 .PP Yet this is only a concern with split-files. If all encoded files only consist of single parts, don't worry. .PD .PP If you rename, copy or link the program to .BR uudecode , it may act as a smart replacement for the standard, accepting the same command-line options. This has not been well-tested yet. .SH "SEE ALSO" .BR uuenview (1), .BR uudecode (1), .BR uuencode (1). .PD 0 .PP The .I UUDeview homepage on the Web, .PD 0 .PP http://www.fpx.de/fp/Software/UUDeview/ .PD .SH BUGS To read a file whose name starts with a hyphen '-', prepend a path name, for example './'. .PP The checksums found in .I BinHex data are ignored. .PP The program cannot fully handle partial multipart messages (MIME-style multipart messages split over several mail messages). The individual parts are recognized and concatenated, and the embedded multipart message is "decoded" into a plain-text file, which must then be fed again to .B uudeview. Don't worry, these kinds of messages are rare. .PP UUDeview cannot decipher RFC 1522 headers. uudeview-0.5.20.orig/man/uuenview.10000644001167100001440000001623707441420120017035 0ustar cphusers00000000000000.\" $Id: uuenview.1,v 1.12 2002/03/06 13:57:36 fp Exp $ " .TH UUENVIEW 1 "June 2001" .SH NAME uuenview \- a powerful encoder for binary files .SH SYNOPSIS .B "uuenview [options] \fIfile(s)\fP" .br .SH DESCRIPTION .B uuenview encodes a binary file into ASCII text for sending over non-8-bit electronic data channels, such as electronic mail or the usenet. .B uuenview is a superset of and fully backwards compatible with the standard .BR uuencode (1) command, featuring more comfort and more flexibility. .PP Files encoded with .B uuenview are compatible with virtually all decoders, as long as the encoding method (see below) is supported by the remote side. If the remote side uses .BR uudeview (1), there shouldn't be any problems at all. .PP If properly configured, .B uuenview can directly send encoded files by email or to the usenet. These messages are wrapped into a proper MIME envelope, which is handy if the recipient uses MIME-compliant mail or news software. .SH OPTIONS .SS ENCODING SELECTION .TP .B -b Chooses the .I Base64 encoding method as specified by the .I MIME standard. .TP .B -u Chooses the .I uuencoding method, for compatibility with .BR uuencode (1). .TP .B -y Chooses the .I yEncoding method. .TP .B -x Chooses the now obsolete .I xxencoding method. .TP .B -t Sends the file(s) as plain text. .TP .B -q Encodes the file(s) using quoted printable encoding. .PP These options are positional and affect the encoding of all remaining files on the command line until changed. .PP When sending, posting or attaching files, the default is to use Base64, resulting in MIME compliant messages. Otherwise, when encoding to standard output or into a file, the default is to use uuencoding. .SS TARGETS .TP .B -o Specifies that output shall be written into files. These files will have the same base name as the source file and an extension of .B .001, .002 etc, depending on the number of parts required by the .B \-lines option. The encoded files are written to the current directory. .TP .BI -od " path" Same as '-o', but the encoded files are written to the given directory instead. .TP .BI -m " email" Mails the encoded file(s), each one probably split into multiple parts, to the given email address. Multiple recipients can be given as a quoted, comma-separated list. On Unix systems, mail is usually piped to .BR sendmail (8). .TP .BI -p " newsgroup" Posts the encoded file(s), each one probably split into multiple parts, to the given newsgroup. Multiple newsgroups can be given as a quoted, comma-separated list. The .BR inews (1) program is invoked for posting. You may have to set the .I NNTPSERVER enviroment variable to your news server. .TP .B -a Attaches files. This feature is expected to be used from shell scripts and the like. In attach mode, a message is read from standard input, complete with headers. The files given on the command line are then "attached" to the message, which is converted, if necessary, to a proper MIME multipart format. The .B -a option can be combined with .B -m or .B -p in order to directly mail or post the result. Else, the message, complete with attachments, is written to standard output. .PP If no target option is given, the encoded data is printed to standard output. .SS HEADERS When mailing or posting a file, it is possible to set certain headers. Be careful to quote parameters that consist of more than one word. .TP .BI -s " subject" Set the .I Subject: header line. The file name and part number are automatically appended. Without this, a default subject header is generated. .TP .BI -f " from" Set the .I From: header line. .TP .BI -r " reply" Set the .I Reply-To: header line. .SS OTHER .TP .B -v Verbosely prints everything the program's trying to do. .TP .BI - lines Substituting .I lines with a number, sets the maximum number of encoded lines per part. The encoded data is automatically split into as many parts as required. Line counts less than 200 are ignored. The uuencoding and xxencoding methods encode 45k, and Base64 encodes 57k of data in 1000 lines. If this option is not specified, the default is unlimited lines per part, resulting in exactly one part. .TP .I file(s) One or more filenames to be processed. To encode a file from the standard input, use a single hyphen '\-' and give a filename to be used for the encoded file as the next parameter. .PP Options may also be set in the $UUENVIEW environment variable, which is read before processing the options on the command line. .SH NOTES .PP Files read from standard input can only be used once, meaning that at most one target option may be given. .PP Output written to standard output cannot be split into multiple parts. In this case, the .BI - lines option is ignored. .PP .B uuenview must be correctly configured at compile time in order for mailing and posting to work. If it doesn't, consult your system administrator. The program used for posting a file can be set at runtime using the .I INEWS environment variable. This setting overrides the compile-time configuration. .PP Base64 is not MIME. Base64 is the encoding specified by the MIME standard, but in order for a message to become a proper MIME message, a number of headers are required. .B uuenview produces these headers when mailing or posting, but not when writing to a file. In this case, .B uuenview does not have any control over the headers. If you include Base64 output into your messages, they are .B not MIME-compliant! .PP If you rename, copy or link the program to .BR uuencode , it may act as a smart replacement for the standard, accepting the same command-line syntax. This has not been well-tested yet. .SH EXAMPLES .TP .B uuenview -m 'root,fred@somewhere.com' uudeview.tgz Encodes the file .I uudeview.tgz and mails it to both your local system administrator and to your friend Fred at the Somewhere company. .PP If you give more than one filename on the command line, each file is usually handled separately. A workaround is to send them all as attachment to a single (or empty) mail: .TP .B uuenview -m root -b -a file1 file2 < /dev/null Creates an empty mail and attaches the two given files, encoded in Base64 format, and mails the result to your system administrator. .SH "SEE ALSO" .BR uudeview (1), .BR uuencode (1), .BR uudecode (1), .BR sendmail (8), .BR inews (1). .PD 0 .PP The .B uudeview homepage on the Web, .PD 0 .PP http://www.fpx.de/fp/Software/UUDeview/ .PD .SH BUGS .PP The program does not detect error conditions when mailing or posting. .PP Attaching only works reliably if certain headers of the input message (for example Content-Type) are not folded and shorter than 1024 characters. .PP It is not possible to encode into BinHex. .PP The program will quite likely fail to handle binary data as input for plain text or quoted-printable attachments. On plain text attachments, the line length (must be less than 998 characters according to MIME) is not enforced. .PP It is not possible to set the "charset" value of plain text attachments. .PP It is not possible to set the content type value of attachments. .PP .BR sendmail (8) stops reading upon a line consisting only of a single dot. .I uudeview does not check plain text input files against this condition. (The problem is worked around when using quoted-printable, and does not exist with the other encodings.) uudeview-0.5.20.orig/man/xdeview.10000644001167100001440000004454607306733320016656 0ustar cphusers00000000000000.\" $Id: xdeview.1,v 1.6 2001/06/04 16:26:56 fp Exp $ " .TH XDEVIEW 1 "June 1996" .SH NAME xdeview \- a powerful decoder for binary files .SH SYNOPSIS .B "xdeview [Xt options] [-- options] [\fIfile(s)\fP]" .br .SH DESCRIPTION .I XDeview is a smart decoder for attachments that you have received in encoded form via electronic mail or from the usenet. It is similar to the standard .BR uudecode (1) command, yet with more comfort and flexibility. .I XDeview supports the .I uuencoding, xxencoding, Base64 and .I BinHex encoding methods, and is able to handle split-files (which have been sent in multiple parts) as well as multiple files at once, thus greatly simplifying the decoding process. Usually, you will not have to manually edit files to prepare them for decoding. .PP If you don't really need a graphical frontend for these kinds of jobs, have a look at .BR uudeview (1) and .BR uuenview (1). .PP After invoking the program, it will scan all the given files for encoded data. If any of them were directories, they will be recursively dived into. You don't need to give files on the command line; you can also select files later from within the program. After completing the initial scan, you will be presented with a list of files that seem like they can be decoded properly. You can then pick files individually for decoding. .SH OPTIONS There's no real need to set options on the command line; they can also be set from within the program. Note that options must be preceded by a double-hyphen '--', otherwise they might be mistaken for display options. .TP .B -d Sets the program into desperate mode. It will then offer you to decode incomplete files. This is useful if you are missing the last part of a 50-parts posting, but in most cases the desperately-decoded files will simply be corrupt and unusable. The degree of usefulness of an incomplete file depends on the file type. .TP .B -f Uses fast mode for file scanning. The program assumes that each input file holds at most one part, which is usually true for files in a news spool directory. This option .B breaks decoding of input files with multiple articles. Also, certain sanity checks are disabled, probably causing erroneous files to be presented for decoding. Sometimes you'll get error messages when decoding, sometimes you'll just receive invalid files. Don't use .B -f if you can't live with these problems. .TP .B -o Gives the OK to overwrite files already there on decoding. The default is to prompt the user whether to overwrite, rename or skip the file. .TP .B -v Disables verbosity. Normally, the program prints some status messages while reading the input files, which can be very helpful if something should go wrong. Use if these messages disturb you. .TP .B -p path Sets the path where decoded files shall be written to. This must be a valid pathname, or you'll get errors when trying to decode anything. Defaults to the current working directory. .TP .B -b This changes .I xdeview's policy of finding a part number on a subject line and may only be needed in some rare cases when part numbers are found in () parentheses as well as in [] brackets, for example in a series of multi-part postings. By default, .I xdeview uses the numbers found in () parentheses first. But if this number indicates the file's number in the series and the part number is given in [] brackets, use this parameters to make the program read the other number first. This does not affect decoding of files with only one or neither type of brackets. If you prefer, you can also use the option as .B -b[] .TP .B -s Read "minus smartness". This option turns off automatic part number detection from the subject line. Try this option if .I xdeview fails to parse the subject line correctly and makes errors at guessing part numbers, resulting in incorrect ordering of the parts. With this option, parts are always put together sequentially (so the parts must be correctly ordered in the input file). .B Note: The correct part number found in proper .I MIME files is still evaluated. .TP .B -t Use plaintext messages. Usually, XDeview only presents encoded data for decoding. With this option set, text parts from .I MIME messages and non-encoded messages are also offered. Plaintext messages frequently don't have an associated filename, so they're assigned a unique name from a sequential four-digit number. .SH MAIN MENU The main window of .I xdeview is composed of six main elements. At the top is the .I Menu Bar. Centered is the .I File List, which lists all the files that have been detected in the encoded data and are ready for decoding. Left of the File List is the .I Status List, which describes the status of each file. Usually, this list will show "OK" for all files, as display of erroneous files is normally suppressed. On the right is a bunch of short-cut buttons with the most heavily-used functions. At the bottom of the window is the .I Save Path entry field, and the status bar. Each of these items will be described individually in the following text. .SH MENU BAR .TP .B File Menu .RS .TP .B Load ... Loads encoded files. These files are then scanned for encoded data and files; these files are added to the File List. You can also select directories, which are then recursively descended into .TP .B Encode Encode file(s), storing the encoded data on disk, sending them via email, or posting them to newsgroups. See below. .TP .B Helpers Xdeview reads information from your .mailcap and .mime.types to perform the appropriate default action when you hit the "Execute" button. In this dialogue, you can configure the locations of these files. .TP .B Save Setup Saves all current options, the input and output file paths etc. into the .xdeviewrc file in your home directory. This file is automatically read upon startup, so the saved settings will be set by default in future sessions. The resource file is actually a Tcl script which you can edit with any editor. .TP .B Quit Exits the program. .RE .TP .B Options Set various options that modify the behaviour of the program. Note that most options only catch for files read afterwards. .RS .TP .B Fast Scanning Sets fast scanning mode. The program will then assume that all input files contain at most one encoded part (as it is true with files from a news spool). The scanning engine will be sped up because it does not have to read each input file completely but stops scanning after encoded data has been found. .PP The decoder has to disable some safety options in fast mode, so certain problems with the file will only be detected when finally decoding the file. .TP .B Automatic Overwrite When decoding a file which is already present in the target directory, the user will be asked whether the file shall be overwritten. By enabling this option, target files will be overwritten without asking. .TP .B Desperate Mode Usually, you will only be presented files to which all parts have been found. Enabling Desperate Mode, you'll also get to see the other files as well, with an appropriate description of the problem in the Status List. In desperate mode, the decoder will also try to detect short Base64 files outside of MIME messages. This is normally disabled, because these desperate tries to find Base64 encoding may cause misdetection of encoded data, again resulting in invalid files. .TP .B Verbose Mode Opens a separate text box to which additional messages will be written while scanning the input files. These messages are extremely helpful for finding out what went wrong if files cannot be decoded properly. .TP .B Alternate Bracket Policy Changes the heuristics by which the decoder tries to extract a part number from the subject line. The algorithm usually gives numbers in braces () higher priority than numbers in brackets []. If both kinds of brackets are present, and their use is conflicting (for example if both the part number and a series number are given), then you may have to explicitely select the bracket policy. If this option is false (default), then the "part number" is taken from the braces (), otherwise from the brackets []. .TP .B Dumb Mode Disables automatic part number detection by parsing the subject line. Use if .I xdeview fails to pick up the correct part numbers. Note that with the option set, the parts must be correctly ordered in the input files. Also, missing parts will not be detected this way. .TP .B Handle Text Files Usually, XDeview only presents encoded data for decoding. With this option set, text parts from .I MIME messages and non-encoded messages are also offered. Plaintext messages frequently don't have an associated filename, so they're assigned a unique name from a sequential four-digit number. .TP .B Auto Info Opens up the information window whenever you click on a file in the File List. .TP .B Remove Input Files With this option set, input files are removed if any file was successfully decoded from them. Use with care! UUDeview only checks if any data was decoded from an input file, but does not care about any other contents of that input file, or whether a file also held an incomplete attachment. .TP .B MIME Compliance Be more strict when reading MIME input files. .RE .TP .B Actions .RS .TP .B Decode Decode the selected file(s). .TP .B Rename Rename the selected file(s), for example if the filename conflicts with existing files, or if the name doesn't meet system limitations. .TP .B Decode All Decode all files currently visible in the File List. .TP .B Info Displays available info on the currently selected file (if more than one file is selected, only info for the first will be displayed). This is the zeroeth part of a file, if available, or the header of the first part up to the beginning of encoded data. .TP .B Execute Runs an external program with the currently selected file. A program is selected by first looking at the .I Content-Type of the message, if available, then by checking the file's extension. The appropriate information is read from your .B .mailcap and .B .mime.types files (although the handling of information in .mailcap files is currently incomplete). If no matching type is found, a dialog box pops up where you can enter any command. .TP .B List Text File This is for the rare cases when a text file has been sent through the net in encoded form. Use this action only when you know the file in question is in fact a text file, otherwise you'll get a load of trash on the screen. .RE .TP .B Help .RS .TP .B About A short message from the Author. .TP .B License Displays the license under which xdeview is distributed, the .B GPL. Read it, or you'll hear from my lawyers. .SH FILE LIST The File List is a list box displaying all the files that have been picked up while scanning the encoded data. These files are ready for decoding, previewing or anything. The list can be scrolled using the scrollbar on the right of the list. .PP Individual files can be selected simply by clicking on them. Multiple files can be selected by holding down the .I CTRL key and clicking on the individual files. .SH STATUS LIST The Status Lists notes the corresponding status for each file in the .I File List, Usually, you'll just see "OK" here; otherwise, an error message is shown describing why the file cannot be decoded properly. There are the following states: .TP .B OK All parts of the file have been found, and the encoded data looks correct on first sight. There are certain problems that might only appear when decoding the file, but usually everything is fine. .TP .B Incomplete This file is missing one or more parts. If you decode this file, the output data will be corrupt and usually unusable. .TP .B No Begin The file doesn't have a beginning. The decoded file will be most certainly corrupt and unusable. .TP .B No End No end was found on the file. This usually means that one or more parts at the end are missing. The degree of usefulness of a decoded file depends on the file type. .TP .B Error A previous attempt to decode the file has failed. .SH SHORT-CUT BUTTONS The buttons on the right side of the window are short-cuts for the menu items. Read the discussion of the Main Menu items above for an explanation. .SH SAVE PATH This is the path where decoded files will be written to. .SH STATUS A short message what the program is currently doing or what it expects you to do. .SH ENCODING MENU When encoding files ("Encode" from the "File" menu), a large dialog box opens where you can set various options for the file. If you selected multiple files for encoding, a status line at the top displays the number of files left. The dialog itself stays open until all files have been handled. .TP .B Filename The current file to encode. You cannot edit this field. .TP .B Send As The file name by which the file will be sent. Defaults to the filename stripped of all directory information. .TP .B Use Subject When mailing or posting, this text will be used as subject. The filename and part numbers are added automatically, so you can choose to leave this line empty. .TP .B Lines per File Sets the number of encoded lines per part. Bigger files will be automatically split into multiple parts. Use if you are posting files to a newsgroup, or if the recipient's system cannot handle large files. A good splitting size is 1000 lines. "0" lines means not to split. .TP .B ... Encoding Selects the encoding method to use. If you wonder which one's the best, you might find a clue in my article "Introduction to Decoding". .TP .B File In (Path) Sets a directory where to encode the file to. The encoding will go to files with the same base name as the original file, but with extensions of .001, .002 (depending on the number of necessary parts as enforced by the "Lines per File" setting). .TP .B Email To Give a comma-separated list of email addresses. This option might be disabled if your system does not allow sending of emails. .TP .B Post To Here you can enter a comma-separated list of newsgroups to which the file should be posted. This option might be disabled if your system does not support posting news. .TP .B NNTP Server This field only appears on some systems, in the case that a news host is needed, but none was configured at compile-time. If this field does appear, you must enter a valid host name here in order for posting to work. If you don't want to post the file anyway, don't worry about it. .TP .B OK Performs the selected action(s) on this file and skips to the next one. .TP .B OK to All Uses these settings for each file in question (does not prompt you for the other files), thus sending all files at once. .TP .B Next Does not encode the file and skips to the next one (sorry, there's no button to skip backwards). .TP .B Cancel Cancels encoding and returns to the main menu. .SH SETUP FILE If it exists, the file .I .xdeviewrc in your home directory will be executed in the Tcl interpreter during program initialization. It must be a valid Tcl program, which you can use to set certain options by default. For the Tcl-illaterate: variables can be set using the following syntax: .PD 0 .PP .B set var_name value .PP .PD The following variables (options) can be set (look at the text above for an explanation of what they're doing) .TP .B OptionFast If set to 1, use fast scanning mode. .TP .B OptionBracket If set to 1, use the alternate bracket policy. .TP .B OptionOverwrite If set to 1, assume it's Ok to overwrite files without asking. .TP .B OptionDesperate If set to 1, switch into desperate mode. .TP .B OptionVerbose If set to 1, print progress messages. .TP .B SaveFilePath This is a string variable with the default Save Path, where you want decoded files to go. .TP .B EncodeMaxLines Maximum number of lines per file for encoding. "0" for unlimited. .TP .B EncodeEncoding Default encoding to use. "0" for UUencoding, "1" for XXencoding and "2" for Base64 encoding. .TP .B NNTPServer The address of your NNTP server (only needed on some systems). Can also be set (preferredly) in your environment variable .I NNTPSERVER. .SH RUNTIME MESSGAGES If you have enabled verbose mode, progress messages will appear in an own text window titled .I Runtime Messages. The messages generated during the scanning phase are extremely helpful in tracing what the program does, and can be used to figure out the reason why files cannot be decoded, if you understand them. This section explains how to interpret them. Understanding this section is not necessary to operate the program. .PP First, there are "Loading" messages, which begin with the string "Loaded". Each line should feature the following items: .TP .B Source File The first item is the source file from which a part was loaded. Many parts can be detected within a single file. .TP .B Subject Line The complete subject is reproduced in single quotes. .TP .B Identifier The program derives a unique identification for this thread from the subject line, for grouping articles that look like they belong to the same file. The result of this algorithm is presented in braces. .TP .B Filename If a filename was detected on the subject line or within the data (for example, on a begin line, or as part of the Content-Type information). .TP .B Part Number The part number derived from the subject line, or, in the case of properly MIME-formatted messages, from the "part" information. .TP .B Begin/End If a "begin" or "end" token was detected, it is printed here. .TP .B Encoding Type If encoded data was detected within this part, either "UUdata", "Base64", "XXdata" or "Binhex" is printed here. .PP More messages are printed after scanning has completed. A single line will be printed for each group of articles. The contents of this line are best understood by looking at an example. Here is one: .PP .B Found 'mailfile.gz' State 16 UUData Parts begin 1 2 3 4 5 end 6 OK .PP This indicates that the file .I mailfile.gz has been found. The file was uuencoded ("UUData") and consists of 6 parts. The "begin" token was found in the first part, and the "end" token was found in the sixth part. Because it looks like everything's there, this file is tagged as being "OK". The .I State is a set of bits, where the following values may be or'ed: .TP .B 1 Missing Part .TP .B 2 No Begin .TP .B 4 No End .TP .B 8 No encoded data found. .TP .B 16 File looks Ok .TP .B 32 An error occured during decoding of the file. .TP .B 64 File was successfully decoded. .SH NOTES If you cannot execute .I xdeview, and it reports something like "command not found", but are sure that the file itself can be found, check the reference to the main file .I uuwish at the top of the file. .SH SEE ALSO .BR uudeview (1), .BR uuenview (1), .BR uudecode (1), .BR uuencode (1), .PD 0 .PP The .I uudeview homepage on the Web, .PD 0 .PP http://www.fpx.de/fp/Software/UUDeview/ uudeview-0.5.20.orig/tcl/0000755001167100001440000000000010020741142015077 5ustar cphusers00000000000000uudeview-0.5.20.orig/tcl/Makefile.in0000644001167100001440000000424007306733321017161 0ustar cphusers00000000000000# # # ============================================================================ # # Makefile for the Tcl/Tk stuff of UUDeview # # ============================================================================ # # $Id: Makefile.in,v 1.4 2001/06/04 16:26:57 fp Exp $ # # your make might need this # SHELL = /bin/sh # # Source and Installation Paths # prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = @srcdir@ # # Where you want the binaries and the manual pages installed # BINDIR = @bindir@ MANDIR = @mandir@ # # install program. use our own, as AC_PROG_INSTALL doesn't work reliably # INSTALL = @srcdir@/install-sh INSTALL_PROGRAM = ${INSTALL} -c INSTALL_DATA = ${INSTALL} -c -m 644 # # If you don't have the GNU C compiler installed, set CC=cc here # CC = @CC@ # # C Compiler Options # CFLAGS = @CFLAGS@ -I@srcdir@ @CPPFLAGS@ @TCL_CPPFLAGS@ @DEFS@ # # Libraries to link and their paths # LIBS = @LDFLAGS@ @TCL_LDFLAGS@ @TCL_LIBS@ # # the ranlib program # RANLIB = @RANLIB@ # # shared library stuff, if available. not yet active. i first need to # find someone who can really explain this to me. # SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ SHLIB_VERSION = @SHLIB_VERSION@ # ############################################################################### # You shouldn't have to change anything below. ############################################################################### # @SET_MAKE@ # SOURCE = uuwish.c uutcl.c OBJ = ${SOURCE:.c=.o} # # make stuff # .SUFFIXES: .SUFFIXES: .c .o all: uuwish xdeview clean: rm -f uuwish rm -f *.o *.a *.so core *~ TAGS distclean: clean rm -f config.status config.cache config.log Makefile config.h rm -f uudeview-*tar* uudeview-sfx realclean: distclean install: all for d in $(PROGS) ; do \ $(INSTALL_PROGRAM) $(srcdir)/$$d $(BINDIR)/$$d ; \ done -for d in $(MPAGES) ; do \ $(INSTALL_DATA) $(srcdir)/$$d $(MANDIR)/man1/$$d ; \ done new: clean rm -f uuwish make all uuwish: $(OBJ) ../uulib/libuu.a $(CC) -o $@ $(OBJ) -L../uulib -luu $(LIBS) xdeview: chmod 755 $@ .c.o: $(CC) -c $(CFLAGS) -I../uulib $(VDEF) $< uuwish.o: uuwish.c config.h uutcl.o: uutcl.c config.h uudeview-0.5.20.orig/tcl/uutcl.c0000644001167100001440000007627007441417455016437 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * The TCL Interface of UUDeview */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined(HAVE_TCL) || defined(HAVE_TK) #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #ifdef HAVE_TK #include #else #include #endif /* * The following variable is a special hack that is needed in order for * Sun shared libraries to be used for Tcl. */ extern int matherr(); int *tclDummyMathPtr = (int *) matherr; #include #include #include /* * As Windows DLL, we need a DllEntryPoint */ #ifdef SYSTEM_WINDLL BOOL _export WINAPI DllEntryPoint (HINSTANCE hInstance, DWORD seginfo, LPVOID lpCmdLine) { /* Don't do anything, so just return true */ return TRUE; } #endif /* * Declare external functions as __cdecl for Watcom C */ #ifdef __WATCOMC__ #pragma aux (__cdecl) Tcl_Eval #pragma aux (__cdecl) Tcl_GetVar #pragma aux (__cdecl) Tcl_SetVar #pragma aux (__cdecl) Tcl_AppendResult #pragma aux (__cdecl) Tcl_SetResult #pragma aux (__cdecl) Tcl_CreateCommand #endif /* * cvs version */ char * uutcl_id = "$Id: uutcl.c,v 1.14 2002/03/06 13:52:45 fp Exp $"; /* * data for our Callbacks */ static struct uutclcbdata { Tcl_Interp *interp; char tclproc[256]; } theDMcbdata, theBusycbdata; /* * Don't let Uu_Init initialize us twice */ static int uu_AlreadyInitialized = 0; /* * mail and news software */ #ifdef PROG_INEWS char * uue_inewsprog = PROG_INEWS; #else char * uue_inewsprog = NULL; #endif #ifdef PROG_MAILER char * uue_mailprog = PROG_MAILER; #else char * uue_mailprog = NULL; #endif #ifdef MAILER_NEEDS_SUBJECT int uue_mpsubject = 1; #else int uue_mpsubject = 0; #endif /* * Mail or Post a file. Remember to keep in sync with uuenview.c */ static int SendAFile (Tcl_Interp *interp, FILE *infile, char *infname, int encoding, int linperfile, char *outfname, char *towhom, char *subject, char *from, char *replyto, int isemail) { char *command, *rcptlist, *ptr; FILE *thepipe, *theifile; int len, count, res, part; if (towhom==NULL || (outfname==NULL&&infname==NULL) || (infile&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED)) { Tcl_SetResult (interp, "oops: Parameter check failed in SendAFile()", TCL_STATIC); return UURET_ILLVAL; } #ifndef HAVE_POPEN Tcl_SetResult (interp, "error: Your system does not support sending of files", TCL_STATIC); return UURET_ILLVAL; #else if (isemail && (uue_mailprog == NULL || *uue_mailprog == '\0')) { Tcl_SetResult (interp, "error: Cannot Email file: option not configured", TCL_STATIC); return UURET_ILLVAL; } else if (!isemail && (uue_inewsprog == NULL || *uue_inewsprog == '\0')) { Tcl_SetResult (interp, "error: Cannot Post file: option not configured", TCL_STATIC); return UURET_ILLVAL; } len = strlen ((isemail)?uue_mailprog:uue_inewsprog) + ((uue_mpsubject)?strlen(subject):0) + ((isemail)?0:strlen(towhom)) + 32; if ((command = (char *) malloc (len)) == NULL) { Tcl_SetResult (interp, "error: Out of memory allocating some bytes", TCL_STATIC); return UURET_NOMEM; } if ((rcptlist = (char *) malloc (strlen (towhom) + 16)) == NULL) { Tcl_SetResult (interp, "error: Out of memory allocating some bytes", TCL_STATIC); _FP_free (command); return UURET_NOMEM; } if (isemail) { if (uue_mpsubject) sprintf (command, "%s -s \"%s\"", uue_mailprog, subject); else sprintf (command, "%s", uue_mailprog); /* * Attach list of recipients to mailer command and compose another list * of recipients */ count = 0; rcptlist[0] = '\0'; ptr = _FP_strtok (towhom, ",; "); while (ptr) { strcat (command, " "); strcat (command, ptr); if (count++) strcat (rcptlist, ","); strcat (rcptlist, ptr); ptr = _FP_strtok (NULL, ",; "); } } else { sprintf (command, "%s", uue_inewsprog); count = 0; rcptlist[0] = '\0'; ptr = _FP_strtok (towhom, ";, "); while (ptr) { if (count++) strcat (rcptlist, ","); strcat (rcptlist, ptr); ptr = _FP_strtok (NULL, ";, "); } } if (from && *from == '\0') { from = NULL; } if (subject && *subject == '\0') { subject = NULL; } if (replyto && *replyto == '\0') { replyto = NULL; } /* * Get going ... */ if (infile == NULL) { if ((theifile = fopen (infname, "rb")) == NULL) { _FP_free (rcptlist); _FP_free (command); return UURET_IOERR; } } else { theifile = infile; } for (part=1; !feof (theifile); part++) { if ((thepipe = popen (command, "w")) == NULL) { if (infile==NULL) fclose (theifile); _FP_free (rcptlist); _FP_free (command); return UURET_IOERR; } if (UUGetOption(UUOPT_VERBOSE, NULL, NULL, 0)) { #if 0 fprintf (stderr, "%s part %03d of %s to %s ... ", (isemail)?"mailing":"posting", part, (infname)?infname:outfname, rcptlist); fflush (stderr); #endif } res = UUE_PrepPartialExt (thepipe, theifile, infname, encoding, outfname, 0, part, linperfile, 0, rcptlist, from, subject, replyto, isemail); #if 0 if (UUGetOption (UUOPT_VERBOSE, NULL, NULL, 0)) { if (res == UURET_OK) fprintf (stderr, "ok.\n"); else fprintf (stderr, "%s\n", UUstrerror (res)); } #endif pclose (thepipe); if (res != UURET_OK) { if (infile == NULL) fclose (theifile); _FP_free (rcptlist); _FP_free (command); return res; } } if (infile == NULL) fclose (theifile); _FP_free (rcptlist); _FP_free (command); return UURET_OK; #endif } /* * Display a Message in a dialog box */ static void uutcl_DisplayMessage (void *param, char *message, int level) { struct uutclcbdata *data = (struct uutclcbdata *) param; char tmpstring[2048]; if (data->interp && *data->tclproc) { sprintf (tmpstring, "%s %d {%s}\n", data->tclproc, level, message); Tcl_Eval (data->interp, tmpstring); } } /* * Our Busy Callback */ static int uutcl_BusyCallback (void *param, uuprogress *progress) { struct uutclcbdata *data = (struct uutclcbdata *) param; if (data->interp && *data->tclproc) { Tcl_Eval (data->interp, data->tclproc); } return 0; } /* * exchage variables with the interpreter */ static void uutcl_UpdateParameter (Tcl_Interp *interp) { char *cval; if ((cval = Tcl_GetVar (interp, "OptionFast", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_FAST, atoi (cval), NULL); if ((cval = Tcl_GetVar (interp, "OptionBracket", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_BRACKPOL, atoi (cval), NULL); if ((cval = Tcl_GetVar (interp, "OptionDesperate",TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_DESPERATE, atoi (cval), NULL); if ((cval = Tcl_GetVar (interp, "OptionDebug", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_DEBUG, atoi (cval), NULL); if ((cval = Tcl_GetVar (interp, "OptionDumbness", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_DUMBNESS, atoi (cval), NULL); if ((cval = Tcl_GetVar (interp, "OptionUsetext", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_USETEXT, atoi (cval), NULL); if ((cval = Tcl_GetVar (interp, "SaveFilePath", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_SAVEPATH, 0, cval); if ((cval = Tcl_GetVar (interp, "OptionRemove", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_REMOVE, atoi (cval), NULL); if ((cval = Tcl_GetVar (interp, "OptionMoreMime", TCL_GLOBAL_ONLY))!=NULL) UUSetOption (UUOPT_MOREMIME, atoi (cval), NULL); } /* * configuration info */ static int uutcl_HaveArg (int argc, char *argv[], char *string) { int index; for (index=1; index 0) { UUSetBusyCallback (&theBusycbdata, uutcl_BusyCallback, msecs); } theBusycbdata.interp = interp; strcpy (theBusycbdata.tclproc, argv[1]); return TCL_OK; } static int UUTCLFUNC uutcl_GetProgressInfo (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { uuprogress progress; char tmpstring[32]; if (UUGetOption (UUOPT_PROGRESS, NULL, (char *) &progress, sizeof (uuprogress)) != 0) { Tcl_SetResult (interp, "oops, could not get info?", TCL_STATIC); return TCL_ERROR; } sprintf (tmpstring, "%d", progress.action); Tcl_AppendElement (interp, tmpstring); Tcl_AppendElement (interp, progress.curfile); sprintf (tmpstring, "%d", progress.partno); Tcl_AppendElement (interp, tmpstring); sprintf (tmpstring, "%d", progress.numparts); Tcl_AppendElement (interp, tmpstring); sprintf (tmpstring, "%d", progress.percent); Tcl_AppendElement (interp, tmpstring); return TCL_OK; } static int UUTCLFUNC uutcl_GetListOfFiles (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { char tmpstring[1024], t2[42]; int count=0, index=0; uulist *iter; uutcl_UpdateParameter (interp); while ((iter=UUGetFileListItem(count))) { if (((iter->state & UUFILE_OK) || UUGetOption (UUOPT_DESPERATE, NULL, NULL, 0)) && iter->filename) { sprintf (tmpstring, " { %d %d {%s} %s %s {", count, iter->state, iter->filename, (iter->mimetype)?iter->mimetype:"{}", (iter->uudet == UU_ENCODED) ? "UUdata " : (iter->uudet == B64ENCODED) ? "Base64 " : (iter->uudet == XX_ENCODED) ? "XXdata " : (iter->uudet == BH_ENCODED) ? "Binhex " : (iter->uudet == YENC_ENCODED) ? "yEnc" : "Text"); if (iter->haveparts) { sprintf (t2, "%s%s%d ", (iter->begin&&iter->begin==iter->haveparts[0])?"begin ":"", (iter->end &&iter->end == iter->haveparts[0])?"end " :"", iter->haveparts[0]); strcat (tmpstring, t2); for (index=1; iter->haveparts[index]; index++) { sprintf (t2, "%s%s%d ", (iter->begin==iter->haveparts[index]) ? "begin " : "", (iter->end == iter->haveparts[index]) ? "end " : "", iter->haveparts[index]); strcat (tmpstring, t2); } } if (iter->state & UUFILE_OK) strcat (tmpstring, "OK"); strcat (tmpstring, "} }"); Tcl_AppendResult (interp, tmpstring, NULL); } count++; } return TCL_OK; } /* * Load an encoded file */ static int UUTCLFUNC uutcl_LoadFile (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { char tmpstring[256]; int res; uutcl_UpdateParameter (interp); if (argc != 2) { sprintf (tmpstring, "wrong # args: should be \"%s filename\"", argv[0]); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } if ((res = UULoadFile (argv[1], NULL, 0)) != UURET_OK) { sprintf (tmpstring, "couldn't read %s: %s (%s)", argv[1], UUstrerror (res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; } /* * Decode A File. This function overwrites files without asking, because * this was already done by the script */ static int UUTCLFUNC uutcl_DecodeFile (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { char tmpstring[256]; uulist *iter; int res; uutcl_UpdateParameter (interp); if (argc < 2 || argc > 3) { sprintf (tmpstring, "wrong # args: should be \"%s number ?targetname?\"", argv[0]); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } if ((iter = UUGetFileListItem (atoi (argv[1]))) == NULL) { Tcl_SetResult (interp, "invalid file number", TCL_STATIC); return TCL_ERROR; } if ((res = UUDecodeFile (iter, (argc==3)?argv[2]:NULL)) != UURET_OK) { sprintf (tmpstring, "Error while decoding %s (%s): %s (%s)", (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", UUstrerror (res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; } static int UUTCLFUNC uutcl_GetTempFile (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { char tmpstring[256]; uulist *iter; int res; uutcl_UpdateParameter (interp); if (argc != 2) { sprintf (tmpstring, "wrong # args: should be \"%s number\"", argv[0]); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } if ((iter = UUGetFileListItem (atoi (argv[1]))) == NULL) { Tcl_SetResult (interp, "invalid file number", TCL_STATIC); return TCL_ERROR; } if ((res = UUDecodeToTemp (iter)) != UURET_OK) { sprintf (tmpstring, "Error while decoding %s (%s): %s (%s)", (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", UUstrerror (res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } if (iter->binfile == NULL) { Tcl_SetResult (interp, "unknown error while decoding", TCL_STATIC); return TCL_ERROR; } Tcl_SetResult (interp, iter->binfile, TCL_VOLATILE); return TCL_OK; } /* * InfoFile takes two parameters: the number of the file to get info for, * and the name of the text widget to send the text to */ struct uuInfoCBData { Tcl_Interp *interp; char * widget; }; static int uutcl_InfoCallback (void *param, char *string) { struct uuInfoCBData *data = (struct uuInfoCBData *) param; char tmpstring[1024], *p; sprintf (tmpstring, "%s insert end \"", data->widget); p = tmpstring + strlen (tmpstring); while (*string) { switch (*string) { case '"': case '\\': case '[': case ']': case '$': *p++ = '\\'; /* fallthrough */ default: *p++ = *string; } string++; } *p++ = '"'; *p++ = '\0'; if (Tcl_Eval (data->interp, tmpstring) != TCL_OK) return 1; return 0; } static int UUTCLFUNC uutcl_InfoFile (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { struct uuInfoCBData data; char tmpstring[256]; uulist *iter; int res; uutcl_UpdateParameter (interp); if (argc != 3) { sprintf (tmpstring, "wrong # args: should be \"%s number textwidget\"", argv[0]); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } if ((iter = UUGetFileListItem (atoi (argv[1]))) == NULL) { Tcl_SetResult (interp, "invalid file number", TCL_STATIC); return TCL_ERROR; } sprintf (tmpstring, "%s delete 1.0 end", argv[2]); if (Tcl_Eval (interp, tmpstring) != TCL_OK) return TCL_ERROR; data.interp = interp; data.widget = argv[2]; if ((res = UUInfoFile (iter, &data, uutcl_InfoCallback)) != UURET_OK) { sprintf (tmpstring, "Error while getting info for %s (%s): %s (%s)", (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", UUstrerror (res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; } /* * ShowFile takes two parameters: the number of the file to get info for, * and the name of the text widget to send the text to. We might have to * decode the file before we can show it. * Hey, the above callback worked so well, let's use it again! */ static int UUTCLFUNC uutcl_ListFile (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { uulist *iter; struct uuInfoCBData data; char tmpstring[1024]; FILE *inpfile; int res; uutcl_UpdateParameter (interp); if (argc != 3) { sprintf (tmpstring, "wrong # args: should be \"%s number textwidget\"", argv[0]); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } if ((iter = UUGetFileListItem (atoi (argv[1]))) == NULL) { Tcl_SetResult (interp, "invalid file number", TCL_STATIC); return TCL_ERROR; } if ((res = UUDecodeToTemp (iter)) != UURET_OK) { sprintf (tmpstring, "Error while decoding %s (%s): %s (%s)", (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", UUstrerror(res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } sprintf (tmpstring, "%s delete 1.0 end", argv[2]); if (Tcl_Eval (interp, tmpstring) != TCL_OK) return TCL_ERROR; if (iter->binfile==NULL || (inpfile=fopen (iter->binfile, "r"))==NULL) { Tcl_SetResult (interp, "couldn't read file", TCL_STATIC); return TCL_ERROR; } if ((inpfile = fopen (iter->binfile, "r")) == NULL) { sprintf (tmpstring, "Could not open temp file %s of %s (%s): %s", iter->binfile, (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", strerror (errno)); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } data.interp = interp; data.widget = argv[2]; while (!feof (inpfile)) { if (_FP_fgets (tmpstring, 512, inpfile) == NULL) break; if (ferror (inpfile)) break; if (uutcl_InfoCallback (&data, tmpstring)) break; } if (ferror (inpfile)) { sprintf (tmpstring, "Error while reading from temp file %s of %s (%s): %s", iter->binfile, (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", strerror (errno)); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); fclose (inpfile); return TCL_ERROR; } fclose (inpfile); return TCL_OK; } static int UUTCLFUNC uutcl_Rename (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { char tmpstring[256]; uulist *iter; int res; uutcl_UpdateParameter (interp); if (argc != 3) { sprintf (tmpstring, "wrong # args: should be \"%s number newname\"", argv[0]); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } if (*argv[2] == '\0') { Tcl_SetResult (interp, "illegal file name", TCL_STATIC); return TCL_ERROR; } if ((iter = UUGetFileListItem (atoi (argv[1]))) == NULL) { Tcl_SetResult (interp, "invalid file number", TCL_STATIC); return TCL_ERROR; } if ((res = UURenameFile (iter, argv[2])) != UURET_OK) { sprintf (tmpstring, "could not rename %s to %s: %s (%s)", (iter->filename) ? iter->filename : "", argv[2], UUstrerror (res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, tmpstring, TCL_VOLATILE); return TCL_ERROR; } return TCL_OK; } /* * clean up memory and temp files */ static int UUTCLFUNC uutcl_CleanUp (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { uutcl_UpdateParameter (interp); UUCleanUp (); return TCL_OK; } /* * Generic function to extract the encoding and linperfile parameters * from the command's command line */ static int uutcl_GetEncodeParams (Tcl_Interp *interp, int argc, char *argv[], int argv1, int *encoding, int argv2, int *linperfile) { if (argv2 && argv2 < argc) { *linperfile = atoi (argv[argv2]); if (*linperfile != 0 && *linperfile < 200) { Tcl_SetResult (interp, "illegal number of lines per file", TCL_STATIC); return TCL_ERROR; } } if (argv1 && argv1 < argc) { switch (*argv[argv1]) { case '0': case 'u': case 'U': *encoding = UU_ENCODED; break; case '1': case 'x': case 'X': *encoding = XX_ENCODED; break; case '2': case 'b': case 'B': *encoding = B64ENCODED; break; case '3': case 't': case 'T': *encoding = PT_ENCODED; break; case '4': case 'q': case 'Q': *encoding = QP_ENCODED; break; case '5': case 'y': case 'Y': *encoding = YENC_ENCODED; break; default: Tcl_SetResult (interp, "invalid encoding method", TCL_STATIC); return TCL_ERROR; } } return TCL_OK; } /* * Encode and store in a file. * Syntax: * uu_EncodeToFile source path \ * [ dest subject intro lines encoding from replyto] * * Most arguments are just for compatibilty with the other encoding procs. */ static int UUTCLFUNC uutcl_EncodeToFile (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { int encoding=UU_ENCODED, linperfile=0, res; char errstring[256], olddir[256]; if (argc < 3 || argc > 10) { Tcl_SetResult (interp, "wrong # args", TCL_STATIC); return TCL_ERROR; } uutcl_UpdateParameter (interp); if (uutcl_GetEncodeParams (interp, argc, argv, 7, &encoding, 6, &linperfile) != TCL_OK) return TCL_ERROR; UUGetOption (UUOPT_SAVEPATH, NULL, olddir, 256); UUSetOption (UUOPT_SAVEPATH, 0, argv[2]); if ((res = UUEncodeToFile (NULL, argv[1], encoding, (argc>3) ? argv[3] : NULL, (argc>2) ? argv[2] : NULL, linperfile)) != UURET_OK) { UUSetOption (UUOPT_SAVEPATH, 0, olddir); sprintf (errstring, "error while encoding %s to file: %s (%s)", argv[1], UUstrerror(res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, errstring, TCL_VOLATILE); return TCL_ERROR; } UUSetOption (UUOPT_SAVEPATH, 0, olddir); return TCL_OK; } /* * Encode and send by email * Syntax: * uu_EncodeToMail source addr \ * [ dest subject intro lines encoding from replyto ] * * addr can be a single address or a list of addresses */ static int UUTCLFUNC uutcl_EncodeToMail (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { int encoding=UU_ENCODED, linperfile=0, res; char errstring[256]; if (argc < 3 || argc > 10) { Tcl_SetResult (interp, "wrong # args", TCL_STATIC); return TCL_ERROR; } uutcl_UpdateParameter (interp); if (uutcl_GetEncodeParams (interp, argc, argv, 7, &encoding, 6, &linperfile) != TCL_OK) return TCL_ERROR; if ((res = SendAFile (interp, NULL, argv[1], encoding, linperfile, /* outfname */ (argc>3) ? argv[3] : NULL, /* towhom */ argv[2], /* subject */ (argc>4) ? argv[4] : NULL, /* from */ (argc>8) ? argv[8] : NULL, /* replyto */ (argc>9) ? argv[9] : NULL, 1)) != UURET_OK) { /* * If res==UURET_ILLVAL, SendAMail has already filled in the result */ if (res != UURET_ILLVAL) { sprintf (errstring, "error while emailing %s: %s (%s)", argv[1], UUstrerror(res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, errstring, TCL_VOLATILE); } return TCL_ERROR; } return TCL_OK; } /* * Encode and post to the news * Syntax: * uu_EncodeToNews source addr \ * [ dest subject intro lines encoding from replyto ] * * addr can be a single newsgroup or a list of newsgroups */ static int UUTCLFUNC uutcl_EncodeToNews (ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { int encoding=UU_ENCODED, linperfile=0, res; char errstring[256]; if (argc < 3 || argc > 10) { Tcl_SetResult (interp, "wrong # args", TCL_STATIC); return TCL_ERROR; } uutcl_UpdateParameter (interp); if (uutcl_GetEncodeParams (interp, argc, argv, 7, &encoding, 6, &linperfile) != TCL_OK) return TCL_ERROR; if ((res = SendAFile (interp, NULL, argv[1], encoding, linperfile, /* outfname */ (argc>3) ? argv[3] : NULL, /* towhom */ argv[2], /* subject */ (argc>4) ? argv[4] : NULL, /* from */ (argc>8) ? argv[8] : NULL, /* replyto */ (argc>9) ? argv[9] : NULL, 0)) != UURET_OK) { /* * If res==UURET_ILLVAL, SendAMail has already filled in the result */ if (res != UURET_ILLVAL) { sprintf (errstring, "error while posting %s: %s (%s)", argv[1], UUstrerror(res), (res==UURET_IOERR)? strerror(UUGetOption(UUOPT_ERRNO,NULL,NULL,0)):""); Tcl_SetResult (interp, errstring, TCL_VOLATILE); } return TCL_ERROR; } return TCL_OK; } /* * Initialize the TCL package. The only function that is exported from * this module. */ int UUTCLEXPORT UUTCLFUNC Uu_Init (Tcl_Interp *interp) { char tmp[32]; /* * Check whether we are already initialized */ if (uu_AlreadyInitialized++) return TCL_OK; /* * Initialize decoding engine */ if (UUInitialize () != UURET_OK) { Tcl_SetResult (interp, "Error initializing decoding engine", TCL_STATIC); return TCL_ERROR; } /* * register commands */ Tcl_CreateCommand (interp, "uu_Info", uutcl_Info, NULL, NULL); Tcl_CreateCommand (interp, "uu_SetMessageProc",uutcl_SetMessageProc, NULL, NULL); Tcl_CreateCommand (interp, "uu_SetBusyProc", uutcl_SetBusyProc,NULL,NULL); Tcl_CreateCommand (interp, "uu_GetProgressInfo",uutcl_GetProgressInfo, NULL, NULL); Tcl_CreateCommand (interp, "uu_GetListOfFiles",uutcl_GetListOfFiles, NULL, NULL); Tcl_CreateCommand (interp, "uu_LoadFile", uutcl_LoadFile, NULL, NULL); Tcl_CreateCommand (interp, "uu_DecodeFile", uutcl_DecodeFile, NULL, NULL); Tcl_CreateCommand (interp, "uu_GetTempFile", uutcl_GetTempFile,NULL,NULL); Tcl_CreateCommand (interp, "uu_InfoFile", uutcl_InfoFile, NULL, NULL); Tcl_CreateCommand (interp, "uu_ListFile", uutcl_ListFile, NULL, NULL); Tcl_CreateCommand (interp, "uu_Rename", uutcl_Rename, NULL, NULL); Tcl_CreateCommand (interp, "uu_CleanUp", uutcl_CleanUp, NULL, NULL); Tcl_CreateCommand (interp, "uu_EncodeToFile", uutcl_EncodeToFile,NULL,NULL); Tcl_CreateCommand (interp, "uu_EncodeToMail", uutcl_EncodeToMail,NULL,NULL); Tcl_CreateCommand (interp, "uu_EncodeToNews", uutcl_EncodeToNews,NULL,NULL); /* * our message-handling function and busy callback */ theDMcbdata.interp = NULL; theDMcbdata.tclproc[0] = '\0'; UUSetMsgCallback (&theDMcbdata, uutcl_DisplayMessage); theBusycbdata.interp = NULL; theBusycbdata.tclproc[0] = '\0'; UUSetBusyCallback (&theBusycbdata, uutcl_BusyCallback, 1000); /* * only set variables if they aren't set already */ sprintf (tmp, "%d", UUGetOption (UUOPT_FAST, NULL, NULL, 0)); if (Tcl_GetVar (interp, "OptionFast", TCL_GLOBAL_ONLY) == NULL) Tcl_SetVar (interp, "OptionFast", tmp, TCL_GLOBAL_ONLY); sprintf (tmp, "%d", UUGetOption (UUOPT_BRACKPOL, NULL, NULL, 0)); if (Tcl_GetVar (interp, "OptionBracket", TCL_GLOBAL_ONLY) == NULL) Tcl_SetVar (interp, "OptionBracket", tmp, TCL_GLOBAL_ONLY); sprintf (tmp, "%d", UUGetOption (UUOPT_DESPERATE, NULL, NULL, 0)); if (Tcl_GetVar (interp, "OptionDesperate", TCL_GLOBAL_ONLY) == NULL) Tcl_SetVar (interp, "OptionDesperate", tmp, TCL_GLOBAL_ONLY); sprintf (tmp, "%d", UUGetOption (UUOPT_DEBUG, NULL, NULL, 0)); if (Tcl_GetVar (interp, "OptionDebug", TCL_GLOBAL_ONLY) == NULL) Tcl_SetVar (interp, "OptionDebug", tmp, TCL_GLOBAL_ONLY); sprintf (tmp, "%d", UUGetOption (UUOPT_USETEXT, NULL, NULL, 0)); if (Tcl_GetVar (interp, "OptionUsetext", TCL_GLOBAL_ONLY) == NULL) Tcl_SetVar (interp, "OptionUsetext", tmp, TCL_GLOBAL_ONLY); return TCL_OK; } #endif uudeview-0.5.20.orig/tcl/uuwish.c0000644001167100001440000000333707314377473016625 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * A minimal wish, extended by the UU commands */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif #ifdef HAVE_TK #include #else #ifdef HAVE_TCL #include #endif #endif char * uuwish_id = "$Id: uuwish.c,v 1.5 2001/06/21 14:05:47 fp Exp $"; /* * Tcl Init function */ int Tcl_AppInit (Tcl_Interp *interp) { extern int Uu_Init (Tcl_Interp *); if (Tcl_Init (interp) == TCL_ERROR) { return TCL_ERROR; } #ifdef HAVE_TK if (Tk_Init (interp) == TCL_ERROR) { return TCL_ERROR; } #endif if (Uu_Init (interp) == TCL_ERROR) { return TCL_ERROR; } /* * if (getenv("HOME")) { * sprintf (tempstring, "%s/.xdeviewrc", getenv ("HOME")); * Tcl_EvalFile (interp, tempstring); * } */ return TCL_OK; } /* * uudeview/tcl main function */ int main (int argc, char *argv[]) { #ifdef HAVE_TK Tk_Main (argc, argv, Tcl_AppInit); #else #ifdef HAVE_TCL Tcl_Main (argc, argv, Tcl_AppInit); #endif #endif return 0; } uudeview-0.5.20.orig/tcl/xdeview0000755001167100001440000033472707441417455016544 0ustar cphusers00000000000000#! /bin/sh # The next line restarts using wish \ exec uuwish "$0" ${1+"$@"} # # Init Options # proc ifndef { var val } { global $var if { [ catch { set $var } ] } { set $var $val } } # # read in rc file # if { ! [ catch { set env(HOME) } ] } { catch { source $env(HOME)/.xdeviewrc } } # # overridable options for decoding # ifndef OptionFast 0 ifndef OptionBracket 0 ifndef OptionOverwrite 0 ifndef OptionDesperate 0 ifndef OptionVerbose 0 ifndef OptionDumbness 0 ifndef OptionUsetext 0 ifndef SaveFilePath [ pwd ] ifndef OptionDebug 0 ifndef OptionAutoInfo 0 ifndef OptionRemove 0 ifndef OptionMoreMime 0 # # overridable encoding options # ifndef EncodeMaxLines 0 ifndef EncodeEncoding 0 ifndef EncodeSubject "" ifndef EncodeFrom "" ifndef EncodeReplyTo "" ifndef EncodeFileYes 1 ifndef EncodeFilePath $SaveFilePath ifndef EncodeMailYes 0 ifndef EncodeMailAddr "" ifndef EncodeNewsYes 0 ifndef EncodeNewsGroup "" ifndef NNTPServer "" # # MIME configuration # ifndef MIMEGlobalTypes "" ifndef MIMEGlobalCap "" if { ! [ catch { set env(HOME) } ] } { ifndef MIMELocalTypes $env(HOME)/.mime.types ifndef MIMELocalCap $env(HOME)/.mailcap } else { ifndef MIMELocalTypes "" ifndef MIMELocalCap "" } # # check whether we are started from within uudeview and have tk support # if { [ catch { uu_Info have_tk } have_tk ] } { puts "Xdeview error: this file must be loaded from within uudeview" exit 1 } if { ! [ lindex [ lindex $have_tk 0 ] 1 ] } { puts "Xdeview error: tk support not compiled" exit 1 } ############################################################################## # General Helper functions ############################################################################## # # Get a file type from .mime.types # proc GetTypeByExtension { ext } { global MIMELocalTypes MIMEGlobalTypes foreach fname "$MIMELocalTypes $MIMEGlobalTypes" { if { [ catch { open $fname r } fileID ] } { return } while { ! [ eof $fileID ] } { if { [ gets $fileID TheLine ] < 0 } { break } if { [ string index $TheLine 0 ] == "#" } { continue } elseif { [ llength $TheLine ] < 2 } { continue } for { set index 1 } { $index < [ llength $TheLine ] } { incr index } { if { [ string tolower [ lindex $TheLine $index ] ] == \ [ string tolower $ext ] } { close $fileID return [ lindex $TheLine 0 ] } } } close $fileID } return } # # see what to do with this type by reading .mailcap # proc GetTypeAction { type } { global MIMELocalCap MIMEGlobalCap foreach fname "$MIMELocalCap $MIMEGlobalCap" { if { [ catch { open $fname r } fileID ] } { continue } while { ! [ eof $fileID ] } { if { [ gets $fileID TheLine ] < 0 } { break } if { [ string index $TheLine 0 ] == "#" } { continue } if { [ set ThisType [ lindex [ split $TheLine ";" ] 0 ] ] == "" } { continue } if { [ string match \ [ string tolower $ThisType ] [ string tolower $type ] ] } { close $fileID return [ lindex [ split $TheLine ";" ] 1 ] } } close $fileID } return } ############################################################################## # Specific helper functions ############################################################################## # # Retrieve the current global FileList and display it. Store in $FileList # proc ShowFileList {} { global FileList proc GetStatus { Code } { if { [ expr $Code & 0x08 ] } { return "No Data" } elseif { [ expr $Code & 0x20 ] } { return "Error" } elseif { [ expr $Code & 0x10 ] } { return "OK" } elseif { [ expr $Code & 0x01 ] } { return "Incomplete" } elseif { [ expr $Code & 0x02 ] } { return "No Begin" } elseif { [ expr $Code & 0x04 ] } { return "No End" } elseif { $Code == 0 } { return "Oops" } return "Error" } ._MainFrame._FileList._Status delete 0 end ._MainFrame._FileList._Liste delete 0 end set FileList [uu_GetListOfFiles] foreach item $FileList { ._MainFrame._FileList._Status insert end [GetStatus [lindex $item 1]] ._MainFrame._FileList._Liste insert end [ lindex $item 2 ] } } # # Check the Path # proc CheckWritable { Path } { if { ! [ expr [ file isdirectory $Path ] && [ file writable $Path ] ] } { tk_dialog ._Dialog { Illegal Save Path } "You do not have the\ proper permissions to write to the selected Save Path.\ Please use a different Directory" \ warning 0 OK return 0 } return 1 } # # Callback function for warnings and errors # proc OpenMessageWindow { } { if { [ catch { .messages configure } ] } { toplevel .messages frame .messages.top frame .messages.bot text .messages.top.text -relief raised -bd 2 -wrap none \ -xscrollcommand ".messages.top.sbx set" \ -yscrollcommand ".messages.top.sby set" scrollbar .messages.top.sbx -command ".messages.top.text xview" \ -orient horizontal scrollbar .messages.top.sby -command ".messages.top.text yview" pack .messages.top.sbx -side bottom -fill x pack .messages.top.sby -side right -fill y pack .messages.top.text -fill both -expand 1 button .messages.bot.done -text "Done" -command "destroy .messages" pack .messages.bot.done -side right -padx 4 -pady 4 pack .messages.top -side top -fill both -expand 1 pack .messages.bot -side bottom wm title .messages "Runtime Messages" } } # # Display a message in our Runtime Messages window, if verbose # proc DisplayMessage { level string } { global OptionVerbose if { $OptionVerbose } { OpenMessageWindow .messages.top.text insert end $string .messages.top.text insert end "\n" .messages.top.text yview end update } if { $level == 2 } { tk_dialog ._Dialog "Warning" $string warning 0 OK } elseif { $level > 2 } { tk_dialog ._Dialog "Error" $string error 0 OK } } # # Dump the current File List in the Runtime Messages window # proc DumpFileList { } { global FileList OpenMessageWindow if { [ llength $FileList ] == 0 } { return } .messages.top.text insert end "\n" foreach file $FileList { if { [ expr [ lindex $file 1 ] & 0x08 ] } { continue } .messages.top.text insert end \ "Found '[lindex $file 2]'\ State [lindex $file 1] [lindex $file 4]\ Parts [lindex $file 5]\n" } .messages.top.text insert end "\n" .messages.top.text yview end } # # Handle Busy Callback # proc WeAreBusy {} { set BusyInfo [uu_GetProgressInfo] if { [ lindex $BusyInfo 0 ] == 1 } { ._Status._Text config -text \ "Loading [ file tail [ lindex $BusyInfo 1 ] ] --\ [ lindex $BusyInfo 4 ]% done" } elseif { [ lindex $BusyInfo 0 ] == 2 } { set percent [expr 100*[lindex $BusyInfo 2]+[lindex $BusyInfo 4]-100] set percent [expr $percent / [lindex $BusyInfo 3]] ._Status._Text configure -text \ "Decoding [file tail [lindex $BusyInfo 1 ] ] --\ $percent% done" } elseif { [ lindex $BusyInfo 0 ] == 3 } { ._Status._Text config -text \ "Copying [ file tail [ lindex $BusyInfo 1 ] ] --\ [ lindex $BusyInfo 4 ]% done" } elseif { [ lindex $BusyInfo 0 ] == 4 } { set percent [expr 100*[lindex $BusyInfo 2]+[lindex $BusyInfo 4]-100] set percent [expr $percent / [lindex $BusyInfo 3]] ._Status._Text configure -text \ "Encoding [file tail [lindex $BusyInfo 1 ] ] --\ $percent% done" } update } # # Helper function to load a bunch of files # proc LoadFiles { LoadFileList } { set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] . config -cursor watch foreach file $LoadFileList { # # recurse into subdirectories # if { [ file isdirectory $file ] && [ file readable $file ] } { LoadFiles [ glob -nocomplain [ file join $file * ] ] continue } elseif { ! [ file readable $file ] || [ file isdirectory $file ] } { tk_dialog ._Dialog "File Unreadable" "File $file is read\ protected or is a directory" warning 0 OK continue } ._Status._Text config -text "Loading [ file tail $file ] ..." update uu_LoadFile $file } ._Status._Text config -text $oldText . config -cursor $oldCursor } ############################################################################## # Button bindings && Menu functions ############################################################################## # # Menu Command File->Quit # proc Quit {} { uu_CleanUp destroy . exit 0 } # # Menu Command File->Load # proc Load {} { global OptionVerbose set oldText [ lindex [ ._Status._Text config -text ] 4 ] ._Status._Text config -text "Waiting for you to Select Files" set LoadFileList [ tk_SelectFiles "Select Files for Decoding" 1 1 ] ._Status._Text config -text $oldText if { $LoadFileList != {} } { LoadFiles $LoadFileList ShowFileList if { $OptionVerbose } { DumpFileList } } } # # Menu Command File->Helper Setup # proc MimeSetup {} { global MIMEGlobalTypes MIMELocalCap MIMEGlobalCap MIMELocalTypes global tempGlobalTypes tempLocalCap tempGlobalCap tempLocalTypes global MSFinish set tempGlobalTypes $MIMEGlobalTypes set tempLocalCap $MIMELocalCap set tempGlobalCap $MIMEGlobalCap set tempLocalTypes $MIMELocalTypes set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] set oldFocus [ focus ] toplevel .mime wm title .mime "Helper Setup" frame .mime.top -relief groove -bd 1 frame .mime.top.gt frame .mime.top.lt frame .mime.top.gc frame .mime.top.lc label .mime.top.gt.lab -text "Global Types File" -width 16 \ -justify left -anchor w entry .mime.top.gt.ent -relief sunken -width 30 \ -textvariable MIMEGlobalTypes button .mime.top.gt.but -text "Browse" -width 8 -command { set OldDir [ file dirname $MIMEGlobalTypes ] set NewFile [ tk_SelectFiles "Global Types File" 0 0 $OldDir ] if { $NewFile != "" } { set MIMEGlobalTypes $NewFile } } label .mime.top.lt.lab -text "Local Types File" -width 16 \ -justify left -anchor w entry .mime.top.lt.ent -relief sunken -width 30 \ -textvariable MIMELocalTypes button .mime.top.lt.but -text "Browse" -width 8 -command { set OldDir [ file dirname $MIMELocalTypes ] set NewFile [ tk_SelectFiles "Local Types File" 0 0 $OldDir ] if { $NewFile != "" } { set MIMELocalTypes $NewFile } } label .mime.top.gc.lab -text "Global Mailcap File" -width 16 \ -justify left -anchor w entry .mime.top.gc.ent -relief sunken -width 30 \ -textvariable MIMEGlobalCap button .mime.top.gc.but -text "Browse" -width 8 -command { set OldDir [ file dirname $MIMEGlobalCap ] set NewFile [ tk_SelectFiles "Global Mailcap File" 0 0 $OldDir ] if { $NewFile != "" } { set MIMEGlobalCap $NewFile } } label .mime.top.lc.lab -text "Local Mailcap File" -width 16 \ -justify left -anchor w entry .mime.top.lc.ent -relief sunken -width 30 \ -textvariable MIMELocalCap button .mime.top.lc.but -text "Browse" -width 8 -command { set OldDir [ file dirname $MIMELocalCap ] set NewFile [ tk_SelectFiles "Local Mailcap File" 0 0 $OldDir ] if { $NewFile != "" } { set MIMELocalCap $NewFile } } pack .mime.top.gt.lab -side left -padx 4 -pady 4 pack .mime.top.gt.but -side right -padx 4 pack .mime.top.gt.ent -side right -padx 4 -pady 4 -expand true -fill x pack .mime.top.lt.lab -side left -padx 4 -pady 4 pack .mime.top.lt.but -side right -padx 4 pack .mime.top.lt.ent -side right -padx 4 -pady 4 -expand true -fill x pack .mime.top.gc.lab -side left -padx 4 -pady 4 pack .mime.top.gc.but -side right -padx 4 pack .mime.top.gc.ent -side right -padx 4 -pady 4 -expand true -fill x pack .mime.top.lc.lab -side left -padx 4 -pady 4 pack .mime.top.lc.but -side right -padx 4 pack .mime.top.lc.ent -side right -padx 4 -pady 4 -expand true -fill x pack .mime.top.gt .mime.top.lt .mime.top.gc .mime.top.lc \ -side top -expand true -fill both frame .mime.but -relief raised -bd 2 frame .mime.but.b button .mime.but.b.ok -text "Ok" -width 8 -command { if { $MIMEGlobalTypes != "" && \ ! [ file readable $MIMEGlobalTypes ] } { tk_dialog ._Dialog "File Does not Exist" "Global Types File\ $MIMEGlobalTypes does not exist or is not readable." \ error 0 OK } elseif { $MIMELocalTypes != "" && \ ! [ file readable $MIMELocalTypes ] } { tk_dialog ._Dialog "File Does not Exist" "Local Types File\ $MIMELocalTypes does not exist or is not readable." \ error 0 OK } elseif { $MIMEGlobalCap != "" && \ ! [ file readable $MIMEGlobalCap ] } { tk_dialog ._Dialog "File Does not Exist" "Global Mailcap File\ $MIMEGlobalCap does not exist or is not readable." \ error 0 OK } elseif { $MIMELocalCap != "" && \ ! [ file readable $MIMELocalCap ] } { tk_dialog ._Dialog "File Does not Exist" "Local Mailcap File\ $MIMELocalCap does not exist or is not readable." \ error 0 OK } else { set MSFinish ok } } button .mime.but.b.cancel -text "Cancel" -width 8 \ -command { set MSFinish cancel } pack .mime.but.b.ok .mime.but.b.cancel -side left -ipadx 4 -ipady 4 \ -padx 4 -pady 4 -expand true pack .mime.but.b -fill both -expand true -fill both pack .mime.top -side top -fill x pack .mime.but -side bottom -fill both -expand true bind .mime.top.gt.ent { if { $MIMEGlobalTypes != "" } { if { ! [ file readable $MIMEGlobalTypes ] } { tk_dialog ._Dialog "File Does not Exist" "Global Types File\ $MIMEGlobalTypes does not exist or is not readable." \ error 0 OK } } } bind .mime.top.lt.ent { if { $MIMELocalTypes != "" } { if { ! [ file readable $MIMELocalTypes ] } { tk_dialog ._Dialog "File Does not Exist" "Local Types File\ $MIMELocalTypes does not exist or is not readable." \ error 0 OK } } } bind .mime.top.gc.ent { if { $MIMEGlobalCap != "" } { if { ! [ file readable $MIMEGlobalCap ] } { tk_dialog ._Dialog "File Does not Exist" "Global Mailcap File\ $MIMEGlobalCap does not exist or is not readable." \ error 0 OK } } } bind .mime.top.lc.ent { if { $MIMELocalCap != "" } { if { ! [ file readable $MIMELocalCap ] } { tk_dialog ._Dialog "File Does not Exist" "Local Mailcap File\ $MIMELocalCap does not exist or is not readable." \ error 0 OK } } } . config -cursor watch tkwait visibility .mime ._Status._Text config -text "Waiting for Configuration" grab set .mime focus .mime set MSFinish {} tkwait variable MSFinish if { $MSFinish != "ok" } { set MIMEGlobalTypes $tempGlobalTypes set MIMELocalCap $tempLocalCap set MIMEGlobalCap $tempGlobalCap set MIMELocalTypes $tempLocalTypes } . config -cursor $oldCursor ._Status._Text config -text $oldText focus $oldFocus destroy .mime } # # Menu Command File->Save Setup # proc SaveSetup {} { global OptionFast OptionBracket OptionOverwrite global OptionDesperate OptionVerbose OptionAutoInfo global SaveFilePath EncodeMaxLines EncodeEncoding global EncodeFilePath NNTPServer MIMELocalTypes global MIMEGlobalTypes MIMELocalCap MIMEGlobalCap global OptionDumbness OptionUsetext OptionRemove global OptionMoreMime EncodeFrom EncodeReplyTo global env set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] . config -cursor watch ._Status._Text config -text "Saving Setup" if { [ catch { set env(HOME) } ] || $env(HOME) == "" } { tk_dialog ._Dialog "OOps" "Could not find your home directory." \ error 0 OK . config -cursor $oldCursor ._Status._Text config -text $oldText return } # # need temp file # if { ! [ catch { set $env(TEMP) } ] } { set tempname "$env(TEMP)/xdeview[pid]" } else { set tempname "/tmp/xdeview.[pid]" } if { [ file exists $tempname ] } { foreach ext { 001 002 003 004 005 006 007 008 009 010 042 } { if { ! [ catch { set $env(TEMP) } ] } { set tempname "$env(TEMP)/xdeview.$ext" } else { set tempname "/tmp/xdeview.$ext" } if { [ file exists $tempname ] } { break } } if { [ file exits $tempname] } { tk_dialog ._Dialog "OOps" "Could not save your setup. Couldn't\ find suitable temporary file" error 0 OK . config -cursor $oldCursor ._Status._Text config -text $oldText return } } if { [ catch { open $tempname w } writeID ] } { tk_dialog ._Dialog "OOps" "Cannot write to temp file $tempname.\ Setup not saved." error 0 OK . config -cursor $oldCursor ._Status._Text config -text $oldText return } set rcfile $env(HOME)/.xdeviewrc if { ! [ catch { open $rcfile r } readID ] } { # # copy existing resouce file # while { ! [ eof $readID ] } { if { [ gets $readID TheLine ] < 0 } { break } puts $writeID $TheLine if { [ string first "--xdeview--" $TheLine ] != -1 } { break } } if { [ eof $readID ] } { puts $writeID "#" puts $writeID "# --xdeview-- auto-generated do not add code below" } close $readID } else { puts $writeID "#" puts $writeID "# --xdeview-- auto-generated do not add code below" } # # save configuration information # puts $writeID "#" puts $writeID "# options for decoding" puts $writeID "#" puts $writeID "ifndef OptionFast $OptionFast" puts $writeID "ifndef OptionBracket $OptionBracket" puts $writeID "ifndef OptionOverwrite $OptionOverwrite" puts $writeID "ifndef OptionDesperate $OptionDesperate" puts $writeID "ifndef OptionVerbose $OptionVerbose" puts $writeID "ifndef OptionDumbness $OptionDumbness" puts $writeID "ifndef OptionAutoInfo $OptionAutoInfo" puts $writeID "ifndef OptionUsetext $OptionUsetext" puts $writeID "ifndef SaveFilePath \"$SaveFilePath\"" puts $writeID "ifndef OptionRemove $OptionRemove" puts $writeID "ifndef OptionMoreMime $OptionMoreMime" puts $writeID "#" puts $writeID "# encoding options" puts $writeID "#" puts $writeID "ifndef EncodeMaxLines $EncodeMaxLines" puts $writeID "ifndef EncodeEncoding $EncodeEncoding" puts $writeID "ifndef EncodeFilePath \"$EncodeFilePath\"" puts $writeID "ifndef EncodeFrom \"$EncodeFrom\"" puts $writeID "ifndef EncodeReplyTo \"$EncodeReplyTo\"" puts $writeID "ifndef NNTPServer \"$NNTPServer\"" puts $writeID "#" puts $writeID "# MIME capabilities" puts $writeID "#" puts $writeID "ifndef MIMELocalTypes \"$MIMELocalTypes\"" puts $writeID "ifndef MIMEGlobalTypes \"$MIMEGlobalTypes\"" puts $writeID "ifndef MIMELocalCap \"$MIMELocalCap\"" puts $writeID "ifndef MIMEGlobalCap \"$MIMEGlobalCap\"" puts $writeID "#" puts $writeID "" close $writeID # # copy temp file back to real ./xdeviewrc # if { [ catch { open $tempname r } readID ] } { tk_dialog ._Dialog "This is weird" "Could not re-open the temp\ file $tempname. Setup not saved." error 0 OK . config -cursor $oldCursor ._Status._Text config -text $oldText exec -- rm -f $tempname return } if { [ catch { open $rcfile w } writeID ] } { tk_dialog ._Dialog "OOps" "Cannot write to setup file $rcfile.\ Setup not saved." error 0 OK . config -cursor $oldCursor ._Status._Text config -text $oldText close $readID exec -- rm -f $tempname return } while { ! [ eof $readID ] } { if { [ gets $readID TheLine ] < 0 } { break } puts $writeID $TheLine } close $writeID close $readID exec -- rm -f $tempname . config -cursor $oldCursor ._Status._Text config -text $oldText tk_dialog ._Dialog "OK" "Setup successfully saved to $rcfile." \ "" 0 OK } # # Menu Command File->Encode # proc Encode {} { global EncodeFileName global EncodeMaxLines global EncodeEncoding global EncodeSubject global EncodeFrom global EncodeReplyTo global EncodeFileYes global EncodeFilePath global EncodeMailYes global EncodeMailAddr global EncodeNewsYes global EncodeNewsGroup global SaveFilePath global EncodeButton global HaveNNTPServer global NNTPServer global env ifndef EncodeMaxLines 0 ifndef EncodeEncoding 0 ifndef EncodeSubject "" ifndef EncodeFrom "" ifndef EncodeReplyTo "" ifndef EncodeFileYes 1 ifndef EncodeFilePath $SaveFilePath ifndef EncodeMailYes 0 ifndef EncodeMailAddr "" ifndef EncodeNewsYes 0 ifndef EncodeNewsGroup "" ifndef NNTPServer "" set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] set oldFocus [ focus ] set have_mail [ lindex [ lindex [ uu_Info have_mail ] 0 ] 1 ] set have_news [ lindex [ lindex [ uu_Info have_news ] 0 ] 1 ] set need_nntp [ lindex [ lindex [ uu_Info need_nntpserver ] 0 ] 1 ] if { $have_news && $need_nntp && $NNTPServer == "" } { if { [ catch { set NNTPServer $env(NNTPSERVER) } ] } { set NNTPServer "" } } ._Status._Text config -text "Waiting for you to Select Files for Encoding" set EncodeFileList [ tk_SelectFiles "Select Files for Encoding" 1 0 ] if { $EncodeFileList == {} } { ._Status._Text config -text $oldText return } set EncodeFileCount [ llength $EncodeFileList ] # # what to do with these files? # toplevel ._Encode wm title ._Encode "Encode Files" # # first section: How many files left? # frame ._Encode._Toplab -relief raised -bd 2 label ._Encode._Toplab.lab -text "0 Files left to Encode" pack ._Encode._Toplab.lab -padx 2 -pady 2 -anchor w # # second section: file names of source and sent file # frame ._Encode._Names -relief raised -bd 2 frame ._Encode._Names.top frame ._Encode._Names.bot label ._Encode._Names.top.lab -text "Filename:" -width 12 \ -justify left -anchor w entry ._Encode._Names.top.nam -relief sunken -width 30 label ._Encode._Names.bot.lab -text "Send as:" -width 12 \ -justify left -anchor w entry ._Encode._Names.bot.nam -relief sunken -width 30 \ -textvariable EncodeFileName pack ._Encode._Names.top.lab -side left -padx 2 -pady 2 pack ._Encode._Names.top.nam -side right -padx 2 -pady 2 \ -fill x -expand true pack ._Encode._Names.bot.lab -side left -padx 2 -pady 2 pack ._Encode._Names.bot.nam -side right -padx 2 -pady 2 \ -fill x -expand true pack ._Encode._Names.top ._Encode._Names.bot \ -padx 4 -pady 4 -side top -fill x -expand true frame ._Encode._Header -relief raised -bd 2 frame ._Encode._Header.from frame ._Encode._Header.replyto frame ._Encode._Header.subject label ._Encode._Header.from.msg -text "From:" -width 12 \ -justify left -anchor w entry ._Encode._Header.from.ent -relief sunken -width 30 \ -textvariable EncodeFrom label ._Encode._Header.replyto.msg -text "Reply To:" -width 12 \ -justify left -anchor w entry ._Encode._Header.replyto.ent -relief sunken -width 30 \ -textvariable EncodeReplyTo label ._Encode._Header.subject.msg -text "Subject:" -width 12 \ -justify left -anchor w entry ._Encode._Header.subject.ent -relief sunken -width 30 \ -textvariable EncodeSubject pack ._Encode._Header.from.msg -side left -padx 2 -pady 2 pack ._Encode._Header.from.ent -side right -padx 2 -pady 2 \ -expand true -fill x pack ._Encode._Header.replyto.msg -side left -padx 2 -pady 2 pack ._Encode._Header.replyto.ent -side right -padx 2 -pady 2 \ -expand true -fill x pack ._Encode._Header.subject.msg -side left -padx 2 -pady 2 pack ._Encode._Header.subject.ent -side right -padx 2 -pady 2 \ -expand true -fill x pack ._Encode._Header.from ._Encode._Header.replyto \ ._Encode._Header.subject \ -padx 4 -pady 4 -side top -fill x -expand true # # third section: encoding options # frame ._Encode._Options -relief raised -bd 2 frame ._Encode._Options.left frame ._Encode._Options.right frame ._Encode._Options.righter frame ._Encode._Options.left.top frame ._Encode._Options.left.empty frame ._Encode._Options.left.bot label ._Encode._Options.left.top.msg -text "Encoding Options:" entry ._Encode._Options.left.bot.lines -relief sunken -width 5 \ -textvariable EncodeMaxLines label ._Encode._Options.left.bot.msg -text "Lines per File" \ -justify left radiobutton ._Encode._Options.right.uue -text "UU Encoding" \ -variable EncodeEncoding -value 0 -relief flat -anchor w \ -selectcolor black radiobutton ._Encode._Options.right.xxe -text "XX Encoding" \ -variable EncodeEncoding -value 1 -relief flat -anchor w \ -selectcolor black radiobutton ._Encode._Options.right.b64 -text "Base64 Encoding" \ -variable EncodeEncoding -value 2 -relief flat -anchor w \ -selectcolor black radiobutton ._Encode._Options.righter.pt -text "Plain Text" \ -variable EncodeEncoding -value 3 -relief flat -anchor w \ -selectcolor black radiobutton ._Encode._Options.righter.qp -text "Quoted Printable" \ -variable EncodeEncoding -value 4 -relief flat -anchor w \ -selectcolor black radiobutton ._Encode._Options.righter.ye -text "yEnc Encoding" \ -variable EncodeEncoding -value 5 -relief flat -anchor w \ -selectcolor black pack ._Encode._Options.left.bot.lines ._Encode._Options.left.bot.msg \ -padx 4 -pady 4 -side left pack ._Encode._Options.left.top.msg -padx 2 -pady 2 -anchor nw pack ._Encode._Options.left.top -fill x -side top pack ._Encode._Options.left.bot -anchor sw -side bottom -padx 4 -pady 4 pack ._Encode._Options.left.empty -fill both -expand true pack ._Encode._Options.right.uue ._Encode._Options.right.xxe \ ._Encode._Options.right.b64 \ -padx 4 -pady 2 -fill x pack ._Encode._Options.righter.pt ._Encode._Options.righter.qp \ -padx 4 -pady 2 -fill x pack ._Encode._Options.righter.ye \ -padx 4 -pady 2 -fill x pack ._Encode._Options.left ._Encode._Options.right \ ._Encode._Options.righter \ -side left -fill both -expand true # # fourth section: what to do with encoded data # frame ._Encode._Actions -relief raised -bd 2 frame ._Encode._Actions.title frame ._Encode._Actions.file frame ._Encode._Actions.mail frame ._Encode._Actions.news label ._Encode._Actions.title.lab -text "Encoding Actions:" pack ._Encode._Actions.title.lab -padx 2 -pady 2 -anchor w checkbutton ._Encode._Actions.file.but -variable EncodeFileYes \ -text "File In (Path):" -width 12 -justify left -anchor w \ -selectcolor black entry ._Encode._Actions.file.ent -relief sunken -width 30 \ -textvariable EncodeFilePath button ._Encode._Actions.file.bb -text "Browse" -command { set NewPath [ tk_SelectFiles "Encoding Path" 0 2 ] if { $NewPath != "" } { if { [ CheckWritable $NewPath ] } { set EncodeFilePath [ CompressSlashes $NewPath ] } } } checkbutton ._Encode._Actions.mail.but -variable EncodeMailYes \ -text "Email To ..." -width 12 -justify left -anchor w \ -selectcolor black entry ._Encode._Actions.mail.ent -relief sunken -width 30 \ -textvariable EncodeMailAddr checkbutton ._Encode._Actions.news.but -variable EncodeNewsYes \ -text "Post To ..." -width 12 -justify left -anchor w \ -selectcolor black entry ._Encode._Actions.news.ent -relief sunken -width 30 \ -textvariable EncodeNewsGroup # # if we need an NNTP server, add a button # if { $have_news && $need_nntp } { frame ._Encode._Actions.nntp checkbutton ._Encode._Actions.nntp.but -variable HaveNNTPServer \ -text "NNTP Server" -width 12 -justify left -anchor w \ -selectcolor black entry ._Encode._Actions.nntp.ent -relief sunken -width 30 \ -textvariable NNTPServer ._Encode._Actions.nntp.but select } pack ._Encode._Actions.file.but -side left -padx 4 -pady 4 pack ._Encode._Actions.file.bb -side right -padx 4 pack ._Encode._Actions.file.ent -side right -padx 4 -pady 4 \ -expand true -fill x pack ._Encode._Actions.mail.but -side left -padx 4 -pady 4 pack ._Encode._Actions.mail.ent -side right -padx 4 -pady 4 \ -expand true -fill x pack ._Encode._Actions.news.but -side left -padx 4 -pady 4 pack ._Encode._Actions.news.ent -side right -padx 4 -pady 4 \ -expand true -fill x pack ._Encode._Actions.title -side top -fill x -expand true pack ._Encode._Actions.file -side top -fill x -expand true pack ._Encode._Actions.mail -side top -fill x -expand true pack ._Encode._Actions.news -side top -fill x -expand true if { $have_news && $need_nntp } { pack ._Encode._Actions.nntp.but -side left -padx 4 -pady 4 pack ._Encode._Actions.nntp.ent -side right -padx 4 -pady 4 \ -expand true -fill x pack ._Encode._Actions.nntp -side top -fill x -expand true } # # fifth section: the buttons # frame ._Encode._Buttons -relief raised -bd 2 frame ._Encode._Buttons.b button ._Encode._Buttons.b._Ok -text "Ok" -width 8 \ -command { set EncodeButton ok } button ._Encode._Buttons.b._OkAll -text "Ok to All" -width 8 \ -command { set EncodeButton okall } button ._Encode._Buttons.b._Next -text "Next" -width 8 \ -command { set EncodeButton next } button ._Encode._Buttons.b._Cancel -text "Cancel" -width 8 \ -command { set EncodeButton cancel } pack ._Encode._Buttons.b._Ok ._Encode._Buttons.b._OkAll \ ._Encode._Buttons.b._Next ._Encode._Buttons.b._Cancel \ -side left -ipadx 4 -ipady 4 -padx 4 -pady 4 -expand true pack ._Encode._Buttons.b -fill both -expand true pack ._Encode._Toplab ._Encode._Names ._Encode._Header \ ._Encode._Options ._Encode._Actions \ -fill x -side top pack ._Encode._Buttons -fill both -side bottom -expand true # # wow, dialog box is finally drawn. now make it do something # if { $have_mail == 0 } { ._Encode._Actions.mail.but deselect ._Encode._Actions.mail.ent delete 0 end ._Encode._Actions.mail.ent insert 0 "(Email not Available)" ._Encode._Actions.mail.but configure -state disabled ._Encode._Actions.mail.ent configure -state disabled } if { $have_news == 0 } { ._Encode._Actions.news.but deselect ._Encode._Actions.news.ent delete 0 end ._Encode._Actions.news.ent insert 0 "(Posting not Available)" ._Encode._Actions.news.but configure -state disabled ._Encode._Actions.news.ent configure -state disabled } bind ._Encode._Actions.file.ent { if { $EncodeFilePath == {} } { set EncodeFilePath [ pwd ] } set EncodeFilePath [ CompressSlashes $EncodeFilePath ] CheckWritable $EncodeFilePath } bind ._Encode._Options.left.bot.lines { if { $EncodeMaxLines < 200 && $EncodeMaxLines != 0 } { tk_dialog ._Dialog { Illegal Number of Lines } "You have\ entered an invalid value for the number of lines\ per encoded file. It must either be 0 (no limit)\ or greater than 200." error 0 OK set EncodeMaxLines 0 } } # # iterate through files # . config -cursor watch tkwait visibility ._Encode grab set ._Encode focus ._Encode set index 0 set EncodeButton {} while { $index < $EncodeFileCount } { set EFPath [ lindex $EncodeFileList $index ] set EFName [ file tail $EFPath ] ._Encode config -cursor {} if { ! [ file readable $EFPath ] || [ file isdirectory $EFPath ] } { tk_dialog ._Dialog { Cannot read File } "Cannot read $EFPath" \ error 0 OK incr index continue } ._Encode._Names.top.nam configure -state normal ._Encode._Names.top.nam delete 0 end ._Encode._Names.top.nam insert 0 $EFPath ._Encode._Names.top.nam configure -state disabled ._Encode._Names.bot.nam delete 0 end ._Encode._Names.bot.nam insert 0 $EFName ._Encode._Toplab.lab config -text \ "[ expr $EncodeFileCount - $index ] Files left to Encode" ._Status._Text config -text "Waiting for action on $EFName" if { $EncodeButton != "okall" } { while { 42 } { set EncodeButton {} tkwait variable EncodeButton if { $EncodeButton == "cancel" } { break } # # check parameter # if { $EncodeFilePath == {} } { set EncodeFilePath [ pwd ] } set EncodeFilePath [ CompressSlashes $EncodeFilePath ] if { $EncodeFileYes && ! [ CheckWritable $EncodeFilePath ] } { continue } if { $EncodeMaxLines < 200 && $EncodeMaxLines != 0 } { tk_dialog ._Dialog { Illegal Number of Lines } "You have\ entered an invalid value for the number of lines\ per encoded file. It must either be 0 (no limit)\ or greater than 200." error 0 OK set EncodeMaxLines 0 continue } if { $have_news && $need_nntp && $EncodeNewsYes } { if { $HaveNNTPServer == 0 || $NNTPServer == {} } { tk_dialog ._Dialog { No NNTP Server } "You must\ provide the address of an NNTP server in\ order to post a file. You can also set\ your environment variable\ \$NNTPSERVER or define the address at\ compile time." error 0 OK continue } } break } } # # check which button was pressed # if { $EncodeButton == "cancel" } { break } elseif { $EncodeButton == "next" } { incr index continue } # # at this point, we want to process the file (either ok or okall) # if { $have_news && $need_nntp && $EncodeNewsYes } { set env(NNTPSERVER) $NNTPServer } ._Encode config -cursor watch if { $EncodeFileYes } { ._Status._Text config -text "Encoding $EFName to File ..." update if { [ catch { uu_EncodeToFile $EFPath \ [ file join $EncodeFilePath $EncodeFileName] \ $EncodeFileName $EncodeSubject "" $EncodeMaxLines \ $EncodeEncoding $EncodeFrom $EncodeReplyTo } message ] } { tk_dialog ._Dialog { Error while Encoding } "The following\ error occured while encoding into a file: $message" \ error 0 OK } } if { $EncodeMailYes } { ._Status._Text config -text "Encoding and Emailing $EFName ..." update if { [ catch { uu_EncodeToMail $EFPath $EncodeMailAddr \ $EncodeFileName $EncodeSubject "" $EncodeMaxLines \ $EncodeEncoding $EncodeFrom $EncodeReplyTo } message ] } { tk_dialog ._Dialog { Error while Encoding } "The following\ error occured while sending the file via mail:\ $message" \ error 0 OK } } if { $EncodeNewsYes } { ._Status._Text config -text "Encoding and Emailing $EFName ..." update if { [ catch { uu_EncodeToNews $EFPath $EncodeNewsGroup \ $EncodeFileName $EncodeSubject "" $EncodeMaxLines \ $EncodeEncoding $EncodeFrom $EncodeReplyTo } message ] } { tk_dialog ._Dialog { Error while Encoding } "The following\ error occured while sending the file via news:\ $message" \ error 0 OK } } # # end of processing # incr index } . config -cursor $oldCursor ._Status._Text config -text $oldText focus $oldFocus destroy ._Encode } # # Helper function to decode a bunch of files # proc DecodeProc { DecodeList } { global OptionOverwrite global OptionDesperate global SaveFilePath global FileList set count [ llength $DecodeList ] set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] if { $DecodeList == {} } { return; } if { ! [ CheckWritable $SaveFilePath ] } { return; } . config -cursor watch for { set index 0 } { $index < $count } { incr index } { set ItemNo [ lindex $DecodeList $index ] set FileName [ lindex [ lindex $FileList $ItemNo ] 2 ] set FileNumber [ lindex [ lindex $FileList $ItemNo ] 0 ] set FilePath [ file join $SaveFilePath $FileName ] ._Status._Text configure -text "Decoding $FileName ..." if { [ file exists $FilePath ] && ! [ file writable $FilePath ] } { tk_dialog ._Dialog { File Error } "The File $FilePath exists\ and can not be written" error 0 OK continue } elseif { [ file exists $FilePath ] && ! $OptionOverwrite } { set answer [ tk_dialog ._Dialog "File Exists" "$FileName\ already exists in $SaveFilePath." question 0 \ "Overwrite" "Next File" "Cancel" ] if { $answer == "1" } { continue } elseif { $answer == "2" } { break } } # # At this point, the target file either does not exist or # we want to overwrite it # update set result [ catch { uu_DecodeFile $FileNumber $FilePath } errorMsg ] if { $result } { tk_dialog ._Dialog "Error while Decoding" "The following\ problem occured while decoding: $errorMsg" \ error 0 OK continue } } ._Status._Text config -text $oldText . config -cursor $oldCursor } # # Button 'Decode' # proc Decode {} { DecodeProc [ ._MainFrame._FileList._Liste curselection ] } # # Button 'Decode All' # proc DecodeAll {} { set count [ ._MainFrame._FileList._Liste size ] set DecodeList {} for { set index 0 } { $index < $count } { incr index } { lappend DecodeList $index } DecodeProc $DecodeList } # # Action 'Info' # # Info about a file. This displays either the zeroeth part of a file or # the first part up to the first encoded line # proc Info {} { set TheInfoFile [ lindex [ ._MainFrame._FileList._Liste curselection ] 0 ] if { $TheInfoFile == {} } { return } InfoFile $TheInfoFile } proc InfoFile { TheInfoFile } { global FileList set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] set FileName [ lindex [ lindex $FileList $TheInfoFile ] 2 ] set FileNumber [ lindex [ lindex $FileList $TheInfoFile ] 0 ] if { $FileName == "" } { return } . config -cursor watch ._Status._Text config -text "Getting File Info for $FileName" if { [ catch { .info configure } ] } { toplevel .info frame .info.top frame .info.bot text .info.top.text -relief raised -bd 2 -wrap none \ -xscrollcommand ".info.top.sbx set" \ -yscrollcommand ".info.top.sby set" scrollbar .info.top.sbx -command ".info.top.text xview" \ -orient horizontal scrollbar .info.top.sby -command ".info.top.text yview" pack .info.top.sbx -side bottom -fill x pack .info.top.sby -side right -fill y pack .info.top.text -fill both -expand 1 button .info.bot.done -text "Done" -command "destroy .info" pack .info.bot.done -side right -padx 4 -pady 4 pack .info.top -side top -fill both -expand 1 pack .info.bot -side bottom } wm title .info "Info about [ file tail $FileName ]" .info.top.text configure -state normal if { [ catch { uu_InfoFile $FileNumber .info.top.text } errorMsg ] } { tk_dialog ._Dialog "No Info" "The following problem occured\ while trying to get Info: $errorMsg" error 0 OK } .info.top.text configure -state disabled ._Status._Text config -text $oldText . config -cursor $oldCursor } # # Action 'List' # proc List {} { global FileList set ListFile [ lindex [ ._MainFrame._FileList._Liste curselection ] 0 ] if { $ListFile == {} } { return; } set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] set FileName [ lindex [ lindex $FileList $ListFile ] 2 ] . config -cursor watch ._Status._Text config -text "Listing $FileName" if { [ catch { .list configure } ] } { toplevel .list frame .list.top frame .list.bot text .list.top.text -relief raised -bd 2 -wrap none \ -xscrollcommand ".list.top.sbx set" \ -yscrollcommand ".list.top.sby set" scrollbar .list.top.sbx -command ".list.top.text xview" \ -orient horizontal scrollbar .list.top.sby -command ".list.top.text yview" pack .list.top.sbx -side bottom -fill x pack .list.top.sby -side right -fill y pack .list.top.text -fill both -expand 1 button .list.bot.done -text "Done" -command "destroy .list" pack .list.bot.done -side right -padx 4 -pady 4 pack .list.top -side top -fill both -expand 1 pack .list.bot -side bottom } wm title .list "Listing of [ file tail $FileName ]" .list.top.text configure -state normal if { [ catch { uu_ListFile $ListFile .list.top.text } errorMsg ] } { tk_dialog ._Dialog "Oops" "The following problem occured\ while trying to list the file: $errorMsg" error 0 OK } .list.top.text configure -state disabled ._Status._Text config -text $oldText . config -cursor $oldCursor } # # Action 'Rename' # proc Rename {} { global FileList global NewName global OldName global RenBut set RenameList [ ._MainFrame._FileList._Liste curselection ] set count [ llength $RenameList ] set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] set oldFocus [ focus ] if { $RenameList == {} } { return; } toplevel .rename frame .rename.cur -relief raised -bd 1 frame .rename.new -relief raised -bd 1 frame .rename.but -relief raised -bd 2 frame .rename.but.but label .rename.cur.lab -text "Old Name: " entry .rename.cur.nam -width 40 -relief sunken -bd 2 \ -textvariable OldName label .rename.new.lab -text "New Name: " entry .rename.new.nam -width 40 -relief sunken -bd 2 \ -textvariable NewName pack .rename.cur.nam -side right -padx 8 -pady 8 pack .rename.new.nam -side right -padx 8 -pady 8 pack .rename.cur.lab -side left -padx 8 -pady 8 -fill x pack .rename.new.lab -side left -padx 8 -pady 8 -fill x button .rename.but.but.ok -text "Ok" -command "set RenBut 1" button .rename.but.but.can -text "Cancel" -command "set RenBut 0" pack .rename.but.but.ok -side left -padx 4 -pady 4 -fill x pack .rename.but.but.can -side left -padx 4 -pady 4 -fill x pack .rename.but.but pack .rename.cur -side top -fill x pack .rename.new -side top -fill x pack .rename.but -side bottom -fill x bind .rename.new.nam "set RenBut 1" wm title .rename "Rename" . config -cursor watch set oldFocus [ focus ] tkwait visibility .rename grab set .rename focus .rename for { set index 0 } { $index < $count } { incr index } { set ItemNo [ lindex $RenameList $index ] set FileName [ lindex [ lindex $FileList $ItemNo ] 2 ] set FileNumber [ lindex [ lindex $FileList $ItemNo ] 0 ] ._Status._Text config -text "Renaming $FileName" .rename.cur.nam configure -state normal set OldName $FileName set NewName $FileName .rename.cur.nam configure -state disabled set RenBut {} update tkwait variable RenBut if { $RenBut == 0 } { break } elseif { $RenBut == 1 && $NewName != {} } { if { [ catch { uu_Rename $ItemNo [file tail $NewName] } eMsg ] } { tk_dialog ._Dialog "Oops" "Couldn't rename the file for\ the following reason: $eMsg" error 0 OK } } } ._Status._Text config -text $oldText . config -cursor $oldCursor destroy .rename focus $oldFocus ShowFileList } # # Action 'Execute' # proc Execute {} { global FileList global FileTypes global ExeCom global ExeBut ifndef ExeCom {} set ListFile [ lindex [ ._MainFrame._FileList._Liste curselection ] 0 ] set app {} if { $ListFile == {} } { return; } set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] set FileName [ lindex [ lindex $FileList $ListFile ] 2 ] set FileNumb [ lindex [ lindex $FileList $ListFile ] 0 ] set mimtype [ lindex [ lindex $FileList $ListFile ] 3 ] set oldFocus [ focus ] . config -cursor watch ._Status._Text config -text "Decoding $FileName to temp file" update if { [ catch { uu_GetTempFile $FileNumb } tempFile ] } { tk_dialog ._Dialog "Error while decoding" "The following problem\ occured while decoding: $tempFile" \ error 0 OK } else { # # Do we have a Content-Type: # if { $mimtype != "" } { set app [ GetTypeAction $mimtype ] } # # try to determine app from file extension # if { $app == "" } { set lfn [ split [ string tolower $FileName ] . ] set ext [ lindex $lfn [ expr [ llength $lfn ] - 1 ] ] if { [ set mimtype [ GetTypeByExtension $ext ] ] != "" } { set app [ GetTypeAction $mimtype ] } } # # if we have no app yet, ask the user # if { $app == "" } { toplevel .app label .app.msg -wraplength 3i -relief raised -bd 1 -text "Enter \ a command line to execute. Use %s for the file name.\ Do not attempt to background the command." pack .app.msg -side top -ipadx 8 -ipady 8 -fill x frame .app.com label .app.com.lab -text "Command: " entry .app.com.ent -relief sunken -bd 2 \ -textvariable ExeCom pack .app.com.lab -side left -padx 8 -pady 8 pack .app.com.ent -side right -padx 8 -pady 8 -fill x -expand 1 pack .app.com -side top -fill x frame .app.but -relief raised -bd 2 frame .app.but.but button .app.but.but.ok -text "Execute" -command "set ExeBut 1" button .app.but.but.can -text "Cancel" -command "set ExeBut 0" pack .app.but.but.ok -side left -padx 4 -pady 4 -fill x pack .app.but.but.can -side left -padx 4 -pady 4 -fill x pack .app.but.but pack .app.but -side bottom -fill x bind .app.com.ent "set ExeBut 1" wm title .app "Execute Command" tkwait visibility .app grab set .app focus .app ._Status._Text config -text "Watiting for you to enter command" set ExeBut {} update tkwait variable ExeBut destroy .app focus $oldFocus if { $ExeBut == 1 } { set app $ExeCom } } if { $app != "" } { set RunString [ format $app $tempFile ] ._Status._Text config -text "Watiting for child to terminate" update if { [ catch { eval exec $RunString } errorMsg ] } { tk_dialog ._Dialog "Execution failed" "The following problem\ occured while executing your command: $errorMsg" \ error 0 OK } } } ._Status._Text config -text $oldText . config -cursor $oldCursor focus $oldFocus } # # Menu Help->About # proc About {} { global AboutFinish global FrankPic set w ._About set AboutFinish {} toplevel $w wm title $w "About UUDeview" # # don't load the image if less than 256 colors or colormap full # if { [ catch { winfo colormapfull $w } cmf ] } { set cmf 0 } if { [ winfo depth $w ] >= 8 && ! $cmf } { if { ! [ catch { image create photo Frank -data $FrankPic } ] } { frame $w._Image -relief raised -bd 2 label $w._Image._Frank -image Frank label $w._Image._Name -text "This Is Me" pack $w._Image._Frank $w._Image._Name -side top pack $w._Image -side left -padx 3 -pady 3 } } frame $w._Right label $w._Right._Text1 -text "UUDeview Version\ [ lindex [ lindex [ uu_Info version ] 0 ] 1 ]" \ -font -Adobe-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-* label $w._Right._Text2 -text "Written by Frank Pilhofer" label $w._Right._Text3 -text "fp@fpx.de\ \nhttp://www.fpx.de/" label $w._Right._Text4 -text "This software is Freeware and may be\ distributed freely. But if you happen to like it, why not\ surprise the Author with a postcard, sent to" \ -font -Adobe-Helvetica-Bold-R-Normal--*-100-*-*-*-*-*-* \ -wraplength 3i label $w._Right._Addr -text "Frank Pilhofer\nIn Der Wink 3\ \n60437 Frankfurt\nGermany" -justify left button $w._Right._Button -text "Ok" -command { set AboutFinish ok } pack $w._Right._Button -fill both -padx 10 -pady 3 -side bottom pack $w._Right._Text1 $w._Right._Text2 $w._Right._Text3 \ $w._Right._Text4 $w._Right._Addr \ -fill both -padx 10 -pady 5 -side top pack $w._Right -fill both set oldFocus [ focus ] tkwait visibility $w grab set $w focus $w tkwait variable AboutFinish destroy $w focus $oldFocus } # # Menu Help->License # proc License {} { global COPYING set oldCursor [ lindex [ . config -cursor ] 4 ] set oldText [ lindex [ ._Status._Text config -text ] 4 ] . config -cursor watch ._Status._Text config -text "Loading and Displaying License" if { [ catch { set COPYING } ] } { tk_dialog ._Dialog "Not Available" "I could not load the License\ file. You received a copy of the GPL (GNU General Public\ License) in the file COPYING along with the UUDeview\ distribution. Please refer to this file instead." \ error 0 OK } elseif { [ catch { .license configure } ] } { toplevel .license frame .license.top frame .license.bot text .license.top.text -relief raised -bd 2 -wrap none \ -xscrollcommand ".license.top.sbx set" \ -yscrollcommand ".license.top.sby set" \ -font -*-Courier-Medium-R-Normal--*-120-*-*-*-*-*-* scrollbar .license.top.sbx -command ".license.top.text xview" \ -orient horizontal scrollbar .license.top.sby -command ".license.top.text yview" pack .license.top.sbx -side bottom -fill x pack .license.top.sby -side right -fill y pack .license.top.text -fill both -expand 1 button .license.bot.done -text "Done" -command "destroy .license" pack .license.bot.done -side right -padx 4 -pady 4 pack .license.top -side top -fill both -expand 1 pack .license.bot -side bottom wm title .license "GPL - Gnu General Public License" regsub -all "#" $COPYING "" TempText .license.top.text insert 1.0 $TempText .license.top.text configure -state disabled } ._Status._Text config -text $oldText . config -cursor $oldCursor } ############################################################################## ## Display helper functions ############################################################################## # # these two procedures are needed to keep 2 listboxes in sync # proc ScrollCommand { args } { eval ._MainFrame._FileList._Status yview $args eval ._MainFrame._FileList._Liste yview $args } proc UpdateListScroll { idlb1 idlb2 idsb first last } { set InMotion 1 if { [ $idlb1 size ] } { set lbnf [ expr $first + 0.5 / [ $idlb1 size ] ] } else { set lbnf $first } $idsb set $first $last $idlb1 yview moveto $lbnf $idlb2 yview moveto $lbnf } proc UpdateSBScroll { idlb1 idlb2 idsb command number { units "" } } { set InMotion 1 if { [ $idlb1 size ] } { set lbnf [ expr $number + 0.5 / [ $idlb1 size ] ] } else { set lbnf $number } if { $command == "scroll" } { $idlb1 yview $command $number $units $idlb2 yview $command $number $units update } elseif { $command == "moveto" } { $idlb1 yview $command $lbnf $idlb2 yview $command $lbnf update } else { puts "Unknown Scrolling Command: $view $command $number $units" } } ############################################################################## ## Build our Main Frame ############################################################################## # # Menu Bar # frame ._MainMenu -relief raised -bd 2 menubutton ._MainMenu._File -text File -underline 0 \ -menu ._MainMenu._File._Menu menubutton ._MainMenu._Options -text Options -underline 0 \ -menu ._MainMenu._Options._Menu menubutton ._MainMenu._Actions -text Actions -underline 0 \ -menu ._MainMenu._Actions._Menu menubutton ._MainMenu._Help -text Help -underline 0 \ -menu ._MainMenu._Help._Menu menu ._MainMenu._File._Menu menu ._MainMenu._Options._Menu menu ._MainMenu._Actions._Menu menu ._MainMenu._Help._Menu ._MainMenu._File._Menu add command -label "Load ..." -underline 0 \ -command "Load" ._MainMenu._File._Menu add command -label "Encode ..." -underline 0 \ -command "Encode" ._MainMenu._File._Menu add separator ._MainMenu._File._Menu add command -label "Helpers" -underline 0 \ -command "MimeSetup" ._MainMenu._File._Menu add command -label "Save Setup" -underline 0 \ -command "SaveSetup" ._MainMenu._File._Menu add separator ._MainMenu._File._Menu add command -label "Quit" -underline 0 \ -command "Quit" ._MainMenu._Options._Menu add checkbutton -label "Fast Scanning" \ -underline 0 -selectcolor black -variable OptionFast ._MainMenu._Options._Menu add checkbutton -label "Automatic Overwrite" \ -underline 10 -selectcolor black -variable OptionOverwrite ._MainMenu._Options._Menu add checkbutton -label "Desperate Mode" \ -underline 10 -selectcolor black -variable OptionDesperate ._MainMenu._Options._Menu add checkbutton -label "Verbose Mode" \ -underline 0 -selectcolor black -variable OptionVerbose ._MainMenu._Options._Menu add checkbutton -label "Alternate Bracket Policy" \ -underline 0 -selectcolor black -variable OptionBracket ._MainMenu._Options._Menu add checkbutton -label "Dumb Mode" \ -underline 0 -selectcolor black -variable OptionDumbness ._MainMenu._Options._Menu add checkbutton -label "Handle Text Files" \ -underline 0 -selectcolor black -variable OptionUsetext ._MainMenu._Options._Menu add checkbutton -label "Auto Info" \ -underline 5 -selectcolor black -variable OptionAutoInfo ._MainMenu._Options._Menu add checkbutton -label "Remove Input Files" \ -underline 0 -selectcolor black -variable OptionRemove ._MainMenu._Options._Menu add checkbutton -label "MIME Compliance" \ -underline 0 -selectcolor black -variable OptionMoreMime ._MainMenu._Actions._Menu add command -label "Decode" -underline 0 \ -command "Decode" ._MainMenu._Actions._Menu add command -label "Rename" -underline 0 \ -command "Rename" ._MainMenu._Actions._Menu add command -label "Decode All" -underline 7 \ -command "DecodeAll" ._MainMenu._Actions._Menu add command -label "Info" -underline 0 \ -command "Info" ._MainMenu._Actions._Menu add command -label "Execute" -underline 0 \ -command "Execute" ._MainMenu._Actions._Menu add command -label "List Text File" -underline 0 \ -command "List" ._MainMenu._Help._Menu add command -label "About ..." -underline 0 \ -command "About" ._MainMenu._Help._Menu add command -label "License ..." -underline 0 \ -command "License" #._MainMenu._Help._Menu add command -label "Index ..." -underline 0 \ # -command "Index" pack ._MainMenu._File ._MainMenu._Options ._MainMenu._Actions \ ._MainMenu._Help -side left pack ._MainMenu._Help -side right tk_menuBar ._MainMenu ._MainMenu._File ._MainMenu._Options \ ._MainMenu._Actions ._MainMenu._Help # # middle part, on the left the file listboxes, on the right some buttons # frame ._MainFrame -relief raised -bd 2 # # Left: file listboxes and scrollbar # frame ._MainFrame._FileList # # definition of the second listbox which I couldn't get to work properly # # Design 1 # #listbox ._MainFrame._FileList._Status -relief sunken -width 4 \ # -yscrollcommand "\ # UpdateListScroll ._MainFrame._FileList._Status \ # ._MainFrame._FileList._Liste \ # ._MainFrame._FileList._Scrollbar " #listbox ._MainFrame._FileList._Liste -relief sunken -selectmode extended \ # -yscrollcommand "\ # UpdateListScroll ._MainFrame._FileList._Status \ # ._MainFrame._FileList._Liste \ # ._MainFrame._FileList._Scrollbar " #scrollbar ._MainFrame._FileList._Scrollbar -command " \ # UpdateSBScroll ._MainFrame._FileList._Status \ # ._MainFrame._FileList._Liste \ # ._MainFrame._FileList._Scrollbar " #pack ._MainFrame._FileList._Status -side left -padx 8 -pady 8 -fill y # # Design 2 # #listbox ._MainFrame._FileList._Liste -relief sunken -selectmode extended \ # -yscrollcommand "._MainFrame._FileList._Scrollbar set" #scrollbar ._MainFrame._FileList._Scrollbar \ # -command "._MainFrame._FileList._Liste yview" #pack ._MainFrame._FileList._Liste -side left -padx 8 -pady 8 \ # -expand true -fill both # # Design 3 # listbox ._MainFrame._FileList._Status -relief sunken -width 8 \ -yscrollcommand { ._MainFrame._FileList._Scrollbar set } \ -exportselection false listbox ._MainFrame._FileList._Liste -relief sunken -selectmode extended \ -yscrollcommand { ._MainFrame._FileList._Scrollbar set } \ -exportselection false scrollbar ._MainFrame._FileList._Scrollbar \ -command ScrollCommand pack ._MainFrame._FileList._Status -side left -padx 8 -pady 8 -fill y pack ._MainFrame._FileList._Liste -side left -padx 8 -pady 8 \ -expand true -fill both pack ._MainFrame._FileList._Scrollbar -pady 8 -side right -fill y if { [ lindex [ ._MainFrame._FileList._Liste configure -width ] 4 ] < 20 } { ._MainFrame._FileList._Liste configure -width 20 } # # Right: some buttons # frame ._MainFrame._Buttons button ._MainFrame._Buttons._Load -text "Load" -command "Load" button ._MainFrame._Buttons._Decode -text "Decode" -command "Decode" button ._MainFrame._Buttons._Execute -text "Execute" -command "Execute" button ._MainFrame._Buttons._Info -text "Info" -command "Info" button ._MainFrame._Buttons._Quit -text "Quit" -command "Quit" pack ._MainFrame._Buttons._Load \ ._MainFrame._Buttons._Decode ._MainFrame._Buttons._Execute \ ._MainFrame._Buttons._Info ._MainFrame._Buttons._Quit \ -ipadx 4 -ipady 4 -fill x -padx 2 -pady 2 # # packe MainFrame # pack ._MainFrame._FileList -side left -expand true -fill both pack ._MainFrame._Buttons -side right -padx 8 -pady 8 -anchor center # # Down: Save Path # frame ._SPEntry -relief raised -bd 2 button ._SPEntry._Label -text "Save Path:" -bd 1 -command { set NewPath [ tk_SelectFiles "Savefile Path" 0 2 $SaveFilePath ] if { $NewPath != "" } { if { [ CheckWritable $NewPath ] } { set SaveFilePath [ CompressSlashes $NewPath ] } } } entry ._SPEntry._Path -relief sunken -textvariable SaveFilePath pack ._SPEntry._Label -side left -padx 4 -pady 4 pack ._SPEntry._Path -side right -padx 4 -pady 4 -fill x -expand true # # noch weiter unten: Statuszeile # frame ._Status -relief sunken -bd 1 label ._Status._Desc -text "Status: " \ -font -Adobe-Helvetica-Bold-R-Normal--*-100-*-*-*-*-*-* label ._Status._Text -text "OK" -justify left -anchor w \ -font -Adobe-Helvetica-Bold-R-Normal--*-100-*-*-*-*-*-* pack ._Status._Desc -side left -padx 2 -pady 2 pack ._Status._Text -side left -pady 2 -fill x # # Packe alles zusammen # pack ._MainMenu -side top -fill x pack ._Status -side bottom -fill x pack ._SPEntry -side bottom -fill x pack ._MainFrame -expand true -fill both # # Bindings # bind ._SPEntry._Path { if { $SaveFilePath == {} } { set SaveFilePath [ pwd ] } set SaveFilePath [ CompressSlashes $SaveFilePath ] CheckWritable $SaveFilePath } # # AutoInfo pops up Info about a file whenever the user clicks on it # bind ._MainFrame._FileList._Liste { if { $OptionAutoInfo } { set TheInfoFile [ ._MainFrame._FileList._Liste index @%x,%y ] if { $TheInfoFile != "" } { InfoFile $TheInfoFile } } } # # ---------------------------------------------------------------------- # # # A File Selector Box for multiple files in Tk # # Frank Pilhofer Feb/Mar 1996 # # # Default Path and Pattern # set MFSLoadFilterPath [pwd] set MFSLoadFilterPattern "*" # # directory separator # if { $tcl_platform(platform) == "windows" } { set ds "\\" set parent ".." } elseif { $tcl_platform(platform) == "macintosh" } { set ds ":" set parent ":" } else { set ds "/" set parent ".." } ############################################################################## ## General helper functions ############################################################################## # # Canonicalize a path: compress multiple slashes, remove slash at end, # expand double-dots and perform tilde expansion # proc CompressSlashes { Path } { global ds parent set thepath [ file split $Path ] set lastel [ expr [ llength $thepath ] - 1 ] set newpat {} set ignore 0 set element "." for { set index $lastel } { $index >= 0 } { incr index -1 } { set element [ lindex $thepath $index ] if { $element == {} } { } elseif { $element == "." } { } elseif { $element == $parent } { incr ignore } elseif { $index == 0 && [ string range $element 0 0 ] == "~" } { set hopath [ file split [ glob -nocomplain $element ] ] if { $hopath == {} } { tk_dialog ._Dialog { User does not exist } "This user does\ not exist." {} 0 OK } elseif { $ignore } { if { $ignore > [ llength $hopath ] } { set newpat [ linsert $newpat 0 {} ] } else { set holen [ llength $hopath ] set newpat [ concat [ lrange $hopath 0 \ [ expr $holen - $ignore - 1 ] ] \ $newpat ] } } else { set newpat [ concat $hopath $newpat ] } } elseif { $ignore } { incr ignore -1 } else { set newpat [ linsert $newpat 0 $element ] } } if { $element == {} } { set newpat [ linsert $newpat 0 {} ] } elseif { $element == $ds } { } elseif { $element == "." || $element == $parent } { if { $ignore } { set curdir [ file split [ pwd ] ] if { $ignore > [ llength $curdir ] } { set newpat [ linsert $newpat 0 {} ] } else { set cdlen [ llength $curdir ] set newpat [ concat [ lrange $curdir 0 \ [ expr $cdlen - $ignore - 1 ] ] \ $newpat ] } } else { set newpat [ linsert $newpat 0 "." ] } } else { set newpat [ linsert $newpat 0 "." ] } set ThePath [ eval file join $newpat ] # if { $ThePath == {} } { # set ThePath [ file join "" ] # } return $ThePath } # # Canonize our search pattern # proc CanonPattern { Pattern } { global MFSLoadFilterPath global MFSLoadFilterPattern global ds parent set ThePath [ CompressSlashes $Pattern ] set TheDir [ file dirname $ThePath ] set TheFile [ file tail $ThePath ] # split up by directory and pattern if { $TheDir == {} } { set MFSLoadFilterPath "." set MFSLoadFilterPattern "*" } elseif { [ file exists $ThePath ] && [ file isdirectory $ThePath ] } { set MFSLoadFilterPath $ThePath if { $MFSLoadFilterPattern == {} } { set MFSLoadFilterPattern "*" } } else { set MFSLoadFilterPath $TheDir set MFSLoadFilterPattern $TheFile } set MFSCurPattern [ file join $MFSLoadFilterPath $MFSLoadFilterPattern ] return $MFSCurPattern } # # Add new value to a listbox if it's not already there # proc AddToLb { lb value } { set count [ $lb size ] for { set index 0 ; set found 0 } { $index < $count } { incr index } { if { [ $lb get $index ] == $value } { set found 1 break } } if { $found == 0 } { $lb insert end $value } } # # Update elements in Listboxes after directory or filter change # proc MFSSelectShow { havefiles } { global MFSLoadFilterPath global MFSLoadFilterPattern global ds parent if { $havefiles } { global MFSlbf } global MFSlbd if { $havefiles } { $MFSlbf delete 0 end } $MFSlbd delete 0 end if { ! [ file readable $MFSLoadFilterPath ] } { tk_dialog ._Dialog { File Error } "You do not have the proper\ permissions to browse this Directory: $MFSLoadFilterPath" \ {} 0 OK if { [ file pathtype $MFSLoadFilterPath ] == "absolute" } { if { [ llength [ file split $MFSLoadFilterPath ] ] > 1 } { $MFSlbd insert 0 $parent$ds } } return } # # insert files into file list # if { $havefiles } { set pat [ file join $MFSLoadFilterPath $MFSLoadFilterPattern ] foreach file [ lsort [ glob -nocomplain -- $pat ] ] { set basename [ file tail $file ] if { ! [ file isdirectory $file ] } { $MFSlbf insert end $basename } } } # # insert directories into directory list # set pat [ file join $MFSLoadFilterPath * ] foreach file [ lsort [ glob -nocomplain -- $pat ] ] { set basename [ file tail $file ] if { [ file isdirectory $file ] } { append basename / $MFSlbd insert end $basename } } if { [ file pathtype $MFSLoadFilterPath ] == "absolute" } { if { [ llength [ file split $MFSLoadFilterPath ] ] > 1 } { $MFSlbd insert 0 $parent$ds } } $MFSlbd insert 0 "./" } proc SelectAddFromList { lb } { global MFSLoadFilterPath global MFSLoadFilterPattern global ds parent global MFSlbi set Selection [ $lb curselection ] set SelItems [ llength $Selection ] for { set index 0 } { $index < $SelItems } { incr index } { set SelFile [ $lb get [ lindex $Selection $index ] ] set TheFile [ file join $MFSLoadFilterPath $SelFile ] if { ! [ file readable $TheFile ] } { tk_dialog ._Dialog { File Error } "You do not have the proper\ permissions to read this file or directory: $TheFile" \ {} 0 OK } else { set TheFile [ CompressSlashes $TheFile ] if { [ file isdirectory $TheFile ] && $TheFile != $ds } { append TheFile $ds } AddToLb $MFSlbi $TheFile } } return 0 } ############################################################################## # Main function ############################################################################## # # title: Title of this dialog box. Printed in the title bar # multifile: whether we allow to select multiple files # allowdir: Whether we allow directories to be selected: # 0: no directories may be added to the selection # 1: directories may be selected # 2: only directories may be selected # startpath: the path where we want the selection to start # proc tk_SelectFiles { title multifile allowdir { startpath "" } } { global MFSLoadFilterPath global MFSLoadFilterPattern global MFSSelectFinish global MFSCurPattern global MFSCurSelection global MFSlbf global MFSlbd global MFSlbi global ds parent set MFSLoadFilterPath [ CompressSlashes $MFSLoadFilterPath ] set OldFilterPath $MFSLoadFilterPath set OldFilterPattern $MFSLoadFilterPattern if { $startpath != "" } { set MFSLoadFilterPath [ CompressSlashes $startpath ] } set MFSCurPattern [ file join $MFSLoadFilterPath $MFSLoadFilterPattern ] set MFSSelectFinish {} set MFSCurSelection "" set MFSlbf ._Selector._Top._FileList.sub.box set MFSlbd ._Selector._Top._DirList.sub.box set MFSlbi ._Selector._SelList._FileList._List toplevel ._Selector wm title ._Selector $title wm minsize ._Selector 300 200 frame ._Selector._Filter -relief raised -bd 1 label ._Selector._Filter._Label -text "Filter:" entry ._Selector._Filter._Filter -relief sunken -textvariable MFSCurPattern pack ._Selector._Filter._Label -side left -padx 4 -pady 4 pack ._Selector._Filter._Filter -side right -padx 8 -pady 4 \ -fill x -expand true pack ._Selector._Filter -side top -fill x frame ._Selector._Top -relief groove -bd 1 frame ._Selector._Top._DirList frame ._Selector._Top._DirList.sub label ._Selector._Top._DirList.label -text "Directories" listbox ._Selector._Top._DirList.sub.box -relief sunken \ -xscrollcommand "._Selector._Top._DirList.sub.xsb set" \ -yscrollcommand "._Selector._Top._DirList.sub.ysb set" \ -selectmode normal -height 8 scrollbar ._Selector._Top._DirList.sub.xsb -orient horizontal \ -command "._Selector._Top._DirList.sub.box xview" scrollbar ._Selector._Top._DirList.sub.ysb \ -command "._Selector._Top._DirList.sub.box yview" pack ._Selector._Top._DirList.sub.xsb -side bottom -fill x pack ._Selector._Top._DirList.sub.ysb -side right -fill y pack ._Selector._Top._DirList.sub.box -side left -expand true -fill both pack ._Selector._Top._DirList.label -side top -anchor w -padx 4 pack ._Selector._Top._DirList.sub -side bottom -expand true -fill both if { $allowdir != 2 } { frame ._Selector._Top._FileList frame ._Selector._Top._FileList.sub label ._Selector._Top._FileList.label -text "Files" if { $multifile } { listbox ._Selector._Top._FileList.sub.box -relief sunken \ -xscrollcommand "._Selector._Top._FileList.sub.xsb set" \ -yscrollcommand "._Selector._Top._FileList.sub.ysb set" \ -selectmode extended -height 8 } else { listbox ._Selector._Top._FileList.sub.box -relief sunken \ -xscrollcommand "._Selector._Top._FileList.sub.xsb set" \ -yscrollcommand "._Selector._Top._FileList.sub.ysb set" \ -selectmode normal -height 8 } scrollbar ._Selector._Top._FileList.sub.xsb -orient horizontal \ -command "._Selector._Top._FileList.sub.box xview" scrollbar ._Selector._Top._FileList.sub.ysb \ -command "._Selector._Top._FileList.sub.box yview" pack ._Selector._Top._FileList.sub.xsb -side bottom -fill x pack ._Selector._Top._FileList.sub.ysb -side right -fill y pack ._Selector._Top._FileList.sub.box -side left \ -expand true -fill both pack ._Selector._Top._FileList.label -side top -anchor w -padx 4 pack ._Selector._Top._FileList.sub -side bottom \ -expand true -fill both } if { $multifile } { frame ._Selector._Top._Buttons frame ._Selector._Top._Buttons.b if { $allowdir == 2 } { button ._Selector._Top._Buttons.b._Add -text "Add" -width 8 \ -command { SelectAddFromList $MFSlbd } } else { button ._Selector._Top._Buttons.b._Add -text "Add" -width 8 \ -command { SelectAddFromList $MFSlbf } if { $allowdir == 1 } { button ._Selector._Top._Buttons.b._AddPath -text "Add Path" \ -width 8 -command { SelectAddFromList $MFSlbd } } } if { $allowdir != 2 } { button ._Selector._Top._Buttons.b._AddAll -text "Add All" \ -width 8 -command { set ThePath $MFSLoadFilterPath set count [ $MFSlbf size ] if { $ThePath != $ds } { append ThePath $ds } for { set index 0 } { $index < $count} { incr index } { set TheFile $ThePath append TheFile [ $MFSlbf get $index ] AddToLb $MFSlbi $TheFile } } } if { $allowdir == 1 } { pack ._Selector._Top._Buttons.b._Add \ ._Selector._Top._Buttons.b._AddPath \ ._Selector._Top._Buttons.b._AddAll \ -side left -ipadx 4 -ipady 4 -fill x -padx 2 -pady 2 } elseif { $allowdir == 2 } { pack ._Selector._Top._Buttons.b._Add \ -side left -ipadx 4 -ipady 4 -fill x -padx 2 -pady 2 } else { pack ._Selector._Top._Buttons.b._Add \ ._Selector._Top._Buttons.b._AddAll \ -side left -ipadx 4 -ipady 4 -fill x -padx 2 -pady 2 } pack ._Selector._Top._Buttons.b } if { $multifile } { pack ._Selector._Top._Buttons -side bottom -fill x -padx 4 -pady 4 } pack ._Selector._Top._DirList -side left -expand true -fill both -padx 4 if { $allowdir != 2 } { pack ._Selector._Top._FileList -side right -expand true \ -fill both -padx 4 } if { $multifile } { frame ._Selector._SelList -relief groove -bd 1 frame ._Selector._SelList._FileList frame ._Selector._SelList._Buttons -bd 4 label ._Selector._SelList._Label -text "Selected Files" -relief groove listbox ._Selector._SelList._FileList._List -relief sunken \ -xscrollcommand "._Selector._SelList._FileList._XScrollbar set" \ -yscrollcommand "._Selector._SelList._FileList._YScrollbar set" \ -selectmode extended -height 4 scrollbar ._Selector._SelList._FileList._XScrollbar -orient horizontal \ -command "._Selector._SelList._FileList._List xview" scrollbar ._Selector._SelList._FileList._YScrollbar \ -command "._Selector._SelList._FileList._List yview" pack ._Selector._SelList._FileList._XScrollbar -side bottom -fill x pack ._Selector._SelList._FileList._YScrollbar -side right -fill y pack ._Selector._SelList._FileList._List -side left -expand true \ -fill both button ._Selector._SelList._Buttons._Remove -text "Remove" -width 8 \ -command { set Selection [ $MFSlbi curselection ] set count 0 foreach index $Selection { $MFSlbi delete [ expr $index - $count ] incr count } } pack ._Selector._SelList._Buttons._Remove -ipadx 4 -ipady 4 -fill x \ -padx 2 -pady 2 -anchor center pack ._Selector._SelList._Label -side top -fill x -padx 4 -pady 4 pack ._Selector._SelList._FileList -side left -expand true -fill both \ -padx 4 -pady 4 pack ._Selector._SelList._Buttons -side right -padx 4 -pady 4 } else { frame ._Selector._Selection -relief groove -bd 1 label ._Selector._Selection.lab -text "Selection" entry ._Selector._Selection.ent -relief sunken \ -textvariable MFSCurSelection pack ._Selector._Selection.ent -side bottom -padx 4 -fill x pack ._Selector._Selection.lab -side bottom -anchor w -padx 4 } frame ._Selector._Buttons -relief raised -bd 1 frame ._Selector._Buttons.b if { $multifile } { button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command { set MFSSelectFinish ok } } else { if { $allowdir == 0 } { button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command { if { ! [ file exists $MFSCurSelection ] || \ ! [ file readable $MFSCurSelection ] || \ [ file isdirectory $MFSCurSelection ] } { tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\ does not exist, is not readable or is a\ directory" {} 0 OK } else { set MFSSelectFinish ok } } } elseif { $allowdir == 2 } { button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command { if { ! [ file exists $MFSCurSelection ] || \ ! [ file readable $MFSCurSelection ] || \ ! [ file isdirectory $MFSCurSelection ] } { tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\ does not exist, is not readable or is not a\ directory" {} 0 OK } else { set MFSSelectFinish ok } } } else { button ._Selector._Buttons.b._Ok -text "Ok" -width 8 -command { if { ! [ file exists $MFSCurSelection ] || \ ! [ file readable $MFSCurSelection ] } { tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\ does not exist or is not readable" {} 0 OK } else { set MFSSelectFinish ok } } } } if { $allowdir != 2 } { button ._Selector._Buttons.b._Filter -text "Filter" -width 8 -command { set MFSCurPattern [ CanonPattern $MFSCurPattern ] MFSSelectShow 1 } } else { button ._Selector._Buttons.b._Filter -text "Filter" -width 8 -command { set MFSCurPattern [ CanonPattern $MFSCurPattern ] MFSSelectShow 0 } } button ._Selector._Buttons.b._Cancel -text "Cancel" -width 8 \ -command { set MFSSelectFinish cancel } pack ._Selector._Buttons.b._Ok \ ._Selector._Buttons.b._Filter \ ._Selector._Buttons.b._Cancel \ -side left -ipadx 4 -ipady 4 -padx 4 -pady 4 pack ._Selector._Buttons.b pack ._Selector._Top -side top -expand true -fill both -ipadx 8 -ipady 8 if { $multifile } { pack ._Selector._SelList -side top -expand true -fill both \ -ipadx 8 -ipady 8 } else { pack ._Selector._Selection -side top -fill both -ipadx 8 -ipady 4 } pack ._Selector._Buttons -side bottom -fill x # # the items are up on screen. define bindings # if { $allowdir != 2 } { bind ._Selector._Filter._Filter { set MFSCurPattern [ CanonPattern $MFSCurPattern ] MFSSelectShow 1 } } else { bind ._Selector._Filter._Filter { set MFSCurPattern [ CanonPattern $MFSCurPattern ] MFSSelectShow 0 } } if { $multifile } { if { $allowdir != 2 } { bind $MFSlbd { set Selection [ lindex [ $MFSlbd curselection ] 0 ] if { $Selection != "" } { set TheFile [ $MFSlbd get $Selection ] set MFSLoadFilterPath [ CompressSlashes \ [ file join $MFSLoadFilterPath $TheFile ] ] set MFSCurPattern [ \ file join $MFSLoadFilterPath $MFSLoadFilterPattern] MFSSelectShow 1 } } } else { bind $MFSlbd { set Selection [ lindex [ $MFSlbd curselection ] 0 ] if { $Selection != "" } { set TheFile [ $MFSlbd get $Selection ] set MFSLoadFilterPath [ CompressSlashes \ [ file join $MFSLoadFilterPath $TheFile ] ] set MFSCurPattern [ \ file join $MFSLoadFilterPath $MFSLoadFilterPattern] MFSSelectShow 0 } } } if { $allowdir != 2 } { bind $MFSlbf { SelectAddFromList $MFSlbf } } } else { if { $allowdir != 2 } { bind $MFSlbd { set Selection [ lindex [ $MFSlbd curselection ] 0 ] if { $Selection != "" } { set TheFile [ $MFSlbd get $Selection ] set MFSLoadFilterPath [ CompressSlashes \ [ file join $MFSLoadFilterPath $TheFile ] ] set MFSCurPattern [ \ file join $MFSLoadFilterPath $MFSLoadFilterPattern] MFSSelectShow 1 } } } else { bind $MFSlbd { set Selection [ lindex [ $MFSlbd curselection ] 0 ] if { $Selection != "" } { set TheFile [ $MFSlbd get $Selection ] set MFSLoadFilterPath [ CompressSlashes \ [ file join $MFSLoadFilterPath $TheFile ] ] set MFSCurPattern [ \ file join $MFSLoadFilterPath $MFSLoadFilterPattern] MFSSelectShow 0 } } } } if { ! $multifile } { if { $allowdir } { bind $MFSlbd { set Selection [ $MFSlbd index @%x,%y ] set TheFile [ $MFSlbd get $Selection ] if { $TheFile != "" } { set MFSCurSelection [ \ file join $MFSLoadFilterPath $TheFile ]$ds } } } if { $allowdir != 2 } { bind $MFSlbf { set Selection [ $MFSlbf index @%x,%y ] set TheFile [ $MFSlbf get $Selection ] if { $TheFile != "" } { set MFSCurSelection [ \ file join $MFSLoadFilterPath $TheFile ] } } bind $MFSlbf { set Selection [ lindex [ $MFSlbf curselection ] 0 ] if { $Selection != "" } { set TheFile [ $MFSlbf get $Selection ] set MFSCurSelection [ \ file join $MFSLoadFilterPath $TheFile ] set MFSSelectFinish ok } } } if { $allowdir == 0 } { bind ._Selector._Selection.ent { set MFSCurSelection [ CompressSlashes $MFSCurSelection ] if { ! [ file exists $MFSCurSelection ] || \ ! [ file readable $MFSCurSelection ] || \ [ file isdirectory $MFSCurSelection ] } { tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\ does not exist, is not readable or is a\ directory" {} 0 OK } else { set MFSSelectFinish ok } } } elseif { $allowdir == 2 } { bind ._Selector._Selection.ent { set MFSCurSelection [ CompressSlashes $MFSCurSelection ] if { ! [ file exists $MFSCurSelection ] || \ ! [ file readable $MFSCurSelection ] || \ ! [ file isdirectory $MFSCurSelection ] } { tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\ does not exist, is not readable or is not a\ directory" {} 0 OK } else { set MFSSelectFinish ok } } } else { bind ._Selector._Selection.ent { set MFSCurSelection [ CompressSlashes $MFSCurSelection ] if { ! [ file exists $MFSCurSelection ] || \ ! [ file readable $MFSCurSelection ] } { tk_dialog ._Dialog { Invalid Choice } "$MFSCurSelection\ does not exist or is not readable" {} 0 OK } else { set MFSSelectFinish ok } } } } if { $allowdir != 2 } { MFSSelectShow 1 } else { MFSSelectShow 0 } set oldFocus [ focus ] tkwait visibility ._Selector grab set ._Selector focus ._Selector tkwait variable MFSSelectFinish set FileList {} if { $MFSSelectFinish == "cancel" } { set MFSLoadFilterPath $OldFilterPath set MFSLoadFilterPattern $OldFilterPattern } else { if { $multifile } { set count [ ._Selector._SelList._FileList._List size ] for { set index 0 } { $index < $count } { incr index } { lappend FileList \ [ ._Selector._SelList._FileList._List get $index ] } } else { set FileList $MFSCurSelection } } destroy ._Selector focus $oldFocus return $FileList } # # ---------------------------------------------------------------------- # set FrankPic " R0lGODdhcgCWAPUAADA0MDg4ODg8OEBAQEBEQEhISEhMSFBQUFBUUFhYWFhcWGBgYGBkYGhoaGhs aHBwcHB0cHh4eHh8eICAgICEgIiIiIiMiJCQkJCUkJiYmJicmKCgoKCkoKioqKisqLCwsLC0sLi4 uLi8uMDAwMDEwMjIyMjMyNDQ0NDU0NjY2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAcgCWAAAG/kCDsEAsGA5I4fBQ IBwPBkQCYtFkOBcOBGNZPCAQg7PgUFAqIg3Xs6VgKpoNVvJIIBSbTcPysHQ8ICIcHyMkIyAgGBEK CY0JCgoLkQwMDZYODw8OlZSSCggIUEqjT6NNBEYGjQwWXREZHxsZERcHDhIOYowFCg4ZWRASGhwW HBMVGRISFxkLDRMUbhcUGg/LE7AdsCGFIB4aEJCNUowKlJaXmJadkuNKSKJC8UNNjw6vGxAMHcMW DmUMHmhocMACBAEGAm7AEA5CBwt5KAhMhkGDggoQOVTE0GELBgwZOnDIAKLDBg8kRHjA4ECKI0jm KjX49w9dg06f7MgLNc9U/pEDD47F8WABmYUMDBQ0QMCggoIHGSxIaPDAFoUMZRwsrJBpCzMMDyoo qoBMg4ZpGypQmCAhg5WUHwZ9SNYOVKNJ5y7JvMnAkx14CEr5bCIkwoMIECZw8FCBWQYKzhwcgNAg AVcJGCZ8sQDWgoBbyh5QjfZ4wgQLFIpCuFAhArQLIA1G4GbCRIkQwy44aLCgEihGlIJfmrkOJiOe POEpByXm2QQwYj1o1bgAVwTmEhSshjBX8QMDjBxAiBClAGXE1sxq6ICRAVMJEeAUkx7BA7cQ+L1V A0VOyoL/eW3SV29+gYIEf8oxkQp4EVBwgAIQTfPFBhPwll0DAowHAWQh/nTwAQYUHNFAGM4Y8AAG DEBxgQLYZOBBPlRgkAAzclDQAT9HeTBCCSPExQEWKbp0ByQAykQgJ4zYwZ8USx6oHCsLJOBGBhMw MMFFFTCQgHsC0MKAPmp0gEguB/RlwAIIFFUVAAZMBQcG+UQQgQYW1CfSBmYRc9UGgYTwgQd/biBB lHcw+QiRfUXSW6LiOOLSXwkeYU0BC7g2QWBeeKElAgIwsIEDaJ62gAaAIkCAewUshQBrByBQQAS2 3LLaAhlgwEF0HGiDxQYdXLBeByIg8oE2IHTRVwKtPorofwC2Y8ddjSK43JcJEKfAAAUEEFgoChBA QDgJ/OfBAg5UwFYC/gOI8Qh4lhAgXlJV3sKAbhHcytkFI5iEgQR5dPCAjt/IMtIGFhCUrF2HMjtg JEkeatwjoRh4oBeMLBXFAAKgmQS2vxWQAQQIgNrIEQYMgCwqhEFgzQAPUsKia0VxpYCt34xKwQa0 xqJBY8xwhhUUByJczoDhNkzkfzCNg5w94TLgrRG6OSEEQkJ4K8GWCaDirQLZguLtACz3VYEkBBxQ 7ZwVSODqAlZV4MEFC9UaNwcSUHABfBVw4KAoBz7rF7NJDjlJOY4i2+ojvZlKgAAFWDDBEEIgMAAB ATQDXgECTI6KAIxjTADG4D2AAKzYInuRBAJI0NfiITtw1RUcqDGB/hp1SoVPBUkAbVeSkvSuJJEM N9wIEnddzcTkBQywYQOnSF4yUAcQwCnGqQQQAMaZcw5e1gxgWzYkEGBCQRgJBEBAuH1cwAwyba1F gQSmpcYQ0Ic7bFyj4TKLdMOh5B9BS8kzguSe4oAilAxzrSJZADiHrWwtkHOcKxsRSPY5J0DCdWAo mfW+VzcI0M5FWGkK/Bo0gQgkIAp2IYdxPMG7//Blf0o60AMY0AQBlI1z4WJCAJJXQSGkC2MLnNwA APBAzpmvANETQBK15rL/RGBxAgAA2LbnOoxsYC7XcYDt6hYBVdXPYQtj2JaCw452iKIXDRAD2Aag uE+skXKLM0AT/pBoxOtRrogCCKL3sBVBzGFLFQVw2hAjCLqAOMA+ILiAJRIQFsOw5QGf4M8jmlYJ FsJEf2FUEuK4tjjzScACA+AaxtYItuQhr45gsx4EIQi2VTLwaUTwlhqxZ0SwNQIbcGKke+Cnieew 7WB3KFKzWIi0/ZVDCYzwVh5f1UVXMTB7qADb5xa4wGm68pmZA+IrP1dKbAmRgdQUAgPGNyIEQOAA DZCAPlRGKIQljC/B8YTCkpI0JEZBDNwskwEs4MfsbTN71LRhHldJTVoONJukxB7LPofN690hIP8j TgIMU4kHoAmFdmHWTeC5P2F6goIGsKH0AtMqz3DzmQy9ZuYC/gpBVbYUjwycHAMN8MABFBF5lYFA lFzWAMPMREtH2B2i9sKbJB0NcFD4HA8l6IQESIAAAPCn5wZqU1ZWFY8ubakr9UhQPaYUeQlwQNaq xZsRFSkVyUJcX9ZBCUdAS4xQEKK34siEBDwuiKsEojafydI6bvWvrMwjLVsZUyTyBgqPoARlkrIA Oe7kLr0ZjnueZT9GMKGW2VwcUC6y1VSuVKug1SpWrRfQ0sIUnK00wFKY8FAGqEMKEwxawoiawkM1 QhJLxBwr2fSgRxC0kwcFrjazasSuqpK0xQUiHqvKuVSFomy3JRckT2jAoCJqoy2R5CZxa9PkFZFy IS1ZSPN6/tBs/pW45c0jcpGbXpg+0FsRQ4XZFmVRKBTBCMSbrSWACa3/cGqHpazgDs1nUICSt6/q BWwdj7ve9L5UsEiMMMeaRhUFyPG+j53ETSQpVEmElI3WG6VNRXza5Cq3vOgdLYNJW+LQlg0V+GzV ASQBqgs/TR5mUxQllqRCmBxAczcVbXsDmkoWq3TBCzZyklWKxwmego0DrFYdkmBA4ukYTUt6iTi+ Rl7jFve4AFXyNY2c4ge3mJVO5mEBBtgX0YkCw1E41I55/JL/yNGgBc4qNd3L3jGz98/tdbBKsZUE rUWPKRUmhWPjDIm+GEiSMEnK1JIr2iLueat9Vi+LLX3k/jF3Gpo21loBHjGTX86jb41OETCH1Jtr Ye7SX8YrcR+4aeMq+biDJahfryniWGotc9JrRARUDY8noNoZPEbYfw4gUFgPVM9YTbKKxZy9Agv5 yL0+BUPBlgSLQop+ySLSamV8OEWVzKbOnvWsNd1gdju4goG9tkoXV0o5cll7yALVcRJktvzteDku kYQpn23paa930wfPtDSL8Epa0prXQpzcEBj6Xig0IHDS6vei3KOc/nZLmQh2KcJHTnIihjibc4xl c3noacLasJVrTupX10gZt0pMhZFNTrgZxuW+/pnkQCczShHrKlQAIK5QdKXmGHiKNX8ieimFpr7H oSSh/kVGYmmd5BrB7O6gB724wJYjT8zEMgCcUKa6nmsfnRDMT4ghr+aLks0hrah/YF2o16L4ive8 aQCYfOQJfiV+mYTOyrBMAAoQRWeNsDgnQAFAN0FTE0hpvtvy763/2c1xtDvJkx404V6vtVTlqPHI FlVqTw/p9YxYtuixbBW7OYwmdhEK3bKMcOGy7XUvHkOhZY2wtA494LVK6GAOxxKaSNH56iJijJkN ChWbyRfkpKFgoOYBowTP/dQqHNc6y62TrKFphU9tYBshf9LPxBfEo3kCIK0R1JOjAB4Vvi8kpkHv i4AFYJOBX3DzfLvTOwLoWmz1fcDzdrVGfgqHRA+F/gn/YH/2Fz43YQ5FJUqq0C1HAgYNIgFpQxYY 0QpxIAf0ZjKXdFR9cQ4ywSjB40bS5nV/11d/ZAcZMCLrpzIqgxhg0BVT0RsHUgkGgAkaCD/ucwyt gAHMMBQeMErncz8KE1lrVRP0pD9Rgm4KiHB5JUDhghhaeBiuEQHKUEJBqAmaEHsqM33KoAyt0Apw ABsVcQUfAAIHsEDaV1kxYXpUQRMneIJoEkVVqGkHhTxmcxNfcBjBAD+GeIZe6IUlhINgEAxeyIHR QBanQRbSUBFy8Ach8ADL9B/5syx6eBPo8UIoSFN853Ux9UbyhQDO4Fo6KCfUF4QqAx8j5BpnaBrQ /mAutkgWaigWsJEnPxICnsE4KihP8FQJt5AJApIOGNKHr8RoRYIOD4iDrign8IEe01iN8AMNHGgu ahENdYMRZ5CGbpEHw/IB2iNPHTVMN/EcYLAbl2BR7BZ6q/Q950ATmDCGmTCNj2iL6nSGyoAY71M3 0LAWtqiN3RiJ6tMK4wgC2XImxGSClbQAi2gYmmCDDOCHL2WFhTVj6XeP6geEhjEe/niItqiPhyiL BcmPrrEWZRgMbHE3ZVNMTKgoACKLOCiGM9RJpphX8hUZ6geBP6mBj0h9rhg/WpiIjkiNawEfGjge XaQxKvQlF0AAkRB55SBGDCMJsliNIQkfcpRu/hr5SjMWENP3kfcojTa4CS5kCeRShqLxll0xHuwo Gj4VGEbQdAiQThWgCuxQgu1wlaahDEKZiJTwateTPBkJU6VDFfh4k+04iLxRF6BwlzOWWJX0jofx HJlwcT+mUItpDUdRJmRkSfijlWwRkIYYmIMiWG6XRNQGVjR4j434k6JhWfbGZW8kcRPUgPdAB7yH mAVlQ0wBmh0QVk2YNNECCQLJFvrolJoIAKo4OYHhbjw5Yw4ohjn4Dxc1R8oUb/4EQajgHwGhMu5R MoK1Q69mQ9VxAR1QjCqIey7xhRTgioLpig4wRHWQOegSlp4znP8QkuGjedtSP4FzBF8zSpm1/mar 8AVJkTUhZlM/KAY7NAUWwAag0iziwD92QZBswZXTGAbfIjkPkmBBVkqqWJHIqA5/s3GJZ56odESx dTiVAAZcc03kgixSMCIXAAKqQyAymTSOwo+GSI2JeDUGEAahpACYpXTpcqJAqDI1EZlHoxPAVVOC RTVPsCX/CQFnp1cJ8SxUAD8a8AEXcA5SKEZVhwBs0aH0yZXhcKRE0BdWtUaZZTaGhIyaUByRZmHT pEqaxQDnhjLW5QyWAqiAmEAI8AXIABu80gyjqT/isCQdGpi0iIhdFFauog8RNFeIOUUPco8PmKdW OUl31jmmFACu9XvpkqVnc4sRoDEHYg7j/mE34+gBtppqZOQymxcKBYmNiDgeMwQyk9EA3YU8phSD kbEbUWqV+4aYL1ZDvGCXTRA0iLYhHsg2gXEE4YIJHAgntiomSZGrwREtoRANlDqS1diIkCAazKY4 xwNL5uCANCFZnIijukN422I4gGEXIwINVQAZ49AqSjGrFZEr9iGuG1VUSnMAA6ma2eiPXigaI5IU NlR5YiAGSLQlxGET6wA4vXNUckd14GZlX3IMvjILa1VREKCLIMEr9lEkKRhPC7uUJEmQD1tCl/AJ /4cEjKetruWOykocZMQbA9IJkddOTWI2dzATDUIjYHEJj/iBVkCOIeCeCXsTMWQANluQ/hyaknl6 QrBkX471IMrojjNBExKLDnooT7j3F0yiFEGBEXByK4gBH2u6f4z6IyOgU0PLCfVqIB2ajfEDDWua jYYBQAKkQskRE8tKgNeJp6KRF1e7MG5VlfdwGgXLBZKYGnZzhGYhJtkhrjjxbZO6lQVZpO/zBS2K NSFjUXIXWbsRIPYoHm6JnThZhh1LTDORGI2RAXnwCxiBizzTsn8wNpgUmVHydEjQq194uoEJDeMh GVFQGQeghfpAJGaLXR2Zg4TYkoP4k4kygIz5jZ+rEWnIGpzxEerxDeagMHxxHPqKmv8IsV/4hSGJ KvzxPw64UQGyDqA6iE3piNmJp/CE/hfGaH2++7sXEDNFURHD8CMe0AFSGE8YBwqz2Kb0eZReaIN5 iiaZEBn8q4wJi7aY8IquyL0PqLbOAHm9mRpjqg1GqBZF0X9XYKuAkhedwChKMzrzW7e/6qGmEY0V YjYSm6fZqxfbO5tgcIYcPIa5677i4YXI8AEfoAYL7IFwEoI2bBNHgqbjgJQmqcECGQ3/kwklxDZP YUj/ILk/e4f/0Igt6aHoEaUDwsJUwbsV8SeUGA0K6RZxAAIb4MQ5/DDxOZFNSZSPGImOo37wgQnk crZsxQlq+4Ch2pKFO5RjuBvFFCDWkBpX9CEbcot4238/8imNS0/3gyXM2cRBaBpq/iEWrQGB99gX 2SscIByq4qF+cpmNa0F9kExM5PKA5DsI/iKfH/gRHJEBmayWdWxJewyGtKmIhJsai4wYUZp5HBsc YzS7ESiSS6mIjSwgOIo4ziB9wdAY5EgBJVw3RWiJ+eCR7uijLNQK3qhOlGx/QpgaCywBP7iZEusM omq2dvjGg6mIAekawCqgfGm0u7HEa2Erf7BOUowMIDESFPmWRvKxvYEavSwnyGjOxqwWD/A5XqAh Rhy7fKG97wiSIrmP9Skacke260AcX2Aa8REd6lzCpqE+V8AQurwJBag/qEEW6WrEXyCfZ6DOnwOd VHHRscsJUL2xQdmmzAkfyEgo/nYAwkNLu0FxDL9AGdbAzh/xECl6xJE5IM88m0E7fba4Fk5jRIGE j2prtFf7v4P5j5jcoH9BgTjxjOPLgXQQxdEAG3rjlspKxxu3f+aiTtmprK1Yt91SS0qBgmzJCVF6 zx95yE4JBhWoNJEAdeQAWek0UURdwmvBDB2gzvVnzim8xnugFmyRnSv9pFq4AEtNOYuSvETFsWYb lPegwTl4LETyF2qUOSgED5EQH0OYyDRSjWVNwpQspNYcpaLhkWWZPJ2ZrI0GT7ydDjipyyYN0+Xw fq4icXwzX1aiyKwxqcjQASVEBzf4kT9pGPqIHk58ttYNBm0VGEox11drE4dN/rvcC6wf/ZfxJAnJ EQokEy5UAYmU2KHy0wGymIP1973VV5Q4OK/pQJYATOHhQUZK0Rtm27iMqctAqXnmwNeMFTjUGi5y mdRFgZrobKnB0BVx2aZc+ZMorQ67u8sgYVEkPLQz7bjpZ7spOoFrmYJ/WcED27ycW5BVoAEDiddw XOVOSX02vpl7IYZtwQF54A/+KyAoKOSHTZtZ/kIbd7XGFAm/E8VeeAawPZC+IhWUGoHd/IpNLK/Z O0NzEgI4I0VOcJkb654yEXuPW+TuuFZzLdCT0GqMQC7U2NbV+Boa4D7fbIPVd+VKfNJA/YAWIALt iS1BlJcBQYGTK+QdCYR4/rrGMiGxlCCqRxJ5A5JO+EeQP1s3XGC3+afB0siFdGCWNTGvroUIkkM5 IxZWxFHOjxpPNhGUIky0d5jN8WSMZ2vj9cc2Z9JTbrCINjmUTJmDiKEZYji7HNsAF0ACGRBeA9UL FWXqApLmhT6793y2sBvJzB55h92gLiSiTHEPqTGN1qAh1OihS8y9mVzut4ABJKABkoM9/V3OVWmV PnqCN2GP6RC0toyOkJBAVfY7MtEIRbyy83nR1Se49Ssnsa3j5S59DqC5Sso5IQPtifVCWblxBFhR 9qgJkpAo2epY1aVzLhEJBUCI/WgN5kLhmm7Q77OUiZHym7nyIyJ98HMt/trCCRoLCqtITEUb7xb/ vlGCgOa3IPxmb7bwj+5jfYwdl1cemDSrTjYt2yld6DOEJjQ5ao+O9e6BaMdCzu4ruckOIJCyVNtW YFPkBY+0gRDelHjqzadJuP3IlKLKUekQJQhuDo+QVq2CW6rI85uEF/BuEy5zgsgSVBETDzn2JcHQ 0GdAuMyJHk6JjRxaN/M7n1Aa1PHkupKZbIGRe6rALM/ChM3shBcqfby3E/OlUeog38odDWS8wU65 iE3PoUO5+rXPURrlupCgc1QmCjl0/BEjOI3uibndxq0GblIwmu7e9F+oFoh41JZiKb0a23UetMir UfoDKaTAeKOG7ZuU/l8ziUlAwFAoFoxGgyFELA9NRCIxVESLjshkEpFQKhPJdwLRUrAVi6X7jayv kvUDfkQuhtXGIppYIg4GQ78gcMBg6C9Kgc/gSYpxKoFhYeHIQe4ITw+K72BxiMHhAeLBiwINwo1N YoJitaKCjOILQvZBbfbTwQGSToHhIXJqL7HAz6+AgEAxwaAgD/BAbwiKMTLJCClpN1p6T9oIbm31 IiI0NEu1lRQdS0LsU8wttIESOzLyISl6r4+YOLBgE8EwJnyGQTnEyKC1arqkGITihIonUBLMVNAS 4YEVWudInakQ60EEXKC0ZIxDD9u9O3g09QFUbJi/PwQKPBGWzKEU/mpJ5tSjk0maQSKSGoSMQOGC BFChlqbiwkWdUlAZxZiCg+sIPXuShjDxs28ZzGX+jP37A+ifNJ10ilzT9SuP0DpGcF0hdUHWLFls VD115YVpxjdwTMrzxKutgnvAEPBzPJYsgQECBmkai3OKFK26sDVEQORaA1luJlS4UMEIBFwj36my 8DTLuIwOZhHGSklSW0gOWG762qTJ40DFCFAeNrZ4skVRFiqs54gXJXmmvnxZhUGCu6mEW3ch48XN 6lCfZleyZCQ7L2DA2T+GGejY5AH+jh07gKibEUjWfHZKctWUp9LBQAzZriJPjNKggsVA2ii5Sp5K iugFBAvoWCKB/k3YC044mOobYACaPhzkGbUm5Ek/nlZzx5RzSruAgqrYIAyj6qzzYg1bVssowkly WSACD0qg4IAFbGLPMg7DOo4+ySajbEQCPqOiiAkXmMeTI7jLawszzoitQIwCI60077LQ8bYHkJDD CApCOOEDCDRBpCXg/uCHSciMcVK+EP0c4JkpqkwRtEmKms0dLNDA8ZQ38lojFSy8wFEWSlbESk01 HbBgBBNK4GACPb4KxiUl8XyvvmMEoAxEP2n6rA7z9CtqNTlo+8IVSFOpLsdQwOhiUtlUmwRCS+G4 YAQSSAjBAgmMbAwZgEptD61+mnRyVVYlEwCZQxYKTctPQrs1/otTUtGCUjjcUCPd8uShap6MMiBh hHo1+EiIDAsAUVoN7zzrTibh2xPbVkE8Zhid9lvzDjl4tIKNBLXY4txec4yFHR6RMOlANTEQAYQQ RgAhA3yfII4m4Ja4c0PH4IsvvmxbTXWTBOqBhJdZ5/DEilj2AkPS2CauRTXpkMBFtdoqEBkEEUbw AMYJeHOiiT1VDg4sPMkiGFtWQ0TYjynr2IUOhTzRIKlxxolUlUm/M6eWSw8NTJRkPxBhWQ0wIAOC BvSget/5NGnssawj29PggwcOu2abgLJ5WAww+KgpMrpcJejqACNsKgQFC6GED0JQVgQOYMToHkgS qTrElmpi/tzlrVPFlqaw/mACScUm6IAD0ZHa4AOpHIjUqVYkTcUieHLs/CpQOiABBA5EMMGEEULY II0Iesqwn8n+2TBrPa+NEplRM+HGATNK80AEEU5AIQUTNJhN1y0wRxeqYMPsezoIMCghBNKr3gic JgIL4EhN+OCePyZDAA3ZSWvvGV99auIExz2BAWRQQAO4EAEN4A0FJ/AAVsL0hUVhYRWwSAM88mIo N42AA6DrVAkAmIF0ZSUfaJHPWR7oniVNMGVPcAhzIDCBBSADD+m7AAc69QEAFQh5b+vLFiQFqXEY iwOh64AJ7qasEmxAFW54GBIMogljrEpwvmkMh4ZxAIFF/iZVimiEYr4QOAMsoFm0mcC9aMMlSE1K c+B5CtAkEKEKkOADQgoZCUpggg58ByRYMVIm/LWvAHBLje0RTky2JhOxFUEUEDCAZIzBAFkIQTQH cscVJja0Aq2DkJCQwN0+GIIQUI+LB7ScbLByB0pa5kkBSOO/whK+frjsD2STRHYOcIxREm4/40kC a0KiF2tSJ2J9Y4AGSuABEFjvBCagFwb6srwDWYIlrsuWAALQxqyZylpkMV9uiqK9BRjga02oj2Kw wpNDmWRH/+SOGBUAARB8oAPtO8EJbPmBj/CqHTzKhiOgNQx2rioAUiImBL/yQ8csYYOUKGQSAAEo BkBz/k2QONqDNMWaS9UKCUvrgMg8BTIQaABztdCUEX7BiJsUJ1vC9M1vwGIWTjrmPlEgT4zu0cxj ZMIAs9qPJCx1qXP6yGgd2EAHRlYvp3nAFWTI0S2whDPPEASfFw2AMBUBPnie6nY2gwQENGABD0RA D8YQhlR9gqJJWMMw1YiQAzagAa4SkF7Qy8CXztTLO7xFCl7hx5PYecnvtYSomjyOE9pCCzdwQE7L WFkBejIUtuRsmtO5KjYY0IEM4C0E7WMfCNBxLkSJSwg9xcMziOGS4lwSAOw0C8B4CJCWHBcBV5IH UiywAQc083YIuEM0xpZbf4pnPI8digdGV68QfHME/ntrBTsCUysjRDYYGaLJ934bVClRLbPGxR03 JBKBC0hOAwoQETIaQFFp+OREOyrPaRUAghKI4AMc4G4IOjBeWWABIzBdSDSa8Dd9RsuNAgDAWgFQ mWnZ6Rn6gEhmPOHBIlbgHoHTQ3qrpDBrkKco0x3KgQ/aNBF0YHJtQ2AcbjuHrvBhIH0AW4YrS6IH uoSHmMiQWnghDzcszEhFwtAinjOU1JJnHn0VgS2d9t0LXOA15C3Pith0iRU3hlQEi0ll1/o6Ue0D xM+oGRTK1oAI5KYA+OFFiIWYGdPWQx63GRsd2uc0EBxUb+VSDcfIeg1qnA/IK/6b7DAaAABUsFQ8 /hwchkykJgMIgDd5zXMfbCJEJv8XRbmtgwK2fGgDf2ByyoPDsMiqpp4qoETnOzPhKLittWb0asEW YjAW4YkCcMtZ+ronUeXSFVTf2s/tQ6wIwFyuGbljR+JCwhQCNcQyFnVPQc0ohpDEDYcA+QkNAJEC KpCBvm1QLIrgA6TLeIie5gFvJjhBCTJAAUdpp2+YGjAk5JyZnIgYOduqtAPPEukK61rSCKCMsxTz CAeIr42DM25O/AyFEiyU37DonIPk0RYfVYIBZwZIvS3sIcpW9ntHnvOK6QQFA1x6lIqoCQOQsafh UIvYBzl3OAOYBe0QxlYa6yc2KMHtlQ8Rs/B5/rll4Rtdgzw9AcnxeR/0S8HhwJU9eaDoEkoAgg5c oFxXueJExOQgbGybKPkqNSa6YidjgGidqxpue6Y8kAS005ltJMTX1itPfjwwCsPew8g4YBFhVfMi a/ACxCqVC3T+yL+cwHVRY5b3771n2BpKrgNbtY/kcm1gZLEgpynpBBqKoK5fUkOkZGOgv+6HP0PJ x8Ezffe8N1DenJxzifaFCHaG6B8LaFLqv756hJRaWSDwAAc2kIEMfLkLtVfTxvoZiVxMVVBVVksi XL7OBgbCjSzT0IoFUNCsr2pbCThcWZr/9B/DN3TV10D1Cyu5ReUFaVIHH5KLLYqgIUzrAMmP/jjw jjKgBP06ihj2gADWoJkaSDIYwI1Sr/CK64JwBzhMgGQm5y/CwQIwYLG4IAxoAxRyQcnoTAj8CwFt ZvPwhE8koz4yEE/QbF8EAC0I5gFsZ2vm4zdYL0PAp8Fs7Sf+SzRM4zUgDA4i4SF+gyh+AjhAI7cs A2Va5XAcqPmE6EnmQxBCJLRQBWEEzxAQwa0OwG9aj0M2YQGM4grCYDZIDA1BiqekwA86oR6QzEO8 jj4wTjQOQJhmxpkgQBn6sAw1jc/cSrI2q8IOoBdUEPIywkp+4VkeobTCxsrQkLj+sB/Kpx8OQAsc AKMOJkQMAAKW7RPpL+M6sE4yED6KQTnWbKCqjGIOKAEC8KEa6GSDDEMB0I8IeOFvVudOggjOHrAA TEkWCCC4hMlJULEBBK8sIGNUBsIDgaM+cu57dMee4g5ePqEacIEndAtLCIfKnkXjXqJm4CzwaAUC BPGSvMYA5AHOMK4a0e0aDyAIAAA7 " # # ---------------------------------------------------------------------- # catch { set COPYING "# GNU GENERAL PUBLIC LICENSE\n\ # Version 2, June 1991\n\ #\n\ # Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n\ # 675 Mass Ave, Cambridge, MA 02139, USA\n\ # Everyone is permitted to copy and distribute verbatim copies\n\ # of this license document, but changing it is not allowed.\n\ #\n\ # Preamble\n\ #\n\ # The licenses for most software are designed to take away your\n\ #freedom to share and change it. By contrast, the GNU General Public\n\ #License is intended to guarantee your freedom to share and change free\n\ #software--to make sure the software is free for all its users. This\n\ #General Public License applies to most of the Free Software\n\ #Foundation's software and to any other program whose authors commit to\n\ #using it. (Some other Free Software Foundation software is covered by\n\ #the GNU Library General Public License instead.) You can apply it to\n\ #your programs, too.\n\ #\n\ # When we speak of free software, we are referring to freedom, not\n\ #price. Our General Public Licenses are designed to make sure that you\n\ #have the freedom to distribute copies of free software (and charge for\n\ #this service if you wish), that you receive source code or can get it\n\ #if you want it, that you can change the software or use pieces of it\n\ #in new free programs; and that you know you can do these things.\n\ #\n\ # To protect your rights, we need to make restrictions that forbid\n\ #anyone to deny you these rights or to ask you to surrender the rights.\n\ #These restrictions translate to certain responsibilities for you if you\n\ #distribute copies of the software, or if you modify it.\n\ #\n\ # For example, if you distribute copies of such a program, whether\n\ #gratis or for a fee, you must give the recipients all the rights that\n\ #you have. You must make sure that they, too, receive or can get the\n\ #source code. And you must show them these terms so they know their\n\ #rights.\n\ #\n\ # We protect your rights with two steps: (1) copyright the software, and\n\ #(2) offer you this license which gives you legal permission to copy,\n\ #distribute and/or modify the software.\n\ #\n\ # Also, for each author's protection and ours, we want to make certain\n\ #that everyone understands that there is no warranty for this free\n\ #software. If the software is modified by someone else and passed on, we\n\ #want its recipients to know that what they have is not the original, so\n\ #that any problems introduced by others will not reflect on the original\n\ #authors' reputations.\n\ #\n\ # Finally, any free program is threatened constantly by software\n\ #patents. We wish to avoid the danger that redistributors of a free\n\ #program will individually obtain patent licenses, in effect making the\n\ #program proprietary. To prevent this, we have made it clear that any\n\ #patent must be licensed for everyone's free use or not licensed at all.\n\ #\n\ # The precise terms and conditions for copying, distribution and\n\ #modification follow.\n\ #\n\ # GNU GENERAL PUBLIC LICENSE\n\ # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\ #\n\ # 0. This License applies to any program or other work which contains\n\ #a notice placed by the copyright holder saying it may be distributed\n\ #under the terms of this General Public License. The \"Program\", below,\n\ #refers to any such program or work, and a \"work based on the Program\"\n\ #means either the Program or any derivative work under copyright law:\n\ #that is to say, a work containing the Program or a portion of it,\n\ #either verbatim or with modifications and/or translated into another\n\ #language. (Hereinafter, translation is included without limitation in\n\ #the term \"modification\".) Each licensee is addressed as \"you\".\n\ #\n\ #Activities other than copying, distribution and modification are not\n\ #covered by this License; they are outside its scope. The act of\n\ #running the Program is not restricted, and the output from the Program\n\ #is covered only if its contents constitute a work based on the\n\ #Program (independent of having been made by running the Program).\n\ #Whether that is true depends on what the Program does.\n\ #\n\ # 1. You may copy and distribute verbatim copies of the Program's\n\ #source code as you receive it, in any medium, provided that you\n\ #conspicuously and appropriately publish on each copy an appropriate\n\ #copyright notice and disclaimer of warranty; keep intact all the\n\ #notices that refer to this License and to the absence of any warranty;\n\ #and give any other recipients of the Program a copy of this License\n\ #along with the Program.\n\ #\n\ #You may charge a fee for the physical act of transferring a copy, and\n\ #you may at your option offer warranty protection in exchange for a fee.\n\ #\n\ # 2. You may modify your copy or copies of the Program or any portion\n\ #of it, thus forming a work based on the Program, and copy and\n\ #distribute such modifications or work under the terms of Section 1\n\ #above, provided that you also meet all of these conditions:\n\ #\n\ # a) You must cause the modified files to carry prominent notices\n\ # stating that you changed the files and the date of any change.\n\ #\n\ # b) You must cause any work that you distribute or publish, that in\n\ # whole or in part contains or is derived from the Program or any\n\ # part thereof, to be licensed as a whole at no charge to all third\n\ # parties under the terms of this License.\n\ #\n\ # c) If the modified program normally reads commands interactively\n\ # when run, you must cause it, when started running for such\n\ # interactive use in the most ordinary way, to print or display an\n\ # announcement including an appropriate copyright notice and a\n\ # notice that there is no warranty (or else, saying that you provide\n\ # a warranty) and that users may redistribute the program under\n\ # these conditions, and telling the user how to view a copy of this\n\ # License. (Exception: if the Program itself is interactive but\n\ # does not normally print such an announcement, your work based on\n\ # the Program is not required to print an announcement.)\n\ #\n\ #These requirements apply to the modified work as a whole. If\n\ #identifiable sections of that work are not derived from the Program,\n\ #and can be reasonably considered independent and separate works in\n\ #themselves, then this License, and its terms, do not apply to those\n\ #sections when you distribute them as separate works. But when you\n\ #distribute the same sections as part of a whole which is a work based\n\ #on the Program, the distribution of the whole must be on the terms of\n\ #this License, whose permissions for other licensees extend to the\n\ #entire whole, and thus to each and every part regardless of who wrote it.\n\ #\n\ #Thus, it is not the intent of this section to claim rights or contest\n\ #your rights to work written entirely by you; rather, the intent is to\n\ #exercise the right to control the distribution of derivative or\n\ #collective works based on the Program.\n\ #\n\ #In addition, mere aggregation of another work not based on the Program\n\ #with the Program (or with a work based on the Program) on a volume of\n\ #a storage or distribution medium does not bring the other work under\n\ #the scope of this License.\n\ #\n\ # 3. You may copy and distribute the Program (or a work based on it,\n\ #under Section 2) in object code or executable form under the terms of\n\ #Sections 1 and 2 above provided that you also do one of the following:\n\ #\n\ # a) Accompany it with the complete corresponding machine-readable\n\ # source code, which must be distributed under the terms of Sections\n\ # 1 and 2 above on a medium customarily used for software interchange; or,\n\ #\n\ # b) Accompany it with a written offer, valid for at least three\n\ # years, to give any third party, for a charge no more than your\n\ # cost of physically performing source distribution, a complete\n\ # machine-readable copy of the corresponding source code, to be\n\ # distributed under the terms of Sections 1 and 2 above on a medium\n\ # customarily used for software interchange; or,\n\ #\n\ # c) Accompany it with the information you received as to the offer\n\ # to distribute corresponding source code. (This alternative is\n\ # allowed only for noncommercial distribution and only if you\n\ # received the program in object code or executable form with such\n\ # an offer, in accord with Subsection b above.)\n\ #\n\ #The source code for a work means the preferred form of the work for\n\ #making modifications to it. For an executable work, complete source\n\ #code means all the source code for all modules it contains, plus any\n\ #associated interface definition files, plus the scripts used to\n\ #control compilation and installation of the executable. However, as a\n\ #special exception, the source code distributed need not include\n\ #anything that is normally distributed (in either source or binary\n\ #form) with the major components (compiler, kernel, and so on) of the\n\ #operating system on which the executable runs, unless that component\n\ #itself accompanies the executable.\n\ #\n\ #If distribution of executable or object code is made by offering\n\ #access to copy from a designated place, then offering equivalent\n\ #access to copy the source code from the same place counts as\n\ #distribution of the source code, even though third parties are not\n\ #compelled to copy the source along with the object code.\n\ #\n\ # 4. You may not copy, modify, sublicense, or distribute the Program\n\ #except as expressly provided under this License. Any attempt\n\ #otherwise to copy, modify, sublicense or distribute the Program is\n\ #void, and will automatically terminate your rights under this License.\n\ #However, parties who have received copies, or rights, from you under\n\ #this License will not have their licenses terminated so long as such\n\ #parties remain in full compliance.\n\ #\n\ # 5. You are not required to accept this License, since you have not\n\ #signed it. However, nothing else grants you permission to modify or\n\ #distribute the Program or its derivative works. These actions are\n\ #prohibited by law if you do not accept this License. Therefore, by\n\ #modifying or distributing the Program (or any work based on the\n\ #Program), you indicate your acceptance of this License to do so, and\n\ #all its terms and conditions for copying, distributing or modifying\n\ #the Program or works based on it.\n\ #\n\ # 6. Each time you redistribute the Program (or any work based on the\n\ #Program), the recipient automatically receives a license from the\n\ #original licensor to copy, distribute or modify the Program subject to\n\ #these terms and conditions. You may not impose any further\n\ #restrictions on the recipients' exercise of the rights granted herein.\n\ #You are not responsible for enforcing compliance by third parties to\n\ #this License.\n\ #\n\ # 7. If, as a consequence of a court judgment or allegation of patent\n\ #infringement or for any other reason (not limited to patent issues),\n\ #conditions are imposed on you (whether by court order, agreement or\n\ #otherwise) that contradict the conditions of this License, they do not\n\ #excuse you from the conditions of this License. If you cannot\n\ #distribute so as to satisfy simultaneously your obligations under this\n\ #License and any other pertinent obligations, then as a consequence you\n\ #may not distribute the Program at all. For example, if a patent\n\ #license would not permit royalty-free redistribution of the Program by\n\ #all those who receive copies directly or indirectly through you, then\n\ #the only way you could satisfy both it and this License would be to\n\ #refrain entirely from distribution of the Program.\n\ #\n\ #If any portion of this section is held invalid or unenforceable under\n\ #any particular circumstance, the balance of the section is intended to\n\ #apply and the section as a whole is intended to apply in other\n\ #circumstances.\n\ #\n\ #It is not the purpose of this section to induce you to infringe any\n\ #patents or other property right claims or to contest validity of any\n\ #such claims; this section has the sole purpose of protecting the\n\ #integrity of the free software distribution system, which is\n\ #implemented by public license practices. Many people have made\n\ #generous contributions to the wide range of software distributed\n\ #through that system in reliance on consistent application of that\n\ #system; it is up to the author/donor to decide if he or she is willing\n\ #to distribute software through any other system and a licensee cannot\n\ #impose that choice.\n\ #\n\ #This section is intended to make thoroughly clear what is believed to\n\ #be a consequence of the rest of this License.\n\ #\n\ # 8. If the distribution and/or use of the Program is restricted in\n\ #certain countries either by patents or by copyrighted interfaces, the\n\ #original copyright holder who places the Program under this License\n\ #may add an explicit geographical distribution limitation excluding\n\ #those countries, so that distribution is permitted only in or among\n\ #countries not thus excluded. In such case, this License incorporates\n\ #the limitation as if written in the body of this License.\n\ #\n\ # 9. The Free Software Foundation may publish revised and/or new versions\n\ #of the General Public License from time to time. Such new versions will\n\ #be similar in spirit to the present version, but may differ in detail to\n\ #address new problems or concerns.\n\ #\n\ #Each version is given a distinguishing version number. If the Program\n\ #specifies a version number of this License which applies to it and \"any\n\ #later version\", you have the option of following the terms and conditions\n\ #either of that version or of any later version published by the Free\n\ #Software Foundation. If the Program does not specify a version number of\n\ #this License, you may choose any version ever published by the Free Software\n\ #Foundation.\n\ #\n\ # 10. If you wish to incorporate parts of the Program into other free\n\ #programs whose distribution conditions are different, write to the author\n\ #to ask for permission. For software which is copyrighted by the Free\n\ #Software Foundation, write to the Free Software Foundation; we sometimes\n\ #make exceptions for this. Our decision will be guided by the two goals\n\ #of preserving the free status of all derivatives of our free software and\n\ #of promoting the sharing and reuse of software generally.\n\ #\n\ # NO WARRANTY\n\ #\n\ # 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n\ #FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n\ #OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n\ #PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n\ #OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n\ #MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n\ #TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n\ #PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n\ #REPAIR OR CORRECTION.\n\ #\n\ # 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n\ #WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n\ #REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n\ #INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n\ #OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n\ #TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n\ #YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n\ #PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n\ #POSSIBILITY OF SUCH DAMAGES.\n\ #\n\ # END OF TERMS AND CONDITIONS\n\ #\n\ # Appendix: How to Apply These Terms to Your New Programs\n\ #\n\ # If you develop a new program, and you want it to be of the greatest\n\ #possible use to the public, the best way to achieve this is to make it\n\ #free software which everyone can redistribute and change under these terms.\n\ #\n\ # To do so, attach the following notices to the program. It is safest\n\ #to attach them to the start of each source file to most effectively\n\ #convey the exclusion of warranty; and each file should have at least\n\ #the \"copyright\" line and a pointer to where the full notice is found.\n\ #\n\ # \n\ # Copyright (C) 19yy \n\ #\n\ # This program is free software; you can redistribute it and/or modify\n\ # it under the terms of the GNU General Public License as published by\n\ # the Free Software Foundation; either version 2 of the License, or\n\ # (at your option) any later version.\n\ #\n\ # This program is distributed in the hope that it will be useful,\n\ # but WITHOUT ANY WARRANTY; without even the implied warranty of\n\ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\ # GNU General Public License for more details.\n\ #\n\ # You should have received a copy of the GNU General Public License\n\ # along with this program; if not, write to the Free Software\n\ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\ #\n\ #Also add information on how to contact you by electronic and paper mail.\n\ #\n\ #If the program is interactive, make it output a short notice like this\n\ #when it starts in an interactive mode:\n\ #\n\ # Gnomovision version 69, Copyright (C) 19yy name of author\n\ # Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n\ # This is free software, and you are welcome to redistribute it\n\ # under certain conditions; type `show c' for details.\n\ #\n\ #The hypothetical commands `show w' and `show c' should show the appropriate\n\ #parts of the General Public License. Of course, the commands you use may\n\ #be called something other than `show w' and `show c'; they could even be\n\ #mouse-clicks or menu items--whatever suits your program.\n\ #\n\ #You should also get your employer (if you work as a programmer) or your\n\ #school, if any, to sign a \"copyright disclaimer\" for the program, if\n\ #necessary. Here is a sample; alter the names:\n\ #\n\ # Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n\ # `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\ #\n\ # , 1 April 1989\n\ # Ty Coon, President of Vice\n\ #\n\ #This General Public License does not permit incorporating your program into\n\ #proprietary programs. If your program is a subroutine library, you may\n\ #consider it more useful to permit linking proprietary applications with the\n\ #library. If this is what you want to do, use the GNU Library General\n\ #Public License instead of this License.\n\ #\n\ #" } # # ---------------------------------------------------------------------- # # # set a trace on OptionDesperate, because the FileList might change # with desperateness # proc VarTrace { name element op } { ShowFileList } trace variable OptionDesperate w VarTrace # # Set Window title # wm minsize . 300 250 wm title . "UUDeview for X" # # Set Message Callback # uu_SetMessageProc DisplayMessage # # Set Busy Callback: update every 100 msecs # uu_SetBusyProc WeAreBusy 100 # # Handle Command line arguments # set FilesToLoad {} set setpath 0 foreach arg $argv { if { $setpath } { set setpath 0 set SaveFilePath $arg } if { [ string index $arg 0 ] == "-" } { switch [ string index $arg 1 ] { f { set OptionFast 1 } b { set OptionBracket 1 } o { set OptionOverwrite 1 } d { set OptionDesperate 1 } v { set OptionVerbose 0 } p { set setpath 1 } s { set OptionDumbness 1 } t { set OptionUsetext 1 } z { set OptionMoreMime 1 } c { set OptionRemove 1 } default { tk_dialog ._Dialog { Invalid Switch } "Invalid switch\ found on command line: $arg" warning 0 OK } } } else { lappend FilesToLoad $arg } } if { $FilesToLoad != {} } { LoadFiles $FilesToLoad ShowFileList if { $OptionVerbose } { DumpFileList } } # # Initialize Listbox # ShowFileList # # go into event loop # vwait forever uudeview-0.5.20.orig/unix/0000755001167100001440000000000010020741142015300 5ustar cphusers00000000000000uudeview-0.5.20.orig/unix/Makefile.in0000644001167100001440000000600007306733322017357 0ustar cphusers00000000000000# # # ============================================================================ # # This is the Makefile for the uudeview package, including the uudeview # decoding, the uuenview encoding program, and a mini-inews that can be # used by uuencode to post directly to the usenet. # The values here were guessed by ./configure and are probably correct. # # Usefull targets # all Compile the package # install Install the binaries and manual pages # clean Deletes the binaries and objects and all the # other dirty stuff. # tar Packages everything neatly into a tar.gz file # for distribution. # # ============================================================================ # # $Id: Makefile.in,v 1.2 2001/06/04 16:26:58 fp Exp $ # # your make might need this # SHELL = /bin/sh # # Source and Installation Paths # prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ VPATH = @srcdir@ # # Where you want the binaries and the manual pages installed # BINDIR = @bindir@ MANDIR = @mandir@ # # install program. use our own, as AC_PROG_INSTALL doesn't work reliably # INSTALL = @srcdir@/install-sh INSTALL_PROGRAM = ${INSTALL} -c INSTALL_DATA = ${INSTALL} -c -m 644 # # If you don't have the GNU C compiler installed, set CC=cc here # CC = @CC@ # # C Compiler Options # CFLAGS = @CFLAGS@ -I@srcdir@ @CPPFLAGS@ @DEFS@ # # Libraries to link and their paths # LIBS = @LDFLAGS@ @LIBS@ # # the ranlib program # RANLIB = @RANLIB@ # # shared library stuff, if available. not yet active. i first need to # find someone who can really explain this to me. # SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ SHLIB_VERSION = @SHLIB_VERSION@ # ############################################################################### # You shouldn't have to change anything below. ############################################################################### # # Programs to compile, Manpages to install and Versions # VERSION = @VERSION@ PATCH = @PATCH@ VDEF = -DVERSION=\"$(VERSION)\" -DPATCH=\"$(PATCH)\" # @SET_MAKE@ # UUDEVIEW_SOURCE = uudeview.c uufnflt.c UUENVIEW_SOURCE = uuenview.c uufnflt.c UUDEVIEW_OBJ = ${UUDEVIEW_SOURCE:.c=.o} UUENVIEW_OBJ = ${UUENVIEW_SOURCE:.c=.o} # # make stuff # .SUFFIXES: .SUFFIXES: .c .o all: uudeview uuenview clean: rm -f uudeview uuenview rm -f *.o *.a *.so core *~ TAGS distclean: clean rm -f config.status config.cache config.log Makefile config.h rm -f uudeview-*tar* uudeview-sfx realclean: distclean install: all for d in $(PROGS) ; do \ $(INSTALL_PROGRAM) $(srcdir)/$$d $(BINDIR)/$$d ; \ done -for d in $(MPAGES) ; do \ $(INSTALL_DATA) $(srcdir)/$$d $(MANDIR)/man1/$$d ; \ done new: clean rm -f uudeview uuenview make all uudeview: $(UUDEVIEW_OBJ) ../uulib/libuu.a $(CC) -o $@ $(UUDEVIEW_OBJ) -L../uulib -luu $(LIBS) uuenview: $(UUENVIEW_OBJ) ../uulib/libuu.a $(CC) -o $@ $(UUENVIEW_OBJ) -L../uulib -luu $(LIBS) .c.o: $(CC) -c $(CFLAGS) -I../uulib $(VDEF) $< uudeview.o: uudeview.c config.h uuenview.o: uuenview.c config.h uufnflt.o: uufnflt.c uufnflt.h config.h uudeview-0.5.20.orig/unix/uudeview.c0000644001167100001440000011030707646121143017320 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif #include #include #include #include #include #ifdef HAVE_FCNTL_H #include #endif #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_MEMORY_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #include #include #include /* For the sake of getcwd() in DOS */ #ifdef HAVE_DIRECT_H #include #endif /* * the progress meter is only displayed if stderr is a terminal. * take care of systems where we can't check this condition. */ #ifdef HAVE_ISATTY #define UUISATTY(f) (isatty(fileno(f))) #else #define UUISATTY(f) (1) #endif #define SHOW_INFO (1) /* For more () */ #define SHOW_FILE (2) /* * local definitions */ typedef struct _extlist { char extension[8]; struct _extlist *NEXT; } extlist; /* * Operational Flags */ static int incext = 0, stdinput = 0; static int overwrite = 0, interact = 1; static int quiet = 0, decoall = 0; static int nobar = 0, autoren = 0; /* * Global Variables */ static extlist *extensions = NULL; static char savepath[512]; /* * some statistics */ static int decodedok = 0; static int decodedfailed = 0; static int decodedmisp = 0; static int inputerrors = 0; static int inputfiles = 0; /* * version string */ static char uuversion[256] = VERSION "pl" PATCH; /* * cvs version */ char * uudeview_id = "$Id: uudeview.c,v 1.28 2003/04/12 23:33:55 fp Exp $"; static int addexts _ANSI_ARGS_((char *)); static int work_file _ANSI_ARGS_((char *)); static int proc_stdin _ANSI_ARGS_((void)); static void loadparfile _ANSI_ARGS_((char *)); static int work_comline _ANSI_ARGS_((int, char *[])); static int moreCB _ANSI_ARGS_((void *, char *)); static void more _ANSI_ARGS_((uulist *, int)); static void DumpFileList _ANSI_ARGS_((void)); static int process_one _ANSI_ARGS_((uulist *)); static int process_files _ANSI_ARGS_((void)); static void sighandler _ANSI_ARGS_((int)); static void usage _ANSI_ARGS_((char *)); /* * Header lines starting with these texts will be stripped when * printing a file's info */ static char *hateheaders[] = { "Path:", "Newsgroups:", /*"Organization:",*/ "Lines:", "Message-ID:", "NNTP-Posting-Host:", "Xref:", "References:", "X-Newsreader:", "Distribution", /*"Sender:",*/ "Nntp-Posting-Host:", /*"Reply-To:",*/ /*"Approved:",*/ "Mime-Version:", "Content-Type:", "Content-Transfer-Encoding:", "X-Posting-Software:", NULL }; /* * Busy Callback */ static int BusyCallback (void *param, uuprogress *progress) { char stuff[26]; int count, pcts; char *ptr; /* * Display progress meter only if stderr is a terminal */ if (!UUISATTY(stderr) || nobar) return 0; if ((ptr = _FP_strrchr (progress->curfile, DIRSEPARATOR[0])) == NULL) ptr = progress->curfile; else ptr++; if (!quiet && progress->action == 1) { fprintf (stderr, "scanned %3d%% of %-50s\r", progress->percent, ptr); fflush (stderr); } else if (!quiet && progress->action == 2) { pcts = (int)((100*progress->partno+progress->percent-100) / progress->numparts); for (count=0, stuff[25]='\0'; count<25; count++) stuff[count] = (countpartno, progress->numparts, stuff); fflush (stderr); } else if (!quiet && progress->action == 3) { for (count=0, stuff[25]='\0'; count<25; count++) stuff[count] = (countpercent/4)?'#':'.'; fprintf (stderr, "copying target file %s\r", stuff); fflush (stderr); } return 0; } /* * Message Callback */ static void MessageCallback (void *param, char *message, int level) { if (!quiet || level >= UUMSG_WARNING) fprintf (stderr, "%s\n", message); } /* * local functions */ static void killext (extlist *data) { extlist *iter=data, *ptr; while (iter) { ptr = iter->NEXT; _FP_free (iter); iter = ptr; } } static char * filemode (int mode) { static char result[11]; static char rwxkey[8][4] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx" }; result[0] = '-'; result[1] = rwxkey[((mode >> 6) & 0x07)][0]; result[2] = rwxkey[((mode >> 6) & 0x07)][1]; result[3] = rwxkey[((mode >> 6) & 0x07)][2]; result[4] = rwxkey[((mode >> 3) & 0x07)][0]; result[5] = rwxkey[((mode >> 3) & 0x07)][1]; result[6] = rwxkey[((mode >> 3) & 0x07)][2]; result[7] = rwxkey[ mode & 0x07 ][0]; result[8] = rwxkey[ mode & 0x07 ][1]; result[9] = rwxkey[ mode & 0x07 ][2]; result[10]= '\0'; return result; } /* * check if we want the header displayed */ static int IsHeaderLine (char *text) { char **hiter = hateheaders; if (text == NULL || hiter == NULL) return 0; while (*hiter) { if (_FP_strnicmp (text, *hiter, strlen (*hiter)) == 0) return 1; hiter++; } return 0; } /* * get a character from stdin (the keyboard), or accept default */ static char getyn (char *theline, char def) { char line[256], *ptr=0; int isdebug; if (interact && !feof (stdin)) { fflush (stdout); if ((ptr = _FP_fgets ((theline)?theline:line, 255, stdin)) == NULL) { if (theline) *theline='\0'; return def; } if (ptr[0]=='4'&&ptr[1]=='2') { UUGetOption (UUOPT_DEBUG, &isdebug, NULL, 0); UUSetOption (UUOPT_DEBUG, !isdebug, NULL); if (!isdebug) printf ("*** Debugging Mode On\n"); else printf ("*** Debugging Mode Off\n"); ptr+=2; } while (isspace (*ptr) && *ptr!='\n') ptr++; if (*ptr == '\n') { if (theline) *theline='\0'; return def; } } else { if (theline) *theline='\0'; printf ("%c\n", def); return def; } return tolower(*ptr); } /* * check whether a file exists or not. This check is used when we decide * if a file would be overwritten. We also overwrite files with zero * length. */ static int exists (char *filename) { struct stat finfo; if (filename == NULL || *filename == '\0') return 0; if (stat (filename, &finfo) != 0) return 0; if ((long) finfo.st_size == 0) return 0; return 1; } /* * Find a new unique filename by adding a unique number to the file name. * Some want the unique name at the end, while others prefer to keep it * before the file extension. Support both. * So if autoren is positive, append the unique number at the end. If it * is negative, insert it before the first dot in the filename. */ int findAlternateName (char *originalName, char *newName, int autoren) { char *p; int i; for (i=1; i<32768; i++) { if (autoren > 0) { sprintf (newName, "%s.%d", originalName, i); } else { strcpy (newName, originalName); if ((p = strchr (newName, '.')) != NULL) { sprintf (p, "_%d%s", i, strchr (originalName, '.')); } else { sprintf (newName, "%s_%d", originalName, i); } } if (!exists (newName)) { return 1; } } return 0; } /* * Add another extension we shall or shall not decode */ static int addexts (char *elist) { extlist *enew; int iter; while (*elist) { if (*elist != '.') { elist++; continue; } if (*++elist == '\0') break; if ((enew = (extlist *) malloc (sizeof (extlist))) == NULL) { fprintf (stderr, "ERROR: Out of memory in addexts()\n"); return 0; } iter = 0; while (*elist != '.' && *elist != '\0' && iter < 7) enew->extension[iter++] = *elist++; enew->extension[iter] = '\0'; enew->NEXT = extensions; extensions = enew; } return 1; } /* * looks at the extension of a file and decides whether we want to decode * it or not, based on our extensions list */ static int work_file (char *filename) { extlist *iter = extensions; char *ptr; if (filename == NULL) return 0; if ((ptr = _FP_strrchr (filename, '.')) == NULL) return incext ? 0 : 1; ptr++; while (iter) { if (_FP_stricmp (ptr, iter->extension) == 0) return incext ? 1 : 0; iter = iter->NEXT; } return incext ? 0 : 1; } /* * Handle standard input. Dump it into a temporary file and then add * this temp file to our list of command-line files */ static int proc_stdin (void) { static char buffer[1024]; char *stdfile; FILE *target; size_t bytes; int res; if (stdinput) { fprintf (stderr, "proc_stdin: cannot process stdin twice\n"); return 0; } if ((stdfile = tempnam (NULL, "uu")) == NULL) { fprintf (stderr, "proc_stdin: cannot get temporary file\n"); return 0; } if ((target = fopen (stdfile, "wb")) == NULL) { fprintf (stderr, "proc_stdin: cannot open temp file %s for writing: %s\n", stdfile, strerror (errno)); _FP_free (stdfile); return 0; } while (!feof (stdin)) { bytes = fread (buffer, 1, 1024, stdin); if (bytes == 0) break; if (ferror (stdin)) { fprintf (stderr, "proc_stdin: error reading from stdin: %s\n", strerror (errno)); break; } if (fwrite (buffer, 1, bytes, target) != bytes) { fprintf (stderr, "proc_stdin: cannot write to temp file %s: %s\n", stdfile, strerror (errno)); break; } if (ferror (target)) { fprintf (stderr, "proc_stdin: error writing to temp file %s: %s\n", stdfile, strerror (errno)); break; } } if (ferror (stdin) || ferror (target)) { fclose (target); unlink (stdfile); _FP_free (stdfile); return 0; } fclose (target); inputfiles++; if ((res = UULoadFile (stdfile, NULL, 1)) != UURET_OK) { fprintf (stderr, "ERROR: while reading from copied standard input %s: %s %s\n", stdfile, UUstrerror (res), (res==UURET_IOERR)? strerror (UUGetOption (UUOPT_ERRNO, NULL, NULL, 0)) : ""); inputerrors = 1; } _FP_free (stdfile); stdinput = 1; return 1; } /* * extract parameters from "command line" */ static void makeparams (char *comline) { char *p1, *argv[32]; int argc=2, quote=0; if (comline==NULL || *comline=='\0') return; p1 = comline; while (*p1 == ' ' || *p1 == '\t') { p1++; } argv[1] = p1; while (*p1 && argc < 31) { switch (*p1) { case ' ': case '\t': if (!quote) { if ((*argv[argc-1] == '"' || *argv[argc-1] == '\'') && p1-1 != argv[argc-1] && *(p1-1) == *argv[argc-1]) { *(p1-1) = '\0'; argv[argc-1] += 1; } *p1++ = '\0'; while (*p1 == ' ' || *p1 == '\t') p1++; argv[argc++] = p1; } else { p1++; } break; case '"': case '\'': if (!quote) { quote = *p1++; } else if (quote == *p1++) { quote = 0; } break; default: p1++; } } if (!quote) { if ((*argv[argc-1] == '"' || *argv[argc-1] == '\'') && p1-1 != argv[argc-1] && *(p1-1) == *argv[argc-1]) { *(p1-1) = '\0'; argv[argc-1] += 1; } } work_comline (argc, argv); } /* * Load a file with command-line parameters (given with @) */ static void loadparfile (char *filename) { char line[256], c; FILE *pfile; if ((pfile = fopen (filename+1, "r")) == NULL) { fprintf (stderr, "Couldn't load parameter file %s: %s (ignored)\n", filename+1, strerror (errno)); return; } while (!feof (pfile)) { if (_FP_fgets (line, 256, pfile) == NULL) break; if (ferror (pfile)) break; line[strlen(line)-1] = '\0'; if (strlen (line) == 0) continue; if (line[strlen(line)-1] == 0x0a || line[strlen(line)-1] == 0x0d) line[strlen(line)-1] = '\0'; if (line[0] == '\0' || line[0] == '#') continue; makeparams (line); c = fgetc (pfile); if (feof (pfile)) break; else ungetc (c, pfile); } fclose (pfile); /* * command line files are always removed */ unlink (filename+1); } /* * process command line parameters */ static int work_comline (int argc, char *argv[]) { int number, res; for (number=1; number= '0' && argv[number][2] <= '9') { UUSetOption (UUOPT_MOREMIME, argv[number][2]-'0', NULL); } else if (argv[number][2] == 'z') { UUSetOption (UUOPT_MOREMIME, 2, NULL); } else { res = UUGetOption (UUOPT_MOREMIME, NULL, NULL, 0); UUSetOption (UUOPT_MOREMIME, res+1, NULL); } break; default: usage (argv[0]); exit (99); break; } } return 1; } /* * list a file callback */ struct mCBparm { int aline, lines; int quitit, cols; }; static int moreCB (void *param, char *string) { struct mCBparm *data = (struct mCBparm *) param; if (IsHeaderLine (string)) return 0; if (data->aline+2 >= data->lines) { data->aline = 0; if (interact) { fprintf (stdout, "<>"); if (getyn (NULL, 'y') == 'q') { data->quitit = 1; return 1; } } } while (strlen(string) && (string[strlen(string)-1] == '\012' || string[strlen(string)-1] == '\015')) string[strlen(string)-1] = '\0'; if (data->cols > 0) string[data->cols-1] = '\0'; fprintf (stdout, "%s\n", string); data->aline += 1; return 0; } static void more (uulist *uin, int type) { struct mCBparm data; FILE *inpfile = NULL; char text[256], *p; int res; data.aline = 0; data.quitit = 0; if ((p = getenv ("LINES")) != NULL) { if ((data.lines = atoi(p)) < 5) data.lines = 24; } else data.lines = 24; if ((p = getenv ("COLUMNS")) != NULL) { if ((data.cols = atoi(p)) < 30) data.cols = 80; } else data.cols = 80; if (uin == NULL || uin->thisfile == NULL) { printf ("\tError -- (?)\n"); return; } if (type == SHOW_INFO) { UUInfoFile (uin, &data, moreCB); } else { if ((res = UUDecodeToTemp (uin)) != UURET_OK) { fprintf (stderr, "ERROR: while decoding %s (%s): %s\n", uin->filename, (uin->subfname) ? uin->subfname : "", UUstrerror(res)); return; } if (UUISATTY(stderr) && !nobar) { fprintf (stderr, "%70s\r", ""); /* clear progress information */ fflush (stderr); } if ((inpfile = fopen (uin->binfile, "r")) == NULL) { fprintf (stderr, "ERROR: could not open %s: %s\n", uin->binfile, strerror (errno)); return; } while (!feof (inpfile)) { if (_FP_fgets (text, data.cols, inpfile) == NULL) break; if (ferror (inpfile)) { fprintf (stderr, "ERROR: while reading from %s: %s\n", uin->binfile, strerror (errno)); break; } if (moreCB (&data, text)) break; } fclose (inpfile); } if (interact && data.aline+2 >= data.lines) { fprintf (stdout, "<>"); getyn (NULL, '?'); } else fprintf (stdout, "<>"); } static void DumpFileList (void) { int count, printed=0, index=0; uulist *iter; while ((iter=UUGetFileListItem(index))) { if (iter->state & UUFILE_NODATA) { index++; continue; } if (UUISATTY(stderr) && !nobar) { fprintf (stderr, "\r%70s\r", ""); fflush (stderr); } if (!printed++) printf ("\n"); printf ("Found '%s' State %d %s Parts ", (iter->filename) ? iter->filename : (iter->subfname) ? iter->subfname : "???", iter->state, (iter->uudet == UU_ENCODED) ? "UUdata" : (iter->uudet == B64ENCODED) ? "Base64" : (iter->uudet == XX_ENCODED) ? "XXdata" : (iter->uudet == BH_ENCODED) ? "Binhex" : (iter->uudet == YENC_ENCODED) ? "yEnc" : "Text"); if (iter->haveparts) { printf ("%s%d%s ", (iter->begin && iter->begin==iter->haveparts[0]) ? "begin " : "", iter->haveparts[0], (iter->end && iter->end == iter->haveparts[0]) ? " end" : ""); for (count=1; iter->haveparts[count]; count++) { printf ("%s%d%s ", (iter->begin==iter->haveparts[count]) ? "begin " : "", iter->haveparts[count], (iter->end == iter->haveparts[count]) ? " end" : ""); } } if (iter->state & UUFILE_OK) { printf ("OK"); } printf ("\n"); index++; } if (printed) printf ("\n"); } /* * Returning 1 skips to next file * -1 skips to prev file * 0 quits program */ static int process_one (uulist *iter) { char targetname[1024], renamedname[1024]; char line[1024], command[256], tmp, *ptr1, *ptr2; int res, escflag; char *name; while (42) { if ((name = UUFNameFilter (iter->filename)) == NULL) { fprintf (stderr, "ERROR: couldn't get filename of %s (%s)\n", (iter->filename)?iter->filename:"(null)", (iter->subfname)?iter->subfname:"(null)"); break; } if (interact && !decoall) { printf (" %s %-15s is %s [d] (?=help) ", filemode((int)iter->mode), (iter->filename) ? (iter->filename) : "", (iter->state&UUFILE_OK) ? "OK" : "in error (DESPERATE MODE)"); tmp = getyn (line, 'd'); } else { line[0] = '\0'; tmp = 'd'; } for (ptr1=line; *ptr1 && *ptr1 != tmp; ptr1++); if (*ptr1++==tmp) { while (isspace(*ptr1)) ptr1++; } if (tmp == 'n') return 1; if (tmp == 'b') { if (iter->PREV == NULL) printf ("*** Already at the beginning of the list\n"); else return -1; continue; } else if (tmp == 'a') { decoall = 1; continue; } else if (tmp == 'c') { printf ("\n\n-------------------------------------------------------------------------------\n\n"); printf ("\tYou are now using UUDEVIEW, the uudecoder by Frank Pilhofer\n\n"); printf ("\tThe program is distributed under the terms of the GNU\n"); printf ("\tGeneral Public License. You should have received a copy of\n"); printf ("\tthe GPL with the uudeview program. In particular this means\n"); printf ("\tthat the program is distributed without any warranty.\n\n"); printf ("\tIf you like uudeview, you are encouraged to send the author\n"); printf ("\ta postcard (find the address in the README file), or at\n"); printf ("\tleast an email.\n\n"); printf ("\tCheck out uudeview's home page:\n"); printf ("\t\thttp://www.fpx.de/fp/Software/UUDeview/\n\n"); printf ("\t Frank Pilhofer (fp@fpx.de)\n\n"); printf ("-------------------------------------------------------------------------------\n\n"); continue; } else if (tmp == 'q') { return 0; } else if (tmp == '?') { printf ("\n\tYou can ...\n"); printf ("\t - (d)ecode the file\n"); printf ("\t - (y)es - same as (d)\n"); printf ("\t - e(x)tract - same as (d)\n"); printf ("\t - decode (a)ll files\n"); printf ("\t - go to (n)ext file\n"); printf ("\t - show file (i)nfo\n"); /* * Can't execute anything in QuickWin */ #ifndef SYSTEM_QUICKWIN printf ("\t - (e)xecute a command\n"); #endif printf ("\t - (l)ist textfile\n"); printf ("\t - (r)ename file\n"); printf ("\t - decode (a)ll files\n"); printf ("\t - go (b)ack to the previous file\n"); printf ("\t - set decode (p)ath: %s\n", savepath); printf ("\t - (q)uit program\n"); printf ("\t - display (c)opyright\n\n"); continue; } else if (tmp == 'r') { if (strlen(ptr1) <= 1) { printf ("Enter new filename: "); fflush (stdout); if (_FP_fgets (line, 250, stdin) == NULL) { printf ("\nERROR: Could not get filename: %s\n", strerror (errno)); line[0] = '\0'; } ptr1 = line; } if (strlen (ptr1) > 1) { if (ptr1[strlen(ptr1)-1] == '\n') ptr1[strlen(ptr1)-1] = '\0'; UURenameFile (iter, ptr1); } continue; } else if (tmp == 'p') { if (strlen(ptr1) <= 1) { printf ("Enter new path: "); fflush (stdout); if (_FP_fgets (line, 250, stdin) == NULL) { printf ("\nERROR: Could not get path: %s\n", strerror (errno)); line[0] = '\0'; } ptr1 = line; } if (strlen (ptr1) > 1) { if (ptr1[strlen(ptr1)-1] == '\n') ptr1[strlen(ptr1)-1] = '\0'; /* check that path exists */ if (access(ptr1, W_OK|X_OK) == 0) { struct stat finfo; if (stat (ptr1, &finfo) != 0) { printf ("\nERROR: Could not get path: %s\n", strerror (errno)); break; } if (!S_ISDIR(finfo.st_mode)) { printf("\nERROR: `%s' is not a directory\n", ptr1); break; } } strcpy (savepath, ptr1); if (strlen (savepath)) { if (savepath[strlen(savepath)-1]!=DIRSEPARATOR[0]) strcat (savepath, DIRSEPARATOR); } } continue; } else if (tmp == 'i') { printf ("\nFile info ...\n\n"); printf ("-------------------------------------------------------------------------------\n"); more (iter, SHOW_INFO); printf ("\n-------------------------------------------------------------------------------\n\n"); continue; } /* * for the following menu items, we need the file decoded */ if ((res = UUDecodeToTemp (iter)) != UURET_OK) { fprintf (stderr, "ERROR: while decoding %s (%s): %s\n", (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", UUstrerror(res)); decodedfailed++; break; } if (!quiet && UUISATTY(stderr) && !nobar) { fprintf (stderr, "%70s\r", ""); /* clear progress information */ fflush (stderr); } if (iter->binfile == NULL) { fprintf (stderr, "ERROR: Ooops. Decoded %s but no binfile??\n", (iter->filename) ? iter->filename : ""); decodedfailed++; break; } if (tmp=='d' || tmp=='y' || tmp=='x' || tmp=='\0' || tmp=='\n') { /* * Set Target directory */ make_target: sprintf (targetname, "%s%s%s", savepath, (strlen(savepath) && savepath[strlen(savepath)-1]==DIRSEPARATOR[0]) ? "":DIRSEPARATOR, name); /* * check whether this file exists */ retryexcheck: if (exists (targetname) && overwrite!=1 && autoren && findAlternateName (targetname, renamedname, autoren)) { printf ("*** Target File %s exists - autorenamed to %s\n", targetname, renamedname); strcpy (targetname, renamedname); } if (exists (targetname) && overwrite == -1) { printf ("*** Target File %s exists! (file not decoded)\n", targetname); return 1; } if (exists (targetname) && !overwrite) { printf ("*** Target File %s exists! Options:\n", targetname); res = ' '; printf ("\ *** (O)verwrite, Overwrite (A)ll, Overwrite Non(e),\n\ *** (R)ename, Au(t)o-Rename, (N)ext, (P)ath [o] "); fflush (stdout); /* * Ask the user for her/his choice. If 'r' or 'p', and there * is more data on the line, use it as reply */ res = getyn (line, stdinput ? 'n' : 'o'); for (ptr1=line; *ptr1 && tolower(*ptr1) != res; ptr1++); if (*ptr1++==res) { while (isspace(*ptr1)) ptr1++; } switch (res) { case 'n': return 1; case 'a': overwrite=1; goto retryexcheck; case 'o': goto noexcheck; case 'e': overwrite=-1; return 1; case 't': autoren=1; goto retryexcheck; case 'r': if (strlen(ptr1) <= 1) { printf ("Enter new filename: "); fflush (stdout); if (_FP_fgets (line, 250, stdin) == NULL) { printf ("\nERROR: Could not get filename: %s\n", strerror (errno)); line[0] = '\0'; } ptr1 = line; } if (strlen (ptr1) > 1) { if (ptr1[strlen(ptr1)-1] == '\n') ptr1[strlen(ptr1)-1] = '\0'; UURenameFile (iter, ptr1); } if ((name = UUFNameFilter (iter->filename)) == NULL) { fprintf (stderr, "ERROR: couldn't get filename of %s (%s)\n", (iter->filename)?iter->filename:"(null)", (iter->subfname)?iter->subfname:"(null)"); return 1; } goto make_target; case 'p': if (strlen(ptr1) <= 1) { printf ("Enter new path: "); fflush (stdout); if (_FP_fgets (line, 250, stdin) == NULL) { printf ("\nERROR: Could not get path: %s\n", strerror (errno)); line[0] = '\0'; } ptr1 = line; } if (strlen (ptr1) > 1) { if (ptr1[strlen(ptr1)-1] == '\n') ptr1[strlen(ptr1)-1] = '\0'; strcpy (savepath, ptr1); if (strlen(savepath)) { if (savepath[strlen(savepath)-1]!=DIRSEPARATOR[0]) strcat (savepath, DIRSEPARATOR); } } goto make_target; default: goto retryexcheck; } } noexcheck: if ((res = UUDecodeFile (iter, targetname)) != UURET_OK) { if (UUISATTY(stderr) && !nobar) fprintf (stderr, "%70s\r", ""); /* clear progress information */ fprintf (stderr, "ERROR: while writing %s (%s): %s\n", targetname, (iter->subfname) ? iter->subfname : "", UUstrerror(res)); decodedfailed++; break; } if (!quiet) { if (UUISATTY(stderr) && !nobar) fprintf (stderr, "%70s\r", ""); /* clear progress information */ printf (" File successfully written to %s\n", targetname); } decodedok++; break; } else if (tmp == 'l') { printf ("\nContents of file ...\n\n"); printf ("------------------------------------------------------------------------------\n"); more (iter, SHOW_FILE); printf ("\n------------------------------------------------------------------------------\n\n"); } /* * Can't do that in QuickWin, since we'd need system() */ #ifndef SYSTEM_QUICKWIN else if (tmp == 'e') { printf ("Enter command line ($) for file: "); fflush (stdout); if (_FP_fgets (line, 256, stdin) == NULL) printf ("\nERROR: Could not get Command line: %s\n", strerror (errno)); else if (strlen (line) > 1) { ptr1 = line; ptr2 = command; escflag = 0; while (*ptr1 && *ptr1 != '\012' && *ptr1 != '\015') { if (!escflag && *ptr1 != '\\') { if (*ptr1 == '$') { strcpy (ptr2, iter->binfile); ptr2 += strlen (iter->binfile); ptr1++; } else *ptr2++ = *ptr1++; } else if (escflag) { *ptr2++ = *ptr1++; escflag = 0; } else escflag = 1; } *ptr2 = '\0'; printf ("------------------------------------------------------------------------------\n"); system (command); printf ("------------------------------------------------------------------------------\n\n"); } } #endif else { printf ("ERROR: unknown action '%c'. Enter ? for list of options.\n", tmp); } } return 1; } static int process_files (void) { int res, index=0, desp; uulist *iter; char *ptr; while ((iter=UUGetFileListItem(index))) { if (iter->filename == NULL) { index++; continue; } if (!(work_file (iter->filename))) { if (interact && !quiet) printf (" %s %s ignored.\n", filemode((int)iter->mode), (iter->filename)?iter->filename:""); index++; continue; } if (iter->state & UUFILE_OK) ptr = "State is OK"; else if (iter->state & UUFILE_NODATA) ptr = NULL; else if (iter->state & UUFILE_NOBEGIN) ptr = "No Begin found"; else if (iter->state & UUFILE_MISPART) ptr = "Missing Part(s)"; else if (iter->state & UUFILE_NOEND) ptr = "No End found"; else ptr = "Unknown State"; if (iter->state & UUFILE_NODATA) { index++; continue; } UUGetOption (UUOPT_DESPERATE, &desp, NULL, 0); if (iter->state & UUFILE_OK || desp) { res = process_one (iter); } else { if (ptr && iter->filename) printf ("ERROR: File %s (%s): %s (%d)\n", (iter->filename) ? iter->filename : "", (iter->subfname) ? iter->subfname : "", ptr, iter->state); decodedmisp++; res = 1; } if (res == 0) break; else if (res == -1) { if (index==0) printf ("*** Already at beginning of list\n"); else { index--; while ((!(iter->state & UUFILE_OK || desp) || iter->state == UUFILE_NODATA) && index) index--; } } else { index++; } } return 0; } static void sighandler (int signo) { printf ("\nReceived Signal (%d), cleaning up temp files.\n", signo); UUCleanUp (); exit (99); } /* * usage */ static void usage (char *argv0) { printf ("\n\ UUDEVIEW %s%s%s - the nice and friendly decoder - (w) 1994 Frank Pilhofer\n", VERSION, (PATCH[0]>'0')?"pl":"", (PATCH[0]>'0')?PATCH:""); printf (" usage:\n"); printf (" uudeview [options] [file ...]\n\n"); printf (" Options:\n"); printf ("\t-i Disable interactivity (do not ask, decode everything)\n"); printf ("\t-a Autorename (rename file if it exists on disk)\n"); printf ("\t-m Ignore the file mode of uuencoded files\n"); printf ("\t+e/-e Include or exclude extensions exclusively\n"); printf ("\t-d Sets 'desperate' mode (process incomplete files)\n"); printf ("\t-f Fast mode. Only if each file holds no more than one part\n"); printf ("\t-o/+o -o OK to overwrite files, +o never overwrite files\n"); printf ("\t-b1 Select alternate bracket policy\n"); printf ("\t-p path Sets path where to save decoded binaries to\n"); printf ("\t-c Autoclear files that were successfully decoded.\n"); printf ("\t-s Be more strict on MIME adherance.\n"); printf ("\t-q Quiet. Do not emit progress messages.\n\n"); #if defined(SYSTEM_DOS) || defined(SYSTEM_QUICKWIN) printf (" See Manual for more details\n\n"); #else printf (" See uudeview(1) for more details.\n\n"); #endif printf (" Example:\n"); printf (" uudeview +e .jpg.gif -i newsfile\n"); printf ("\tThis decodes all .jpg or .gif files encountered in \n"); printf ("\twithout asking.\n\n"); } /* * uudeview main function */ int main (int argc, char *argv[]) { int res; #ifdef SYSTEM_QUICKWIN struct _wsizeinfo ws; #endif /* * No Signal handler in QuickWin */ #ifndef SYSTEM_QUICKWIN signal (SIGINT, sighandler); #endif /* * In QuickWin, set the about() Box, and give more space to scroll */ #ifdef SYSTEM_QUICKWIN ws._version = _QWINVER; ws._type = _WINSIZEMAX; (void) _wabout ("UUdeview for Windows\n(c) 1995 Frank Pilhofer\nfp@fpx.de"); (void) _wsetscreenbuf (fileno(stdout), 16384); (void) _wsetscreenbuf (fileno(stderr), 16384); (void) _wsetsize (fileno(stdout), &ws); #endif /* * Check where we are and set the save directory */ #ifdef HAVE_GETCWD if (getcwd (savepath, 255) == NULL) #endif strcpy (savepath, "./"); /* * in DOS, set the DOS Filename Filter */ #if defined(SYSTEM_DOS) || defined(SYSTEM_QUICKWIN) UUSetFNameFilter (NULL, UUFNameFilterDOS); #else UUSetFNameFilter (NULL, UUFNameFilterUnix); #endif UUSetBusyCallback (NULL, BusyCallback, 100); /* * If we were called as uudecode, be quiet and don't interact */ if (_FP_stristr (argv[0], "uudecode") != NULL) { interact = 0; decoall = 1; quiet = 1; overwrite = 1; } else if (argc < 2) { usage (argv[0]); return 99; } /* * Setup Callback */ UUSetMsgCallback (NULL, MessageCallback); if (UUInitialize () != UURET_OK) { fprintf (stderr, "oops: could not initialize decoding library\n"); return 99; } /* * use options from UUDEVIEW environment variable */ if ((getenv ("UUDEVIEW")) != NULL) { makeparams (getenv ("UUDEVIEW")); } if (argc < 2) { /* * can only be in uudecode compatibility mode */ proc_stdin (); } else { work_comline (argc, argv); } if (strlen(savepath)) { if (savepath[strlen(savepath)-1] != DIRSEPARATOR[0]) strcat (savepath, DIRSEPARATOR); } if (!stdinput && !quiet && UUGetOption (UUOPT_VERBOSE, NULL, NULL, 0)) { DumpFileList (); } /* * try merging thrice with increased tolerance */ UUSmerge (0); UUSmerge (1); UUSmerge (99); res = process_files (); /* * clear info */ if (UUISATTY(stderr) && !nobar) { fprintf (stderr, "\r%70s\r", ""); fflush (stderr); } #ifndef SYSTEM_QUICKWIN signal (SIGINT, SIG_DFL); #endif UUCleanUp(); killext (extensions); /* * Without user interaction, or if the user has quit * the proggy, kill myself in QuickWin */ #ifdef SYSTEM_QUICKWIN if (!interact || res==1) _wsetexit (_WINEXITNOPERSIST); else { printf ("\n\ No more Programs to decode.\n\ Select File-Exit to close window\n\ \n"); } #endif if (UUGetOption (UUOPT_VERBOSE, NULL, NULL, 0) && !quiet && inputfiles && (decodedok || decodedfailed || decodedmisp)) { printf ("%d file%s decoded from %d input file%s, %d failed\n", decodedok, (decodedok==1)?"":"s", inputfiles, (inputfiles==1)?"":"s", decodedfailed+decodedmisp); } /* * determine return value */ if (decodedfailed || decodedmisp) { return ((decodedok?1:0) | ((decodedmisp||decodedfailed)?2:0)); } return 0; } uudeview-0.5.20.orig/unix/uuenview.c0000644001167100001440000007671607441417456017361 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif /* * Main function for standalone uuenview */ #include #include #include #include #include #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #include #include #include char * uuenview_id = "$Id: uuenview.c,v 1.22 2002/03/06 13:52:46 fp Exp $"; /* * mail and news software */ #ifdef PROG_INEWS char * uue_inewsprog = PROG_INEWS; #else char * uue_inewsprog = NULL; #endif #ifdef PROG_MAILER char * uue_mailprog = PROG_MAILER; #else char * uue_mailprog = NULL; #endif #ifdef MAILER_NEEDS_SUBJECT int uue_mpsubject = 1; #else int uue_mpsubject = 0; #endif /* * defines */ #define UUE_STDOUT 0 #define UUE_TOFILE 1 #define UUE_MAILTO 2 #define UUE_POSTTO 3 /* * the progress meter is only displayed if stderr is a terminal. * take care of systems where we can't check this condition. */ #ifdef HAVE_ISATTY #define UUISATTY(f) (isatty(fileno(f))) #else #define UUISATTY(f) (1) #endif /* * Message Callback */ static void MessageCallback (void *param, char *message, int level) { #if 0 if (UUGetOption (UUOPT_VERBOSE, NULL, NULL, 0) || level >= UUMSG_WARNING) { fprintf (stderr, "%70s\r", ""); fprintf (stderr, "%s\n", message); } #else if (level >= UUMSG_WARNING) { fprintf (stderr, "%70s\r", ""); fprintf (stderr, "%s\n", message); } #endif } static int BusyCallback (void *param, uuprogress *progress) { char stuff[26]; int count, pcts; char *ptr; /* * Display progress meter only if stderr is a terminal */ if (!UUISATTY(stderr)) return 0; if ((ptr = _FP_strrchr (progress->curfile, DIRSEPARATOR[0])) == NULL) ptr = progress->curfile; else ptr++; if (progress->action == 4 && UUGetOption (UUOPT_VERBOSE, NULL, NULL, 0)) { pcts = (int)((100*progress->partno+progress->percent-100) / progress->numparts); for (count=0, stuff[25]='\0'; count<25; count++) stuff[count] = (countpartno, progress->numparts, stuff); fflush (stderr); } return 0; } /* * usage */ static void usage (char *argv0) { if (_FP_stristr (argv0, "uuencode") != NULL) { printf ("\n\ uuencode -- a simple encoder (w) 1995 Frank Pilhofer\n\n\ usage:\n\ uuencode [infile] remotefile\n\n\ "); printf ("\ \tinfile the local file, where to read data from. If no infile\n\ \t is given, or infile is a single hyphen, the standard\n\ \t input is used instead.\n\ \tremotefile the name as which the recepient will receive the file\n\ \n\ For much more powerful encoding facilities, try calling this program\n\ as 'uuenview'.\n\ \n\ "); return; } printf ("\n\ UUENVIEW %spl%s -- a simple encoder (w) 1995 Frank Pilhofer\n\n\ usage:\n\ uuenview [-type] [options] file [...]\n\n", VERSION, PATCH); printf (" Options:\n"); printf ("\t-b,-u,-x,-y Encode files as Base64, Uuencoding, Xx, yEnc,\n"); printf ("\t-t,-q Plain text or Quoted-Printable, respectively\n"); printf ("\t-o Encode to file(s) using the original's base name\n"); printf ("\t-od path Same, but write files to selected path\n"); #if defined(HAVE_POPEN) && defined(PROG_MAILER) printf ("\t-m addr Send file(s) by mail\n"); #endif #if defined(HAVE_POPEN) && defined(PROG_INEWS) printf ("\t-p group Post file(s) to newsgroups\n"); #endif printf ("\t-a Read message from stdin and attach files\n"); printf ("\t-lines Chunk into messages of lines lines each\n"); printf ("\n"); #if defined(SYSTEM_DOS) || defined(SYSTEM_QUICKWIN) printf (" See Manual for more details\n\n"); #else printf (" See uuenview(1) for more details.\n\n"); #endif printf (" Example:\n"); #ifndef HAVE_POPEN printf (" uuenview -b -2000 -o uuenview.exe\n"); printf ("\tEncodes uuenview.exe as Base64 into 2000-line chunks, and\n"); printf ("\twrites the result to uuenview.001 and uuenview.002.\n\n"); #else printf (" uuenview -b -2000 -m root -o uudeview.tar.gz\n"); printf ("\tEncodes 'uudeview.tar.gz' as Base64 into 2000-line chunks.\n"); printf ("\tIt is both mailed to your system administrator and written\n"); printf ("\tto the files uudeview.001 and uudeview.002\n\n"); #endif return; } /* * ----------------------------------------------------------------------- * Stolen from uuscan.c to parse boundary * ----------------------------------------------------------------------- */ /* * Extract the value from a MIME attribute=value pair. This function * receives a pointer to the attribute. */ static char * ParseValue (char *attribute) { static char uuscan_pvvalue[256]; char *ptr=uuscan_pvvalue; int length=0; if (attribute == NULL) return NULL; while (*attribute && *attribute != '=') attribute++; if (*attribute == '=') { attribute++; while (isspace (*attribute)) attribute++; } if (!*attribute) return NULL; if (*attribute == '"') { /* quoted-string */ attribute++; while (*attribute && *attribute != '"' && length < 255) { if (*attribute == '\\') *ptr++ = *++attribute; else *ptr++ = *attribute; attribute++; length++; } *ptr = '\0'; } else { /* tspecials from RFC1521 */ while (*attribute && !isspace (*attribute) && *attribute != '(' && *attribute != ')' && *attribute != '<' && *attribute != '>' && *attribute != '@' && *attribute != ',' && *attribute != ';' && *attribute != ':' && *attribute != '\\' &&*attribute != '"' && *attribute != '/' && *attribute != '[' && *attribute != ']' && *attribute != '?' && *attribute != '=' && length < 255) *ptr++ = *attribute++; *ptr = '\0'; } return uuscan_pvvalue; } /* * ----------------------------------------------------------------------- * Stolen from uuscan.c (end) * ----------------------------------------------------------------------- */ /* * Create command line to mail or post a file. The result is malloc()ed * and must be freed manually */ static char * SendMkCommand (char **rcptlist, char *towhom, char *subject, int isemail) { char *command, *ptr; int len, count; *rcptlist = NULL; if (isemail && (uue_mailprog == NULL || *uue_mailprog == '\0')) { fprintf (stderr, "error: Cannot Email file: option not configured\n"); return NULL; } else if (!isemail && (uue_inewsprog == NULL || *uue_inewsprog == '\0')) { fprintf (stderr, "error: Cannot Post file: option not configured\n"); return NULL; } len = strlen ((isemail)?uue_mailprog:uue_inewsprog) + ((uue_mpsubject)?strlen(subject):0) + ((isemail)?strlen(towhom):0) + 32; if ((command = (char *) malloc (len)) == NULL) { fprintf (stderr, "error: Out of memory allocating %d bytes\n", len); return NULL; } if ((*rcptlist = (char *) malloc (strlen (towhom) + 16)) == NULL) { fprintf (stderr, "error: Out of memory allocating %d bytes\n", strlen (towhom)+16); _FP_free (command); return NULL; } if (isemail) { if (uue_mpsubject && subject!=NULL) sprintf (command, "%s -s \"%s\"", uue_mailprog, subject); else sprintf (command, "%s", uue_mailprog); /* * Attach list of recipients to mailer command and compose another list * of recipients */ count = 0; (*rcptlist)[0] = '\0'; ptr = _FP_strtok (towhom, ",; "); while (ptr) { strcat (command, " \""); strcat (command, ptr); strcat (command, "\""); if (count++) strcat (*rcptlist, ","); strcat (*rcptlist, ptr); ptr = _FP_strtok (NULL, ",; "); } } else { /* posting */ sprintf (command, "%s", uue_inewsprog); count = 0; (*rcptlist)[0] = '\0'; ptr = _FP_strtok (towhom, ";, "); while (ptr) { if (count++) strcat (*rcptlist, ","); strcat (*rcptlist, ptr); ptr = _FP_strtok (NULL, ";, "); } } return command; } /* * Attach something. A text is read from stdin and converted into a proper * MIME message. All files from the command line are then attached MIME- * style. The result is mailed or posted. * If towhom==NULL, the result is sent to stdout. */ static int AttachFiles (char *towhom, char *subject, char *from, char *replyto, int isemail, int encoding, int argc, char *argv[]) { static char input[1024], *ctype=NULL, *cte=NULL, boundary[64]; char *command=NULL, *rcptlist=NULL, *ptr; FILE *thepipe; int index, res; /* remember the headers we care about */ int hadsubject=0, hadgroups=0, hadto=0, hadmime=0, hadmulti=0; int hadfrom=0, hadreplyto=0; if (towhom) { #ifndef HAVE_POPEN fprintf (stderr, "error: Your system does not support %s of files\n", (isemail)?"mailing":"posting"); return UURET_ILLVAL; #else if ((command = SendMkCommand (&rcptlist, towhom, subject, isemail)) == NULL) { return UURET_ILLVAL; } if ((thepipe = popen (command, "w")) == NULL) { fprintf (stderr, "error: could not open pipe %s\n", command); _FP_free (rcptlist); _FP_free (command); return UURET_IOERR; } #endif } else { thepipe = stdout; } /* * okay, copy and scan header */ index=0; while (!feof (stdin)) { if (_FP_fgets (input, 1024, stdin) == NULL) break; if (input[0] == '\0' || input[0] == '\012' || input[0] == '\015') break; /* * If the first line does not appear to be a header */ if (index == 0) { ptr = input; while (*ptr && !isspace(*ptr) && *ptr!=':') ptr++; if (*ptr != ':' && _FP_strnicmp (input, "From ", 5) != 0) { break; } index++; } if (_FP_strnicmp (input, "Subject:", 8) == 0) { if (subject) { fprintf (thepipe, "Subject: %s\n", subject); } else { fprintf (thepipe, "%s", input); } hadsubject = 1; } else if (_FP_strnicmp (input, "Newsgroups:", 11) == 0) { if (towhom && !isemail && rcptlist) { fprintf (thepipe, "Newsgroups: %s\n", rcptlist); } else { fprintf (thepipe, "%s", input); } hadgroups = 1; } else if (_FP_strnicmp (input, "To:", 3) == 0) { if (towhom && isemail && rcptlist) { fprintf (thepipe, "To: %s\n", rcptlist); } else { fprintf (thepipe, "%s", input); } hadto = 1; } else if (_FP_strnicmp (input, "From:", 5) == 0) { if (from) { fprintf (thepipe, "From: %s\n", from); } else { fprintf (thepipe, "%s", input); } hadfrom = 1; } else if (_FP_strnicmp (input, "Reply-To:", 9) == 0) { if (replyto) { fprintf (thepipe, "Reply-To: %s\n", replyto); } else { fprintf (thepipe, "%s", input); } hadreplyto = 1; } else if (_FP_strnicmp (input, "Mime-Version:", 13) == 0) { fprintf (thepipe, "%s", input); hadmime = 1; } else if (_FP_strnicmp (input, "Content-Type:", 13) == 0) { if (_FP_stristr (input, "multipart") != NULL) { /* it is already a multipart posting. grab the boundary */ if ((ptr = _FP_stristr (input, "boundary=")) != NULL) { fprintf(thepipe, input); strcpy (boundary, ParseValue (ptr)); hadmulti = 1; } } else { /* * save content-type for later, must be only one line! */ ctype = _FP_strdup (input); } } else if (_FP_strnicmp (input, "Content-Transfer-Encoding:", 26) == 0) { /* * save for later, must be only one line */ cte = _FP_strdup (input); } else { /* * just copy header line */ fprintf (thepipe, "%s", input); } } /* * okay, header is copied. add our own fields if necessary */ if (!hadmime && encoding != YENC_ENCODED) fprintf (thepipe, "Mime-Version: 1.0\n"); if (!hadmulti && encoding != YENC_ENCODED) { /* must invent a boundary */ sprintf (boundary, "==UUD_=_%ld", (long) time (NULL)); fprintf (thepipe, "Content-Type: multipart/mixed; boundary=\"%s\"\n", boundary); } /* * huh, there have been no headers. */ if (!hadfrom && from) { fprintf (thepipe, "From: %s\n", from); } if (!hadgroups && towhom && !isemail && rcptlist) { fprintf (thepipe, "Newsgroups: %s\n", rcptlist); } if (!hadto && towhom && isemail && rcptlist) { fprintf (thepipe, "To: %s\n", rcptlist); } if (!hadreplyto && replyto) { fprintf (thepipe, "Reply-To: %s\n", replyto); } if (!hadsubject && subject) { fprintf (thepipe, "Subject: %s\n", subject); } /* * end headers */ fprintf (thepipe, "\n"); /* * okay, copy text if available */ if (!feof (stdin) && index > 0) { ptr = _FP_fgets (input, 1024, stdin); } else { ptr = input; } if (!feof (stdin) && ptr) { if (!hadmulti && encoding != YENC_ENCODED) { /* * need our own header */ fprintf (thepipe, "--%s\n", boundary); if (ctype) { fprintf (thepipe, "%s", ctype); } else { fprintf (thepipe, "Content-Type: text/plain\n"); } if (cte) { fprintf (thepipe, "%s", cte); } else { fprintf (thepipe, "Content-Transfer-Encoding: 8bit\n"); } fprintf (thepipe, "\n"); /* * just copy stdin */ fprintf (thepipe, "%s", input); while (!feof (stdin)) { if (_FP_fgets (input, 256, stdin) == NULL) break; fprintf (thepipe, "%s", input); } /* * the last crlf is to be ignored, so add another one */ fprintf (thepipe, "\n"); } else { /* * this was already a multipart/mixed posting, copy everything up * to the final boundary */ while (!feof (stdin)) { if (_FP_fgets (input, 256, stdin) == NULL) break; if (input[0] == '-' && input[1] == '-' && strncmp (input+2, boundary, strlen (boundary)) == 0 && input[strlen(boundary)+2] == '-' && input[strlen(boundary)+3] == '-') break; fprintf (thepipe, "%s", input); } } } /* * okay, so let's finally make our attachments */ for (index=1; index0) { if (outdir[strlen(outdir)-1]!=DIRSEPARATOR[0]) { strcat (outdir, DIRSEPARATOR); } } UUSetOption (UUOPT_SAVEPATH, 0, outdir); } else { fprintf (stderr, "error: -od requires a parameter\n"); } } else { outflags[UUE_TOFILE] = index; tostdout = 0; } break; case 's': if (index+1='0' && myargv[index][1]<='9') { if (attach) { fprintf (stderr, "error: cannot attach to splitfile\n"); return 1; } linperfile = atoi (myargv[index] + 1); if (linperfile != 0 && linperfile < 200) { fprintf (stderr, "warning: lines per file must be >= 200 (ignored).\n"); linperfile=0; } } else if (myargv[index][1]=='-' && myargv[index][2]>='0' && myargv[index][2]<='9') { if (attach) { fprintf (stderr, "error: cannot attach to splitfile\n"); return 1; } linperfile = atoi (myargv[index] + 2); } else if (myargv[index][1]=='-') { usage(myargv[0]); return 0; } else { fprintf (stderr, "warning: unknown option '%s' ignored.\n", myargv[index]); } } } else { files++; } } if (_FP_stristr (myargv[0], "uuencode") != NULL) { uuencode = 1; /* uuencode compatibility */ if (encoding == -1) { encoding = UU_ENCODED; } if (files == 1) { stdinused = 1; } else if (files > 2) { fprintf (stderr, "usage: %s [infile] destname\n", myargv[0]); return 0; } } /* * check integrity */ if (linperfile != 0 && tostdout) { fprintf (stderr, "warning: cannot split file on standard output (use -o)\n"); linperfile=0; } if (subject>0 && tostdout && !attach) { fprintf (stderr, "warning: -s not possible on standard output\n"); subject = -1; } if (encoding == -1) { if (attach || outflags[UUE_POSTTO]>0 || outflags[UUE_MAILTO]>0) { encoding = B64ENCODED; } else { encoding = UU_ENCODED; } } if (encoding!=UU_ENCODED && encoding!=XX_ENCODED && encoding!=B64ENCODED && encoding!=PT_ENCODED && encoding!=QP_ENCODED && encoding!=YENC_ENCODED) { fprintf (stderr, "warning: unknown encoding method (%d)?\n", encoding); encoding=UU_ENCODED; } #ifdef SYSTEM_DOS if (tostdout==0 && outflags[UUE_TOFILE] == -1) { fprintf (stderr, "error: no output defined?\n"); exit (2); } #endif /* * In Attach mode, first open the pipe and copy the existing article */ if (attach) { if (outflags[UUE_POSTTO]==0 && outflags[UUE_MAILTO]==0 && !tostdout) { fprintf (stderr, "error: attach only possible to mail, news or stdout\n"); exit (2); } if (outflags[UUE_POSTTO]>0 && outflags[UUE_MAILTO]>0) { fprintf (stderr, "warning: can attach only to one destination (sending mail only)\n"); outflags[UUE_POSTTO] = 0; } if (outflags[UUE_POSTTO]>0) { AttachFiles (myargv[outflags[UUE_POSTTO]], (subject>0)?myargv[subject]:NULL, (from>0)?myargv[from]:NULL, (replyto>0)?myargv[replyto]:NULL, 0, encoding, myargc, myargv); } else if (outflags[UUE_MAILTO]>0) { AttachFiles (myargv[outflags[UUE_MAILTO]], (subject>0)?myargv[subject]:NULL, (from>0)?myargv[from]:NULL, (replyto>0)?myargv[replyto]:NULL, 1, encoding, myargc, myargv); } else /* tostdout */ { AttachFiles (NULL, (subject>0)?myargv[subject]:NULL, (from>0)?myargv[from]:NULL, (replyto>0)?myargv[replyto]:NULL, 0, encoding, myargc, myargv); } /* finished here */ count=1; goto uuenview_end; } /* * okay, now process the files */ for (index=1, iskipflag=0; index 0) ? 1 : 0) + ((outflags[UUE_MAILTO] > 0) ? 1 : 0) + ((outflags[UUE_TOFILE] > 0) ? 1 : 0) > 1) { fprintf (stderr, "error: can use standard input only once\n"); continue; } } else if ((testit = fopen (myargv[index], "r")) == NULL) { fprintf (stderr, "error: '%s' unreadable.\n", myargv[index]); continue; } else fclose (testit); fileflag = 0; #ifdef HAVE_POPEN /* * post it */ if (outflags[UUE_POSTTO] > 0) { fileflag++; SendAFile ((filename[0])?NULL:stdin, (filename[0])?filename:NULL, encoding, linperfile, usename, myargv[outflags[UUE_POSTTO]], (subject>0)?myargv[subject]:NULL, (from>0)?myargv[from]:NULL, (replyto>0)?myargv[replyto]:NULL, 0); } /* * mail it separately to each recepient */ if (outflags[UUE_MAILTO] > 0) { fileflag++; SendAFile ((filename[0])?NULL:stdin, (filename[0])?filename:NULL, encoding, linperfile, usename, myargv[outflags[UUE_MAILTO]], (subject>0)?myargv[subject]:NULL, (from>0)?myargv[from]:NULL, (replyto>0)?myargv[replyto]:NULL, 1); } #endif /* * store output into a file */ if (outflags[UUE_TOFILE] > 0 || outflags[UUE_TOFILE] == -42) { fileflag++; UUEncodeToFile ((filename[0])?NULL:stdin, (filename[0])?filename:NULL, encoding, usename, NULL, linperfile); } /* * send it to stdout */ if (tostdout) { fileflag++; UUEncodeToStream (stdout, (filename[0])?NULL:stdin, (filename[0])?filename:NULL, encoding, usename, 0); } if (fileflag > 0) count++; } /* end file processing */ } /* end loop */ uuenview_end: if (UUISATTY(stderr)) { fprintf (stderr, "%70s\r", ""); fflush (stderr); } if (count==0) { fprintf (stderr, "error: no files.\n"); } UUCleanUp (); return 0; } uudeview-0.5.20.orig/unix/uufnflt.c0000644001167100001440000000630507646302502017150 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * Predefined Filename filters. They aren't part of the Library, because * they are system-dependent. Just add this file to your project. If you * write filters for other systems, or find problems with these here, let * me know. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif #include #include #ifdef STDC_HEADERS #include #include #endif #include #include char * uufnflt_id = "$Id: uufnflt.c,v 1.7 2003/04/13 15:41:54 fp Exp $"; char * UUFNameFilterUnix (void *opaque, char *fname) { char *ptr; if (fname == NULL) return NULL; /* * strip directory information */ if ((ptr = _FP_strrchr (fname, '/')) != NULL) { fname = ptr+1; } if ((ptr = _FP_strrchr (fname, '\\')) != NULL) { fname = ptr+1; } if (strcmp (fname, ".") == 0 || strcmp (fname, "..") == 0) { fname[0] = '_'; } /* * remove space characters from the beginning */ while (*fname == ' ') { fname++; } /* * If filename is empty by now, return a dummy string */ if (!*fname) { return "blank_filename"; } /* * Replace all questionable punctuation characters by underscores */ for (ptr=fname; *ptr; ptr++) { if (*ptr == '"' || *ptr == '<' || *ptr == '>' || *ptr == '{' || *ptr == '}' || *ptr == '|' || *ptr == '&' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n') { *ptr = '_'; } } return fname; } char * UUFNameFilterDOS (void *opaque, char *fname) { static char dosname[13], *ptr1, *ptr2; int count=0; if (fname == NULL) return NULL; /* * strip directory information */ if ((ptr1 = _FP_strrchr (fname, '/')) != NULL) fname = ptr1 + 1; else if ((ptr1 = _FP_strrchr (fname, '\\')) != NULL) fname = ptr1 + 1; ptr1 = dosname; while (*fname && *fname!='.' && count++ < 8) { if (*fname == ' ') *ptr1++ = '_'; else *ptr1++ = *fname; fname++; } while (*fname && *fname!='.') fname++; if (ptr1 == dosname) *ptr1++ = '_'; if (*fname=='.') { *ptr1++ = *fname++; if (_FP_stricmp (fname, "tar.gz") == 0) { *ptr1++ = 't'; *ptr1++ = 'g'; *ptr1++ = 'z'; } else { if ((ptr2 = _FP_strrchr (fname, '.')) == NULL) ptr2 = fname; else ptr2++; count=0; while (*ptr2 && count++ < 3) { if (*ptr2 == ' ') *ptr1++ = '_'; else *ptr1++ = *ptr2; ptr2++; } } } *ptr1 = '\0'; return dosname; } uudeview-0.5.20.orig/unix/uufnflt.h0000644001167100001440000000160207307472264017157 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * Predefined Filename filters */ #ifndef __UUFNFLT_H__ #define __UUFNFLT_H__ char * UUFNameFilterUnix _ANSI_ARGS_((void *, char *)); char * UUFNameFilterDOS _ANSI_ARGS_((void *, char *)); #endif uudeview-0.5.20.orig/uulib/0000755001167100001440000000000010020741142015435 5ustar cphusers00000000000000uudeview-0.5.20.orig/uulib/Makefile.in0000644001167100001440000000426707443072702017531 0ustar cphusers00000000000000# # ============================================================================ # # This is the Makefile for the uu library, part of the uudeview package. # The values here were guessed by ./configure and are probably correct. # # Usefull targets # all Compile the package # clean Deletes the binaries and objects and all the # other dirty stuff. # # ============================================================================ # # $Id: Makefile.in,v 1.6 2002/03/11 09:15:46 fp Exp $ # # your make might need this # SHELL = /bin/sh # # If you don't have the GNU C compiler installed, set CC=cc here # CC = @CC@ # # C Compiler Options # CFLAGS = @CFLAGS@ -I. @CPPFLAGS@ @DEFS@ # # the ranlib program # RANLIB = @RANLIB@ # ############################################################################### # You shouldn't have to change anything below. ############################################################################### # # Programs to compile, Manpages to install and Versions # VERSION = @VERSION@ PATCH = @PATCH@ VDEF = -DVERSION=\"$(VERSION)\" -DPATCH=\"$(PATCH)\" # UULIB_SOURCE = uulib.c uucheck.c uunconc.c uuutil.c uuencode.c \ uuscan.c uustring.c fptools.c crc32.c UULIB_OBJ = ${UULIB_SOURCE:.c=.o} # # make stuff # .SUFFIXES: .SUFFIXES: .c .o all: libuu.a clean: rm -f [Xx]deview gif2gfp rm -f *.o *.a *.so core *~ TAGS distclean: clean rm -f config.status config.cache config.log Makefile config.h rm -f uudeview-*tar* uudeview-sfx realclean: distclean new: clean rm -f libuu.a $(MAKE) all libuu.a: $(UULIB_OBJ) rm -f $@ ar r $@ $(UULIB_OBJ) -$(RANLIB) $@ .c.o: $(CC) -c $(CFLAGS) $(VDEF) $< uuencode.o: uuencode.c uudeview.h uuint.h uustring.h fptools.h config.h uulib.o: uulib.c uudeview.h uuint.h uustring.h fptools.h config.h uunconc.o: uunconc.c uudeview.h uuint.h uustring.h fptools.h config.h uucheck.o: uucheck.c uudeview.h uuint.h uustring.h fptools.h config.h uuutil.o: uuutil.c uudeview.h uuint.h uustring.h fptools.h config.h uuscan.o: uuutil.c uudeview.h uuint.h uustring.h fptools.h config.h uustring.o: uustring.c uudeview.h uuint.h uustring.h config.h fptools.o: fptools.c fptools.h config.h uustring.h: uustring.c awk -f uustring.awk < uustring.c > uustring.h uudeview-0.5.20.orig/uulib/acconfig.h0000644001167100001440000000246206155632133017400 0ustar cphusers00000000000000 /* * needed for auto configuration * $Id: acconfig.h,v 1.1.1.1 1996/06/06 19:41:15 fp Exp $ */ /* * If your system is kinda special */ #undef SYSTEM_DOS #undef SYSTEM_QUICKWIN #undef SYSTEM_WINDLL #undef SYSTEM_OS2 /* * If your system has stdin/stdout/stderr */ #undef HAVE_STDIO /* * how to declare functions that are exported from the UU library */ #undef UUEXPORT /* * how to declare functions that are exported from the fptools library */ #undef TOOLEXPORT /* * define if your compiler supports function prototypes */ #undef PROTOTYPES /* * Replacement functions. * #define strerror _FP_strerror * #define tempnam _FP_tempnam * if you don't have these functions */ #undef strerror #undef tempnam /* * your mailing program. full path and the necessary parameters. * the recepient address is added to the command line (with a leading * space) without any further options */ #undef PROG_MAILER /* * define if the mailer needs to have the subject set on the command * line with -s "Subject". Preferredly, we send the subject as a header. */ #undef MAILER_NEEDS_SUBJECT /* * define if posting is enabled. Do not edit. */ #undef HAVE_NEWS /* * your local news posting program. full path and parameters, so that * the article and all its headers are read from stdin */ #undef PROG_INEWS uudeview-0.5.20.orig/uulib/aclocal.m40000644001167100001440000001471407744547244017336 0ustar cphusers00000000000000dnl dnl originally from ncftp 2.3.0 dnl added wi_EXTRA_PDIR and wi_ANSI_C dnl $Id: aclocal.m4,v 1.2 2003/10/19 17:49:24 fp Exp $ dnl AC_DEFUN(wi_EXTRA_IDIR, [ incdir="$1" if test -r $incdir ; then case "$CPPFLAGS" in *-I${incdir}*) # echo " + already had $incdir" 1>&6 ;; *) if test "$CPPFLAGS" = "" ; then CPPFLAGS="-I$incdir" else CPPFLAGS="$CPPFLAGS -I$incdir" fi echo " + found $incdir" 1>&6 ;; esac fi ]) dnl dnl dnl dnl AC_DEFUN(wi_EXTRA_LDIR, [ libdir="$1" if test -r $libdir ; then case "$LDFLAGS" in *-L${libdir}*) # echo " + already had $libdir" 1>&6 ;; *) if test "$LDFLAGS" = "" ; then LDFLAGS="-L$libdir" else LDFLAGS="$LDFLAGS -L$libdir" fi echo " + found $libdir" 1>&6 ;; esac fi ]) dnl dnl __FP__ dnl dnl AC_DEFUN(wi_EXTRA_PDIR, [ progdir="$1" if test -r $progdir ; then case "$PATH" in *:${progdir}*) # echo " + already had $progdir" 1>&6 ;; *${progdir}:*) # echo " + already had $progdir" 1>&6 ;; *) if test "$PATH" = "" ; then PATH="$progdir" else PATH="$PATH:$progdir" fi echo " + found $progdir" 1>&6 ;; esac fi ]) dnl dnl dnl If you want to also look for include and lib subdirectories in the dnl $HOME tree, you supply "yes" as the first argument to this macro. dnl dnl If you want to look for subdirectories in include/lib directories, dnl you pass the names in argument 3, otherwise pass a dash. dnl AC_DEFUN(wi_EXTRA_DIRS, [echo "checking for extra include and lib directories..." 1>&6 ifelse([$1], yes, [dnl b1=`cd .. ; pwd` b2=`cd ../.. ; pwd` exdirs="$HOME $j $b1 $b2 $prefix $2" ],[dnl exdirs="$prefix $2" ]) subexdirs="$3" if test "$subexdirs" = "" ; then subexdirs="-" fi for subexdir in $subexdirs ; do if test "$subexdir" = "-" ; then subexdir="" else subexdir="/$subexdir" fi for exdir in $exdirs ; do if test "$exdir" != "/usr" || test "$subexdir" != ""; then incdir="${exdir}/include${subexdir}" wi_EXTRA_IDIR($incdir) libdir="${exdir}/lib${subexdir}" wi_EXTRA_LDIR($libdir) progdir="${exdir}/bin${subexdirr}" wi_EXTRA_PDIR($progdir) fi done done ]) dnl dnl dnl AC_DEFUN(wi_PROTOTYPES, [ AC_MSG_CHECKING(if the compiler supports function prototypes) AC_TRY_COMPILE(,[extern void exit(int status);],[wi_cv_prototypes=yes AC_DEFINE(PROTOTYPES)],wi_cv_prototypes=no) AC_MSG_RESULT($wi_cv_prototypes) ]) dnl dnl dnl AC_DEFUN(wi_ANSI_C, [ AC_MSG_CHECKING(ANSI-style function definitions) AC_TRY_COMPILE(,[int blubb(int x) { return 0; }],[wi_cv_ansi_funcs=yes AC_DEFINE(ANSI_FUNCS)],wi_cv_ansi_funcs=no) AC_MSG_RESULT($wi_cv_ansi_funcs) ]) dnl dnl dnl AC_DEFUN(wi_HEADER_SYS_SELECT_H, [ # See if is includable after if test "$ac_cv_header_sys_time_h" = no ; then AC_CHECK_HEADERS(sys/time.h sys/select.h) else AC_CHECK_HEADERS(sys/select.h) fi if test "$ac_cv_header_sys_select_h" = yes ; then AC_MSG_CHECKING([if is compatible with ]) selecth=yes if test "$ac_cv_header_sys_time_h" = yes ; then AC_TRY_COMPILE([#include #include ],[ fd_set a; struct timeval tmval; tmval.tv_sec = 0;],selecth=yes,selecth=no) if test "$selecth" = yes ; then AC_DEFINE(CAN_USE_SYS_SELECT_H) fi fi AC_MSG_RESULT($selecth) fi ]) dnl dnl dnl AC_DEFUN(wi_LIB_RESOLV, [ # See if we could access two well-known sites without help of any special # libraries, like resolv. AC_TRY_RUN([ #include #include #include #include main() { struct hostent *hp1, *hp2; int result; hp1 = gethostbyname("gatekeeper.dec.com"); hp2 = gethostbyname("ftp.ncsa.uiuc.edu"); result = ((hp1 != (struct hostent *) 0) && (hp2 != (struct hostent *) 0)); exit(! result); }],look_for_resolv=no,look_for_resolv=yes,look_for_resolv=yes) AC_MSG_CHECKING([if we need to look for -lresolv]) AC_MSG_RESULT($look_for_resolv) if test "$look_for_resolv" = yes ; then AC_CHECK_LIB(resolv,main) else ac_cv_lib_resolv=no fi ]) dnl dnl dnl AC_DEFUN(wi_LIB_NSL, [ AC_MSG_CHECKING(if we can use -lnsl) ac_save_LIBS="$LIBS"; LIBS="$LIBS -lnsl"; AC_CACHE_VAL(r_cv_use_libnsl, [ AC_TRY_RUN( main() { if (getpwuid(getuid())) exit(0); exit(-1); }, nc_cv_use_libnsl=yes, nc_cv_use_libnsl=no, nc_cv_use_libnsl=no) ]) if test "$nc_cv_use_libnsl" = "no"; then LIBS="$ac_save_LIBS"; fi AC_MSG_RESULT($nc_cv_use_libnsl) ])dnl dnl dnl dnl AC_DEFUN(nc_PATH_PROG_ZCAT, [ AC_PATH_PROG(GZCAT,gzcat) AC_PATH_PROG(ZCAT,zcat) if test "x$GZCAT" = x ; then if test "x$ZCAT" != x ; then # See if zcat is really gzcat. gzcat has a --version option, regular # zcat does not. AC_MSG_CHECKING(if zcat is really gzcat in disguise) if $ZCAT --version 2> /dev/null ; then AC_DEFINE_UNQUOTED(GZCAT, "$ZCAT") AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi fi else AC_DEFINE_UNQUOTED(GZCAT, "$GZCAT") fi if test "x$ZCAT" != x ; then AC_DEFINE_UNQUOTED(ZCAT, "$ZCAT") fi ]) dnl dnl dnl AC_DEFUN(wi_SYSV_EXTRA_DIRS, [ # Use System V because their curses extensions are required. This must # be done early so we use the -I and -L in the library checks also. # This is mostly a Solaris/SunOS hack. Note that doing this will also # use all of the other System V libraries and headers. AC_MSG_CHECKING(for alternative System V libraries) if test -f /usr/5include/curses.h ; then CPPFLAGS="$CPPFLAGS -I/usr/5include" LDFLAGS="$LDFLAGS -L/usr/5lib" AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi ]) dnl dnl dnl AC_DEFUN(wi_DEFINE_UNAME, [ # Get first 127 chars of all uname information. Some folks have # way too much stuff there, so grab only the first 127. unam=`uname -a 2>/dev/null | cut -c1-127` if test "$unam" != "" ; then AC_DEFINE_UNQUOTED(UNAME, "$unam") fi ]) dnl dnl dnl AC_DEFUN(wi_READLINE_WITH_NCURSES, [ # Readline and Ncurses could both define "backspace". # Warn about this if we have both things in our definitions list. if test "$ac_cv_lib_readline" = yes && test "$ac_cv_lib_ncurses" = yes ; then AC_MSG_CHECKING(if readline and ncurses will link together) j="$LIBS" LIBS="-lreadline -lncurses" AC_TRY_LINK(,[ readline("prompt"); endwin(); ],k=yes,k=no) if test "$k" = no ; then AC_MSG_RESULT(no) # Remove '-lreadline' from LIBS. LIBS=`echo $j | sed s/-lreadline//g` ac_cv_lib_readline=no AC_WARN([The versions of GNU readline and ncurses you have installed on this system can't be used together, because they use the same symbol, backspace. If possible, recompile one of the libraries with -Dbackspace=back_space, then re-run configure.]) else AC_MSG_RESULT(yes) LIBS="$j" fi fi ]) dnl dnl dnl uudeview-0.5.20.orig/uulib/config.h.in0000644001167100001440000000325506174254664017514 0ustar cphusers00000000000000/* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define to `unsigned' if doesn't define. */ #undef size_t /* Define if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* * If your system is kinda special */ #undef SYSTEM_DOS #undef SYSTEM_QUICKWIN #undef SYSTEM_WINDLL #undef SYSTEM_OS2 /* * If your system has stdin/stdout/stderr */ #undef HAVE_STDIO /* * how to declare functions that are exported from the UU library */ #undef UUEXPORT /* * how to declare functions that are exported from the fptools library */ #undef TOOLEXPORT /* * define if your compiler supports function prototypes */ #undef PROTOTYPES /* * Replacement functions. * #define strerror _FP_strerror * #define tempnam _FP_tempnam * if you don't have these functions */ #undef strerror #undef tempnam /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY /* Define if you have the header file. */ #undef HAVE_ERRNO_H /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_IO_H /* Define if you have the header file. */ #undef HAVE_MALLOC_H /* Define if you have the header file. */ #undef HAVE_MEMORY_H /* Define if you have the header file. */ #undef HAVE_STDARG_H /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H /* Define if you have the header file. */ #undef HAVE_VARARGS_H uudeview-0.5.20.orig/uulib/configure0000755001167100001440000015271310020740756017367 0ustar cphusers00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=uulib.c # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi # # package revision # VERSION=0.5 PATCH=20 # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:537: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:567: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:618: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:650: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 661 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:692: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:697: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:725: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:757: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:778: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:795: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:812: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking if the compiler supports function prototypes""... $ac_c" 1>&6 echo "configure:838: checking if the compiler supports function prototypes" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* wi_cv_prototypes=yes cat >> confdefs.h <<\EOF #define PROTOTYPES 1 EOF else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* wi_cv_prototypes=no fi rm -f conftest* echo "$ac_t""$wi_cv_prototypes" 1>&6 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 echo "configure:864: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftestmake <<\EOF all: @echo 'ac_maketemp="${MAKE}"' EOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` if test -n "$ac_maketemp"; then eval ac_cv_prog_make_${ac_make}_set=yes else eval ac_cv_prog_make_${ac_make}_set=no fi rm -f conftestmake fi if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then echo "$ac_t""yes" 1>&6 SET_MAKE= else echo "$ac_t""no" 1>&6 SET_MAKE="MAKE=${MAKE-make}" fi # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:893: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" break fi done IFS="$ac_save_ifs" test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" fi fi RANLIB="$ac_cv_prog_RANLIB" if test -n "$RANLIB"; then echo "$ac_t""$RANLIB" 1>&6 else echo "$ac_t""no" 1>&6 fi if test "$wi_cv_prototypes" = no ; then echo "configure: warning: Your compiler does not support function prototyping and" 1>&2 echo "configure: warning: is not able to properly compile this package. What a pity." 1>&2 echo "configure: warning: Get gcc, or any compiler that supports function prototypes." 1>&2 exit 1 fi # # Checks for header files and library functions # echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:933: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:946: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:1037: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 echo "configure:1070: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include int main() { struct tm *tp; ; return 0; } EOF if { (eval echo configure:1084: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 if test $ac_cv_header_time = yes; then cat >> confdefs.h <<\EOF #define TIME_WITH_SYS_TIME 1 EOF fi for ac_hdr in fcntl.h unistd.h memory.h malloc.h errno.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1108: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1118: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_hdr in io.h sys/time.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1148: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1158: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done for ac_func in gettimeofday do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1187: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char $ac_func(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_$ac_func) || defined (__stub___$ac_func) choke me #else $ac_func(); #endif ; return 0; } EOF if { (eval echo configure:1215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_$ac_func=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 fi done echo $ac_n "checking for tempnam""... $ac_c" 1>&6 echo "configure:1241: checking for tempnam" >&5 if eval "test \"`echo '$''{'ac_cv_func_tempnam'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char tempnam(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_tempnam) || defined (__stub___tempnam) choke me #else tempnam(); #endif ; return 0; } EOF if { (eval echo configure:1269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_tempnam=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_tempnam=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_func_'tempnam`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 cat >> confdefs.h <<\EOF #define tempnam _FP_tempnam EOF fi # # strerror might be internally defined. this would cause a # CHECK_FUNCS(strerror) to fail because it'd be called with # zero arguments. So use our own code. # echo $ac_n "checking for strerror""... $ac_c" 1>&6 echo "configure:1299: checking for strerror" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_strerror=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* cat >> confdefs.h <<\EOF #define strerror _FP_strerror EOF have_strerror=no fi rm -f conftest* echo "$ac_t""$have_strerror" 1>&6 echo $ac_n "checking for stdin""... $ac_c" 1>&6 echo "configure:1329: checking for stdin" >&5 cat > conftest.$ac_ext < char *blubb() { FILE *in, *out; in=stdin; out=stdout; return (char*)0; } int main() { (void) blubb(); ; return 0; } EOF if { (eval echo configure:1343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* have_stdio=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_STDIO 1 EOF have_stdio=no fi rm -f conftest* echo "$ac_t""$have_stdio" 1>&6 if test "$ac_cv_header_stdc" = "no" ; then for ac_hdr in stdarg.h varargs.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 echo "configure:1364: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1374: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 fi done if test "$ac_cv_header_stdarg_h" = "no" ; then if test "$ac_cv_header_varargs_h" = "no" ; then { echo "configure: error: neither stdarg.h nor varargs.h present" 1>&2; exit 1; } fi fi fi # # Check whether this is a DOS-Based system. Another bogus test. # Don't even bother to print a message. This code is needed so # that autoheader includes the #undef into the final config.h # and we can change the definition by hand on a really DOS # system (where ./configure doesn't work anyway ...) # if false ; then cat >> confdefs.h <<\EOF #define SYSTEM_DOS 1 EOF cat >> confdefs.h <<\EOF #define SYSTEM_QUICKWIN 1 EOF cat >> confdefs.h <<\EOF #define SYSTEM_WINDLL 1 EOF cat >> confdefs.h <<\EOF #define SYSTEM_OS2 1 EOF fi # # On some systems (so far, OS2 and WINDOWS), functions that are exported # from a DLL must be declared specifically. # cat >> confdefs.h <> confdefs.h <&6 echo "configure:1452: checking version number" >&5 version_number="$VERSION"pl"$PATCH" echo "$ac_t""$version_number" 1>&6 # # done # trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 DEFS=-DHAVE_CONFIG_H # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@SET_MAKE@%$SET_MAKE%g s%@RANLIB@%$RANLIB%g s%@VERSION@%$VERSION%g s%@PATCH@%$PATCH%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* # These sed commands are passed to sed as "A NAME B NAME C VALUE D", where # NAME is the cpp macro being defined and VALUE is the value it is being given. # # ac_d sets the value in "#define NAME VALUE" lines. ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' ac_dC='\3' ac_dD='%g' # ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_uB='\([ ]\)%\1#\2define\3' ac_uC=' ' ac_uD='\4%g' # ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' ac_eB='$%\1#\2define\3' ac_eC=' ' ac_eD='%g' if test "${CONFIG_HEADERS+set}" != set; then EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF fi for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac echo creating $ac_file rm -f conftest.frag conftest.in conftest.out ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` cat $ac_file_inputs > conftest.in EOF # Transform confdefs.h into a sed script conftest.vals that substitutes # the proper values into config.h.in to produce config.h. And first: # Protect against being on the right side of a sed subst in config.status. # Protect against being in an unquoted here document in config.status. rm -f conftest.vals cat > conftest.hdr <<\EOF s/[\\&%]/\\&/g s%[\\$`]%\\&%g s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp s%ac_d%ac_u%gp s%ac_u%ac_e%gp EOF sed -n -f conftest.hdr confdefs.h > conftest.vals rm -f conftest.hdr # This sed command replaces #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. cat >> conftest.vals <<\EOF s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */% EOF # Break up conftest.vals because some shells have a limit on # the size of here documents, and old seds have small limits too. rm -f conftest.tail while : do ac_lines=`grep -c . conftest.vals` # grep -c gives empty output for an empty file on some AIX systems. if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi # Write a limited-size here document to conftest.frag. echo ' cat > conftest.frag <> $CONFIG_STATUS sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS echo 'CEOF sed -f conftest.frag conftest.in > conftest.out rm -f conftest.in mv conftest.out conftest.in ' >> $CONFIG_STATUS sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail rm -f conftest.vals mv conftest.tail conftest.vals done rm -f conftest.vals cat >> $CONFIG_STATUS <<\EOF rm -f conftest.frag conftest.h echo "/* $ac_file. Generated automatically by configure. */" > conftest.h cat conftest.in >> conftest.h rm -f conftest.in if cmp -s $ac_file conftest.h 2>/dev/null; then echo "$ac_file is unchanged" rm -f conftest.h else # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" fi rm -f $ac_file mv conftest.h $ac_file fi fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 uudeview-0.5.20.orig/uulib/configure.in0000644001167100001440000000516710020740756017771 0ustar cphusers00000000000000dnl This file is an input file used by the GNU "autoconf" program to dnl generate the file "configure", which tries to guess your system dnl configuration so that no manual editing of the Makefile should be dnl necessary dnl dnl $Id: configure.in,v 1.25 2004/03/01 23:06:22 fp Exp $ dnl AC_INIT(uulib.c) AC_PREREQ(2.9) AC_CONFIG_HEADER(config.h) # # package revision # VERSION=0.5 PATCH=20 AC_PROG_CC AC_PROG_CPP wi_PROTOTYPES AC_PROG_MAKE_SET AC_PROG_RANLIB if test "$wi_cv_prototypes" = no ; then AC_WARN([Your compiler does not support function prototyping and]) AC_WARN([is not able to properly compile this package. What a pity.]) AC_WARN([Get gcc, or any compiler that supports function prototypes.]) exit 1 fi # # Checks for header files and library functions # AC_HEADER_STDC AC_TYPE_SIZE_T AC_HEADER_TIME AC_CHECK_HEADERS(fcntl.h unistd.h memory.h malloc.h errno.h) AC_CHECK_HEADERS(io.h sys/time.h) AC_CHECK_FUNCS(gettimeofday) AC_CHECK_FUNC(tempnam,,AC_DEFINE(tempnam,_FP_tempnam)) # # strerror might be internally defined. this would cause a # CHECK_FUNCS(strerror) to fail because it'd be called with # zero arguments. So use our own code. # AC_MSG_CHECKING([for strerror]) AC_TRY_LINK([ char *blubb() { return (char *) strerror (42); } ],[ (void) blubb(); ],have_strerror=yes,AC_DEFINE(strerror,_FP_strerror) have_strerror=no) AC_MSG_RESULT($have_strerror) AC_MSG_CHECKING([for stdin]) AC_TRY_LINK([ #include char *blubb() { FILE *in, *out; in=stdin; out=stdout; return (char*)0; } ],[ (void) blubb(); ],have_stdio=yes,AC_DEFINE(HAVE_STDIO) have_stdio=no) AC_MSG_RESULT($have_stdio) if test "$ac_cv_header_stdc" = "no" ; then AC_CHECK_HEADERS(stdarg.h varargs.h) if test "$ac_cv_header_stdarg_h" = "no" ; then if test "$ac_cv_header_varargs_h" = "no" ; then AC_MSG_ERROR([neither stdarg.h nor varargs.h present]) fi fi fi # # Check whether this is a DOS-Based system. Another bogus test. # Don't even bother to print a message. This code is needed so # that autoheader includes the #undef into the final config.h # and we can change the definition by hand on a really DOS # system (where ./configure doesn't work anyway ...) # if false ; then AC_DEFINE(SYSTEM_DOS) AC_DEFINE(SYSTEM_QUICKWIN) AC_DEFINE(SYSTEM_WINDLL) AC_DEFINE(SYSTEM_OS2) fi # # On some systems (so far, OS2 and WINDOWS), functions that are exported # from a DLL must be declared specifically. # AC_DEFINE_UNQUOTED(UUEXPORT,) AC_DEFINE_UNQUOTED(TOOLEXPORT,) # # set version number # AC_MSG_CHECKING([version number]) version_number="$VERSION"pl"$PATCH" AC_MSG_RESULT($version_number) AC_SUBST(VERSION) AC_SUBST(PATCH) # # done # AC_OUTPUT(Makefile) uudeview-0.5.20.orig/uulib/crc32.c0000644001167100001440000001230207452302262016526 0ustar cphusers00000000000000/* crc32.c -- compute the CRC-32 of a data stream Copyright (C) 1995-1998 Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu */ #include /* ======================================================================== * Table of CRC-32's of all single-byte values (made by make_crc_table) */ static const crc32_t crc_table[256] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; /* ========================================================================= */ #define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); #define DO2(buf) DO1(buf); DO1(buf); #define DO4(buf) DO2(buf); DO2(buf); #define DO8(buf) DO4(buf); DO4(buf); /* ========================================================================= */ crc32_t crc32(crc32_t crc, const unsigned char *buf, unsigned int len) { if (buf == Z_NULL) return 0L; crc = crc ^ 0xffffffffL; while (len >= 8) { DO8(buf); len -= 8; } if (len) do { DO1(buf); } while (--len); return crc ^ 0xffffffffL; } uudeview-0.5.20.orig/uulib/crc32.h0000644001167100001440000000153307452302262016537 0ustar cphusers00000000000000#ifndef __CRC32_H__ #define __CRC32_H__ #ifndef _ANSI_ARGS_ #ifdef PROTOTYPES #define _ANSI_ARGS_(c) c #else #define _ANSI_ARGS_(c) () #endif #endif #ifdef __cplusplus extern "C" { #endif typedef unsigned long crc32_t; #define Z_NULL 0 crc32_t crc32 _ANSI_ARGS_((crc32_t crc, const unsigned char *buf, unsigned int len)); /* Update a running crc with the bytes buf[0..len-1] and return the updated crc. If buf is NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is performed within this function so it shouldn't be done by the application. Usage example: uLong crc = crc32(0L, Z_NULL, 0); while (read_buffer(buffer, length) != EOF) { crc = crc32(crc, buffer, length); } if (crc != original_crc) error(); */ #ifdef __cplusplus } #endif #endif uudeview-0.5.20.orig/uulib/fptools.c0000644001167100001440000002205410016512514017276 0ustar cphusers00000000000000/* * fptools.c, some helper functions for getcgi.c and uu(en|de)view * * Distributed under the terms of the GNU General Public License. * Use and be happy. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif /* * This file provides replacements for some handy functions that aren't * available on all systems, like most of the functions. They * should behave exactly as their counterparts. There are also extensions * that aren't portable at all (like strirstr etc.). * The proper behaviour in a configure script is as follows: * AC_CHECK_FUNC(strrchr,AC_DEFINE(strrchr,_FP_strrchr)) * This way, the (probably less efficient) replacements will only be used * where it is not provided by the default libraries. Be aware that this * does not work with replacements that just shadow wrong behaviour (like * _FP_free) or provide extended functionality (_FP_gets). * The above is not used in the uuenview/uudeview configuration script, * since both only use the replacement functions in non-performance-cri- * tical sections (except for _FP_tempnam and _FP_strerror, where some * functionality of the original would be lost). */ #include #include #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_MEMORY_H #include #endif #include #if 0 #ifdef SYSTEM_WINDLL BOOL _export WINAPI DllEntryPoint (HINSTANCE hInstance, DWORD seginfo, LPVOID lpCmdLine) { /* Don't do anything, so just return true */ return TRUE; } #endif #endif char * fptools_id = "$Id: fptools.c,v 1.8 2004/02/24 00:05:32 fp Exp $"; /* * some versions of free can't handle a NULL pointer properly * (ANSI says, free ignores a NULL pointer, but some machines * prefer to SIGSEGV on it) */ void TOOLEXPORT _FP_free (void *ptr) { if (ptr) free (ptr); } /* * This is non-standard, so I'm defining my own */ char * TOOLEXPORT _FP_strdup (char *string) { char *result; if (string == NULL) return NULL; if ((result = (char *) malloc (strlen (string) + 1)) == NULL) return NULL; strcpy (result, string); return result; } /* * limited-length string copy. this function behaves differently from * the original in that the dest string is always terminated with a * NULL character. */ char * TOOLEXPORT _FP_strncpy (char *dest, char *src, int length) { char *odest=dest; if (src == NULL || dest == NULL || length-- <= 0) return dest; while (length-- && *src) *dest++ = *src++; *dest++ = '\0'; return odest; } /* * duplicate a memory area */ void * TOOLEXPORT _FP_memdup (void *ptr, int len) { void *result; if (ptr == NULL) return NULL; if ((result = malloc (len)) == NULL) return NULL; memcpy (result, ptr, len); return result; } /* * case-insensitive compare */ int TOOLEXPORT _FP_stricmp (char *str1, char *str2) { if (str1==NULL || str2==NULL) return -1; while (*str1) { if (tolower(*str1) != tolower(*str2)) break; str1++; str2++; } return (tolower (*str1) - tolower (*str2)); } int TOOLEXPORT _FP_strnicmp (char *str1, char *str2, int count) { if (str1==NULL || str2==NULL) return -1; while (*str1 && count) { if (tolower(*str1) != tolower(*str2)) break; str1++; str2++; count--; } return count ? (tolower (*str1) - tolower (*str2)) : 0; } /* * autoconf says this function might be a compatibility problem */ char * TOOLEXPORT _FP_strstr (char *str1, char *str2) { char *ptr1, *ptr2; if (str1==NULL) return NULL; if (str2==NULL) return str1; while (*(ptr1=str1)) { for (ptr2=str2; *ptr1 && *ptr2 && *ptr1==*ptr2; ptr1++, ptr2++) /* empty loop */ ; if (*ptr2 == '\0') return str1; str1++; } return NULL; } char * TOOLEXPORT _FP_strpbrk (char *str, char *accept) { char *ptr; if (str == NULL) return NULL; if (accept == NULL || *accept == '\0') return str; for (; *str; str++) for (ptr=accept; *ptr; ptr++) if (*str == *ptr) return str; return NULL; } /* * autoconf also complains about this one */ char * TOOLEXPORT _FP_strtok (char *str1, char *str2) { static char *optr; char *ptr; if (str2 == NULL) return NULL; if (str1) { optr = str1; } else { if (*optr == '\0') return NULL; } while (*optr && strchr (str2, *optr)) /* look for beginning of token */ optr++; if (*optr == '\0') /* no token found */ return NULL; ptr = optr; while (*optr && strchr (str2, *optr) == NULL) /* look for end of token */ optr++; if (*optr) { *optr++ = '\0'; } return ptr; } /* * case insensitive strstr. */ char * TOOLEXPORT _FP_stristr (char *str1, char *str2) { char *ptr1, *ptr2; if (str1==NULL) return NULL; if (str2==NULL) return str1; while (*(ptr1=str1)) { for (ptr2=str2; *ptr1 && *ptr2 && tolower(*ptr1)==tolower(*ptr2); ptr1++, ptr2++) /* empty loop */ ; if (*ptr2 == '\0') return str1; str1++; } return NULL; } /* * Nice fake of the real (non-standard) one */ char * TOOLEXPORT _FP_strrstr (char *ptr, char *str) { char *found=NULL, *new, *iter=ptr; if (ptr==NULL || str==NULL) return NULL; if (*str == '\0') return ptr; while ((new = _FP_strstr (iter, str)) != NULL) { found = new; iter = new + 1; } return found; } char * TOOLEXPORT _FP_strirstr (char *ptr, char *str) { char *found=NULL, *iter=ptr, *new; if (ptr==NULL || str==NULL) return NULL; if (*str == '\0') return ptr; while ((new = _FP_stristr (iter, str)) != NULL) { found = new; iter = new + 1; } return found; } /* * convert whole string to case */ char * TOOLEXPORT _FP_stoupper (char *input) { char *iter = input; if (input == NULL) return NULL; while (*iter) { *iter = toupper (*iter); iter++; } return input; } char * TOOLEXPORT _FP_stolower (char *input) { char *iter = input; if (input == NULL) return NULL; while (*iter) { *iter = tolower (*iter); iter++; } return input; } /* * string matching with wildcards */ int TOOLEXPORT _FP_strmatch (char *string, char *pattern) { char *p1 = string, *p2 = pattern; if (pattern==NULL || string==NULL) return 0; while (*p1 && *p2) { if (*p2 == '?') { p1++; p2++; } else if (*p2 == '*') { if (*++p2 == '\0') return 1; while (*p1 && *p1 != *p2) p1++; } else if (*p1 == *p2) { p1++; p2++; } else return 0; } if (*p1 || *p2) return 0; return 1; } char * TOOLEXPORT _FP_strrchr (char *string, int tc) { char *ptr; if (string == NULL || !*string) return NULL; ptr = string + strlen (string) - 1; while (ptr != string && *ptr != tc) ptr--; if (*ptr == tc) return ptr; return NULL; } /* * strip directory information from a filename. Works only on DOS and * Unix systems so far ... */ char * TOOLEXPORT _FP_cutdir (char *filename) { char *ptr; if (filename == NULL) return NULL; if ((ptr = _FP_strrchr (filename, '/')) != NULL) ptr++; else if ((ptr = _FP_strrchr (filename, '\\')) != NULL) ptr++; else ptr = filename; return ptr; } /* * My own fgets function. It handles all kinds of line terminators * properly: LF (Unix), CRLF (DOS) and CR (Mac). In all cases, the * terminator is replaced by a single LF */ char * TOOLEXPORT _FP_fgets (char *buf, int n, FILE *stream) { char *obp = buf; int c; if (feof (stream)) return NULL; while (--n && !feof (stream)) { if ((c = fgetc (stream)) == EOF) { if (ferror (stream)) return NULL; else { if (obp == buf) return NULL; *buf = '\0'; return obp; } } if (c == '\015') { /* CR */ /* * Peek next character. If it's no LF, push it back. * ungetc(EOF, stream) is handled correctly according * to the manual page */ if ((c = fgetc (stream)) != '\012') if (!feof (stream)) ungetc (c, stream); *buf++ = '\012'; *buf = '\0'; return obp; } else if (c == '\012') { /* LF */ *buf++ = '\012'; *buf = '\0'; return obp; } /* * just another standard character */ *buf++ = c; } /* * n-1 characters already transferred */ *buf = '\0'; /* * If a line break is coming up, read it */ if (!feof (stream)) { if ((c = fgetc (stream)) == '\015' && !feof (stream)) { if ((c = fgetc (stream)) != '\012' && !feof (stream)) { ungetc (c, stream); } } else if (c != '\012' && !feof (stream)) { ungetc (c, stream); } } return obp; } /* * A replacement strerror function that just returns the error code */ char * TOOLEXPORT _FP_strerror (int errcode) { static char number[8]; sprintf (number, "%03d", errcode); return number; } /* * tempnam is not ANSI, but tmpnam is. Ignore the prefix here. */ char * TOOLEXPORT _FP_tempnam (char *dir, char *pfx) { return _FP_strdup (tmpnam (NULL)); } uudeview-0.5.20.orig/uulib/fptools.h0000644001167100001440000000351007307472273017317 0ustar cphusers00000000000000/* * fptools.c, some helper functions for getcgi.c and uu(en|de)view * * Distributed under the terms of the GNU General Public License. * Use and be happy. */ /* * Some handy, nonstandard functions. Note that the original may * be both faster and better. ``better'', if your compiler allows * cleaner use of such functions by proper use of ``const''. * * $Id: fptools.h,v 1.4 2001/06/06 18:21:47 fp Exp $ */ #ifndef __FPTOOLS_H__ #define __FPTOOLS_H__ #ifndef _ANSI_ARGS_ #ifdef PROTOTYPES #define _ANSI_ARGS_(c) c #else #define _ANSI_ARGS_(c) () #endif #endif #ifndef TOOLEXPORT #define TOOLEXPORT #endif #ifdef __cplusplus extern "C" { #endif void TOOLEXPORT _FP_free _ANSI_ARGS_((void *)); char * TOOLEXPORT _FP_strdup _ANSI_ARGS_((char *)); char * TOOLEXPORT _FP_strncpy _ANSI_ARGS_((char *, char *, int)); void * TOOLEXPORT _FP_memdup _ANSI_ARGS_((void *, int)); int TOOLEXPORT _FP_stricmp _ANSI_ARGS_((char *, char *)); int TOOLEXPORT _FP_strnicmp _ANSI_ARGS_((char *, char *, int)); char * TOOLEXPORT _FP_strrstr _ANSI_ARGS_((char *, char *)); char * TOOLEXPORT _FP_stoupper _ANSI_ARGS_((char *)); char * TOOLEXPORT _FP_stolower _ANSI_ARGS_((char *)); int TOOLEXPORT _FP_strmatch _ANSI_ARGS_((char *, char *)); char * TOOLEXPORT _FP_strstr _ANSI_ARGS_((char *, char *)); char * TOOLEXPORT _FP_stristr _ANSI_ARGS_((char *, char *)); char * TOOLEXPORT _FP_strirstr _ANSI_ARGS_((char *, char *)); char * TOOLEXPORT _FP_strrchr _ANSI_ARGS_((char *, int)); char * TOOLEXPORT _FP_fgets _ANSI_ARGS_((char *, int, FILE *)); char * TOOLEXPORT _FP_strpbrk _ANSI_ARGS_((char *, char *)); char * TOOLEXPORT _FP_strtok _ANSI_ARGS_((char *, char *)); char * TOOLEXPORT _FP_cutdir _ANSI_ARGS_((char *)); char * TOOLEXPORT _FP_strerror _ANSI_ARGS_((int)); char * TOOLEXPORT _FP_tempnam _ANSI_ARGS_((char *, char *)); #ifdef __cplusplus } #endif #endif uudeview-0.5.20.orig/uulib/uucheck.c0000644001167100001440000011003207646302503017243 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif /* * uucheck.c * * Various checking and processing of one input part **/ #include #include #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_MALLOC_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_MEMORY_H #include #endif #include #include #include #include char * uucheck_id = "$Id: uucheck.c,v 1.15 2003/04/13 15:41:55 fp Exp $"; /* * Arbitrary number. This is the maximum number of part numbers we * store for our have-parts and missing-parts lists */ #define MAXPLIST 256 /* * forward declarations of local functions */ static char * UUGetFileName _ANSI_ARGS_((char *, char *, char *)); static int UUGetPartNo _ANSI_ARGS_((char *, char **, char **)); /* * State of Scanner function and PreProcessPart */ int lastvalid, lastenc, nofnum; char *uucheck_lastname; char *uucheck_tempname; static int lastpart = 0; static char *nofname = "UNKNOWN"; /* * special characters we allow an unquoted filename to have */ static char *fnchars = "._-~!"; /* * Policy for extracting a part number from the subject line. * usually, look for part numbers in () brackets first, then in [] */ static char *brackchr[] = { "()[]", "[]()" }; /* * Extract a filename from the subject line. We need anything to identify * the name of the program for sorting. If a nice filename cannot be found, * the subject line itself is used * ptonum is, if not NULL, a pointer to the part number in the subject line, * so that it won't be used as filename. **/ static char * UUGetFileName (char *subject, char *ptonum, char *ptonend) { char *ptr = subject, *iter, *result, *part; int count, length=0, alflag=0; /* * If this file has no subject line, assume it is the next part of the * previous file (this is done in UUPreProcessPart) **/ if (subject == NULL) return NULL; /* * If the subject starts with 'Re', it is ignored * REPosts or RETries are not ignored! **/ if (uu_ignreply && (subject[0] == 'R' || subject[0] == 'r') && (subject[1] == 'E' || subject[1] == 'e') && (subject[2] == ':' || subject[2] == ' ')) { return NULL; } /* * Ignore a "Repost" prefix of the subject line. We don't want to get * a file named "Repost" :-) **/ if (_FP_strnicmp (subject, "repost", 6) == 0) subject += 6; if (_FP_strnicmp (subject, "re:", 3) == 0) subject += 3; while (*subject == ' ' || *subject == ':') subject++; part = _FP_stristr (subject, "part"); if (part == subject) { subject += 4; while (*subject == ' ') subject++; } /* * If the file was encoded by uuenview, then the filename is enclosed * in [brackets]. But check what's inside these bracket's, try not to * fall for something other than a filename */ ptr = subject; while ((iter = strchr (ptr, '[')) != NULL) { if (strchr (iter, ']') == NULL) { ptr = iter + 1; continue; } iter++; while (isspace (*iter)) iter++; count = length = alflag = 0; while (iter[count] && (isalnum (iter[count]) || strchr (fnchars, iter[count])!=NULL)) { if (isalpha (iter[count])) alflag++; count++; } if (count<4 || alflag==0) { ptr = iter + 1; continue; } length = count; while (isspace (iter[count])) count++; if (iter[count] == ']') { ptr = iter; break; } length = 0; ptr = iter + 1; } /* * new filename detection routine, fists mostly for files by ftp-by-email * servers that create subject lines with ftp.host.address:/full/path/file * on them. We look for slashes and take the filename from after the last * one ... or at least we try to. */ if (length == 0) { ptr = subject; while ((iter = strchr (ptr, '/')) != NULL) { if (iter >= ptonum && iter <= ptonend) { ptr = iter + 1; continue; } count = length = 0; iter++; while (iter[count] && (isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL)) count++; if (iter[count] == ' ' && length > 4) { length = count; break; } ptr = iter + ((count)?count:1); } } /* * Look for two alphanumeric strings separated by a '.' * (That's most likely a filename) **/ if (length == 0) { ptr = subject; while (*ptr && *ptr != 0x0a && *ptr != 0x0d && ptr != part) { iter = ptr; count = length = alflag = 0; if (_FP_strnicmp (ptr, "ftp", 3) == 0) { /* hey, that's an ftp address */ while (isalpha (*ptr) || isdigit (*ptr) || *ptr == '.') ptr++; continue; } while ((isalnum(*iter)||strchr(fnchars, *iter)!=NULL|| *iter=='/') && *iter && iter != ptonum && *iter != '.') { if (isalpha (*iter)) alflag = 1; count++; iter++; } if (*iter == '\0' || iter == ptonum) { if (iter == ptonum) ptr = ptonend; else ptr = iter; length = 0; continue; } if (*iter++ != '.' || count > 32 || alflag == 0) { ptr = iter; length = 0; continue; } if (_FP_strnicmp (iter, "edu", 3) == 0 || _FP_strnicmp (iter, "gov", 3) == 0) { /* hey, that's an ftp address */ while (isalpha (*iter) || isdigit (*iter) || *iter == '.') iter++; ptr = iter; length = 0; continue; } length += count + 1; count = 0; while ((isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL|| iter[count]=='/') && iter[count] && iter[count] != '.') count++; if (iter[count]==':' && iter[count+1]=='/') { /* looks like stuff from a mail server */ ptr = iter + 1; length = 0; continue; } if (count > 8 || iter == ptonum) { ptr = iter; length = 0; continue; } if (iter[count] != '.') { length += count; break; } while (iter[count] && (isalnum(iter[count])||strchr(fnchars, iter[count])!=NULL|| iter[count]=='/')) count++; if (iter[count]==':' && iter[count+1]=='/') { /* looks like stuff from a mail server */ ptr = iter + 1; length = 0; continue; } if (count < 12 && iter != ptonum) { length += count; break; } ptr = iter; length = 0; } } if (length == 0) { /* No filename found, use subject line for ident */ ptr = subject; while (*ptr && !isalpha (*ptr)) ptr++; while ((isalnum(ptr[length])||strchr(fnchars,ptr[length])!=NULL|| ptr[length] == '/') && ptr[length] && ptr+length!=part && ptr+length!=ptonum) length++; if (length) { if (ptr[length] == '\0' || ptr[length] == 0x0a || ptr[length] == 0x0d) { length--; /* * I used to cut off digits from the end of the string, but * let's try to live without. We want to distinguish * DUTCH951 from DUTCH952 * * while ((ptr[length] == ' ' || isdigit (ptr[length])) && length > 0) * length--; */ } else { length--; while (ptr[length] == ' ' && length > 0) length--; } length++; } } if (length == 0) { /* Still found nothing? We need *something*! */ ptr = nofname; length = strlen (nofname); } if ((result = (char *) malloc (length + 1)) == NULL) { UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), length+1); return NULL; } memcpy (result, ptr, length); result[length] = '\0'; return result; } /* * Extract the Part Number from the subject line. * We look first for numbers in (#/#)'s, then for numbers in [#/#]'s * and then for digits that are not part of a string. * If we cannot find anything, assume it is the next part of the * previous file. * If we find a part number, we put a pointer to it in *where. This is * done so that the UUGetFileName function doesn't accidentally use the * part number as the file name. *whend points to the end of this part * number. **/ static int UUGetPartNo (char *subject, char **where, char **whend) { char *ptr = subject, *iter, *delim, bdel[2]=" "; int count, length=0, bpc; *where = NULL; bdel[0] = ' '; *whend = NULL; bdel[1] = '\0'; iter = NULL; delim = ""; if (subject == NULL) return -1; if (uu_ignreply && (subject[0] == 'R' || subject[0] == 'r') && /* Ignore replies, but not */ (subject[1] == 'E' || subject[1] == 'e') && /* reposts */ (subject[2] == ':' || subject[2] == ' ')) return -2; /* * First try numbers in () or [] (or vice versa, according to bracket * policy) */ for (bpc=0, length=0; brackchr[uu_bracket_policy][bpc]; bpc+=2) { ptr = subject; while ((iter = strchr (ptr, brackchr[uu_bracket_policy][bpc])) != NULL) { count = length = 0; iter++; while (*iter == ' ' || *iter == '#') iter++; if (!isdigit (*iter)) { ptr = iter; continue; } while (isdigit (iter[count])) count++; length = count; if (iter[count] == '\0' || iter[count+1] == '\0') { iter += count; length = 0; break; } if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) { *where = iter; bdel[0] = brackchr[uu_bracket_policy][bpc+1]; delim = bdel; break; } while (iter[count] == ' ' || iter[count] == '#' || iter[count] == '/' || iter[count] == '\\') count++; if (_FP_strnicmp (iter + count, "of", 2) == 0) count += 2; while (iter[count] == ' ') count++; while (isdigit (iter[count])) count++; while (iter[count] == ' ') count++; if (iter[count] == brackchr[uu_bracket_policy][bpc+1]) { *where = iter; bdel[0] = brackchr[uu_bracket_policy][bpc+1]; delim = bdel; break; } length = 0; ptr = iter; } if (length) break; } /* * look for the string "part " followed by a number */ if (length == 0) { if ((iter = _FP_stristr (subject, "part ")) != NULL) { iter += 5; while (isspace (*iter) || *iter == '.' || *iter == '-') iter++; while (isdigit (iter[length])) length++; if (length == 0) { if (_FP_strnicmp (iter, "one", 3) == 0) length = 1; else if (_FP_strnicmp (iter, "two", 3) == 0) length = 2; else if (_FP_strnicmp (iter, "three", 5) == 0) length = 3; else if (_FP_strnicmp (iter, "four", 4) == 0) length = 4; else if (_FP_strnicmp (iter, "five", 4) == 0) length = 5; else if (_FP_strnicmp (iter, "six", 3) == 0) length = 6; else if (_FP_strnicmp (iter, "seven", 5) == 0) length = 7; else if (_FP_strnicmp (iter, "eight", 5) == 0) length = 8; else if (_FP_strnicmp (iter, "nine", 4) == 0) length = 9; else if (_FP_strnicmp (iter, "ten", 3) == 0) length = 10; if (length && (*whend = strchr (iter, ' '))) { *where = iter; return length; } else length = 0; } else { *where = iter; delim = "of"; } } } /* * look for the string "part" followed by a number */ if (length == 0) { if ((iter = _FP_stristr (subject, "part")) != NULL) { iter += 4; while (isspace (*iter) || *iter == '.' || *iter == '-') iter++; while (isdigit (iter[length])) length++; if (length == 0) { if (_FP_strnicmp (iter, "one", 3) == 0) length = 1; else if (_FP_strnicmp (iter, "two", 3) == 0) length = 2; else if (_FP_strnicmp (iter, "three", 5) == 0) length = 3; else if (_FP_strnicmp (iter, "four", 4) == 0) length = 4; else if (_FP_strnicmp (iter, "five", 4) == 0) length = 5; else if (_FP_strnicmp (iter, "six", 3) == 0) length = 6; else if (_FP_strnicmp (iter, "seven", 5) == 0) length = 7; else if (_FP_strnicmp (iter, "eight", 5) == 0) length = 8; else if (_FP_strnicmp (iter, "nine", 4) == 0) length = 9; else if (_FP_strnicmp (iter, "ten", 3) == 0) length = 10; if (length && (*whend = strchr (iter, ' '))) { *where = iter; return length; } else length = 0; } else { *where = iter; delim = "of"; } } } /* * look for [0-9]* "of" [0-9]* */ if (length == 0) { if ((iter = _FP_strirstr (subject, "of")) != NULL) { while (iter>subject && isspace (*(iter-1))) iter--; if (isdigit(*(iter-1))) { while (iter>subject && isdigit (*(iter-1))) iter--; if (!isdigit (*iter) && !isalpha (*iter) && *iter != '.') iter++; ptr = iter; while (isdigit (*ptr)) { ptr++; length++; } *where = iter; delim = "of"; } } } /* * look for whitespace-separated (or '/'-separated) digits */ if (length == 0) { ptr = subject; while (*ptr && length==0) { while (*ptr && !isdigit (*ptr)) ptr++; if (isdigit (*ptr) && (ptr==subject || *ptr==' ' || *ptr=='/')) { while (isdigit (ptr[length])) length++; if (ptr[length]!='\0' && ptr[length]!=' ' && ptr[length]!='/') { ptr += length; length = 0; } else { iter = ptr; bdel[0] = ptr[length]; delim = bdel; } } else { while (isdigit (*ptr)) ptr++; } } } /* * look for _any_ digits -- currently disabled, because it also fell * for "part numbers" in file names */ #if 0 if (length == 0) { count = strlen(subject) - 1; ptr = subject; while (count > 0) { if (!isdigit(ptr[count])||isalpha(ptr[count+1])||ptr[count+1] == '.') { count--; continue; } length = 0; while (count >= 0 && isdigit (ptr[count])) { count--; length++; } if (count>=0 && ((isalpha (ptr[count]) && (ptr[count] != 's' || ptr[count+1] != 't') && (ptr[count] != 'n' || ptr[count+1] != 'd')) || ptr[count] == '/' || ptr[count] == '.' || ptr[count] == '-' || ptr[count] == '_')) { length = 0; continue; } count++; iter = ptr + count; if (length > 4) { length = 0; continue; } *where = iter; delim = "of"; break; } } #endif /* * look for part numbering as string */ if (length == 0) { /* * some people use the strangest things, including spelling mistakes :-) */ if ((iter = _FP_stristr (subject, "first")) != NULL) length = 1; else if ((iter = _FP_stristr (subject, "second")) != NULL) length = 2; else if ((iter = _FP_stristr (subject, "third")) != NULL) length = 3; else if ((iter = _FP_stristr (subject, "forth")) != NULL) length = 4; else if ((iter = _FP_stristr (subject, "fourth")) != NULL) length = 4; else if ((iter = _FP_stristr (subject, "fifth")) != NULL) length = 5; else if ((iter = _FP_stristr (subject, "sixth")) != NULL) length = 6; else if ((iter = _FP_stristr (subject, "seventh")) != NULL) length = 7; else if ((iter = _FP_stristr (subject, "eigth")) != NULL) length = 8; else if ((iter = _FP_stristr (subject, "nineth")) != NULL) length = 9; else if ((iter = _FP_stristr (subject, "ninth")) != NULL) length = 9; else if ((iter = _FP_stristr (subject, "tenth")) != NULL) length = 10; else iter = NULL; if (length && iter && (*whend = strchr (iter, ' '))) { *where = iter; return length; } else length = 0; } if (iter == NULL || length == 0) /* should be equivalent */ return -1; *where = iter; if (delim && delim[0]) { if ((*whend=_FP_stristr (iter, delim)) != NULL && (*whend - *where) < 12) { ptr = (*whend += strlen (delim)); while (*ptr == ' ') ptr++; if (isdigit (*ptr)) { *whend = ptr; while (isdigit (**whend)) *whend += 1; } } else { *whend = iter + length; } } else { *whend = iter + length; } return atoi (iter); } /* * Obtain and process some information about the data. **/ uufile * UUPreProcessPart (fileread *data, int *ret) { char *where, *whend, temp[80], *ptr, *p2; uufile *result; if ((result = (uufile *) malloc (sizeof (uufile))) == NULL) { UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), sizeof (uufile)); *ret = UURET_NOMEM; return NULL; } memset (result, 0, sizeof (uufile)); if (data->partno) { where = whend = NULL; result->partno = data->partno; } else if (uu_dumbness) { result->partno = -1; where = whend = NULL; } else if ((result->partno=UUGetPartNo(data->subject,&where,&whend)) == -2) { *ret = UURET_NODATA; UUkillfile (result); return NULL; } if (data->filename != NULL) { if ((result->filename = _FP_strdup (data->filename)) == NULL) { UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), strlen (data->filename)+1); *ret = UURET_NOMEM; UUkillfile (result); return NULL; } } else result->filename = NULL; if (uu_dumbness <= 1) result->subfname = UUGetFileName (data->subject, where, whend); else result->subfname = NULL; result->mimeid = _FP_strdup (data->mimeid); result->mimetype = _FP_strdup (data->mimetype); if (result->partno == -1 && (data->uudet == PT_ENCODED || data->uudet == QP_ENCODED)) result->partno = 1; if (data->flags & FL_SINGLE) { /* * Don't touch this part. But it should really have a filename */ if (result->filename == NULL) { sprintf (temp, "%s.%03d", nofname, ++nofnum); result->filename = _FP_strdup (temp); } if (result->subfname == NULL) result->subfname = _FP_strdup (result->filename); if (result->filename == NULL || result->subfname == NULL) { UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), (result->filename==NULL)? (strlen(temp)+1):(strlen(result->filename)+1)); *ret = UURET_NOMEM; UUkillfile(result); return NULL; } if (result->partno == -1) result->partno = 1; } else if (result->subfname == NULL && data->uudet && (data->begin || result->partno == 1 || (!uu_dumbness && result->partno == -1 && (data->subject != NULL || result->filename != NULL)))) { /* * If it's the first part of something and has some valid data, but * no subject or anything, initialize lastvalid */ /* * in this case, it really _should_ have a filename somewhere */ if (result->filename != NULL && *result->filename) result->subfname = _FP_strdup (result->filename); else { /* if not, escape to UNKNOWN. We need to fill subfname */ sprintf (temp, "%s.%03d", nofname, ++nofnum); result->subfname = _FP_strdup (temp); } /* * in case the strdup failed */ if (result->subfname == NULL) { UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), (result->filename)? (strlen(result->filename)+1):(strlen(temp)+1)); *ret = UURET_NOMEM; UUkillfile (result); return NULL; } /* * if it's also got an 'end', or is the last part in a MIME-Mail, * then don't set lastvalid */ if (!data->end && (!data->partno || data->partno != data->maxpno)) { /* * initialize lastvalid */ lastvalid = 1; lastenc = data->uudet; lastpart = result->partno = 1; _FP_strncpy (uucheck_lastname, result->subfname, 256); } else result->partno = 1; } else if (result->subfname == NULL && data->uudet && data->mimeid) { /* * if it's got a file name, use it. Else use the mime-id for identifying * this part, and hope there's no other files encoded in the same message * under the same id. */ if (result->filename) result->subfname = _FP_strdup (result->filename); else result->subfname = _FP_strdup (result->mimeid); } else if (result->subfname == NULL && data->uudet) { /* * ff we have lastvalid, use it. Make an exception for * Base64-encoded files. */ if (data->uudet == B64ENCODED) { /* * Assume it's the first part. I wonder why it's got no part number? */ if (result->filename != NULL && *result->filename) result->subfname = _FP_strdup (result->filename); else { /* if not, escape to UNKNOWN. We need to fill subfname */ sprintf (temp, "%s.%03d", nofname, ++nofnum); result->subfname = _FP_strdup (temp); } if (result->subfname == NULL) { UUMessage (uucheck_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), (result->filename)? (strlen(result->filename)+1):(strlen(temp)+1)); *ret = UURET_NOMEM; UUkillfile (result); return NULL; } lastvalid = 0; } else if (lastvalid && data->uudet == lastenc && result->partno == -1) { result->subfname = _FP_strdup (uucheck_lastname); result->partno = ++lastpart; /* * if it's the last part, invalidate lastvalid */ if (data->end || (data->partno && data->partno == data->maxpno)) lastvalid = 0; } else if (data->partno != -1 && result->filename) { result->subfname = _FP_strdup (result->filename); } else { /* * it's got no info, it's got no begin, and we don't know anything * about this part. Let's forget all about it. */ *ret = UURET_NODATA; UUkillfile (result); return NULL; } } else if (result->subfname == NULL && result->partno == -1) { /* * This, too, is a part without any useful information that we * should forget about. */ *ret = UURET_NODATA; UUkillfile (result); return NULL; } else if (result->subfname == NULL) { /* * This is a part without useful subject name, a valid part number * but no encoded data. It *could* be the zeroeth part of something, * but we don't care here. Just forget it. */ *ret = UURET_NODATA; UUkillfile (result); return NULL; } /* * now, handle some cases where we have a useful subject but no * useful part number */ if (result->partno == -1 && data->begin) { /* * hmm, this is reason enough to initialize lastvalid, at least * if we have no end */ if (!data->end) { _FP_strncpy (uucheck_lastname, result->subfname, 256); result->partno = lastpart = 1; lastenc = data->uudet; lastvalid = 1; } else result->partno = 1; } else if (result->partno == -1 && data->uudet) { if (lastvalid && _FP_stricmp (uucheck_lastname, result->subfname) == 0) { /* * if the subject filename is the same as last time, use part no * of lastvalid. If at end, invalidate lastvalid */ result->partno = ++lastpart; if (data->end) lastvalid = 0; } else { /* * data but no part no. It's something UUInsertPartToList() should * handle */ goto skipcheck; } } else if (result->partno == -1) { /* * it's got no data, so why should we need this one anyway? */ *ret = UURET_NODATA; UUkillfile (result); return NULL; } /* * at this point, the part should have a valid subfname and a valid * part number. If it doesn't, then fail. */ if (result->subfname == NULL || result->partno == -1) { *ret = UURET_NODATA; UUkillfile (result); return NULL; } skipcheck: if (result->filename) { if (*(ptr = _FP_cutdir (result->filename))) { p2 = _FP_strdup (ptr); _FP_free (result->filename); result->filename = p2; } } result->data = data; result->NEXT = NULL; *ret = UURET_OK; return result; } /* * Insert one part of a file into the global list **/ int UUInsertPartToList (uufile *data) { uulist *iter = UUGlobalFileList, *unew; uufile *fiter, *last; /* * Part belongs together, if * (1) The MIME-IDs match, or * (2) The file name received from the subject lines match, and * (a) Not both parts have a begin line * (b) Not both parts have an end line * (c) Both parts don't have different MIME-IDs * (d) Both parts don't encode different files * (e) The other part wants to stay alone (FL_SINGLE) */ /* * check if this part wants to be left alone. If so, don't bother * to do all the checks */ while (iter) { if (data->data->flags & FL_SINGLE) { /* this space intentionally left blank */ } else if ((data->mimeid && iter->mimeid && strcmp (data->mimeid, iter->mimeid) == 0) || (_FP_stricmp (data->subfname, iter->subfname) == 0 && !(iter->begin && data->data->begin) && !(iter->end && data->data->end) && !(data->mimeid && iter->mimeid && strcmp (data->mimeid, iter->mimeid) != 0) && !(data->filename && iter->filename && strcmp (data->filename, iter->filename) != 0) && !(iter->flags & FL_SINGLE))) { /* * Don't insert a part that is already there. * * Also don't add a part beyond the "end" marker (unless we * have a mimeid, which screws up the marker). */ for (fiter=iter->thisfile; fiter; fiter=fiter->NEXT) { if (data->partno == fiter->partno) goto goahead; if (!iter->mimeid) { if (data->partno > fiter->partno && fiter->data->end) { goto goahead; } } } if (iter->filename == NULL && data->filename != NULL) { if ((iter->filename = _FP_strdup (data->filename)) == NULL) return UURET_NOMEM; } /* * special case when we might have tagged a part as Base64 when the * file was really XX */ if (data->data->uudet == B64ENCODED && iter->uudet == XX_ENCODED && iter->begin) { data->data->uudet = XX_ENCODED; } else if (data->data->uudet == XX_ENCODED && data->data->begin && iter->uudet == B64ENCODED) { iter->uudet = XX_ENCODED; fiter = iter->thisfile; while (fiter) { fiter->data->uudet = XX_ENCODED; fiter = fiter->NEXT; } } /* * If this is from a Message/Partial, we believe only the * iter->uudet from the first part */ if (data->data->flags & FL_PARTIAL) { if (data->partno == 1) { iter->uudet = data->data->uudet; iter->flags = data->data->flags; } } else { if (data->data->uudet) iter->uudet = data->data->uudet; if (data->data->flags) iter->flags = data->data->flags; } if (iter->mode == 0 && data->data->mode != 0) iter->mode = data->data->mode; if (data->data->begin) iter->begin = (data->partno)?data->partno:1; if (data->data->end) iter->end = (data->partno)?data->partno:1; if (data->mimetype) { _FP_free (iter->mimetype); iter->mimetype = _FP_strdup (data->mimetype); } /* * insert part at the beginning */ if (data->partno != -1 && data->partno < iter->thisfile->partno) { iter->state = UUFILE_READ; data->NEXT = iter->thisfile; iter->thisfile = data; return UURET_OK; } /* * insert part somewhere else */ iter->state = UUFILE_READ; /* prepare for re-checking */ fiter = iter->thisfile; last = NULL; while (fiter) { /* * if we find the same part no again, check which one looks better */ if (data->partno == fiter->partno) { if (fiter->data->subject == NULL) return UURET_NODATA; else if (_FP_stristr (fiter->data->subject, "repost") != NULL && _FP_stristr (data->data->subject, "repost") == NULL) return UURET_NODATA; else if (fiter->data->uudet && !data->data->uudet) return UURET_NODATA; else { /* * replace */ data->NEXT = fiter->NEXT; fiter->NEXT = NULL; UUkillfile (fiter); if (last == NULL) iter->thisfile = data; else last->NEXT = data; return UURET_OK; } } /* * if at the end of the part list, add it */ if (fiter->NEXT == NULL || (data->partno != -1 && data->partno < fiter->NEXT->partno)) { data->NEXT = fiter->NEXT; fiter->NEXT = data; if (data->partno == -1) data->partno = fiter->partno + 1; return UURET_OK; } last = fiter; fiter = fiter->NEXT; } return UURET_OK; /* Shouldn't get here */ } goahead: /* * we need iter below */ if (iter->NEXT == NULL) break; iter = iter->NEXT; } /* * handle new entry */ if (data->partno == -1) { /* * if it's got no part no, and it's MIME mail, then assume this is * part no. 1. If it's not MIME, then we can't handle it; if it * had a 'begin', it'd have got a part number assigned by * UUPreProcessPart(). */ if (data->data->uudet == B64ENCODED || data->data->uudet == BH_ENCODED) data->partno = 1; else return UURET_NODATA; } if ((unew = (uulist *) malloc (sizeof (uulist))) == NULL) { return UURET_NOMEM; } if ((unew->subfname = _FP_strdup (data->subfname)) == NULL) { _FP_free (unew); return UURET_NOMEM; } if (data->filename != NULL) { if ((unew->filename = _FP_strdup (data->filename)) == NULL) { _FP_free (unew->subfname); _FP_free (unew); return UURET_NOMEM; } } else unew->filename = NULL; if (data->mimeid != NULL) { if ((unew->mimeid = _FP_strdup (data->mimeid)) == NULL) { _FP_free (unew->subfname); _FP_free (unew->filename); _FP_free (unew); return UURET_NOMEM; } } else unew->mimeid = NULL; if (data->mimetype != NULL) { if ((unew->mimetype = _FP_strdup (data->mimetype)) == NULL) { _FP_free (unew->mimeid); _FP_free (unew->subfname); _FP_free (unew->filename); _FP_free (unew); return UURET_NOMEM; } } else unew->mimetype = NULL; unew->state = UUFILE_READ; unew->binfile = NULL; unew->thisfile = data; unew->mode = data->data->mode; unew->uudet = data->data->uudet; unew->flags = data->data->flags; unew->begin = (data->data->begin) ? ((data->partno)?data->partno:1) : 0; unew->end = (data->data->end) ? ((data->partno)?data->partno:1) : 0; unew->misparts = NULL; unew->haveparts = NULL; unew->NEXT = NULL; if (iter == NULL) UUGlobalFileList = unew; else iter->NEXT = unew; return UURET_OK; } /* * At this point, all files are read in and stored in the * "UUGlobalFileList". Do some checking. All parts there? **/ uulist * UUCheckGlobalList (void) { int misparts[MAXPLIST], haveparts[MAXPLIST]; int miscount, havecount, count, flag, part; uulist *liter=UUGlobalFileList, *prev; uufile *fiter; long thesize; while (liter) { miscount = 0; thesize = 0; if (liter->state & UUFILE_OK) { liter = liter->NEXT; continue; } else if ((liter->uudet == QP_ENCODED || liter->uudet == PT_ENCODED) && (liter->flags & FL_SINGLE)) { if ((liter->flags&FL_PROPER)==0) liter->size = -1; else liter->size = liter->thisfile->data->length; liter->state = UUFILE_OK; continue; } else if ((fiter = liter->thisfile) == NULL) { liter->state = UUFILE_NODATA; liter = liter->NEXT; continue; } /* * Re-Check this file */ flag = 0; miscount = 0; havecount = 0; thesize = 0; liter->state = UUFILE_READ; /* * search encoded data */ while (fiter && !fiter->data->uudet) { if (havecountpartno; } fiter = fiter->NEXT; } if (fiter == NULL) { liter->state = UUFILE_NODATA; liter = liter->NEXT; continue; } if (havecountpartno; } if ((part = fiter->partno) > 1) { if (!fiter->data->begin) { for (count=1; count < part && miscount < MAXPLIST; count++) misparts[miscount++] = count; } } /* * don't care if so many parts are missing */ if (miscount >= MAXPLIST) { liter->state = UUFILE_MISPART; liter = liter->NEXT; continue; } if (liter->uudet == B64ENCODED || liter->uudet == QP_ENCODED || liter->uudet == PT_ENCODED) flag |= 3; /* Don't need begin or end with Base64 or plain text*/ if (fiter->data->begin) flag |= 1; if (fiter->data->end) flag |= 2; if (fiter->data->uudet) flag |= 4; /* * guess size of part */ switch (fiter->data->uudet) { case UU_ENCODED: case XX_ENCODED: thesize += 3*fiter->data->length/4; thesize -= 3*fiter->data->length/124; /* substract 2 of 62 chars */ break; case B64ENCODED: thesize += 3*fiter->data->length/4; thesize -= fiter->data->length/52; /* substract 2 of 78 chars */ break; case QP_ENCODED: case PT_ENCODED: thesize += fiter->data->length; break; } fiter = fiter->NEXT; while (fiter != NULL) { for (count=part+1; countpartno && miscountpartno; if (havecountdata->begin) flag |= 1; if (fiter->data->end) flag |= 2; if (fiter->data->uudet) flag |= 4; switch (fiter->data->uudet) { case UU_ENCODED: case XX_ENCODED: thesize += 3*fiter->data->length/4; thesize -= 3*fiter->data->length/124; /* substract 2 of 62 chars */ break; case B64ENCODED: thesize += 3*fiter->data->length/4; thesize -= fiter->data->length/52; /* substract 2 of 78 chars */ break; case QP_ENCODED: case PT_ENCODED: thesize += fiter->data->length; break; } if (fiter->data->end) break; fiter = fiter->NEXT; } /* * if in fast mode, we don't notice an 'end'. So if its uu or xx * encoded, there's a begin line and encoded data, assume it's * there. */ if (uu_fast_scanning && (flag & 0x01) && (flag & 0x04) && (liter->uudet == UU_ENCODED || liter->uudet == XX_ENCODED)) flag |= 2; /* * Set the parts we have and/or missing */ _FP_free (liter->haveparts); _FP_free (liter->misparts); liter->haveparts = NULL; liter->misparts = NULL; if (havecount) { if ((liter->haveparts=(int*)malloc((havecount+1)*sizeof(int)))!=NULL) { memcpy (liter->haveparts, haveparts, havecount*sizeof(int)); liter->haveparts[havecount] = 0; } } if (miscount) { if ((liter->misparts=(int*)malloc((miscount+1)*sizeof(int)))!=NULL) { memcpy (liter->misparts, misparts, miscount*sizeof(int)); liter->misparts[miscount] = 0; } liter->state |= UUFILE_MISPART; } /* * Finalize checking */ if ((flag & 4) == 0) liter->state |= UUFILE_NODATA; if ((flag & 1) == 0) liter->state |= UUFILE_NOBEGIN; if ((flag & 2) == 0) liter->state |= UUFILE_NOEND; if ((flag & 7) == 7 && miscount==0) { liter->state = UUFILE_OK; } if ((uu_fast_scanning && (liter->flags&FL_PROPER)==0) || thesize<=0) liter->size = -1; else liter->size = thesize; if (liter->state==UUFILE_OK && (liter->filename==NULL || liter->filename[0]=='\0')) { /* * Emergency backup if the file does not have a filename */ _FP_free (liter->filename); if (liter->subfname && liter->subfname[0] && _FP_strpbrk (liter->subfname, "()[];: ") == NULL) liter->filename = _FP_strdup (liter->subfname); else { sprintf (uucheck_tempname, "%s.%03d", nofname, ++nofnum); liter->filename = _FP_strdup (uucheck_tempname); } } liter = liter->NEXT; } /* * Sets back (PREV) links */ liter = UUGlobalFileList; prev = NULL; while (liter) { liter->PREV = prev; prev = liter; liter = liter->NEXT; } return UUGlobalFileList; } uudeview-0.5.20.orig/uulib/uudeview.h0000644001167100001440000002241507736137763017503 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef __UUDEVIEW_H__ #define __UUDEVIEW_H__ /* * This include file features all the definitions that should * be externally visible. This isn't much. * * $Id: uudeview.h,v 1.18 2003/09/29 23:27:47 fp Exp $ */ #ifndef _ANSI_ARGS_ #ifdef PROTOTYPES #define _ANSI_ARGS_(c) c #else #define _ANSI_ARGS_(c) () #endif #endif /* * Message Types */ #define UUMSG_MESSAGE (0) /* just a message, nothing important */ #define UUMSG_NOTE (1) /* something that should be noticed */ #define UUMSG_WARNING (2) /* important msg, processing continues */ #define UUMSG_ERROR (3) /* processing has been terminated */ #define UUMSG_FATAL (4) /* decoder cannot process further requests */ #define UUMSG_PANIC (5) /* recovery impossible, app must terminate */ /* * Return Values */ #define UURET_OK (0) /* everything went fine */ #define UURET_IOERR (1) /* I/O Error - examine errno */ #define UURET_NOMEM (2) /* not enough memory */ #define UURET_ILLVAL (3) /* illegal value for operation */ #define UURET_NODATA (4) /* decoder didn't find any data */ #define UURET_NOEND (5) /* encoded data wasn't ended properly */ #define UURET_UNSUP (6) /* unsupported function (encoding) */ #define UURET_EXISTS (7) /* file exists (decoding) */ #define UURET_CONT (8) /* continue -- special from ScanPart */ #define UURET_CANCEL (9) /* operation canceled */ /* * File states, may be OR'ed */ #define UUFILE_READ (0) /* Read in, but not further processed */ #define UUFILE_MISPART (1) /* Missing Part(s) detected */ #define UUFILE_NOBEGIN (2) /* No 'begin' found */ #define UUFILE_NOEND (4) /* No 'end' found */ #define UUFILE_NODATA (8) /* File does not contain valid uudata */ #define UUFILE_OK (16) /* All Parts found, ready to decode */ #define UUFILE_ERROR (32) /* Error while decoding */ #define UUFILE_DECODED (64) /* Successfully decoded */ #define UUFILE_TMPFILE (128) /* Temporary decoded file exists */ /* * Encoding Types */ #define UU_ENCODED (1) /* UUencoded data */ #define B64ENCODED (2) /* Mime-Base64 data */ #define XX_ENCODED (3) /* XXencoded data */ #define BH_ENCODED (4) /* Binhex encoded */ #define PT_ENCODED (5) /* Plain-Text encoded (MIME) */ #define QP_ENCODED (6) /* Quoted-Printable (MIME) */ #define YENC_ENCODED (7) /* yEnc encoded */ /* * Option indices for GetOption / SetOption */ #define UUOPT_VERSION (0) /* version number MAJOR.MINORplPATCH (ro) */ #define UUOPT_FAST (1) /* assumes only one part per file */ #define UUOPT_DUMBNESS (2) /* switch off the program's intelligence */ #define UUOPT_BRACKPOL (3) /* give numbers in [] higher precendence */ #define UUOPT_VERBOSE (4) /* generate informative messages */ #define UUOPT_DESPERATE (5) /* try to decode incomplete files */ #define UUOPT_IGNREPLY (6) /* ignore RE:plies (off by default) */ #define UUOPT_OVERWRITE (7) /* whether it's OK to overwrite ex. files */ #define UUOPT_SAVEPATH (8) /* prefix to save-files on disk */ #define UUOPT_IGNMODE (9) /* ignore the original file mode */ #define UUOPT_DEBUG (10) /* print messages with FILE/LINE info */ #define UUOPT_ERRNO (14) /* get last error code for UURET_IOERR (ro) */ #define UUOPT_PROGRESS (15) /* retrieve progress information */ #define UUOPT_USETEXT (16) /* handle text messages */ #define UUOPT_PREAMB (17) /* handle Mime preambles/epilogues */ #define UUOPT_TINYB64 (18) /* detect short B64 outside of Mime */ #define UUOPT_ENCEXT (19) /* extension for single-part encoded files */ #define UUOPT_REMOVE (20) /* remove input files after decoding */ #define UUOPT_MOREMIME (21) /* strict MIME adherence */ /* * Code for the "action" in the progress structure */ #define UUACT_IDLE (0) /* we don't do anything */ #define UUACT_SCANNING (1) /* scanning an input file */ #define UUACT_DECODING (2) /* decoding into a temp file */ #define UUACT_COPYING (3) /* copying temp to target */ #define UUACT_ENCODING (4) /* encoding a file */ /* * forward definition */ struct _uufile; /* * Structure for holding the list of files that have been found * uufile items are inserted into this list with UUInsertPartToList * After inserting a bunch of files, UUCheckGlobalList must be called * to update the states. */ typedef struct _uulist { short state; /* Status as described by the macros above */ short mode; /* file mode as found on begin line */ int begin; /* part number where begin was detected */ int end; /* part number where end was detected */ short uudet; /* Encoding type (see macros above) */ int flags; /* flags, especially for single-part files */ long size; /* approximate size of resulting file */ char *filename; /* malloc'ed file name */ char *subfname; /* malloc'ed ID from subject line */ char *mimeid; /* malloc'ed MIME-ID, if available */ char *mimetype; /* malloc'ed Content-Type, if available */ char *binfile; /* name of temp file, if already decoded */ struct _uufile *thisfile; /* linked list of this file's parts */ int *haveparts; /* the parts we have (max. 256 are listed) */ int *misparts; /* list of missing parts (max. 256) */ struct _uulist *NEXT; /* next item of the list */ struct _uulist *PREV; /* previous item of the list */ } uulist; /* * The "progress" structure which is passed to the Busy Callback */ typedef struct { int action; /* see UUACT_* definitions above */ char curfile[256]; /* the file we are working on, incl. path */ int partno; /* part we're currently decoding */ int numparts; /* total number of parts of this file */ long fsize; /* size of the current file */ int percent; /* % of _current part_ */ long foffset; /* file offset -- internal use only */ long totsize; /* file total size -- internal use only */ } uuprogress; /* * Externally visible Functions */ #ifndef UUEXPORT #define UUEXPORT #endif #ifdef __cplusplus extern "C" { #endif int UUEXPORT UUInitialize _ANSI_ARGS_((void)); int UUEXPORT UUGetOption _ANSI_ARGS_((int, int *, char *, int)); int UUEXPORT UUSetOption _ANSI_ARGS_((int, int, char *)); char * UUEXPORT UUstrerror _ANSI_ARGS_((int)); int UUEXPORT UUSetMsgCallback _ANSI_ARGS_((void *, void (*) (void *, char *, int))); int UUEXPORT UUSetBusyCallback _ANSI_ARGS_((void *, int (*) (void *, uuprogress *), long)); int UUEXPORT UUSetFileCallback _ANSI_ARGS_((void *, int (*) (void *, char *, char *, int))); int UUEXPORT UUSetFNameFilter _ANSI_ARGS_((void *, char * (*) (void *, char *))); char * UUEXPORT UUFNameFilter _ANSI_ARGS_((char *)); int UUEXPORT UULoadFile _ANSI_ARGS_((char *, char *, int)); int UUEXPORT UULoadFileWithPartNo _ANSI_ARGS_((char *, char *, int, int)); uulist *UUEXPORT UUGetFileListItem _ANSI_ARGS_((int)); int UUEXPORT UURenameFile _ANSI_ARGS_((uulist *, char *)); int UUEXPORT UUDecodeToTemp _ANSI_ARGS_((uulist *)); int UUEXPORT UURemoveTemp _ANSI_ARGS_((uulist *)); int UUEXPORT UUDecodeFile _ANSI_ARGS_((uulist *, char *)); int UUEXPORT UUInfoFile _ANSI_ARGS_((uulist *, void *, int (*) (void *, char *))); int UUEXPORT UUSmerge _ANSI_ARGS_((int)); int UUEXPORT UUCleanUp _ANSI_ARGS_((void)); int UUEXPORT UUQuickDecode _ANSI_ARGS_((FILE *, FILE *, char *, long)); int UUEXPORT UUEncodeMulti _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, char *, int)); int UUEXPORT UUEncodePartial _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, char *, int, int, long, unsigned long*)); int UUEXPORT UUEncodeToStream _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, int)); int UUEXPORT UUEncodeToFile _ANSI_ARGS_((FILE *, char *, int, char *, char *, long)); int UUEXPORT UUE_PrepSingle _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, int, char *, char *, char *, int)); int UUEXPORT UUE_PrepPartial _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, int, int, long, long, char *, char *, char *, int)); int UUEXPORT UUE_PrepSingleExt _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, int, char *, char *, char *, char *, int)); int UUEXPORT UUE_PrepPartialExt _ANSI_ARGS_((FILE *, FILE *, char *, int, char *, int, int, long, long, char *, char *, char *, char *, int)); #ifdef __cplusplus } #endif #endif uudeview-0.5.20.orig/uulib/uuencode.c0000644001167100001440000013364107452301104017425 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif #include #include #include #include #include #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #include #include #include #include #include /* for braindead systems */ #ifndef SEEK_SET #ifdef L_BEGIN #define SEEK_SET L_BEGIN #else #define SEEK_SET 0 #endif #endif char * uuencode_id = "$Id: uuencode.c,v 1.22 2002/04/02 10:04:52 fp Exp $"; #if 0 /* * the End-Of-Line string. MIME enforces CRLF, so that's what we use. Some * implementations of uudecode will complain about a missing end line, since * they look for "end^J" but find "end^J^M". We don't care - especially be- * cause they still decode the file properly despite this complaint. */ #ifndef EOLSTRING #define EOLSTRING "\015\012" #endif #else /* * Argh. Some delivery software (inews) has problems with the CRLF * line termination. Let's try native EOL and see if we run into * any problems. * This involves opening output files in text mode instead of binary */ #ifndef EOLSTRING #define EOLSTRING "\n" #endif #endif /* * ========================================================================= * User-configurable settings end here. Don't spy below unless you know what * you're doing. * ========================================================================= */ /* * Define End-Of-Line sequence */ #ifdef EOLSTRING static unsigned char *eolstring = (unsigned char *) EOLSTRING; #else static unsigned char *eolstring = (unsigned char *) "\012"; #endif /* * Content-Transfer-Encoding types for non-MIME encodings */ #define CTE_UUENC "x-uuencode" #define CTE_XXENC "x-xxencode" #define CTE_BINHEX "x-binhex" #define CTE_YENC "x-yenc" #define CTE_TYPE(y) (((y)==B64ENCODED) ? "Base64" : \ ((y)==UU_ENCODED) ? CTE_UUENC : \ ((y)==XX_ENCODED) ? CTE_XXENC : \ ((y)==PT_ENCODED) ? "8bit" : \ ((y)==QP_ENCODED) ? "quoted-printable" : \ ((y)==BH_ENCODED) ? CTE_BINHEX : \ ((y)==YENC_ENCODED) ? CTE_YENC : "x-oops") /* * encoding tables */ unsigned char UUEncodeTable[64] = { '`', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\',']', '^', '_' }; unsigned char B64EncodeTable[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; unsigned char XXEncodeTable[64] = { '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; unsigned char BHEncodeTable[64] = { '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '0', '1', '2', '3', '4', '5', '6', '8', '9', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'X', 'Y', 'Z', '[', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'j', 'k', 'l', 'm', 'p', 'q', 'r' }; unsigned char HexEncodeTable[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; typedef struct { char *extension; char *mimetype; } mimemap; /* * This table maps a file's extension into a Content-Type. The current * official list can be downloaded as * ftp://ftp.isi.edu/in-notes/iana/assignments/media-type * I haven't listed any text types since it doesn't make sense to encode * them. Everything not on the list gets mapped to application/octet-stream */ static mimemap mimetable[] = { { "gif", "image/gif" }, /* Grafics Interchange Format */ { "jpg", "image/jpeg" }, /* JFIF encoded files */ { "jpeg", "image/jpeg" }, { "tif", "image/tiff" }, /* Tag Image File Format */ { "tiff", "image/tiff" }, { "cgm", "image/cgm" }, /* Computer Graphics Metafile */ { "au", "audio/basic" }, /* 8kHz ulaw audio data */ { "mov", "video/quicktime" }, /* Apple Quicktime */ { "qt", "video/quicktime" }, /* Also infrequently used */ { "mpeg", "video/mpeg" }, /* Motion Picture Expert Group */ { "mpg", "video/mpeg" }, { "mp2", "video/mpeg" }, /* dito, MPEG-2 encoded files */ { "mp3", "audio/mpeg" }, /* dito, MPEG-3 encoded files */ { "ps", "application/postscript" }, /* Postscript Language */ { "zip", "application/zip" }, /* ZIP archive */ { "doc", "application/msword"},/* assume Microsoft Word */ { NULL, NULL } }; /* * the order of the following two tables must match the * Encoding Types definition in uudeview.h */ /* * encoded bytes per line */ static int bpl[8] = { 0, 45, 57, 45, 45, 0, 0, 128 }; /* * tables */ static unsigned char *etables[5] = { NULL, UUEncodeTable, B64EncodeTable, XXEncodeTable, BHEncodeTable }; /* * variables to malloc upon initialization */ char *uuestr_itemp; char *uuestr_otemp; /* * Encode one part of the data stream */ static int UUEncodeStream (FILE *outfile, FILE *infile, int encoding, long linperfile, crc32_t *crc, crc32_t *pcrc) { unsigned char *itemp = (char *) uuestr_itemp; unsigned char *otemp = (char *) uuestr_otemp; unsigned char *optr, *table, *tptr; int index, count; long line=0; size_t llen; if (outfile==NULL || infile==NULL || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeStream()"); return UURET_ILLVAL; } /* * Special handling for plain text and quoted printable. Text is * read line oriented. */ if (encoding == PT_ENCODED || encoding == QP_ENCODED) { while (!feof (infile) && (linperfile <= 0 || line < linperfile)) { if (_FP_fgets (itemp, 255, infile) == NULL) { break; } itemp[255] = '\0'; count = strlen (itemp); llen = 0; optr = otemp; /* * Busy Callback */ if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) { UUMessage (uuencode_id, __LINE__, UUMSG_NOTE, uustring (S_ENCODE_CANCEL)); return UURET_CANCEL; } if (encoding == PT_ENCODED) { /* * If there is a line feed, replace by eolstring */ if (count > 0 && itemp[count-1] == '\n') { itemp[--count] = '\0'; if (fwrite (itemp, 1, count, outfile) != count || fwrite ((char *) eolstring, 1, strlen(eolstring), outfile) != strlen (eolstring)) { return UURET_IOERR; } } else { if (fwrite (itemp, 1, count, outfile) != llen) { return UURET_IOERR; } } } else if (encoding == QP_ENCODED) { for (index=0; index> 4]; *optr++ = HexEncodeTable[itemp[index] & 0x0f]; llen += 3; } else if ((itemp[index] >= 33 && itemp[index] <= 60) || (itemp[index] >= 62 && itemp[index] <= 126) || itemp[index] == 9 || itemp[index] == 32) { *optr++ = itemp[index]; llen++; } else if (itemp[index] == '\n') { /* * If the last character before EOL was a space or tab, * we must encode it. If llen > 74, there's no space to do * that, so generate a soft line break instead. */ if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32)) { *(optr-1) = '='; if (llen <= 74) { *optr++ = HexEncodeTable[itemp[index-1] >> 4]; *optr++ = HexEncodeTable[itemp[index-1] & 0x0f]; llen += 2; } } if (fwrite (otemp, 1, llen, outfile) != llen || fwrite ((char *) eolstring, 1, strlen(eolstring), outfile) != strlen (eolstring)) { return UURET_IOERR; } /* * Fix the soft line break condition from above */ if (index>0 && (itemp[index-1] == 9 || itemp[index-1] == 32) && *(optr-1) == '=') { otemp[0] = '='; otemp[1] = HexEncodeTable[itemp[index-1] >> 4]; otemp[2] = HexEncodeTable[itemp[index-1] & 0x0f]; if (fwrite (otemp, 1, 3, outfile) != 3 || fwrite ((char *) eolstring, 1, strlen(eolstring), outfile) != strlen (eolstring)) { return UURET_IOERR; } } optr = otemp; llen = 0; } else { *optr++ = '='; *optr++ = HexEncodeTable[itemp[index] >> 4]; *optr++ = HexEncodeTable[itemp[index] & 0x0f]; llen += 3; } /* * Lines must be shorter than 76 characters (not counting CRLF). * If the line grows longer than that, we must include a soft * line break. */ if (itemp[index+1] != 0 && itemp[index+1] != '\n' && (llen >= 75 || (!((itemp[index+1] >= 33 && itemp[index+1] <= 60) || (itemp[index+1] >= 62 && itemp[index+1] <= 126)) && llen >= 73))) { *optr++ = '='; llen++; if (fwrite (otemp, 1, llen, outfile) != llen || fwrite ((char *) eolstring, 1, strlen(eolstring), outfile) != strlen (eolstring)) { return UURET_IOERR; } optr = otemp; llen = 0; } } } line++; } return UURET_OK; } /* * Special handling for yEnc */ if (encoding == YENC_ENCODED) { llen = 0; optr = otemp; while (!feof (infile) && (linperfile <= 0 || line < linperfile)) { if ((count = fread (itemp, 1, 128, infile)) != 128) { if (count == 0) { break; } else if (ferror (infile)) { return UURET_IOERR; } } if (pcrc) *pcrc = crc32(*pcrc, itemp, count); if (crc) *crc = crc32(*crc, itemp, count); line++; /* * Busy Callback */ if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) { UUMessage (uuencode_id, __LINE__, UUMSG_NOTE, uustring (S_ENCODE_CANCEL)); return UURET_CANCEL; } for (index=0; index 127) { if (fwrite (otemp, 1, llen, outfile) != llen || fwrite ((char *) eolstring, 1, strlen(eolstring), outfile) != strlen (eolstring)) { return UURET_IOERR; } llen = 0; optr = otemp; } switch ((char) ((int) itemp[index] + 42)) { case '\0': case '\t': case '\n': case '\r': case '=': case '\033': *optr++ = '='; *optr++ = (char) ((int) itemp[index] + 42 + 64); llen += 2; break; case '.': if (llen == 0) { *optr++ = '='; *optr++ = (char) ((int) itemp[index] + 42 + 64); llen += 2; } else { *optr++ = (char) ((int) itemp[index] + 42); llen++; } break; default: *optr++ = (char) ((int) itemp[index] + 42); llen++; break; } } } /* * write last line */ if (llen) { if (fwrite (otemp, 1, llen, outfile) != llen || fwrite ((char *) eolstring, 1, strlen(eolstring), outfile) != strlen (eolstring)) { return UURET_IOERR; } } return UURET_OK; } /* * Handling for binary encodings */ /* * select charset */ table = etables[encoding]; if (table==NULL || bpl[encoding]==0) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeStream()"); return UURET_ILLVAL; } while (!feof (infile) && (linperfile <= 0 || line < linperfile)) { if ((count = fread (itemp, 1, bpl[encoding], infile)) != bpl[encoding]) { if (count == 0) break; else if (ferror (infile)) return UURET_IOERR; } optr = otemp; llen = 0; /* * Busy Callback */ if (UUBUSYPOLL(ftell(infile)-progress.foffset,progress.fsize)) { UUMessage (uuencode_id, __LINE__, UUMSG_NOTE, uustring (S_ENCODE_CANCEL)); return UURET_CANCEL; } /* * for UU and XX, encode the number of bytes as first character */ if (encoding == UU_ENCODED || encoding == XX_ENCODED) { *optr++ = table[count]; llen++; } /* * Main encoding */ for (index=0; index<=count-3; index+=3, llen+=4) { *optr++ = table[itemp[index] >> 2]; *optr++ = table[((itemp[index ] & 0x03) << 4)|(itemp[index+1] >> 4)]; *optr++ = table[((itemp[index+1] & 0x0f) << 2)|(itemp[index+2] >> 6)]; *optr++ = table[ itemp[index+2] & 0x3f]; } /* * Special handling for incomplete lines */ if (index != count) { if (encoding == B64ENCODED) { if (count - index == 2) { *optr++ = table[itemp[index] >> 2]; *optr++ = table[((itemp[index ] & 0x03) << 4) | ((itemp[index+1] & 0xf0) >> 4)]; *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; *optr++ = '='; } else if (count - index == 1) { *optr++ = table[ itemp[index] >> 2]; *optr++ = table[(itemp[index] & 0x03) << 4]; *optr++ = '='; *optr++ = '='; } llen += 4; } else if (encoding == UU_ENCODED || encoding == XX_ENCODED) { if (count - index == 2) { *optr++ = table[itemp[index] >> 2]; *optr++ = table[((itemp[index ] & 0x03) << 4) | ( itemp[index+1] >> 4)]; *optr++ = table[((itemp[index+1] & 0x0f) << 2)]; *optr++ = table[0]; } else if (count - index == 1) { *optr++ = table[ itemp[index] >> 2]; *optr++ = table[(itemp[index] & 0x03) << 4]; *optr++ = table[0]; *optr++ = table[0]; } llen += 4; } } /* * end of line */ tptr = eolstring; while (*tptr) *optr++ = *tptr++; *optr++ = '\0'; llen += strlen ((char *) eolstring); if (fwrite (otemp, 1, llen, outfile) != llen) return UURET_IOERR; line++; } return UURET_OK; } /* * Encode as MIME multipart/mixed sub-message. */ int UUEXPORT UUEncodeMulti (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, char *mimetype, int filemode) { mimemap *miter=mimetable; struct stat finfo; int res, themode; FILE *theifile; char *ptr; crc32_t crc; crc32_t *crcptr=NULL; if (outfile==NULL || (infile == NULL && infname==NULL) || (outfname==NULL && infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeMulti()"); return UURET_ILLVAL; } progress.action = 0; if (infile==NULL) { if (stat (infname, &finfo) == -1) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } if ((theifile = fopen (infname, "rb")) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); progress.fsize = (long) finfo.st_size; } else { if (fstat (fileno (infile), &finfo) != 0) { themode = (filemode)?filemode:0644; progress.fsize = -1; } else { themode = (int) finfo.st_mode & 0777; progress.fsize = (long) finfo.st_size; } theifile = infile; } if (progress.fsize < 0) progress.fsize = -1; _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); progress.partno = 1; progress.numparts = 1; progress.percent = 0; progress.foffset = 0; progress.action = UUACT_ENCODING; /* * If not given from outside, select an appropriate Content-Type by * looking at the file's extension. If it is unknown, default to * Application/Octet-Stream */ if (mimetype == NULL) { if ((ptr = _FP_strrchr ((outfname)?outfname:infname, '.'))) { while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0) miter++; mimetype = miter->mimetype; } } if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) { mimetype = "text/plain"; } /* * print sub-header */ if (encoding != YENC_ENCODED) { fprintf (outfile, "Content-Type: %s%s", (mimetype)?mimetype:"Application/Octet-Stream", eolstring); fprintf (outfile, "Content-Transfer-Encoding: %s%s", CTE_TYPE(encoding), eolstring); fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", UUFNameFilter ((outfname)?outfname:infname), eolstring); fprintf (outfile, "%s", eolstring); } if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "begin %o %s%s", (themode) ? themode : 0644, UUFNameFilter ((outfname)?outfname:infname), eolstring); } else if (encoding == YENC_ENCODED) { crc = crc32(0L, Z_NULL, 0); crcptr = &crc; if (progress.fsize == -1) { fprintf (outfile, "=ybegin line=128 name=%s%s", UUFNameFilter ((outfname)?outfname:infname), eolstring); } else { fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", progress.fsize, UUFNameFilter ((outfname)?outfname:infname), eolstring); } } if ((res = UUEncodeStream (outfile, theifile, encoding, 0, crcptr, NULL)) != UURET_OK) { if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_ERR_ENCODING), UUFNameFilter ((infname)?infname:outfname), (res==UURET_IOERR)?strerror(uu_errno):UUstrerror(res)); } progress.action = 0; return res; } if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], eolstring); fprintf (outfile, "end%s", eolstring); } else if (encoding == YENC_ENCODED) { if (progress.fsize == -1) { fprintf (outfile, "=yend crc32=%08lx%s", crc, eolstring); } else { fprintf (outfile, "=yend size=%ld crc32=%08lx%s", progress.fsize, crc, eolstring); } } /* * empty line at end does no harm */ fprintf (outfile, "%s", eolstring); if (infile==NULL) fclose (theifile); progress.action = 0; return UURET_OK; } /* * Encode as MIME message/partial */ int UUEXPORT UUEncodePartial (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, char *mimetype, int filemode, int partno, long linperfile, crc32_t *crcptr) { mimemap *miter=mimetable; static FILE *theifile; int themode, numparts; struct stat finfo; long thesize; char *ptr; int res; crc32_t pcrc; crc32_t *pcrcptr=NULL; if ((outfname==NULL&&infname==NULL) || partno<=0 || (infile == NULL&&infname==NULL) || outfile==NULL || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodePartial()"); return UURET_ILLVAL; } /* * The first part needs a set of headers */ progress.action = 0; if (partno == 1) { if (infile==NULL) { if (stat (infname, &finfo) == -1) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } if ((theifile = fopen (infname, "rb")) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } if (linperfile <= 0) numparts = 1; else numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ (linperfile*bpl[encoding])); themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); thesize = (long) finfo.st_size; } else { if (fstat (fileno (infile), &finfo) != 0) { UUMessage (uuencode_id, __LINE__, UUMSG_WARNING, uustring (S_STAT_ONE_PART)); numparts = 1; themode = (filemode)?filemode:0644; thesize = -1; } else { if (linperfile <= 0) numparts = 1; else numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ (linperfile*bpl[encoding])); themode = (int) finfo.st_mode & 0777; thesize = (long) finfo.st_size; } theifile = infile; } _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); progress.totsize = (thesize>=0) ? thesize : -1; progress.partno = 1; progress.numparts = numparts; progress.percent = 0; progress.foffset = 0; /* * If not given from outside, select an appropriate Content-Type by * looking at the file's extension. If it is unknown, default to * Application/Octet-Stream */ if (mimetype == NULL) { if ((ptr = _FP_strrchr ((outfname)?outfname:infname, '.'))) { while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0) miter++; mimetype = miter->mimetype; } } if (mimetype == NULL && (encoding==PT_ENCODED || encoding==QP_ENCODED)) { mimetype = "text/plain"; } /* * print sub-header */ if (encoding != YENC_ENCODED) { fprintf (outfile, "MIME-Version: 1.0%s", eolstring); fprintf (outfile, "Content-Type: %s%s", (mimetype)?mimetype:"Application/Octet-Stream", eolstring); fprintf (outfile, "Content-Transfer-Encoding: %s%s", CTE_TYPE(encoding), eolstring); fprintf (outfile, "Content-Disposition: attachment; filename=\"%s\"%s", UUFNameFilter ((outfname)?outfname:infname), eolstring); } fprintf (outfile, "%s", eolstring); /* * for the first part of UU or XX messages, print a begin line */ if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "begin %o %s%s", (themode) ? themode : ((filemode)?filemode:0644), UUFNameFilter ((outfname)?outfname:infname), eolstring); } } if (encoding == YENC_ENCODED) { pcrc = crc32(0L, Z_NULL, 0); pcrcptr = &pcrc; if (numparts != 1) { if (progress.totsize == -1) { fprintf (outfile, "=ybegin part=%d line=128 name=%s%s", partno, UUFNameFilter ((outfname)?outfname:infname), eolstring); } else { fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s", partno, progress.totsize, UUFNameFilter ((outfname)?outfname:infname), eolstring); } fprintf (outfile, "=ypart begin=%d end=%d%s", (partno-1)*linperfile*128+1, (partno*linperfile*128) < progress.totsize ? (partno*linperfile*128) : progress.totsize, eolstring); } else { if (progress.totsize == -1) { fprintf (outfile, "=ybegin line=128 name=%s%s", UUFNameFilter ((outfname)?outfname:infname), eolstring); } else { fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", progress.totsize, UUFNameFilter ((outfname)?outfname:infname), eolstring); } } } /* * update progress information */ progress.partno = partno; progress.percent = 0; progress.foffset = ftell (theifile); if (progress.totsize <= 0) progress.fsize = -1; else if (linperfile <= 0) progress.fsize = progress.totsize; else if (progress.foffset+linperfile*bpl[encoding] > progress.totsize) progress.fsize = progress.totsize - progress.foffset; else progress.fsize = linperfile*bpl[encoding]; progress.action = UUACT_ENCODING; if ((res = UUEncodeStream (outfile, theifile, encoding, linperfile, crcptr, pcrcptr)) != UURET_OK) { if (infile==NULL) fclose (theifile); if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_ERR_ENCODING), UUFNameFilter ((outfname)?outfname:infname), (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res)); } progress.action = 0; return res; } /* * print end line */ if (feof (theifile) && (encoding == UU_ENCODED || encoding == XX_ENCODED)) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], eolstring); fprintf (outfile, "end%s", eolstring); } else if (encoding == YENC_ENCODED) { if (numparts != 1) { fprintf (outfile, "=yend size=%d part=%d pcrc32=%08lx", (partno*linperfile*128) < progress.totsize ? linperfile*128 : (progress.totsize-(partno-1)*linperfile*128), partno, pcrc); } else { fprintf (outfile, "=yend size=%d", progress.totsize); } if (feof (theifile)) fprintf (outfile, " crc32=%08lx", *crcptr); fprintf (outfile, "%s", eolstring); } /* * empty line at end does no harm */ if (encoding != PT_ENCODED && encoding != QP_ENCODED) { fprintf (outfile, "%s", eolstring); } if (infile==NULL) { if (res != UURET_OK) { progress.action = 0; fclose (theifile); return res; } if (feof (theifile)) { progress.action = 0; fclose (theifile); return UURET_OK; } return UURET_CONT; } /* * leave progress.action as-is */ return UURET_OK; } /* * send output to a stream, don't do any headers at all */ int UUEXPORT UUEncodeToStream (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, int filemode) { struct stat finfo; FILE *theifile; int themode; int res; crc32_t crc; crc32_t *crcptr=NULL; if (outfile==NULL || (infile == NULL&&infname==NULL) || (outfname==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeToStream()"); return UURET_ILLVAL; } progress.action = 0; if (infile==NULL) { if (stat (infname, &finfo) == -1) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } if ((theifile = fopen (infname, "rb")) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); progress.fsize = (long) finfo.st_size; } else { if (fstat (fileno (infile), &finfo) == -1) { /* gotta live with it */ themode = 0644; progress.fsize = -1; } else { themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); progress.fsize = (long) finfo.st_size; } theifile = infile; } if (progress.fsize < 0) progress.fsize = -1; _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); progress.partno = 1; progress.numparts = 1; progress.percent = 0; progress.foffset = 0; progress.action = UUACT_ENCODING; if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "begin %o %s%s", (themode) ? themode : 0644, UUFNameFilter ((outfname)?outfname:infname), eolstring); } else if (encoding == YENC_ENCODED) { crc = crc32(0L, Z_NULL, 0); crcptr = &crc; if (progress.fsize == -1) { fprintf (outfile, "=ybegin line=128 name=%s%s", UUFNameFilter ((outfname)?outfname:infname), eolstring); } else { fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", progress.fsize, UUFNameFilter ((outfname)?outfname:infname), eolstring); } } if ((res = UUEncodeStream (outfile, theifile, encoding, 0, crcptr, NULL)) != UURET_OK) { if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_ERR_ENCODING), UUFNameFilter ((infname)?infname:outfname), (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res)); } progress.action = 0; return res; } if (encoding == UU_ENCODED || encoding == XX_ENCODED) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], eolstring); fprintf (outfile, "end%s", eolstring); } else if (encoding == YENC_ENCODED) { if (progress.fsize == -1) { fprintf (outfile, "=yend crc32=%08lx%s", crc, eolstring); } else { fprintf (outfile, "=yend size=%ld crc32=%08lx%s", progress.fsize, crc, eolstring); } } /* * empty line at end does no harm */ fprintf (outfile, "%s", eolstring); if (infile==NULL) fclose (theifile); progress.action = 0; return UURET_OK; } /* * Encode to files on disk, don't generate any headers */ int UUEXPORT UUEncodeToFile (FILE *infile, char *infname, int encoding, char *outfname, char *diskname, long linperfile) { int part, numparts, len, filemode, res; char *oname=NULL, *optr, *ptr; FILE *theifile, *outfile; struct stat finfo; crc32_t pcrc, crc; crc32_t *pcrcptr=NULL, *crcptr=NULL; if ((diskname==NULL&&infname==NULL) || (outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUEncodeToFile()"); return UURET_ILLVAL; } if (diskname) { if ((ptr = strchr (diskname, '/')) == NULL) ptr = strchr (diskname, '\\'); if (ptr) { len = strlen (diskname) + ((uuencodeext)?strlen(uuencodeext):3) + 5; if ((oname = malloc (len)) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), len); return UURET_NOMEM; } sprintf (oname, "%s", diskname); } else { len = ((uusavepath)?strlen(uusavepath):0) + strlen (diskname) + ((uuencodeext)?strlen(uuencodeext):0) + 5; if ((oname = malloc (len)) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), len); return UURET_NOMEM; } sprintf (oname, "%s%s", (uusavepath)?uusavepath:"", diskname); } } else { len = ((uusavepath) ? strlen (uusavepath) : 0) + strlen(UUFNameFilter(infname)) + ((uuencodeext)?strlen(uuencodeext):0) + 5; if ((oname = malloc (len)) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), len); return UURET_NOMEM; } optr = UUFNameFilter (infname); sprintf (oname, "%s%s", (uusavepath)?uusavepath:"", (*optr=='.')?optr+1:optr); } /* * optr points after the last dot, so that we can print the part number * there. */ optr = _FP_strrchr (oname, '.'); if (optr==NULL || strchr (optr, '/')!=NULL || strchr (optr, '\\')!=NULL) { optr = oname + strlen (oname); *optr++ = '.'; } else if (optr==oname || *(optr-1)=='/' || *(optr-1)=='\\') { optr = oname + strlen (oname); *optr++ = '.'; } else optr++; progress.action = 0; if (infile==NULL) { if (stat (infname, &finfo) == -1) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), infname, strerror (uu_errno=errno)); _FP_free (oname); return UURET_IOERR; } if ((theifile = fopen (infname, "rb")) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), infname, strerror (uu_errno=errno)); _FP_free (oname); return UURET_IOERR; } if (linperfile <= 0) numparts = 1; else numparts = (int) (((long)finfo.st_size + (linperfile*bpl[encoding]-1)) / (linperfile*bpl[encoding])); filemode = (int) finfo.st_mode & 0777; progress.totsize = (long) finfo.st_size; } else { if (fstat (fileno (infile), &finfo) == -1) { /* gotta live with it */ filemode = 0644; numparts = -1; progress.totsize = -1; } else { if (linperfile <= 0) numparts = 1; else numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ (linperfile*bpl[encoding])); filemode = (int) finfo.st_mode & 0777; progress.totsize = -1; } theifile = infile; } _FP_strncpy (progress.curfile, (outfname)?outfname:infname, 256); progress.totsize = (progress.totsize<0) ? -1 : progress.totsize; progress.numparts = numparts; for (part=1; !feof (theifile); part++) { /* * Attach extension */ if (progress.numparts==1 && progress.totsize!=-1 && uuencodeext!=NULL) strcpy (optr, uuencodeext); else sprintf (optr, "%03d", part); /* * check if target file exists */ if (!uu_overwrite) { if (stat (oname, &finfo) == 0) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_TARGET_EXISTS), oname); if (infile==NULL) fclose (theifile); progress.action = 0; free (oname); return UURET_EXISTS; } } /* * update progress information */ progress.action = 0; progress.partno = part; progress.percent = 0; progress.foffset = ftell (theifile); if (progress.totsize == -1) progress.fsize = -1; else if (linperfile <= 0) progress.fsize = progress.totsize; else if (progress.foffset+linperfile*bpl[encoding] > progress.totsize) progress.fsize = progress.totsize - progress.foffset; else progress.fsize = linperfile*bpl[encoding]; progress.action = UUACT_ENCODING; if ((outfile = fopen (oname, "w")) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_TARGET), oname, strerror (uu_errno = errno)); if (infile==NULL) fclose (theifile); progress.action = 0; free (oname); return UURET_IOERR; } if (encoding != YENC_ENCODED) { fprintf (outfile, "%s", eolstring); fprintf (outfile, "_=_ %s", eolstring); if (numparts == -1) fprintf (outfile, "_=_ Part %03d of file %s%s", part, UUFNameFilter ((outfname)?outfname:infname), eolstring); else fprintf (outfile, "_=_ Part %03d of %03d of file %s%s", part, numparts, UUFNameFilter ((outfname)?outfname:infname), eolstring); fprintf (outfile, "_=_ %s", eolstring); fprintf (outfile, "%s", eolstring); } if (part==1 && (encoding == UU_ENCODED || encoding == XX_ENCODED)) { fprintf (outfile, "begin %o %s%s", (filemode)?filemode : 0644, UUFNameFilter ((outfname)?outfname:infname), eolstring); } else if (encoding == YENC_ENCODED) { if (!crcptr) { crc = crc32(0L, Z_NULL, 0); crcptr = &crc; } pcrc = crc32(0L, Z_NULL, 0); pcrcptr = &pcrc; if (numparts != 1) { if (progress.totsize == -1) { fprintf (outfile, "=ybegin part=%d line=128 name=%s%s", part, UUFNameFilter ((outfname)?outfname:infname), eolstring); } else { fprintf (outfile, "=ybegin part=%d line=128 size=%ld name=%s%s", part, progress.totsize, UUFNameFilter ((outfname)?outfname:infname), eolstring); } fprintf (outfile, "=ypart begin=%d end=%d%s", (part-1)*linperfile*128+1, (part*linperfile*128) < progress.totsize ? (part*linperfile*128) : progress.totsize, eolstring); } else { if (progress.totsize == -1) { fprintf (outfile, "=ybegin line=128 name=%s%s", UUFNameFilter ((outfname)?outfname:infname), eolstring); } else { fprintf (outfile, "=ybegin line=128 size=%ld name=%s%s", progress.totsize, UUFNameFilter ((outfname)?outfname:infname), eolstring); } } } if ((res = UUEncodeStream (outfile, theifile, encoding, linperfile, crcptr, pcrcptr)) != UURET_OK) { if (res != UURET_CANCEL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_ERR_ENCODING), UUFNameFilter ((infname)?infname:outfname), (res==UURET_IOERR)?strerror(uu_errno):UUstrerror (res)); } if (infile==NULL) fclose (theifile); progress.action = 0; fclose (outfile); unlink (oname); _FP_free (oname); return res; } if (feof (theifile) && (encoding == UU_ENCODED || encoding == XX_ENCODED)) { fprintf (outfile, "%c%s", (encoding==UU_ENCODED) ? UUEncodeTable[0] : XXEncodeTable[0], eolstring); fprintf (outfile, "end%s", eolstring); } else if (encoding == YENC_ENCODED) { if (numparts != 1) { fprintf (outfile, "=yend size=%d part=%d pcrc32=%08lx", (part*linperfile*128) < progress.totsize ? linperfile*128 : (progress.totsize-(part-1)*linperfile*128), part, pcrc); } else { fprintf (outfile, "=yend size=%d", progress.totsize); } if (feof (theifile)) fprintf (outfile, " crc32=%08lx", crc); fprintf (outfile, "%s", eolstring); } /* * empty line at end does no harm */ fprintf (outfile, "%s", eolstring); fclose (outfile); } if (infile==NULL) fclose (theifile); progress.action = 0; _FP_free (oname); return UURET_OK; } /* * Encode a MIME Mail message or Newsgroup posting and send to a * stream. Still needs a somewhat smart MDA, since we only gene- * rate a minimum set of headers. */ int UUEXPORT UUE_PrepSingle (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, int filemode, char *destination, char *from, char *subject, int isemail) { return UUE_PrepSingleExt (outfile, infile, infname, encoding, outfname, filemode, destination, from, subject, NULL, isemail); } int UUEXPORT UUE_PrepSingleExt (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, int filemode, char *destination, char *from, char *subject, char *replyto, int isemail) { mimemap *miter=mimetable; char *subline, *oname; char *mimetype, *ptr; int res, len; if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUE_PrepSingle()"); return UURET_ILLVAL; } oname = UUFNameFilter ((outfname)?outfname:infname); len = ((subject)?strlen(subject):0) + strlen(oname) + 40; if ((ptr = _FP_strrchr (oname, '.'))) { while (miter->extension && _FP_stricmp (ptr+1, miter->extension) != 0) miter++; mimetype = miter->mimetype; } else mimetype = NULL; if (mimetype == NULL && (encoding == PT_ENCODED || encoding == QP_ENCODED)) { mimetype = "text/plain"; } if ((subline = (char *) malloc (len)) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), len); return UURET_NOMEM; } if (encoding == YENC_ENCODED) { if (subject) sprintf (subline, "- %s - %s (001/001)", oname, subject); else sprintf (subline, "- %s - (001/001)", oname); } else { if (subject) sprintf (subline, "%s (001/001) - [ %s ]", subject, oname); else sprintf (subline, "[ %s ] (001/001)", oname); } if (from) { fprintf (outfile, "From: %s%s", from, eolstring); } if (destination) { fprintf (outfile, "%s: %s%s", (isemail)?"To":"Newsgroups", destination, eolstring); } fprintf (outfile, "Subject: %s%s", subline, eolstring); if (replyto) { fprintf (outfile, "Reply-To: %s%s", replyto, eolstring); } if (encoding != YENC_ENCODED) { fprintf (outfile, "MIME-Version: 1.0%s", eolstring); fprintf (outfile, "Content-Type: %s; name=\"%s\"%s", (mimetype)?mimetype:"Application/Octet-Stream", UUFNameFilter ((outfname)?outfname:infname), eolstring); fprintf (outfile, "Content-Transfer-Encoding: %s%s", CTE_TYPE(encoding), eolstring); } fprintf (outfile, "%s", eolstring); res = UUEncodeToStream (outfile, infile, infname, encoding, outfname, filemode); _FP_free (subline); return res; } int UUEXPORT UUE_PrepPartial (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, int filemode, int partno, long linperfile, long filesize, char *destination, char *from, char *subject, int isemail) { return UUE_PrepPartialExt (outfile, infile, infname, encoding, outfname, filemode, partno, linperfile, filesize, destination, from, subject, NULL, isemail); } int UUEXPORT UUE_PrepPartialExt (FILE *outfile, FILE *infile, char *infname, int encoding, char *outfname, int filemode, int partno, long linperfile, long filesize, char *destination, char *from, char *subject, char *replyto, int isemail) { static int numparts, themode; static char mimeid[64]; static FILE *theifile; struct stat finfo; char *subline, *oname; long thesize; int res, len; static crc32_t crc; crc32_t *crcptr=NULL; if ((outfname==NULL&&infname==NULL) || (infile==NULL&&infname==NULL) || (encoding!=UU_ENCODED&&encoding!=XX_ENCODED&&encoding!=B64ENCODED&& encoding!=PT_ENCODED&&encoding!=QP_ENCODED&&encoding!=YENC_ENCODED)) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_PARM_CHECK), "UUE_PrepPartial()"); return UURET_ILLVAL; } oname = UUFNameFilter ((outfname)?outfname:infname); len = ((subject)?strlen(subject):0) + strlen (oname) + 40; /* * if first part, get information about the file */ if (partno == 1) { if (infile==NULL) { if (stat (infname, &finfo) == -1) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } if ((theifile = fopen (infname, "rb")) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), infname, strerror (uu_errno=errno)); return UURET_IOERR; } if (linperfile <= 0) numparts = 1; else numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ (linperfile*bpl[encoding])); themode = (filemode) ? filemode : ((int) finfo.st_mode & 0777); thesize = (long) finfo.st_size; } else { if (fstat (fileno (infile), &finfo) != 0) { if (filesize <= 0) { UUMessage (uuencode_id, __LINE__, UUMSG_WARNING, uustring (S_STAT_ONE_PART)); numparts = 1; themode = (filemode)?filemode:0644; thesize = -1; } else { if (linperfile <= 0) numparts = 1; else numparts = (int) ((filesize+(linperfile*bpl[encoding]-1))/ (linperfile*bpl[encoding])); themode = (filemode)?filemode:0644; thesize = filesize; } } else { if (linperfile <= 0) numparts = 1; else numparts = (int) (((long)finfo.st_size+(linperfile*bpl[encoding]-1))/ (linperfile*bpl[encoding])); filemode = (int) finfo.st_mode & 0777; thesize = (long) finfo.st_size; } theifile = infile; } /* * if there's one part only, don't use Message/Partial */ if (numparts == 1) { if (infile==NULL) fclose (theifile); return UUE_PrepSingleExt (outfile, infile, infname, encoding, outfname, filemode, destination, from, subject, replyto, isemail); } /* * we also need a unique ID */ sprintf (mimeid, "UUDV-%ld.%ld.%s", (long) time(NULL), thesize, (strlen(oname)>16)?"oops":oname); } if ((subline = (char *) malloc (len)) == NULL) { UUMessage (uuencode_id, __LINE__, UUMSG_ERROR, uustring (S_OUT_OF_MEMORY), len); if (infile==NULL) fclose (theifile); return UURET_NOMEM; } if (encoding == YENC_ENCODED) { if (partno == 1) crc = crc32(0L, Z_NULL, 0); crcptr = &crc; if (subject) sprintf (subline, "- %s - %s (%03d/%03d)", oname, subject, partno, numparts); else sprintf (subline, "- %s - (%03d/%03d)", oname, partno, numparts); } else { if (subject) sprintf (subline, "%s (%03d/%03d) - [ %s ]", subject, partno, numparts, oname); else sprintf (subline, "[ %s ] (%03d/%03d)", oname, partno, numparts); } if (from) { fprintf (outfile, "From: %s%s", from, eolstring); } if (destination) { fprintf (outfile, "%s: %s%s", (isemail)?"To":"Newsgroups", destination, eolstring); } fprintf (outfile, "Subject: %s%s", subline, eolstring); if (replyto) { fprintf (outfile, "Reply-To: %s%s", replyto, eolstring); } if (encoding != YENC_ENCODED) { fprintf (outfile, "MIME-Version: 1.0%s", eolstring); fprintf (outfile, "Content-Type: Message/Partial; number=%d; total=%d;%s", partno, numparts, eolstring); fprintf (outfile, "\tid=\"%s\"%s", mimeid, eolstring); } fprintf (outfile, "%s", eolstring); res = UUEncodePartial (outfile, theifile, infname, encoding, (outfname)?outfname:infname, NULL, themode, partno, linperfile, crcptr); _FP_free (subline); if (infile==NULL) { if (res != UURET_OK) { fclose (theifile); return res; } if (feof (theifile)) { fclose (theifile); return UURET_OK; } return UURET_CONT; } return res; } uudeview-0.5.20.orig/uulib/uuint.h0000644001167100001440000002345707646117307017011 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef __UUINT_H__ #define __UUINT_H__ /* * This file describes the internal structures, variables and definitions * of UUDeview. It should not be included from other packages. Subject to * change without notice. Do not depend on anything here. * * $Id: uuint.h,v 1.19 2003/04/12 23:18:31 fp Exp $ */ #ifndef _ANSI_ARGS_ #ifdef PROTOTYPES #define _ANSI_ARGS_(c) c #else #define _ANSI_ARGS_(c) () #endif #endif /* * Busy Polls will be made after processing ... lines */ #define BUSY_LINE_TICKS 50 /* * States of MIME scanner */ #define MS_HEADERS 1 /* still inside of headers */ #define MS_BODY 2 /* body of `simple' messages */ #define MS_PREAMBLE 3 /* preamble of Multipart/Mixed */ #define MS_SUBPART 4 /* within one of the Multiparts */ #define MS_EPILOGUE 5 /* epilogue of Multipart/Mixed */ /* * Number of subsequent encoded lines we require to believe this * is valid data. */ #define ELC_COUNT 4 /* * Flags a part may have. FL_PROPER means that we are sure about the file's * encoding, beginning and end, and don't have to use special care when de- * coding. */ #define FL_NONE 0 /* no flag, just plain normal */ #define FL_SINGLE 1 /* standalone MSG, do not mix */ #define FL_PARTIAL 2 /* from Message/Partial */ #define FL_PROPER 4 /* proper MIME part */ #define FL_TOEND 8 /* part continues to EOF */ /* * Auxiliary macro: compute the percentage of a against b. * The obvious answer is (100*a)/b, but this overflows for large a. * a/(b/100) is better; we use a/((b/100)+1) so that we don't divide * by zero for b<100 and the result doesn't become larger than 100% */ #define UUPERCENT(a,b) ((int) ((unsigned long)(a) / \ (((unsigned long)(b)/100)+1))) /* * Make the Busy Callback easier. The macro returns true if the BusyCallback * wants us to terminate. */ extern unsigned long uuyctr; #define UUBUSYPOLL(a,b) (((++uuyctr%BUSY_LINE_TICKS)==0) ? (progress.percent=UUPERCENT((a),(b)),UUBusyPoll()):0) /* * How many lines of headers do we need to believe another mail * header is approaching? Use more restrictive values for MIME * mails, less restrictive for Freestyle */ typedef struct { int restart; /* restarting after a MIME body (not subpart) */ int afterdata; /* after we had useful data in freestyle mode */ int afternl; /* after an empty line in freestyle mode */ } headercount; extern headercount hlcount; /* * Information from the headers of a message. Each instance must * have its very own copy of the strings. If `mimevers' is NULL, * then this message does not comply to the MIME standard. */ typedef struct _headers { char *from; /* From: */ char *subject; /* Subject: */ char *rcpt; /* To: */ char *date; /* Date: */ char *mimevers; /* MIME-Version: */ char *ctype; /* Content-Type: */ char *ctenc; /* Content-Transfer-Encoding: */ char *fname; /* Potential Filename from Content-Type Parameter */ char *boundary; /* MIME-Boundary from Content-Type Parameter */ char *mimeid; /* MIME-Id for Message/Partial */ int partno; /* part number for Message/Partial */ int numparts; /* number of parts for Message/Partial */ } headers; /* * Scanner state */ typedef struct _scanstate { int isfolder; /* if we think this is a valid email folder */ int ismime; /* if we are within a valid MIME message */ int mimestate; /* state of MIME scanner */ int mimeenc; /* encoding of this MIME file */ char *source; /* source filename */ headers envelope; /* mail envelope headers */ } scanstate; /* * Structure that holds the information for a single file / part of * a file. If a subject line is encountered, it is copied to subject; * if a begin is found, the mode and name of the file is extracted. * flags are set if 'begin' or 'end' is detected and 'uudet' if valid * uuencoded data is found. If the file contains a 'From:' line with * a '@' in it (indicating an origin email address), it is preserved * in 'origin'. **/ typedef struct _fileread { char *subject; /* Whole subject line */ char *filename; /* Only filled in if begin detected */ char *origin; /* Whole 'From:' line */ char *mimeid; /* the ID for Mime-encoded files */ char *mimetype; /* Content-Type */ short mode; /* Mode of File (from 'begin') */ int begin; /* begin detected */ int end; /* end detected */ int flags; /* associated flags */ short uudet; /* valid encoded data. value indicates encoding */ short partno; /* Mime-files have a part number within */ short maxpno; /* ... plus the total number of parts */ char *sfname; /* Associated source file */ long startpos; /* ftell() position where data starts */ long length; /* length of data */ } fileread; /* * Structure for holding one part of a file, with some more information * about it. The UUPreProcessPart() function takes one a fileread structure * and produces this uufile structure. * Linked List, ordered by partno. **/ typedef struct _uufile { char *filename; char *subfname; char *mimeid; char *mimetype; short partno; fileread *data; struct _uufile *NEXT; } uufile; extern void *uu_MsgCBArg; extern void *uu_BusyCBArg; extern void *uu_FileCBArg; extern void *uu_FFCBArg; /* * variables */ extern int uu_fast_scanning; extern int uu_bracket_policy; extern int uu_verbose; extern int uu_desperate; extern int uu_ignreply; extern int uu_debug; extern int uu_errno; extern int uu_dumbness; extern int uu_overwrite; extern int uu_ignmode; extern int uu_headercount; extern int uu_usepreamble; extern int uu_handletext; extern int uu_tinyb64; extern int uu_remove_input; extern int uu_more_mime; extern char *uusavepath; extern char *uuencodeext; /* * Encoding/Decoding tables */ extern unsigned char UUEncodeTable[]; extern unsigned char XXEncodeTable[]; extern unsigned char B64EncodeTable[]; extern unsigned char BHEncodeTable[]; /* * String tables from uustring.c */ extern char *msgnames[]; extern char *codenames[]; extern char *uuretcodes[]; extern uulist *UUGlobalFileList; /* * State of MIME variables and current progress */ extern int nofnum, mssdepth; extern int mimseqno, lastvalid; extern int lastenc; extern scanstate multistack[]; extern headers localenv; extern scanstate sstate; extern uuprogress progress; /* * mallocable areas */ extern char *uugen_fnbuffer, *uugen_inbuffer; extern char *uucheck_lastname, *uucheck_tempname; extern char *uuestr_itemp, *uuestr_otemp; extern char *uulib_msgstring, *uuncdl_fulline; extern char *uuncdp_oline, *uuscan_shlline, *uuscan_shlline2; extern char *uuscan_pvvalue, *uuscan_phtext; extern char *uuscan_sdline, *uuscan_sdbhds1; extern char *uuscan_sdbhds2, *uuscan_spline; extern char *uuutil_bhwtmp; extern char *uunconc_UUxlat, *uunconc_UUxlen; extern char *uunconc_B64xlat, *uunconc_XXxlat; extern char *uunconc_BHxlat, *uunconc_save; #ifdef __cplusplus extern "C" { #endif extern void (*uu_MsgCallback) _ANSI_ARGS_((void *, char *, int)); extern int (*uu_BusyCallback) _ANSI_ARGS_((void *, uuprogress *)); extern int (*uu_FileCallback) _ANSI_ARGS_((void *, char *, char *, int)); extern char * (*uu_FNameFilter) _ANSI_ARGS_((void *, char *)); /* * Functions from uulib.c that aren't defined in * Be careful about the definition with variable arguments. */ #if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) int UUMessage _ANSI_ARGS_((char *, int, int, char *, ...)); #else int UUMessage (); #endif int UUBusyPoll _ANSI_ARGS_((void)); /* * Functions from uucheck.c */ uufile * UUPreProcessPart _ANSI_ARGS_((fileread *, int *)); int UUInsertPartToList _ANSI_ARGS_((uufile *)); uulist * UUCheckGlobalList _ANSI_ARGS_((void)); /* * Functions from uuutil.c */ void UUkillfread _ANSI_ARGS_((fileread *)); void UUkillfile _ANSI_ARGS_((uufile *)); void UUkilllist _ANSI_ARGS_((uulist *)); void UUkillheaders _ANSI_ARGS_((headers *)); fileread * ScanPart _ANSI_ARGS_((FILE *, char *, int *)); int UUbhdecomp _ANSI_ARGS_((char *, char *, char *, int *, size_t, size_t, size_t *)); size_t UUbhwrite _ANSI_ARGS_((char *, size_t, size_t, FILE *)); /* * Functions from uunconc.c */ int UURepairData _ANSI_ARGS_((FILE *, char *, int, int *)); void UUInitConc _ANSI_ARGS_((void)); int UUValidData _ANSI_ARGS_((char *, int, int *)); size_t UUDecodeLine _ANSI_ARGS_((char *, char *, int)); int UUDecodeField _ANSI_ARGS_((char *, char *, int)); int UUDecodePart _ANSI_ARGS_((FILE *, FILE *, int *, long, int, int, char *)); int UUDecode _ANSI_ARGS_((uulist *)); /* * Message retrieval from uustring.c */ char * uustring _ANSI_ARGS_((int)); /* * From uuscan.c */ int UUScanHeader _ANSI_ARGS_((FILE *, headers *)); #ifdef __cplusplus } #endif #endif uudeview-0.5.20.orig/uulib/uulib.c0000644001167100001440000007225407736137763016767 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * This file implements the externally visible functions, as declared * in uudeview.h, and some internal interfacing functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif #include #include #include #ifdef HAVE_FCNTL_H #include #endif #ifdef STDC_HEADERS #include #include #include #else #ifdef HAVE_STDARG_H #include #else #ifdef HAVE_VARARGS_H #include #endif #endif #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #ifdef HAVE_ERRNO_H #include #endif /* to get open() in Windows */ #ifdef HAVE_IO_H #include #endif #include #include #include #include char * uulib_id = "$Id: uulib.c,v 1.28 2003/09/29 23:27:47 fp Exp $"; #ifdef SYSTEM_WINDLL BOOL _export WINAPI DllEntryPoint (HINSTANCE hInstance, DWORD seginfo, LPVOID lpCmdLine) { /* Don't do anything, so just return true */ return TRUE; } #endif /* * In DOS, we must open the file binary, O_BINARY is defined there */ #ifndef O_BINARY #define O_BINARY 0 #endif /* for braindead systems */ #ifndef SEEK_SET #ifdef L_BEGIN #define SEEK_SET L_BEGIN #else #define SEEK_SET 0 #endif #endif /* * Callback functions and their opaque arguments */ void (*uu_MsgCallback) _ANSI_ARGS_((void *, char *, int)) = NULL; int (*uu_BusyCallback) _ANSI_ARGS_((void *, uuprogress *)) = NULL; int (*uu_FileCallback) _ANSI_ARGS_((void *, char *, char *, int)) = NULL; char * (*uu_FNameFilter) _ANSI_ARGS_((void *, char *)) = NULL; void *uu_MsgCBArg = NULL; void *uu_BusyCBArg = NULL; void *uu_FileCBArg = NULL; void *uu_FFCBArg = NULL; /* * Global variables */ int uu_fast_scanning = 0; /* assumes at most 1 part per file */ int uu_bracket_policy = 0; /* gives part numbers in [] higher priority */ int uu_verbose = 1; /* enables/disables messages¬es */ int uu_desperate = 0; /* desperate mode */ int uu_ignreply = 0; /* ignore replies */ int uu_debug = 0; /* debugging mode (print __FILE__/__LINE__) */ int uu_errno = 0; /* the errno that caused this UURET_IOERR */ int uu_dumbness = 0; /* switch off the program's intelligence */ int uu_overwrite = 1; /* whether it's ok to overwrite ex. files */ int uu_ignmode = 0; /* ignore the original file mode */ int uu_handletext = 0; /* do we want text/plain messages */ int uu_usepreamble = 0; /* do we want Mime preambles/epilogues */ int uu_tinyb64 = 0; /* detect short B64 outside of MIME */ int uu_remove_input = 0; /* remove input files after decoding */ int uu_more_mime = 0; /* strictly adhere to MIME headers */ headercount hlcount = { 3, /* restarting after a MIME body */ 2, /* after useful data in freestyle mode */ 1 /* after useful data and an empty line */ }; /* * version string */ char uulibversion[256] = VERSION "pl" PATCH; /* * prefix to the files on disk, usually a path name to save files to */ char *uusavepath; /* * extension to use when encoding single-part files */ char *uuencodeext; /* * areas to malloc */ char *uulib_msgstring; char *uugen_inbuffer; char *uugen_fnbuffer; /* * The Global List of Files */ uulist *UUGlobalFileList = NULL; /* * time values for BusyCallback. msecs is MILLIsecs here */ static long uu_busy_msecs = 0; /* call callback function each msecs */ static long uu_last_secs = 0; /* secs of last call to callback */ static long uu_last_usecs = 0; /* usecs of last call to callback */ /* * progress information */ uuprogress progress; /* * Linked list of files we want to delete after decoding */ typedef struct _itbd { char *fname; struct _itbd *NEXT; } itbd; static itbd * ftodel = NULL; /* * for the busy poll */ unsigned long uuyctr; /* * Areas to allocate. Instead of using static memory areas, we malloc() * the memory in UUInitialize() and release them in UUCleanUp to prevent * blowing up of the binary size * This is a table with the pointers to allocate and required sizes. * They are guaranteed to be never NULL. */ typedef struct { char **ptr; size_t size; } allomap; static allomap toallocate[] = { { &uugen_fnbuffer, 1024 }, /* generic filename buffer */ { &uugen_inbuffer, 1024 }, /* generic input data buffer */ { &uucheck_lastname, 256 }, /* from uucheck.c */ { &uucheck_tempname, 256 }, { &uuestr_itemp, 256 }, /* from uuencode.c:UUEncodeStream() */ { &uuestr_otemp, 1024 }, { &uulib_msgstring, 1024 }, /* from uulib.c:UUMessage() */ { &uuncdl_fulline, 300 }, /* from uunconc.c:UUDecodeLine() */ { &uuncdp_oline, 1200 }, /* from uunconc.c:UUDecodePart() */ { &uunconc_UUxlat, 256 * sizeof (int) }, /* from uunconc.c:toplevel */ { &uunconc_UUxlen, 64 * sizeof (int) }, { &uunconc_B64xlat, 256 * sizeof (int) }, { &uunconc_XXxlat, 256 * sizeof (int) }, { &uunconc_BHxlat, 256 * sizeof (int) }, { &uunconc_save, 3*300 }, /* from uunconc.c:decoding buffer */ { &uuscan_shlline, 1024 }, /* from uuscan.c:ScanHeaderLine() */ { &uuscan_shlline2, 1024 }, /* from uuscan.c:ScanHeaderLine() */ { &uuscan_pvvalue, 300 }, /* from uuscan.c:ParseValue() */ { &uuscan_phtext, 300 }, /* from uuscan.c:ParseHeader() */ { &uuscan_sdline, 300 }, /* from uuscan.c:ScanData() */ { &uuscan_sdbhds1, 300 }, { &uuscan_sdbhds2, 300 }, { &uuscan_spline, 300 }, /* from uuscan.c:ScanPart() */ { &uuutil_bhwtmp, 300 }, /* from uuutil.c:UUbhwrite() */ { NULL, 0 } }; /* * Handle the printing of messages. Works like printf. */ #if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) int UUMessage (char *file, int line, int level, char *format, ...) #else int UUMessage (va_alist) va_dcl #endif { char *msgptr; #if defined(STDC_HEADERS) || defined(HAVE_STDARG_H) va_list ap; va_start (ap, format); #else char *file, *format; int line, level; va_list ap; va_start (ap); file = va_arg (ap, char *); line = va_arg (ap, int); level = va_arg (ap, int); format = va_arg (ap, char *); #endif if (uu_debug) { sprintf (uulib_msgstring, "%s(%d): %s", file, line, msgnames[level]); msgptr = uulib_msgstring + strlen (uulib_msgstring); } else { sprintf (uulib_msgstring, "%s", msgnames[level]); msgptr = uulib_msgstring + strlen (uulib_msgstring); } if (uu_MsgCallback && (level>UUMSG_NOTE || uu_verbose)) { vsprintf (msgptr, format, ap); (*uu_MsgCallback) (uu_MsgCBArg, uulib_msgstring, level); } va_end (ap); return UURET_OK; } /* * Call the Busy Callback from time to time. This function must be * polled from the Busy loops. */ int UUBusyPoll (void) { #ifdef HAVE_GETTIMEOFDAY struct timeval tv; long msecs; if (uu_BusyCallback) { (void) gettimeofday (&tv, NULL); msecs = 1000*(tv.tv_sec-uu_last_secs)+(tv.tv_usec-uu_last_usecs)/1000; if (uu_last_secs==0 || msecs > uu_busy_msecs) { uu_last_secs = tv.tv_sec; uu_last_usecs = tv.tv_usec; return (*uu_BusyCallback) (uu_BusyCBArg, &progress); } } #else time_t now; long msecs; if (uu_BusyCallback) { if (uu_busy_msecs <= 0) { msecs = 1; } else { now = time(NULL); msecs = 1000 * (now - uu_last_secs); } if (uu_last_secs==0 || msecs > uu_busy_msecs) { uu_last_secs = now; uu_last_usecs = 0; return (*uu_BusyCallback) (uu_BusyCBArg, &progress); } } #endif return 0; } /* * Initialization function */ int UUEXPORT UUInitialize (void) { allomap *aiter; progress.action = 0; progress.curfile[0] = '\0'; ftodel = NULL; uusavepath = NULL; uuencodeext = NULL; mssdepth = 0; memset (&localenv, 0, sizeof (headers)); memset (&sstate, 0, sizeof (scanstate)); nofnum = 0; mimseqno = 0; lastvalid = 0; lastenc = 0; uuyctr = 0; /* * Allocate areas */ for (aiter=toallocate; aiter->ptr; aiter++) *(aiter->ptr) = NULL; for (aiter=toallocate; aiter->ptr; aiter++) { if ((*(aiter->ptr) = (char *) malloc (aiter->size)) == NULL) { /* * oops. we may not print a message here, because we need these * areas (uulib_msgstring) in UUMessage() */ for (aiter=toallocate; aiter->ptr; aiter++) { _FP_free (*(aiter->ptr)); } return UURET_NOMEM; } } /* * Must be called after areas have been malloced */ UUInitConc (); return UURET_OK; } /* * Set and get Options */ int UUEXPORT UUGetOption (int option, int *ivalue, char *cvalue, int clength) { int result; switch (option) { case UUOPT_VERSION: _FP_strncpy (cvalue, uulibversion, clength); result = 0; break; case UUOPT_FAST: if (ivalue) *ivalue = uu_fast_scanning; result = uu_fast_scanning; break; case UUOPT_DUMBNESS: if (ivalue) *ivalue = uu_dumbness; result = uu_dumbness; break; case UUOPT_BRACKPOL: if (ivalue) *ivalue = uu_bracket_policy; result = uu_bracket_policy; break; case UUOPT_VERBOSE: if (ivalue) *ivalue = uu_verbose; result = uu_verbose; break; case UUOPT_DESPERATE: if (ivalue) *ivalue = uu_desperate; result = uu_desperate; break; case UUOPT_IGNREPLY: if (ivalue) *ivalue = uu_ignreply; result = uu_ignreply; break; case UUOPT_DEBUG: if (ivalue) *ivalue = uu_debug; result = uu_debug; break; case UUOPT_ERRNO: if (ivalue) *ivalue = uu_errno; result = uu_errno; break; case UUOPT_OVERWRITE: if (ivalue) *ivalue = uu_overwrite; result = uu_overwrite; break; case UUOPT_SAVEPATH: _FP_strncpy (cvalue, uusavepath, clength); result = 0; break; case UUOPT_PROGRESS: if (clength==sizeof(uuprogress)) { memcpy (cvalue, &progress, sizeof (uuprogress)); result = 0; } else result = -1; break; case UUOPT_IGNMODE: if (ivalue) *ivalue = uu_ignmode; result = uu_ignmode; break; case UUOPT_USETEXT: if (ivalue) *ivalue = uu_handletext; result = uu_handletext; break; case UUOPT_PREAMB: if (ivalue) *ivalue = uu_usepreamble; result = uu_usepreamble; break; case UUOPT_TINYB64: if (ivalue) *ivalue = uu_tinyb64; result = uu_tinyb64; break; case UUOPT_ENCEXT: _FP_strncpy (cvalue, uuencodeext, clength); result = 0; break; case UUOPT_REMOVE: if (ivalue) *ivalue = uu_remove_input; result = uu_remove_input; break; case UUOPT_MOREMIME: if (ivalue) *ivalue = uu_more_mime; result = uu_more_mime; break; default: return -1; } return result; } int UUEXPORT UUSetOption (int option, int ivalue, char *cvalue) { switch (option) { case UUOPT_FAST: uu_fast_scanning = ivalue; break; case UUOPT_DUMBNESS: uu_dumbness = ivalue; break; case UUOPT_BRACKPOL: uu_bracket_policy = ivalue; break; case UUOPT_VERBOSE: uu_verbose = ivalue; break; case UUOPT_DESPERATE: uu_desperate = ivalue; break; case UUOPT_IGNREPLY: uu_ignreply = ivalue; break; case UUOPT_DEBUG: uu_debug = ivalue; break; case UUOPT_OVERWRITE: uu_overwrite = ivalue; break; case UUOPT_SAVEPATH: _FP_free (uusavepath); uusavepath = _FP_strdup (cvalue); break; case UUOPT_IGNMODE: uu_ignmode = ivalue; break; case UUOPT_USETEXT: uu_handletext = ivalue; break; case UUOPT_PREAMB: uu_usepreamble = ivalue; break; case UUOPT_TINYB64: uu_tinyb64 = ivalue; break; case UUOPT_ENCEXT: _FP_free (uuencodeext); uuencodeext = _FP_strdup (cvalue); break; case UUOPT_REMOVE: uu_remove_input = ivalue; break; case UUOPT_MOREMIME: uu_more_mime = ivalue; break; default: return UURET_ILLVAL; } return UURET_OK; } char * UUEXPORT UUstrerror (int code) { return uuretcodes[code]; } /* * Set the various Callback functions */ int UUEXPORT UUSetMsgCallback (void *opaque, void (*func) _ANSI_ARGS_((void *, char *, int))) { uu_MsgCallback = func; uu_MsgCBArg = opaque; return UURET_OK; } int UUEXPORT UUSetBusyCallback (void *opaque, int (*func) _ANSI_ARGS_((void *, uuprogress *)), long msecs) { uu_BusyCallback = func; uu_BusyCBArg = opaque; uu_busy_msecs = msecs; return UURET_OK; } int UUEXPORT UUSetFileCallback (void *opaque, int (*func) _ANSI_ARGS_((void *, char *, char *, int))) { uu_FileCallback = func; uu_FileCBArg = opaque; return UURET_OK; } int UUEXPORT UUSetFNameFilter (void *opaque, char * (*func) _ANSI_ARGS_((void *, char *))) { uu_FNameFilter = func; uu_FFCBArg = opaque; return UURET_OK; } /* * Return a pointer to the nth element of the GlobalFileList * zero-based, returns NULL if item is too large. */ uulist * UUEXPORT UUGetFileListItem (int item) { uulist *iter=UUGlobalFileList; if (item < 0) return NULL; while (item && iter) { iter = iter->NEXT; item--; } return iter; } /* * call the current filter */ char * UUEXPORT UUFNameFilter (char *fname) { if (uu_FNameFilter) return (*uu_FNameFilter) (uu_FFCBArg, fname); return fname; } /* * Load a File. We call ScanPart repeatedly until at EOF and * add the parts to UUGlobalFileList */ int UUEXPORT UULoadFile (char *filename, char *fileid, int delflag) { return UULoadFileWithPartNo(filename, fileid, delflag, -1); } int UUEXPORT UULoadFileWithPartNo (char *filename, char *fileid, int delflag, int partno) { int res, sr, count=0; struct stat finfo; fileread *loaded; uufile *fload; itbd *killem; FILE *datei; if ((datei = fopen (filename, "rb")) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_SOURCE), filename, strerror (uu_errno = errno)); return UURET_IOERR; } if (fstat (fileno(datei), &finfo) == -1) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), filename, strerror (uu_errno = errno)); fclose (datei); return UURET_IOERR; } /* * schedule for destruction */ if (delflag && fileid==NULL) { if ((killem = (itbd *) malloc (sizeof (itbd))) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_OUT_OF_MEMORY), sizeof (itbd)); } else if ((killem->fname = _FP_strdup (filename)) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_OUT_OF_MEMORY), strlen(filename)+1); _FP_free (killem); } else { killem->NEXT = ftodel; ftodel = killem; } } progress.action = 0; progress.partno = 0; progress.numparts = 1; progress.fsize = (long) ((finfo.st_size>0)?finfo.st_size:-1); progress.percent = 0; progress.foffset = 0; _FP_strncpy (progress.curfile, (strlen(filename)>255)? (filename+strlen(filename)-255):filename, 256); progress.action = UUACT_SCANNING; if (fileid == NULL) fileid = filename; while (!feof (datei) && !ferror (datei)) { /* * Peek file, or some systems won't detect EOF */ res = fgetc (datei); if (feof (datei) || ferror (datei)) break; else ungetc (res, datei); if ((loaded = ScanPart (datei, fileid, &sr)) == NULL) { if (sr != UURET_NODATA && sr != UURET_OK && sr != UURET_CONT) { UUkillfread (loaded); if (sr != UURET_CANCEL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, strerror (uu_errno)); } UUCheckGlobalList (); progress.action = 0; fclose (datei); return sr; } continue; } if (ferror (datei)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, strerror (uu_errno = errno)); UUCheckGlobalList (); progress.action = 0; fclose (datei); return UURET_IOERR; } if (partno != -1) loaded->partno = partno; if ((loaded->uudet == QP_ENCODED || loaded->uudet == PT_ENCODED) && (loaded->filename == NULL || *(loaded->filename) == '\0') && !uu_handletext && (loaded->flags&FL_PARTIAL)==0) { /* * Don't want text */ UUkillfread (loaded); continue; } if ((loaded->subject == NULL || *(loaded->subject) == '\0') && (loaded->mimeid == NULL || *(loaded->mimeid) == '\0') && (loaded->filename== NULL || *(loaded->filename)== '\0') && (loaded->uudet == 0)) { /* * no useful data here */ UUkillfread (loaded); if (uu_fast_scanning && sr != UURET_CONT) break; continue; } if ((fload = UUPreProcessPart (loaded, &res)) == NULL) { /* * no useful data found */ if (res != UURET_NODATA) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, (res==UURET_IOERR)?strerror(uu_errno):UUstrerror(res)); } UUkillfread (loaded); if (uu_fast_scanning && sr != UURET_CONT) break; continue; } if ((loaded->subject && *(loaded->subject)) || (loaded->mimeid && *(loaded->mimeid)) || (loaded->filename&& *(loaded->filename))|| (loaded->uudet)) { UUMessage (uulib_id, __LINE__, UUMSG_MESSAGE, uustring (S_LOADED_PART), filename, (loaded->subject) ? loaded->subject : "", (fload->subfname) ? fload->subfname : "", (loaded->filename) ? loaded->filename : "", fload->partno, (loaded->begin) ? "begin" : "", (loaded->end) ? "end" : "", codenames[loaded->uudet]); } if ((res = UUInsertPartToList (fload))) { /* * couldn't use the data */ UUkillfile (fload); if (res != UURET_NODATA) { UUCheckGlobalList (); progress.action = 0; fclose (datei); return res; } if (uu_fast_scanning && sr != UURET_CONT) break; continue; } /* * if in fast mode, we don't look any further, because we're told * that each source file holds at most one encoded part */ if (uu_fast_scanning && sr != UURET_CONT) break; if (loaded->uudet) count++; } if (ferror (datei)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), filename, strerror (uu_errno = errno)); UUCheckGlobalList (); progress.action = 0; fclose (datei); return UURET_IOERR; } fclose (datei); if (!uu_fast_scanning && count==0) { UUMessage (uulib_id, __LINE__, UUMSG_NOTE, uustring (S_NO_DATA_FOUND), filename); } progress.action = 0; UUCheckGlobalList (); return UURET_OK; } /* * decode to a temporary file. this is well handled by uudecode() */ int UUEXPORT UUDecodeToTemp (uulist *thefile) { return UUDecode (thefile); } /* * decode file first to temp file, then copy it to a final location */ int UUEXPORT UUDecodeFile (uulist *thefile, char *destname) { FILE *target, *source; struct stat finfo; int fildes, res; size_t bytes; if (thefile == NULL) return UURET_ILLVAL; if ((res = UUDecode (thefile)) != UURET_OK) if (res != UURET_NOEND || !uu_desperate) return res; if (thefile->binfile == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NO_BIN_FILE)); return UURET_IOERR; } if ((source = fopen (thefile->binfile, "rb")) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), thefile->binfile, strerror (uu_errno = errno)); return UURET_IOERR; } /* * for system security, strip setuid/setgid bits from mode */ if ((thefile->mode & 0777) != thefile->mode) { UUMessage (uulib_id, __LINE__, UUMSG_NOTE, uustring (S_STRIPPED_SETUID), destname, (int)thefile->mode); thefile->mode &= 0777; } /* * Determine the name of the target file according to the rules: * * IF (destname!=NULL) THEN filename=destname; * ELSE * filename = thefile->filename * IF (FilenameFilter!=NULL) THEN filename=FilenameFilter(filename); * filename = SaveFilePath + filename * END */ if (destname) strcpy (uugen_fnbuffer, destname); else { sprintf (uugen_fnbuffer, "%s%s", (uusavepath)?uusavepath:"", UUFNameFilter ((thefile->filename)? thefile->filename:"unknown.xxx")); } /* * if we don't want to overwrite existing files, check if it's there */ if (!uu_overwrite) { if (stat (uugen_fnbuffer, &finfo) == 0) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_TARGET_EXISTS), uugen_fnbuffer); fclose (source); return UURET_EXISTS; } } if (fstat (fileno(source), &finfo) == -1) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_STAT_FILE), thefile->binfile, strerror (uu_errno = errno)); fclose (source); return UURET_IOERR; } progress.action = 0; _FP_strncpy (progress.curfile, (strlen(uugen_fnbuffer)>255)? (uugen_fnbuffer+strlen(uugen_fnbuffer)-255):uugen_fnbuffer, 256); progress.partno = 0; progress.numparts = 1; progress.fsize = (long) ((finfo.st_size)?finfo.st_size:-1); progress.foffset = 0; progress.percent = 0; progress.action = UUACT_COPYING; if ((fildes = open (uugen_fnbuffer, O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, (uu_ignmode)?0666:thefile->mode)) == -1) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); fclose (source); return UURET_IOERR; } if ((target = fdopen (fildes, "wb")) == NULL) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_IO_ERR_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); fclose (source); close (fildes); return UURET_IOERR; } while (!feof (source)) { if (UUBUSYPOLL(ftell(source),progress.fsize)) { UUMessage (uulib_id, __LINE__, UUMSG_NOTE, uustring (S_DECODE_CANCEL)); fclose (source); fclose (target); unlink (uugen_fnbuffer); return UURET_CANCEL; } bytes = fread (uugen_inbuffer, 1, 1024, source); if (ferror (source) || (bytes == 0 && !feof (source))) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), thefile->binfile, strerror (uu_errno = errno)); fclose (source); fclose (target); unlink (uugen_fnbuffer); return UURET_IOERR; } if (fwrite (uugen_inbuffer, 1, bytes, target) != bytes) { progress.action = 0; UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_WR_ERR_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); fclose (source); fclose (target); unlink (uugen_fnbuffer); return UURET_IOERR; } } fclose (source); if (fclose (target)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_WR_ERR_TARGET), uugen_fnbuffer, strerror (uu_errno = errno)); unlink (uugen_fnbuffer); return UURET_IOERR; } /* * after a successful decoding run, we delete the temporary file */ if (unlink (thefile->binfile)) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_TMP_NOT_REMOVED), thefile->binfile, strerror (uu_errno = errno)); } _FP_free (thefile->binfile); thefile->binfile = NULL; thefile->state &= ~UUFILE_TMPFILE; thefile->state |= UUFILE_DECODED; progress.action = 0; return UURET_OK; } /* * Calls a function repeatedly with all the info we have for a file * If the function returns non-zero, we break and don't send any more */ int UUEXPORT UUInfoFile (uulist *thefile, void *opaque, int (*func) _ANSI_ARGS_((void *, char *))) { int errflag=0, res, bhflag=0, dd; long maxpos; FILE *inpfile; /* * We might need to ask our callback function to download the file */ if (uu_FileCallback) { if ((res = (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname, uugen_fnbuffer, 1)) != UURET_OK) return res; if ((inpfile = fopen (uugen_fnbuffer, "rb")) == NULL) { (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname, uugen_fnbuffer, 0); UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), uugen_fnbuffer, strerror (uu_errno = errno)); return UURET_IOERR; } } else { if ((inpfile = fopen (thefile->thisfile->data->sfname, "rb")) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_OPEN_FILE), thefile->thisfile->data->sfname, strerror (uu_errno=errno)); return UURET_IOERR; } _FP_strncpy (uugen_fnbuffer, thefile->thisfile->data->sfname, 1024); } /* * seek to beginning of info */ fseek (inpfile, thefile->thisfile->data->startpos, SEEK_SET); maxpos = thefile->thisfile->data->startpos + thefile->thisfile->data->length; while (!feof (inpfile) && (uu_fast_scanning || ftell(inpfile) < maxpos)) { if (_FP_fgets (uugen_inbuffer, 511, inpfile) == NULL) break; uugen_inbuffer[511] = '\0'; if (ferror (inpfile)) break; dd = UUValidData (uugen_inbuffer, 0, &bhflag); if (thefile->uudet == B64ENCODED && dd == B64ENCODED) break; else if (thefile->uudet == BH_ENCODED && bhflag) break; else if ((thefile->uudet == UU_ENCODED || thefile->uudet == XX_ENCODED) && strncmp (uugen_inbuffer, "begin ", 6) == 0) break; else if (thefile->uudet == YENC_ENCODED && strncmp (uugen_inbuffer, "=ybegin ", 8) == 0) break; if ((*func) (opaque, uugen_inbuffer)) break; } if (ferror (inpfile)) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_READ_ERROR), uugen_fnbuffer, strerror (uu_errno = errno)); errflag = 1; } fclose (inpfile); if (uu_FileCallback) (*uu_FileCallback) (uu_FileCBArg, thefile->thisfile->data->sfname, uugen_fnbuffer, 0); if (errflag) return UURET_IOERR; return UURET_OK; } int UUEXPORT UURenameFile (uulist *thefile, char *newname) { char *oldname; if (thefile == NULL) return UURET_ILLVAL; oldname = thefile->filename; if ((thefile->filename = _FP_strdup (newname)) == NULL) { UUMessage (uulib_id, __LINE__, UUMSG_ERROR, uustring (S_NOT_RENAME), oldname, newname); thefile->filename = oldname; return UURET_NOMEM; } _FP_free (oldname); return UURET_OK; } int UUEXPORT UURemoveTemp (uulist *thefile) { if (thefile == NULL) return UURET_ILLVAL; if (thefile->binfile) { if (unlink (thefile->binfile)) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_TMP_NOT_REMOVED), thefile->binfile, strerror (uu_errno = errno)); } _FP_free (thefile->binfile); thefile->binfile = NULL; thefile->state &= ~UUFILE_TMPFILE; } return UURET_OK; } int UUEXPORT UUCleanUp (void) { itbd *iter=ftodel, *ptr; uulist *liter; uufile *fiter; allomap *aiter; /* * delete temporary input files (such as the copy of stdin) */ while (iter) { if (unlink (iter->fname)) { UUMessage (uulib_id, __LINE__, UUMSG_WARNING, uustring (S_TMP_NOT_REMOVED), iter->fname, strerror (uu_errno = errno)); } _FP_free (iter->fname); ptr = iter; iter = iter->NEXT; _FP_free (ptr); } ftodel = NULL; /* * Delete input files after successful decoding */ if (uu_remove_input) { liter = UUGlobalFileList; while (liter) { if (liter->state & UUFILE_DECODED) { fiter = liter->thisfile; while (fiter) { if (fiter->data && fiter->data->sfname) { /* * Error code ignored. We might want to delete a file multiple * times */ unlink (fiter->data->sfname); } fiter = fiter->NEXT; } } liter = liter->NEXT; } } UUkilllist (UUGlobalFileList); UUGlobalFileList = NULL; _FP_free (uusavepath); _FP_free (uuencodeext); _FP_free (sstate.source); uusavepath = NULL; uuencodeext = NULL; UUkillheaders (&localenv); UUkillheaders (&sstate.envelope); memset (&localenv, 0, sizeof (headers)); memset (&sstate, 0, sizeof (scanstate)); while (mssdepth) { mssdepth--; UUkillheaders (&(multistack[mssdepth].envelope)); _FP_free (multistack[mssdepth].source); } /* * clean up the malloc'ed stuff */ for (aiter=toallocate; aiter->ptr; aiter++) { _FP_free (*(aiter->ptr)); *(aiter->ptr) = NULL; } return UURET_OK; } uudeview-0.5.20.orig/uulib/uunconc.c0000644001167100001440000012212710020737253017270 0ustar cphusers00000000000000/* * This file is part of uudeview, the simple and friendly multi-part multi- * file uudecoder program (c) 1994-2001 by Frank Pilhofer. The author may * be contacted at fp@fpx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * These are the functions that are responsible for decoding. The * original idea is from a freeware utility called "uunconc", and * few lines of this code may still bear a remote resemblance to * its code. If you are the author or know him, contact me. * This program could only decode one multi-part, uuencoded file * where the parts were in order. Base64, XX and BinHex decoding, * support for multi-files and part-ordering covered by myself. **/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef SYSTEM_WINDLL #include #endif #ifdef SYSTEM_OS2 #include #endif #include #include #ifdef STDC_HEADERS #include #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ERRNO_H #include #endif #include #include #include #include #include char * uunconc_id = "$Id: uunconc.c,v 1.38 2004/03/01 22:52:27 fp Exp $"; /* for braindead systems */ #ifndef SEEK_SET #ifdef L_BEGIN #define SEEK_SET L_BEGIN #else #define SEEK_SET 0 #endif #endif /* * decoder states */ #define BEGIN (1) #define DATA (2) #define END (3) #define DONE (4) /* * mallocable areas */ char *uunconc_UUxlat; char *uunconc_UUxlen; char *uunconc_B64xlat; char *uunconc_XXxlat; char *uunconc_BHxlat; char *uunconc_save; /* * decoding translation tables and line length table */ static int * UUxlen; /* initialized in UUInitConc() */ static int * UUxlat; /* from the malloc'ed areas above */ static int * B64xlat; static int * XXxlat; static int * BHxlat; /* * buffer for decoding */ static char *save[3]; /* * mallocable areas */ char *uuncdl_fulline; char *uuncdp_oline; /* * Return information for QuickDecode */ static int uulboundary; /* * To prevent warnings when using a char as index into an array */ #define ACAST(s) ((int)(unsigned char)(s)) /* * Initialize decoding tables */ void UUInitConc (void) { int i, j; /* * Update pointers */ UUxlen = (int *) uunconc_UUxlen; UUxlat = (int *) uunconc_UUxlat; B64xlat = (int *) uunconc_B64xlat; XXxlat = (int *) uunconc_XXxlat; BHxlat = (int *) uunconc_BHxlat; save[0] = uunconc_save; save[1] = uunconc_save + 256; save[2] = uunconc_save + 512; /* prepare decoding translation table */ for(i = 0; i < 256; i++) UUxlat[i] = B64xlat[i] = XXxlat[i] = BHxlat[i] = -1; /* * At some time I received a file which used lowercase characters for * uuencoding. This shouldn't be, but let's accept it. Must take special * care that this doesn't break xxdecoding. This is giving me quite a * headache. If this one file hadn't been a Pocahontas picture, I might * have ignored it for good. */ for (i = ' ', j = 0; i < ' ' + 64; i++, j++) UUxlat[i] /* = UUxlat[i+64] */ = j; for (i = '`', j = 0; i < '`' + 32; i++, j++) UUxlat[i] = j; /* add special cases */ UUxlat['`'] = UUxlat[' ']; UUxlat['~'] = UUxlat['^']; /* prepare line length table */ UUxlen[0] = 1; for(i = 1, j = 5; i <= 61; i += 3, j += 4) UUxlen[i] = UUxlen[i+1] = UUxlen[i+2] = j; /* prepare other tables */ for (i=0; i<64; i++) { B64xlat[ACAST(B64EncodeTable[i])] = i; XXxlat [ACAST(XXEncodeTable [i])] = i; BHxlat [ACAST(BHEncodeTable [i])] = i; } } /* * Workaround for Netscape */ /* * Determines whether Netscape may have broken up a data line (by * inserting a newline). This only seems to happen after ") > ptr) return 2; } ptr = string + len; while (len && (*(ptr-1)=='\015' || *(ptr-1)=='\012')) { ptr--; len--; } if (len<3) return 0; if (*--ptr == ' ') ptr--; ptr--; if (_FP_strnicmp (ptr, "",4)). If the first expression * becomes true, the costly function isn't called :-) * * Since '<', '>', '&' might even be replaced by their html equivalents * in href strings, I'm now using two passes, the first one for & + co, * the second one for hrefs. */ int UUNetscapeCollapse (char *string) { char *p1=string, *p2=string; int res = 0; if (string==NULL) return 0; /* * First pass */ while (*p1) { if (*p1 == '&') { if (_FP_strnicmp (p1, "&", 5) == 0) { p1+=5; *p2++='&'; res=1; } else if (_FP_strnicmp (p1, "<", 4) == 0) { p1+=4; *p2++='<'; res=1; } else if (_FP_strnicmp (p1, ">", 4) == 0) { p1+=4; *p2++='>'; res=1; } else *p2++ = *p1++; } else *p2++ = *p1++; } *p2 = '\0'; /* * Second pass */ p1 = p2 = string; while (*p1) { if (*p1 == '<') { if ((_FP_strnicmp (p1, "") != 0 || _FP_strstr (p1, "") != 0)) { while (*p1 && *p1!='>') p1++; if (*p1=='\0' || *(p1+1)!='<') return 0; p1++; while (*p1 && (*p1!='<' || _FP_strnicmp(p1,"",4)!=0)) { *p2++ = *p1++; } if (_FP_strnicmp(p1,"",4) != 0) return 0; p1+=4; res=1; } else *p2++ = *p1++; } else *p2++ = *p1++; } *p2 = '\0'; return res; } /* * The second parameter is 0 if we are still searching for encoded data, * otherwise it indicates the encoding we're using right now. If we're * still in the searching stage, we must be a little more strict in * deciding for or against encoding; there's too much plain text looking * like encoded data :-( */ int UUValidData (char *ptr, int encoding, int *bhflag) { int i=0, j, len=0, suspicious=0, flag=0; char *s = ptr; if ((s == NULL) || (*s == '\0')) { return 0; /* bad string */ } while (*s && *s!='\012' && *s!='\015') { s++; len++; i++; } if (i == 0) return 0; switch (encoding) { case UU_ENCODED: goto _t_UU; case XX_ENCODED: goto _t_XX; case B64ENCODED: goto _t_B64; case BH_ENCODED: goto _t_Binhex; case YENC_ENCODED: return YENC_ENCODED; } _t_Binhex: /* Binhex Test */ len = i; s = ptr; /* * bhflag notes the state we're in. Within the data, it's 1. If we're * still looking for the initial :, it's 0 */ if (*bhflag == 0 && *s != ':') { if (encoding==BH_ENCODED) return 0; goto _t_B64; } else if (*bhflag == 0 /* *s == ':' */) { s++; len--; } while (len && BHxlat[ACAST(*s)] != -1) { len--; s++; } /* allow space characters at the end of the line if we are sure */ /* that this is Binhex encoded data or the line was long enough */ flag = (*s == ':') ? 0 : 1; if (*s == ':' && len>0) { s++; len--; } if (((i>=60 && len<=10) || encoding) && *s==' ') { while (len && *s==' ') { s++; len--; } } /* * BinHex data shall have exactly 64 characters (except the last * line). We ignore everything with less than 40 characters to * be flexible */ if (len != 0 || (flag && i < 40)) { if (encoding==BH_ENCODED) return 0; goto _t_B64; } *bhflag = flag; return BH_ENCODED; _t_B64: /* Base64 Test */ len = i; s = ptr; /* * Face it: there _are_ Base64 lines that are not a multiple of four * in length :-( * * if (len%4) * goto _t_UU; */ while (len--) { if (*s < 0 || (B64xlat[ACAST(*s)] == -1 && *s != '=')) { /* allow space characters at the end of the line if we are sure */ /* that this is Base64 encoded data or the line was long enough */ if (((i>=60 && len<=10) || encoding) && *s++==' ') { while (*s==' ' && len) s++; if (len==0) return B64ENCODED; } if (encoding==B64ENCODED) return 0; goto _t_UU; } else if (*s == '=') { /* special case at end */ /* if we know this is B64encoded, allow spaces at end of line */ s++; if (*s=='=' && len>=1) { len--; s++; } if (encoding && len && *s==' ') { while (len && *s==' ') { s++; len--; } } if (len != 0) { if (encoding==B64ENCODED) return 0; goto _t_UU; } return B64ENCODED; } s++; } return B64ENCODED; _t_UU: len = i; s = ptr; if (UUxlat[ACAST(*s)] == -1) { /* uutest */ if (encoding==UU_ENCODED) return 0; goto _t_XX; } j = UUxlen[UUxlat[ACAST(*s)]]; if (len-1 == j) /* remove trailing character */ len--; if (len != j) { switch (UUxlat[ACAST(*s)]%3) { case 1: if (j-2 == len) j-=2; break; case 2: if (j-1 == len) j-=1; break; } } /* * some encoders are broken with respect to encoding the last line of * a file and produce extraoneous characters beyond the expected EOL * So were not too picky here about the last line, as long as it's longer * than necessary and shorter than the maximum * this tolerance broke the xxdecoding, because xxencoded data was * detected as being uuencoded :( so don't accept 'h' as first character * also, if the first character is lowercase, don't accept the line to * have space characters. the only encoder I've heard of which uses * lowercase characters at least accepts the special case of encoding * 0 as `. The strchr() shouldn't be too expensive here as it's only * evaluated if the first character is lowercase, which really shouldn't * be in uuencoded text. */ if (len != j && ((ptr[0] == '-' && ptr[1] == '-' && strstr(ptr,"part")!=NULL) || !(*ptr != 'M' && *ptr != 'h' && len > j && len <= UUxlen[UUxlat['M']]))) { if (encoding==UU_ENCODED) return 0; goto _t_XX; /* bad length */ } if (len != j || islower (*ptr)) { /* * if we are not in a 'uuencoded' state, don't allow the line to have * space characters at all. if we know we _are_ decoding uuencoded * data, the rest of the line, beyond the length of encoded data, may * have spaces. */ if (encoding != UU_ENCODED) if (strchr (ptr, ' ') != NULL) goto _t_XX; /* suspicious = 1; we're careful here REMOVED 0.4.15 __FP__ */ len = j; } while (len--) { if (*s < 0 || UUxlat[ACAST(*s++)] < 0) { if (encoding==UU_ENCODED) return 0; goto _t_XX; /* bad code character */ } if (*s == ' ' && suspicious) { if (encoding==UU_ENCODED) return 0; goto _t_XX; /* this line looks _too_ suspicious */ } } return UU_ENCODED; /* data is valid */ _t_XX: /* XX Test */ len = i; s = ptr; if (XXxlat[ACAST(*s)] == -1) return 0; j = UUxlen[XXxlat[ACAST(*s)]]; /* Same line length table as UUencoding */ if (len-1 == j) /* remove trailing character */ len--; if (len != j) switch (UUxlat[ACAST(*s)]%3) { case 1: if (j-2 == len) j-=2; break; case 2: if (j-1 == len) j-=1; break; } /* * some encoders are broken with respect to encoding the last line of * a file and produce extraoneous characters beyond the expected EOL * So were not too picky here about the last line, as long as it's longer * than necessary and shorter than the maximum */ if (len != j && !(*ptr != 'h' && len > j && len <= UUxlen[UUxlat['h']])) return 0; /* bad length */ while(len--) { if(*s < 0 || XXxlat[ACAST(*s++)] < 0) { return 0; /* bad code character */ } } return XX_ENCODED; /* data is valid */ } /* * This function may be called upon a line that does not look like * valid encoding on first sight, but might be erroneously encoded * data from Netscape, Lynx or MS Exchange. We might need to read * a new line from the stream, which is why we need the FILE. * Returns the type of encoded data if successful or 0 otherwise. */ int UURepairData (FILE *datei, char *line, int encoding, int *bhflag) { int nflag, vflag=0, safety=42; char *ptr; nflag = UUBrokenByNetscape (line); while (vflag == 0 && nflag && safety--) { if (nflag == 1) { /* need next line to repair */ if (strlen (line) > 250) break; ptr = line + strlen (line); while (ptr>line && (*(ptr-1)=='\015' || *(ptr-1)=='\012')) ptr--; if (_FP_fgets (ptr, 255-(ptr-line), datei) == NULL) break; } else { /* don't need next line to repair */ } if (UUNetscapeCollapse (line)) { if ((vflag = UUValidData (line, encoding, bhflag)) == 0) nflag = UUBrokenByNetscape (line); } else nflag = 0; } /* * Sometimes, a line is garbled even without it being split into * the next line. Then we try this in our despair */ if (vflag == 0) { if (UUNetscapeCollapse (line)) vflag = UUValidData (line, encoding, bhflag); } /* * If this line looks uuencoded, but the line is one character short * of a valid line, it was probably broken by MS Exchange. According * to my test cases, there is at most one space character missing; * there are never two spaces together. * If adding a space character helps making this line uuencoded, do * it! */ if (vflag == 0) { ptr = line + strlen(line); while (ptr>line && (*(ptr-1)=='\012' || *(ptr-1)=='\015')) { ptr--; } *ptr++ = ' '; *ptr-- = '\0'; if ((vflag = UUValidData (line, encoding, bhflag)) != UU_ENCODED) { *ptr = '\0'; vflag = 0; } } return vflag; } /* * Decode a single encoded line using method */ size_t UUDecodeLine (char *s, char *d, int method) { int i, j, c, cc, count=0, z1, z2, z3, z4; static int leftover=0; int *table; /* * for re-initialization */ if (s == NULL || d == NULL) { leftover = 0; return 0; } /* * To shut up gcc -Wall */ z1 = z2 = z3 = z4 = 0; if (method == UU_ENCODED || method == XX_ENCODED) { if (method == UU_ENCODED) table = UUxlat; else table = XXxlat; i = table [ACAST(*s++)]; j = UUxlen[i] - 1; while(j > 0) { c = table[ACAST(*s++)] << 2; cc = table[ACAST(*s++)]; c |= (cc >> 4); if(i-- > 0) d[count++] = c; cc <<= 4; c = table[ACAST(*s++)]; cc |= (c >> 2); if(i-- > 0) d[count++] = cc; c <<= 6; c |= table[ACAST(*s++)]; if(i-- > 0) d[count++] = c; j -= 4; } } else if (method == B64ENCODED) { if (leftover) { strcpy (uuncdl_fulline+leftover, s); leftover = 0; s = uuncdl_fulline; } while ((z1 = B64xlat[ACAST(*s)]) != -1) { if ((z2 = B64xlat[ACAST(*(s+1))]) == -1) break; if ((z3 = B64xlat[ACAST(*(s+2))]) == -1) break; if ((z4 = B64xlat[ACAST(*(s+3))]) == -1) break; d[count++] = (z1 << 2) | (z2 >> 4); d[count++] = (z2 << 4) | (z3 >> 2); d[count++] = (z3 << 6) | (z4); s += 4; } if (z1 != -1 && z2 != -1 && *(s+2) == '=') { d[count++] = (z1 << 2) | (z2 >> 4); s+=2; } else if (z1 != -1 && z2 != -1 && z3 != -1 && *(s+3) == '=') { d[count++] = (z1 << 2) | (z2 >> 4); d[count++] = (z2 << 4) | (z3 >> 2); s+=3; } while (B64xlat[ACAST(*s)] != -1) uuncdl_fulline[leftover++] = *s++; } else if (method == BH_ENCODED) { if (leftover) { strcpy (uuncdl_fulline+leftover, s); leftover = 0; s = uuncdl_fulline; } else if (*s == ':') s++; while ((z1 = BHxlat[ACAST(*s)]) != -1) { if ((z2 = BHxlat[ACAST(*(s+1))]) == -1) break; if ((z3 = BHxlat[ACAST(*(s+2))]) == -1) break; if ((z4 = BHxlat[ACAST(*(s+3))]) == -1) break; d[count++] = (z1 << 2) | (z2 >> 4); d[count++] = (z2 << 4) | (z3 >> 2); d[count++] = (z3 << 6) | (z4); s += 4; } if (z1 != -1 && z2 != -1 && *(s+2) == ':') { d[count++] = (z1 << 2) | (z2 >> 4); s+=2; } else if (z1 != -1 && z2 != -1 && z3 != -1 && *(s+3) == ':') { d[count++] = (z1 << 2) | (z2 >> 4); d[count++] = (z2 << 4) | (z3 >> 2); s+=3; } while (BHxlat[ACAST(*s)] != -1) uuncdl_fulline[leftover++] = *s++; } else if (method == YENC_ENCODED) { while (*s) { if (*s == '=') { if (*++s != '\0') { d[count++] = (char) ((int) *s - 64 - 42); s++; } } else if (*s == '\n' || *s == '\r') { s++; /* ignore */ } else { d[count++] = (char) ((int) *s++ - 42); } } } return count; } /* * ``Decode'' Quoted-Printable text */ int UUDecodeQP (FILE *datain, FILE *dataout, int *state, long maxpos, int method, int flags, char *boundary) { char *line=uugen_inbuffer, *p1, *p2; int val; uulboundary = -1; while (!feof (datain) && (ftell(datain)line && (*(ptr-1) == '\012' || *(ptr-1) == '\015')) ptr--; /* * If the part ends directly after this line, the data does not end * with a linebreak. Or, as the docs put it, "the CRLF preceding the * encapsulation line is conceptually attached to the boundary. * So if the part ends here, don't print a line break" */ if ((*ptr == '\012' || *ptr == '\015') && (ftell(datain)> 4); d[count++] = (z2 << 4) | (z3 >> 2); d[count++] = (z3 << 6) | (z4); s+=4; } if (z1 != -1 && z2 != -1 && *(s+2) == '=') { d[count++] = (z1 << 2) | (z2 >> 4); s+=2; } else if (z1 != -1 && z2 != -1 && z3 != -1 && *(s+3) == '=') { d[count++] = (z1 << 2) | (z2 >> 4); d[count++] = (z2 << 4) | (z3 >> 2); s+=3; } } else if (method == QP_ENCODED) { while (*s && (*s != '?' || *(s+1) != '=')) { while (*s && *s != '=' && (*s != '?' || *(s+1) != '=')) { d[count++] = *s++; } if (*s == '=') { if (isxdigit (*(s+1)) && isxdigit (*(s+2))) { d[count] = (isdigit (*(s+1)) ? (*(s+1)-'0') : (tolower (*(s+1))-'a'+10)) << 4; d[count] |= (isdigit (*(s+2)) ? (*(s+2)-'0') : (tolower (*(s+2))-'a'+10)); count++; s+=3; } else if (*(s+1) == '\012' || *(s+1) == '\015') { s+=2; } else { d[count++] = *s++; } } } } else { return -1; } d[count] = '\0'; return count; } int UUDecodePart (FILE *datain, FILE *dataout, int *state, long maxpos, int method, int flags, char *boundary) { char *line=uugen_fnbuffer, *oline=uuncdp_oline; int warning=0, vlc=0, lc[2], hadct=0; int tc=0, tf=0, vflag, haddata=0, haddh=0; long yefilesize=0, yepartends=0; crc32_t yepartcrc=crc32(0L, Z_NULL, 0); static crc32_t yefilecrc=0; static int bhflag=0; size_t count=0; size_t yepartsize=0; char *ptr; if (datain == NULL || dataout == NULL) { yefilecrc = crc32(0L, Z_NULL, 0); bhflag = 0; return UURET_OK; } /* * Use specialized functions for QP_ENCODED and PT_ENCODED plaintext */ if (method == QP_ENCODED) return UUDecodeQP (datain, dataout, state, maxpos, method, flags, boundary); else if (method == PT_ENCODED) return UUDecodePT (datain, dataout, state, maxpos, method, flags, boundary); lc[0] = lc[1] = 0; vflag = 0; uulboundary = -1; if (method == YENC_ENCODED) { *state = BEGIN; } while (!feof (datain) && *state != DONE && (ftell(datain) 5) tf = tc = 0; vlc = 0; continue; } /* * Busy Polls */ if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) { UUMessage (uunconc_id, __LINE__, UUMSG_NOTE, uustring (S_DECODE_CANCEL)); return UURET_CANCEL; } /* * try to make sense of data */ line[255] = '\0'; /* For Safety of string functions */ count = 0; if (boundary && line[0]=='-' && line[1]=='-' && strncmp (line+2, boundary, strlen (boundary)) == 0) { if (line[strlen(boundary)+2]=='-') uulboundary = 1; else uulboundary = 0; return UURET_OK; } /* * Use this pseudo-handling only if !FL_PROPER */ if ((flags&FL_PROPER) == 0) { if (strncmp (line, "BEGIN", 5) == 0 && _FP_strstr (line, "CUT HERE") && !tf) { /* I hate these lines */ tc = tf = vlc = 0; continue; } /* MIME body boundary */ if (line[0] == '-' && line[1] == '-' && method == B64ENCODED) { if ((haddata || tc) && (haddh || hadct)) { *state = DONE; vlc = 0; lc[0] = lc[1] = 0; continue; } hadct = 0; haddh = 1; continue; } if (_FP_strnicmp (line, "Content-Type", 12) == 0) hadct = 1; } if (*state == BEGIN) { if ((method == UU_ENCODED || method == XX_ENCODED) && (strncmp (line, "begin ", 6) == 0 || _FP_strnicmp (line, "
begin ", 11) == 0)) { /* for LYNX */
	*state = DATA;
	continue;
      }
      else if (method == BH_ENCODED && line[0] == ':') {
	if (UUValidData (line, BH_ENCODED, &bhflag) == BH_ENCODED) {
	  bhflag = 0;
	  *state = DATA;
	}
	else
	  continue;
      }
      else if (method == YENC_ENCODED &&
	       strncmp (line, "=ybegin ", 8) == 0 &&
	       _FP_strstr (line, " name=") != NULL) {
	*state = DATA;

	if ((ptr = _FP_strstr (line, " size=")) != NULL) {
	  ptr += 6;
	  yefilesize = atoi (ptr);
	}
	else {
	  yefilesize = -1;
	}

	if (_FP_strstr (line, " part=") != NULL) {
	  if (_FP_fgets (line, 255, datain) == NULL) {
	    break;
	  }

	  if ((ptr = _FP_strstr (line, " end=")) == NULL) {
	    break;
	  }
       
	  yepartends = atoi (ptr + 5);
	}
	tf = 1;
	continue;
      }
      else {
	continue;
      }
      
      tc = tf = vlc = 0;
      lc[0] = lc[1] = 0;
    }
    else if ((*state == END) &&
	     (method == UU_ENCODED || method == XX_ENCODED)) {
      if (strncmp (line, "end", 3) == 0) {
	*state = DONE;
	break;
      }
    }

    if (*state == DATA && method == YENC_ENCODED &&
	strncmp (line, "=yend ", 6) == 0) {
      if ((ptr = _FP_strstr (line, " pcrc32=")) != NULL) {
	crc32_t pcrc32 = strtoul (ptr + 8, NULL, 16);
	if (pcrc32 != yepartcrc) {
	  UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
		     uustring (S_PCRC_MISMATCH), progress.curfile, progress.partno);
	}
      }
      if ((ptr = _FP_strstr (line, " crc32=")) != NULL)
      {
	crc32_t fcrc32 = strtoul (ptr + 7, NULL, 16);
	if (fcrc32 != yefilecrc) {
	  UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
		     uustring (S_CRC_MISMATCH), progress.curfile);
	}
      }
      if ((ptr = _FP_strstr (line, " size=")) != NULL)
      {
	size_t size = atol(ptr + 6);
	if (size != yepartsize && yefilesize != -1) {
	  if (size != yefilesize)
	    UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
		       uustring (S_PSIZE_MISMATCH), progress.curfile,
		       progress.partno, yepartsize, size);
	  else
	    UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
		       uustring (S_SIZE_MISMATCH), progress.curfile,
		       yepartsize, size);
	}
      }
      if (yepartends == 0 || yepartends >= yefilesize) {
	*state = DONE;
      }
      break;
    }

    if (*state == DATA || *state == END) {
      if (method==B64ENCODED && line[0]=='-' && line[1]=='-' && tc) {
	break;
      }

      if ((vflag = UUValidData (line, (tf)?method:0, &bhflag)) == 0)
	vflag = UURepairData (datain, line, (tf)?method:0, &bhflag);

      /*
       * correct XX/UUencoded lines that were declared Base64
       */

      if ((method == XX_ENCODED || method == UU_ENCODED) &&
	  vflag == B64ENCODED) {
	if (UUValidData (line, method, &bhflag) == method)
	  vflag = method;
      }

      if (vflag == method) {
	if (tf) {
	  count  = UUDecodeLine (line, oline, method);
	  if (method == YENC_ENCODED) {
	    if (yepartends)
	      yepartcrc = crc32(yepartcrc, oline, count);
	    yefilecrc = crc32(yefilecrc, oline, count);
	    yepartsize += count;
	  }
	  vlc++; lc[1]++;
	}
	else if (tc == 3) {
	  count  = UUDecodeLine (save[0], oline,         method);
	  count += UUDecodeLine (save[1], oline + count, method);
	  count += UUDecodeLine (save[2], oline + count, method);
	  count += UUDecodeLine (line,    oline + count, method);
	  tf     = 1;
	  tc     = 0;

	  /*
	   * complain if we had one or two invalid lines amidst of
	   * correctly encoded data. This usually means that the
	   * file is in error
	   */

	  if (lc[1] > 10 && (lc[0] >= 1 && lc[0] <= 2) && !warning) {
	    UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
		       uustring (S_DATA_SUSPICIOUS));
	    warning=1;
	  }
	  lc[0] = 0;
	  lc[1] = 3;
	}
	else {
	  _FP_strncpy (save[tc++], line, 256);
	}

	if (method == UU_ENCODED)
	  *state = (line[0] == 'M') ? DATA : END;
	else if (method == XX_ENCODED)
	  *state = (line[0] == 'h') ? DATA : END;
	else if (method == B64ENCODED)
	  *state = (strchr (line, '=') == NULL) ? DATA : DONE;
	else if (method == BH_ENCODED)
	  *state = (!line[0] || strchr(line+1,':')==NULL)?DATA:DONE;
      }
      else {
	vlc = tf = tc = 0;
	haddh = 0;
	lc[0]++;
      }
    }
    else if (*state != DONE) {
      return UURET_NOEND;
    }

    if (count) {
      if (method == BH_ENCODED) {
	if (UUbhwrite (oline, 1, count, dataout) != count) {
	  UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		     uustring (S_WR_ERR_TEMP),
		     strerror (uu_errno = errno));
	  return UURET_IOERR;
	}
      }
      else if (fwrite (oline, 1, count, dataout) != count) {
	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		   uustring (S_WR_ERR_TEMP),
		   strerror (uu_errno = errno));
	return UURET_IOERR;
      }
      haddata++;
      count = 0;
    }
  }

  if (*state  == DONE ||
      (*state == DATA && method == B64ENCODED &&
       vflag == B64ENCODED && (flags&FL_PROPER || haddh))) {
    for (tf=0; tfthisfile == NULL)
    return UURET_ILLVAL;

  if (data->state & UUFILE_TMPFILE)
    return UURET_OK;

  if (data->state & UUFILE_NODATA)
    return UURET_NODATA;

  if (data->state & UUFILE_NOBEGIN && !uu_desperate)
    return UURET_NODATA;

  if (data->uudet == PT_ENCODED)
    mode = "wt";	/* open text files in text mode */
  else
    mode = "wb";	/* otherwise in binary          */

  if ((data->binfile = tempnam (NULL, "uu")) == NULL) {
    UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
	       uustring (S_NO_TEMP_NAME));
    return UURET_NOMEM;
  }

  if ((dataout = fopen (data->binfile, mode)) == NULL) {
    /*
     * we couldn't create a temporary file. Usually this means that TMP
     * and TEMP aren't set
     */
    UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
	       uustring (S_WR_ERR_TARGET),
	       data->binfile, strerror (uu_errno = errno));
    _FP_free (data->binfile);
    data->binfile = NULL;
    uu_errno = errno;
    return UURET_IOERR;
  }
  /*
   * we don't have begin lines in Base64 or plain text files.
   */
  if (data->uudet == B64ENCODED || data->uudet == QP_ENCODED ||
      data->uudet == PT_ENCODED)
    state = DATA;

  /*
   * If we know that the file does not have a begin, we simulate
   * it in desperate mode
   */

  if ((data->state & UUFILE_NOBEGIN) && uu_desperate)
    state = DATA;

  (void) UUDecodeLine (NULL, NULL, 0);                   /* init */
  (void) UUbhwrite    (NULL, 0, 0, NULL);                /* dito */
  (void) UUDecodePart (NULL, NULL, NULL, 0, 0, 0, NULL); /* yep  */

  /*
   * initialize progress information
   */
  progress.action = 0;
  if (data->filename != NULL) {
    _FP_strncpy (progress.curfile,
		 (strlen(data->filename)>255)?
		 (data->filename+strlen(data->filename)-255):data->filename,
		 256);
  }
  else {
    _FP_strncpy (progress.curfile,
		 (strlen(data->binfile)>255)?
		 (data->binfile+strlen(data->binfile)-255):data->binfile,
		 256);
  }
  progress.partno   =  0;
  progress.numparts =  0;
  progress.fsize    = -1;
  progress.percent  =  0;
  progress.action   =  UUACT_DECODING;

  iter = data->thisfile;
  while (iter) {
    progress.numparts = (iter->partno)?iter->partno:1;
    iter = iter->NEXT;
  }
  
  /*
   * let's rock!
   */

  iter = data->thisfile;
  while (iter) {
    if (part != -1 && iter->partno != part+1 && !uu_desperate)
      break;
    else
      part = iter->partno;

    if (iter->data->sfname == NULL) {
      iter = iter->NEXT;
      continue;
    }

    /*
     * call our FileCallback to retrieve the file
     */

    if (uu_FileCallback) {
      if ((res = (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname,
				     uugen_fnbuffer, 1)) != UURET_OK)
	break;
      if ((datain = fopen (uugen_fnbuffer, "rb")) == NULL) {
	(*uu_FileCallback) (uu_FileCBArg, iter->data->sfname,
			    uugen_fnbuffer, 0);
	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		   uustring (S_NOT_OPEN_FILE),
		   uugen_fnbuffer, strerror (uu_errno = errno));
	res = UURET_IOERR;
	break;
      }
    }
    else {
      if ((datain = fopen (iter->data->sfname, "rb")) == NULL) {
	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		   uustring (S_NOT_OPEN_FILE),
		   iter->data->sfname, strerror (uu_errno = errno));
	res = UURET_IOERR;
	break;
      }
      _FP_strncpy (uugen_fnbuffer, iter->data->sfname, 1024);
    }

    progress.partno  = part;
    progress.fsize   = (iter->data->length)?iter->data->length:-1;
    progress.percent = 0;
    progress.foffset = iter->data->startpos;

    fseek              (datain, iter->data->startpos, SEEK_SET);
    res = UUDecodePart (datain, dataout, &state,
			iter->data->startpos+iter->data->length,
			data->uudet, iter->data->flags, NULL);
    fclose             (datain);

    if (uu_FileCallback)
      (*uu_FileCallback) (uu_FileCBArg, iter->data->sfname, uugen_fnbuffer, 0);

    if (state == DONE || res != UURET_OK)
      break;

    iter = iter->NEXT;
  }

  if (state == DATA && 
      (data->uudet == B64ENCODED || data->uudet == QP_ENCODED ||
       data->uudet == PT_ENCODED))
    state = DONE; /* assume we're done */

  if (fclose (dataout)) {
    UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
	       uustring (S_WR_ERR_TEMP),
	       strerror (uu_errno = errno));
    res = UURET_IOERR;
  }

  if (res != UURET_OK || (state != DONE && !uu_desperate)) {
    unlink (data->binfile);
    _FP_free (data->binfile);
    data->binfile = NULL;
    data->state  &= ~UUFILE_TMPFILE;
    data->state  |=  UUFILE_ERROR;

    if (res == UURET_OK && state != DONE)
      res = UURET_NOEND;
  }
  else if (res != UURET_OK) {
    data->state &= ~UUFILE_DECODED;
    data->state |=  UUFILE_ERROR | UUFILE_TMPFILE;
  }
  else {
    data->state &= ~UUFILE_ERROR;
    data->state |=  UUFILE_TMPFILE;
  }

  /*
   * If this was a BinHex file, we must extract its data or resource fork
   */

  if (data->uudet == BH_ENCODED && data->binfile) {
    if ((ntmp = tempnam (NULL, "uu")) == NULL) {
      UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		 uustring (S_NO_TEMP_NAME));
      progress.action = 0;
      return UURET_NOMEM;
    }
    if ((datain = fopen (data->binfile, "rb")) == NULL) {
      UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		 uustring (S_NOT_OPEN_FILE),
		 data->binfile, strerror (uu_errno = errno));
      progress.action = 0;
      free (ntmp);
      return UURET_IOERR;
    }
    if ((dataout = fopen (ntmp, "wb")) == NULL) {
      UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		 uustring (S_NOT_OPEN_TARGET),
		 ntmp, strerror (uu_errno = errno));
      progress.action = 0;
      fclose (datain);
      free   (ntmp);
      return UURET_IOERR;
    }
    /*
     * read fork lengths. remember they're in Motorola format
     */
    r[0] = fgetc (datain);
    hb   = (int) r[0] + 22;
    fseek (datain, (int) r[0] + 12, SEEK_SET);
    fread (r, 1, 8, datain);

    dsize = (((long) 1 << 24) * (long) r[0]) +
            (((long) 1 << 16) * (long) r[1]) +
            (((long) 1 <<  8) * (long) r[2]) +
            (                   (long) r[3]);
    rsize = (((long) 1 << 24) * (long) r[4]) +
	    (((long) 1 << 16) * (long) r[5]) +
	    (((long) 1 <<  8) * (long) r[6]) +
	    (                   (long) r[7]);

    UUMessage (uunconc_id, __LINE__, UUMSG_MESSAGE,
	       uustring (S_BINHEX_SIZES),
	       dsize, rsize);

    if (dsize == 0) {
      fseek  (datain, dsize + hb + 2, SEEK_SET);
      numbytes = rsize;
    }
    else if (rsize == 0) {
      fseek  (datain, hb, SEEK_SET);
      numbytes = dsize;
    }
    else {
      /* we should let the user have the choice here */
      UUMessage (uunconc_id, __LINE__, UUMSG_NOTE,
		 uustring (S_BINHEX_BOTH));
      fseek  (datain, hb, SEEK_SET);
      numbytes = dsize;
    }

    progress.action   = 0;
    progress.partno   = 0;
    progress.numparts = 1;
    progress.fsize    = (numbytes)?numbytes:-1;
    progress.foffset  = hb;
    progress.percent  = 0;
    progress.action   = UUACT_COPYING;

    /*
     * copy the chosen fork
     */

    while (!feof (datain) && numbytes) {
      if (UUBUSYPOLL(ftell(datain)-progress.foffset,progress.fsize)) {
	UUMessage (uunconc_id, __LINE__, UUMSG_NOTE,
		   uustring (S_DECODE_CANCEL));
	fclose (datain);
	fclose (dataout);
	unlink (ntmp);
	free   (ntmp);
	return UURET_CANCEL;
      }

      bytes = fread (uugen_inbuffer, 1,
		     (size_t) ((numbytes>1024)?1024:numbytes), datain);

      if (ferror (datain) || (bytes == 0 && !feof (datain))) {
	progress.action = 0;
	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		   uustring (S_SOURCE_READ_ERR),
		   data->binfile, strerror (uu_errno = errno));
	fclose (datain);
	fclose (dataout);
	unlink (ntmp);
	free   (ntmp);
	return UURET_IOERR;
      }
      if (fwrite (uugen_inbuffer, 1, bytes, dataout) != bytes) {
	progress.action = 0;
	UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		   uustring (S_WR_ERR_TARGET),
		   ntmp, strerror (uu_errno = errno));
	fclose (datain);
	fclose (dataout);
	unlink (ntmp);
	free   (ntmp);
	return UURET_IOERR;
      }
      numbytes -= bytes;
    }

    if (numbytes) {
      UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
		 uustring (S_SHORT_BINHEX),
		 (data->filename)?data->filename:
		 (data->subfname)?data->subfname:"???",
		 numbytes);
    }

    /*
     * replace temp file
     */

    fclose (datain);
    if (fclose (dataout)) {
      UUMessage (uunconc_id, __LINE__, UUMSG_ERROR,
		 uustring (S_WR_ERR_TARGET),
		 ntmp, strerror (uu_errno = errno));
      unlink (ntmp);
      free   (ntmp);
      return UURET_IOERR;
    }

    if (unlink (data->binfile)) {
      UUMessage (uunconc_id, __LINE__, UUMSG_WARNING,
		 uustring (S_TMP_NOT_REMOVED),
		 data->binfile, strerror (uu_errno = errno));
    }

    free (data->binfile);
    data->binfile = ntmp;
  }

  progress.action = 0;
  return res;
}

/*
 * QuickDecode for proper MIME attachments. We expect the pointer to
 * be on the first header line.
 */

int
UUQuickDecode (FILE *datain, FILE *dataout, char *boundary, long maxpos)
{
  int state=BEGIN, encoding=-1;
  headers myenv;

  /*
   * Read header and find out about encoding.
   */

  memset (&myenv, 0, sizeof (headers));
  UUScanHeader (datain, &myenv);

  if (_FP_stristr (myenv.ctenc, "uu") != NULL)
    encoding = UU_ENCODED;
  else if (_FP_stristr (myenv.ctenc, "xx") != NULL)
    encoding = XX_ENCODED;
  else if (_FP_stricmp (myenv.ctenc, "base64") == 0)
    encoding = B64ENCODED;
  else if (_FP_stricmp (myenv.ctenc, "quoted-printable") == 0)
    encoding = QP_ENCODED;
  else
    encoding = PT_ENCODED;

  UUkillheaders (&myenv);

  /*
   * okay, so decode this one
   */

  (void) UUDecodePart (NULL, NULL, NULL, 0, 0, 0, NULL); /* init  */
  return UUDecodePart (datain, dataout, &state, maxpos,
		       encoding, FL_PROPER|FL_TOEND,
		       boundary);
}
uudeview-0.5.20.orig/uulib/uuscan.c0000644001167100001440000025077310020737253017125 0ustar  cphusers00000000000000/*
 * This file is part of uudeview, the simple and friendly multi-part multi-
 * file uudecoder  program  (c) 1994-2001 by Frank Pilhofer. The author may
 * be contacted at fp@fpx.de
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * These are very central functions of UUDeview. Here, we scan a file
 * and decide whether it contains encoded data or not. ScanPart() must
 * be called repeatedly on the same file until feof(file). Each time,
 * it returns information about the next part found within.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef SYSTEM_WINDLL
#include 
#endif
#ifdef SYSTEM_OS2
#include 
#endif

#include 
#include 

#ifdef STDC_HEADERS
#include 
#include 
#endif
#ifdef HAVE_MALLOC_H
#include 
#endif
#ifdef HAVE_UNISTD_H
#include 
#endif
#ifdef HAVE_MEMORY_H
#include 
#endif
#ifdef HAVE_ERRNO_H
#include 
#endif

#include 
#include 
#include 
#include 

char * uuscan_id = "$Id: uuscan.c,v 1.46 2004/03/01 22:52:27 fp Exp $";

/*
 * Header fields we recognize as such. See RFC822. We add "From ",
 * the usual marker for a beginning of a new message, and a couple
 * of usual MDA, News and MIME headers.
 * We make a distinction of MIME headers as we need the difference
 * to scan the bodies from partial multipart messages.
 */

static char *knownmsgheaders[] = {
  "From ", "Return-Path:", "Received:", "Reply-To:",
  "From:", "Sender:", "Resent-Reply-To:", "Resent-From:",
  "Resent-Sender:", "Date:", "Resent-Date:", "To:",
  "Resent-To:", "Cc:", "Bcc:", "Resent-bcc:",
  "Message-ID:", "Resent-Message-Id:", "In-Reply-To:",
  "References:", "Keywords:", "Subject:", "Comments:",
  
  "Delivery-Date:", "Posted-Date:", "Received-Date:",
  "Precedence:", 

  "Path:", "Newsgroups:", "Organization:", "Lines:",
  "NNTP-Posting-Host:",
  NULL
};

static char *knownmimeheaders[] = {
  "Mime-Version:",  "Content-Transfer-Encoding:",
  "Content-Type:", "Content-Disposition:", 
  "Content-Description:", "Content-Length:",
  NULL
};

/*
 * for MIME (plaintext) parts without filename
 */
int mimseqno;

/*
 * how many lines do we read when checking for headers
 */
#define WAITHEADER	10

/*
 * The stack for encapsulated Multipart messages
 */
#define MSMAXDEPTH	3

int       mssdepth = 0;
scanstate multistack[MSMAXDEPTH+1];

/*
 * The state and the local envelope
 */
headers   localenv;
scanstate sstate;

/*
 * mallocable areas
 */

char *uuscan_shlline;
char *uuscan_shlline2;
char *uuscan_pvvalue;
char *uuscan_phtext;
char *uuscan_sdline;
char *uuscan_sdbhds1;
char *uuscan_sdbhds2;
char *uuscan_spline;

/*
 * Macro: print cancellation message in UUScanPart
 */

#define SPCANCEL()	{UUMessage(uuscan_id,__LINE__,UUMSG_NOTE,uustring(S_SCAN_CANCEL));*errcode=UURET_CANCEL;goto ScanPartEmergency;}

/*
 * Is line empty? A line is empty if it is composed of whitespace.
 */

static int
IsLineEmpty (char *data)
{
  if (data == NULL) return 0;
  while (*data && isspace (*data)) data++;
  return ((*data)?0:1);
}

/*
 * Is this a header line? A header line has alphanumeric characters
 * followed by a colon.
 */

static int
IsHeaderLine (char *data)
{
  if (data == NULL) return 0;
  if (*data == ':') return 0;
  while (*data && (isalnum (*data) || *data=='-')) data++;
  return (*data == ':') ? 1 : 0;
}

/*
 * Scans a potentially folded header line from the input file. If
 * initial is non-NULL, it is the first line of the header, useful
 * if the calling function just coincidentally noticed that this is
 * a header.
 * RFC0822 does not specify a maximum length for headers, but we
 * truncate everything beyond an insane value of 1024 characters.
 */

static char *
ScanHeaderLine (FILE *datei, char *initial)
{
  char *ptr=uuscan_shlline;
  char *ptr2, *p1, *p2, *p3;
  int llength, c;
  long curpos;
  int hadcr;

  if (initial) {
    _FP_strncpy (uuscan_shlline, initial, 1024);
  }
  else {
    /* read first line */
    if (feof (datei) || ferror (datei))
      return NULL;
    if (_FP_fgets (uuscan_shlline, 1023, datei) == NULL)
      return NULL;
    uuscan_shlline[1023] = '\0';
  }

  llength = strlen (uuscan_shlline);
  hadcr   = 0;

  /* strip whitespace at end */
  ptr = uuscan_shlline + llength;
  while (llength && isspace(*(ptr-1))) {
    if (*(ptr-1) == '\012' || *(ptr-1) == '\015')
      hadcr = 1;
    ptr--; llength--;
  }
  if (llength == 0) {
    uuscan_shlline[0] = '\0';
    return uuscan_shlline;
  }

  while (!feof (datei)) {
    c = fgetc (datei);
    if (feof (datei))
      break;

    /*
     * If the line didn't have a CR, it was longer than 256 characters
     * and is continued anyway.
     */

    if (hadcr==1 && c != ' ' && c != '\t') {
      /* no LWSP-char, header line does not continue */
      ungetc (c, datei);
      break;
    }
    while (!feof (datei) && (c == ' ' || c == '\t'))
      c = fgetc (datei);

    if (!feof (datei))
      ungetc (c, datei);	/* push back for fgets() */

    /* insert a single LWSP */
    if (hadcr==1 && llength < 1023) {
      *ptr++ = ' ';
      llength++;
    }
    *ptr = '\0'; /* make lint happier */

    if (feof (datei))
      break;

    /* read next line */
    curpos = ftell (datei);
    if (_FP_fgets (uugen_inbuffer, 255, datei) == NULL)
      break;
    uugen_inbuffer[255] = '\0';

    if (IsLineEmpty (uugen_inbuffer)) { /* oops */
      fseek (datei, curpos, SEEK_SET);
      break;
    }

    _FP_strncpy (ptr, uugen_inbuffer, 1024-llength);

    /*
     * see if line was terminated with CR. Otherwise, it continues ...
     */
    c = strlen (ptr);
    if (c>0 && (ptr[c-1] == '\012' || ptr[c-1] == '\015'))
      hadcr = 1;
    else
      hadcr = 0;

    /*
     * strip whitespace
     */

    ptr     += c;
    llength += c;
    while (llength && isspace(*(ptr-1))) {
      ptr--; llength--;
    }
  }

  *ptr = '\0';

  if (llength == 0)
    return NULL;

  /*
   * Now that we've read the header line, we can RFC 1522-decode it
   */

  ptr = uuscan_shlline;
  ptr2 = uuscan_shlline2;

  while (*ptr) {
    /*
     * Look for =? magic
     */

    if (*ptr == '=' && *(ptr+1) == '?') {
      /*
       * Let p1 point to the charset, look for next question mark
       */

      p1 = p2 = ptr+2;

      while (*p2 && *p2 != '?') {
	p2++;
      }

      if (*p2 == '?' &&
	  (*(p2+1) == 'q' || *(p2+1) == 'Q' ||
	   *(p2+1) == 'b' || *(p2+1) == 'B') &&
	  *(p2+2) == '?') {
	/*
	 * Let p2 point to the encoding, look for ?= magic
	 */

	p2++;
	p3=p2+2;

	while (*p3 && (*p3 != '?' || *(p3+1) != '=')) {
	  p3++;
	}

	if (*p3 == '?' && *(p3+1) == '=') {
	  /*
	   * Alright, we've found an RFC 1522 header field
	   */
	  if (*p2 == 'q' || *p2 == 'Q') {
	    c = UUDecodeField (p2+2, ptr2, QP_ENCODED);
	  }
	  else if (*p2 == 'b' || *p2 == 'B') {
	    c = UUDecodeField (p2+2, ptr2, B64ENCODED);
	  }
	  if (c >= 0) {
	    ptr2 += c;
	    ptr = p3+2;
	    continue;
	  }
	}
      }
    }

    *ptr2++ = *ptr++;
  }

  *ptr2 = 0;

  return uuscan_shlline2;
}

/*
 * Extract the value from a MIME attribute=value pair. This function
 * receives a pointer to the attribute.
 */
static char *
ParseValue (char *attribute)
{
  char *ptr=uuscan_pvvalue;
  int length=0;

  if (attribute == NULL)
    return NULL;

  while ((isalnum(*attribute) || *attribute=='_') && *attribute != '=')
    attribute++;

  while (isspace(*attribute))
    attribute++;

  if (*attribute == '=') {
    attribute++;
    while (isspace (*attribute))
      attribute++;
  }
  else
    return NULL;

  if (*attribute == '"') {
    /* quoted-string */
    attribute++;
    while (*attribute && *attribute != '"' && length < 255) {
      *ptr++ = *attribute++;
      length++;
    }
    *ptr = '\0';
  }
  else {
    /* tspecials from RFC1521 */
    /*
     * Note - exclude '[', ']' and ';' on popular request; these are
     * used in some Content-Type fields by the Klez virus, and people
     * who feed their virus scanners with the output of UUDeview would
     * like to catch it!
     */

    while (*attribute && !isspace (*attribute) &&
	   *attribute != '(' && *attribute != ')' &&
	   *attribute != '<' && *attribute != '>' &&
	   *attribute != '@' && *attribute != ',' &&
	   /* *attribute != ';' && */ *attribute != ':' &&
	   *attribute != '\\' &&*attribute != '"' &&
	   *attribute != '/' && /* *attribute != '[' &&
	   *attribute != ']' && */ *attribute != '?' &&
	   *attribute != '=' && length < 255) {
      *ptr++ = *attribute++;
      length++;
    }

    *ptr = '\0';
  }
  return uuscan_pvvalue;
}

/*
 * Extract the information we need from header fields
 */

static headers *
ParseHeader (headers *theheaders, char *line)
{
  char **variable=NULL;
  char *value, *ptr, *thenew;
  int delimit, length;

  if (line == NULL)
    return theheaders;

  if (_FP_strnicmp (line, "From:", 5) == 0) {
    if (theheaders->from) return theheaders;
    variable = &theheaders->from;
    value    = line+5;
    delimit  = 0;
  }
  else if (_FP_strnicmp (line, "Subject:", 8) == 0) {
    if (theheaders->subject) return theheaders;
    variable = &theheaders->subject;
    value    = line+8;
    delimit  = 0;
  }
  else if (_FP_strnicmp (line, "To:", 3) == 0) {
    if (theheaders->rcpt) return theheaders;
    variable = &theheaders->rcpt;
    value    = line+3;
    delimit  = 0;
  }
  else if (_FP_strnicmp (line, "Date:", 5) == 0) {
    if (theheaders->date) return theheaders;
    variable = &theheaders->date;
    value    = line+5;
    delimit  = 0;
  }
  else if (_FP_strnicmp (line, "Mime-Version:", 13) == 0) {
    if (theheaders->mimevers) return theheaders;
    variable = &theheaders->mimevers;
    value    = line+13;
    delimit  = 0;
  }
  else if (_FP_strnicmp (line, "Content-Type:", 13) == 0) {
    if (theheaders->ctype) return theheaders;
    variable = &theheaders->ctype;
    value    = line+13;
    delimit  = ';';

    /* we can probably extract more information */
    if ((ptr = _FP_stristr (line, "boundary")) != NULL) {
      if ((thenew = ParseValue (ptr))) {
	if (theheaders->boundary) free (theheaders->boundary);
	theheaders->boundary = _FP_strdup (thenew);
      }
    }
    if ((ptr = _FP_stristr (line, "name")) != NULL) {
      if ((thenew = ParseValue (ptr))) {
	if (theheaders->fname) free (theheaders->fname);
	theheaders->fname = _FP_strdup (thenew);
      }
    }
    if ((ptr = _FP_stristr (line, "id")) != NULL) {
      if ((thenew = ParseValue (ptr))) {
	if (theheaders->mimeid) free (theheaders->mimeid);
	theheaders->mimeid = _FP_strdup (thenew);
      }
    }
    if ((ptr = _FP_stristr (line, "number")) != NULL) {
      if ((thenew = ParseValue (ptr))) {
	theheaders->partno = atoi (thenew);
      }
    }
    if ((ptr = _FP_stristr (line, "total")) != NULL) {
      if ((thenew = ParseValue (ptr))) {
	theheaders->numparts = atoi (thenew);
      }
    }
  }
  else if (_FP_strnicmp (line, "Content-Transfer-Encoding:", 26) == 0) {
    if (theheaders->ctenc) return theheaders;
    variable = &theheaders->ctenc;
    value    = line+26;
    delimit  = ';';
  }
  else if (_FP_strnicmp (line, "Content-Disposition:", 20) == 0) {
    /*
     * Some encoders mention the original filename as parameter to
     * Content-Type, others as parameter to Content-Disposition. We
     * do prefer the first solution, but accept this situation, too.
     * TODO: Read RFC1806
     */
    if ((ptr = _FP_stristr (line, "name")) != NULL) {
      if (theheaders->fname == NULL && (thenew=ParseValue(ptr)) != NULL) {
	theheaders->fname = _FP_strdup (thenew);
      }
    }
    variable = NULL;
  }
  else {
    /*
     * nothing interesting
     */
    return theheaders;
  }

  /*
   * okay, so extract the actual data
   */
  if (variable) {
    length = 0;
    ptr = uuscan_phtext;

    while (isspace (*value))
      value++;
    while (*value && (delimit==0 || *value!=delimit) &&
	   *value != '\012' && *value != '\015' && length < 255) {
      *ptr++ = *value++;
      length++;
    }
    while (length && isspace(*(ptr-1))) {
      ptr--; length--;
    }
    *ptr = '\0';

    if ((*variable = _FP_strdup (uuscan_phtext)) == NULL)
      return NULL;
  }

  return theheaders;
}

/*
 * is this a header line we know about?
 */

static int
IsKnownHeader (char *line)
{
  char **iter = knownmsgheaders;

  while (iter && *iter) {
    if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
      return 1;
    iter++;
  }

  iter = knownmimeheaders;

  while (iter && *iter) {
    if (_FP_strnicmp (line, *iter, strlen (*iter)) == 0)
      return 2;
    iter++;
  }

  return 0;
}

/*
 * Scan a header
 */

int
UUScanHeader (FILE *datei, headers *envelope)
{
  char *ptr;

  while (!feof (datei)) {
    if ((ptr = ScanHeaderLine (datei, NULL)) == NULL)
      break;
    if (*ptr == '\0' || *ptr == '\012' || *ptr == '\015')
      break;
    ParseHeader (envelope, ptr);
  }
  return 0;
}

/*
 * Scan something for encoded data and fill the fileread* structure.
 * If boundary is non-NULL, we stop after having read it. If Check-
 * Headers != 0, we also stop after we've found uu_headercount recog-
 * nized header lines.
 * If we have a boundary, then we also don't accept Base64; MIME mails
 * really should handle this properly.
 * We return -1 if something went wrong, 0 if everything is normal,
 * 1 if we found a new header and 2 if we found a boundary.
 * In MIME message bodies (not multiparts), we also disable our reduced
 * MIME handling.
 */

static int
ScanData (FILE *datei, char *fname, int *errcode,
	  char *boundary, int ismime, int checkheaders,
	  fileread *result)
{
  char *line=uuscan_sdline, *bhds1=uuscan_sdbhds1, *bhds2=uuscan_sdbhds2;
  static char *ptr, *p2, *p3=NULL, *bhdsp, bhl;
  int islen[10], isb64[10], isuue[10], isxxe[10], isbhx[10], iscnt;
  int cbb64, cbuue, cbxxe, cbbhx;
  int bhflag=0, vflag, haddh=0, hadct=0;
  int bhrpc=0, bhnf=0, c, hcount, lcount, blen=0;
  int encoding=0, dflag=0, ctline=42;
  int dontcare=0, hadnl=0;
  long preheaders=0, oldposition;
  long yefilesize=0, yepartends=0;
  size_t dcc, bhopc;

  *errcode = UURET_OK;
  (void) UUDecodeLine (NULL, NULL, 0);          /* init */
  bhdsp = bhds2;

  if (datei == NULL || feof (datei))
    return -1;

  result->startpos = ftell (datei);
  hcount = lcount  = 0;

  for (iscnt=0; iscnt<10; iscnt++) {
    isb64[iscnt] = isuue[iscnt] = isxxe[iscnt] = isbhx[iscnt] = 0;
    islen[iscnt] = -1;
  }

  iscnt = 0;

  if (boundary)
    blen = strlen (boundary);

  while (!feof (datei)) {
    oldposition = ftell (datei);
    if (_FP_fgets (line, 255, datei) == NULL)
      break;
    if (ferror (datei))
      break;

    line[255] = '\0'; /* For Safety of string functions */

    /*
     * Make Busy Polls
     */

    if (UUBUSYPOLL(ftell(datei),progress.fsize)) {
      UUMessage (uuscan_id, __LINE__, UUMSG_NOTE,
		 uustring (S_SCAN_CANCEL));
      *errcode = UURET_CANCEL;
      break;
    }

    if (IsLineEmpty (line)) { /* line empty? */
      hcount = 0;
      hadnl  = 1;
      continue;               /* then ignore */
    }

    if (checkheaders) {
      if (IsKnownHeader (line)) {
	(void) ScanHeaderLine (datei, line);

	if (hcount == 0) {
	  preheaders = oldposition;
	  lcount     = 0;
	}
	hcount++;
	lcount++;

	/*
	 * check for the various restart counters
	 */

	if ((hcount >= hlcount.restart) ||
	    (hcount >= hlcount.afterdata && ismime == 0) ||
	    (hcount >= hlcount.afterdata && result->uudet) ||
	    (hcount >= hlcount.afternl   && result->uudet && hadnl)) {
	  /*
	   * Hey, a new header starts here
	   */
	  fseek (datei, preheaders, SEEK_SET);
	  break;
	}
	/* continue; */
      }
      else if (lcount > WAITHEADER) {
	hcount = 0;
	lcount = 0;
	dontcare=0;
      }
      else if (hcount) {
	lcount++;
	dontcare=1;
      }
      else {
	dontcare=0;
      }
    }
    else {
      dontcare=0;
    }

    if (boundary != NULL && 
	line[0] == '-' && line[1] == '-' &&
	strncmp (line+2, boundary, blen) == 0) {
      fseek (datei, oldposition, SEEK_SET);
      break;
    }
    if (boundary != NULL && line[0] == 'C' && line[1] == 'o' &&
	_FP_strnicmp (line, "Content-Type:", 13) == 0) {
      ptr = ScanHeaderLine (datei, line);
      p2  = (ptr)?_FP_stristr(ptr,"boundary"):NULL;
      p3  = (p2)?ParseValue(p2):NULL;

      if (p3 && strcmp (p3, boundary) == 0) {
	fseek (datei, oldposition, SEEK_SET);
	break;
      }
      else {
	p3 = NULL;
      }
    }

    if (strncmp      (line, "begin ",       6) == 0 ||
	_FP_strnicmp (line, "
begin ", 11) == 0) {
      if ((result->begin || result->end ||
	   result->uudet == B64ENCODED ||
	   result->uudet == BH_ENCODED) && !uu_more_mime) {
	fseek (datei, oldposition, SEEK_SET);
	break;
      }
      
      if (*line == '<')
	ptr = line + 10;
      else
	ptr = line + 5;

      while (*ptr == ' ') ptr++;
      while (isdigit (*ptr)) 
	result->mode = result->mode * 8 + *ptr++ - '0';
      while (*ptr == ' ') ptr++;

      /*
       * We may have picked up a filename from a uuenview-style header
       */
      _FP_free (result->filename);
      result->filename = _FP_strdup (ptr);
      result->begin    = 1;

      while (isspace (result->filename[strlen(result->filename)-1]))
	result->filename[strlen(result->filename)-1] = '\0';

      continue;
    }

    if ((strncmp (line, "end", 3) == 0) &&
	result->uudet != BH_ENCODED &&
	result->uudet != YENC_ENCODED) {
      if (result->uudet == B64ENCODED && result->begin)
	result->uudet = XX_ENCODED;

      if (result->uudet != B64ENCODED) {
	result->end = 1;
	if (dflag && encoding)
	  result->uudet = encoding;
	continue;
      }
    }

    hadnl = 0;

    /*
     * Detect a UUDeview-Style header
     */

    if (_FP_strnicmp (line, "_=_ Part ", 9) == 0 &&
	result->uudet != YENC_ENCODED) {
      if (result->uudet) {
	fseek (datei, oldposition, SEEK_SET);
	break;
      }
      result->partno = atoi (line + 8);
      if ((ptr = _FP_stristr (line, "of file ")) != NULL) {
	ptr += 8;
	while (isspace (*ptr)) ptr++;
	p2 = ptr;
	while (isalnum(*p2) || 
	       *p2 == '.' || *p2=='_' || *p2 == '-' ||
	       *p2 == '!' || *p2=='@' || *p2 == '$')
	  p2++;
	c = *p2; *p2 = '\0';
	if (p2 != ptr && result->filename == NULL)
	  result->filename = _FP_strdup (ptr);
	else if (p2 - ptr > 5 && strchr (ptr, '.') != NULL) {
	  /*
	   * This file name looks good, too. Let's use it
	   */
	  _FP_free (result->filename);
	  result->filename = _FP_strdup (ptr);
	}
	*p2 = c;
      }
    }

    /*
     * Some reduced MIME handling. Only use if boundary == NULL. Also
     * accept the "X-Orcl-Content-Type" used by some braindead program.
     */
    if (boundary == NULL && !ismime && !uu_more_mime &&
	result->uudet != YENC_ENCODED) {
      if (_FP_strnicmp (line, "Content-Type", 12) == 0 ||
	  _FP_strnicmp (line, "X-Orcl-Content-Type", 19) == 0) {
	/*
	 * We use Content-Type to mark a new attachment and split the file.
	 * However, we do not split if we haven't found anything encoded yet.
	 */
	if (result->uudet) {
	  fseek (datei, oldposition, SEEK_SET);
	  break;
	}
	if ((ptr = strchr (line, ':')) != NULL) {
	  ptr++;
	  while (isspace (*ptr)) ptr++; p2 = ptr;
	  while (!isspace (*p2) && *p2 != ';') p2++;
	  c = *p2; *p2 = '\0';
	  if (p2 != ptr) {
	    _FP_free (result->mimetype);
	    result->mimetype = _FP_strdup (ptr);
	  }
	  *p2 = c;
	}
	ctline=0;
	hadct=1;
      }
      if ((ptr = _FP_stristr (line, "number=")) && ctline<4) {
	ptr += 7; if (*ptr == '"') ptr++;
	result->partno = atoi (ptr);
      }
      if ((ptr = _FP_stristr (line, "total=")) && ctline<4) {
	ptr += 6; if (*ptr == '"') ptr++;
	result->maxpno = atoi (ptr);
      }
      if ((ptr = _FP_stristr (line, "name=")) && ctline<4) {
	ptr += 5;
	while (isspace (*ptr)) ptr++;
	if (*ptr == '"' && *(ptr+1) && (p2 = strchr (ptr+2, '"')) != NULL) {
	  c = *p2; *p2 = '\0';
	  _FP_free (result->filename);
	  result->filename = _FP_strdup (ptr+1);
	  *p2 = c;
	}
	else if (*ptr=='\''&&*(ptr+1)&&(p2 = strchr(ptr+2, '\'')) != NULL) {
	  c = *p2; *p2 = '\0';
	  _FP_free (result->filename);
	  result->filename = _FP_strdup (ptr+1);
	  *p2 = c;
	}
	else {
	  p2 = ptr;
	  while (isalnum(*p2) || 
		 *p2 == '.' || *p2=='_' || *p2 == '-' ||
		 *p2 == '!' || *p2=='@' || *p2 == '$')
	    p2++;
	  c = *p2; *p2 = '\0';
	  if (p2 != ptr && result->filename == NULL)
	    result->filename = _FP_strdup (ptr);
	  else if (p2 - ptr > 5 && strchr (ptr, '.') != NULL) {
	    /*
	     * This file name looks good, too. Let's use it
	     */
	    _FP_free (result->filename);
	    result->filename = _FP_strdup (ptr);
	  }
	  *p2 = c;
	}
      }
      if ((ptr = _FP_stristr (line, "id=")) && ctline<4) {
	p2 = ptr += 3;
	if (*p2 == '"') {
	  p2 = strchr (++ptr, '"');
	}
	else {
	  while (*p2 && isprint(*p2) && !isspace(*p2) && *p2 != ';')
	    p2++;
	}
	if (p2 && *p2 && p2!=ptr) {
	  c = *p2; *p2 = '\0';
	  if (result->mimeid)
	    _FP_free (result->mimeid);
	  result->mimeid = _FP_strdup (ptr);
	  *p2 = c;
	}
      }
      
      /* 
       * Handling for very short Base64 files.
       */
      if (uu_tinyb64 && !ismime && !uu_more_mime) {
	if (line[0] == '-' && line[1] == '-') {
	  if (dflag && (encoding==B64ENCODED || result->uudet==B64ENCODED)) {
	    if (encoding==B64ENCODED && result->uudet==0 && (haddh||hadct)) {
	      result->uudet = encoding;
	      encoding = dflag = 0;
	    }
	    haddh = 1;
	    continue;
	  }
	  hadct = 0;
	}
      }
    } /* end of reduced MIME handling */

    /*
     * If we're in "freestyle" mode, have not encountered anything
     * interesting yet, and stumble upon something that looks like
     * a boundary, followed by a Content-* line, try to use it.
     */

    if (boundary == NULL && !ismime && !uu_more_mime && dflag <= 1 &&
	line[0] == '-' && line[1] == '-' && strlen(line+2)>10 &&
	(((ptr = _FP_strrstr (line+2, "--")) == NULL) ||
	 (*(ptr+2) != '\012' && *(ptr+2) != '\015')) &&
	_FP_strstr (line+2, "_=_") != NULL) {
      if (_FP_fgets (line, 255, datei) == NULL) {
	break;
      }
      if (_FP_strnicmp (line, "Content-", 8) == 0) {
	/*
	 * Okay, let's do it. This breaks out of ScanData. ScanPart will
	 * recognize the boundary on the next call and use it.
	 */
	fseek (datei, oldposition, SEEK_SET);
	break;
      }
    }

    /*
     * Detection for yEnc encoding
     */

    if (strncmp (line, "=ybegin ", 8) == 0 &&
	_FP_strstr (line, " name=") != NULL) {
      if ((result->begin || result->end || result->uudet) && !uu_more_mime) {
	fseek (datei, oldposition, SEEK_SET);
	break;
      }

      /*
       * name continues to the end of the line
       */
      
      _FP_free (result->filename);
      ptr = _FP_strstr (line, " name=") + 6;
      result->filename = _FP_strdup (ptr);

      while (isspace (result->filename[strlen(result->filename)-1]))
	result->filename[strlen(result->filename)-1] = '\0';

      /*
       * Determine size
       */

      if ((ptr = _FP_strstr (line, " size=")) != NULL) {
	ptr += 6;
	yefilesize = atoi (ptr);
      }
      else {
	yefilesize = -1;
      }

      /*
       * check for multipart file and read =ypart line
       */

      if ((ptr = _FP_strstr (line, " part=")) != NULL) {
	result->partno = atoi (ptr + 6);

	if (result->partno == 1) {
	  result->begin = 1;
	}

	if (_FP_fgets (line, 255, datei) == NULL) {
	  break;
	}

	line[255] = '\0';

	if (strncmp (line, "=ypart ", 7) != 0) {
	  break;
	}

	if ((ptr = _FP_strstr (line, " end=")) == NULL) {
	  break;
	}
       
	yepartends = atoi (ptr + 5);
      }
      else {
	result->partno = 1;
	result->begin = 1;
      }

      /*
       * Don't want auto-detection
       */

      result->uudet = YENC_ENCODED;
      continue;
    }

    if (strncmp (line, "=yend ", 6) == 0 &&
	result->uudet == YENC_ENCODED) {
      if (yepartends == 0 || yepartends >= yefilesize) {
	result->end = 1;
      }
#if 0
      if (!uu_more_mime)
	break;
#endif
      continue;
    }

    /*
     * if we haven't yet found anything encoded, try to find something
     */

    if (!(result->uudet)) {
      /*
       * Netscape-Repair code is the same as in uunconc.c
       */

      if ((vflag = UUValidData (line, 0, &bhflag)) == 0 && !ismime)
	vflag = UURepairData (datei, line, 0, &bhflag);

      /*
       * Check data against all possible encodings
       */

      islen[iscnt%10] = strlen(line);
      isb64[iscnt%10] = (UUValidData (line, B64ENCODED, &bhflag)==B64ENCODED);
      isuue[iscnt%10] = (UUValidData (line, UU_ENCODED, &bhflag)==UU_ENCODED);
      isxxe[iscnt%10] = (UUValidData (line, XX_ENCODED, &bhflag)==XX_ENCODED);
      isbhx[iscnt%10] = (UUValidData (line, BH_ENCODED, &bhflag)==BH_ENCODED);

      /*
       * If we've got a first valid encoded line, we get suspicious if
       * it's shorter than, say, 40 characters.
       */

      if (vflag == B64ENCODED &&
	  (dflag == 0 || encoding != B64ENCODED) &&
	  strlen (line) < 40 && !result->begin && !uu_tinyb64) {
	isb64[iscnt%10] = 0;
	vflag = 0;
      }

      if ((vflag == UU_ENCODED || vflag == XX_ENCODED) &&
	      (dflag == 0 || encoding != vflag) &&
	      strlen (line) < 40 && !result->begin) {
	isuue[iscnt%10] = isxxe[iscnt%10] = 0;
	vflag = 0;
      }

      iscnt++;

      /*
       * Ah, so we got an encoded line? How interesting!
       */

      if (vflag) {
	/*
	 * For BinHex data, we can use the initial colon ':' as begin
	 * and the terminating colon as ':'.
	 * If (vflag && !bhflag), this is the last line,
	 */
	if (vflag == BH_ENCODED) {
	  if (line[0] == ':' && result->end) {
	    fseek (datei, oldposition, SEEK_SET);
	    break;
	  }
	  if (line[0] == ':')
	    result->begin = 1;
	  if (bhflag == 0) {
	    result->uudet = BH_ENCODED;
	    result->end   = 1;
	  }
	}
	/*
	 * For BinHex files, the file name is encoded in the first encoded
	 * data bytes. We try to extract it here
	 */
	if (vflag == BH_ENCODED && bhnf == 0 && result->filename == NULL) {
	  if (bhdsp == bhds2 ||
	      ((bhdsp-bhds2) <= (int) bhds2[0] &&
	       (bhdsp-bhds2) <  256)) { 
	    dcc = UUDecodeLine (line, bhds1, BH_ENCODED);
	    UUbhdecomp (bhds1, bhdsp, &bhl, &bhrpc,
			dcc, 256-(bhdsp-bhds2), &bhopc);
	    bhdsp += bhopc;
	  }
	  if ((bhdsp-bhds2) > (int) bhds2[0] && bhds2[0]>0 &&
	      result->filename==NULL) {
	    memcpy (bhds1, bhds2+1, (int) bhds2[0]);
	    bhds1[(int)bhds2[0]]='\0';
	    result->filename = _FP_strdup (bhds1);
	    bhnf             = 1;
	  }
	  else if (bhdsp-bhds2 >= 256 && bhds2[0]>0) {
	    memcpy (bhds1, bhds2+1, 255);
	    bhds1[255]       = '\0';
	    result->filename = _FP_strdup (bhds1);
	    bhnf             = 1;
	  }
	  else if (bhds2[0] <= 0)
	    bhnf = 1;
	}

	/*
	 * We accept an encoding if it has been true for four consecutive
	 * lines. Check the is arrays to avoid mistaking one encoding
	 * for the other. Uuencoded data is rather easily mistaken for
	 * Base 64. If the data matches more than one encoding, we need to
	 * scan further.
	 *
	 * Since text can also rather easily be mistaken for UUencoded
	 * data if it just happens to have 4 lines in a row that have the
	 * correct first character for the length of the line, we also add
	 * a check that the first 3 lines must be the same length, and the
	 * 4th line must be less than or equal to that length. (since
	 * uuencoders use the same length for all lines except the last,
	 * this shouldn't increase the minimum size of UUdata we can
	 * detect, as it would if we tested all 4 lines for being the same
	 * length.)  - Matthew Mueller, 20030109
	 */

	if (iscnt > 3) {
	  cbb64 = (isb64[(iscnt-1)%10] && isb64[(iscnt-2)%10] &&
		   isb64[(iscnt-3)%10] && isb64[(iscnt-4)%10]);
	  cbuue = (isuue[(iscnt-1)%10] && isuue[(iscnt-2)%10] &&
		   isuue[(iscnt-3)%10] && isuue[(iscnt-4)%10] &&
		   islen[(iscnt-1)%10] <= islen[(iscnt-2)%10] &&
		   islen[(iscnt-2)%10] == islen[(iscnt-3)%10] &&
		   islen[(iscnt-3)%10] == islen[(iscnt-4)%10]);
	  cbxxe = (isxxe[(iscnt-1)%10] && isxxe[(iscnt-2)%10] &&
		   isxxe[(iscnt-3)%10] && isxxe[(iscnt-4)%10] &&
		   islen[(iscnt-1)%10] <= islen[(iscnt-2)%10] &&
		   islen[(iscnt-2)%10] == islen[(iscnt-3)%10] &&
		   islen[(iscnt-3)%10] == islen[(iscnt-4)%10]);
	  cbbhx = (isbhx[(iscnt-1)%10] && isbhx[(iscnt-2)%10] &&
		   isbhx[(iscnt-3)%10] && isbhx[(iscnt-4)%10]);
	}
	else {
	  cbb64 = cbuue = cbxxe = cbbhx = 0;
	}

	if (cbb64 && !cbuue && !cbxxe && !cbbhx) {
	  result->uudet = B64ENCODED;
	}
	else if (!cbb64 && cbuue && !cbxxe && !cbbhx) {
	  result->uudet = UU_ENCODED;
	}
	else if (!cbb64 && !cbuue && cbxxe && !cbbhx) {
	  result->uudet = XX_ENCODED;
	}
	else if (!cbb64 && !cbuue && !cbxxe && cbbhx) {
	  result->uudet = BH_ENCODED;
	}

	if (result->uudet) {
          encoding = dflag = 0;

	  /*
	   * If we're in fast mode, we're told we don't have to look
	   * for anything below, so we can as well break out of every-
	   * thing
	   * We cannot fast-scan if we have a boundary to look after.
	   */

	  if (uu_fast_scanning && boundary == NULL)
	    break;

	  /*
	   * Skip the encoded data. We simply wait for a boundary, for
	   * a header or for an empty line. But we also try to pick up
	   * an "end"
	   */

	  hcount = lcount = 0;

	  while (!feof (datei)) {
	    /*
	     * Make Busy Polls
	     */
	    if (UUBUSYPOLL(ftell(datei),progress.fsize)) {
	      UUMessage (uuscan_id, __LINE__, UUMSG_NOTE,
			 uustring (S_SCAN_CANCEL));
	      *errcode = UURET_CANCEL;
	      break;
	    }

	    oldposition = ftell (datei);
	    if (_FP_fgets (line, 255, datei) == NULL)
	      break;
	    if (ferror (datei))
	      break;

	    line[255] = '\0';

	    /*
	     * Stop scanning at an empty line or a MIME-boundary.
	     */
	    if (IsLineEmpty (line))
	      break;
	    if (boundary && line[0] == '-' && line[1] == '-' &&
		strncmp (line+2, boundary, blen) == 0) {
	      fseek (datei, oldposition, SEEK_SET);
	      break;
	    }
	    else if (line[0] == 'e' && (result->uudet == UU_ENCODED ||
					result->uudet == XX_ENCODED)) {
	      if (strncmp (line, "end", 3) == 0) {
		result->end = 1;
		break;
	      }
	    }
	    else if (line[0] == 'b') {
	      if (strncmp (line, "begin ", 6) == 0) {
		fseek (datei, oldposition, SEEK_SET);
		break;
	      }
	    }

	    if (checkheaders) {
	      if (IsKnownHeader (line)) {
		(void) ScanHeaderLine (datei, line);
		if (hcount == 0)
		  preheaders = oldposition;
		hcount++;
		lcount++;
		if ((hcount >= hlcount.restart) ||
		    (hcount >= hlcount.afterdata && result->uudet)) {
		  /*
		   * Hey, a new header starts here
		   */
		  fseek (datei, preheaders, SEEK_SET);
		  break;
		}
	      }
	      else if (lcount > WAITHEADER) {
		hcount = 0;
		lcount = 0;
	      }
	      else if (hcount) {
		lcount++;
	      }
	    }
	    if (result->uudet == BH_ENCODED) {
	      /* pick up ``EOF'' for BinHex files. Slow :-< */
	      if (line[0] && strchr (line+1, ':') != NULL) {
		result->end = 1;
		bhflag      = 0;
		break;
	      }
	    }
	  }

	  if (ferror (datei) || *errcode == UURET_CANCEL)
	    break;

	  if (line[0] == '-' && line[1] == '-')
	    haddh = 1;

	  /*
	   * Okay, got everything we need. If we had headers or a
	   * boundary, we break out of the outer loop immediately.
	   */

	  if (IsKnownHeader (line) ||
	      (boundary && line[0] == '-' && line[1] == '-' &&
	       strncmp (line+2, boundary, blen) == 0)) {
	    break;
	  }

	  /*
	   * Otherwise, we wait until finding something more interesting
	   * in the outer loop
	   */

	  continue;
	}
	
	/*
	 * Select the encoding with the best "history"
	 */

	cbb64 = isb64[(iscnt-1)%10];
	cbuue = isuue[(iscnt-1)%10];
	cbxxe = isxxe[(iscnt-1)%10];
	cbbhx = isbhx[(iscnt-1)%10];
	dflag = 0;

	if (cbb64 || cbuue || cbxxe || cbbhx) {
	  for (dflag=2; dflagbegin) {
	  encoding = UU_ENCODED;
	}
	else if (!encoding && cbxxe && result->begin) {
	  encoding = XX_ENCODED;
	}
	else if (!encoding && cbb64) {
	  encoding = B64ENCODED;
	}
	else if (!encoding && cbuue) {
	  encoding = UU_ENCODED;
	}
	else if (!encoding && cbxxe) {
	  encoding = XX_ENCODED;
	}
	else if (!encoding && cbbhx) {
	  encoding = BH_ENCODED;
	}
      }
      else if (!dontcare) {
	encoding = 0;
        dflag = 0;
	haddh = 0;
      }
    } /* if (!uudet) */
    /*
     * End of scanning loop
     */
  } /* while (!feof (datei)) */

  if (feof (datei))
    oldposition = ftell (datei);

  if (dflag && encoding == B64ENCODED && haddh)
    result->uudet = B64ENCODED;
  else if (dflag && encoding == BH_ENCODED)
    result->uudet = BH_ENCODED;

  /* Base64 doesn't have begin or end, so it was probably XX */
  if (result->uudet == B64ENCODED && result->begin && result->end)
    result->uudet = XX_ENCODED;

  /* Base64 doesn't have begin or end */
  if (result->uudet == B64ENCODED)
    result->begin = result->end = 0;

  /* Base64 and BinHex don't have a file mode */
  if (result->uudet == B64ENCODED || result->uudet == BH_ENCODED ||
      result->uudet == YENC_ENCODED)
    result->mode  = 6*64+4*8+4;

  /*
   * When strict MIME adherance is set, throw out suspicious attachments
   */

  if (uu_more_mime) {
    /*
     * In a MIME message, Base64 should be appropriately tagged
     */

    if (result->uudet == B64ENCODED) {
      result->uudet = 0;
    }

    /*
     * Do not accept incomplete UU or XX encoded messages
     */

    if ((result->uudet != 0 && result->uudet != B64ENCODED) &&
	(!result->begin || !result->end)) {
      result->uudet = 0;
    }
  }

  /*
   * In fast mode, this length will yield a false value. We don't care.
   * This must be checked for in uunconc(), where we usually stop decoding
   * after reaching startpos+length
   */

  if (uu_fast_scanning)
    result->length = progress.fsize-result->startpos;
  else
    result->length = ftell(datei)-result->startpos;

  if (ferror (datei)) {
    *errcode = UURET_IOERR;
    uu_errno = errno;
    return -1;
  }
  if (*errcode != UURET_OK) {
    return -1;
  }

  if (boundary && line[0] == '-' && line[1] == '-' &&
      strncmp (line+2, boundary, blen) == 0)
    return 2;
  else if (boundary && p3 &&
	   line[0] == 'C' && line[1] == 'o' &&
	   _FP_strnicmp (line, "Content-Type:", 13) == 0 &&
	   strcmp (p3, boundary) == 0)
    return 2;
  else if (IsKnownHeader (line))
    return 1;

  return 0;
}

/*
 * This is the main scanning function.
 */

fileread *
ScanPart (FILE *datei, char *fname, int *errcode)
{
  int ecount, hcount, lcount;
  int bhflag, begflag, vflag, blen=0, res;
  long preheaders, prevpos=0, preenc, before;
  char *line=uuscan_spline;
  fileread *result;
  char *ptr1, *ptr2;

  (void) UUDecodeLine (NULL, NULL, 0);          /* init */
  if (datei == NULL || feof (datei)) {
    *errcode = UURET_OK;
    return NULL;
  }

  *errcode = UURET_OK;

  if ((result = (fileread *) malloc (sizeof (fileread))) == NULL) {
    *errcode = UURET_NOMEM;
    return NULL;
  }
  memset (result, 0, sizeof (fileread));
  result->startpos = ftell (datei);
  preheaders       = result->startpos;
  before           = result->startpos;

  /* if this is a new file, reset our scanning state */
  if (sstate.source == NULL || strcmp (fname, sstate.source) != 0) {
    sstate.isfolder  = 1;		/* assume yes            */
    sstate.ismime    = 0;		/* wait for MIME-Version */
    sstate.mimestate = MS_HEADERS;	/* assume headers follow */
    /* mimseqno      = 1; */

    while (mssdepth) {
      mssdepth--;
      UUkillheaders (&(multistack[mssdepth].envelope));
      _FP_free (multistack[mssdepth].source);
    }

    UUkillheaders (&sstate.envelope);
    memset (&sstate.envelope, 0, sizeof (headers));

    _FP_free (sstate.source);
    if ((sstate.source = _FP_strdup (fname)) == NULL) {
      *errcode = UURET_NOMEM;
      _FP_free (result);
      return NULL;
    }

    /* ignore empty lines at the beginning of a file */
    preheaders = ftell (datei);
    while (!feof (datei)) {
      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
      if (_FP_fgets (line, 255, datei) == NULL)
	break;
      line[255] = '\0';
      if (!IsLineEmpty (line)) {
	fseek (datei, preheaders, SEEK_SET);
	break;
      }
      preheaders = ftell (datei);
    }
  }

  if (ferror(datei) || feof(datei)) {
    _FP_free (result);
    return NULL;
  }

  /*
   * If we are confident that this is a mail folder and are at the
   * beginning of the file, expecting to read some headers, scan
   * the envelope.
   */

  if (sstate.isfolder && sstate.mimestate == MS_HEADERS) {
    hcount = 0;
    lcount = 0;
    UUkillheaders (&sstate.envelope);

    /*
     * clean up leftovers from invalid messages
     */

    while (mssdepth) {
      mssdepth--;
      UUkillheaders (&(multistack[mssdepth].envelope));
      _FP_free (multistack[mssdepth].source);
    }

    prevpos = ftell (datei);
    if (_FP_fgets (line, 255, datei) == NULL) {
      _FP_free (result);
      return NULL;
    }
    line[255] = '\0';

    /*
     * Special handling for AOL folder files, which start off with a boundary.
     * We recognize them by a valid boundary line as the first line of a file.
     * Note that the rest of the scanning code becomes suspicious if a boun-
     * dary does never appear in a file -- this should save us from grave
     * false detection errors
     */

    if (!feof (datei) && line[0] == '-' && line[1] == '-' && line[2]) {
      while (line[strlen(line)-1] == '\012' ||
	     line[strlen(line)-1] == '\015') {
	line[strlen(line)-1] = '\0';
      }

      sstate.ismime            = 1;
      sstate.envelope.mimevers = _FP_strdup ("1.0");
      sstate.envelope.boundary = _FP_strdup (line+2);
      sstate.envelope.ctype    = _FP_strdup ("multipart/mixed");
      sstate.mimestate         = MS_SUBPART;

      *errcode = UURET_CONT;
      _FP_free (result);
      return NULL;
    }

    /*
     * Normal behavior: look for a RFC 822 header
     */

    while (!feof (datei) && !IsLineEmpty (line)) {
      if (IsKnownHeader (line))
	hcount++;
      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
      if (IsHeaderLine (line)) {
	ptr1 = ScanHeaderLine (datei, line);
	if (ParseHeader (&sstate.envelope, ptr1) == NULL) {
	  *errcode = UURET_NOMEM;
	  _FP_free (result);
	  return NULL;
	}
      }
      /*
       * if we've read too many lines without finding headers, then
       * this probably isn't a mail folder after all
       */
      lcount++;
      if (lcount > WAITHEADER && hcount < hlcount.afternl) {
	fseek (datei, prevpos, SEEK_SET);
	line[0] = '\0';
	break;
      }

      if (_FP_fgets (line, 255, datei) == NULL)
	break;
      line[255] = '\0';
    }

    /* skip empty lines */
    prevpos = ftell (datei);
    if (IsLineEmpty (line)) {
      while (!feof (datei)) {
	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	if (!IsLineEmpty (line)) {
	  fseek (datei, prevpos, SEEK_SET);
	  line[255] = '\0';
	  break;
	}
	prevpos = ftell (datei);
      }
    }

    /*
     * If we don't have all valid MIME headers yet, but the following
     * line is a MIME header, accept it anyway.
     */

    if (!uu_more_mime &&
	sstate.envelope.mimevers == NULL &&
	sstate.envelope.ctype    == NULL &&
	sstate.envelope.ctenc    == NULL &&
	IsKnownHeader (line)) {
      /*
       * see above
       */
      if (_FP_fgets (line, 255, datei) == NULL) {
	line[0] = '\012';
	line[1] = '\0';
      }
      line[255] = '\0';

      while (!feof (datei) && !IsLineEmpty (line)) {
	if (IsKnownHeader (line))
	  hcount++;
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	ptr1 = ScanHeaderLine (datei, line);
	if (ParseHeader (&sstate.envelope, ptr1) == NULL) {
	  *errcode = UURET_NOMEM;
	  _FP_free (result);
	  return NULL;
	}
	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	line[255] = '\0';
      }
      /* skip empty lines */
      prevpos = ftell (datei);
      while (!feof (datei)) {
	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	if (!IsLineEmpty (line)) {
	  fseek (datei, prevpos, SEEK_SET);
	  line[255] = '\0';
	  break;
	}
	prevpos = ftell (datei);
      }
    }

    /*
     * A partial multipart message probably has only a Content-Type
     * header but nothing else. In this case, at least simulate a
     * MIME message
     * if mimevers is not set but there are other well-known MIME
     * headers, don't be too picky about it.
     */
    if (sstate.envelope.ctype && sstate.envelope.mimevers==NULL  &&
	_FP_stristr (sstate.envelope.ctype, "multipart") != NULL &&
	sstate.envelope.boundary != NULL) {
      sstate.envelope.mimevers = _FP_strdup ("1.0");
      hcount = hlcount.afternl;
    }
    else if (sstate.envelope.mimevers==NULL && sstate.envelope.ctype &&
	     sstate.envelope.fname && sstate.envelope.ctenc) {
      sstate.envelope.mimevers = _FP_strdup ("1.0");
      hcount = hlcount.afternl;
    }

    if (sstate.envelope.mimevers != NULL) {
      /* this is a MIME file. check the Content-Type */
      sstate.ismime = 1;
      if (_FP_stristr (sstate.envelope.ctype, "multipart") != NULL) {
	if (sstate.envelope.boundary == NULL) {
	  UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		     uustring (S_MIME_NO_BOUNDARY));
	  sstate.mimestate = MS_BODY;
	  _FP_free (sstate.envelope.ctype);
	  sstate.envelope.ctype = _FP_strdup ("text/plain");
	}
	else {
	  sstate.mimestate = MS_PREAMBLE;
	}
      }
      else {
	sstate.mimestate = MS_BODY;	/* just a `simple' message */
      }
    }
    else {
      /* not a folder after all */
      fseek (datei, prevpos, SEEK_SET);
      sstate.isfolder = 0;
      sstate.ismime   = 0;
    }
  }

  if (feof (datei) || ferror (datei)) { /* oops */
    _FP_free (result);
    return NULL;
  }

  /*
   * Handle MIME stuff
   */

  /*
   * Read Preamble. This must be ended by a sstate.envelope.boundary line.
   * If uu_usepreamble is set, we produce a result from this one
   */

  if (sstate.ismime && sstate.mimestate == MS_PREAMBLE) {
    result->startpos = ftell (datei);	/* remember start of preamble */
    prevpos          = ftell (datei);
    preheaders       = ftell (datei);

    blen   = strlen (sstate.envelope.boundary);
    lcount = 0;
    
    while (!feof (datei)) {
      if (_FP_fgets (line, 255, datei) == NULL) {
	line[0] = '\0';
	break;
      }
      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
      if (line[0] == '-' && line[1] == '-' &&
	  strncmp (line+2, sstate.envelope.boundary, blen) == 0)
	break;
      if (!IsLineEmpty (line))
	lcount++;

      prevpos = ftell (datei);
    }
    if (feof (datei) || ferror (datei)) {
      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		 uustring (S_MIME_B_NOT_FOUND));
      /*
       * restart and try again; don't restart if uu_fast_scanning
       */
      sstate.isfolder  = 0;
      sstate.ismime    = 0;
      sstate.mimestate = MS_BODY;

      if (!uu_fast_scanning) {
	*errcode = UURET_CONT;
	fseek (datei, preheaders, SEEK_SET);
      }
      _FP_free (result);
      return NULL;
    }
    if (line[0] == '-' && line[1] == '-' &&
	strncmp (line+2, sstate.envelope.boundary, blen) == 0) {
      ptr1 = line + 2 + blen;
      if (*ptr1 == '-' && *(ptr1+1) == '-') {
	/* Empty Multipart Message. Duh. */
	sstate.mimestate = MS_EPILOGUE;
      }
      else {
	sstate.mimestate = MS_SUBPART;
      }
    }
    else { /* shouldn't happen */
      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		 uustring (S_MIME_B_NOT_FOUND));
      /*
       * restart and try again; don't restart if uu_fast_scanning
       */
      sstate.isfolder  = 0;
      sstate.ismime    = 0;
      sstate.mimestate = MS_BODY;

      if (!uu_fast_scanning) {
	*errcode = UURET_CONT;
	fseek (datei, preheaders, SEEK_SET);
      }
      _FP_free (result);
      return NULL;
    }
    /* produce result if uu_usepreamble is set */
    if (uu_usepreamble && lcount) {
      sprintf (line, "%04d.txt", ++mimseqno);
      result->subject  = _FP_strdup (sstate.envelope.subject);
      result->filename = _FP_strdup (line);
      result->origin   = _FP_strdup (sstate.envelope.from);
      result->mimeid   = _FP_strdup (sstate.envelope.mimeid);
      result->mimetype = _FP_strdup ("text/plain");
      result->mode     = 0644;
      result->uudet    = PT_ENCODED;	/* plain text */
      result->sfname   = _FP_strdup (fname);
      result->flags    = FL_SINGLE | FL_PROPER;
      /* result->startpos set from above */
      result->length   = prevpos - result->startpos;
      result->partno   = 1;

      /* MIME message, let's continue */
      *errcode = UURET_CONT;

      if ((sstate.envelope.subject != NULL && result->subject == NULL) ||
	  result->filename == NULL || result->sfname == NULL) {
	*errcode = UURET_NOMEM;
      }

      return result;
    }
    /* MIME message, let's continue */
    if (*errcode == UURET_OK)
      *errcode = UURET_CONT;

    /* otherwise, just return NULL */
    _FP_free (result);
    return NULL;
  }

  /*
   * Read Epilogue, the plain text after the last boundary.
   * This can either end with new headers from the next message of a
   * mail folder or with a `parent' boundary if we are inside an
   * encapsulated Multipart message. Oh yes, and of course the file
   * may also simply end :-)
   * Another possibility is that we might find plain encoded data
   * without encapsulating message. We're not _too_ flexible here,
   * we won't detect Base64, and require a proper `begin' line for
   * uuencoding and xxencoding
   * If uu_usepreamble is set, we produce a result from this one
   */

  if (sstate.ismime && sstate.mimestate == MS_EPILOGUE) {
    result->startpos = ftell (datei);	/* remember start of epilogue */
    prevpos          = ftell (datei);
    preheaders       = ftell (datei);
    preenc           = ftell (datei);
    hcount = lcount  = 0;
    ecount = bhflag  = 0;
    begflag = vflag  = 0;
    res = 0;

    /*
     * If we are in the outermost message and uu_fast_scanning, we
     * know (or assume) that no more messages will follow, so there's
     * no need to scan the rest.
     */
    if (uu_fast_scanning && mssdepth == 0) {
      /*
       * check if the epilogue is empty
       */
      while (!feof (datei) && !ferror (datei) && lcount<10 && res==0) {
	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	if (!IsLineEmpty (line))
	  res++;
	lcount++;
      }
      if (uu_usepreamble && res) {
	sprintf (line, "%04d.txt", ++mimseqno);
	result->subject  = _FP_strdup (sstate.envelope.subject);
	result->filename = _FP_strdup (line);
	result->origin   = _FP_strdup (sstate.envelope.from);
	result->mimeid   = _FP_strdup (sstate.envelope.mimeid);
	result->mimetype = _FP_strdup ("text/plain");
	result->mode     = 0644;
	result->uudet    = PT_ENCODED;	/* plain text */
	result->sfname   = _FP_strdup (fname);
	result->flags    = FL_SINGLE | FL_PROPER | FL_TOEND;
	result->partno   = 1;
	/* result->startpos set from above */
	result->length   = progress.fsize - result->startpos;

	if ((sstate.envelope.subject != NULL && result->subject == NULL) ||
	    result->filename == NULL || result->sfname == NULL) {
	  *errcode = UURET_NOMEM;
	}

	return result;
      }
      _FP_free (result);
      return NULL;
    }

    if (mssdepth > 0)
      blen = strlen (multistack[mssdepth-1].envelope.boundary);

    while (!feof (datei)) {
      if (_FP_fgets (line, 255, datei) == NULL) {
	line[0] = '\0';
	break;
      }
      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
      line[255] = '\0';
      /* check for parent boundary */
      if (mssdepth > 0 && line[0] == '-' && line[1] == '-' &&
	  strncmp (line+2,
		   multistack[mssdepth-1].envelope.boundary, blen) == 0)
	break;

      /* check for next headers only at outermost level */
      if (mssdepth == 0 && IsKnownHeader (line)) {
	(void) ScanHeaderLine (datei, line);
	if (hcount == 0) {
	  preheaders = prevpos;
	  lcount     = 0;
	}
	hcount++; 
	lcount++;

	if (hcount >= hlcount.restart) {
	  /* okay, new headers */
	  break;
	}
      }
      else if (lcount > WAITHEADER) {
	hcount = 0;
	lcount = 0;
      }
      else if (hcount) {
	lcount++;
      }
      else {
	hcount = lcount = 0;
      }

      /* check for begin and encoded data only at outermost level */
      if (mssdepth == 0 && !uu_more_mime) {
	if (strncmp      (line, "begin ",       6) == 0 ||
	    _FP_strnicmp (line, "
begin ", 11) == 0) {
	  preenc  = prevpos;
	  begflag = 1;
	}
	else if (strncmp (line, "end", 3) == 0 && begflag) {
	  ecount = ELC_COUNT;
	  break;
	}
	else if ((vflag = UUValidData (line, 0, &bhflag)) != 0) {
	  if (vflag == BH_ENCODED && bhflag == 0) {
	    /* very short BinHex file follows */
	    preenc = prevpos;
	    break;
	  }
	  /* remember that XX can easily be mistaken as Base64 */
	  if ((vflag == UU_ENCODED || vflag == XX_ENCODED ||
	       vflag == B64ENCODED) && begflag) {
	    if (++ecount >= ELC_COUNT)
	      break;
	  }
	  else {
	    begflag = 0;
	    ecount  = 0;
	  }
	}
	else {
	  begflag = 0;
	  ecount  = 0;
	}
      }

      if (!IsLineEmpty (line))
	res++;

      prevpos = ftell (datei);
    }

    if (mssdepth > 0 &&	line[0] == '-' && line[1] == '-' &&
	strncmp (line+2,
		 multistack[mssdepth-1].envelope.boundary, blen) == 0) {
      /* restore previous state */
      mssdepth--;
      UUkillheaders (&sstate.envelope);
      _FP_free  (sstate.source);
      memcpy (&sstate, &(multistack[mssdepth]), sizeof (scanstate));

      ptr1 = line + 2 + strlen (sstate.envelope.boundary);

      if (*ptr1 == '-' && *(ptr1+1) == '-') {
	sstate.mimestate = MS_EPILOGUE;
      }
      else {
	sstate.mimestate = MS_SUBPART;
      }
      result->length = prevpos - result->startpos;
      *errcode = UURET_CONT;
    }
    else if (mssdepth > 0) {
      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		 uustring (S_MIME_B_NOT_FOUND));
      /*
       * restart and try again; don't restart if uu_fast_scanning
       */
      sstate.isfolder  = 0;
      sstate.ismime    = 0;
      sstate.mimestate = MS_BODY;

      while (mssdepth) {
	mssdepth--;
	UUkillheaders (&(multistack[mssdepth].envelope));
	_FP_free (multistack[mssdepth].source);
      }

      if (!uu_fast_scanning) {
	*errcode = UURET_CONT;
	fseek (datei, preheaders, SEEK_SET);
      }
      _FP_free (result);
      return NULL;
    }
    else if (IsKnownHeader (line)) {
      /* new message follows */
      sstate.isfolder  = 1;
      sstate.ismime    = 0;
      sstate.mimestate = MS_HEADERS;
      result->length   = preheaders - result->startpos;
      fseek (datei, preheaders, SEEK_SET);
    }
    else if (ecount >= ELC_COUNT) {
      /* new plain encoding */
      sstate.isfolder  = 0;
      sstate.ismime    = 0;
      sstate.mimestate = MS_BODY;
      result->length   = preenc - result->startpos;
      fseek (datei, preenc, SEEK_SET);
    }

    /* produce result if uu_usepreamble is set */
    if (uu_usepreamble && res) {
      sprintf (line, "%04d.txt", ++mimseqno);
      result->subject  = _FP_strdup (sstate.envelope.subject);
      result->filename = _FP_strdup (line);
      result->origin   = _FP_strdup (sstate.envelope.from);
      result->mimeid   = _FP_strdup (sstate.envelope.mimeid);
      result->mimetype = _FP_strdup ("text/plain");
      result->mode     = 0644;
      result->uudet    = PT_ENCODED;	/* plain text */
      result->sfname   = _FP_strdup (fname);
      result->flags    = FL_SINGLE | FL_PROPER;
      result->partno   = 1;
      /* result->startpos set from above */
      /* result->length set from above */

      if ((sstate.envelope.subject != NULL && result->subject == NULL) ||
	  result->filename == NULL || result->sfname == NULL) {
	*errcode = UURET_NOMEM;
      }

      return result;
    }
    /* otherwise, just return NULL */
    _FP_free (result);
    return NULL;
  }

  /*
   * Scan a new part from a Multipart message. Check for a new local
   * envelope (which defaults to `Content-Type: text/plain') and
   * evaluate its Content-Type and Content-Transfer-Encoding. If this
   * is another Multipart/something, push the current state onto our
   * stack and dive into the new environment, starting with another
   * preamble.
   */
			   
  if (sstate.ismime && sstate.mimestate == MS_SUBPART) {
    memset (&localenv, 0, sizeof (headers));
    result->startpos = ftell (datei);
    prevpos = ftell (datei);
    hcount  = 0;
    lcount  = 0;

    /*
     * Duplicate some data from outer envelope
     */

    localenv.mimevers = _FP_strdup (sstate.envelope.mimevers);
    localenv.from     = _FP_strdup (sstate.envelope.from);
    localenv.subject  = _FP_strdup (sstate.envelope.subject);
    localenv.rcpt     = _FP_strdup (sstate.envelope.rcpt);
    localenv.date     = _FP_strdup (sstate.envelope.date);

    if ((sstate.envelope.mimevers != NULL && localenv.mimevers == NULL) ||
	(sstate.envelope.from     != NULL && localenv.from     == NULL) ||
	(sstate.envelope.subject  != NULL && localenv.subject  == NULL) ||
	(sstate.envelope.rcpt     != NULL && localenv.rcpt     == NULL) ||
	(sstate.envelope.date     != NULL && localenv.date     == NULL)) {

      while (mssdepth) {
	mssdepth--;
	UUkillheaders (&(multistack[mssdepth].envelope));
	_FP_free (multistack[mssdepth].source);
      }
      sstate.isfolder = 0;
      sstate.ismime   = 0;
      
      UUkillheaders (&localenv);
      *errcode = UURET_NOMEM;
      _FP_free (result);
      return NULL;
    }
    
    /* Scan subheader. But what if there is no subheader? */
    hcount = 0;
    lcount = 0;
    preheaders = prevpos;
    
    if (_FP_fgets (line, 255, datei) == NULL) {
      sstate.isfolder = 0;
      sstate.ismime   = 0;
      while (mssdepth) {
	mssdepth--;
	UUkillheaders (&(multistack[mssdepth].envelope));
	_FP_free (multistack[mssdepth].source);
      }
      UUkillheaders (&localenv);
      _FP_free (result);
      return NULL;
    }
    line[255] = '\0';

    while (!feof (datei) && !IsLineEmpty (line)) {
      if (IsKnownHeader (line))
	hcount++;
      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
      if (lcount > WAITHEADER && hcount == 0) {
	fseek (datei, preheaders, SEEK_SET);
	prevpos = preheaders;
	break;
      }
      ptr1 = ScanHeaderLine (datei, line);
      if (ParseHeader (&localenv, ptr1) == NULL)
	*errcode = UURET_NOMEM;

      if (line[0] == '-' && line[1] == '-')
	break;

      prevpos = ftell (datei);

      if (_FP_fgets (line, 255, datei) == NULL)
	break;
      line[255] = '\0';
      lcount++;
    }
    if (line[0] == '-' && line[1] == '-') {
      /*
       * this shouldn't happen, there must always be an empty line,
       * but let's accept it anyway. Just skip back to before the
       * boundary, so that it gets handled below
       */
      fseek (datei, prevpos, SEEK_SET);
    }

    if (_FP_stristr (localenv.ctype, "multipart") != NULL) {
      /* oh no, not again */
      if (mssdepth >= MSMAXDEPTH) {
	/* Argh, what an isane message. Treat as plain text */
	UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		   uustring (S_MIME_MULTI_DEPTH));
      }
      else if (localenv.boundary == NULL) {
	UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		   uustring (S_MIME_NO_BOUNDARY));
      }
      else {
	memcpy (&multistack[mssdepth], &sstate, sizeof (scanstate));
	memcpy (&sstate.envelope,    &localenv, sizeof (headers));
	memset (&localenv, 0, sizeof (headers));
	sstate.mimestate = MS_PREAMBLE;
	if ((sstate.source = _FP_strdup (sstate.source)) == NULL)
	  *errcode = UURET_NOMEM;

	if (*errcode == UURET_OK)
	  *errcode = UURET_CONT;

	mssdepth++;
	/* need a restart */
	_FP_free (result);
	return NULL;
      }
    }

    /*
     * So this subpart is either plain text or something else. Check
     * the Content-Type and Content-Transfer-Encoding. If the latter
     * is a defined value, we know what to do and just copy everything
     * up to the boundary.
     * If Content-Transfer-Encoding is unknown or missing, look at the
     * Content-Type. If it's "text/plain" or undefined, we subject the
     * message to our encoding detection. Otherwise, treat as plain
     * text.
     * This is done because users might `attach' a uuencoded file, which
     * would then be correctly typed as `text/plain'.
     */

    if (_FP_stristr (localenv.ctenc, "base64") != NULL)
      result->uudet = B64ENCODED;
    else if (_FP_stristr (localenv.ctenc, "x-uue") != NULL) {
      result->uudet = UU_ENCODED;
      result->begin = result->end = 1;
    }
    else if (_FP_stristr (localenv.ctenc, "x-yenc") != NULL) {
      result->uudet = YENC_ENCODED;
      result->begin = result->end = 1;
    }
    else if (_FP_stristr (localenv.ctenc, "quoted-printable") != NULL)
      result->uudet = QP_ENCODED;
    else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
	     _FP_stristr (localenv.ctenc, "8bit") != NULL)
      result->uudet = PT_ENCODED;
    else if (_FP_stristr (localenv.ctype, "multipart") != NULL ||
	     _FP_stristr (localenv.ctype, "message")   != NULL)
      result->uudet = PT_ENCODED;

    /*
     * If we're switched to MIME-only mode, handle as text
     */

    if (uu_more_mime >= 2 && !result->uudet) {
      result->uudet = PT_ENCODED;
    }

    if (result->uudet) {
      /*
       * Oh-kay, go ahead. Just read and wait for the boundary
       */
      result->startpos = ftell (datei);
      prevpos          = ftell (datei);
      blen = strlen (sstate.envelope.boundary);
      lcount = 0;
      
      while (!feof (datei)) {
	if (_FP_fgets (line, 255, datei) == NULL) {
	  line[0] = '\0';
	  break;
	}
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	line[255] = '\0';
	if (line[0] == '-' && line[1] == '-' &&
	    strncmp (line+2, sstate.envelope.boundary, blen) == 0)
	  break;
	/*
	 * I've had a report of someone who tried to decode a huge file
	 * that had an early truncated multipart message and later another
	 * multipart message with the *same* boundary. Consequently, all
	 * some hundred messages inbetween were ignored ...
	 * This check here doesn't cover folded header lines, but we don't
	 * want to slow down scanning too much. We just check for
	 * Content-Type: multipart/... boundary="same-boundary"
	 */
	if (line[0] == 'C' && line[1] == 'o' &&
	    _FP_strnicmp (line, "Content-Type:", 13) == 0) {
	  ptr1 = ScanHeaderLine (datei, line);
	  ptr2 = (ptr1)?_FP_stristr(ptr1,"boundary"):NULL;
	  ptr1 = (ptr2)?ParseValue(ptr2):NULL;
	  if (ptr1 && strcmp (ptr1, sstate.envelope.boundary) == 0)
	    break;
	  for (res=0; ptr1 && resstartpos, SEEK_SET);

	UUkillfread (result);
	if ((result = (fileread *) malloc (sizeof (fileread))) == NULL) {
	  *errcode = UURET_NOMEM;
	  sstate.isfolder = 0;
	  sstate.ismime   = 0;
	  UUkillheaders (&localenv);
	  return NULL;
	}
	memset (result, 0, sizeof (fileread));

	if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result))==-1) {
	  /* oops, something went wrong */
	  sstate.isfolder = 0;
	  sstate.ismime   = 0;
	  UUkillfread   (result);
	  UUkillheaders (&localenv);
	  return NULL;
	}
	if (res == 1) {
	  /*
	   * new headers found
	   */
	  sstate.isfolder  = 1;
	  sstate.ismime    = 0;
	  sstate.mimestate = MS_HEADERS;
	}
	else {
	  sstate.isfolder  = 0;
	  sstate.ismime    = 0;
	}
      }
      /* produce result if uu_handletext is set */
      /* or if the file is explicitely named */
      if (result->uudet == B64ENCODED || lcount) {
	if (localenv.fname) {
	  _FP_free (result->filename);
	  if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
	    *errcode = UURET_NOMEM;
	}
	else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
		 result->filename == NULL && uu_handletext) {
	  sprintf (line, "%04d.txt", ++mimseqno);
	  if ((result->filename = _FP_strdup (line)) == NULL)
	    *errcode = UURET_NOMEM;
	}
	result->subject  = _FP_strdup (localenv.subject);
	result->origin   = _FP_strdup (localenv.from);
	result->mimeid   = _FP_strdup (localenv.mimeid);
	result->mimetype = _FP_strdup (localenv.ctype);
	result->mode     = 0644;
	result->sfname   = _FP_strdup (fname);
	result->flags    = FL_SINGLE | FL_PROPER;
	result->partno   = 1;
	/* result->uudet determined above */
	/* result->startpos set from above */
	result->length   = prevpos - result->startpos;

	if ((localenv.subject != NULL && result->subject == NULL) ||
	    result->filename == NULL  || result->sfname == NULL) {
	  *errcode = UURET_NOMEM;
	}
      }
      else {
	/* don't produce a result */
	_FP_free (result);
	result = NULL;
      }
      if (*errcode == UURET_OK)
	*errcode = UURET_CONT;
      /*
       * destroy local envelope
       */
      UUkillheaders (&localenv);
      return result;
    }

    /*
     * we're in a subpart, but the local headers don't give us any
     * clue about what's to find here. So look for encoded data by
     * ourselves.
     */

    if ((res = ScanData (datei, fname, errcode,
			 sstate.envelope.boundary,
			 1, 0, result)) == -1) {
      /* oops, something went wrong */
      sstate.isfolder = 0;
      sstate.ismime   = 0;
      UUkillfread   (result);
      UUkillheaders (&localenv);
      return NULL;
    }
    /*
     * we should really be at a boundary here, but check again
     */
    blen    = strlen (sstate.envelope.boundary);
    prevpos = ftell  (datei);

    while (!feof (datei)) {
      if (_FP_fgets (line, 255, datei) == NULL) {
	line[0] = '\0';
	break;
      }
      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
      line[255] = '\0';
      if (line[0] == '-' && line[1] == '-' &&
	  strncmp (line+2, sstate.envelope.boundary, blen) == 0)
	break;
      if (line[0] == 'C' && line[1] == 'o' &&
	  _FP_strnicmp (line, "Content-Type:", 13) == 0) {
	ptr1 = ScanHeaderLine (datei, line);
	ptr2 = (ptr1)?_FP_stristr(ptr1,"boundary"):NULL;
	ptr1 = (ptr2)?ParseValue(ptr2):NULL;
	if (ptr1 && strcmp (ptr1, sstate.envelope.boundary) == 0)
	  break;
      }
      prevpos = ftell (datei);
    }
    /*
     * check if this was the last subpart
     */
    if (line[0] == '-' && line[1] == '-' &&
	strncmp (line+2, sstate.envelope.boundary, blen) == 0) {
      ptr1 = line + 2 + blen;
      if (*ptr1 == '-' && *(ptr1+1) == '-')
	sstate.mimestate = MS_EPILOGUE;
      else
	sstate.mimestate = MS_SUBPART;
    }
    else {
      UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		 uustring (S_MIME_B_NOT_FOUND));
      
      while (mssdepth) {
	mssdepth--;
	UUkillheaders (&(multistack[mssdepth].envelope));
	_FP_free (multistack[mssdepth].source);
      }

      if (uu_fast_scanning) {
	UUkillheaders (&localenv);
	sstate.isfolder  = 0;
	sstate.ismime    = 0;
	sstate.mimestate = MS_BODY;
	_FP_free (result);
	return NULL;
      }

      /*
       * Retry, listening to headers this time
       */
      fseek (datei, result->startpos, SEEK_SET);
      
      UUkillfread (result);
      if ((result = (fileread *) malloc (sizeof (fileread))) == NULL) {
	*errcode = UURET_NOMEM;
	sstate.isfolder = 0;
	sstate.ismime   = 0;
	UUkillheaders (&localenv);
	return NULL;
      }
      memset (result, 0, sizeof (fileread));

      if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result))==-1) {
	/* oops, something went wrong */
	sstate.isfolder = 0;
	sstate.ismime   = 0;
	UUkillfread   (result);
	UUkillheaders (&localenv);
	return NULL;
      }
      if (res == 1) {
	/*
	 * new headers found
	 */
	sstate.isfolder  = 1;
	sstate.ismime    = 0;
	sstate.mimestate = MS_HEADERS;
      }
      else {
	sstate.isfolder  = 0;
	sstate.ismime    = 0;
      }
    }

    /*
     * If this file has been nicely MIME so far, then be very suspicious
     * if ScanData reports anything else. So do a double check, and if
     * it doesn't hold up, handle as plain text instead.
     */

    if (strcmp (localenv.mimevers, "1.0") == 0 &&
	_FP_stristr (localenv.ctype, "text") != NULL &&
	sstate.ismime && sstate.mimestate == MS_SUBPART &&
	!uu_desperate) {
      if (result->uudet == UU_ENCODED && !(result->begin || result->end)) {
	result->uudet = 0;
      }
    }

    /*
     * produce result
     */

    if (result->uudet == 0) {
      result->uudet = PT_ENCODED; /* plain text */
    }

    if (localenv.fname) {
      _FP_free (result->filename);
      if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
	*errcode = UURET_NOMEM;
    }
    else if ((result->uudet==QP_ENCODED || result->uudet==PT_ENCODED) &&
	     result->filename==NULL && uu_handletext) {
      sprintf (line, "%04d.txt", ++mimseqno);
      if ((result->filename = _FP_strdup (line)) == NULL)
	*errcode = UURET_NOMEM;
    }
    else {
      /* assign a filename lateron */
    }
    if (result->mimetype) _FP_free (result->mimetype);
    if (result->uudet) {
      if (_FP_stristr (localenv.ctype, "text") != NULL &&
	  result->uudet != QP_ENCODED && result->uudet != PT_ENCODED)
	result->mimetype = NULL; /* better don't set it */
      else
	result->mimetype = _FP_strdup (localenv.ctype);
    }
    if (result->origin) _FP_free  (result->origin);
    result->origin  = _FP_strdup  (localenv.from);

    if (result->subject) _FP_free (result->subject);
    result->subject = _FP_strdup  (localenv.subject);

    if (result->sfname == NULL)
      if ((result->sfname = _FP_strdup (fname)) == NULL)
	*errcode = UURET_NOMEM;

    result->length = prevpos - result->startpos;
    result->flags  = FL_SINGLE | FL_PROPER;
    result->partno = 1;

    if (result->mode == 0)
      result->mode = 0644;

    /*
     * the other fields should already be set appropriately
     */

    if (*errcode == UURET_OK)
      *errcode = UURET_CONT;

    /*
     * kill local envelope
     */
    UUkillheaders (&localenv);
    
    return result;
  }

  /*
   * All right, so we're not in a Multipart message. Phew, took quite
   * long to figure this out. But this might still be a MIME message
   * body. And if it's a message/partial, we need more special handling
   */

  if (sstate.isfolder && sstate.ismime && sstate.mimestate == MS_BODY &&
      _FP_stristr (sstate.envelope.ctype, "message") != NULL &&
      _FP_stristr (sstate.envelope.ctype, "partial") != NULL) {

    result->startpos = ftell (datei);

    if (sstate.envelope.partno == 1) {
      /* read local envelope */
      UUkillheaders (&localenv);
      memset (&localenv, 0, sizeof (headers));

      /* skip over blank lines first */
      prevpos = ftell (datei);
      while (!feof (datei)) {
	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	line[255] = '\0';
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	if (!IsLineEmpty (line))
	  break;
	prevpos = ftell (datei);
      }
      /* Next, read header. But what if there is no subheader? */
      hcount = 0;
      lcount = 0;
      preheaders = prevpos;

      while (!feof (datei) && !IsLineEmpty (line)) {
	if (IsKnownHeader (line))
	  hcount++;
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	if (lcount > WAITHEADER && hcount == 0) {
	  fseek (datei, preheaders, SEEK_SET);
	  break;
	}
	ptr1 = ScanHeaderLine (datei, line);
	if (ParseHeader (&localenv, ptr1) == NULL)
	  *errcode = UURET_NOMEM;

	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	line[255] = '\0';
	lcount++;
      }
      prevpos = ftell (datei);
      /*
       * Examine local header. We're mostly interested in the Content-Type
       * and the Content-Transfer-Encoding.
       */
      if (_FP_stristr (localenv.ctype, "multipart") != NULL) {
	UUMessage (uuscan_id, __LINE__, UUMSG_WARNING,
		   uustring (S_MIME_PART_MULTI));
      }
      if (localenv.subject)
	result->subject  = _FP_strdup (localenv.subject);
      else
	result->subject  = _FP_strdup (sstate.envelope.subject);

      if (localenv.from)
	result->origin   = _FP_strdup (localenv.from);
      else
	result->origin   = _FP_strdup (sstate.envelope.from);

      if (localenv.ctype)
	result->mimetype = _FP_strdup (localenv.ctype);
      else
	result->mimetype = _FP_strdup ("text/plain");

      if (_FP_stristr (localenv.ctenc, "quoted-printable") != NULL)
	result->uudet = QP_ENCODED;
      else if (_FP_stristr (localenv.ctenc, "base64") != NULL)
	result->uudet = B64ENCODED;
      else if (_FP_stristr (localenv.ctenc, "x-uue") != NULL) {
	result->uudet = UU_ENCODED;
	result->begin = result->end = 1;
      }
      else if (_FP_stristr (localenv.ctenc, "x-yenc") != NULL) {
	result->uudet = YENC_ENCODED;
	result->begin = result->end = 1;
      }
      else if (_FP_stristr (localenv.ctenc, "7bit") != NULL ||
	       _FP_stristr (localenv.ctenc, "8bit") != NULL)
	result->uudet = PT_ENCODED;
      else if (_FP_stristr (localenv.ctype, "multipart") != NULL ||
	       _FP_stristr (localenv.ctype, "message")   != NULL)
	result->uudet = PT_ENCODED;

      /*
       * If we're switched to MIME-only mode, handle as text
       */

      if (uu_more_mime >= 2 && !result->uudet) {
	result->uudet = PT_ENCODED;
      }
    }
    else {
      memset (&localenv, 0, sizeof (headers));
    }

    /*
     * If this is Quoted-Printable or Plain Text, just try looking
     * for the next message header. If uu_fast_scanning, and the
     * encoding is known, there's no need to look below. Otherwise,
     * we check the type of encoding first.
     * The encoding type is determined on the first part; in all
     * others, we also don't read on.
     * If we have a partial multipart message, scan for headers, but
     * do not react on standard MIME headers, as they are probably
     * from the subparts. However, we're stuck if there's an embedded
     * message/rfc822 :-(
     * If it is a "trivial" (non-embedded) message/rfc822, skip over
     * the message header and then start looking for the next header.
     */
    if (uu_fast_scanning && (result->uudet!=0||sstate.envelope.partno!=1)) {
      /* do nothing */
      res = 0;
    }
    else if (result->uudet != 0) {
      hcount = lcount = 0;
      prevpos = ftell (datei);

      if (_FP_stristr (localenv.ctype, "message") != NULL &&
	  _FP_stristr (localenv.ctype, "rfc822")  != NULL) {
	/*
	 * skip over empty lines and local header
	 */
	preheaders = ftell (datei);
	while (!feof (datei)) {
	  if (_FP_fgets (line, 255, datei) == NULL)
	    break;
	  line[255] = '\0';
	  if (!IsLineEmpty (line)) {
	    break;
	  }
	}

	while (!feof (datei) && !IsLineEmpty (line)) { 
	  if (IsKnownHeader (line))
	    hcount++;
	  lcount++;
	  if (lcount > WAITHEADER && hcount < hlcount.afternl)
	    break;

	  if (_FP_fgets (line, 255, datei) == NULL)
	    break;
	  line[255] = '\0';
	}
	if (hcount < hlcount.afternl)
	  fseek (datei, preheaders, SEEK_SET);
	hcount = lcount = 0;
      }

      /*
       * look for next header
       */

      while (!feof (datei)) {
	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	if (ferror (datei))
	  break;
	line[255] = '\0';

	if ((vflag = IsKnownHeader (line))) {
	  (void) ScanHeaderLine (datei, line);

	  if (result->uudet != PT_ENCODED || vflag == 1) {
	    if (hcount == 0)
	      preheaders = prevpos;
	    hcount++;
	    lcount++;
	    if (hcount >= hlcount.restart) {
	      /*
	       * Hey, a new header starts here
	       */
	      fseek (datei, preheaders, SEEK_SET);
	      prevpos = preheaders;
	      break;
	    }
	  }
	}
	else if (lcount > WAITHEADER) {
	  hcount = 0;
	  lcount = 0;
	}
	else if (hcount) {
	  lcount++;
	}
	prevpos = ftell (datei);
      }
      res = 1;
    }
    else {
      /*
       * Otherwise, let's see what we can find ourself. No
       * boundary (NULL) but MIME, and respect new headers.
       */
      if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result)) == -1) {
	/* oops, something went wrong */
	sstate.isfolder = 0;
	sstate.ismime   = 0;
	UUkillfread   (result);
	UUkillheaders (&localenv);
	return NULL;
      }
      if (result->uudet == 0 && uu_handletext)
	result->uudet = PT_ENCODED;

      prevpos = ftell (datei);
    }
    /*
     * produce result
     */
    if (localenv.fname) {
      _FP_free (result->filename);
      if ((result->filename = _FP_strdup (localenv.fname)) == NULL)
	*errcode = UURET_NOMEM;
    }
    else if (sstate.envelope.fname) {
      _FP_free (result->filename);
      if ((result->filename = _FP_strdup (sstate.envelope.fname)) == NULL)
	*errcode = UURET_NOMEM;
    }
    else if ((result->uudet==QP_ENCODED || result->uudet==PT_ENCODED) &&
	     result->filename == NULL) {
      sprintf (line, "%04d.txt", ++mimseqno);
      if ((result->filename = _FP_strdup (line)) == NULL)
	*errcode = UURET_NOMEM;
    }
    else {
      /* assign a filename lateron */
    }
    if (result->subject == NULL) {
      if (sstate.envelope.subject)
	result->subject = _FP_strdup (sstate.envelope.subject);
    }
    result->partno = sstate.envelope.partno;
    result->maxpno = sstate.envelope.numparts;
    result->flags  = FL_PARTIAL | 
      ((res==1 || uu_fast_scanning) ? FL_PROPER : 0) |
	((uu_fast_scanning) ? FL_TOEND : 0);
    result->mimeid = _FP_strdup (sstate.envelope.mimeid);
    if (result->partno == 1)
      result->begin = 1;

    if (uu_fast_scanning)
      result->length = progress.fsize - result->startpos;
    else
      result->length = prevpos - result->startpos;

    if (result->sfname == NULL)
      result->sfname = _FP_strdup (fname);

    if (result->mode == 0)
      result->mode = 0644;

    /*
     * the other fields should already be set appropriately
     */

    if (res == 1) {
      /*
       * new headers found
       */
      sstate.isfolder  = 1;
      sstate.ismime    = 0;
      sstate.mimestate = MS_HEADERS;
      
      UUkillheaders (&sstate.envelope);
      memset (&sstate.envelope, 0, sizeof (headers));
    }
    else {
      /*
       * otherwise, this can't be a mail folder
       */
      sstate.isfolder  = 0;
      sstate.ismime    = 0;
    }
    /*
     * kill local envelope
     */
    UUkillheaders (&localenv);
    return result;
  }

  /*
   * If this is a MIME body, honor a Content-Type different than
   * text/plain or a proper Content-Transfer-Encoding.
   * We also go in here if we have an assigned filename - this means
   * that we've had a Content-Disposition field, and we should probably
   * decode a plain-text segment with a filename.
   */

  if (sstate.isfolder && sstate.ismime &&
      sstate.mimestate == MS_BODY &&
      (_FP_stristr (sstate.envelope.ctenc, "quoted-printable") != NULL ||
       _FP_stristr (sstate.envelope.ctenc, "base64")           != NULL ||
       _FP_stristr (sstate.envelope.ctenc, "x-uue")            != NULL ||
       _FP_stristr (sstate.envelope.ctenc, "x-yenc")           != NULL ||
       _FP_stristr (sstate.envelope.ctype, "message")          != NULL ||
       sstate.envelope.fname != NULL)) {

    if (sstate.envelope.subject)
      result->subject = _FP_strdup (sstate.envelope.subject);
    if (sstate.envelope.from)
      result->origin  = _FP_strdup (sstate.envelope.from);

    if (sstate.envelope.ctype)
      result->mimetype = _FP_strdup (sstate.envelope.ctype);
    else
      result->mimetype = _FP_strdup ("text/plain");

    if (_FP_stristr (sstate.envelope.ctenc, "quoted-printable") != NULL)
      result->uudet = QP_ENCODED;
    else if (_FP_stristr (sstate.envelope.ctenc, "base64") != NULL)
      result->uudet = B64ENCODED;
    else if (_FP_stristr (sstate.envelope.ctenc, "x-uue") != NULL) {
      result->uudet = UU_ENCODED;
      result->begin = result->end = 1;
    }
    else if (_FP_stristr (sstate.envelope.ctenc, "x-yenc") != NULL) {
      result->uudet = YENC_ENCODED;
    }
    else if (_FP_stristr (sstate.envelope.ctenc, "7bit") != NULL ||
	     _FP_stristr (sstate.envelope.ctenc, "8bit") != NULL)
      result->uudet = PT_ENCODED;
    else if (_FP_stristr (sstate.envelope.ctype, "multipart") != NULL ||
	     _FP_stristr (sstate.envelope.ctype, "message")   != NULL ||
	     sstate.envelope.fname != NULL)
      result->uudet = PT_ENCODED;

    /*
     * If we're switched to MIME-only mode, handle as text
     */

    if (uu_more_mime >= 2 && !result->uudet) {
      result->uudet = PT_ENCODED;
    }

    result->startpos = prevpos = ftell (datei);
    
    /*
     * If this is Quoted-Printable or Plain Text, just try looking
     * for the next message header. If uu_fast_scanning, we know
     * there won't be more headers.
     * If it is a "trivial" (non-embedded) message/rfc822, skip over
     * the message header and then start looking for the next header.
     */
    if (result->uudet != 0 && uu_fast_scanning) {
      /* do nothing */
      res = 0;
    }
    else if (result->uudet != 0) {
      hcount = lcount = 0;
      prevpos = ftell (datei);

      if (_FP_stristr (sstate.envelope.ctype, "message") != NULL &&
	  _FP_stristr (sstate.envelope.ctype, "rfc822")  != NULL) {
	/*
	 * skip over empty lines and local header
	 */
	preheaders = ftell (datei);
	while (!feof (datei)) {
	  if (_FP_fgets (line, 255, datei) == NULL)
	    break;
	  line[255] = '\0';
	  if (!IsLineEmpty (line)) {
	    break;
	  }
	}

	while (!feof (datei) && !IsLineEmpty (line)) { 
	  if (IsKnownHeader (line))
	    hcount++;
	  lcount++;
	  if (lcount > WAITHEADER && hcount < hlcount.afternl)
	    break;

	  if (_FP_fgets (line, 255, datei) == NULL)
	    break;
	  line[255] = '\0';
	}
	if (hcount < hlcount.afternl)
	  fseek (datei, preheaders, SEEK_SET);
	hcount = lcount = 0;
      }

      /*
       * look for next header
       */

      while (!feof (datei)) {
	if (_FP_fgets (line, 255, datei) == NULL)
	  break;
	if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
	if (ferror (datei))
	  break;
	line[255] = '\0';

	if (IsKnownHeader (line)) {
	  (void) ScanHeaderLine (datei, line);
	  if (hcount == 0)
	    preheaders = prevpos;
	  hcount++;
	  lcount++;
	  if (hcount >= hlcount.restart) {
	    /*
	     * Hey, a new header starts here
	     */
	    fseek (datei, preheaders, SEEK_SET);
	    prevpos = preheaders;
	    break;
	  }
	}
	else if (lcount > WAITHEADER) {
	  hcount = 0;
	  lcount = 0;
	}
	else if (hcount) {
	  lcount++;
	}
	prevpos = ftell (datei);
      }
      res = 1;
    }
    else {
      /*
       * Otherwise, let's see what we can find ourself. No
       * boundary (NULL) but MIME, and respect new headers.
       */
      if ((res = ScanData (datei, fname, errcode, NULL, 1, 1, result)) == -1) {
	/* oops, something went wrong */
	sstate.isfolder = 0;
	sstate.ismime   = 0;
	UUkillfread   (result);
	return NULL;
      }
      if (result->uudet == 0 && uu_handletext) {
	result->startpos = before;	/* display headers */
	result->uudet = PT_ENCODED;
      }

      prevpos = ftell (datei);
    }
    /*
     * produce result
     */
    if (sstate.envelope.fname) {
      _FP_free (result->filename);
      if ((result->filename = _FP_strdup (sstate.envelope.fname)) == NULL)
	*errcode = UURET_NOMEM;
    }
    else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
	     result->filename == NULL) {
      sprintf (line, "%04d.txt", ++mimseqno);
      if ((result->filename = _FP_strdup (line)) == NULL)
	*errcode = UURET_NOMEM;
    }
    else {
      /* assign a filename lateron */
    }
    if (result->subject == NULL) {
      if (sstate.envelope.subject)
	result->subject = _FP_strdup (sstate.envelope.subject);
    }
    result->flags  = ((res==1||uu_fast_scanning)?FL_PROPER:0) |
      ((uu_fast_scanning) ? FL_TOEND : 0);
    result->mimeid = _FP_strdup (sstate.envelope.mimeid);

    if (uu_fast_scanning)
      result->length = progress.fsize - result->startpos;
    else
      result->length = prevpos - result->startpos;

    if (result->sfname == NULL)
      result->sfname = _FP_strdup (fname);

    if (result->mode == 0)
      result->mode = 0644;

    /*
     * the other fields should already be set appropriately
     */

    if (res == 1) {
      /*
       * new headers found
       */
      sstate.isfolder  = 1;
      sstate.ismime    = 0;
      sstate.mimestate = MS_HEADERS;

      UUkillheaders (&sstate.envelope);
      memset (&sstate.envelope, 0, sizeof (headers));
    }
    else {
      /*
       * otherwise, this can't be a mail folder
       */
      sstate.isfolder  = 0;
      sstate.ismime    = 0;
    }

    return result;
  }

  /*
   * Some files have reduced headers, and what should be a multipart
   * message is missing the proper Content-Type. If the first thing
   * we find after a couple of empty lines is a boundary, try it!
   * But make sure that this is indeed intended as being a boundary.
   *
   * Only accept it if there was indeed no Content-Type header line
   * and if the following line is a proper Content-Type header. BTW,
   * we know that sstate.envelope.boundary is NULL, or we wouldn't
   * be here!
   */

  if ((sstate.envelope.ctype == NULL ||
       _FP_stristr (sstate.envelope.ctype, "multipart") != NULL) &&
      !uu_more_mime) {
    prevpos = ftell (datei);
    while (!feof (datei)) {
      if (_FP_fgets (line, 255, datei) == NULL) {
	line[0] = '\0';
	break;
      }
      if (UUBUSYPOLL(ftell(datei),progress.fsize)) SPCANCEL();
      if (!IsLineEmpty (line))
	break;
    }
    if (line[0] == '-' && line[1] == '-' &&
	!IsLineEmpty (line+2) && !feof (datei)) {
      ptr1 = _FP_strrstr (line+2, "--");
      ptr2 = ScanHeaderLine (datei, NULL);
      if ((ptr1 == NULL || (*(ptr1+2) != '\012' && *(ptr1+2) != '\015')) &&
	  ptr2 && _FP_strnicmp (ptr2, "Content-", 8) == 0) {
	/*
	 * hmm, okay, let's do it!
	 */
	sstate.isfolder  = 1;
	sstate.ismime    = 1;
	sstate.mimestate = MS_PREAMBLE;
	/*
	 * get boundary
	 */
	ptr1 = line+2;
	while (*ptr1 && !isspace(*ptr1))
	  ptr1++;
	*ptr1 = '\0';

	sstate.envelope.mimevers = _FP_strdup ("1.0");
	sstate.envelope.boundary = _FP_strdup (line+2);
	
	/*
	 * need restart
	 */
	
	fseek (datei, prevpos, SEEK_SET);
	
	_FP_free (result);
	return NULL;
      }
    }
    fseek (datei, prevpos, SEEK_SET);
  }

  /*
   * Hmm, we're not in a ''special'' state, so it's more or less
   * Freestyle time. Anyway, if this seems to be a Mime message,
   * don't allow the minimal Base64 handling.
   */

  if (sstate.envelope.subject)
    result->subject = _FP_strdup (sstate.envelope.subject);
  if (sstate.envelope.from)
    result->origin  = _FP_strdup (sstate.envelope.from);

  if (sstate.envelope.ctype)
    result->mimetype = _FP_strdup (sstate.envelope.ctype);
  
  if ((res=ScanData (datei, fname, errcode, NULL, 
		     sstate.ismime, 1, result))==-1) {
    /* oops, something went wrong */
    sstate.isfolder = 0;
    sstate.ismime   = 0;
    UUkillfread   (result);
    return NULL;
  }

  /*
   * produce result
   */

  if (result->uudet == 0 && uu_handletext) {
    result->startpos = before;	/* display headers */
    result->uudet  = PT_ENCODED;
    result->partno = 1;
  }

  if (result->uudet == YENC_ENCODED && result->filename != NULL) {
    /*
     * prevent replacing the filename found on the =ybegin line
     */
  }
  else if (sstate.envelope.fname) {
    _FP_free (result->filename);
    if ((result->filename = _FP_strdup (sstate.envelope.fname)) == NULL)
      *errcode = UURET_NOMEM;
  }
  else if ((result->uudet==QP_ENCODED||result->uudet==PT_ENCODED) &&
	   result->filename == NULL) {
    sprintf (line, "%04d.txt", ++mimseqno);
    if ((result->filename = _FP_strdup (line)) == NULL)
      *errcode = UURET_NOMEM;
  }
  else {
    /* assign a filename lateron */
  }

  if (result->subject == NULL) {
    if (sstate.envelope.subject)
      result->subject = _FP_strdup (sstate.envelope.subject);
  }

  result->flags  = (result->uudet==PT_ENCODED)?FL_SINGLE:0;
  result->mimeid = _FP_strdup (sstate.envelope.mimeid);
  result->length = ftell (datei) - result->startpos;

  if (result->mode == 0)
    result->mode = 0644;

  if (result->sfname == NULL)
    result->sfname = _FP_strdup (fname);

  if (res == 1) {
    /*
     * new headers found
     */
    sstate.isfolder  = 1;
    sstate.ismime    = 0;
    sstate.mimestate = MS_HEADERS;

    UUkillheaders (&sstate.envelope);
    memset (&sstate.envelope, 0, sizeof (headers));
  }
  else {
    /*
     * otherwise, this can't be a mail folder
     */
    sstate.isfolder  = 0;
    sstate.ismime    = 0;
  }

  return result;

  /*
   * Emergency handling. Set errcode before jumping here.
   */
 ScanPartEmergency:
  UUkillfread   (result);
  UUkillheaders (&localenv);

  while (mssdepth) {
    mssdepth--;
    UUkillheaders (&(multistack[mssdepth].envelope));
    _FP_free (multistack[mssdepth].source);
  }

  return NULL;
}

uudeview-0.5.20.orig/uulib/uustring.awk0000644001167100001440000000074606166545100020044 0ustar  cphusers00000000000000#! /usr/bin/awk
#
# $Id: uustring.awk,v 1.2 1996/07/03 19:30:08 fp Exp $
#
# Extract definitions for string codes from uustring.c into uustring.h
# Does this script require GAWK?
#
BEGIN		{ i=1; }
/\$Id/		{
		  match ($0, "\\$Id.*\\$");
		  printf ("/* extracted from %s */\n",
			  substr ($0, RSTART+1, RLENGTH-2));
		}
/^[ 	]*\{[ 	]*S_[A-Z_]+.*\}[ 	]*,[ 	]*$/ {
		  match ($0, "S_[A-Z_]+");
		  printf ("#define %-20s %3d\n",
			  substr ($0, RSTART, RLENGTH),
			  i);
		  i++;
		}
uudeview-0.5.20.orig/uulib/uustring.c0000644001167100001440000001217007443072703017501 0ustar  cphusers00000000000000/*
 * This file is part of uudeview, the simple and friendly multi-part multi-
 * file uudecoder  program  (c) 1994-2001 by Frank Pilhofer. The author may
 * be contacted at fp@fpx.de
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * Strings used in the library for easier translation etc.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef SYSTEM_WINDLL
#include 
#endif
#ifdef SYSTEM_OS2
#include 
#endif

#include 
#include 

#ifdef STDC_HEADERS
#include 
#include 
#endif
#ifdef HAVE_MALLOC_H
#include 
#endif
#ifdef HAVE_UNISTD_H
#include 
#endif
#ifdef HAVE_MEMORY_H
#include 
#endif

#include 
#include 
#include 

char * uustring_id = "$Id: uustring.c,v 1.8 2002/03/11 09:15:47 fp Exp $";

typedef struct {
  int code;
  char * msg;
} stringmap;

/*
 * Map of messages. This table is not exported, the messages must
 * be retrieved via the below uustring() function.
 */

static stringmap messages[] = {
  /* I/O related errors/messages. Last parameter is strerror() */
  { S_NOT_OPEN_SOURCE,  "Could not open source file %s: %s" },
  { S_NOT_OPEN_TARGET,  "Could not open target file %s for writing: %s" },
  { S_NOT_OPEN_FILE,    "Could not open file %s: %s" },
  { S_NOT_STAT_FILE,    "Could not stat file %s: %s" },
  { S_SOURCE_READ_ERR,  "Read error on source file: %s" },
  { S_READ_ERROR,       "Error reading from %s: %s" },
  { S_IO_ERR_TARGET,    "I/O error on target file %s: %s" },
  { S_WR_ERR_TARGET,    "Write error on target file %s: %s" },
  { S_WR_ERR_TEMP,      "Write error on temp file: %s" },
  { S_TMP_NOT_REMOVED,  "Could not remove temp file %s: %s (ignored)" },

  /* some other problems */
  { S_OUT_OF_MEMORY,    "Out of memory allocating %d bytes" },
  { S_TARGET_EXISTS,    "Target file %s exists and overwriting is not allowed" },
  { S_NOT_RENAME,       "Could not change name of %s to %s" },
  { S_ERR_ENCODING,     "Error while encoding %s: %s" },
  { S_STAT_ONE_PART,    "Could not stat input, encoding to one part only" },
  { S_PARM_CHECK,       "Parameter check failed in %s" },
  { S_SHORT_BINHEX,     "BinHex encoded file %s ended prematurely (%ld bytes left)" },
  { S_DECODE_CANCEL,    "Decode operation canceled" },
  { S_ENCODE_CANCEL,    "Encode operation canceled" },
  { S_SCAN_CANCEL,      "Scanning canceled" },
  { S_SIZE_MISMATCH,    "%s: Decoded size (%ld) does not match expected size (%ld)" },
  { S_PSIZE_MISMATCH,   "%s part %d: Decoded size (%ld) does not match expected size (%ld)" },
  { S_CRC_MISMATCH,     "CRC32 mismatch in %s. Decoded file probably corrupt." },
  { S_PCRC_MISMATCH,    "PCRC32 mismatch in %s part %d. Decoded file probably corrupt." },

  /* informational messages */
  { S_LOADED_PART,      "Loaded from %s: '%s' (%s): %s part %d %s %s %s" },
  { S_NO_DATA_FOUND,    "No encoded data found in %s" },
  { S_NO_BIN_FILE,      "Oops, could not find decoded file?" },
  { S_STRIPPED_SETUID,  "Stripped setuid/setgid bits from target file %s mode %d" },
  { S_DATA_SUSPICIOUS,  "Data looks suspicious. Decoded file might be corrupt." },
  { S_NO_TEMP_NAME,     "Could not get name for temporary file" },
  { S_BINHEX_SIZES,     "BinHex file: data/resource fork sizes %ld/%ld" },
  { S_BINHEX_BOTH,      "BinHex file: both forks non-empty, decoding data fork" },
  { S_SMERGE_MERGED,    "Parts of '%s' merged with parts of '%s' (%d)" },
  
  /* MIME-related messages */
  { S_MIME_NO_BOUNDARY, "Multipart message without boundary ignored" },
  { S_MIME_B_NOT_FOUND, "Boundary expected on Multipart message but found EOF" },
  { S_MIME_MULTI_DEPTH, "Multipart message nested too deep" },
  { S_MIME_PART_MULTI,  "Handling partial multipart message as plain text" },

  { 0, "" }
};

/*
 * description of the return values UURET_*
 */

char *uuretcodes[] = {
  "OK",
  "File I/O Error",
  "Not Enough Memory",
  "Illegal Value",
  "No Data found",
  "Unexpected End of File",
  "Unsupported function",
  "File exists",
  "Continue -- no error",	/* only to be seen internally */
  "Operation Canceled"
};

/*
 * Names of encoding types
 */

char *codenames[8] = {
  "", "UUdata", "Base64", "XXdata", "Binhex", "Text", "Text", "yEnc"
};

/*
 * Message types
 */

char *msgnames[6] = {
  "", "Note: ", "Warning: ", "ERROR: ", "FATAL ERROR: ", "PANIC: "
};

/*
 * Retrieve one of the messages. We never return NULL
 * but instead escape to "oops".
 */

char *
uustring (int codeno)
{
  static char * faileddef = "oops";
  stringmap *ptr = messages;

  while (ptr->code) {
    if (ptr->code == codeno)
      return ptr->msg;
    ptr++;
  }

  UUMessage (uustring_id, __LINE__, UUMSG_ERROR,
	     "Could not retrieve string no %d",
	     codeno);

  return faileddef;
}
uudeview-0.5.20.orig/uulib/uustring.h0000644001167100001440000000241307452301105017474 0ustar  cphusers00000000000000/* extracted from Id: uustring.c,v 1.8 2002/03/11 09:15:47 fp Exp  */
#define S_NOT_OPEN_SOURCE      1
#define S_NOT_OPEN_TARGET      2
#define S_NOT_OPEN_FILE        3
#define S_NOT_STAT_FILE        4
#define S_SOURCE_READ_ERR      5
#define S_READ_ERROR           6
#define S_IO_ERR_TARGET        7
#define S_WR_ERR_TARGET        8
#define S_WR_ERR_TEMP          9
#define S_TMP_NOT_REMOVED     10
#define S_OUT_OF_MEMORY       11
#define S_TARGET_EXISTS       12
#define S_NOT_RENAME          13
#define S_ERR_ENCODING        14
#define S_STAT_ONE_PART       15
#define S_PARM_CHECK          16
#define S_SHORT_BINHEX        17
#define S_DECODE_CANCEL       18
#define S_ENCODE_CANCEL       19
#define S_SCAN_CANCEL         20
#define S_SIZE_MISMATCH       21
#define S_PSIZE_MISMATCH      22
#define S_CRC_MISMATCH        23
#define S_PCRC_MISMATCH       24
#define S_LOADED_PART         25
#define S_NO_DATA_FOUND       26
#define S_NO_BIN_FILE         27
#define S_STRIPPED_SETUID     28
#define S_DATA_SUSPICIOUS     29
#define S_NO_TEMP_NAME        30
#define S_BINHEX_SIZES        31
#define S_BINHEX_BOTH         32
#define S_SMERGE_MERGED       33
#define S_MIME_NO_BOUNDARY    34
#define S_MIME_B_NOT_FOUND    35
#define S_MIME_MULTI_DEPTH    36
#define S_MIME_PART_MULTI     37
uudeview-0.5.20.orig/uulib/uuutil.c0000644001167100001440000002333207307472273017157 0ustar  cphusers00000000000000/*
 * This file is part of uudeview, the simple and friendly multi-part multi-
 * file uudecoder  program  (c) 1994-2001 by Frank Pilhofer. The author may
 * be contacted at fp@fpx.de
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * certain utilitarian functions that didn't fit anywhere else
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef SYSTEM_WINDLL
#include 
#endif
#ifdef SYSTEM_OS2
#include 
#endif

#include 
#include 

#ifdef STDC_HEADERS
#include 
#include 
#endif
#ifdef HAVE_MALLOC_H
#include 
#endif
#ifdef HAVE_UNISTD_H
#include 
#endif
#ifdef HAVE_MEMORY_H
#include 
#endif
#ifdef HAVE_ERRNO_H
#include 
#endif

#include 
#include 
#include 
#include 

char * uuutil_id = "$Id: uuutil.c,v 1.15 2001/06/06 18:21:47 fp Exp $";

/*
 * Parts with different known extensions will not be merged by SPMS.
 * if first character is '@', it is synonymous to the previous one.
 */

static char *knownexts[] = {
  "mpg", "@mpeg", "avi", "mov",
  "gif", "jpg", "@jpeg", "tif",
  "voc", "wav", "@wave", "au",
  "zip", "arj", "tar",
  NULL
};

/*
 * forward declarations of local functions
 */

static int	UUSMPKnownExt		_ANSI_ARGS_((char *filename));
static uulist *	UU_smparts_r		_ANSI_ARGS_((uulist *, int));

/*
 * mallocable areas
 */

char *uuutil_bhwtmp;

/*
 * free some memory
 **/

void
UUkillfread (fileread *data)
{
  if (data != NULL) {
    _FP_free (data->subject);
    _FP_free (data->filename);
    _FP_free (data->origin);
    _FP_free (data->mimeid);
    _FP_free (data->mimetype);
    _FP_free (data->sfname);
    _FP_free (data);
  }
}

void
UUkillfile (uufile *data)
{
  uufile *next;

  while (data) {
    _FP_free    (data->filename);
    _FP_free    (data->subfname);
    _FP_free    (data->mimeid);
    _FP_free    (data->mimetype);
    UUkillfread (data->data);

    next = data->NEXT;
    _FP_free  (data);
    data = next;
  }
}

void
UUkilllist (uulist *data)
{
  uulist *next;

  while (data) {
    if (data->binfile != NULL)
      if (unlink (data->binfile))
	UUMessage (uuutil_id, __LINE__, UUMSG_WARNING,
		   uustring (S_TMP_NOT_REMOVED),
		   data->binfile, strerror (errno));

    _FP_free   (data->filename);
    _FP_free   (data->subfname);
    _FP_free   (data->mimeid);
    _FP_free   (data->mimetype);
    _FP_free   (data->binfile);
    UUkillfile (data->thisfile);
    _FP_free   (data->haveparts);
    _FP_free   (data->misparts);

    next = data->NEXT;
    _FP_free (data);
    data = next;
  }
}

/*
 * this kill function is an exception in that it doesn't kill data itself
 */

void
UUkillheaders (headers *data)
{
  if (data != NULL) {
    _FP_free (data->from);
    _FP_free (data->subject);
    _FP_free (data->rcpt);
    _FP_free (data->date);
    _FP_free (data->mimevers);
    _FP_free (data->ctype);
    _FP_free (data->ctenc);
    _FP_free (data->fname);
    _FP_free (data->boundary);
    _FP_free (data->mimeid);
    memset   (data, 0, sizeof (headers));
  }
}

/*
 * checks for various well-known extensions. if two parts have different
 * known extensions, we won't merge them.
 */

static int
UUSMPKnownExt (char *filename)
{
  char **eiter = knownexts, *ptr=_FP_strrchr(filename, '.');
  int count=0, where=0;

  if (ptr == NULL)
    return -1;
  ptr++;

  while (*eiter) {
    if (_FP_stricmp (ptr, (**eiter=='@')?*eiter+1:*eiter) == 0)
      return where;
    else
      eiter++;

    if (*eiter == NULL)
      break;

    if (**eiter=='@')
      count++;
    else
      where = ++count;
  }
  return -1;
}

/*
 * de-compress a binhex RLE stream
 * the data read from in is uncompressed, and at most maxcount bytes
 * (or octets, as they say) are copied to out. Because an uncompression
 * might not be completed because of this maximum number of bytes. There-
 * for, the leftover character and repetition count is saved. If a marker
 * has been read but not the repetition count, *rpc is set to -256.
 *
 * the function returns the number of bytes eaten from in. If opc is not
 * NULL, the total number of characters stored in out is saved there
 *
 * with repetition counts, remember that we've already transferred *one*
 * occurence
 */

int
UUbhdecomp (char *in, char *out, char *last, int *rpc, 
	    size_t inc, size_t max, size_t *opc)
{
  size_t count, used=0, dummy;
  char marker = '\220' /* '\x90' */;

  if (opc == NULL)
    opc = &dummy;
  else
    *opc = 0;

  if (*rpc == -256) {
    if (inc == 0)
      return 0;
    *rpc = (int) (unsigned char) *in++; used++;

    if (*rpc == 0) {
      *last = *out++ = marker;
      max--; *opc+=1;
    }
    else
      *rpc-=1;
  }

  if (*rpc) {
    count = (max > (size_t) *rpc) ? (size_t) *rpc : max;

    memset (out, *last, count);

    out  += count;
    *opc += count;
    max  -= count;
    *rpc -= count;
  }

  while (used < inc && max) {
    if (*in == marker) {
      used++; in++;
      if (used == inc) {
	*rpc = -256;
	return used;
      }
      *rpc = (int) (unsigned char) *in++; used++;

      if (*rpc == 0) {
	*last = *out++ = marker;
	max--; *opc+=1;
	continue;
      }
      else
	*rpc -= 1;

      count = (max > (size_t) *rpc) ? (size_t) *rpc : max;
      memset (out, *last, count);

      out  += count;
      *opc += count;
      max  -= count;
      *rpc -= count;
    }
    else {
      *last = *out++ = *in++;
      used++; *opc+=1; max--;
    }
  }

  return used;
}

/*
 * write to binhex file
 */

size_t
UUbhwrite (char *ptr, size_t sel, size_t nel, FILE *file)
{
  char *tmpstring=uuutil_bhwtmp;
  static int rpc = 0;
  static char lc;
  int count, tc=0;
  size_t opc;

  if (ptr == NULL) { /* init */
    rpc = 0;
    return 0;
  }

  while (nel || (rpc != 0 && rpc != -256)) {
    count = UUbhdecomp (ptr, tmpstring, &lc, &rpc,
			nel, 256, &opc);
    if (fwrite (tmpstring, 1, opc, file) != opc)
      return 0;
    if (ferror (file))
      return 0;
    nel -= count;
    ptr += count;
    tc  += count;
  }

  return tc;
}

static uulist *
UU_smparts_r (uulist *addit, int pass)
{
  uulist *iter = UUGlobalFileList;
  uufile *fiter, *dest, *temp;
  int count, flag, a, b;

  while (iter) {
    if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
      iter = iter->NEXT;
      continue;
    }
    if (iter == addit) {
      iter = iter->NEXT;
      continue;
    }
    if ((iter->begin && addit->begin) || (iter->end && addit->end) ||
	(iter->uudet != addit->uudet)) {
      iter = iter->NEXT;
      continue;
    }
    if ((a = UUSMPKnownExt (addit->subfname)) != -1 &&
        (b = UUSMPKnownExt (iter->subfname))  != -1)
      if (a != b) {
        iter = iter->NEXT;
        continue;
      }

    flag  = count = 0;
    fiter = iter->thisfile;
    temp  = addit->thisfile;
    dest  = NULL;

    while (temp) {
      if (!(temp->data->uudet)) {
	temp = temp->NEXT;
	continue;
      }

      while (fiter && fiter->partno < temp->partno) {
        dest  = fiter;
        fiter = fiter->NEXT;
      }
      if (fiter && fiter->partno == temp->partno) {
        flag = 0;
        break;
      }
      else {
	flag   = 1;
        count += ((dest)  ? temp->partno - dest->partno - 1 : 0) +
                 ((fiter) ? fiter->partno - temp->partno - 1 : 0);
      }

      temp = temp->NEXT;
    }
    if (flag == 0 ||
        (pass == 0 && count > 0) ||
        (pass == 1 && count > 5)) {
      iter = iter->NEXT;
      continue;
    }

    dest  = iter->thisfile;
    fiter = addit->thisfile;

    if (iter->filename == NULL && addit->filename != NULL)
      iter->filename = _FP_strdup (addit->filename);

    if (addit->begin) iter->begin = 1;
    if (addit->end)   iter->end   = 1;

    if (addit->mode != 0 && iter->mode == 0)
      iter->mode = addit->mode;

    while (fiter) {
      flag = 0;

      if (fiter->partno == iter->thisfile->partno ||
	  (dest->NEXT != NULL && fiter->partno == dest->NEXT->partno)) {
	temp           = fiter->NEXT;
	fiter->NEXT    = NULL;

	UUkillfile (fiter);

	addit->thisfile= temp;
	fiter          = temp;
	continue;
      }
      if (fiter->partno < iter->thisfile->partno) {
	temp           = fiter->NEXT;
	fiter->NEXT    = iter->thisfile;
	iter->thisfile = fiter;
	dest           = fiter;
	addit->thisfile= temp;
	fiter          = temp;
      }
      else if (dest->NEXT == NULL || fiter->partno < dest->NEXT->partno) {
	temp           = fiter->NEXT;
	fiter->NEXT    = dest->NEXT;
	dest->NEXT     = fiter;
	addit->thisfile= temp;
	fiter          = temp;
      }
      else {
	dest = dest->NEXT;
      }
    }
    break;
  }
  return iter;
}

int UUEXPORT
UUSmerge (int pass)
{
  uulist *iter = UUGlobalFileList, *last=NULL, *res, *temp;
  int flag = 0;

  while (iter) {
    if ((iter->state & UUFILE_OK) || iter->uudet == 0) {
      last = iter;
      iter = iter->NEXT;
      continue;
    }
    if ((res = UU_smparts_r (iter, pass)) != NULL) {
      UUMessage (uuutil_id, __LINE__, UUMSG_MESSAGE,
		 uustring (S_SMERGE_MERGED),
		 (iter->subfname) ? iter->subfname : "",
		 (res->subfname)  ? res->subfname  : "", pass);
 
      temp       = iter->NEXT;
      iter->NEXT = NULL;
      UUkilllist (iter);

      flag++;

      if (last == NULL) {
	UUGlobalFileList = temp;
	iter             = temp;
      }
      else {
	last->NEXT       = temp;
	iter             = temp;
      }

      continue;
    }
    last = iter;
    iter = iter->NEXT;
  }

  /*
   * check again
   */

  UUCheckGlobalList ();

  return flag;
}