ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/CCSFinger/CCSFinger.cpp
(Generate patch)

Comparing CCSFinger/CCSFinger.cpp (file contents):
Revision 594 by douglas, 2005-11-27T17:04:53-08:00 vs.
Revision 610 by douglas, 2005-12-05T01:05:13-08:00

# Line 6 | Line 6
6  
7   #include <windows.h>
8   #include <tchar.h>
9 + #include <signal.h>
10 + #include <wtsapi32.h>
11  
12 < /*LPTSTR name;
12 > #include <iostream>
13 > #include <string>
14 > #include <sstream>
15 > #include <vector>
16 >
17 > inline std::string Utf8(const std::wstring &wstring)
18 > {
19 >        std::string string(WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), NULL, 0, NULL, NULL), '\0');
20 >
21 >        WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), const_cast<LPSTR>(string.data()), int(string.size()), NULL, NULL);
22 >
23 >        return string;
24 > }
25 >
26 > class Finger
27 > {
28 > private:
29 >        std::ostringstream stream;
30 >
31 > public:
32 >        Finger(bool full)
33 >        {
34 >                if (!full)
35 >                        stream << "Login\t\tName\t\tTTY\r\n";
36 >
37 >                PWTS_SESSION_INFO sessions;
38 >                DWORD count;
39 >
40 >                WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count);
41 >
42 >                for (PWTS_SESSION_INFO session = sessions; session != sessions + count; ++session)
43 >                {
44 >                        LPTSTR name;
45 >                        DWORD size;
46 >
47 >                        WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &name, &size);
48 >
49 >                        stream << Utf8(name) << "\r\n";
50 >
51 >                        WTSFreeMemory(name);
52 >
53 >                        //PWTS_CLIENT_ADDRESS address;
54 >                        //WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSClientAddress, reinterpret_cast<LPTSTR *>(&address), &size);
55 >                        //WTSFreeMemory(address);
56 >                }
57 >
58 >                WTSFreeMemory(sessions);
59 >        }
60 >
61 >        Finger(const std::string &name)
62 >        {
63 >        }
64 >
65 >        inline operator std::string()
66 >        {
67 >                return stream.str();
68 >        }
69 > };
70 >
71 > LPTSTR name;
72   SERVICE_STATUS status;
73   SERVICE_STATUS_HANDLE handle;
74 < HANDLE stop;*/
74 > HANDLE stop;
75   WSADATA data;
76 + std::vector<HANDLE> threads;
77  
78 < /*void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
79 < void WINAPI FingerControl(DWORD control);*/
78 > void FingerDaemon();
79 > DWORD WINAPI FingerListen(LPVOID server_);
80 > DWORD WINAPI FingerDo(LPVOID client_);
81 > void FingerStop(int);
82 > void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
83 > void WINAPI FingerControl(DWORD control);
84  
85   int _tmain(int argc, TCHAR *argv[])
86   {
87 <        /*SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
87 >        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
88  
89          if (!StartServiceCtrlDispatcher(entry))
90          {
# Line 27 | Line 93 | int _tmain(int argc, TCHAR *argv[])
93                  switch (error)
94                  {
95                  case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
96 <                        std::cerr << "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT" << std::endl;
31 <
32 <                        break;
96 >                        goto go;
97  
98                  case ERROR_INVALID_DATA:
99                          std::cerr << "ERROR_INVALID_DATA" << std::endl;
# Line 49 | Line 113 | int _tmain(int argc, TCHAR *argv[])
113          }
114  
115          return 0;
52 }
116  
117 < void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
55 < {
56 <        name = argv[0];
57 <        handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
117 > go:
118          stop = CreateEvent(NULL, TRUE, FALSE, NULL);
119  
120 <        //*/
120 >        signal(SIGINT, FingerStop);
121  
122 <        WSAStartup(MAKEWORD(2, 0), &data);
122 >        try
123 >        {
124 >                FingerDaemon();
125 >        }
126 >        catch (...) {}
127  
128 <        //
128 >        return 0;
129 > }
130  
131 <        /*status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
132 <        status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
133 <        status.dwServiceSpecificExitCode = 0;
69 <        status.dwCurrentState = SERVICE_RUNNING;
70 <        status.dwWin32ExitCode = NO_ERROR;
71 <        status.dwCheckPoint = 0;
72 <        status.dwWaitHint = 0;
131 > void FingerDaemon()
132 > {
133 >        WSAStartup(MAKEWORD(2, 0), &data);
134  
135 <        SetServiceStatus(handle, &status);*/
135 >        //
136  
137 <        SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
137 >        SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
138          SOCKADDR_IN service;
139          
140          service.sin_family = AF_INET;
141          service.sin_addr.s_addr = inet_addr("0.0.0.0");
142          service.sin_port = htons(79);
143  
144 <        bind(sock, (SOCKADDR *)(&service), sizeof (service));
145 <        listen(sock, SOMAXCONN);
144 >        bind(server, (SOCKADDR *)(&service), sizeof (service));
145 >        listen(server, SOMAXCONN);
146 >
147 >        threads.push_back(CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
148  
149 <        //while(/*WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0*/ /*&&*/)
149 >        while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
150 >
151 >        //
152 >
153 >        closesocket(server);
154 >
155 >        WSACleanup();
156 > }
157 >
158 > DWORD WINAPI FingerListen(LPVOID server_)
159 > {
160 >        SOCKET &server(*reinterpret_cast<SOCKET *>(server_));
161 >
162 >        while (true)
163          {
164 <                //
164 >                SOCKET client(accept(server, NULL, NULL));
165 >
166 >                threads.push_back(CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
167          }
168  
169 +        return 0;
170 + }
171 +
172 + DWORD WINAPI FingerDo(LPVOID client_)
173 + {
174 +        SOCKET &client(*reinterpret_cast<SOCKET *>(client_));
175 +        char buffer[1024];
176 +        std::istringstream stream(std::string(buffer, recv(client, buffer, sizeof buffer, 0)));
177 +        std::string line;
178 +
179 +        std::getline(stream, line);
180 +
181 +        stream.str(line);
182 +
183 +        std::getline(stream, line, '\r');
184 +
185 +        stream.str(line);
186 +
187 +        std::string name;
188 +        bool full(false);
189 +
190 +        while (stream >> line)
191 +                if (line == "/W")
192 +                        full = true;
193 +                else
194 +                        name = line;
195 +
196 +        std::string finger(name.empty() ? Finger(full) : Finger(name));
197 +
198 +        send(client, finger.data(), int(finger.size()), 0);
199 +        closesocket(client);
200 +
201 +        return 0;
202 + }
203 +
204 + void FingerStop(int)
205 + {
206 +        SetEvent(stop);
207 + }
208 +
209 + void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
210 + {
211 +        name = argv[0];
212 +        handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
213 +        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
214 +
215          //
216  
217 <        WSACleanup();
217 >        status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
218 >        status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
219 >        status.dwServiceSpecificExitCode = 0;
220 >        status.dwCurrentState = SERVICE_RUNNING;
221 >        status.dwWin32ExitCode = NO_ERROR;
222 >        status.dwCheckPoint = 0;
223 >        status.dwWaitHint = 0;
224 >
225 >        SetServiceStatus(handle, &status);
226  
227 <        /*status.dwCurrentState = SERVICE_STOPPED;
227 >        try
228 >        {
229 >                FingerDaemon();
230 >        }
231 >        catch (...) {}
232 >
233 >        status.dwCurrentState = SERVICE_STOPPED;
234          status.dwWin32ExitCode = NO_ERROR;
235          status.dwCheckPoint = 0;
236          status.dwWaitHint = 0;
# Line 116 | Line 254 | void WINAPI FingerControl(DWORD control)
254                  break;
255          }
256  
257 <        SetServiceStatus(handle, &status);*/
120 <
121 <        return 0;
257 >        SetServiceStatus(handle, &status);
258   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines