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 595 by douglas, 2005-11-27T17:57:41-08:00 vs.
Revision 612 by douglas, 2005-12-05T02:32:27-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   #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 +                        std::string name_(Utf8(name));
50 +
51 +                        if (!name_.empty())
52 +                                stream << name_ << "\r\n";
53 +
54 +                        WTSFreeMemory(name);
55 +
56 +                        //PWTS_CLIENT_ADDRESS address;
57 +                        //WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSClientAddress, reinterpret_cast<LPTSTR *>(&address), &size);
58 +                        //WTSFreeMemory(address);
59 +                }
60 +
61 +                WTSFreeMemory(sessions);
62 +        }
63 +
64 +        Finger(const std::string &name)
65 +        {
66 +                //NetQueryDisplayInformation
67 +                //NetUserGetInfo
68 +        }
69 +
70 +        inline operator std::string()
71 +        {
72 +                return stream.str();
73 +        }
74 + };
75  
76   LPTSTR name;
77   SERVICE_STATUS status;
78   SERVICE_STATUS_HANDLE handle;
79   HANDLE stop;
80   WSADATA data;
81 + std::vector<HANDLE> threads;
82  
83 + void FingerDaemon();
84 + DWORD WINAPI FingerListen(LPVOID server_);
85 + DWORD WINAPI FingerDo(LPVOID client_);
86 + void FingerStop(int);
87   void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
88   void WINAPI FingerControl(DWORD control);
89  
# Line 51 | Line 120 | int _tmain(int argc, TCHAR *argv[])
120          return 0;
121  
122   go:
123 <        std::cout << "Here!" << std::endl;
123 >        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
124 >
125 >        signal(SIGINT, FingerStop);
126 >
127 >        try
128 >        {
129 >                FingerDaemon();
130 >        }
131 >        catch (...) {}
132 >
133 >        return 0;
134 > }
135 >
136 > void FingerDaemon()
137 > {
138 >        WSAStartup(MAKEWORD(2, 0), &data);
139 >
140 >        //
141 >
142 >        SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
143 >        SOCKADDR_IN service;
144 >        
145 >        service.sin_family = AF_INET;
146 >        service.sin_addr.s_addr = inet_addr("0.0.0.0");
147 >        service.sin_port = htons(79);
148 >
149 >        bind(server, (SOCKADDR *)(&service), sizeof (service));
150 >        listen(server, SOMAXCONN);
151 >
152 >        threads.push_back(CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
153 >
154 >        while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
155 >
156 >        //
157 >
158 >        closesocket(server);
159 >
160 >        WSACleanup();
161 > }
162 >
163 > DWORD WINAPI FingerListen(LPVOID server_)
164 > {
165 >        SOCKET &server(*reinterpret_cast<SOCKET *>(server_));
166 >
167 >        while (true)
168 >        {
169 >                SOCKET client(accept(server, NULL, NULL));
170 >
171 >                threads.push_back(CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
172 >        }
173 >
174 >        return 0;
175 > }
176 >
177 > DWORD WINAPI FingerDo(LPVOID client_)
178 > {
179 >        SOCKET &client(*reinterpret_cast<SOCKET *>(client_));
180 >        char buffer[1024];
181 >        std::istringstream stream(std::string(buffer, recv(client, buffer, sizeof buffer, 0)));
182 >        std::string line;
183 >
184 >        std::getline(stream, line);
185 >
186 >        stream.str(line);
187 >
188 >        std::getline(stream, line, '\r');
189 >
190 >        stream.str(line);
191 >
192 >        std::string name;
193 >        bool full(false);
194 >
195 >        while (stream >> line)
196 >                if (line == "/W")
197 >                        full = true;
198 >                else
199 >                        name = line;
200 >
201 >        std::string finger(name.empty() ? Finger(full) : Finger(name));
202 >
203 >        send(client, finger.data(), int(finger.size()), 0);
204 >        closesocket(client);
205  
206          return 0;
207   }
208  
209 + void FingerStop(int)
210 + {
211 +        SetEvent(stop);
212 + }
213 +
214   void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
215   {
216          name = argv[0];
# Line 64 | Line 219 | void WINAPI FingerMain(DWORD argc, LPTST
219  
220          //
221  
67        WSAStartup(MAKEWORD(2, 0), &data);
68
69        //
70
222          status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
223          status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
224          status.dwServiceSpecificExitCode = 0;
# Line 78 | Line 229 | void WINAPI FingerMain(DWORD argc, LPTST
229  
230          SetServiceStatus(handle, &status);
231  
232 <        SOCKET sock(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
82 <        SOCKADDR_IN service;
83 <        
84 <        service.sin_family = AF_INET;
85 <        service.sin_addr.s_addr = inet_addr("0.0.0.0");
86 <        service.sin_port = htons(79);
87 <
88 <        bind(sock, (SOCKADDR *)(&service), sizeof (service));
89 <        listen(sock, SOMAXCONN);
90 <
91 <        while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0 /*&&*/)
232 >        try
233          {
234 <                //
234 >                FingerDaemon();
235          }
236 <
96 <        //
97 <
98 <        WSACleanup();
236 >        catch (...) {}
237  
238          status.dwCurrentState = SERVICE_STOPPED;
239          status.dwWin32ExitCode = NO_ERROR;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines