static void config_rescan(GVC_t *gvc, char *config_path) { FILE *f = NULL; glob_t globbuf; char *config_glob, *config_re, *path, *libdir; int i, rc, re_status; gvplugin_library_t *library; regex_t re; #ifndef WIN32 char *plugin_glob = "libgvplugin_*"; #endif #if defined(DARWIN_DYLIB) char *plugin_re_beg = "[^0-9]\\."; char *plugin_re_end = "\\.dylib$"; #elif defined(__MINGW32__) char *plugin_glob = "libgvplugin_*"; char *plugin_re_beg = "[^0-9]-"; char *plugin_re_end = "\\.dll$"; #elif defined(__CYGWIN__) plugin_glob = "cyggvplugin_*"; char *plugin_re_beg = "[^0-9]-"; char *plugin_re_end = "\\.dll$"; #elif defined(WIN32) char *plugin_glob = "gvplugin_*"; char *plugin_re_beg = "[^0-9]"; char *plugin_re_end = "\\.dll$"; #elif ((defined(__hpux__) || defined(__hpux)) && !(defined(__ia64))) char *plugin_re_beg = "\\.sl\\."; char *plugin_re_end = "$"; #else /* Everyone else */ char *plugin_re_beg = "\\.so\\."; char *plugin_re_end= "$"; #endif if (config_path) { f = fopen(config_path,"w"); if (!f) { agerr(AGERR,"failed to open %s for write.\n", config_path); exit(1); } fprintf(f, "# This file was generated by \"dot -c\" at time of install.\n\n"); fprintf(f, "# You may temporarily disable a plugin by removing or commenting out\n"); fprintf(f, "# a line in this file, or you can modify its \"quality\" value to affect\n"); fprintf(f, "# default plugin selection.\n\n"); fprintf(f, "# Manual edits to this file **will be lost** on upgrade.\n\n"); } libdir = gvconfig_libdir(gvc); config_re = gmalloc(strlen(plugin_re_beg) + 20 + strlen(plugin_re_end) + 1); #if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) sprintf(config_re,"%s%s", plugin_re_beg, plugin_re_end); #elif defined(GVPLUGIN_VERSION) sprintf(config_re,"%s%d%s", plugin_re_beg, GVPLUGIN_VERSION, plugin_re_end); #else sprintf(config_re,"%s[0-9]+%s", plugin_re_beg, plugin_re_end); #endif if (regcomp(&re, config_re, REG_EXTENDED|REG_NOSUB) != 0) { agerr(AGERR,"cannot compile regular expression %s", config_re); } config_glob = gmalloc(strlen(libdir) + 1 + strlen(plugin_glob) + 1); strcpy(config_glob, libdir); strcat(config_glob, DIRSEP); strcat(config_glob, plugin_glob); /* load all libraries even if can't save config */ #if defined(WIN32) rc = glob(gvc, config_glob, GLOB_NOSORT, NULL, &globbuf); #else rc = glob(config_glob, GLOB_NOSORT, NULL, &globbuf); #endif if (rc == 0) { for (i = 0; i < globbuf.gl_pathc; i++) { re_status = regexec(&re, globbuf.gl_pathv[i], (size_t) 0, NULL, 0); if (re_status == 0) { library = gvplugin_library_load(gvc, globbuf.gl_pathv[i]); if (library) { gvconfig_plugin_install_from_library(gvc, globbuf.gl_pathv[i], library); } } } /* rescan with all libs loaded to check cross dependencies */ for (i = 0; i < globbuf.gl_pathc; i++) { re_status = regexec(&re, globbuf.gl_pathv[i], (size_t) 0, NULL, 0); if (re_status == 0) { library = gvplugin_library_load(gvc, globbuf.gl_pathv[i]); if (library) { path = strrchr(globbuf.gl_pathv[i],DIRSEP[0]); if (path) path++; if (f && path) gvconfig_write_library_config(gvc, path, library, f); } } } } regfree(&re); globfree(&globbuf); free(config_glob); free(config_re); if (f) fclose(f); }
/* load a plugin of type=str where str can optionally contain a ":packagename" modifier */ gvplugin_available_t *gvplugin_load(GVC_t * gvc, api_t api, char *str) { gvplugin_available_t **pnext, *rv; gvplugin_library_t *library; gvplugin_api_t *apis; gvplugin_installed_t *types; char *s, *p; int i; /* check for valid apis[] index */ if (api < 0) return NULL; /* does str have a :packagename modifier? */ s = strdup(str); p = strchr(s, ':'); if (p) *p++ = '\0'; /* point to the beginning of the linked list of plugins for this api */ pnext = &(gvc->apis[api]); while (*pnext) { if (strcmp(s, (*pnext)->typestr) == 0) { if (p) { if (strcmp(p, (*pnext)->packagename) == 0) break; } else break; } pnext = &((*pnext)->next); } rv = *pnext; if ((*pnext) && (*pnext)->typeptr == NULL) { rv = NULL; library = gvplugin_library_load((*pnext)->path); if (library) { /* * FIXME - would be cleaner to here remove the entries from the * config data for the uninstalled library - i.e. the entries * without type ptrs. It works without because the real library * data is inserted ahead of, and so supercedes, the config data. */ /* Now reinsert the library with real type ptrs */ for (apis = library->apis; (types = apis->types); apis++) { for (i = 0; types[i].type; i++) { gvplugin_install(gvc, apis->api, types[i].type, types[i].quality, library->packagename, (*pnext)->path, &types[i]); } } /* Now search again for the specific plugin type */ pnext = &(gvc->apis[api]); while (*pnext) { if (strcmp(s, (*pnext)->typestr) == 0) { if (p) { if (strcmp(p, (*pnext)->packagename) == 0) break; } else break; } pnext = &((*pnext)->next); } rv = *pnext; } } /* one last check for succesfull load */ if ((*pnext) && (*pnext)->typeptr == NULL) rv = NULL; free(s); gvc->api[api] = rv; return rv; }