bool tokz_pushf_file(Tokenizer *tokz, FILE *file, const char *fname) { char *fname_copy=NULL; if(file==NULL) return FALSE; if(fname!=NULL){ fname_copy=scopy(fname); if(fname_copy==NULL){ warn_err(); return FALSE; } } if(tokz->file!=NULL){ if(!do_tokz_pushf(tokz)){ warn_err(); if(fname_copy!=NULL) free(fname_copy); return FALSE; } } tokz->file=file; tokz->name=fname_copy; tokz->line=1; tokz->ungetc=-1; tokz->ungettok.type=TOK_INVALID; return TRUE; }
void libtu_asprintf(char **ret, const char *p, ...) { *ret=NULL; CALL_V(vasprintf, (ret, p, args)); if(*ret==NULL) warn_err(); }
void wm_exec(const char *cmd) { int pid; char *tmp; int tmp_len; pid=fork(); if(pid<0) warn_err(); if(pid!=0) return; setup_environ(SCREEN->xscr); close(wglobal.conn); tmp_len = strlen(cmd)+8; tmp=ALLOC_N(char, tmp_len); if(tmp==NULL) die_err(); snprintf(tmp, tmp_len, "exec %s", cmd); do_exec(tmp); }
static bool do_tokz_popf(Tokenizer *tokz, bool shrink) { Tokenizer_FInfo *finfo; if(tokz->filestack_n<=0) return FALSE; if(tokz->file!=NULL) fclose(tokz->file); if(tokz->name!=NULL) free(tokz->name); finfo=&(tokz->filestack[--tokz->filestack_n]); tokz->file=finfo->file; tokz->name=finfo->name; tokz->line=finfo->line; tokz->ungetc=finfo->ungetc; tokz->ungettok=finfo->ungettok; if(tokz->filestack_n==0){ free(tokz->filestack); tokz->filestack=NULL; }else if(shrink){ finfo=REALLOC_N(tokz->filestack, Tokenizer_FInfo, tokz->filestack_n+1, tokz->filestack_n); if(finfo==NULL) warn_err(); else tokz->filestack=finfo; } return TRUE; }
static Tokenizer *tokz_create() { Tokenizer*tokz; tokz=ALLOC(Tokenizer); if(tokz==NULL){ warn_err(); return NULL; } tokz->file=NULL; tokz->name=NULL; tokz->line=1; tokz->ungetc=-1; tokz->ungettok.type=TOK_INVALID; tokz->flags=0; tokz->optstack=NULL; tokz->nest_lvl=0; tokz->filestack_n=0; tokz->filestack=NULL; tokz->buffer.data=0; tokz->buffer.len=0; tokz->buffer.pos=0; return tokz; }
static WDock *create_dock(int x, int y, bool horiz) { WDock *dock; dock=ALLOC(WDock); if(dock==NULL){ warn_err(); return NULL; } WTHING_INIT(dock, WTHING_DOCK); if(create_flags&DOCK_RIGHT) create_x=SCREEN->width+create_x-DOCKWIN_W; if(create_flags&DOCK_BOTTOM) create_y=SCREEN->height+create_y-DOCKWIN_H; if(!do_create_dock(dock, create_x, create_y, create_flags)){ free(dock); return NULL; } return dock; }
void setup_environ(int scr) { char *tmp, *ptr; char *display; int tmp_len; display=XDisplayName(wglobal.display); tmp_len = strlen(display)+16; tmp=ALLOC_N(char, tmp_len); if(tmp==NULL){ warn_err(); return; } snprintf(tmp, tmp_len, "DISPLAY=%s", display); ptr=strchr(tmp, ':'); if(ptr!=NULL){ ptr=strchr(ptr, '.'); if(ptr!=NULL) *ptr='\0'; } if(scr>=0){ int curr_len=strlen(tmp); snprintf(tmp+curr_len, tmp_len-curr_len, ".%i", scr); } putenv(tmp); /*XFree(display);*/ }
void libtu_vasprintf(char **ret, const char *p, va_list args) { *ret=NULL; vasprintf(ret, p, args); if(*ret==NULL) warn_err(); }
/* this function will be called once by the server during startup */ int session_client_module_init(u_config_t *config, session_opt_t *so) { u_config_t *c; const char *v; /* config may be NULL */ dbg_err_if (so == NULL); /* default */ so->hash = EVP_sha1(); /* always enable encryption for client-side sessions */ if(!so->encrypt) warn("encryption is required for client side session"); so->encrypt = 1; if(config && !u_config_get_subkey(config, "client", &c)) { if((v = u_config_get_subkey_value(c, "hash_function")) != NULL) { if(!strcasecmp(v, "md5")) so->hash = EVP_md5(); else if(!strcasecmp(v, "sha1")) so->hash = EVP_sha1(); #ifdef SSL_OPENSSL else if(!strcasecmp(v, "ripemd160")) so->hash = EVP_ripemd160(); #endif else warn_err("config error: bad hash_function"); } } #ifdef SSL_OPENSSL /* initialize OpenSSL HMAC stuff */ HMAC_CTX_init(&so->hmac_ctx); /* gen HMAC key */ dbg_err_if(!RAND_bytes(so->hmac_key, HMAC_KEY_LEN)); /* init HMAC with our key and chose hash algorithm */ HMAC_Init_ex(&so->hmac_ctx, so->hmac_key, HMAC_KEY_LEN, so->hash, NULL); #endif #ifdef SSL_CYASSL /* gen HMAC key */ dbg_err_if(!RAND_bytes(so->hmac_key, HMAC_KEY_LEN)); if(strcmp(so->hash, "MD5") == 0) HmacSetKey(&so->hmac_ctx, MD5, so->hmac_key, HMAC_KEY_LEN); else if(strcmp(so->hash, "SHA") == 0) HmacSetKey(&so->hmac_ctx, SHA, so->hmac_key, HMAC_KEY_LEN); #endif return 0; err: return ~0; }
static int klog_args_check (klog_args_t *ka) { dbg_return_if (ka == NULL, ~0); if (ka->type == KLOG_TYPE_UNKNOWN) warn_err("unknown log type"); /* do not filter if not specified or if a wrong value has been supplied */ if (ka->threshold == KLOG_LEVEL_UNKNOWN) { u_dbg("threshold unspecified: assuming lowest possible (DEBUG)"); ka->threshold = KLOG_DEBUG; } switch (ka->type) { case KLOG_TYPE_MEM: if (ka->mlimit == 0) ka->mlimit = KLOG_MLIMIT_DFL; break; case KLOG_TYPE_FILE: if (ka->fbasename == NULL) warn_err("log file path is mandatory !"); if (ka->fsplits == 0) ka->fsplits = KLOG_FSPLITS_DFL; if (ka->flimit == 0) ka->flimit = KLOG_FLIMIT_DFL; break; case KLOG_TYPE_SYSLOG: if (ka->sfacility == KLOG_FACILITY_UNKNOWN) { warn("facility unspecified: defaults to LOG_LOCAL7"); ka->sfacility = LOG_LOCAL7; } break; default: warn_err("what are you doing here ?"); } return 0; err: return ~0; }
static bool wslist_menudata_init(WMenuData *data, WThing *context) { WMenuEnt *ents; int nents, l, i=0; char *entryname; nents=SCREEN->n_workspaces; /* Some extra space will be allocated depending on number of dockapps */ ents=ALLOC_N(WMenuEnt, nents); if(ents==NULL){ warn_err(); return FALSE; } l=sizeof(int)*3+4+1; /* should be enough */ for(i=0; i<nents; i++){ entryname=ALLOC_N(char, l); if(entryname==NULL){ warn_err(); do_free_winlist(ents, i); return FALSE; } snprintf(entryname, l, "ws %d", i+1); ents[i].name=entryname; ents[i].flags=0; ents[i].u.num=i; SET_INT_ARG(ents[i].u.f.arg, i); } data->entries=ents; data->nentries=nents; return TRUE; }
static int session_client_load(session_t *ss) { session_opt_t *so = ss->so; char hmac[HMAC_HEX_SIZE], buf[COOKIE_MAX_SIZE]; const char *cli_ebuf, *cli_hmac, *cli_mtime, *cli_iv; ssize_t c; dbg_err_if (ss == NULL); /* extract session data, mtime and hmac from cookies */ cli_ebuf = request_get_cookie(ss->rq, KL1_CLISES_DATA); cli_mtime = request_get_cookie(ss->rq, KL1_CLISES_MTIME); cli_hmac = request_get_cookie(ss->rq, KL1_CLISES_HMAC); cli_iv = request_get_cookie(ss->rq, KL1_CLISES_IV); //nop_err_if(cli_ebuf == NULL || cli_mtime == NULL || cli_hmac == NULL); dbg_err_if(cli_ebuf == NULL || cli_mtime == NULL || cli_hmac == NULL); /* cli_iv may be NULL */ /* calc the HMAC */ dbg_err_if(session_client_hmac(&so->hmac_ctx, hmac, HMAC_HEX_SIZE, cli_ebuf, ss->id, cli_mtime, ss->so->encrypt ? cli_iv : NULL)); /* compare HMACs */ if(strcmp(hmac, cli_hmac)) { session_remove(ss); /* remove all bad stale data */ warn_err("HMAC don't match, rejecting session data"); } /* hash ckeched. decode/uncompress/decrypt session data */ /* hex decode and save current cipher IV */ dbg_err_if((c = u_hexncpy(ss->so->cipher_iv, cli_iv, strlen(cli_iv), HEXCPY_DECODE)) <= 0); /* set client provided mtime */ ss->mtime = strtoul(cli_mtime, NULL, 0); dbg_err_if(strlen(cli_ebuf) > COOKIE_MAX_SIZE); /* hex decode session data */ dbg_err_if((c = u_hexncpy(buf, cli_ebuf, strlen(cli_ebuf), HEXCPY_DECODE)) <= 0); /* load session data from the buffer */ dbg_err_if(session_prv_load_from_buf(ss, buf, c)); return 0; err: return ~0; }
bool parse_config_tokz(Tokenizer *tokz, const ConfOpt *options) { Token tokens[MAX_TOKENS]; bool alloced_optstack=FALSE; int i, t, ntokens=0; int init_nest_lvl; bool had_error; int errornest=0; bool is_default=FALSE; /* Allocate tokz->optstack if it does not yet exist (if it does, * we have been called from an option handler) */ if(!tokz->optstack){ tokz->optstack=ALLOC_N(const ConfOpt*, MAX_NEST); if(!tokz->optstack){ warn_err(); return FALSE; } memset(tokz->optstack, 0, sizeof(ConfOpt*)*MAX_NEST); init_nest_lvl=tokz->nest_lvl=0; alloced_optstack=TRUE; }else{
static bool winlist_menudata_init(WMenuData *data, WThing *context) { WMenuEnt *ents; WFrame *frame; int ws; WClientWin *cwin; int nents, length, entryname_length, i=0; const char *winname; char *entryname; nents=SCREEN->n_clientwin; /* Some extra space will be allocated depending on number of dockapps */ ents=ALLOC_N(WMenuEnt, nents); if(ents==NULL){ warn_err(); return FALSE; } for(frame=(WFrame*)subthing((WThing*)SCREEN, WTHING_FRAME); frame!=NULL; frame=(WFrame*)next_thing((WThing*)frame, WTHING_FRAME)){ ws=workspace_of((WWinObj*)frame); /* Don't list active frame */ if(data==&attachlist_menudata){ if(context!=NULL && winobj_of(context)==(WWinObj*)frame) continue; } for(cwin=first_clientwin((WThing*)frame); cwin!=NULL; cwin=next_clientwin(cwin)){ if(!CWIN_HAS_FRAME(cwin)) continue; winname=clientwin_full_label(cwin); length=32+strlen(winname); entryname=ALLOC_N(char, length); if(entryname==NULL){ warn_err(); do_free_winlist(ents, i); return FALSE; } if(ws>=0){ entryname_length=snprintf(entryname+0, length, "%d%c", ws+1, (cwin==frame->current_cwin ? '+' : '-')); }else{ entryname_length=snprintf(entryname+0, length, "%c%c", (ws==WORKSPACE_STICKY ? '*' : '?'), (cwin==frame->current_cwin ? '+' : '-')); } snprintf(entryname + entryname_length, length - entryname_length, " %s", winname); ents[i].name=entryname; ents[i].flags=0; ents[i].u.winlist.clientwin=cwin; ents[i].u.winlist.sort=i; i++; } } nents=i; qsort(ents, nents, sizeof(WMenuEnt), menuent_cmp); data->entries=ents; data->nentries=nents; return TRUE; }
int main(int argc, char*argv[]) { const char *cfgfile="cfg_notion"; const char *display=NULL; char *cmd=NULL; int stflags=0; int opt; ErrorLog el; FILE *ef=NULL; char *efnam=NULL; bool may_continue=FALSE; bool noerrorlog=FALSE; char *localedir; libtu_init(argv[0]); #ifdef CF_RELOCATABLE_BIN_LOCATION prefix_set(argv[0], CF_RELOCATABLE_BIN_LOCATION); #endif localedir=prefix_add(LOCALEDIR); if(!ioncore_init(CF_EXECUTABLE, argc, argv, localedir)) return EXIT_FAILURE; if(localedir!=NULL) free(localedir); prefix_wrap_simple(extl_add_searchdir, EXTRABINDIR); /* ion-completefile */ prefix_wrap_simple(extl_add_searchdir, MODULEDIR); prefix_wrap_simple(extl_add_searchdir, ETCDIR); prefix_wrap_simple(extl_add_searchdir, SHAREDIR); prefix_wrap_simple(extl_add_searchdir, LCDIR); extl_set_userdirs(CF_EXECUTABLE); optparser_init(argc, argv, OPTP_MIDLONG, ion_opts); while((opt=optparser_get_opt())){ switch(opt){ case OPT_ID('d'): display=optparser_get_arg(); break; case 'c': cfgfile=optparser_get_arg(); break; case 's': extl_add_searchdir(optparser_get_arg()); break; case OPT_ID('S'): ioncore_g.sm_client_id=optparser_get_arg(); break; case OPT_ID('o'): stflags|=IONCORE_STARTUP_ONEROOT; break; case OPT_ID('s'): extl_set_sessiondir(optparser_get_arg()); break; case OPT_ID('N'): noerrorlog=TRUE; break; case 'h': help(); return EXIT_SUCCESS; case 'V': printf("%s\n", ION_VERSION); return EXIT_SUCCESS; case OPT_ID('a'): printf("%s\n", ioncore_aboutmsg()); return EXIT_SUCCESS; default: warn(TR("Invalid command line.")); help(); return EXIT_FAILURE; } } if(!noerrorlog){ /* We may have to pass the file to xmessage so just using tmpfile() * isn't sufficient. */ libtu_asprintf(&efnam, "%s/ion-%d-startup-errorlog", P_tmpdir, getpid()); if(efnam==NULL){ warn_err(); }else{ ef=fopen(efnam, "wt"); if(ef==NULL){ warn_err_obj(efnam); free(efnam); efnam=NULL; }else{ cloexec_braindamage_fix(fileno(ef)); fprintf(ef, TR("Notion startup error log:\n")); errorlog_begin_file(&el, ef); } } } if(ioncore_startup(display, cfgfile, stflags)) may_continue=TRUE; if(!may_continue) warn(TR("Refusing to start due to encountered errors.")); else check_new_user_help(); if(ef!=NULL){ pid_t pid=-1; if(errorlog_end(&el) && ioncore_g.dpy!=NULL){ fclose(ef); pid=fork(); if(pid==0){ ioncore_setup_display(DefaultScreen(ioncore_g.dpy)); if(!may_continue) XCloseDisplay(ioncore_g.dpy); else close(ioncore_g.conn); libtu_asprintf(&cmd, CF_XMESSAGE " %s", efnam); if(cmd==NULL){ warn_err(); }else if(system(cmd)==-1){ warn_err_obj(cmd); } unlink(efnam); exit(EXIT_SUCCESS); } if(!may_continue && pid>0) waitpid(pid, NULL, 0); }else{ fclose(ef); } if(pid<0) unlink(efnam); free(efnam); } if(!may_continue) return EXIT_FAILURE; ioncore_mainloop(); /* The code should never return here */ return EXIT_SUCCESS; }
static bool wait_statusd_init(int outfd, int errfd, ExtlFn dh, ExtlFn eh) { fd_set rfds; struct timeval tv, endtime, now; int nfds=MAXOF(outfd, errfd); int retval; bool dummy, doneseen, eagain=FALSE; if(mainloop_gettime(&endtime)!=0){ warn_err(); return FALSE; } now=endtime; endtime.tv_sec+=CF_STATUSD_TIMEOUT_SEC; while(1){ FD_ZERO(&rfds); /* Calculate remaining time */ if(now.tv_sec>endtime.tv_sec){ goto timeout; }else if(now.tv_sec==endtime.tv_sec){ if(now.tv_usec>=endtime.tv_usec) goto timeout; tv.tv_sec=0; tv.tv_usec=endtime.tv_usec-now.tv_usec; }else{ tv.tv_usec=USEC+endtime.tv_usec-now.tv_usec; tv.tv_sec=-1+endtime.tv_sec-now.tv_sec; /* Kernel lameness tuner: */ tv.tv_sec+=tv.tv_usec/USEC; tv.tv_usec%=USEC; } FD_SET(outfd, &rfds); FD_SET(errfd, &rfds); retval=select(nfds+1, &rfds, NULL, NULL, &tv); if(retval>0){ if(FD_ISSET(errfd, &rfds)){ if(!process_pipe(errfd, eh, &dummy, &eagain)) return FALSE; } if(FD_ISSET(outfd, &rfds)){ if(!process_pipe(outfd, dh, &doneseen, &eagain)) return FALSE; if(doneseen){ /* Read rest of errors. */ bool ok; do{ ok=process_pipe(errfd, eh, &dummy, &eagain); }while(ok && !eagain); return TRUE; } } }else if(retval==0){ goto timeout; } if(mainloop_gettime(&now)!=0){ warn_err(); return FALSE; } } return TRUE; timeout: /* Just complain to stderr, not startup error log, and do not fail. * The system might just be a bit slow. We can continue, but without * initial values for the meters, geometry adjustments may be necessary * when we finally get that information. */ ioncore_warn_nolog(TR("ion-statusd timed out.")); return TRUE; }
/* Create a menu window */ static WMenu* create_menu(WMenuData *mdata, WThing *context, int x, int y, WMenu *parent) { int w, h, th, eh; int flags=0; Window win; WMenu *menu; if(mdata->init_func!=NULL && mdata->nref==0) mdata->init_func(mdata, context); if(mdata->flags&WMENUDATA_CONTEXTUAL){ if(context==NULL || WTHING_IS(context, WTHING_SCREEN) || WTHING_IS(context, WTHING_MENU)) return NULL; flags|=(WMENU_NOTITLE|WMENU_CONTEXTUAL); }else{ context=NULL; } if(mdata->nref!=0) flags|=(WMENU_NOTITLE|WMENU_CONTEXTUAL); if(mdata->title==NULL) flags|=(WMENU_NOTITLE|WMENU_CONTEXTUAL); if(parent!=NULL) flags|=parent->flags&(WMENU_NOTITLE|WMENU_CONTEXTUAL); /* */ w=menu_width(mdata, flags); h=menu_height(mdata); /* Don't display empty menus */ if(w==0 || h==0) return NULL; /* */ menu=ALLOC(WMenu); if(menu==NULL){ warn_err(); return NULL; } WTHING_INIT(menu, WTHING_MENU); th=FONT_HEIGHT(GRDATA->font)+2*CF_MENUTITLE_V_SPACE; eh=FONT_HEIGHT(GRDATA->menu_font)+2*CF_MENUENT_V_SPACE; if(parent==NULL){ x-=w/2; y+=th/(flags&WMENU_NOTITLE ? 2 : -2 ); }else if(!(flags&WMENU_NOTITLE)){ y-=th; } if(flags&WMENU_NOTITLE) th=0; h+=th; win=create_simple_window(x, y, w, h, GRDATA->base_colors.pixels[WCG_PIX_BG]); menu->menu_win=win; menu->x=x; menu->y=y; menu->w=w; menu->h=h; menu->title_height=th; menu->entry_height=eh; menu->flags=flags; menu->selected=NO_ENTRY; menu->data=mdata; menu->context=context; if(mdata->nref++==0) mdata->inst1=menu; XSelectInput(wglobal.dpy, win, MENU_MASK); XSaveContext(wglobal.dpy, win, wglobal.win_context, (XPointer)menu); if(parent==NULL) add_winobj((WWinObj*)menu, WORKSPACE_STICKY, LVL_MENU); else add_winobj_above((WWinObj*)menu, (WWinObj*)parent); map_winobj((WWinObj*)menu); return menu; }