void CPlugins::scanDir(const char *dir) { struct dirent **namelist; std::string fname; int number_of_files = scandir(dir, &namelist, 0, alphasort); for (int i = 0; i < number_of_files; i++) { std::string filename; filename = namelist[i]->d_name; int pos = filename.find(".cfg"); if (pos > -1) { plugin new_plugin; new_plugin.filename = filename.substr(0, pos); fname = dir; fname += '/'; new_plugin.cfgfile = fname.append(new_plugin.filename); new_plugin.cfgfile.append(".cfg"); parseCfg(&new_plugin); bool plugin_ok = parseCfg(&new_plugin); if (plugin_ok) { new_plugin.pluginfile = fname; if (new_plugin.type == CPlugins::P_TYPE_SCRIPT) { new_plugin.pluginfile.append(".sh"); } else { new_plugin.pluginfile.append(".so"); } // We do not check if new_plugin.pluginfile exists since .cfg in // PLUGINDIR_VAR can overwrite settings in read only dir // PLUGINDIR. This needs PLUGINDIR_VAR to be scanned at // first -> .cfg in PLUGINDIR will be skipped since plugin // already exists in the list. // This behavior is used to make sure plugins can be disabled // by creating a .cfg in PLUGINDIR_VAR (PLUGINDIR often is read only). if (!plugin_exists(new_plugin.filename)) { plugin_list.push_back(new_plugin); number_of_plugins++; } } } } }
/* * Show user configured banner before service bootstrap progress */ static void banner(void) { char *buf = INIT_HEADING; char separator[SCREEN_WIDTH]; if (plugin_exists(HOOK_BANNER)) { plugin_run_hooks(HOOK_BANNER); return; } if (log_is_silent()) return; memset(separator, '=', sizeof(separator)); fprintf(stderr, "\n\e[2K\e[1m%s %.*s\e[0m\n", buf, SCREEN_WIDTH - (int)strlen(buf) - 2, separator); }
void CPlugins::addPlugin(const char * dir) { PluginInit initPlugin; void *handle = NULL; char *error; struct dirent **namelist; std::string fname; int number_of_files = scandir(dir, &namelist, 0, alphasort); for (int i = 0; i < number_of_files; i++) { std::string filename; filename = namelist[i]->d_name; int pos = filename.find(".cfg"); if (pos > -1) { plugin new_plugin; new_plugin.filename = filename.substr(0, pos); fname = dir; fname += '/'; new_plugin.cfgfile = fname.append(new_plugin.filename); new_plugin.cfgfile.append(".cfg"); parseCfg(&new_plugin); bool plugin_ok = parseCfg(&new_plugin); if (plugin_ok) { new_plugin.pluginfile = fname; if (new_plugin.type == CPlugins::P_TYPE_SCRIPT) { new_plugin.pluginfile.append(".sh"); } else if (new_plugin.type == CPlugins::P_TYPE_GAME) { new_plugin.pluginfile.append(".so"); } else if (new_plugin.type == CPlugins::P_TYPE_TOOL) { new_plugin.pluginfile.append(".so"); } else if (new_plugin.type == CPlugins::P_TYPE_NEUTRINO) { new_plugin.pluginfile.append(".so"); // initPlugin handle = dlopen ( new_plugin.pluginfile.c_str(), RTLD_NOW); if (!handle) { fputs (dlerror(), stderr); } else { initPlugin = (PluginInit) dlsym(handle, "plugin_init"); if ((error = dlerror()) != NULL) { fputs(error, stderr); dlclose(handle); } else { dprintf(DEBUG_DEBUG, "[CPlugins] try init...\n"); initPlugin(); dlclose(handle); dprintf(DEBUG_DEBUG, "[CPlugins] init done...\n"); } } } // if (!plugin_exists(new_plugin.filename)) { plugin_list.push_back(new_plugin); number_of_plugins++; } } } } }
int yylex() { char *p = line + linelim; int ret=0; static int isfunc = 0; static bool isgoto = 0; static bool colstate = 0; static int dateflag; static char *tokenst = NULL; static int tokenl; while (isspace(*p)) p++; if (*p == '\0') { isfunc = isgoto = 0; ret = -1; } else if (isalpha(*p) || (*p == '_')) { register char *la; /* lookahead pointer */ register struct key *tblp; if (!tokenst) { tokenst = p; tokenl = 0; } /* * This picks up either 1 or 2 alpha characters (a column) or * tokens made up of alphanumeric chars and '_' (a function or * token or command or a range name) */ while (isalpha(*p) && isascii(*p)) { p++; tokenl++; } la = p; while (isdigit(*la) || (*la == '$')) la++; /* * A COL is 1 or 2 char alpha with nothing but digits following * (no alpha or '_') */ if (!isdigit(*tokenst) && tokenl && tokenl <= 2 && (colstate || (isdigit(*(la-1)) && !(isalpha(*la) || (*la == '_'))))) { ret = COL; yylval.ival = atocol(tokenst, tokenl); } else { while (isalpha(*p) || (*p == '_') || isdigit(*p)) { p++; tokenl++; } ret = WORD; if (!linelim || isfunc) { if (isfunc) isfunc--; for (tblp = linelim ? experres : statres; tblp->key; tblp++) if (((tblp->key[0]^tokenst[0])&0137)==0 && tblp->key[tokenl]==0) { int i = 1; while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0) i++; if (i >= tokenl) { ret = tblp->val; colstate = (ret <= S_FORMAT); if (isgoto) { isfunc = isgoto = 0; if (ret != K_ERROR && ret != K_INVALID) ret = WORD; } break; } } } if (ret == WORD) { struct range *r; char *path; if (!find_range(tokenst, tokenl, (struct ent *)0, (struct ent *)0, &r)) { yylval.rval.left = r->r_left; yylval.rval.right = r->r_right; if (r->r_is_range) ret = RANGE; else ret = VAR; } else if ((path = scxmalloc((unsigned)PATHLEN)) && plugin_exists(tokenst, tokenl, path)) { strcat(path, p); yylval.sval = path; ret = PLUGIN; } else { scxfree(path); linelim = p-line; yyerror("Unintelligible word"); } } } } else if ((*p == '.') || isdigit(*p)) { #ifdef SIGVOID void (*sig_save)(); #else int (*sig_save)(); #endif double v = 0.0; int temp; char *nstart = p; sig_save = signal(SIGFPE, fpe_trap); if (setjmp(fpe_buf)) { (void) signal(SIGFPE, sig_save); yylval.fval = v; error("Floating point exception\n"); isfunc = isgoto = 0; tokenst = NULL; return FNUMBER; } if (*p=='.' && dateflag) { /* .'s in dates are returned as tokens. */ ret = *p++; dateflag--; } else { if (*p != '.') { tokenst = p; tokenl = 0; do { v = v*10.0 + (double) ((unsigned) *p - '0'); tokenl++; } while (isdigit(*++p)); if (dateflag) { ret = NUMBER; yylval.ival = (int)v; /* * If a string of digits is followed by two .'s separated by * one or two digits, assume this is a date and return the * .'s as tokens instead of interpreting them as decimal * points. dateflag counts the .'s as they're returned. */ } else if (*p=='.' && isdigit(*(p+1)) && (*(p+2)=='.' || (isdigit(*(p+2)) && *(p+3)=='.'))) { ret = NUMBER; yylval.ival = (int)v; dateflag = 2; } else if (*p == 'e' || *p == 'E') { while (isdigit(*++p)) /* */; if (isalpha(*p) || *p == '_') { linelim = p - line; return (yylex()); } else ret = FNUMBER; } else if (isalpha(*p) || *p == '_') { linelim = p - line; return (yylex()); } } if ((!dateflag && *p=='.') || ret == FNUMBER) { ret = FNUMBER; yylval.fval = strtod(nstart, &p); if (!finite(yylval.fval)) ret = K_ERR; else decimal = TRUE; } else { /* A NUMBER must hold at least MAXROW and MAXCOL */ /* This is consistent with a short row and col in struct ent */ if (v > (double)32767 || v < (double)-32768) { ret = FNUMBER; yylval.fval = v; } else { temp = (int)v; if((double)temp != v) { ret = FNUMBER; yylval.fval = v; } else { ret = NUMBER; yylval.ival = temp; } } } } (void) signal(SIGFPE, sig_save); } else if (*p=='"') { char *ptr; ptr = p+1; /* "string" or "string\"quoted\"" */ while (*ptr && ((*ptr != '"') || (*(ptr-1) == '\\'))) ptr++; ptr = scxmalloc((unsigned)(ptr-p)); yylval.sval = ptr; p++; while (*p && ((*p != '"') || (*(p-1) == '\\' && *(p+1) != '\0' && *(p+1) != '\n'))) *ptr++ = *p++; *ptr = '\0'; if (*p) p++; ret = STRING; } else if (*p=='[') { while (*p && *p!=']') p++; if (*p) p++; linelim = p-line; tokenst = NULL; return yylex(); } else ret = *p++; linelim = p-line; if (!isfunc) isfunc = ((ret == '@') + (ret == S_GOTO) - (ret == S_SET)); if (ret == S_GOTO) isgoto = TRUE; tokenst = NULL; return ret; }