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 613 by douglas, 2005-12-12T18:30:01-08:00

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines