move telnetd to main tree, not enabled yet
authorSteven Edwards <winehacker@gmail.com>
Mon, 13 Apr 2009 13:29:21 +0000 (13:29 +0000)
committerSteven Edwards <winehacker@gmail.com>
Mon, 13 Apr 2009 13:29:21 +0000 (13:29 +0000)
svn path=/trunk/; revision=40481

reactos/base/services/telnetd/serviceentry.c [new file with mode: 0644]
reactos/base/services/telnetd/syslog.c [new file with mode: 0644]
reactos/base/services/telnetd/syslog.h [new file with mode: 0644]
reactos/base/services/telnetd/telnetd.c [new file with mode: 0644]
reactos/base/services/telnetd/telnetd.h [new file with mode: 0644]
reactos/base/services/telnetd/telnetd.rbuild [new file with mode: 0644]
reactos/base/services/telnetd/telnetd.rc [new file with mode: 0644]
reactos/base/services/telnetd/telnetd.vcproj [new file with mode: 0644]
reactos/boot/bootdata/packages/reactos.dff

diff --git a/reactos/base/services/telnetd/serviceentry.c b/reactos/base/services/telnetd/serviceentry.c
new file mode 100644 (file)
index 0000000..015d057
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2007 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#if 0
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+
+#define WINE_FIXME printf
+#define WINE_TRACE printf
+
+//#include "wine/debug.h"
+
+//WINE_DEFAULT_DEBUG_CHANNEL(spoolsv);
+
+static WCHAR telnetdW[] = {'T','e','l','n','e','t','D',0};
+
+static SERVICE_STATUS_HANDLE service_handle;
+static HANDLE stop_event;
+
+static DWORD WINAPI service_handler( DWORD ctrl, DWORD event_type, LPVOID event_data, LPVOID context )
+{
+    SERVICE_STATUS status;
+
+    status.dwServiceType             = SERVICE_WIN32;
+    status.dwControlsAccepted        = SERVICE_ACCEPT_STOP;
+    status.dwWin32ExitCode           = 0;
+    status.dwServiceSpecificExitCode = 0;
+    status.dwCheckPoint              = 0;
+    status.dwWaitHint                = 0;
+
+    switch(ctrl)
+    {
+    case SERVICE_CONTROL_STOP:
+    case SERVICE_CONTROL_SHUTDOWN:
+        WINE_TRACE( "shutting down\n" );
+        status.dwCurrentState     = SERVICE_STOP_PENDING;
+        status.dwControlsAccepted = 0;
+        SetServiceStatus( service_handle, &status );
+        SetEvent( stop_event );
+        return NO_ERROR;
+    default:
+        WINE_FIXME( "got service ctrl %x\n", ctrl );
+        status.dwCurrentState = SERVICE_RUNNING;
+        SetServiceStatus( service_handle, &status );
+        return NO_ERROR;
+    }
+}
+
+static void WINAPI serv_main(DWORD argc, LPWSTR *argv)
+{
+    SERVICE_STATUS status;
+    int retval;
+
+    WINE_TRACE( "starting service\n" );
+
+    stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
+
+    service_handle = RegisterServiceCtrlHandlerExW( telnetdW, service_handler, NULL );
+    if (!service_handle)
+        return;
+
+    status.dwServiceType             = SERVICE_WIN32;
+    status.dwCurrentState            = SERVICE_RUNNING;
+    status.dwControlsAccepted        = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+    status.dwWin32ExitCode           = 0;
+    status.dwServiceSpecificExitCode = 0;
+    status.dwCheckPoint              = 0;
+    status.dwWaitHint                = 10000;
+    SetServiceStatus( service_handle, &status );
+
+    /* Argument Ignored for now */
+    retval = kickoff_telnetd();
+
+    WaitForSingleObject( stop_event, INFINITE );
+
+    status.dwCurrentState     = SERVICE_STOPPED;
+    status.dwControlsAccepted = 0;
+    SetServiceStatus( service_handle, &status );
+    WINE_TRACE( "service stopped\n" );
+}
+
+int main(int argc, char **argv)
+{
+    static const SERVICE_TABLE_ENTRYW servtbl[] = {
+        {telnetdW, serv_main},
+        {NULL, NULL}
+    };
+
+    WINE_TRACE("(%d %p)\n", argc, argv);
+
+    StartServiceCtrlDispatcherW(servtbl);
+    return 0;
+}
+#endif
+/* EOF */
+
diff --git a/reactos/base/services/telnetd/syslog.c b/reactos/base/services/telnetd/syslog.c
new file mode 100644 (file)
index 0000000..1ee4499
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * syslog-client.c - syslog client implementation for windows
+ *
+ * Created by Alexander Yaworsky
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+/* define SYSLOG_CONF_DIR where syslog.host should be
+ */
+
+#ifndef SYSLOG_CONF_DIR
+static const char *syslog_conf_dir = ".";
+#else
+static const char *syslog_conf_dir = SYSLOG_CONF_DIR;
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include "syslog.h"
+
+#ifdef TEST
+#    define SYSLOG_DGRAM_SIZE 80
+#else
+#    define SYSLOG_DGRAM_SIZE 1024
+#endif
+
+static BOOL initialized = FALSE;
+static int log_mask = 0xFF;
+static char *syslog_ident;
+static int syslog_facility;
+static char str_pid[ 40 ];
+static SOCKADDR_IN sa_logger;
+static SOCKET sock;
+static char local_hostname[ MAX_COMPUTERNAME_LENGTH + 1 ];
+static char datagramm[ SYSLOG_DGRAM_SIZE ];
+static int datagramm_size;
+
+/******************************************************************************
+ * set_syslog_conf_dir
+ *
+ * maybe this function will be useful...
+ */
+const char* set_syslog_conf_dir( const char* dir )
+{
+    const char *ret = syslog_conf_dir;
+    syslog_conf_dir = dir;
+    return ret;
+}
+
+/******************************************************************************
+ * init_logger_addr
+ *
+ * Read configuration file syslog.host. This file should contain host address
+ * and, optionally, port. Initialize sa_logger. If the configuration file does
+ * not exist, use localhost:514.
+ * Returns: 0 - ok, -1 - error.
+ */
+static void init_logger_addr()
+{
+    char pathname[ FILENAME_MAX ];
+    char *p;
+    FILE *fd;
+    char host[256];
+    struct hostent * phe;
+
+    memset( &sa_logger, 0, sizeof(SOCKADDR_IN) );
+    sa_logger.sin_family = AF_INET;
+
+    if( '\\' == syslog_conf_dir[0] || '/' == syslog_conf_dir[0] || ':' == syslog_conf_dir[1] )
+    {
+        /* absolute path */
+        strcpy( pathname, syslog_conf_dir );
+    }
+    else
+    {
+        /* relative path */
+        char *q;
+
+        strcpy( pathname, __argv[0] );
+        p = strrchr( pathname, '\\' ) + 1;
+        q = strrchr( pathname, '/' ) + 1;
+        if( p < q )
+            *q = 0;
+        else if( p > q )
+            *p = 0;
+        else
+            pathname[0] = 0;
+        strcat( pathname, syslog_conf_dir );
+    }
+    p = &pathname[ strlen( pathname ) - 1 ];
+    if( '\\' != *p && '/' != *p )
+    {
+        p++; *p = '/';
+    }
+    strcpy( ++p, "syslog.host" );
+
+    /* read destination host name */
+    fd = fopen( pathname, "r" );
+    if( !fd )
+        goto use_default;
+
+    if( NULL == fgets( host, sizeof(host), fd ) )
+        host[0] = 0;
+    else
+    {
+        p = strchr( host, '\n' );
+        if( p )
+            *p = 0;
+        p = strchr( host, '\r' );
+        if( p )
+            *p = 0;
+    }
+    fclose( fd );
+
+    p = strchr( host, ':' );
+    if( p )
+        *p++ = 0;
+
+    phe = gethostbyname( host );
+    if( !phe )
+        goto use_default;
+
+    memcpy( &sa_logger.sin_addr.s_addr, phe->h_addr, phe->h_length );
+
+    if( p )
+        sa_logger.sin_port = htons( (unsigned short) strtoul( p, NULL, 0 ) );
+    else
+        sa_logger.sin_port = htons( SYSLOG_PORT );
+    return;
+
+use_default:
+    sa_logger.sin_addr.S_un.S_addr = htonl( 0x7F000001 );
+    sa_logger.sin_port = htons( SYSLOG_PORT );
+}
+
+/******************************************************************************
+ * closelog
+ *
+ * Close desriptor used to write to system logger.
+ */
+void closelog()
+{
+    if( !initialized )
+        return;
+    closesocket( sock );
+    WSACleanup();
+    initialized = FALSE;
+}
+
+/******************************************************************************
+ * openlog
+ *
+ * Open connection to system logger.
+ */
+void openlog( char* ident, int option, int facility )
+{
+    BOOL failed = TRUE, wsa_initialized = FALSE;
+    WSADATA wsd;
+    SOCKADDR_IN sa_local;
+    DWORD n;
+    int size;
+
+    if( initialized )
+        return;
+
+    syslog_facility = facility? facility : LOG_USER;
+
+    /* FIXME: should we reset logmask? */
+
+    if( option & LOG_PID )
+        snprintf( str_pid, sizeof(str_pid), "[%lu]", GetCurrentProcessId() );
+    else
+        str_pid[0] = 0;
+
+    /* FIXME: handle other options */
+
+    n = sizeof(local_hostname);
+    if( !GetComputerName( local_hostname, &n ) )
+        goto done;
+
+    sock = INVALID_SOCKET;
+    if( WSAStartup( MAKEWORD( 2, 2 ), &wsd ) )
+        goto done;
+    wsa_initialized = TRUE;
+
+    init_logger_addr();
+
+    for( n = 0;; n++ )
+    {
+        sock = socket( AF_INET, SOCK_DGRAM, 0 );
+        if( INVALID_SOCKET == sock )
+            goto done;
+
+        memset( &sa_local, 0, sizeof(SOCKADDR_IN) );
+        sa_local.sin_family = AF_INET;
+        if( bind( sock, (SOCKADDR*) &sa_local, sizeof(SOCKADDR_IN) ) == 0 )
+            break;
+        closesocket( sock );
+        sock = INVALID_SOCKET;
+        if( n == 100 )
+            goto done;
+        Sleep(0);
+    }
+
+    /* get size of datagramm */
+    size = sizeof(datagramm_size);
+    if( getsockopt( sock, SOL_SOCKET, SO_MAX_MSG_SIZE, (char*) &datagramm_size, &size ) )
+        goto done;
+    if( datagramm_size - strlen(local_hostname) - (ident? strlen(ident) : 0) < 64 )
+        goto done;
+    if( datagramm_size > sizeof(datagramm) )
+        datagramm_size = sizeof(datagramm);
+
+    if( atexit( closelog ) )
+        goto done;
+
+    syslog_ident = ident;
+    syslog_facility = facility;
+    failed = FALSE;
+
+done:
+    if( failed )
+    {
+        if( sock != INVALID_SOCKET ) closesocket( sock );
+        if( wsa_initialized ) WSACleanup();
+    }
+    initialized = !failed;
+}
+
+/******************************************************************************
+ * setlogmask
+ *
+ * Set the log mask level.
+ */
+int setlogmask( int mask )
+{
+    int ret = log_mask;
+
+    if( mask )
+        log_mask = mask;
+    return ret;
+}
+
+/******************************************************************************
+ * syslog
+ *
+ * Generate a log message using FMT string and option arguments.
+ */
+void syslog( int pri, char* fmt, ... )
+{
+    va_list ap;
+
+    va_start( ap, fmt );
+    vsyslog( pri, fmt, ap );
+    va_end( ap );
+}
+
+/******************************************************************************
+ * vsyslog
+ *
+ * Generate a log message using FMT and using arguments pointed to by AP.
+ */
+void vsyslog( int pri, char* fmt, va_list ap )
+{
+    static char *month[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+    SYSTEMTIME stm;
+    int len;
+    char *p;
+
+    if( !(LOG_MASK( LOG_PRI( pri )) & log_mask) )
+        return;
+
+    openlog( NULL, 0, pri & LOG_FACMASK );
+    if( !initialized )
+        return;
+
+    if( !(pri & LOG_FACMASK) )
+        pri |= syslog_facility;
+
+    GetLocalTime( &stm );
+    len = sprintf( datagramm, "<%d>%s %2d %02d:%02d:%02d %s %s%s: ",
+                   pri,
+                   month[ stm.wMonth - 1 ], stm.wDay, stm.wHour, stm.wMinute, stm.wSecond,
+                   local_hostname, syslog_ident? syslog_ident : "", str_pid );
+    vsnprintf( datagramm + len, datagramm_size - len, fmt, ap );
+    p = strchr( datagramm, '\n' );
+    if( p )
+        *p = 0;
+    p = strchr( datagramm, '\r' );
+    if( p )
+        *p = 0;
+
+    sendto( sock, datagramm, strlen(datagramm), 0, (SOCKADDR*) &sa_logger, sizeof(SOCKADDR_IN) );
+}
+
diff --git a/reactos/base/services/telnetd/syslog.h b/reactos/base/services/telnetd/syslog.h
new file mode 100644 (file)
index 0000000..2dbf821
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 1982, 1986, 1988, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)syslog.h    8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _SYS_SYSLOG_H
+#define _SYS_SYSLOG_H 1
+
+#include <stdarg.h>
+
+/*
+ * priorities/facilities are encoded into a single 32-bit quantity, where the
+ * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
+ * (0-big number).  Both the priorities and the facilities map roughly
+ * one-to-one to strings in the syslogd(8) source code.  This mapping is
+ * included in this file.
+ *
+ * priorities (these are ordered)
+ */
+#define        LOG_EMERG       0       /* system is unusable */
+#define        LOG_ALERT       1       /* action must be taken immediately */
+#define        LOG_CRIT        2       /* critical conditions */
+#define        LOG_ERR         3       /* error conditions */
+#define        LOG_WARNING     4       /* warning conditions */
+#define        LOG_NOTICE      5       /* normal but significant condition */
+#define        LOG_INFO        6       /* informational */
+#define        LOG_DEBUG       7       /* debug-level messages */
+
+#define        LOG_PRIMASK     0x07    /* mask to extract priority part (internal) */
+                               /* extract priority */
+#define        LOG_PRI(p)      ((p) & LOG_PRIMASK)
+#define        LOG_MAKEPRI(fac, pri)   (((fac) << 3) | (pri))
+
+#ifdef SYSLOG_NAMES
+#define        INTERNAL_NOPRI  0x10    /* the "no priority" priority */
+                               /* mark "facility" */
+#define        INTERNAL_MARK   LOG_MAKEPRI(LOG_NFACILITIES, 0)
+typedef struct _code {
+       char    *c_name;
+       int     c_val;
+} CODE;
+
+CODE prioritynames[] =
+  {
+    { "alert", LOG_ALERT },
+    { "crit", LOG_CRIT },
+    { "debug", LOG_DEBUG },
+    { "emerg", LOG_EMERG },
+    { "err", LOG_ERR },
+    { "error", LOG_ERR },              /* DEPRECATED */
+    { "info", LOG_INFO },
+    { "none", INTERNAL_NOPRI },                /* INTERNAL */
+    { "notice", LOG_NOTICE },
+    { "panic", LOG_EMERG },            /* DEPRECATED */
+    { "warn", LOG_WARNING },           /* DEPRECATED */
+    { "warning", LOG_WARNING },
+    { NULL, -1 }
+  };
+#endif
+
+/* facility codes */
+#define        LOG_KERN        (0<<3)  /* kernel messages */
+#define        LOG_USER        (1<<3)  /* random user-level messages */
+#define        LOG_MAIL        (2<<3)  /* mail system */
+#define        LOG_DAEMON      (3<<3)  /* system daemons */
+#define        LOG_AUTH        (4<<3)  /* security/authorization messages */
+#define        LOG_SYSLOG      (5<<3)  /* messages generated internally by syslogd */
+#define        LOG_LPR         (6<<3)  /* line printer subsystem */
+#define        LOG_NEWS        (7<<3)  /* network news subsystem */
+#define        LOG_UUCP        (8<<3)  /* UUCP subsystem */
+#define        LOG_CRON        (9<<3)  /* clock daemon */
+#define        LOG_AUTHPRIV    (10<<3) /* security/authorization messages (private) */
+#define        LOG_FTP         (11<<3) /* ftp daemon */
+
+       /* other codes through 15 reserved for system use */
+#define        LOG_LOCAL0      (16<<3) /* reserved for local use */
+#define        LOG_LOCAL1      (17<<3) /* reserved for local use */
+#define        LOG_LOCAL2      (18<<3) /* reserved for local use */
+#define        LOG_LOCAL3      (19<<3) /* reserved for local use */
+#define        LOG_LOCAL4      (20<<3) /* reserved for local use */
+#define        LOG_LOCAL5      (21<<3) /* reserved for local use */
+#define        LOG_LOCAL6      (22<<3) /* reserved for local use */
+#define        LOG_LOCAL7      (23<<3) /* reserved for local use */
+
+#define        LOG_NFACILITIES 24      /* current number of facilities */
+#define        LOG_FACMASK     0x03f8  /* mask to extract facility part */
+                               /* facility of pri */
+#define        LOG_FAC(p)      (((p) & LOG_FACMASK) >> 3)
+
+#ifdef SYSLOG_NAMES
+CODE facilitynames[] =
+  {
+    { "auth", LOG_AUTH },
+    { "authpriv", LOG_AUTHPRIV },
+    { "cron", LOG_CRON },
+    { "daemon", LOG_DAEMON },
+    { "ftp", LOG_FTP },
+    { "kern", LOG_KERN },
+    { "lpr", LOG_LPR },
+    { "mail", LOG_MAIL },
+    { "mark", INTERNAL_MARK },         /* INTERNAL */
+    { "news", LOG_NEWS },
+    { "security", LOG_AUTH },          /* DEPRECATED */
+    { "syslog", LOG_SYSLOG },
+    { "user", LOG_USER },
+    { "uucp", LOG_UUCP },
+    { "local0", LOG_LOCAL0 },
+    { "local1", LOG_LOCAL1 },
+    { "local2", LOG_LOCAL2 },
+    { "local3", LOG_LOCAL3 },
+    { "local4", LOG_LOCAL4 },
+    { "local5", LOG_LOCAL5 },
+    { "local6", LOG_LOCAL6 },
+    { "local7", LOG_LOCAL7 },
+    { NULL, -1 }
+  };
+#endif
+
+/*
+ * arguments to setlogmask.
+ */
+#define        LOG_MASK(pri)   (1 << (pri))            /* mask for one priority */
+#define        LOG_UPTO(pri)   ((1 << ((pri)+1)) - 1)  /* all priorities through pri */
+
+/*
+ * Option flags for openlog.
+ *
+ * LOG_ODELAY no longer does anything.
+ * LOG_NDELAY is the inverse of what it used to be.
+ */
+#define        LOG_PID         0x01    /* log the pid with each message */
+#define        LOG_CONS        0x02    /* log on the console if errors in sending */
+#define        LOG_ODELAY      0x04    /* delay open until first syslog() (default) */
+#define        LOG_NDELAY      0x08    /* don't delay open */
+#define        LOG_NOWAIT      0x10    /* don't wait for console forks: DEPRECATED */
+#define        LOG_PERROR      0x20    /* log to stderr as well */
+
+#define SYSLOG_PORT     514
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Close desriptor used to write to system logger.  */
+extern void closelog (void);
+
+/* Open connection to system logger.  */
+extern void openlog (char *__ident, int __option, int __facility);
+
+/* Set the log mask level.  */
+extern int setlogmask (int __mask);
+
+/* Generate a log message using FMT string and option arguments.  */
+extern void syslog (int __pri, char *__fmt, ...);
+
+/* Generate a log message using FMT and using arguments pointed to by AP.  */
+extern void vsyslog (int __pri, char *__fmt, va_list __ap);
+
+/* windows-specific;
+   set directory from where syslog.host must be read;
+   this file contains a single line with hostname and port of syslog daemon;
+   default is localhost:514
+*/
+extern const char* set_syslog_conf_dir( const char* dir );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* syslog.h */
diff --git a/reactos/base/services/telnetd/telnetd.c b/reactos/base/services/telnetd/telnetd.c
new file mode 100644 (file)
index 0000000..6dbd20d
--- /dev/null
@@ -0,0 +1,636 @@
+/*
+ * Abstract: a simple telnet 'daemon' for Windows hosts.
+ *
+ * Compiled & run successfully using MSVC 5.0 under Windows95 (requires 
+ * Winsock2 update) and Windows98 and MSVC 6.0 under WindowsNT4
+ *
+ * Compiler options : no special options needed
+ * Linker options   : add wsock32.lib or ws2_32.lib
+ *
+ * Written by fred.van.lieshout 'at' zonnet.nl
+ * Use freely, no copyrights.
+ * Use Linux.
+ *
+ * Parts Copyright Steven Edwards
+ * Public Domain
+ *
+ * TODO: 
+ * - access control
+ * - will/won't handshake
+ * - Unify Debugging output and return StatusCodes
+ */
+
+#include "telnetd.h"
+
+#define telnetd_printf printf
+#if 0
+static inline int telnetd_printf(const char *format, ...);
+{
+    printf(format,...);
+    syslog (6, format);
+}
+#endif
+
+/* Local data */
+
+static BOOLEAN bShutdown = 0;
+static BOOLEAN bSocketInterfaceInitialised = 0;
+static int sock;
+
+/* In the future, some options might be passed here to handle
+ * authentication options in the registry or command line
+ * options passed to the service
+ *
+ * Once you are ready to turn on the service
+ * rename this function
+ * int kickoff_telnetd(void)
+ */
+int main(int argc, char **argv)
+{
+  printf("Attempting to start Simple TelnetD\n");
+
+//  DetectPlatform();
+  SetConsoleCtrlHandler(Cleanup, 1);
+
+  if (!StartSocketInterface())
+    ErrorExit("Unable to start socket interface\n");
+
+  CreateSocket();
+
+  while(!bShutdown) {
+    WaitForConnect();
+  }
+
+  WSACleanup();
+  return 0;
+}
+
+/* Cleanup */
+static BOOL WINAPI Cleanup(DWORD dwControlType)
+{
+  if (bSocketInterfaceInitialised) {
+    telnetd_printf("Cleanup...\n");
+    WSACleanup();
+  }
+  return 0;
+}
+
+/* StartSocketInterface */
+static BOOLEAN StartSocketInterface(void)
+{
+  WORD    wVersionRequested;
+  WSADATA wsaData;
+  int     err; 
+
+  wVersionRequested = MAKEWORD( 2, 0 ); 
+  err = WSAStartup(wVersionRequested, &wsaData);
+  if (err != 0) {
+    telnetd_printf("requested winsock version not supported\n");
+    return 0;
+  } 
+
+  bSocketInterfaceInitialised = 1; /* for ErrorExit function */
+
+  if ( wsaData.wVersion != wVersionRequested)
+    ErrorExit("requested winsock version not supported\n");
+
+  telnetd_printf("TelnetD, using %s\n", wsaData.szDescription);
+  return 1;
+}
+
+/* CreateSocket */
+static void CreateSocket(void)
+{
+   struct sockaddr_in sa;
+
+   sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+   if (sock < 0)
+     ErrorExit("Cannot create socket");
+
+   memset(&sa, 0, sizeof(sa));
+   sa.sin_family = AF_INET;
+   sa.sin_addr.s_addr = INADDR_ANY;
+   sa.sin_port = htons(TELNET_PORT);
+
+   if (bind(sock, (struct sockaddr*) &sa, sizeof(sa)) != 0)
+      ErrorExit("Cannot bind address to socket");
+}
+
+/* WaitForConnect */
+static void WaitForConnect(void)
+{
+  struct sockaddr_in sa;
+  int new_sock;
+
+  if (listen(sock, 1) < 0)
+     ErrorExit("Cannot listen on socket");
+
+  if ((new_sock = accept(sock, (struct sockaddr*) &sa, NULL)) < 0) {
+    fprintf(stderr, "Failed to accept incoming call\n");
+  } else {
+    telnetd_printf("user connected on socket %d, port %d, address %lx\n", new_sock,
+                                       htons(sa.sin_port), sa.sin_addr.s_addr);
+    UserLogin(new_sock);
+  }
+}
+
+/* Function: UserLogin */
+static void UserLogin(int client_socket)
+{
+  DWORD      threadID;
+  client_t  *client = malloc(sizeof(client_t));
+
+  if (client == NULL)
+    ErrorExit("failed to allocate memory for client");
+
+  client->socket = client_socket;
+  CreateThread(NULL, 0, UserLoginThread, client, 0, &threadID);
+}
+
+/* Function: UserLoginThread */
+static DWORD WINAPI UserLoginThread(LPVOID data)
+{
+  client_t  *client = (client_t *) data;
+  char       welcome[256];
+  char       hostname[64] = "Unknown";
+  char      *pwdPrompt = "\r\npass:";
+  //char      *logonPrompt = "\r\nLogin OK, please wait...";
+  //char      *byebye = "\r\nWrong! bye bye...\r\n";
+  char       userID[USERID_SIZE];
+  char       password[USERID_SIZE];
+  int        received;
+  char      *terminator;
+
+  if (DoTelnetHandshake(client->socket)) {
+    closesocket(client->socket);
+    free(client);
+    return 0;
+  }
+
+  gethostname(hostname, sizeof(hostname));
+  sprintf(welcome, "\r\nWelcome to %s, please identify yourself\r\n\r\nuser:", hostname);
+
+  if (send(client->socket, welcome, strlen(welcome), 0) < 0) {   
+    closesocket(client->socket);
+    free(client);
+    return 0;
+  }
+  received = ReceiveLine(client->socket, userID, sizeof(userID), Echo );
+  if (received < 0) {
+    closesocket(client->socket);
+    free(client);
+    return 0;
+  } else if (received) {
+    if ((terminator = strchr(userID, CR)) != NULL) {
+      *terminator = '\0';
+    }
+  }
+
+  if (send(client->socket, pwdPrompt, strlen(pwdPrompt), 0) < 0) {   
+    closesocket(client->socket);
+    free(client);
+    return 0;
+  }
+  received = ReceiveLine(client->socket, password, sizeof(password), Password );
+
+#if 0
+  if (received < 0) {
+    closesocket(client->socket);
+    free(client);
+    return 0;
+  } else if (received) {
+    if ((terminator = strchr(password, CR)) != NULL) {
+      *terminator = '\0';
+    }
+  }
+#endif
+
+  /* TODO: do authentication here */
+
+  
+  telnetd_printf("User '%p' logged on\n", userID);
+#if 0
+  strcpy(client->userID, userID);
+  if (send(client->socket, logonPrompt, strlen(logonPrompt), 0) < 0) {   
+    closesocket(client->socket);
+    free(client);
+    return 0;
+  }
+#endif
+  RunShell(client);
+  return 0;
+}
+
+/* Function: DoTelnetHandshake */
+static int DoTelnetHandshake(int sock)
+{
+  int retval;
+  int received;
+  fd_set set;
+  struct timeval timeout = { HANDSHAKE_TIMEOUT, 0 };
+
+  char will_echo[]=
+      IAC DONT ECHO
+      IAC WILL ECHO
+      IAC WILL NAWS
+      IAC WILL SUPPRESS_GO_AHEAD
+      IAC DO SUPPRESS_GO_AHEAD
+      IAC DONT NEWENVIRON
+      IAC WONT NEWENVIRON
+      IAC WONT LINEMODE
+      IAC DO NAWS
+      IAC SB TERMINAL_TYPE "\x01" IAC SE
+      ;
+
+  unsigned char client_reply[256];
+
+  if (send(sock, will_echo, sizeof(will_echo), 0) < 0) {   
+    return -1;
+  }
+
+  /* Now wait for client response (and ignore it) */
+  FD_ZERO(&set);
+  FD_SET(sock, &set);
+
+  do {
+    retval = select(0, &set, NULL, NULL, &timeout);
+    /* check for error */
+    if (retval < 0) {
+      return -1;
+      /* check for timeout */
+    } else if (retval == 0) {
+      return 0;
+    }
+    /* no error and no timeout, we have data in our sock */
+    received = recv(sock, (char *) client_reply, sizeof(client_reply), 0);
+    if (received <= 0) {
+     return -1;
+    }
+  } while (retval);
+
+  return 0;
+}
+
+/*
+** Function: ReceiveLine
+**
+** Abstract: receive until timeout or CR
+** In      : sock, len
+** Out     : buffer
+** Result  : int
+** Pre     : 'sock' must be valid socket
+** Post    : (result = the number of bytes read into 'buffer')
+**           OR (result = -1 and error)
+*/
+static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo)
+{
+  int            i = 0;
+  int            retval;
+  fd_set         set;
+  struct timeval timeout = { 0, 100000 };
+  char           del[3] = { BS, ' ', BS };
+  char           asterisk[1] = { '*' };
+
+  FD_ZERO(&set);
+  FD_SET(sock, &set);
+
+  memset(buffer, '\0', len);
+
+  do {
+    /* When we're in echo mode, we do not need a timeout */
+    retval = select(0, &set, NULL, NULL, (echo ? NULL : &timeout) );
+    /* check for error */
+    if (retval < 0) {
+      return -1;
+      /* check for timeout */
+    } else if (retval == 0) {
+      /* return number of characters received so far */
+      return i;
+    }
+    /* no error and no timeout, we have data in our sock */
+    if (recv(sock, &buffer[i], 1, 0) <= 0) {
+      return -1;
+    }
+    if ((buffer[i] == '\0') || (buffer[i] == LF)) {
+      /* ignore null characters and linefeeds from DOS telnet clients */
+      buffer[i] = '\0';
+    } else if ((buffer[i] == DEL) || (buffer[i] == BS)) {
+      /* handle delete and backspace */
+      buffer[i] = '\0';
+      if (echo) {
+             if (i > 0) {
+          i--;
+          buffer[i] = '\0';
+          if (send(sock, del, sizeof(del), 0) < 0) {
+            return -1;
+          }
+        }
+      } else {
+        buffer[i] = BS;  /* Let shell process handle it */
+             i++;
+      }
+    } else {
+      /* echo typed characters */
+      if (echo == Echo && send(sock, &buffer[i], 1, 0) < 0) {
+        return -1;
+      } else if (echo == Password && send(sock, asterisk, sizeof(asterisk), 0) < 0) {
+        return -1;
+      }
+      if (buffer[i] == CR) {
+        i++;
+        buffer[i] = LF; /* append LF for DOS command processor */
+        i++;
+        return i;
+      }
+
+      i++;
+    }    
+  } while (i < len);
+
+  return i;
+}
+
+/*
+** Function: RunShell
+*/
+static void RunShell(client_t *client) 
+{ 
+   DWORD                 threadID;
+   HANDLE                hChildStdinRd;
+   HANDLE                hChildStdinWr;
+   HANDLE                hChildStdoutRd;
+   HANDLE                hChildStdoutWr;
+   STARTUPINFO           si;
+   PROCESS_INFORMATION   piProcInfo;
+   SECURITY_ATTRIBUTES   saAttr;
+
+   const char *name = "c:\\reactos\\system32\\cmd.exe";
+   const char *cmd = NULL;
+   //const char *name = "d:\\cygwin\\bin\\bash.exe";
+   //const char *cmd = "d:\\cygwin\\bin\\bash.exe --login -i";
+   
+   saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
+   saAttr.bInheritHandle = TRUE; 
+   saAttr.lpSecurityDescriptor = NULL; 
+   
+   // Create a pipe for the child process's STDOUT.  
+   if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 
+      ErrorExit("Stdout pipe creation failed\n");  
+
+   if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 
+      ErrorExit("Stdin pipe creation failed\n");  
+
+
+   client->bTerminate = FALSE;
+   client->bWriteToPipe = TRUE;
+   client->bReadFromPipe = TRUE;
+   client->hChildStdinWr = hChildStdinWr;   
+   client->hChildStdoutRd = hChildStdoutRd;
+
+
+   // Create the child process (the shell)
+   telnetd_printf("Creating child process...\n");
+
+   ZeroMemory( &si, sizeof(STARTUPINFO) );
+   si.cb = sizeof(STARTUPINFO);  
+
+   si.dwFlags = STARTF_USESTDHANDLES;
+   si.hStdInput = hChildStdinRd;
+   si.hStdOutput = hChildStdoutWr;
+   si.hStdError = hChildStdoutWr;
+
+   //si.dwFlags |= STARTF_USESHOWWINDOW;
+   //si.wShowWindow = SW_SHOW;
+
+   if (!CreateProcess((LPSTR) name,              // executable module
+                      (LPSTR) cmd,               // command line 
+                      NULL,                      // process security attributes 
+                      NULL,                      // primary thread security attributes 
+                      TRUE,                      // handles are inherited 
+                      DETACHED_PROCESS +         // creation flags 
+                      CREATE_NEW_PROCESS_GROUP,
+                      NULL,                      // use parent's environment 
+                      NULL,                      // use parent's current directory 
+                      &si,                       // startup info
+                      &piProcInfo)) {
+     ErrorExit("Create process failed");
+   }
+
+   client->hProcess = piProcInfo.hProcess;
+   client->dwProcessId = piProcInfo.dwProcessId;
+
+   telnetd_printf("New child created (groupid=%lu)\n", client->dwProcessId);
+
+   // No longer need these in the parent...
+   if (!CloseHandle(hChildStdoutWr)) 
+     ErrorExit("Closing handle failed");  
+
+   if (!CloseHandle(hChildStdinRd)) 
+     ErrorExit("Closing handle failed");  
+
+   CreateThread(NULL, 0, WriteToPipeThread, client, 0, &threadID);
+   CreateThread(NULL, 0, ReadFromPipeThread, client, 0, &threadID);
+   CreateThread(NULL, 0, MonitorChildThread, client, 0, &threadID);
+} 
+
+/*
+ * Function: MonitorChildThread
+ *
+ * Abstract: Monitor the child (shell) process
+ */
+static DWORD WINAPI MonitorChildThread(LPVOID data)
+{
+  DWORD exitCode;
+  client_t *client = (client_t *) data;
+
+  telnetd_printf("Monitor thread running...\n");
+
+  WaitForSingleObject(client->hProcess, INFINITE);
+
+  GetExitCodeProcess(client->hProcess, &exitCode);
+  telnetd_printf("Child process terminated with code %lx\n", exitCode);
+
+  /* signal the other threads to give up */
+  client->bTerminate = TRUE;
+
+  Sleep(500);
+
+  CloseHandle(client->hChildStdoutRd);
+  CloseHandle(client->hChildStdinWr);       
+  CloseHandle(client->hProcess);
+
+  closesocket(client->socket);
+
+  telnetd_printf("Waiting for all threads to give up..\n");
+
+  while (client->bWriteToPipe || client->bReadFromPipe) {
+    telnetd_printf(".");
+    fflush(stdout);
+    Sleep(1000);
+  }
+
+  telnetd_printf("Cleanup for user '%s'\n", client->userID);
+  free(client);
+  return 0;
+}
+
+/*
+ * Function: WriteToPipeThread
+ * 
+ * Abstract: read data from the telnet client socket
+ *           and pass it on to the shell process.
+ */
+static DWORD WINAPI WriteToPipeThread(LPVOID data)
+{
+  int       iRead;
+  DWORD     dwWritten;
+  CHAR      chBuf[BUFSIZE];
+  client_t *client = (client_t *) data;
+
+  while (!client->bTerminate) {
+    iRead = ReceiveLine(client->socket, chBuf, BUFSIZE, FALSE);
+    if (iRead < 0) {
+      telnetd_printf("Client disconnect\n");
+      break;
+    } else if (iRead > 0) {
+      if (strchr(chBuf, CTRLC)) {
+        GenerateConsoleCtrlEvent(CTRL_C_EVENT, client->dwProcessId);
+      }
+      if (send(client->socket, chBuf, iRead, 0) < 0) {
+                telnetd_printf("error writing to socket\n");
+         break;    
+         }
+      if (! WriteFile(client->hChildStdinWr, chBuf, (DWORD) iRead, &dwWritten, NULL)) {
+        telnetd_printf("Error writing to pipe\n");
+        break;
+      }
+    }
+  }
+
+  if (!client->bTerminate)
+    TerminateShell(client);
+
+  telnetd_printf("WriteToPipeThread terminated\n");
+
+  client->bWriteToPipe = FALSE;
+  return 0;
+}
+
+/*
+ * Function: ReadFromPipeThread
+ *
+ * Abstract: Read data from the shell's stdout handle and
+ *           pass it on to the telnet client socket.
+ */
+static DWORD WINAPI ReadFromPipeThread(LPVOID data) 
+{    
+  DWORD dwRead;
+  DWORD dwAvail;
+  CHAR chBuf[BUFSIZE];
+  CHAR txBuf[BUFSIZE*2];
+  DWORD from,to;
+  //char warning[] = "warning: rl_prep_terminal: cannot get terminal settings";
+
+  client_t *client = (client_t *) data;
+
+  while (!client->bTerminate && client->bWriteToPipe) {
+    // Since we do not want to block, first peek...
+    if (PeekNamedPipe(client->hChildStdoutRd, NULL, 0, NULL, &dwAvail, NULL) == 0) {
+      telnetd_printf("Failed to peek in pipe\n");
+      break;
+    }
+    if (dwAvail) {
+      if( ! ReadFile( client->hChildStdoutRd, chBuf, BUFSIZE, &dwRead, NULL) ||
+           dwRead == 0) {
+        telnetd_printf("Failed to read from pipe\n");
+        break;
+      }
+         for (from=0, to=0; from<dwRead; from++, to++) {
+        txBuf[to] = chBuf[from];
+               if (txBuf[to] == '\n') {
+                       txBuf[to] = '\r';
+                       to++;
+                       txBuf[to] = '\n';
+               }
+         }
+      if (send(client->socket, txBuf, to, 0) < 0) {
+                telnetd_printf("error writing to socket\n");
+         break;    
+         }
+       }
+    Sleep(100); /* Hmmm, oh well... what the heck! */
+  }
+
+  if (!client->bTerminate)
+    TerminateShell(client);
+
+  telnetd_printf("ReadFromPipeThread terminated\n");
+
+  client->bReadFromPipe = FALSE;
+  return 0;
+}
+
+/* TerminateShell */ 
+static void TerminateShell(client_t *client)
+{
+    DWORD exitCode;
+    DWORD dwWritten;
+    char stop[] = "\003\r\nexit\r\n"; /* Ctrl-C + exit */
+
+    GetExitCodeProcess(client->hProcess, &exitCode);
+
+    if (exitCode == STILL_ACTIVE)
+    {
+        HANDLE hEvent = NULL;
+        DWORD dwWaitResult;
+
+        telnetd_printf("user shell still active, send Ctrl-Break to group-id %lu\n", client->dwProcessId );
+
+        hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+        if (hEvent == NULL)
+            printf("CreateEvent error\n");
+
+        if (!GenerateConsoleCtrlEvent( CTRL_BREAK_EVENT, client->dwProcessId ))
+            telnetd_printf("Failed to send Ctrl_break\n");
+
+        if (!GenerateConsoleCtrlEvent( CTRL_C_EVENT, client->dwProcessId ))
+            telnetd_printf("Failed to send Ctrl_C\n");
+
+        if (!WriteFile(client->hChildStdinWr, stop, sizeof(stop), &dwWritten, NULL))
+            telnetd_printf("Error writing to pipe\n");
+
+        /* wait for our handler to be called */
+        dwWaitResult=WaitForSingleObject(hEvent, 500);
+
+        if (WAIT_FAILED==dwWaitResult)
+            telnetd_printf("WaitForSingleObject failed\n");
+
+        GetExitCodeProcess(client->hProcess, &exitCode);
+        if (exitCode == STILL_ACTIVE) 
+        {
+            telnetd_printf("user shell still active, attempt to terminate it now...\n");
+        
+            if (hEvent != NULL) 
+            {
+                if (!CloseHandle(hEvent)) 
+                   telnetd_printf("CloseHandle");
+            }
+            TerminateProcess(client->hProcess, 0);
+        }
+        TerminateProcess(client->hProcess, 0);
+    }
+    TerminateProcess(client->hProcess, 0);
+}
+
+/* ErrorExit */
+static VOID ErrorExit (LPTSTR lpszMessage) 
+{ 
+   fprintf(stderr, "%s\n", lpszMessage);
+   if (bSocketInterfaceInitialised) {
+     telnetd_printf("WSAGetLastError=%d\n", WSAGetLastError());
+     WSACleanup();
+   }
+   ExitProcess(0); 
+} 
+
diff --git a/reactos/base/services/telnetd/telnetd.h b/reactos/base/services/telnetd/telnetd.h
new file mode 100644 (file)
index 0000000..afb1199
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef __TELNETD_H
+#define __TELNETD_H
+
+#define _CRT_SECURE_NO_WARNINGS
+
+#define WIN32_NO_STATUS
+#include <stdio.h>
+#include <winsock2.h>
+#include <tchar.h>
+#include <time.h>
+
+/*
+** macro definitions
+*/
+#define TELNET_PORT      (23)
+
+#define BUFSIZE        (4096)  
+#define USERID_SIZE      (64)
+#define CTRLC             (3)
+#define BS                (8)
+#define CR               (13)
+#define LF               (10)
+#define DEL             (127)
+
+#define IAC "\xff"
+#define DONT "\xfe"
+#define WONT "\xfc"
+#define WILL "\xfb"
+#define DO "\xfd"
+#define SB "\xfa"
+#define SE "\xf0"
+#define ECHO "\x01"
+#define SUPPRESS_GO_AHEAD "\x03"
+#define TERMINAL_TYPE "\x18"
+#define NAWS "\x1f"
+#define LINEMODE "\x22"
+#define NEWENVIRON "\x27"
+#define MODE "\x01"
+
+#define HANDSHAKE_TIMEOUT (3)
+
+/*
+** types
+*/
+
+typedef struct client_s
+{
+  char     userID[USERID_SIZE];
+  int      socket;
+  BOOLEAN  bTerminate;
+  BOOLEAN  bReadFromPipe;
+  BOOLEAN  bWriteToPipe;
+  HANDLE   hProcess;
+  DWORD    dwProcessId;
+  HANDLE   hChildStdinWr;   
+  HANDLE   hChildStdoutRd;
+} client_t;
+
+typedef enum
+{
+  NoEcho = 0,
+  Echo = 1,
+  Password = 2
+} EchoMode;
+
+/*
+** Forward function declarations
+*/
+static BOOL WINAPI Cleanup(DWORD dwControlType);
+static void WaitForConnect(void);
+static BOOLEAN StartSocketInterface(void);
+static void CreateSocket(void);
+static void UserLogin(int client_socket);
+static DWORD WINAPI UserLoginThread(LPVOID);
+static int DoTelnetHandshake(int sock);
+static int ReceiveLine(int sock, char *buffer, int len, EchoMode echo);
+static void RunShell(client_t *client); 
+//static BOOL CreateChildProcess(const char *); 
+static DWORD WINAPI MonitorChildThread(LPVOID);
+static DWORD WINAPI WriteToPipeThread(LPVOID); 
+static DWORD WINAPI ReadFromPipeThread(LPVOID); 
+static void TerminateShell(client_t *client);
+static VOID ErrorExit(LPTSTR);
+int kickoff_telnetd(void);
+
+#endif /* __TELNETD_H */
+
diff --git a/reactos/base/services/telnetd/telnetd.rbuild b/reactos/base/services/telnetd/telnetd.rbuild
new file mode 100644 (file)
index 0000000..3f6325a
--- /dev/null
@@ -0,0 +1,13 @@
+<module name="telnetd" type="win32cui" installbase="system32" installname="telnetd.exe" allowwarnings="true" unicode="no">
+       <include base="reactos"></include>
+       <include base="telnetd">..</include>
+
+       <library>ntdll</library>
+       <library>kernel32</library>
+       <library>advapi32</library>
+       <library>ws2_32</library>
+
+       <file>telnetd.c</file>
+       <file>serviceentry.c</file>
+       <file>telnetd.rc</file>
+</module>
diff --git a/reactos/base/services/telnetd/telnetd.rc b/reactos/base/services/telnetd/telnetd.rc
new file mode 100644 (file)
index 0000000..53760e9
--- /dev/null
@@ -0,0 +1,7 @@
+/* $Id$ */
+
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS Simple Telnet Deamon\0"
+#define REACTOS_STR_INTERNAL_NAME      "telnetd\0"
+#define REACTOS_STR_ORIGINAL_FILENAME  "telnetd.exe\0"
+#define REACTOS_STR_ORIGINAL_COPYRIGHT  "fred.van.lieshout 'at' zonnet.nl\0"
+#include <reactos/version.rc>
diff --git a/reactos/base/services/telnetd/telnetd.vcproj b/reactos/base/services/telnetd/telnetd.vcproj
new file mode 100644 (file)
index 0000000..9671495
--- /dev/null
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="9.00"
+       Name="telnetd"
+       ProjectGUID="{3B4D6C18-202E-41C8-B1E8-0FC5CD940819}"
+       RootNamespace="telnetd"
+       TargetFrameworkVersion="196613"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               MinimalRebuild="true"
+                               ExceptionHandling="0"
+                               BasicRuntimeChecks="3"
+                               WarningLevel="3"
+                               DebugInformationFormat="4"
+                               CallingConvention="2"
+                               CompileAs="1"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               AdditionalDependencies="msvcrt.lib advapi32.lib ws2_32.lib"
+                               IgnoreAllDefaultLibraries="true"
+                               GenerateDebugInformation="true"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="1"
+                       CharacterSet="2"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="2"
+                               EnableIntrinsicFunctions="true"
+                               RuntimeLibrary="2"
+                               EnableFunctionLevelLinking="true"
+                               WarningLevel="3"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLinkerTool"
+                               GenerateDebugInformation="true"
+                               OptimizeReferences="2"
+                               EnableCOMDATFolding="2"
+                               TargetMachine="1"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCManifestTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCAppVerifierTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\serviceentry.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\telnetd.c"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath=".\telnetd.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
index e2b2fc5..1961332 100644 (file)
@@ -670,7 +670,6 @@ modules\rosapps\applications\sysutils\man\man.exe
 modules\rosapps\applications\sysutils\pedump\pedump.exe                                 1   optional
 modules\rosapps\applications\sysutils\regexpl\regexpl.exe                               1   optional
 modules\rosapps\applications\sysutils\tcat\tcat.exe                                     1   optional
 modules\rosapps\applications\sysutils\pedump\pedump.exe                                 1   optional
 modules\rosapps\applications\sysutils\regexpl\regexpl.exe                               1   optional
 modules\rosapps\applications\sysutils\tcat\tcat.exe                                     1   optional
-modules\rosapps\applications\sysutils\telnetd\telnetd.exe                               1   optional
 modules\rosapps\applications\sysutils\tlist\tlist.exe                                   1   optional
 modules\rosapps\applications\sysutils\screenshot\screenshot.exe                         1   optional
 modules\rosapps\applications\sysutils\utils\binpatch\binpatch.exe                       1   optional
 modules\rosapps\applications\sysutils\tlist\tlist.exe                                   1   optional
 modules\rosapps\applications\sysutils\screenshot\screenshot.exe                         1   optional
 modules\rosapps\applications\sysutils\utils\binpatch\binpatch.exe                       1   optional