From e6552ce4fa6f5b27cc19e84629ea703ac5380c3a Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sun, 10 Jan 2016 20:50:29 +0100 Subject: [PATCH] Import old rinetd 0.61. Taken from the Debian archive: http://archive.debian.org/debian-security/pool/updates/main/r/rinetd/ --- CHANGES | 8 + README | 19 +- getopt.c | 756 +++++++++++++++++++++++++++++++++++++++++++++++++++++ getopt.h | 129 +++++++++ index.html | 29 +- match.c | 35 ++- rinetd.8 | 14 +- rinetd.c | 213 +++++++++++---- rinetd.dsp | 97 +++++++ rinetd.dsw | 29 ++ 10 files changed, 1228 insertions(+), 101 deletions(-) create mode 100644 getopt.c create mode 100644 getopt.h create mode 100644 rinetd.dsp create mode 100644 rinetd.dsw diff --git a/CHANGES b/CHANGES index 82bb24e..f1d223f 100644 --- a/CHANGES +++ b/CHANGES @@ -38,3 +38,11 @@ log file before writing log entries. Version 0.52: documentation added regarding the ability to bind to all IP addresses, if desired, using the special address 0.0.0.0. + +Version 0.6: ported to Win32. Various compatibility +fixes were made and some minor oversights without +functional consequences were corrected. + +Version 0.61: fixed a bug in 0.6 which completely +broke rinetd under Linux. Oops. + diff --git a/README b/README index 24e4454..3859841 100644 --- a/README +++ b/README @@ -1,15 +1,22 @@ -rinetd version 0.51, by Thomas Boutell. Released under -the terms of the GNU Public License, version 2 or later. +rinetd version 0.61, by Thomas Boutell. Released under +the terms of the GNU General Public License, version 2 or later. This program is used to efficiently redirect connections from one IP address/port combination to another. It is useful when operating virtual servers, firewalls and the like. -To build, check the Makefile for platform-specific -details and then type make. To install, type +A binary for 32-bit Windows (95, 98, NT) is included (see the +file rinetd.exe). Windows 3.1 is not supported. + +To build under Unix, check the Makefile for platform- +specific details and then type make. To install, type "make install" as root. -For documentation run "make install", then type -"man rinetd" for details. +To build under Windows, use the provided project +files with Microsoft Visual C++. Windows 3.1 is not supported. + +For documentation run "make install", then type +"man rinetd" for details. Or, read index.html in +your browser. diff --git a/getopt.c b/getopt.c new file mode 100644 index 0000000..5b6be5c --- /dev/null +++ b/getopt.c @@ -0,0 +1,756 @@ +/* THIS IS HERE FOR WIN32's BENEFIT ONLY. */ + +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 + Free Software Foundation, Inc. + + 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef __STDC__ +# ifndef const +# define const +# endif +#endif + +/* This tells Alpha OSF/1 not to define a getopt prototype in . */ +#ifndef _NO_PROTO +#define _NO_PROTO +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined (_LIBC) || !defined (__GNU_LIBRARY__) + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +#include +#endif /* GNU C library. */ + +/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a + long-named option. Because this is not POSIX.2 compliant, it is + being phased out. */ +/* #define GETOPT_COMPAT */ + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = 0; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* XXX 1003.2 says this must be 1 before any call. */ +int optind = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +#define BAD_OPTION '\0' +int optopt = BAD_OPTION; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return EOF with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +#include +#define my_index strchr +#define my_strlen strlen +#else + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#if __STDC__ || defined(PROTO) +extern char *getenv(const char *name); +extern int strcmp (const char *s1, const char *s2); +extern int strncmp(const char *s1, const char *s2, int n); + +static int my_strlen(const char *s); +static char *my_index (const char *str, int chr); +#else +extern char *getenv (); +#endif + +static int +my_strlen (str) + const char *str; +{ + int n = 0; + while (*str++) + n++; + return n; +} + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +#endif /* GNU C library. */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. + + To perform the swap, we first reverse the order of all elements. So + all options now come before all non options, but they are in the + wrong order. So we put back the options and non options in original + order by reversing them again. For example: + original input: a b c -x -y + reverse all: -y -x c b a + reverse options: -x -y c b a + reverse non options: -x -y a b c +*/ + +#if __STDC__ || defined(PROTO) +static void exchange (char **argv); +#endif + +static void +exchange (argv) + char **argv; +{ + char *temp, **first, **last; + + /* Reverse all the elements [first_nonopt, optind) */ + first = &argv[first_nonopt]; + last = &argv[optind-1]; + while (first < last) { + temp = *first; *first = *last; *last = temp; first++; last--; + } + /* Put back the options in order */ + first = &argv[first_nonopt]; + first_nonopt += (optind - last_nonopt); + last = &argv[first_nonopt - 1]; + while (first < last) { + temp = *first; *first = *last; *last = temp; first++; last--; + } + + /* Put back the non options in order */ + first = &argv[first_nonopt]; + last_nonopt = optind; + last = &argv[last_nonopt-1]; + while (first < last) { + temp = *first; *first = *last; *last = temp; first++; last--; + } +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns `EOF'. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return BAD_OPTION after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return BAD_OPTION. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + int option_index; + + optarg = 0; + + /* Initialize the internal data when the first call is made. + Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + if (optind == 0) + { + first_nonopt = last_nonopt = optind = 1; + + nextchar = NULL; + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (getenv ("POSIXLY_CORRECT") != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + } + + if (nextchar == NULL || *nextchar == '\0') + { + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Now skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc + && (argv[optind][0] != '-' || argv[optind][1] == '\0') +#ifdef GETOPT_COMPAT + && (longopts == NULL + || argv[optind][0] != '+' || argv[optind][1] == '\0') +#endif /* GETOPT_COMPAT */ + ) + optind++; + last_nonopt = optind; + } + + /* Special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return EOF; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if ((argv[optind][0] != '-' || argv[optind][1] == '\0') +#ifdef GETOPT_COMPAT + && (longopts == NULL + || argv[optind][0] != '+' || argv[optind][1] == '\0') +#endif /* GETOPT_COMPAT */ + ) + { + if (ordering == REQUIRE_ORDER) + return EOF; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Start decoding its characters. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + if (longopts != NULL + && ((argv[optind][0] == '-' + && (argv[optind][1] == '-' || long_only)) +#ifdef GETOPT_COMPAT + || argv[optind][0] == '+' +#endif /* GETOPT_COMPAT */ + )) + { + const struct option *p; + char *s = nextchar; + int exact = 0; + int ambig = 0; + const struct option *pfound = NULL; + int indfound = 0; + + while (*s && *s != '=') + s++; + + /* Test all options for either exact match or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; + p++, option_index++) + if (!strncmp (p->name, nextchar, s - nextchar)) + { + if (s - nextchar == my_strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, "%s: option `%s' is ambiguous\n", + argv[0], argv[optind]); + nextchar += my_strlen (nextchar); + optind++; + return BAD_OPTION; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*s) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = s + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + "%s: option `--%s' doesn't allow an argument\n", + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + "%s: option `%c%s' doesn't allow an argument\n", + argv[0], argv[optind - 1][0], pfound->name); + } + nextchar += my_strlen (nextchar); + return BAD_OPTION; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, "%s: option `%s' requires an argument\n", + argv[0], argv[optind - 1]); + nextchar += my_strlen (nextchar); + return optstring[0] == ':' ? ':' : BAD_OPTION; + } + } + nextchar += my_strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' +#ifdef GETOPT_COMPAT + || argv[optind][0] == '+' +#endif /* GETOPT_COMPAT */ + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, "%s: unrecognized option `--%s'\n", + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, "%s: unrecognized option `%c%s'\n", + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + return BAD_OPTION; + } + } + + /* Look at and handle the next option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { +#if 0 + if (c < 040 || c >= 0177) + fprintf (stderr, "%s: unrecognized option, character code 0%o\n", + argv[0], c); + else + fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); +#else + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); +#endif + } + optopt = c; + return BAD_OPTION; + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = 0; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { +#if 0 + fprintf (stderr, "%s: option `-%c' requires an argument\n", + argv[0], c); +#else + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, "%s: option requires an argument -- %c\n", + argv[0], c); +#endif + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = BAD_OPTION; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == EOF) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case BAD_OPTION: + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/getopt.h b/getopt.h new file mode 100644 index 0000000..25fd85c --- /dev/null +++ b/getopt.h @@ -0,0 +1,129 @@ +/* THIS IS HERE FOR WIN32's BENEFIT ONLY. */ + +/* Declarations for getopt. + Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc. + + 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns EOF, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if __STDC__ || defined(PROTO) +#if defined(__GNU_LIBRARY__) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#endif /* not __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* not __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* _GETOPT_H */ diff --git a/index.html b/index.html index 46747e5..1b2109a 100644 --- a/index.html +++ b/index.html @@ -4,9 +4,9 @@ @@ -26,14 +26,20 @@ rinetd -- internet ``redirection server''

VERSION

-Version 0.52, 8/7/1998. +Version 0.61, 3/1/1999.

WHERE TO GET

+For Linux: By anonymous FTP from ftp.boutell.com in the subdirectory boutell/rinetd as the file rinetd.tar.gz.

+For Windows 95/98/NT: +By +anonymous FTP from ftp.boutell.com in the subdirectory +boutell/rinetd as the file rinetd.zip. +

DESCRIPTION

Redirects TCP connections from one IP address and port to another. rinetd @@ -78,7 +84,7 @@ can be used. For example:

 0.0.0.0 23 10.1.1.2 23
 
-Would redirect all connections to port 80, for all IP addresses +Would redirect all connections to port 23, for all IP addresses assigned to the server. This is the default behavior for most other programs.

@@ -200,9 +206,9 @@ configuration file option. The server redirected to is not able to identify the host the client really came from. This cannot be corrected; however, the log produced by rinetd provides a way to obtain this -information. Sockets would theoretically lose data when closed +information. Under Unix, sockets would theoretically lose data when closed with SO_LINGER turned off, but in Linux this is not the case -(kernel source comments support this belief on my part). On non-Linux +(kernel source comments support this belief on my part). On non-Linux Unix platforms, alternate code which uses a different trick to work around blocking close() is provided, but this code is untested.

@@ -210,11 +216,11 @@ The logging is inadequate. The duration of the connection should be logged.

LICENSE

-Copyright (c) 1997, 1998, +Copyright (c) 1997, 1998, 1999, Thomas Boutell and Boutell.Com, Inc. This software is released for free use under the terms of -the GNU Public License, version 2 or higher. +the GNU General Public License, version 2 or higher.

CONTACT INFORMATION

@@ -225,8 +231,9 @@ Thomas Boutell can be reached by email:

THANKS

-Thanks are due to Bill Davidsen, Libor Pechachek, Sascha Ziemann, the -Apache Group, and many others who have contributed advice -and/or source code to this and other open software projects. +Thanks are due to Bill Davidsen, Libor Pechachek, Sascha Ziemann, +Joel S. Noble, the Apache Group, and many others who have contributed +advice, encouragement and/or source code to this and other open +software projects. diff --git a/match.c b/match.c index f8203a2..bfb40a2 100644 --- a/match.c +++ b/match.c @@ -12,8 +12,11 @@ int matchNoCase(char *sorig, char *p) return matchBody(sorig, p, 1); } +#define CASE(x) (nocase ? tolower(x) : (x)) + int matchBody(char *sorig, char *p, int nocase) { + static int dummy = 0; /* Algorithm: Word separator: *. End-of-string @@ -28,7 +31,7 @@ int matchBody(char *sorig, char *p, int nocase) and s contain end-of-string at that point, return success. - \ escapes the next character, including \ itself. + \ escapes the next character, including \ itself (6.0). For each *: @@ -49,7 +52,11 @@ int matchBody(char *sorig, char *p, int nocase) char *s = sorig; int escaped = 0; - + if (strstr(p, "WS-0000")) { + if (strstr(s, "ws_ftp_pro.html")) { + dummy = 1; + } + } while (1) { char *word; int wordLen; @@ -61,14 +68,8 @@ int matchBody(char *sorig, char *p, int nocase) if ((*s == '\0') && (*p == '\0')) { return 1; } - if (nocase) { - if (tolower(*p) != tolower(*s)) { - goto nextPattern; - } - } else { - if (*p != *s) { - goto nextPattern; - } + if (CASE(*p) != CASE(*s)) { + goto nextPattern; } p++; s++; @@ -111,7 +112,7 @@ int matchBody(char *sorig, char *p, int nocase) } break; } - if ((((*s) == word[wordPos]) || + if ((((CASE(*s)) == CASE(word[wordPos])) || ((*s == '\0') && (word[wordPos] == '|'))) || (((*s != '\0') && (*s != '|')) && @@ -138,15 +139,9 @@ int matchBody(char *sorig, char *p, int nocase) (*p == '|'))) { return 1; } - if (nocase) { - if (tolower(*p) != tolower(*s)) { - goto nextPattern; - } - } else { - if (*p != *s) { - goto nextPattern; - } - } + if (CASE(*p) != CASE(*s)) { + goto nextPattern; + } p++; s++; break; diff --git a/rinetd.8 b/rinetd.8 index a15d5b6..9480171 100644 --- a/rinetd.8 +++ b/rinetd.8 @@ -1,8 +1,8 @@ -.\" Copyright (c) 1997, 1998, Thomas Boutell and Boutell.Com, Inc. +.\" Copyright (c) 1997, 1998, 1999, Thomas Boutell and Boutell.Com, Inc. .\" This software is released for free use under the terms of .\" the GNU Public License, version 2 or higher. .\" -.Dd February 11, 1998 +.Dd February 18, 1999 .Dt RINETD 8 .Os LINUX .Sh NAME @@ -12,7 +12,7 @@ .Sh SYNOPSIS .Nm /usr/sbin/rinetd .Sh VERSION -Version 0.52, 9/7/1998. +Version 0.61, 3/1/1999. .Sh DESCRIPTION .Nm rinetd redirects TCP connections from one IP address and port to another. rinetd @@ -54,7 +54,7 @@ can be used. For example: .Pp 0.0.0.0 23 10.1.1.2 23 .Pp -Would redirect all connections to port 80, for all IP addresses +Would redirect all connections to port 23, for all IP addresses assigned to the server. This is the default behavior for most other programs. .Pp @@ -170,14 +170,14 @@ use a single TCP socket. This rules out FTP. The server redirected to is not able to identify the host the client really came from. This cannot be corrected; however, the log produced by rinetd provides a way to obtain this -information. Sockets would theoretically lose data when closed +information. Under Unix, Sockets would theoretically lose data when closed with SO_LINGER turned off, but in Linux this is not the case (kernel -source comments support this belief on my part). On non-Linux platforms, +source comments support this belief on my part). On non-Linux Unix platforms, alternate code which uses a different trick to work around blocking close() is provided, but this code is untested. The logging is inadequate. The duration of each connection should be logged. .Sh LICENSE -Copyright (c) 1997, 1998, Thomas Boutell and Boutell.Com, Inc. +Copyright (c) 1997, 1998, 1999, Thomas Boutell and Boutell.Com, Inc. This software is released for free use under the terms of the GNU Public License, version 2 or higher. NO WARRANTY IS EXPRESSED OR IMPLIED. USE THIS SOFTWARE AT YOUR OWN RISK. diff --git a/rinetd.c b/rinetd.c index a214447..9ab161e 100644 --- a/rinetd.c +++ b/rinetd.c @@ -1,19 +1,75 @@ -#include -#include +#define VERSION "0.61" + +#ifdef WIN32 +#include +#include +#include "getopt.h" +#else #include #include +#include #include -#include #include -#include -#include -#include -#include -#include #include +#include +#define INVALID_SOCKET (-1) +#include +#endif /* WIN32 */ + +#include +#include +#include +#include +#include +#include #include -#define VERSION "0.52" +#ifndef WIN32 +/* Windows sockets compatibility defines */ +#define INVALID_SOCKET (-1) +#define SOCKET_ERROR (-1) +int closesocket(int s); + +int closesocket(int s) { + return close(s); +} +#define ioctlsocket ioctl +#define MAKEWORD(a, b) +#define WSAStartup(a, b) (0) +#define WSACleanup() +#ifdef __MAC__ +/* The constants for these are a little screwy in the prelinked + MSL GUSI lib and we can't rebuild it, so roll with it */ +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEAGAIN EAGAIN +#define WSAEINPROGRESS EINPROGRESS +#else +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEAGAIN EAGAIN +#define WSAEINPROGRESS EINPROGRESS +#endif /* __MAC__ */ +#define WSAEINTR EINTR +#define SOCKET int +#define GetLastError() (errno) +typedef struct { + int dummy; +} WSADATA; + +void Sleep(long ms); + +void Sleep(long ms) +{ + struct timeval tv; + tv.tv_sec = ms / 1000; + tv.tv_usec = ms * 1000; + select(0, 0, 0, 0, &tv); +} +#else +/* WIN32 doesn't really have WSAEAGAIN */ +#ifndef WSAEAGAIN +#define WSAEAGAIN WSAEWOULDBLOCK +#endif +#endif /* WIN32 */ #ifndef TRUE #define TRUE 1 @@ -29,7 +85,15 @@ #define PERROR(x) #endif /* DEBUG */ -int *seFds = 0; +/* We've got to get FIONBIO from somewhere. Try the Solaris location + if it isn't defined yet by the above includes. */ +#ifndef FIONBIO +#include +#endif /* FIONBIO */ + +#include "match.h" + +SOCKET *seFds = 0; /* In network order, for network purposes */ struct in_addr *seLocalAddrs = 0; unsigned short *seLocalPorts = 0; @@ -49,8 +113,8 @@ int *seDenyRules = 0; int *seDenyRulesTotal = 0; int globalDenyRules = 0; -int *reFds = 0; -int *loFds = 0; +SOCKET *reFds = 0; +SOCKET *loFds = 0; unsigned char *reAddresses = 0; int *coInputRPos = 0; int *coInputWPos = 0; @@ -111,6 +175,8 @@ void selectLoop(void); void log(int i, int coSe, int result); +int getAddress(char *host, struct in_addr *iaddr); + char *logMessages[] = { "done-local-closed", "done-remote-closed", @@ -151,24 +217,37 @@ RinetdOptions options = { "/etc/rinetd.conf" }; -int readAargs (int argc, +int readArgs (int argc, char **argv, RinetdOptions *options); int main(int argc, char *argv[]) { + WSADATA wsaData; + int result = WSAStartup(MAKEWORD(1, 1), &wsaData); + if (result != 0) { + fprintf(stderr, "Your computer was not connected " + "to the Internet at the time that " + "this program was launched, or you " + "do not have a 32-bit " + "connection to the Internet."); + exit(1); + } readArgs(argc, argv, &options); +#ifndef WIN32 #ifndef DEBUG if (!fork()) { if (!fork()) { #endif /* DEBUG */ signal(SIGPIPE, plumber); signal(SIGHUP, hup); +#endif /* WIN32 */ signal(SIGTERM, term); initArrays(); readConfiguration(); RegisterPID(); selectLoop(); +#ifndef WIN32 #ifndef DEBUG } else { exit(0); @@ -177,6 +256,7 @@ int main(int argc, char *argv[]) exit(0); } #endif /* DEBUG */ +#endif /* WIN32 */ return 0; } @@ -196,7 +276,7 @@ void readConfiguration(void) /* Close existing server sockets. */ for (i = 0; (i < seTotal); i++) { if (seFds[i] != -1) { - close(seFds[i]); + closesocket(seFds[i]); free(seFromHosts[i]); free(seToHosts[i]); } @@ -272,7 +352,7 @@ void readConfiguration(void) } } fclose(in); - seFds = (int *) malloc(sizeof(int) * seTotal); + seFds = (SOCKET *) malloc(sizeof(int) * seTotal); if (!seFds) { goto lowMemory; } @@ -498,49 +578,51 @@ void readConfiguration(void) } /* Make a server socket */ seFds[i] = socket(PF_INET, SOCK_STREAM, 0); - if (seFds[i] < 0) { + if (seFds[i] == INVALID_SOCKET) { fprintf(stderr, "rinetd: couldn't create " "server socket!\n"); seFds[i] = -1; continue; } +#ifndef WIN32 if (seFds[i] > maxfd) { maxfd = seFds[i]; } +#endif saddr.sin_family = AF_INET; memcpy(&saddr.sin_addr, &iaddr, sizeof(iaddr)); saddr.sin_port = htons(bindPort); j = 1; setsockopt(seFds[i], SOL_SOCKET, SO_REUSEADDR, - &j, sizeof(j)); + (const char *) &j, sizeof(j)); if (bind(seFds[i], (struct sockaddr *) - &saddr, sizeof(saddr)) < 0) + &saddr, sizeof(saddr)) == SOCKET_ERROR) { /* Warn -- don't exit. */ fprintf(stderr, "rinetd: couldn't bind to " "address %s port %d\n", bindAddress, bindPort); - close(seFds[i]); - seFds[i] = -1; + closesocket(seFds[i]); + seFds[i] = INVALID_SOCKET; continue; } - if (listen(seFds[i], 5) < 0) { + if (listen(seFds[i], 5) == SOCKET_ERROR) { /* Warn -- don't exit. */ fprintf(stderr, "rinetd: couldn't listen to " "address %s port %d\n", bindAddress, bindPort); - close(seFds[i]); - seFds[i] = -1; + closesocket(seFds[i]); + seFds[i] = INVALID_SOCKET; continue; } - fcntl(seFds[i], F_SETFL, O_NONBLOCK); + ioctlsocket(seFds[i], FIONBIO, &j); if (!getAddress(connectAddress, &iaddr)) { /* Warn -- don't exit. */ fprintf(stderr, "rinetd: host %s could not be " "resolved on line %d.\n", bindAddress, lnum); - close(seFds[i]); - seFds[i] = -1; + closesocket(seFds[i]); + seFds[i] = INVALID_SOCKET; continue; } seLocalAddrs[i] = iaddr; @@ -610,8 +692,8 @@ void initArrays(void) { int j; coTotal = 64; - reFds = (int *) malloc(sizeof(int) * coTotal); - loFds = (int *) malloc(sizeof(int) * coTotal); + reFds = (SOCKET *) malloc(sizeof(int) * coTotal); + loFds = (SOCKET *) malloc(sizeof(int) * coTotal); coInputRPos = (int *) malloc(sizeof(int) * coTotal); coInputWPos = (int *) malloc(sizeof(int) * coTotal); coOutputRPos = (int *) malloc(sizeof(int) * coTotal); @@ -675,7 +757,7 @@ void selectPass(void) { FD_ZERO(&writefds); /* Server sockets */ for (i = 0; (i < seTotal); i++) { - if (seFds[i] != -1) { + if (seFds[i] != INVALID_SOCKET) { FD_SET(seFds[i], &readfds); } } @@ -763,10 +845,10 @@ void handleRemoteRead(int i) return; } if (got < 0) { - if (errno == EWOULDBLOCK) { + if (GetLastError() == WSAEWOULDBLOCK) { return; } - if (errno == EINPROGRESS) { + if (GetLastError() == WSAEINPROGRESS) { return; } handleCloseFromRemote(i); @@ -784,16 +866,16 @@ void handleRemoteWrite(int i) coClosed[i] = 1; PERROR("rinetd: local closed and no more output"); log(i, coSe[i], logDone | coLog[i]); - close(reFds[i]); + closesocket(reFds[i]); return; } got = send(reFds[i], coOutput[i] + coOutputWPos[i], coOutputRPos[i] - coOutputWPos[i], 0); if (got < 0) { - if (errno == EWOULDBLOCK) { + if (GetLastError() == WSAEWOULDBLOCK) { return; } - if (errno == EINPROGRESS) { + if (GetLastError() == WSAEINPROGRESS) { return; } handleCloseFromRemote(i); @@ -820,10 +902,10 @@ void handleLocalRead(int i) return; } if (got < 0) { - if (errno == EWOULDBLOCK) { + if (GetLastError() == WSAEWOULDBLOCK) { return; } - if (errno == EINPROGRESS) { + if (GetLastError() == WSAEINPROGRESS) { return; } handleCloseFromLocal(i); @@ -840,16 +922,16 @@ void handleLocalWrite(int i) coClosed[i] = 1; PERROR("remote closed and no more input"); log(i, coSe[i], logDone | coLog[i]); - close(loFds[i]); + closesocket(loFds[i]); return; } got = send(loFds[i], coInput[i] + coInputWPos[i], coInputRPos[i] - coInputWPos[i], 0); if (got < 0) { - if (errno == EWOULDBLOCK) { + if (GetLastError() == WSAEWOULDBLOCK) { return; } - if (errno == EINPROGRESS) { + if (GetLastError() == WSAEINPROGRESS) { return; } handleCloseFromLocal(i); @@ -869,10 +951,11 @@ void handleCloseFromLocal(int i) /* The local end fizzled out, so make sure we're all done with that */ PERROR("close from local"); - close(loFds[i]); + closesocket(loFds[i]); loClosed[i] = 1; if (!reClosed[i]) { #ifndef LINUX +#ifndef WIN32 /* Now set up the remote end for a polite closing */ /* Request a low-water mark equal to the entire @@ -881,6 +964,7 @@ void handleCloseFromLocal(int i) arg = 1024; setsockopt(reFds[i], SOL_SOCKET, SO_SNDLOWAT, &arg, sizeof(arg)); +#endif /* WIN32 */ #endif /* LINUX */ coLog[i] = logLocalClosedFirst; } @@ -893,10 +977,11 @@ void handleCloseFromRemote(int i) /* The remote end fizzled out, so make sure we're all done with that */ PERROR("close from remote"); - close(reFds[i]); + closesocket(reFds[i]); reClosed[i] = 1; if (!loClosed[i]) { #ifndef LINUX +#ifndef WIN32 /* Now set up the local end for a polite closing */ /* Request a low-water mark equal to the entire @@ -905,6 +990,7 @@ void handleCloseFromRemote(int i) arg = 1024; setsockopt(loFds[i], SOL_SOCKET, SO_SNDLOWAT, &arg, sizeof(arg)); +#endif /* WIN32 */ #endif /* LINUX */ loClosed[i] = 0; coLog[i] = logRemoteClosedFirst; @@ -923,20 +1009,24 @@ void handleAccept(int i) int addrlen; int index = -1; int o; - int nfd; + SOCKET nfd; addrlen = sizeof(addr); nfd = accept(seFds[i], &addr, &addrlen); - if (nfd < 0) { + if (nfd == INVALID_SOCKET) { log(-1, i, logAcceptFailed); return; } +#ifndef WIN32 if (nfd > maxfd) { maxfd = nfd; } +#endif /* WIN32 */ j = 1; - fcntl(nfd, F_SETFL, O_NONBLOCK); + ioctlsocket(nfd, FIONBIO, &j); j = 0; +#ifndef WIN32 setsockopt(nfd, SOL_SOCKET, SO_LINGER, &j, sizeof(j)); +#endif for (j = 0; (j < coTotal); j++) { if (coClosed[j]) { index = j; @@ -947,12 +1037,12 @@ void handleAccept(int i) o = coTotal; coTotal *= 2; if (!SAFE_REALLOC(&reFds, sizeof(int) * o, - sizeof(int) * coTotal)) + sizeof(SOCKET) * coTotal)) { goto shortage; } if (!SAFE_REALLOC(&loFds, sizeof(int) * o, - sizeof(int) * coTotal)) + sizeof(SOCKET) * coTotal)) { goto shortage; } @@ -1142,24 +1232,26 @@ void openLocalFd(int se, int i) int j; struct sockaddr_in saddr; loFds[i] = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (loFds[i] < 0) { - close(reFds[i]); + if (loFds[i] == INVALID_SOCKET) { + closesocket(reFds[i]); reClosed[i] = 1; loClosed[i] = 1; coClosed[i] = 1; log(i, coSe[i], logLocalSocketFailed); return; } +#ifndef WIN32 if (loFds[i] > maxfd) { maxfd = loFds[i]; } +#endif /* WIN32 */ /* Bind the local socket */ saddr.sin_family = AF_INET; saddr.sin_port = INADDR_ANY; saddr.sin_addr.s_addr = 0; - if (bind(loFds[i], (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { - close(loFds[i]); - close(reFds[i]); + if (bind(loFds[i], (struct sockaddr *) &saddr, sizeof(saddr)) == SOCKET_ERROR) { + closesocket(loFds[i]); + closesocket(reFds[i]); reClosed[i] = 1; loClosed[i] = 1; coClosed[i] = 1; @@ -1170,6 +1262,7 @@ void openLocalFd(int se, int i) saddr.sin_family = AF_INET; memcpy(&saddr.sin_addr, &seLocalAddrs[se], sizeof(struct in_addr)); saddr.sin_port = seLocalPorts[se]; +#ifndef WIN32 #ifdef LINUX j = 0; setsockopt(loFds[i], SOL_SOCKET, SO_LINGER, &j, sizeof(j)); @@ -1177,15 +1270,18 @@ void openLocalFd(int se, int i) j = 1024; setsockopt(loFds[i], SOL_SOCKET, SO_SNDBUF, &j, sizeof(j)); #endif /* LINUX */ +#endif /* WIN32 */ j = 1; - fcntl(loFds[i], F_SETFL, O_NONBLOCK); + ioctlsocket(loFds[i], FIONBIO, &j); if (connect(loFds[i], (struct sockaddr *)&saddr, - sizeof(struct sockaddr_in)) < 0) + sizeof(struct sockaddr_in)) == INVALID_SOCKET) { - if (errno != EINPROGRESS) { + if ((GetLastError() != WSAEINPROGRESS) && + (GetLastError() != WSAEWOULDBLOCK)) + { PERROR("rinetd: connect"); - close(loFds[i]); - close(reFds[i]); + closesocket(loFds[i]); + closesocket(reFds[i]); reClosed[i] = 1; loClosed[i] = 1; coClosed[i] = 1; @@ -1223,6 +1319,7 @@ int getAddress(char *host, struct in_addr *iaddr) } } +#ifndef WIN32 void plumber(int s) { /* Just reinstall */ @@ -1236,6 +1333,7 @@ void hup(int s) /* And reinstall the signal handler */ signal(SIGHUP, hup); } +#endif /* WIN32 */ int safeRealloc(void **data, int oldsize, int newsize) { @@ -1406,6 +1504,7 @@ int readArgs (int argc, exit (1); } } + return 0; } /* get_gmtoff was borrowed from Apache. Thanks folks. */ @@ -1443,7 +1542,7 @@ int patternBad(char *pattern) void refuse(int index, int logCode) { - close(reFds[index]); + closesocket(reFds[index]); reClosed[index] = 1; loClosed[index] = 1; coClosed[index] = 1; diff --git a/rinetd.dsp b/rinetd.dsp new file mode 100644 index 0000000..d45592b --- /dev/null +++ b/rinetd.dsp @@ -0,0 +1,97 @@ +# Microsoft Developer Studio Project File - Name="rinetd" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 5.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=rinetd - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "rinetd.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "rinetd.mak" CFG="rinetd - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "rinetd - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "rinetd - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "rinetd - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "rinetd - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "rinetd - Win32 Release" +# Name "rinetd - Win32 Debug" +# Begin Source File + +SOURCE=.\getopt.c +# End Source File +# Begin Source File + +SOURCE=.\match.c +# End Source File +# Begin Source File + +SOURCE=.\rinetd.c +# End Source File +# End Target +# End Project diff --git a/rinetd.dsw b/rinetd.dsw new file mode 100644 index 0000000..61dc1d1 --- /dev/null +++ b/rinetd.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "rinetd"=.\rinetd.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### +