Windows: remove trailing whitespace
[openafs.git] / src / WINNT / afsclass / internal.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
12
13 extern "C" {
14 #include <afsconfig.h>
15 #include <afs/param.h>
16 #include <afs/stds.h>
17 #include <roken.h>
18 }
19
20 #include <WINNT/afsclass.h>
21 #include "internal.h"
22
23 #define LOCAL_CRITSEC_COUNT
24
25
26 /*
27  * VARIABLES __________________________________________________________________
28  *
29  */
30
31 #ifdef LOCAL_CRITSEC_COUNT
32 size_t cs_EnterCount = 0;
33 DWORD cs_ThreadID = 0;
34 #endif
35
36 size_t cRefreshAllReq = 0;
37
38 CRITICAL_SECTION *pcs = NULL;
39 BOOL fLongServerNames = FALSE;
40
41 DWORD dwWant = 0;
42
43 static LPTSTR apszDays[] = {
44    TEXT("sun"), TEXT("mon"), TEXT("tue"),
45    TEXT("wed"), TEXT("thu"), TEXT("fri"), TEXT("sat")
46 };
47
48
49 /*
50  * PROTOTYPES _________________________________________________________________
51  *
52  */
53
54
55 /*
56  * ROUTINES ___________________________________________________________________
57  *
58  */
59
60 void AfsClass_InitCriticalSection (void)
61 {
62    if (pcs == NULL)
63       {
64       pcs = New (CRITICAL_SECTION);
65       InitializeCriticalSection (pcs);
66
67 #ifdef LOCAL_CRITSEC_COUNT
68       cs_EnterCount = 0;
69       cs_ThreadID = 0;
70 #endif
71       }
72 }
73
74 LPCRITICAL_SECTION AfsClass_GetCriticalSection (void)
75 {
76    AfsClass_InitCriticalSection();
77    return pcs;
78 }
79
80 void AfsClass_Enter (void)
81 {
82    AfsClass_InitCriticalSection();
83    EnterCriticalSection (pcs);
84
85 #ifdef LOCAL_CRITSEC_COUNT
86    cs_EnterCount++;
87    cs_ThreadID = GetCurrentThreadId();
88 #endif
89 }
90
91 void AfsClass_Leave (void)
92 {
93 #ifdef LOCAL_CRITSEC_COUNT
94    if (!ASSERT( cs_EnterCount > 0 ))
95       return;
96    if (!ASSERT( cs_ThreadID == GetCurrentThreadId() ))
97       return;
98    cs_EnterCount--;
99 #else
100    if (!ASSERT( pcs->RecursionCount > 0 ))
101       return;
102    if (!ASSERT( pcs->OwningThread == (PVOID)GetCurrentThreadId() ))
103       return;
104 #endif
105    LeaveCriticalSection (pcs);
106 }
107
108 int AfsClass_GetEnterCount (void)
109 {
110 #ifdef LOCAL_CRITSEC_COUNT
111    return (int)cs_EnterCount;
112 #else
113    return pcs->RecursionCount;
114 #endif
115 }
116
117 void AfsClass_UnixTimeToSystemTime (LPSYSTEMTIME pst, ULONG ut, BOOL fElapsed)
118 {
119    if (!ut)
120       {
121       memset (pst, 0x00, sizeof(SYSTEMTIME));
122       return;
123       }
124
125    // A Unix time is the number of seconds since 1/1/1970.
126    // The first step in this conversion is to change that count-of-seconds
127    // into a count-of-100ns-intervals...
128    //
129    LARGE_INTEGER ldw;
130    ldw.QuadPart = (LONGLONG)10000000 * (LONGLONG)ut;
131
132    // Then adjust the count to be a count-of-100ns-intervals since
133    // 1/1/1601, instead of 1/1/1970. That means adding a *big* number...
134    //
135    ldw.QuadPart += (LONGLONG)0x019DB1DED53E8000;
136
137    // Now the count is effectively a FILETIME, which we can convert
138    // to a SYSTEMTIME with a Win32 API.
139    //
140    FILETIME ft;
141    ft.dwHighDateTime = (DWORD)ldw.HighPart;
142    ft.dwLowDateTime = (DWORD)ldw.LowPart;
143    FileTimeToSystemTime (&ft, pst);
144
145    if (fElapsed)
146       {
147       pst->wYear -= 1970;
148       pst->wMonth -= 1;
149       pst->wDayOfWeek -= 1;
150       pst->wDay -= 1;
151       }
152 }
153
154
155 ULONG AfsClass_SystemTimeToUnixTime (LPSYSTEMTIME pst)
156 {
157    SYSTEMTIME st;
158    if (pst == NULL)
159       GetSystemTime (&st);
160    else
161       st = *pst;
162
163    if (st.wYear == 1970)
164       return 0;
165
166    FILETIME ft;
167    if (!SystemTimeToFileTime (&st, &ft))
168       return 0;
169
170    LARGE_INTEGER now;
171    now.HighPart = (LONG)ft.dwHighDateTime;
172    now.LowPart = (ULONG)ft.dwLowDateTime;
173
174    LARGE_INTEGER offset;
175    offset.HighPart = 0x019db1de;
176    offset.LowPart = 0xd53e8000;
177
178    LARGE_INTEGER result;
179    result.QuadPart = (now.QuadPart - offset.QuadPart) / 10000000;
180    return (ULONG)result.LowPart;
181 }
182
183
184 void AfsClass_ElapsedTimeToSeconds (ULONG *pcSeconds, LPSYSTEMTIME pet)
185 {
186    *pcSeconds = 0;
187    if (pet)
188       {
189       *pcSeconds += pet->wSecond;
190       *pcSeconds += pet->wMinute * 60L;
191       *pcSeconds += pet->wHour   * 60L * 60L;
192       *pcSeconds += pet->wDay    * 60L * 60L * 24L;
193       }
194 }
195
196
197 double AfsClass_FileTimeToDouble (FILETIME *pft)
198 {
199    double rc;
200    rc = (double)pft->dwHighDateTime * (double)0x100000000;
201    rc += (double)pft->dwLowDateTime;
202    return rc;
203 }
204
205
206 void AfsClass_RequestLongServerNames (BOOL fLong)
207 {
208    fLongServerNames = fLong;
209 }
210
211
212 void AfsClass_ParseRecurringTime (BOOL *pfEver, LPSYSTEMTIME pst, LPTSTR pszTime)
213 {
214    *pfEver = FALSE;
215    memset (pst, 0x00, sizeof(SYSTEMTIME));
216
217    if (lstrcmpi (pszTime, TEXT("never")))
218       {
219       *pfEver = TRUE;
220
221       if (!lstrncmpi (pszTime, TEXT("at"), lstrlen(TEXT("at"))))
222          pszTime += lstrlen(TEXT("at"));
223       while ((*pszTime == ' ') || (*pszTime == '\t'))
224          ++pszTime;
225
226       // first, does it start with a day-of-week?
227       //
228       pst->wDayOfWeek = (WORD)(-1); // daily until proven otherwise
229
230       for (WORD ii = 0; ii < 7; ++ii)
231          {
232          if (!lstrncmpi (apszDays[ii], pszTime, 3))
233             {
234             pst->wDayOfWeek = ii;
235             break;
236             }
237          }
238
239       // next, find the hour
240       //
241       while (*pszTime && !isdigit(*pszTime))
242          ++pszTime;
243
244       TCHAR szComponent[ cchRESOURCE ];
245       lstrcpy (szComponent, pszTime);
246       LPTSTR pch;
247       for (pch = szComponent; isdigit(*pch); ++pch)
248          ;
249       *pch = TEXT('\0');
250
251       pst->wHour = atoi(szComponent);
252
253       // next, find the minutes
254       //
255       while (isdigit(*pszTime))
256          ++pszTime;
257       while (*pszTime && !isdigit(*pszTime))
258          ++pszTime;
259
260       lstrcpy (szComponent, pszTime);
261       for (pch = szComponent; isdigit(*pch); ++pch)
262          ;
263       *pch = TEXT('\0');
264
265       pst->wMinute = atoi(szComponent);
266
267       // next, check for a 'am' or 'pm' marker
268       //
269       for ( ; *pszTime; ++pszTime)
270          {
271          if (tolower(*pszTime) == TEXT('p'))
272             {
273             if (pst->wHour < 12)
274                pst->wHour += 12;
275             break;
276             }
277          if (tolower(*pszTime) == TEXT('a'))
278             {
279             if (pst->wHour >= 12)
280                pst->wHour -= 12;
281             break;
282             }
283          }
284       }
285 }
286
287
288 void AfsClass_FormatRecurringTime (LPTSTR pszTarget, SYSTEMTIME *pst)
289 {
290    if (pst == NULL)
291       {
292       wsprintf (pszTarget, TEXT("never"));
293       }
294    else
295       {
296       WORD wHour = ((pst->wHour % 12) == 0) ? 12 : (pst->wHour % 12);
297       TCHAR szAMPM[3];
298       lstrcpy (szAMPM, (pst->wHour >= 12) ? TEXT("pm") : TEXT("am"));
299
300       if (pst->wDayOfWeek == (WORD)(-1))  // daily at specified time?
301          {
302          wsprintf (pszTarget, TEXT("%u:%02u %s"), wHour, pst->wMinute, szAMPM);
303          }
304       else // weekly on specified date at specified time?
305          {
306          wsprintf (pszTarget, TEXT("%s %u:%02u %s"), apszDays[ pst->wDayOfWeek ], wHour, pst->wMinute, szAMPM);
307          }
308       }
309 }
310
311
312 void AfsClass_SplitFilename (LPSTR pszDirectoryA, LPSTR pszFilenameA, LPTSTR pszFullName)
313 {
314    CopyStringToAnsi (pszDirectoryA, pszFullName);
315
316    LPSTR pszLastSlashA = NULL;
317    for (LPSTR pszA = pszDirectoryA; *pszA; ++pszA)
318       {
319       if ((*pszA == '/') || (*pszA == '\\'))
320          pszLastSlashA = pszA;
321       }
322
323    if (!pszLastSlashA)
324       {
325       strcpy (pszFilenameA, pszDirectoryA);
326       *pszDirectoryA = 0;
327       }
328    else
329       {
330       strcpy (pszFilenameA, 1+pszLastSlashA);
331       *pszLastSlashA = 0;
332       }
333 }
334
335
336 void AfsClass_SystemTimeToRestartTime (bos_RestartTime_p prt, BOOL fEnable, LPSYSTEMTIME pst)
337 {
338    memset (prt, 0x00, sizeof(bos_RestartTime_t));
339    if (!fEnable)
340       prt->mask = BOS_RESTART_TIME_NEVER;
341    else
342       {
343       prt->mask = (bos_RestartTimeFields_t)(BOS_RESTART_TIME_HOUR | BOS_RESTART_TIME_MINUTE);
344       prt->hour = pst->wHour;
345       prt->min = pst->wMinute;
346
347       if (pst->wDayOfWeek != (WORD)-1)
348          {
349          prt->mask = (bos_RestartTimeFields_t)(prt->mask | BOS_RESTART_TIME_DAY);
350          prt->day = pst->wDayOfWeek;
351          }
352       }
353 }
354
355
356 void AfsClass_RestartTimeToSystemTime (BOOL *pfEnable, LPSYSTEMTIME pst, bos_RestartTime_p prt)
357 {
358    memset (pst, 0x00, sizeof(SYSTEMTIME));
359
360    if ((!prt->mask) || (prt->mask & BOS_RESTART_TIME_NEVER))
361       {
362       *pfEnable = FALSE;
363       }
364    else
365       {
366       *pfEnable = TRUE;
367       pst->wHour = (prt->mask & BOS_RESTART_TIME_HOUR) ? prt->hour : 0;
368       pst->wMinute = (prt->mask & BOS_RESTART_TIME_MINUTE) ? prt->min : 0;
369       pst->wDayOfWeek = (prt->mask & BOS_RESTART_TIME_DAY) ? prt->day : (WORD)-1;
370       }
371 }
372
373
374 void AfsClass_IntToAddress (LPSOCKADDR_IN pAddr, int IntAddr)
375 {
376    memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
377    pAddr->sin_family = AF_INET;
378    pAddr->sin_addr.s_addr = htonl(IntAddr);
379 }
380
381
382 void AfsClass_AddressToInt (int *pIntAddr, LPSOCKADDR_IN pAddr)
383 {
384    *pIntAddr = ntohl(pAddr->sin_addr.s_addr);
385 }
386
387
388 void AfsClass_SpecifyRefreshDomain (DWORD dwWantUser)
389 {
390    dwWant = dwWantUser;
391 }
392
393
394 BOOL AfsClass_Initialize (ULONG *pStatus)
395 {
396    if (!Worker_Initialize (pStatus))
397       return FALSE;
398
399    return TRUE;
400 }
401
402
403 void AfsClass_GenFullUserName (LPTSTR pszTarget, LPCTSTR pszPrincipal, LPCTSTR pszInstance)
404 {
405    lstrcpy (pszTarget, pszPrincipal);
406    if (pszInstance && *pszInstance)
407       wsprintf (&pszTarget[ lstrlen(pszTarget) ], TEXT(".%s"), pszInstance);
408 }
409