// Serves a page by interpreting command codes, processing script commands, // and handling variable substitution. Any variables provided in the override_list // will take precedence over variables of the same name defined in the page. int ServePageWithOverride(char *page, int page_size, PageVar *override_list) { // Initialize varlist PageVar *varlist = calloc(sizeof(PageVar), 1); VerifyPointerOrTerminate(varlist, "VarList initialization"); in_a_box = 0; cgc_memset(line, '\0', sizeof(line)); line_length = 0; #ifdef PATCHED if (page == NULL) { goto error; } #endif while ((*page != '\0')&&(page < page + page_size)) { if (*page == '~') { // Command character, process command page++; switch (*page) { case 't': { for (int i=0; i<4; i++) { OutputChar(' '); } break; } case 'n': { FlushOutput(); break; } case '[': { OutputChar('['); break; } case ']': { OutputChar(']'); break; } case '~': { OutputChar('~'); break; } case '#': { OutputChar('#'); break; } default: { printf("ERROR: Invalid control code\n"); goto error; } } page++; } else if (*page == '[') { // Script tag, find closing tag and process script char *close = ++page; while (*close != ']' && *close != '\0') close++; if (*close == '\0') { goto error; } // Process script commands if (strncmp(page, "line", cgc_strlen("line")) == 0) { page += cgc_strlen("line"); if (*page != ':') { goto error; } char c = *(++page); if (*(++page) != ':') { goto error; } int length = atoi(++page); for (int i = 0; i < length; i++) { OutputChar(c); } page = close + 1; } else if (strncmp(page, "var", cgc_strlen("var")) == 0) { AddPageVar(varlist, page); page = close + 1; } else if (strncmp(page, "box", cgc_strlen("box")) == 0) { in_a_box = 1; FlushOutput(); for (int i = 0; i < 80; i++) { putc('*'); } printf("\n"); page += 4; } } else if (*page == ']') { page++; if (in_a_box) { in_a_box = 0; FlushOutput(); for (int i = 0; i < 80; i++) { putc('*'); } printf("\n"); } else { goto error; } } else if (*page == '#') { // Variable substitution char *end = ++page; while (*end != '\0' && *end != '#') { end++; } if (*end != '#') { goto error; } PageVar *var = NULL; // Check for overridden variables if (override_list != NULL) { var = GetPageVar(override_list, page, end); } // Fall back to default values if override doesn't exist if (var == NULL) { var = GetPageVar(varlist, page, end); } // If a value has been found, output it if (var != NULL) { OutputStr(var->value); } page = end + 1; } else { // Normal character, send to output OutputChar(*page); page++; } } if (line_length != 0) { FlushOutput(); } DestroyVarList(varlist); DestroyVarList(override_list); return 0; error: printf("ERROR: Invalid syntax\n"); DestroyVarList(varlist); DestroyVarList(override_list); return -1; }
int LoadPrimeNet (void) { static int RAS_NOT_AVAILABLE = 0; static HMODULE HRAS = 0; static DWORD (APIENTRY *RAS_ENUM)(LPRASCONNA, LPDWORD, LPDWORD); static DWORD (APIENTRY *RAS_STAT)(HRASCONN, LPRASCONNSTATUSA); RASCONN connections[10]; DWORD bufsize; DWORD i, num_connections; DWORD ret; /* Special handling prior to first primenet call. */ /* Init Winsock, requesting version 1.1 */ if (! SOCKETS_INITIALIZED) { static WSADATA zz; int res; res = WSAStartup (MAKEWORD (1, 1), &zz); if (res != 0) { char buf[80]; sprintf (buf, "ERROR: Winsock initialization returned %d.\n", res); OutputStr (COMM_THREAD_NUM, buf); return (FALSE); } SOCKETS_INITIALIZED = 1; } /* If we're not using a dial-up connection, let primenet try */ /* to contact the server. */ if (!DIAL_UP) return (TRUE); /* Since Windows 95 can bring up a "Connect To" dialog box */ /* on any call to primenet, we try to make sure we are */ /* already connected before we call primenet. Otherwise, if */ /* no one is at the computer to respond to the "Connect To" */ /* dialog, the thread hangs until some one does respond. */ /* RAS calls, see below, is no longer the MS-prefered method of detecting */ /* an Internet connection. Starting in version 22.10 we offer a way for */ /* for users to use the prefered wininet.dll method. */ /* InternetGetConnectedState should return FALSE if the modem is not */ /* connected to the Internet. */ /* Starting in version 25.1, this became the default detection method. */ if (IniGetInt (INI_FILE, "AlternateModemDetection", 1)) { DWORD flags; if (InternetGetConnectedState (&flags, 0)) return (TRUE); goto no_modem_connection; } // Unfortunately, the RASAPI32.DLL is not installed on every // system. We must load it dynamically. If the RAS library // is not found, let primenet.dll try to contact the server. if (RAS_NOT_AVAILABLE) return (TRUE); if (HRAS == 0) { RAS_NOT_AVAILABLE = 1; HRAS = LoadLibrary ("rasapi32.dll"); if (HRAS == 0) return (TRUE); RAS_ENUM = (DWORD (APIENTRY *)(LPRASCONNA, LPDWORD, LPDWORD)) GetProcAddress (HRAS, "RasEnumConnectionsA"); if (RAS_ENUM == NULL) return (TRUE); RAS_STAT = (DWORD (APIENTRY *)(HRASCONN, LPRASCONNSTATUSA)) GetProcAddress (HRAS, "RasGetConnectStatusA"); if (RAS_STAT == NULL) return (TRUE); RAS_NOT_AVAILABLE = 0; } // Call RAS to see if there are any active connections to the Internet connections[0].dwSize = sizeof (RASCONN); bufsize = sizeof (connections); ret = (*RAS_ENUM) ((RASCONN *) &connections, &bufsize, &num_connections); // If RAS returns an error who knows what went wrong. // Let primenet try to connect anyway. if (ret) return (TRUE); // See if any of these connections are really connected for (i = 0; i < num_connections; i++) { RASCONNSTATUS status; status.dwSize = sizeof (RASCONNSTATUS); ret = (*RAS_STAT) (connections[i].hrasconn, &status); if (ret) continue; if (status.rasconnstate == RASCS_Connected) return (TRUE); } // Print error message if no there are no connections no_modem_connection: OutputStr (COMM_THREAD_NUM, "Dial-up connection not active.\n"); return (FALSE); }
void Service95 () { char pathname[256]; char regkey[20]; /* Win9x registry name */ SC_HANDLE schSCManager = 0; SC_HANDLE schService = 0; HKEY hkey = 0; DWORD rc, disposition; /* In Windows 95/98/Me, call RegisterServiceProcess in the Kernel */ /* This will prevent prime95 from terminating on logoff. */ if (isWindows95 ()) { HMODULE hlib; DWORD (__stdcall *proc)(DWORD, DWORD); hlib = LoadLibrary ("KERNEL32.DLL"); if (!hlib) { OutputStr (MAIN_THREAD_NUM, "Unable to load KERNEL32.DLL\n"); goto done; } proc = (DWORD (__stdcall *)(DWORD, DWORD)) GetProcAddress (hlib, "RegisterServiceProcess"); if (proc == NULL) OutputStr (MAIN_THREAD_NUM, "Unable to find RegisterServiceProcess\n"); else { if (WINDOWS95_SERVICE) rc = (*proc) (NULL, RSP_SIMPLE_SERVICE); else rc = (*proc) (NULL, RSP_UNREGISTER_SERVICE); if (!rc) OutputStr (MAIN_THREAD_NUM, "RegisterServiceProcess failed\n"); } FreeLibrary (hlib); } /* Now we deal with making the registry entries correct for proper starting */ /* or not starting of the service. */ /* Get pathname of executable */ GetModuleFileName (NULL, pathname, sizeof (pathname)); /* In Win95/98/Me, we create a registry entry for each -A command line value */ /* We used to do this in WinNT/2000/XP, but now we just delete these old */ /* registry entries. */ if (WINDOWS95_A_SWITCH < 0) strcpy (regkey, "Prime95"); else sprintf (regkey, "Prime95-%d", WINDOWS95_A_SWITCH); // For Windows 95/98/Me create a RunServices entry if (isWindows95 ()) { if (RegCreateKeyEx ( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disposition) != ERROR_SUCCESS) { OutputStr (MAIN_THREAD_NUM, "Can't create registry key.\n"); goto done; } /* Now create or delete an entry for prime95 */ if (WINDOWS95_SERVICE) { if (WINDOWS95_A_SWITCH >= 0) { char append[20]; sprintf (append, " -A%d", WINDOWS95_A_SWITCH); strcat (pathname, append); } rc = RegSetValueEx (hkey, regkey, 0, REG_SZ, (BYTE *) pathname, (DWORD) strlen (pathname) + 1); if (rc != ERROR_SUCCESS) { OutputStr (MAIN_THREAD_NUM, "Can't write registry value.\n"); goto done; } } else { rc = RegDeleteValue (hkey, regkey); if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND){ OutputStr (MAIN_THREAD_NUM, "Can't delete registry entry.\n"); goto done; } } RegCloseKey (hkey); hkey = 0; } // For Windows NT/2000/XP we call the service control manager to maintain the // services database. If we don't have administrator privileges (can't open // the service control manager) then simply create a registry entry to start // the program at logon. So, attempt to open the service control manager on // NULL = local machine, NULL = default database, all access required. // Also Vista won't let services interact with the desktop, so we can't run // as a service. else if (isWindowsVista () || ! (schSCManager = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS))) { if (RegCreateKeyEx ( HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disposition) != ERROR_SUCCESS) { OutputStr (MAIN_THREAD_NUM, "Can't create registry key.\n"); goto done; } /* Now create or delete an entry for prime95 */ if (WINDOWS95_SERVICE) { if (WINDOWS95_A_SWITCH >= 0) { char append[20]; sprintf (append, " -A%d", WINDOWS95_A_SWITCH); strcat (pathname, append); } rc = RegSetValueEx (hkey, regkey, 0, REG_SZ, (BYTE *) pathname, (DWORD) strlen (pathname) + 1); if (rc != ERROR_SUCCESS) { OutputStr (MAIN_THREAD_NUM, "Can't write registry value.\n"); goto done; } } else { rc = RegDeleteValue (hkey, regkey); if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND){ OutputStr (MAIN_THREAD_NUM, "Can't delete registry entry.\n"); goto done; } } RegCloseKey (hkey); hkey = 0; } // Make the necessary NT/2000/XP service control changes else { char servicename[80]; char displayname[80]; // Create the Windows NT service name and display name IniGetString (LOCALINI_FILE, "ServiceName", servicename, sizeof (servicename), NULL); if (servicename[0] == 0) { if (WINDOWS95_A_SWITCH < 0) strcpy (servicename, "Prime95 Service"); else sprintf (servicename, "Prime95 Service-%d", WINDOWS95_A_SWITCH); } IniGetString (LOCALINI_FILE, "DisplayName", displayname, sizeof (displayname), servicename); // Create the service entry if (WINDOWS95_SERVICE) { schService = CreateService ( schSCManager, // SCManager database servicename, // name of service displayname, // display name SERVICE_ALL_ACCESS, // desired access SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type pathname, // service's binary NULL, // no load ordering NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL); // no password if (!schService) { if (GetLastError () != ERROR_SERVICE_EXISTS) OutputStr (MAIN_THREAD_NUM, "Error creating service.\n"); goto done; } // Set description for Win2K and later if (isWindows2000 ()) { SERVICE_DESCRIPTION svc_desc; svc_desc.lpDescription = "GIMPS client to find large prime numbers"; ChangeServiceConfig2 ( schService, SERVICE_CONFIG_DESCRIPTION, &svc_desc); } } // Remove the service entry else { schService = OpenService ( schSCManager, servicename, SERVICE_ALL_ACCESS); if (!schService) { if (GetLastError () != ERROR_SERVICE_DOES_NOT_EXIST) OutputStr (MAIN_THREAD_NUM, "Error opening service.\n"); goto done; } if (! DeleteService (schService)) { OutputStr (MAIN_THREAD_NUM, "Error deleting service.\n"); goto done; } } /* Delete the old-style (version 21) Run entry for the current user */ if (RegCreateKeyEx ( HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disposition) == ERROR_SUCCESS) { RegDeleteValue (hkey, regkey); RegCloseKey (hkey); hkey = 0; } } /* For Windows NT/2000/XP delete the old-style (version 21) Run entry for */ /* the local machine */ if (! isWindows95 ()) { if (RegCreateKeyEx ( HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disposition) == ERROR_SUCCESS) { RegDeleteValue (hkey, regkey); RegCloseKey (hkey); hkey = 0; } } /* Now delete any shortcuts to the program. We do this so that as users */ /* upgrade from version 20 and try this menu choice they do not end up with */ /* both a registry entry and a StartUp menu shortcut. */ if (WINDOWS95_SERVICE) { char buf[256]; DWORD type; DWORD bufsize = sizeof (buf); if (RegCreateKeyEx ( HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &disposition) != ERROR_SUCCESS) goto done; if (RegQueryValueEx (hkey, "Startup", NULL, &type, (BYTE *) buf, &bufsize) == ERROR_SUCCESS && type == REG_SZ) { strcat (buf, "\\prime95.lnk"); _unlink (buf); } } // Cleanup and return done: if (schService) CloseServiceHandle (schService); if (schSCManager) CloseServiceHandle (schSCManager); if (hkey) RegCloseKey (hkey); }