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 608 by douglas, 2005-11-30T18:23:39-08:00 vs.
Revision 614 by douglas, 2005-12-12T18:47:20-08:00

# Line 8 | Line 8
8   #include <tchar.h>
9   #include <signal.h>
10   #include <wtsapi32.h>
11 + #include <lm.h>
12  
13   #include <iostream>
14   #include <string>
15 + #include <sstream>
16 + #include <vector>
17 + #include <set>
18  
19 < LPTSTR name;
20 < SERVICE_STATUS status;
21 < SERVICE_STATUS_HANDLE handle;
18 < HANDLE stop;
19 < WSADATA data;
19 > inline std::string Utf8(const std::wstring &wstring)
20 > {
21 >        std::string string(::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), NULL, 0, NULL, NULL), '\0');
22  
23 < void FingerDaemon();
22 < void FingerStop(int);
23 < void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
24 < void WINAPI FingerControl(DWORD control);
23 >        ::WideCharToMultiByte(CP_UTF8, 0, wstring.data(), int(wstring.size()), const_cast<LPSTR>(string.data()), int(string.size()), NULL, NULL);
24  
25 < int _tmain(int argc, TCHAR *argv[])
26 < {
28 <        PWTS_SESSION_INFO sessions;
29 <        DWORD count;
25 >        return string;
26 > }
27  
28 <        if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count))
28 > class Finger
29 > {
30 > private:
31 >        struct Login
32          {
33 <                std::cerr << GetLastError() << std::endl;
33 >                std::string login, name, session;
34 >                Login(const std::wstring &login, const std::wstring &session) : login(Utf8(login)), session(Utf8(session))
35 >                {
36 >                        USER_INFO_11 *info;
37  
38 <                return 1;
36 <        }
38 >                        ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
39  
40 <        for (PWTS_SESSION_INFO session = sessions; session != sessions + count; ++session)
41 <        {
42 <                LPTSTR userName, clientName;
43 <                DWORD userNameSize, clientNameSize;
40 >                        name = Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
41 >
42 >                        ::NetApiBufferFree(info);
43 >                }
44 >                bool operator<(const Login &login) const
45 >                {
46 >                        if (this->login == login.login)
47 >                                return session < login.session;
48 >                        else
49 >                                return this->login < login.login;
50 >                }
51 >        };
52 >        std::ostringstream stream;
53 >        std::set<Login> logins;
54  
55 <                WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &userName, &userNameSize);
56 <                WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSClientName, &clientName, &clientNameSize);
55 > public:
56 >        Finger(bool full)
57 >        {
58 >                PWTS_SESSION_INFO sessions;
59 >                DWORD count;
60  
61 <                std::wcout << '{' << std::endl
47 <                        << '\t' << session->SessionId << std::endl
48 <                        << '\t' << session->pWinStationName << std::endl
49 <                        << '\t';
61 >                ::WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &sessions, &count);
62  
63 <                switch (session->State)
63 >                for (PWTS_SESSION_INFO session(sessions); session != sessions + count; ++session)
64                  {
65 <                case WTSActive:
66 <                        std::cout << "Active";
55 <                        
56 <                        break;
57 <                case WTSConnected:
58 <                        std::cout << "Connected";
65 >                        LPTSTR name;
66 >                        DWORD size;
67  
68 <                        break;
61 <                case WTSConnectQuery:
62 <                        std::cout << "Connect Query";
68 >                        ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSUserName, &name, &size);
69  
70 <                        break;
71 <                case WTSShadow:
72 <                        std::cout << "Shadow";
70 >                        if (!std::wstring(name).empty())
71 >                        {
72 >                                LPTSTR session_;
73  
74 <                        break;
69 <                case WTSDisconnected:
70 <                        std::cout << "Disconnected";
74 >                                ::WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session->SessionId, WTSWinStationName, &session_, &size);
75  
76 <                        break;
73 <                case WTSIdle:
74 <                        std::cout << "Idle";
76 >                                Login login(name, session_);
77  
78 <                        break;
77 <                case WTSListen:
78 <                        std::cout << "Listen";
78 >                                ::WTSFreeMemory(session_);
79  
80 <                        break;
81 <                case WTSReset:
82 <                        std::cout << "Reset";
80 >                                logins.insert(login);
81 >                        }
82  
83 <                        break;
84 <                case WTSDown:
86 <                        std::cout << "Down";
83 >                        ::WTSFreeMemory(name);
84 >                }
85  
86 <                        break;
89 <                case WTSInit:
90 <                        std::cout << "Init";
86 >                ::WTSFreeMemory(sessions);
87  
88 <                        break;
88 >                if (!full)
89 >                {
90 >                        stream << "Login\t\tName" << std::string(17, ' ') << "Session\r\n";
91 >
92 >                        for (std::set<Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
93 >                                stream << login->login << std::string(16 - login->login.size(), ' ') << login->name << std::string(21 - login->name.size(), ' ') << login->session << "\r\n";
94                  }
95 +        }
96  
97 <                std::wcout << std::endl << '\t' << userName << std::endl
98 <                        << '\t' << clientName << std::endl
99 <                        << '}' << std::endl;
97 >        Finger(const std::string &name)
98 >        {
99 >                //NetQueryDisplayInformation
100 >                //NetUserGetInfo
101 >        }
102  
103 <                WTSFreeMemory(userName);
104 <                WTSFreeMemory(clientName);
103 >        inline operator std::string()
104 >        {
105 >                return stream.str();
106          }
107 + };
108  
109 <        WTSFreeMemory(sessions);
109 > LPTSTR name;
110 > SERVICE_STATUS status;
111 > SERVICE_STATUS_HANDLE handle;
112 > HANDLE stop;
113 > WSADATA data;
114 > std::vector<HANDLE> threads;
115  
116 <        /*SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
116 > void FingerDaemon();
117 > DWORD WINAPI FingerListen(LPVOID server_);
118 > DWORD WINAPI FingerDo(LPVOID client_);
119 > void FingerStop(int);
120 > void WINAPI FingerMain(DWORD argc, LPTSTR *argv);
121 > void WINAPI FingerControl(DWORD control);
122  
123 <        if (!StartServiceCtrlDispatcher(entry))
123 > int _tmain(int argc, TCHAR *argv[])
124 > {
125 >        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
126 >
127 >        if (!::StartServiceCtrlDispatcher(entry))
128          {
129 <                DWORD error(GetLastError());
129 >                DWORD error(::GetLastError());
130  
131                  switch (error)
132                  {
# Line 133 | Line 153 | int _tmain(int argc, TCHAR *argv[])
153          return 0;
154  
155   go:
156 <        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
156 >        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
157  
158 <        signal(SIGINT, FingerStop);
158 >        ::signal(SIGINT, FingerStop);
159  
160          try
161          {
# Line 143 | Line 163 | go:
163          }
164          catch (...) {}
165  
166 <        return 0;*/
166 >        return 0;
167   }
168  
169   void FingerDaemon()
170   {
171 <        WSAStartup(MAKEWORD(2, 0), &data);
171 >        ::WSAStartup(MAKEWORD(2, 0), &data);
172  
173          //
174  
175 <        SOCKET server(socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
175 >        SOCKET server(::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP));
176          SOCKADDR_IN service;
177          
178          service.sin_family = AF_INET;
179          service.sin_addr.s_addr = inet_addr("0.0.0.0");
180          service.sin_port = htons(79);
181  
182 <        bind(server, (SOCKADDR *)(&service), sizeof (service));
183 <        listen(server, SOMAXCONN);
182 >        ::bind(server, (SOCKADDR *)(&service), sizeof (service));
183 >        ::listen(server, SOMAXCONN);
184 >
185 >        threads.push_back(::CreateThread(NULL, 0, FingerListen, &server, 0, NULL));
186 >
187 >        while(::WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0);
188 >
189 >        //
190 >
191 >        ::closesocket(server);
192  
193 <        SOCKET client;
193 >        ::WSACleanup();
194 > }
195  
196 <        while(WaitForSingleObject(stop, 1000) != WAIT_OBJECT_0 && (client = accept(server, NULL, NULL)) == SOCKET_ERROR)
196 > DWORD WINAPI FingerListen(LPVOID server_)
197 > {
198 >        SOCKET &server(*reinterpret_cast<SOCKET *>(server_));
199 >
200 >        while (true)
201          {
202 <                //
202 >                SOCKET client(accept(server, NULL, NULL));
203 >
204 >                threads.push_back(::CreateThread(NULL, 0, FingerDo, &client, 0, NULL));
205          }
206  
207 <        //
207 >        return 0;
208 > }
209 >
210 > DWORD WINAPI FingerDo(LPVOID client_)
211 > {
212 >        SOCKET &client(*reinterpret_cast<SOCKET *>(client_));
213 >        char buffer[1024];
214 >        std::istringstream stream(std::string(buffer, ::recv(client, buffer, sizeof buffer, 0)));
215 >        std::string line;
216  
217 <        closesocket(server);
217 >        std::getline(stream, line);
218  
219 <        WSACleanup();
219 >        stream.str(line);
220 >
221 >        std::getline(stream, line, '\r');
222 >
223 >        stream.str(line);
224 >
225 >        std::string name;
226 >        bool full(false);
227 >
228 >        while (stream >> line)
229 >                if (line == "/W")
230 >                        full = true;
231 >                else
232 >                        name = line;
233 >
234 >        std::string finger(name.empty() ? Finger(full) : Finger(name));
235 >
236 >        ::send(client, finger.data(), int(finger.size()), 0);
237 >        ::closesocket(client);
238 >
239 >        return 0;
240   }
241  
242   void FingerStop(int)
243   {
244 <        SetEvent(stop);
182 <
183 <        std::cout << "Stop!" << std::endl;
244 >        ::SetEvent(stop);
245   }
246  
247   void WINAPI FingerMain(DWORD argc, LPTSTR *argv)
248   {
249          name = argv[0];
250          handle = RegisterServiceCtrlHandler(name, LPHANDLER_FUNCTION(FingerControl));
251 <        stop = CreateEvent(NULL, TRUE, FALSE, NULL);
251 >        stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
252  
253          //
254  
# Line 199 | Line 260 | void WINAPI FingerMain(DWORD argc, LPTST
260          status.dwCheckPoint = 0;
261          status.dwWaitHint = 0;
262  
263 <        SetServiceStatus(handle, &status);
263 >        ::SetServiceStatus(handle, &status);
264  
265          try
266          {
# Line 212 | Line 273 | void WINAPI FingerMain(DWORD argc, LPTST
273          status.dwCheckPoint = 0;
274          status.dwWaitHint = 0;
275  
276 <        SetServiceStatus(handle, &status);
276 >        ::SetServiceStatus(handle, &status);
277   }
278  
279   void WINAPI FingerControl(DWORD control)
# Line 223 | Line 284 | void WINAPI FingerControl(DWORD control)
284          case SERVICE_CONTROL_SHUTDOWN:
285                  status.dwCurrentState = SERVICE_STOP_PENDING;
286  
287 <                SetEvent(stop);
287 >                ::SetEvent(stop);
288  
289                  break;
290  
# Line 231 | Line 292 | void WINAPI FingerControl(DWORD control)
292                  break;
293          }
294  
295 <        SetServiceStatus(handle, &status);
295 >        ::SetServiceStatus(handle, &status);
296   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines