X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=menus.c;h=4934a3c1ebf055e794100f5a8b547a4e53ca5b12;hb=2987ec348b8b2cbf38ba9a6a0793652a6b238ae8;hp=b79c90aa62fe273237df3643269c07750dbdbb2a;hpb=73c2c933cf026d88f54f4bfc3c40bab9bc753aa2;p=xboard.git diff --git a/menus.c b/menus.c index b79c90a..4934a3c 100644 --- a/menus.c +++ b/menus.c @@ -1160,6 +1160,92 @@ ModeToWidgetName (GameMode mode) } } +static void +InstallNewEngine (char *command, char *dir, char *variants, char *protocol) +{ // install the given engine in XBoard's -firstChessProgramNames + char buf[MSG_SIZ], *quote = ""; + if(strchr(command, ' ')) { // quoting needed + if(!strchr(command, '"')) quote = "\""; else + if(!strchr(command, '\'')) quote = "'"; else { + printf("Could not auto-install %s\n", command); // too complex + } + } + // construct engine line, with optional -fd and -fUCI arguments + snprintf(buf, MSG_SIZ, "%s%s%s", quote, command, quote); + if(strcmp(dir, "") && strcmp(dir, ".")) + snprintf(buf + strlen(buf), MSG_SIZ - strlen(buf), " -fd %s", dir); + if(!strcmp(protocol, "uci")) + snprintf(buf + strlen(buf), MSG_SIZ - strlen(buf), " -fUCI"); + // append line + quote = malloc(strlen(firstChessProgramNames) + strlen(buf) + 2); + sprintf(quote, "%s%s\n", firstChessProgramNames, buf); + FREE(firstChessProgramNames); firstChessProgramNames = quote; +} + +#ifdef HAVE_DIRENT_H +#include +#else +#include +#define dirent direct +#endif + +static void +InstallFromDir (char *dirName, char *protocol, char *settingsFile) +{ // scan system for new plugin specs in given directory + DIR *dir; + struct dirent *dp; + struct stat statBuf; + time_t lastSaved = 0; + char buf[1024]; + + if(!stat(settingsFile, &statBuf)) lastSaved = statBuf.st_mtime; + snprintf(buf, 1024, "%s/%s", dirName, protocol); + + if(!(dir = opendir(buf))) return; + while( (dp = readdir(dir))) { + time_t installed = 0; + if(!strstr(dp->d_name, ".eng")) continue; // to suppress . and .. + snprintf(buf, 1024, "%s/%s/%s", dirName, protocol, dp->d_name); + if(!stat(buf, &statBuf)) installed = statBuf.st_mtime; + if(lastSaved == 0 || (int) (installed - lastSaved) > 0) { // first time we see it + FILE *f = fopen(buf, "r"); + if(f) { // read the plugin-specs + char engineCommand[1024], engineDir[1024], variants[1024]; + char bad=0, dummy, *engineCom = engineCommand; + int major, minor; + if(fscanf(f, "plugin spec %d.%d%c", &major, &minor, &dummy) != 3 || + fscanf(f, "%[^\n]%c", engineCommand, &dummy) != 2 || + fscanf(f, "%[^\n]%c", variants, &dummy) != 2) bad = 1; + fclose(f); + if(bad) continue; + // uncomment following two lines for chess-only installs +// if(!(p = strstr(variants, "chess")) || +// p != variants && p[-1] != ',' || p[5] && p[5] != ',') continue; + // split off engine working directory (if any) + strcpy(engineDir, ""); + if(sscanf(engineCommand, "cd %[^;];%c", engineDir, &dummy) == 2) + engineCom = engineCommand + strlen(engineDir) + 4; + InstallNewEngine(engineCom, engineDir, variants, protocol); + } + } + } + closedir(dir); +} + +static void +AutoInstallProtocol (char *settingsFile, char *protocol) +{ // install new engines for given protocol (both from package and source) + InstallFromDir("/usr/local/share/games/plugins", protocol, settingsFile); + InstallFromDir("/usr/share/games/plugins", protocol, settingsFile); +} + +void +AutoInstall (char *settingsFile) +{ // install all new XBoard and UCI engines + AutoInstallProtocol(settingsFile, "xboard"); + AutoInstallProtocol(settingsFile, "uci"); +} + void InitMenuMarkers() { @@ -1234,4 +1320,7 @@ InitMenuMarkers() MarkMenuItem("Options.SaveSettingsonExit", True); } EnableNamedMenuItem("File.SaveSelected", False); + + // all XBoard builds get here, but not WinBoard... + if(*appData.autoInstall) AutoInstall(settingsFileName); }