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 616 by douglas, 2005-12-12T20:25:45-08:00 vs.
Revision 640 by douglas, 2006-01-04T20:54:20-08:00

# Line 5 | Line 5
5   // Windows Finger Daemon
6  
7   #include <windows.h>
8 < #include <tchar.h>
8 > #include <lm.h>
9   #include <signal.h>
10 + #include <tchar.h>
11 + #include <shlobj.h>
12   #include <wtsapi32.h>
11 #include <lm.h>
13  
14   #include <algorithm>
15 < #include <iostream>
15 > #include <cctype>
16 > #include <cwctype>
17 > #include <fstream>
18   #include <iomanip>
19 < #include <string>
19 > #include <iostream>
20 > #include <map>
21   #include <sstream>
22 + #include <string>
23   #include <vector>
19 #include <map>
20 #include <cwctype>
24  
25   std::ostream &operator<<(std::ostream &out, WTS_CONNECTSTATE_CLASS status)
26   {
# Line 67 | Line 70 | inline std::string Utf8(const std::wstri
70          return string;
71   }
72  
73 + inline std::wstring Utf8(const std::string &string)
74 + {
75 +        std::wstring wstring(::MultiByteToWideChar(CP_UTF8, 0, string.data(), int(string.size()), NULL, 0), '\0');
76 +
77 +        ::MultiByteToWideChar(CP_UTF8, 0, string.data(), int(string.size()), const_cast<LPWSTR>(wstring.data()), int(wstring.size()));
78 +
79 +        return wstring;
80 + }
81 +
82   class Finger
83   {
84          class Login
# Line 76 | Line 88 | class Finger
88  
89                  inline void GetInfo() const
90                  {
91 <                        ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
91 >                        if (!info)
92 >                                ::NetUserGetInfo(NULL, login.c_str(), 11, reinterpret_cast<LPBYTE *>(&info));
93                  }
94          public:
95                  std::string session;
# Line 93 | Line 106 | class Finger
106                                  ::NetApiBufferFree(info);
107                  }
108  
109 <                std::string GetName() const
109 >                std::string GetShortName() const
110                  {
111 <                        if (!info)
99 <                                GetInfo();
111 >                        GetInfo();
112  
113                          return Utf8(std::wstring(info->usri11_full_name).substr(0, 20));
114                  }
115 +
116 +                std::string GetName() const
117 +                {
118 +                        GetInfo();
119 +
120 +                        return Utf8(info->usri11_full_name);
121 +                }
122 +
123 +                std::string GetDirectory() const
124 +                {
125 +                        HANDLE token;
126 +
127 +                        if (::WTSQueryUserToken(id, &token))
128 +                        {
129 +                                TCHAR directory[MAX_PATH];
130 +
131 +                                ::SHGetFolderPath(NULL, CSIDL_PROFILE, token, SHGFP_TYPE_CURRENT, directory);
132 +                                ::CloseHandle(token);
133 +
134 +                                return Utf8(directory);
135 +                        }
136 +                        else
137 +                        {
138 +                                TCHAR directory_[MAX_PATH];
139 +
140 +                                ::SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, directory_);
141 +
142 +                                std::wstring directory(directory_);
143 +
144 +                                directory.replace(directory.rfind('\\') + 1, std::wstring::npos, login);
145 +
146 +                                return Utf8(directory);
147 +                        }
148 +                }
149          };
150  
151          std::ostringstream stream;
# Line 109 | Line 155 | class Finger
155          {
156                  for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); login = logins.upper_bound(login->first))
157                  {
158 <                        stream << "Login: " << login->first << std::string(33 - login->first.size(), ' ') << "Name: " << login->second.GetName() << "\r\n";
158 >                        if (login != logins.begin())
159 >                                stream << "\r\n";
160 >
161 >                        std::string directory(login->second.GetDirectory());
162 >
163 >                        stream << "Login: " << login->first << std::string(33 - login->first.size(), ' ') << "Name: " << login->second.GetName() << "\r\nDirectory: " << directory << "\r\n";
164 >
165 >                        for (std::multimap<std::string, Login>::const_iterator login_(logins.lower_bound(login->first)); login_ != logins.upper_bound(login->first); ++login_)
166 >                                stream << login_->second.status << ' ' << login_->second.session << ' ' << login_->second.id << "\r\n";
167 >
168 >                        std::string files[] = { "\\.project", "\\.plan" };
169 >
170 >                        for (std::string *file(files); file != files + sizeof (files) / sizeof (*file); ++file)
171 >                        {
172 >                                file->insert(0, directory);
173 >
174 >                                std::ifstream in(file->c_str());
175 >
176 >                                if (!in.is_open())
177 >                                        continue;
178 >
179 >                                switch (file - files)
180 >                                {
181 >                                case 0:
182 >                                        stream << "Project:\r\n";
183 >
184 >                                        break;
185 >                                case 1:
186 >                                        stream << "Plan:\r\n";
187 >                                }
188 >
189 >                                std::string buffer;
190 >
191 >                                while (std::getline(in, buffer))
192 >                                        stream << buffer << std::endl;
193 >                        }
194                  }
195          }
196  
# Line 155 | Line 236 | public:
236                          stream << "Login" << std::string(11, ' ') << "Name" << std::string(17, ' ') << "Id     Session       Status\r\n";
237  
238                          for (std::multimap<std::string, Login>::const_iterator login(logins.begin()); login != logins.end(); ++login)
239 <                                stream << login->first << std::string(16 - login->first.size(), ' ') << login->second.GetName() << std::string(21 - login->second.GetName().size(), ' ') << std::setw(5) << std::left << login->second.id << "  " << login->second.session << std::string(14 - login->second.session.size(), ' ') << login->second.status << "\r\n";
239 >                                stream << login->first << std::string(16 - login->first.size(), ' ') << login->second.GetShortName() << std::string(21 - login->second.GetShortName().size(), ' ') << std::setw(5) << std::left << login->second.id << "  " << login->second.session << std::string(14 - login->second.session.size(), ' ') << login->second.status << "\r\n";
240                  }
241                  else
242                          Full();
243          }
244  
245 <        Finger(const std::string &name)
245 >        Finger(const std::string &name_)
246          {
247 <                //NetQueryDisplayInformation
248 <                //NetUserGetInfo
247 >                std::wstring name(Utf8(name_));
248 >
249 >                std::transform(name.begin(), name.end(), name.begin(), std::towlower);
250 >
251 >                DWORD size;
252 >                PNET_DISPLAY_USER users;
253 >
254 >                ::NetQueryDisplayInformation(NULL, 1, 0, 100, MAX_PREFERRED_LENGTH, &size, reinterpret_cast<PVOID *>(&users));
255 >
256 >                 for (PNET_DISPLAY_USER user = users; user != users + size; ++user)
257 >                 {
258 >                         std::wstring name_(user->usri1_name);
259 >
260 >                         std::transform(name_.begin(), name_.end(), name_.begin(), std::towlower);
261 >
262 >                         if (name_.find(name) != std::wstring::npos)
263 >                                 ;//logins.insert(std::make_pair(Utf8(name_),
264 >                         else
265 >                         {
266 >                                 std::wstring full(user->usri1_full_name);
267 >
268 >                                 std::transform(full.begin(), full.end(), full.begin(), std::towlower);
269 >
270 >                                 if (full.find(name) != std::wstring::npos)
271 >                                         ;//logins.insert(std::make_pair(Utf8(name_),
272 >                         }
273 >                 }
274 >
275 >                 ::NetApiBufferFree(users);
276 >                
277 >                 if (!logins.empty())
278 >                        Full();
279 >                 else
280 >                         stream << "finger: " << name_ << ": no such user\r\n";
281          }
282  
283          inline operator std::string()
# Line 189 | Line 302 | void WINAPI FingerControl(DWORD control)
302  
303   int _tmain(int argc, TCHAR *argv[])
304   {
305 <        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCS Finger Daemon"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
305 >        SERVICE_TABLE_ENTRY entry[] = { { TEXT("CCSFinger"), LPSERVICE_MAIN_FUNCTION(FingerMain) }, { NULL, NULL } };
306  
307          if (!::StartServiceCtrlDispatcher(entry))
308          {
# Line 220 | Line 333 | int _tmain(int argc, TCHAR *argv[])
333          return 0;
334  
335   go:
336 +        for (int index(1); index != argc; ++index)
337 +        {
338 +                std::wstring arg(argv[index]);
339 +
340 +                if (arg == TEXT("create"))
341 +                {
342 +                        TCHAR file[MAX_PATH];
343 +
344 +                        ::GetModuleFileName(NULL, file, MAX_PATH);
345 +
346 +                        SC_HANDLE manager(::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE)), service(::CreateService(manager, TEXT("CCSFinger"), TEXT("CCS Finger Daemon"), 0, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, file, NULL, NULL, TEXT("TermService\0"), NULL, TEXT("")));
347 +
348 +                        if (!service)
349 +                                std::cerr << ::GetLastError() << std::endl;
350 +                        else
351 +                                ::CloseServiceHandle(service);
352 +
353 +                        ::CloseServiceHandle(manager);
354 +
355 +                        return 0;
356 +                }
357 +                else if (arg == TEXT("delete"))
358 +                {
359 +                        SC_HANDLE manager(::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, DELETE)), service(::OpenService(manager, TEXT("CCSFinger"), DELETE));
360 +
361 +                        if (!::DeleteService(service))
362 +                                std::cerr << ::GetLastError() << std::endl;
363 +
364 +                        ::CloseServiceHandle(service);
365 +                        ::CloseServiceHandle(manager);
366 +
367 +                        return 0;
368 +                }
369 +        }
370 +
371          stop = ::CreateEvent(NULL, TRUE, FALSE, NULL);
372  
373          ::signal(SIGINT, FingerStop);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines