void run_command_source_cmd(const char *cmdstr) /* {{{ */ { /* run commands generated by a command */ FILE *cmd = popen(cmdstr, "r"); tnc_fprintf(logfp, LOG_DEBUG, "source: command \"%s\"", cmdstr); /* check for a valid fd */ if (cmdstr == NULL) { tnc_fprintf(logfp, LOG_ERROR, "source: file \"%s\" could not be opened", cmdstr); statusbar_message(cfg.statusbar_timeout, "source: command \"%s\" could not be opened", cmdstr); return; } /* exit window */ def_prog_mode(); endwin(); /* read command file */ source_fp(cmd); /* force redraw */ reset_prog_mode(); redraw = true; /* close config file */ pclose(cmd); tnc_fprintf(logfp, LOG_DEBUG, "source complete: \"%s\"", cmdstr); statusbar_message(cfg.statusbar_timeout, "source complete: \"%s\"", cmdstr); } /* }}} */
void tasklist_command_message(const int ret, const char *fail, const char *success) /* {{{ */ { /* print a message depending on the return of a command * ret - the return of the command * fail - the format string to use if ret == 1 * success - the literal string to use if ret == 0 */ if (ret!=0) statusbar_message(cfg.statusbar_timeout, fail, ret); else statusbar_message(cfg.statusbar_timeout, success); } /* }}} */
void key_tasklist_undo(void) { /* {{{ */ /* handle a keyboard direction to run an undo */ int ret = task_background_command("task undo"); if (ret == 0) { statusbar_message(cfg.statusbar_timeout, "undo executed"); reload = true; } else { statusbar_message(cfg.statusbar_timeout, "undo execution failed (%d)", ret); } tasklist_check_curs_pos(); } /* }}} */
void run_command_color(char *args) /* {{{ */ { /** * create/modify a color rule * syntax: object foreground background [rule] */ char *object = NULL, *fg = NULL, *bg = NULL, *rule = NULL; color_object obj; int ret = 0, fgc, bgc; if (args != NULL) ret = sscanf(args, "%ms %m[a-z0-9-] %m[a-z0-9-] %m[^\n]", &object, &fg, &bg, &rule); if (ret < 3) { statusbar_message(cfg.statusbar_timeout, "syntax: color <object> <foreground> <background> <rule>"); tnc_fprintf(logfp, LOG_ERROR, "syntax: color <object> <foreground> <background> <rule> [%d](%s)", ret, args); goto cleanup; } /* parse object */ obj = parse_object(object); if (obj == OBJECT_NONE) { statusbar_message(cfg.statusbar_timeout, "color: invalid object \"%s\"", object); tnc_fprintf(logfp, LOG_ERROR, "color: invalid object \"%s\"", object); goto cleanup; } /* parse colors */ fgc = parse_color(fg); bgc = parse_color(bg); if (bgc < -2 || fgc < -2) { statusbar_message(cfg.statusbar_timeout, "color: invalid colors \"%s\" \"%s\"", fg, bg); tnc_fprintf(logfp, LOG_ERROR, "color: invalid colors %d:\"%s\" %d:\"%s\"", fgc, fg, bgc, bg); goto cleanup; } /* create color rule */ if (add_color_rule(obj, rule, fgc, bgc)>=0) statusbar_message(cfg.statusbar_timeout, "applied color rule"); else statusbar_message(cfg.statusbar_timeout, "applying color rule failed"); goto cleanup; cleanup: check_free(object); check_free(fg); check_free(bg); check_free(rule); } /* }}} */
void key_tasklist_sync(void) { /* {{{ */ /* handle a keyboard direction to sync */ int ret; statusbar_message(cfg.statusbar_timeout, "synchronizing tasks..."); ret = task_interactive_command("yes n | task sync"); if (ret == 0) { statusbar_message(cfg.statusbar_timeout, "tasks synchronized"); reload = true; } else { statusbar_message(cfg.statusbar_timeout, "task syncronization failed"); } } /* }}} */
void key_command(const char *arg) /* {{{ */ { /* accept and attemt to execute a command string */ char *cmdstr; if (arg==NULL) { /* prepare prompt */ statusbar_message(-1, ":"); set_curses_mode(NCURSES_MODE_STRING); /* get input */ statusbar_getstr(&cmdstr, ":"); wipe_statusbar(); /* reset */ set_curses_mode(NCURSES_MODE_STD); } else cmdstr = strdup(arg); /* run input command */ if (cmdstr[0]!=0) handle_command(cmdstr); free(cmdstr); } /* }}} */
void force_redraw() /* {{{ */ { /* force a redraw of active windows */ WINDOW *windows[] = {statusbar, tasklist, pager, header}; const int nwins = sizeof(windows)/sizeof(WINDOW *); int i; /* force a resize check */ handle_resize(); /* wipe windows */ for (i=0; i<nwins; i++) { wattrset(windows[i], COLOR_PAIR(0)); if (windows[i]==NULL) continue; wipe_window(windows[i]); wnoutrefresh(windows[i]); } doupdate(); /* print messages */ print_header(); tasklist_print_task_list(); statusbar_message(cfg.statusbar_timeout, "redrawn"); } /* }}} */
void key_tasklist_search_next(void) { /* {{{ */ /* handle a keyboard direction to move to next search result */ if (searchstring != NULL) { find_next_search_result(head, get_task_by_position(selline)); tasklist_check_curs_pos(); redraw = true; } else { statusbar_message(cfg.statusbar_timeout, "no active search string"); } } /* }}} */
void run_command_show(const char *arg) /* {{{ */ { /** * display a variable in the statusbar * syntax: variable */ var *this_var; char *message = NULL; int ret = 0; /* parse arg */ if (arg != NULL) ret = sscanf(arg, "%m[^\n]", &message); if (ret != 1) { statusbar_message(cfg.statusbar_timeout, "syntax: show <variable>"); tnc_fprintf(logfp, LOG_ERROR, "syntax: show <variable> [%d](%s)", ret, arg); goto cleanup; } /* check for a variable */ if (arg == NULL) { statusbar_message(cfg.statusbar_timeout, "no variable specified!"); goto cleanup; } /* find the variable */ this_var = (var *)find_var(arg); if (this_var==NULL) { statusbar_message(cfg.statusbar_timeout, "variable not found: %s", arg); goto cleanup; } /* acquire the value string and print it */ message = var_value_message(this_var, 1); statusbar_message(cfg.statusbar_timeout, message); cleanup: free(message); return; } /* }}} */
void run_command_unbind(char *argstr) /* {{{ */ { /** * unbind a key * syntax - mode key */ char *modestr = NULL, *keystr = NULL, *keyname = NULL; prog_mode mode; int ret = 0; /* parse args */ if (argstr != NULL) ret = sscanf(argstr, "%ms %m[^\n]", &modestr, &keystr); if (ret != 2) { statusbar_message(cfg.statusbar_timeout, "syntax: unbind <mode> <key>"); tnc_fprintf(logfp, LOG_ERROR, "syntax: unbind <mode> <key> [%d](%s)", ret, argstr); goto cleanup; } /* parse mode */ if (str_eq(modestr, "pager")) mode = MODE_PAGER; else if (str_eq(modestr, "tasklist")) mode = MODE_TASKLIST; else mode = MODE_ANY; int key = parse_key(keystr); remove_keybinds(key, mode); keyname = name_key(key); statusbar_message(cfg.statusbar_timeout, "key unbound: %s (%d)", keyname, key); goto cleanup; cleanup: free(keyname); free(modestr); free(keystr); return; } /* }}} */
void key_tasklist_delete(void) { /* {{{ */ /* complete selected task */ struct task* cur = get_task_by_position(selline); int ret; statusbar_message(cfg.statusbar_timeout, "deleting task"); ret = task_background_command("task %s delete"); tasklist_remove_task(cur); tasklist_command_message(ret, "delete failed (%d)", "delete successful"); } /* }}} */
void find_next_search_result(task *head, task *pos) /* {{{ */ { /* find the next search result in the list of tasks * head - the first task in the task list * pos - the position in the task list to start searching from */ task *cur; cur = pos; while (1) { /* move to next item */ cur = cur->next; /* move to head if end of list is reached */ if (cur == NULL) { cur = head; selline = 0; tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "search wrapped"); statusbar_message(cfg.statusbar_timeout, "search wrapped to top"); } else selline++; /* check for match */ if (task_match(cur, searchstring)) return; /* stop if full loop was made */ if (cur==pos) break; } statusbar_message(cfg.statusbar_timeout, "no matches: %s", searchstring); return; } /* }}} */
void run_command_source(const char *filepath) /* {{{ */ { /* run the commands contained in a config file */ FILE *config = NULL; config = fopen(filepath, "r"); tnc_fprintf(logfp, LOG_DEBUG, "source: file \"%s\"", filepath); /* check for a valid fd */ if (config == NULL) { tnc_fprintf(logfp, LOG_ERROR, "source: file \"%s\" could not be opened", filepath); statusbar_message(cfg.statusbar_timeout, "source: file \"%s\" could not be opened", filepath); return; } /* read config file */ source_fp(config); /* close config file */ fclose(config); tnc_fprintf(logfp, LOG_DEBUG, "source complete: \"%s\"", filepath); statusbar_message(cfg.statusbar_timeout, "source complete: \"%s\"", filepath); } /* }}} */
void key_tasklist_filter(const char* arg) { /* {{{ */ /* handle a keyboard direction to add a new filter * arg - string to filter by (pass NULL to prompt user) * see the manual page for how filter strings are parsed */ check_free(active_filter); if (arg == NULL) { statusbar_getstr(&active_filter, "filter by: "); wipe_statusbar(); } else { active_filter = strdup(arg); } /* force reload of task list */ statusbar_message(cfg.statusbar_timeout, "filter applied"); reload = true; } /* }}} */
void key_tasklist_modify(const char* arg) { /* {{{ */ /* handle a keyboard direction to modify a task * arg - the modifications to apply (pass NULL to prompt user) * this will be appended to `task UUID modify ` */ char* argstr; if (arg == NULL) { statusbar_getstr(&argstr, "modify: "); wipe_statusbar(); } else { argstr = strdup(arg); } task_modify(argstr); free(argstr); statusbar_message(cfg.statusbar_timeout, "task modified"); redraw = true; } /* }}} */
void key_tasklist_toggle_started() /* {{{ */ { /* toggle whether a task is started */ bool started; time_t now; task *cur = get_task_by_position(selline); char *cmdstr, *action, *actionpast, *reply; FILE *cmdout; int ret; /* check whether task is started */ started = cur->start>0; /* generate command */ cmdstr = calloc(UUIDLENGTH+16, sizeof(char)); strcpy(cmdstr, "task "); strcat(cmdstr, cur->uuid); action = started ? " stop" : " start"; strcat(cmdstr, action); /* run command */ cmdout = popen(cmdstr, "r"); free(cmdstr); ret = pclose(cmdout); /* check return value */ if (WEXITSTATUS(ret)==0) { time(&now); cur->start = started ? 0 : now; actionpast = started ? "stopped" : "started"; asprintf(&reply, "task %s", actionpast); /* reset cached colors */ cur->pair = -1; cur->selpair = -1; } else asprintf(&reply, "task%s failed (%d)", action, WEXITSTATUS(ret)); statusbar_message(cfg.statusbar_timeout, reply); free(reply); } /* }}} */
void key_tasklist_edit() /* {{{ */ { /* edit selected task */ task *cur = get_task_by_position(selline); int ret; char *uuid; statusbar_message(cfg.statusbar_timeout, "editing task"); ret = task_interactive_command("task %s edit"); uuid = strdup(cur->uuid); reload_task(cur); if (cfg.follow_task) { set_position_by_uuid(uuid); tasklist_check_curs_pos(); } check_free(uuid); tasklist_command_message(ret, "edit failed (%d)", "edit succesful"); } /* }}} */
static gboolean snooper_loopkup_keyseq(GtkWidget *widget, Tbfwin *bfwin, GdkEventKey *kevent1, GdkEventKey *kevent2) { gchar *tmpstr, *r1, *r2; gchar *value; gboolean retval; r1 = snooper_parse_key(kevent1); if (kevent2) { r2 = snooper_parse_key(kevent2); tmpstr = g_strdup_printf("%s%s",r1,r2); g_free(r1); g_free(r2); }else{ tmpstr = r1; } SNOOPER(bfwin->snooper)->stat |= SNOOPER_HAS_EXCUTING_FUNC; retval = FALSE; value = g_hash_table_lookup(main_v->key_hashtable, tmpstr); if (value) { Tfunc *value_; value_ = g_hash_table_lookup(main_v->func_hashtable,value); if (value_) { if ( FUNC_VALID_TYPE( value_->data, widget ) ) { retval = TRUE; /* func_complete_hide(bfwin); *//* why must we do this :( */ FUNC(value_)->exec(widget, kevent1, bfwin, value_->data ); } } } DEBUG_MSG("snooper: lookup '%s' (full=%d), retval = %d\n", tmpstr, kevent2 != NULL, retval); if (retval) { tmpstr = g_strdup_printf("%s : %s", tmpstr, value); }else if (kevent2 != NULL) { tmpstr = g_strdup_printf(_("%s : unknown sequence"), tmpstr); } statusbar_message(bfwin, tmpstr,1500); g_free(tmpstr); return retval; }
void handle_resize() /* {{{ */ { /* handle a change in screen size */ int pagerheight; /* make sure rows and cols are set correctly */ rows = getmaxy(stdscr); cols = getmaxx(stdscr); /* resize windows */ wresize(header, 1, cols); wresize(tasklist, rows-2, cols); wresize(statusbar, 1, cols); /* move to proper positions */ mvwin(header, 0, 0); mvwin(tasklist, 1, 0); mvwin(statusbar, rows-1, 0); /* handle pager */ if (pager != NULL) { pagerheight = getmaxy(pager); if (pagerheight > rows-2) pagerheight = rows-2; wresize(pager, pagerheight, cols); mvwin(pager, rows-pagerheight-1, 0); } /* redraw windows */ tasklist_print_task_list(); print_header(); /* message about resize */ tnc_fprintf(logfp, LOG_DEBUG, "window resized to y=%d x=%d", rows, cols); statusbar_message(cfg.statusbar_timeout, "window resized to y=%d x=%d", rows, cols); } /* }}} */
void run_command_bind(char *args) /* {{{ */ { /** * create a new keybind * syntax - mode key function [funcarg] */ int key, ret = 0; char *function = NULL, *arg = NULL, *keystr = NULL, *modestr = NULL, *keyname = NULL; void (*func)(); funcmap *fmap; prog_mode mode; /* parse command */ if (args != NULL) ret = sscanf(args, "%ms %ms %ms %m[^\n]", &modestr, &keystr, &function, &arg); if (ret < 3) { statusbar_message(cfg.statusbar_timeout, "syntax: bind <mode> <key> <function> <args>"); tnc_fprintf(logfp, LOG_ERROR, "syntax: bind <mode> <key> <function> <args> [%d](%s)", ret, args); goto cleanup; } /* parse mode string */ if (str_eq(modestr, "tasklist")) mode = MODE_TASKLIST; else if (str_eq(modestr, "pager")) mode = MODE_PAGER; else { tnc_fprintf(logfp, LOG_ERROR, "bind: invalid mode (%s)", modestr); goto cleanup; } /* parse key */ key = parse_key(keystr); /* map function to function call */ fmap = find_function(function, mode); if (fmap==NULL) { tnc_fprintf(logfp, LOG_ERROR, "bind: invalid function specified (%s)", args); goto cleanup; } func = fmap->function; /* error out if there is no argument specified when required */ if (fmap->argn>0 && arg==NULL) { statusbar_message(cfg.statusbar_timeout, "bind: argument required for function %s", function); goto cleanup; } /* add keybind */ add_keybind(key, func, arg, mode); keyname = name_key(key); statusbar_message(cfg.statusbar_timeout, "key %s (%d) bound to %s - %s", keyname, key, modestr, name_function(func)); goto cleanup; cleanup: free(function); free(arg); free(keystr); free(modestr); free(keyname); return; } /* }}} */
void key_tasklist_scroll(const int direction) /* {{{ */ { /* handle a keyboard direction to scroll * direction - the direction to scroll in * u = up one * d = down one * h = to first element in list * e = to last element in list */ const char oldsel = selline; const char oldoffset = pageoffset; switch (direction) { case 'u': /* scroll one up */ if (selline>0) { selline--; if (selline<pageoffset) pageoffset--; } else statusbar_message(cfg.statusbar_timeout, "already at top"); break; case 'd': /* scroll one down */ if (selline<taskcount-1) { selline++; if (selline>=pageoffset+rows-2) pageoffset++; } else statusbar_message(cfg.statusbar_timeout, "already at bottom"); break; case 'h': /* go to first entry */ pageoffset = 0; selline = 0; break; case 'e': /* go to last entry */ if (taskcount>rows-2) pageoffset = taskcount-rows+2; selline = taskcount-1; break; default: statusbar_message(cfg.statusbar_timeout, "invalid scroll direction"); break; } if (pageoffset!=oldoffset) redraw = true; else { if (oldsel-selline == 1) tasklist_print_task(selline, NULL, 2); else if (selline-oldsel == 1) tasklist_print_task(oldsel, NULL, 2); else { tasklist_print_task(oldsel, NULL, 1); tasklist_print_task(selline, NULL, 1); } } print_header(); tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "selline:%d offset:%d tasks:%d", selline, pageoffset, taskcount); } /* }}} */
void key_tasklist_reload() /* {{{ */ { /* wrapper function to handle keyboard instruction to reload task list */ reload = true; statusbar_message(cfg.statusbar_timeout, "task list reloaded"); } /* }}} */
static gint main_snooper (GtkWidget *widget, GdkEventKey *kevent, Tbfwin *bfwin) { Tsnooper *snooper = SNOOPER(bfwin->snooper); /** check for valid snooper here **/ if ( ! (snooper->stat & SNOOPER_ACTIVE) ) { DEBUG_MSG("snooper: snooper on bfwin(%p) was disabled...\n", bfwin); return FALSE; } #ifdef DEBUG { gchar *tmpstr = stat_name(snooper->stat); DEBUG_MSG("snooper: stat(%s)press(%d,%d)length(%d)widget(%s)\n", tmpstr,(kevent->type == GDK_KEY_PRESS), kevent->keyval, kevent->length, gtk_widget_get_name(widget) ); g_free(tmpstr); } #endif if (kevent->type == GDK_KEY_PRESS) SNOOPER(bfwin->snooper)->last_event = (GdkEvent *)kevent; if ( kevent->type == GDK_KEY_RELEASE && ( snooper->stat & (SNOOPER_CANCEL_RELEASE_EVENT | SNOOPER_HAS_EXCUTING_FUNC ) ) ) { #ifdef DEBUG { gchar *tmpstr = stat_name(snooper->stat); DEBUG_MSG("snooper: exit as stat = %s\n", tmpstr); g_free(tmpstr); } #endif snooper->stat &= ~(SNOOPER_CANCEL_RELEASE_EVENT | SNOOPER_HAS_EXCUTING_FUNC); return TRUE; } /** special for completion **/ if ( SNOOPER_COMPLETION_ON(bfwin) ) { DEBUG_MSG("snooper: completion on bfwin = %p\n", bfwin); if ( SNOOPER_COMPLETION_MOVE(kevent->keyval) ) { func_complete_move(kevent, bfwin); snooper->stat |= SNOOPER_CANCEL_RELEASE_EVENT; return TRUE; }else if ( SNOOPER_COMPLETION_ACCEPT(kevent->keyval) ) { func_complete_do(bfwin); snooper->stat |= SNOOPER_CANCEL_RELEASE_EVENT; return TRUE; }else if ( SNOOPER_COMPLETION_ESCAPE(kevent->keyval) ) { func_complete_hide(bfwin); snooper->stat |= SNOOPER_CANCEL_RELEASE_EVENT; return TRUE; }else if ( SNOOPER_COMPLETION_DELETE(kevent->keyval) ) { func_complete_delete(widget, bfwin); snooper->stat |= SNOOPER_CANCEL_RELEASE_EVENT; return TRUE; }else if ( snooper->stat & ~SNOOPER_ACTIVE ) { DEBUG_MSG("snooper: completion shown and snooper->stat >0. hide stuff...\n"); func_complete_hide(bfwin); } } /** if completion is hidden **/ if (kevent->type == GDK_KEY_PRESS) { if ( ( snooper->stat & ~SNOOPER_ACTIVE ) && ( kevent->keyval == GDK_Escape ) ) { /* press Escape to cancel the key sequence ; */ snooper->stat = SNOOPER_ACTIVE | SNOOPER_CANCEL_RELEASE_EVENT; statusbar_message(bfwin , _("sequence cancelled"), 2000); return TRUE; }else if ( ( kevent->length || kevent->keyval == GDK_space) && ( ( snooper->stat & SNOOPER_HALF_SEQ ) || SNOOPER_IS_KEYSEQ(kevent) ) ) { DEBUG_MSG("snooper2: diff(time) = %d\n", kevent->time - ( (GdkEventKey*) snooper -> last_seq ) -> time ); if ( snooper->stat & SNOOPER_HALF_SEQ ) { snooper->stat &= ~SNOOPER_HALF_SEQ; snooper_loopkup_keyseq(widget, bfwin, (GdkEventKey*) snooper -> last_seq, kevent); return TRUE; } else { *( (GdkEventKey*) snooper->last_seq )= *kevent; if (snooper_loopkup_keyseq(widget, bfwin, kevent, NULL) ) { return TRUE; }else{ if (snooper_loopkup_keys_in_accel_map(kevent,bfwin)) { snooper->stat |= SNOOPER_HAS_EXCUTING_FUNC; return FALSE; }else{ snooper->stat |= SNOOPER_HALF_SEQ; return TRUE; } } } }else if (kevent->length) { DEBUG_MSG("snooper: not seq; reset stat = 0\n"); snooper->stat = SNOOPER_ACTIVE; return FALSE; } }else{/** key release **/ if ( snooper->stat & SNOOPER_HALF_SEQ ) { DEBUG_MSG("snooper: in the middle of sequence; release event cancelled\n"); return TRUE; } } return FALSE; }
void handle_command(char *cmdstr) /* {{{ */ { /* accept a command string, determine what action to take, and execute */ char *command, *args, *modestr, *pos; funcmap *fmap; prog_mode mode; int ret = 0; /* parse args */ pos = strchr(cmdstr, '\n'); if (pos != NULL) *pos = 0; tnc_fprintf(logfp, LOG_DEBUG, "command received: %s", cmdstr); if (cmdstr != NULL) ret = sscanf(cmdstr, "%ms %m[^\n]", &command, &args); if (ret < 1) { statusbar_message(cfg.statusbar_timeout, "failed to parse command"); tnc_fprintf(logfp, LOG_ERROR, "failed to parse command: [%d] (%s)", ret, cmdstr); return; } /* determine mode */ if (pager != NULL) { modestr = "pager"; mode = MODE_PAGER; } else if (tasklist != NULL) { modestr = "tasklist"; mode = MODE_TASKLIST; } else { modestr = "none"; mode = MODE_ANY; } /* log command */ tnc_fprintf(logfp, LOG_DEBUG_VERBOSE, "command: %s - %s (%s)", modestr, command, args); /* handle command & arguments */ /* try for exposed command */ fmap = find_function(command, mode); if (fmap!=NULL) { (fmap->function)(str_trim(args)); goto cleanup; } /* version: print version string */ if (str_eq(command, "version")) statusbar_message(cfg.statusbar_timeout, "%s %s by %s\n", PROGNAME, PROGVERSION, PROGAUTHOR); /* quit/exit: exit tasknc */ else if (str_eq(command, "quit") || str_eq(command, "exit")) done = true; /* reload: force reload of task list */ else if (str_eq(command, "reload")) { reload = true; statusbar_message(cfg.statusbar_timeout, "task list reloaded"); } /* redraw: force redraw of screen */ else if (str_eq(command, "redraw")) redraw = true; /* dump: write all displayed tasks to log file */ else if (str_eq(command, "dump")) { task *this = head; int counter = 0; while (this!=NULL) { tnc_fprintf(logfp, 0, "uuid: %s", this->uuid); tnc_fprintf(logfp, 0, "description: %s", this->description); tnc_fprintf(logfp, 0, "project: %s", this->project); tnc_fprintf(logfp, 0, "tags: %s", this->tags); this = this->next; counter++; } tnc_fprintf(logfp, 0, "dumped %d tasks", counter); } /* scrdump: do an ncurses scr_dump */ else if (str_eq(command, "scrdump")) { const char *dumppath = "nc_dump"; scr_dump(dumppath); tnc_fprintf(logfp, LOG_DEBUG, "ncurses dumped to '%s'", dumppath); } else { statusbar_message(cfg.statusbar_timeout, "error: command %s not found", command); tnc_fprintf(logfp, LOG_ERROR, "error: command %s not found", command); } goto cleanup; cleanup: /* clean up */ free(command); free(args); } /* }}} */
void run_command_set(char *args) /* {{{ */ { /** * set a variable in the statusbar * syntax: variable value */ var *this_var; char *message = NULL, *varname = NULL, *value = NULL; int ret = 0; /* parse args */ if (args != NULL) ret = sscanf(args, "%ms %m[^\n]", &varname, &value); if (ret != 2) { statusbar_message(cfg.statusbar_timeout, "syntax: set <variable> <value>"); tnc_fprintf(logfp, LOG_ERROR, "syntax: set <variable> <value> [%d](%s)", ret, args); goto cleanup; } /* find the variable */ this_var = (var *)find_var(varname); if (this_var==NULL) { statusbar_message(cfg.statusbar_timeout, "variable not found: %s", varname); goto cleanup; } /* check for permission */ if (this_var->perms == VAR_RO) { statusbar_message(cfg.statusbar_timeout, "variable is read only: %s", varname); goto cleanup; } if (this_var->perms == VAR_RC && tasklist != NULL) { statusbar_message(cfg.statusbar_timeout, "variable must be set in config: %s", varname); goto cleanup; } /* set the value */ switch (this_var->type) { case VAR_INT: ret = sscanf(value, "%d", (int *)this_var->ptr); break; case VAR_CHAR: ret = sscanf(value, "%c", (char *)this_var->ptr); break; case VAR_STR: if (*(char **)(this_var->ptr)!=NULL) free(*(char **)(this_var->ptr)); *(char **)(this_var->ptr) = calloc(strlen(value)+1, sizeof(char)); ret = NULL!=strcpy(*(char **)(this_var->ptr), value); if (ret) strip_quotes((char **)this_var->ptr, 1); break; default: ret = 0; break; } if (ret<=0) tnc_fprintf(logfp, LOG_ERROR, "failed to parse value from command: set %s %s", varname, value); /* acquire the value string and print it */ message = var_value_message(this_var, 1); statusbar_message(cfg.statusbar_timeout, message); cleanup: free(message); free(varname); free(value); return; } /* }}} */