Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 CrossFire, A Multiplayer game for X-windows 00003 00004 Copyright (C) 1992 Frank Tore Johansen 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 00020 The author can be reached via e-mail to frankj@ifi.uio.no. 00021 */ 00022 00030 #include <global.h> 00031 00032 #include <stdarg.h> 00033 #include <malloc.h> 00034 #include <string.h> 00035 #include <errno.h> 00036 #include <mmsystem.h> 00037 00039 struct timezone { 00040 int tz_minuteswest; 00041 int tz_dsttime; 00042 }; 00043 00054 int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info) { 00055 /* Get the time, if they want it */ 00056 if (time_Info != NULL) { 00057 time_Info->tv_sec = time(NULL); 00058 time_Info->tv_usec = timeGetTime()*1000; 00059 } 00060 /* Get the timezone, if they want it */ 00061 if (timezone_Info != NULL) { 00062 _tzset(); 00063 timezone_Info->tz_minuteswest = _timezone; 00064 timezone_Info->tz_dsttime = _daylight; 00065 } 00066 /* And return */ 00067 return 0; 00068 } 00069 00078 DIR *opendir(const char *dir) { 00079 DIR *dp; 00080 char *filespec; 00081 long handle; 00082 int index; 00083 00084 filespec = malloc(strlen(dir)+2+1); 00085 strcpy(filespec, dir); 00086 index = strlen(filespec)-1; 00087 if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\')) 00088 filespec[index] = '\0'; 00089 strcat(filespec, "/*"); 00090 00091 dp = (DIR *)malloc(sizeof(DIR)); 00092 dp->offset = 0; 00093 dp->finished = 0; 00094 dp->dir = strdup(dir); 00095 00096 if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0) { 00097 free(filespec); 00098 free(dp); 00099 return NULL; 00100 } 00101 dp->handle = handle; 00102 free(filespec); 00103 00104 return dp; 00105 } 00106 00116 struct dirent *readdir(DIR *dp) { 00117 if (!dp || dp->finished) 00118 return NULL; 00119 00120 if (dp->offset != 0) { 00121 if (_findnext(dp->handle, &(dp->fileinfo)) < 0) { 00122 dp->finished = 1; 00123 if (ENOENT == errno) 00124 /* Clear error set to mean no more files else that breaks things */ 00125 errno = 0; 00126 return NULL; 00127 } 00128 } 00129 dp->offset++; 00130 00131 strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME); 00132 dp->dent.d_name[_MAX_FNAME] = '\0'; 00133 dp->dent.d_ino = 1; 00134 /* reclen is used as meaning the length of the whole record */ 00135 dp->dent.d_reclen = strlen(dp->dent.d_name)+sizeof(char)+sizeof(dp->dent.d_ino)+sizeof(dp->dent.d_reclen)+sizeof(dp->dent.d_off); 00136 dp->dent.d_off = dp->offset; 00137 00138 return &(dp->dent); 00139 } 00140 00149 int closedir(DIR *dp) { 00150 if (!dp) 00151 return 0; 00152 _findclose(dp->handle); 00153 if (dp->dir) 00154 free(dp->dir); 00155 if (dp) 00156 free(dp); 00157 00158 return 0; 00159 } 00160 00167 void rewinddir(DIR *dir_Info) { 00168 /* Re-set to the beginning */ 00169 char *filespec; 00170 long handle; 00171 int index; 00172 00173 dir_Info->handle = 0; 00174 dir_Info->offset = 0; 00175 dir_Info->finished = 0; 00176 00177 filespec = malloc(strlen(dir_Info->dir)+2+1); 00178 strcpy(filespec, dir_Info->dir); 00179 index = strlen(filespec)-1; 00180 if (index >= 0 && (filespec[index] == '/' || filespec[index] == '\\')) 00181 filespec[index] = '\0'; 00182 strcat(filespec, "/*"); 00183 00184 if ((handle = _findfirst(filespec, &(dir_Info->fileinfo))) < 0) { 00185 if (errno == ENOENT) { 00186 dir_Info->finished = 1; 00187 } 00188 } 00189 dir_Info->handle = handle; 00190 free(filespec); 00191 } 00192 00193 /* Service-related stuff 00194 00195 Those functions are called while init is still being done, so no logging available. 00196 00197 Not useful for plugins, though. 00198 00199 */ 00200 00202 int bRunning; 00203 00204 #ifndef PYTHON_PLUGIN_EXPORTS 00205 00206 SERVICE_STATUS m_ServiceStatus; 00207 SERVICE_STATUS_HANDLE m_ServiceStatusHandle; 00209 #define SERVICE_NAME "Crossfire" 00210 00211 #define SERVICE_DISPLAY "Crossfire server" 00212 00213 #define SERVICE_DESCRIPTION "Crossfire is a multiplayer online RPG game." 00214 00215 #include <winsvc.h> 00216 00221 void service_register() { 00222 char strDir[1024]; 00223 HANDLE schSCManager, schService; 00224 char *strDescription = SERVICE_DESCRIPTION; 00225 00226 GetModuleFileName(NULL, strDir, 1024); 00227 strcat(strDir, " -srv"); 00228 00229 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00230 00231 if (schSCManager == NULL) { 00232 printf("openscmanager failed"); 00233 exit(1); 00234 } 00235 00236 schService = CreateService(schSCManager, 00237 SERVICE_NAME, 00238 SERVICE_DISPLAY, /* service name to display */ 00239 SERVICE_ALL_ACCESS, /* desired access */ 00240 SERVICE_WIN32_OWN_PROCESS, /* service type */ 00241 SERVICE_DEMAND_START, /* start type */ 00242 SERVICE_ERROR_NORMAL, /* error control type */ 00243 strDir, /* service's binary */ 00244 NULL, /* no load ordering group */ 00245 NULL, /* no tag identifier */ 00246 NULL, /* no dependencies */ 00247 NULL, /* LocalSystem account */ 00248 NULL); /* no password */ 00249 00250 if (schService == NULL) { 00251 printf("createservice failed"); 00252 exit(1); 00253 } 00254 00255 ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &strDescription); 00256 00257 CloseServiceHandle(schService); 00258 CloseServiceHandle(schSCManager); 00259 exit(0); 00260 } 00261 00266 void service_unregister() { 00267 HANDLE schSCManager; 00268 SC_HANDLE hService; 00269 00270 schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); 00271 00272 if (schSCManager == NULL) { 00273 printf("open failed"); 00274 exit(1); 00275 } 00276 00277 hService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS); 00278 00279 if (hService == NULL) { 00280 printf("openservice failed"); 00281 exit(1); 00282 } 00283 00284 if (DeleteService(hService) == 0) { 00285 printf("Delete failed"); 00286 exit(1); 00287 } 00288 00289 if (CloseServiceHandle(hService) == 0) { 00290 printf("close failed"); 00291 exit(1); 00292 } 00293 00294 if (!CloseServiceHandle(schSCManager)) { 00295 printf("close schSCManager failed"); 00296 exit(1); 00297 } 00298 00299 exit(0); 00300 } 00301 00308 void WINAPI ServiceCtrlHandler(DWORD Opcode) { 00309 switch (Opcode) { 00310 case SERVICE_CONTROL_PAUSE: 00311 m_ServiceStatus.dwCurrentState = SERVICE_PAUSED; 00312 break; 00313 00314 case SERVICE_CONTROL_CONTINUE: 00315 m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; 00316 break; 00317 00318 case SERVICE_CONTROL_STOP: 00319 m_ServiceStatus.dwWin32ExitCode = 0; 00320 m_ServiceStatus.dwCurrentState = SERVICE_STOPPED; 00321 m_ServiceStatus.dwCheckPoint = 0; 00322 m_ServiceStatus.dwWaitHint = 0; 00323 00324 SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); 00325 00326 bRunning = 0; 00327 00328 LOG(llevInfo, "Service stopped.\n"); 00329 00330 break; 00331 00332 case SERVICE_CONTROL_INTERROGATE: 00333 break; 00334 } 00335 return; 00336 } 00337 00338 extern int main(int argc, char **argv); 00339 00347 void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) { 00348 char strDir[1024]; 00349 char *strSlash; 00350 00351 GetModuleFileName(NULL, strDir, 1024); 00352 strSlash = strrchr(strDir, '\\'); 00353 if (strSlash) 00354 *strSlash = '\0'; 00355 chdir(strDir); 00356 00357 m_ServiceStatus.dwServiceType = SERVICE_WIN32; 00358 m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 00359 m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; 00360 m_ServiceStatus.dwWin32ExitCode = 0; 00361 m_ServiceStatus.dwServiceSpecificExitCode = 0; 00362 m_ServiceStatus.dwCheckPoint = 0; 00363 m_ServiceStatus.dwWaitHint = 0; 00364 00365 m_ServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler); 00366 if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) { 00367 return; 00368 } 00369 00370 m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; 00371 m_ServiceStatus.dwCheckPoint = 0; 00372 m_ServiceStatus.dwWaitHint = 0; 00373 SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus); 00374 00375 bRunning = 1; 00376 main(0, NULL); 00377 00378 return; 00379 } 00380 00384 void service_handle() { 00385 SERVICE_TABLE_ENTRY DispatchTable[] = { 00386 { SERVICE_NAME, ServiceMain }, 00387 { NULL, NULL } 00388 }; 00389 StartServiceCtrlDispatcher(DispatchTable); 00390 exit(0); 00391 } 00392 #endif /* PYTHON_PLUGIN_EXPORTS */