/** * Set a colon-separated path, with environment variable expansions, * and expand '+' to be the value of the previous path. **/ void setPath( char** p_path, const char* newpath, int free_old_path ) { char* oldpath = *p_path; int oldlen = strlen( oldpath ); char* stripped_path = stripcpy( newpath ); int found_plus = strchr( newpath, '+' ) != NULL; /** Leave room for the old path, if we find a '+' in newpath **/ *p_path = envDupExpand( stripped_path, found_plus ? oldlen - 1 : 0 ); free( stripped_path ); if ( found_plus ) { char* p = strchr( *p_path, '+' ); memmove(p + oldlen, p + 1, strlen(p+1) + 1); memmove(p, oldpath, oldlen); } if ( free_old_path ) free( oldpath ); }
/** * Set a colon-separated path, with environment variable expansions, * and expand '+' to be the value of the previous path. **/ void setPath( char** p_path, char* newpath, int free_old_path ) { char* oldpath = *p_path; int oldlen = strlen( oldpath ); char* stripped_path = stripcpy( newpath ); int found_plus = strchr( newpath, '+' ) != NULL; /** Leave room for the old path, if we find a '+' in newpath **/ *p_path = envDupExpand( stripped_path, found_plus ? oldlen : 0 ); free( stripped_path ); if ( found_plus ) { char* p = strchr( *p_path, '+' ); memmove( p+oldlen, p+1, strlen(p+1) ); /* copy oldlen+1 bytes to include the trailing NUL */ strncpy( p, oldpath, oldlen+1 ); } if ( free_old_path ) free( oldpath ); }
/* * delete from module configuration */ void CMD_DestroyModuleConfig(F_CMD_ARGS) { struct moduleInfoList *current, *next, *prev; char *info; /* info to be deleted - may contain wildcards */ char *mi; char *alias_end; int alias_len = 0; while (isspace(*action)) { action++; } alias_end = skipModuleAliasToken(action); if (alias_end && alias_end[0] == MODULE_CONFIG_DELIM) { /* migo: construct an old-style config line */ char *conf_start = alias_end + 1; while (isspace(*conf_start)) conf_start++; *alias_end = '\0'; GetNextToken(conf_start, &conf_start); if (conf_start == NULL) { return; } info = stripcpy(CatString2(action, conf_start)); *alias_end = MODULE_CONFIG_DELIM; /* +1 for a leading '*' */ alias_len = alias_end - action + 1; free(conf_start); } else { GetNextToken(action, &info); if (info == NULL) { return; } } current = modlistroot; prev = NULL; while (current != NULL) { GetNextToken(current->data, &mi); next = current->next; if ((!alias_len || !current->alias_len || alias_len == current->alias_len) && matchWildcards(info, mi+1)) { free(current->data); free(current); if( prev ) { prev->next = next; } else { modlistroot = next; } } else { prev = current; } current = next; if (mi) { free(mi); } } free(info); return; }
xml_elem_t* load_KDE_config(const char* realfilename) { xml_elem_t* config = create_CONTAINER_tag(); FILE *fp = fopen( realfilename, "r" ); if( fp != NULL ) { char buffer[8192]; xml_elem_t* group = NULL ; while(fgets(&buffer[0], sizeof(buffer), fp) != NULL) { xml_elem_t* tag ; int i = 0; while( isspace(buffer[i]) ) ++i ; if( buffer[i] == '#' ) { ++i; if( (tag = make_kde_config_comment_tag()) != NULL ) { int len = strlen( &buffer[i] ) ; while( len > 0 && isspace( buffer[i+len-1] ) ) --len ; if( len > 0 ) { tag->child = create_CDATA_tag(); tag->child->parm = mystrndup( &buffer[i], len ); } if( group == NULL ) { group = make_kde_config_group_tag(NULL); config->child = group; } xml_insert( group, tag ); } }else if( buffer[i] == '[' ) { ++i; if( (tag = make_kde_config_group_tag(&buffer[i])) != NULL ) { if( group ) group->next = tag ; else config->child = tag ; group = tag ; } }else if( buffer[i] != '\0' ) { int name_len ; tag = make_kde_config_item_tag(&buffer[i], &name_len); if( tag ) { /* now we need to parse value and then possibly a comment : */ char *val = stripcpy(&buffer[i+name_len+1] ); if( group == NULL ) { group = make_kde_config_group_tag(NULL); config->child = group; } xml_insert( group, tag ); if( val ) { if( val[0] != '\0' ) { tag->child = create_CDATA_tag(); tag->child->parm = val ; }else free( val ); } } } } fclose( fp ); } return config; }
void executeModule(XEvent * eventp, Window w, FvwmWindow * tmp_win, unsigned long context, char *action, int *Module) { int fvwm_to_app[2], app_to_fvwm[2]; int i, val, nargs = 0; char *cptr; char *args[20]; char *arg1 = NULL; char arg2[20]; char arg3[20]; char arg5[20]; char arg6[20]; extern char *ModulePath; extern char *fvwm_file; Window win; if (eventp->type != KeyPress) UngrabEm(); if (action == NULL) return; if (tmp_win) win = tmp_win->w; else win = None; /* If we execute a module, don't wait for buttons to come up, * that way, a pop-up menu could be implemented */ *Module = 0; action = GetNextToken(action, &cptr); arg1 = findIconFile(cptr, ModulePath, X_OK); if (arg1 == NULL) { if (cptr != NULL) { fvwm_msg(ERR, "executeModule", "No such module %s%s", ModulePath, cptr); free(cptr); } return; } /* Look for an available pipe slot */ for (i = 0; (i < npipes) && (writePipes[i] >= 0); ++i); if (i >= npipes) { fvwm_msg(ERR, "executeModule", "Too many Accessories!"); if (cptr != NULL) free(cptr); return; } /* I want one-ended pipes, so I open two two-ended pipes, * and close one end of each. I need one ended pipes so that * I can detect when the module crashes/malfunctions */ if (pipe(fvwm_to_app) != 0) { fvwm_msg(ERR, "executeModule", "Failed to open pipe"); return; } if (pipe(app_to_fvwm) != 0) { fvwm_msg(ERR, "executeModule", "Failed to open pipe2"); if (cptr != NULL) free(cptr); close(fvwm_to_app[0]); close(fvwm_to_app[1]); return; } pipeName[i] = stripcpy(cptr); sprintf(arg2, "%d", app_to_fvwm[1]); sprintf(arg3, "%d", fvwm_to_app[0]); sprintf(arg5, "%lx", (unsigned long) win); sprintf(arg6, "%lx", (unsigned long) context); args[0] = arg1; args[1] = arg2; args[2] = arg3; if (fvwm_file != NULL) args[3] = fvwm_file; else args[3] = "none"; args[4] = arg5; args[5] = arg6; nargs = 6; while ((action != NULL) && (nargs < 20) && (strlen(args[nargs - 1]) > 0)) { args[nargs] = 0; action = GetNextToken(action, &args[nargs]); nargs++; } if (strlen(args[nargs - 1]) <= 0) { nargs--; if (args[nargs] != NULL) free(args[nargs]); } args[nargs] = 0; /* Try vfork instead of fork. The man page says that vfork is better! */ /* Also, had to change exit to _exit() */ /* Not everyone has vfork! */ val = fork(); if (val > 0) { /* This fork remains running fvwm */ /* close appropriate descriptors from each pipe so * that fvwm will be able to tell when the app dies */ close(app_to_fvwm[1]); close(fvwm_to_app[0]); /* add these pipes to fvwm's active pipe list */ writePipes[i] = fvwm_to_app[1]; readPipes[i] = app_to_fvwm[0]; pipeOn[i] = -1; PipeMask[i] = MAX_MASK; free(arg1); pipeQueue[i] = NULL; /* make the PositiveWrite pipe non-blocking. Don't want to jam up fvwm because of an uncooperative module */ fcntl(writePipes[i], F_SETFL, O_NDELAY); /* Mark the pipes close-on exec so other programs * won`t inherit them */ if (fcntl(readPipes[i], F_SETFD, 1) == -1) fvwm_msg(ERR, "executeModule", "module close-on-exec failed"); if (fcntl(writePipes[i], F_SETFD, 1) == -1) fvwm_msg(ERR, "executeModule", "module close-on-exec failed"); for (i = 6; i < nargs; i++) { if (args[i] != 0) free(args[i]); } if (cptr != NULL) free(cptr); } else if (val == 0) { /* this is the child */ /* this fork execs the module */ close(fvwm_to_app[1]); close(app_to_fvwm[0]); execvp(arg1, args); fvwm_msg(ERR, "executeModule", "Execution of module failed: %s", arg1); perror(""); close(app_to_fvwm[1]); close(fvwm_to_app[0]); exit(1); } else { fvwm_msg(ERR, "executeModule", "Fork failed"); free(arg1); } return; }