:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / apps / utils / net / telnet / main.cpp
1 /* $Id$
2  *
3  * FILE       : main.cpp
4  * AUTHOR     : unknown (sources found on www.telnet.org)
5  * PROJECT    : ReactOS Operating System
6  * DESCRIPTION: telnet client for the W32 subsystem
7  * DATE       : 2001-01-21
8  * REVISIONS
9  *      2001-02-21 ea   Modified to compile under 0.0.16 src tree
10  *      2001-02-27 ea   If run with no argument, it asks for a hostname.
11  */
12 ///////////////////////////////////////////////////////////////////////////////
13 //
14 // File:
15 //        main.cpp
16 // 
17 // Purpose:
18 //        This file provdes the main entry point for the project, and all the
19 //        global scope support routines.
20 //
21 // Notes:
22 //        This file expects to be linked without the C-Runtime. If compiling,
23 //        please force the entry point symbol to be "main", and do not link in
24 //        the default librarys.
25 //        This means that no c-runtime functions can be used anywhere in the
26 //        project. I expect this will also exclude any MFC based additions.
27 //
28 ///////////////////////////////////////////////////////////////////////////////
29
30 #include <winsock.h>
31 #include <windows.h>
32 #include <process.h>
33 #include <stdlib.h>
34
35 #include "telnet.h"
36
37 ///////////////////////////////////////////////////////////////////////////////
38
39 //
40 // Our simple replacement for the c-runtime includes getting the StandardInput,
41 // StandardOutput & StandardError handles, and providing new and delete operators, that work
42 // with the win32 heap functions.
43 //
44
45 //
46 // standard handles needed for CRT emulation
47 //
48 HANDLE hHeap;
49 HANDLE StandardInput;
50 HANDLE StandardOutput;
51 HANDLE StandardError;
52
53 //
54 // new will use the win32 heap functions.
55 //
56 void* operator new(unsigned int nSize)
57 {
58   return HeapAlloc(hHeap,0,nSize);
59 }
60
61 //
62 // delete operator provides all memory de-allocation.
63 // HeapFree doesn't accept NULL.
64 //
65 void operator delete(void* pMem)
66 {
67   if(pMem) HeapFree(hHeap,0,pMem);
68 }
69
70
71
72 void err(char const* s, ...)
73 {
74         char    buf [1024];
75         DWORD   nout;
76         
77         wvsprintf (buf, s, (char*)(s + sizeof(int)));
78         WriteFile (StandardError,"Error: ", 7, & nout, NULL);
79         WriteFile (StandardError, buf, lstrlen(buf), & nout, NULL);
80         WriteFile (StandardError, "\r\n\r\n", 4, & nout, NULL);
81 #ifdef _DEBUG
82         OutputDebugString(buf);
83         OutputDebugString("\n");
84 #endif
85         ExitProcess (ERROR_SUCCESS);
86 }
87
88
89 int main(int argc, char * argv[])
90 {
91         WSADATA wd;
92         int     errn;
93         char    name [256] = {'\0'};
94         short   port = IPPORT_TELNET; /* default tcp port */
95
96         ///////////////////////////////////////
97         // CRT emulation init
98         // Get the IO handles
99         StandardInput = GetStdHandle(STD_INPUT_HANDLE);
100         StandardOutput = GetStdHandle(STD_OUTPUT_HANDLE);
101         StandardError = GetStdHandle(STD_ERROR_HANDLE);
102
103         // Get the heap 
104         hHeap = GetProcessHeap();
105
106         // Explicitly force the console into a good mode (actually all we are doing is turning
107         // mouse input off.
108         SetConsoleMode (
109                 StandardInput,
110                 (ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT)
111                 );
112
113         ///////////////////////////////////////
114         // Init winsock
115
116         if (errn = WSAStartup (0x0101, & wd))
117         {
118                 err(sockmsg(errn));
119         }
120
121         /* hostname */
122         if (1 < argc)
123         {
124                 lstrcpy (name, argv [1]);
125         }
126         /*
127          * Default port is IPPORT_TELNET.
128          * User may hand one.
129          */
130         if (3 == argc)
131         {
132                 port = atoi (argv[2]);
133                 if (port <= 0)
134                 {
135                         struct servent * service = NULL;
136                         
137                         service = getservbyname (argv[2], "tcp");
138                         if (NULL == service)
139                         {
140                                 err("Invalid service name specified");
141                         }
142                         port = service->s_port;
143                 }
144                 else
145                 {
146                         err("Invalid port specified");
147                 }
148         }
149         /* Too many arguments */
150         if (3 < argc)
151         {
152                 err("Usage: telnet <hostname> [<port>]");
153         }
154         /* No argument */
155         if (1 == argc)
156         {
157                 DWORD Count;
158                 char *c;
159                 
160                 WriteFile (StandardError,"host: ", 6, & Count, NULL);
161                 ReadFile (StandardInput, name, sizeof name, & Count, NULL);
162                 c = name;
163                 while (*c > ' ') ++ c;
164                 *c = '\0';
165         }
166
167         // guess what this does.
168         telnet (name, port);
169
170         //Bye bye...
171         WSACleanup ();
172
173         // Exit process terminates any waiting threads.
174         // (Its the CRT that makes a process close when the main thread exits.
175         // The WinAPI will leave the process as is for as long as it has a 
176         // thread any thread.
177         ExitProcess (EXIT_SUCCESS);
178 }
179
180 /* EOF */