示例#1
0
/*
 * Insert into "var", which currently has values "oldvarval", the "newline"
 * at position "insert".
 */
int
ccs_var_insert(struct pine *ps, char *newline, struct variable *var, char **oldvarval, int insert)
{
    int    count, i, offset;
    char **newl, ***alval;

    for(count = 0; oldvarval && oldvarval[count]; count++)
      ;

    if(insert < 0 || insert > count){
	q_status_message(SM_ORDER,3,5, "unexpected problem inserting folder");
	return(0);
    }

    newl = (char **)fs_get((count + 2) * sizeof(char *));
    newl[insert] = cpystr(newline);
    newl[count + 1]   = NULL;
    for(i = offset = 0; oldvarval && oldvarval[i]; i++){
	if(i == insert)
	  offset = 1;

	newl[i + offset] = cpystr(oldvarval[i]);
    }

    alval = ALVAL(var, ew);
    if(alval){
	free_list_array(alval);
	if(newl){
	    for(i = 0; newl[i] ; i++)	/* count elements */
	      ;

	    *alval = (char **) fs_get((i+1) * sizeof(char *));

	    for(i = 0; newl[i] ; i++)
	      (*alval)[i] = cpystr(newl[i]);

	    (*alval)[i]         = NULL;
	}
    }

    free_list_array(&newl);
    return(1);
}
示例#2
0
int
ccs_var_delete(struct pine *ps, CONTEXT_S *ctxt)
{
    int		count, i;
    char      **newl = NULL, **lval, **lp, ***alval;

    if(ctxt)
      lval = LVAL(ctxt->var.v, ew);
    else
      lval = NULL;

    for(count = 0; lval && lval[count]; count++)
      ;				/* sum the list */

    if(count > 1){
	newl = (char **) fs_get(count * sizeof(char *));
	for(i = 0, lp = newl; lval[i]; i++)
	  if(i != ctxt->var.i)
	    *lp++ = cpystr(lval[i]);

	*lp = NULL;
    }
    
    alval = ALVAL(ctxt->var.v, ew);
    if(alval){
	free_list_array(alval);
	if(newl){
	    for(i = 0; newl[i] ; i++)	/* count elements */
	      ;

	    *alval = (char **) fs_get((i+1) * sizeof(char *));

	    for(i = 0; newl[i] ; i++)
	      (*alval)[i] = cpystr(newl[i]);

	    (*alval)[i]         = NULL;
	}
    }

    free_list_array(&newl);
    return(1);
}
示例#3
0
int
incoming_monitoring_list_tool(struct pine *ps, int cmd, CONF_S **cl, unsigned int flags)
{
    int	        rv = 0;
    CONTEXT_S  *cntxt;
    char      **the_list;
    CONF_S     *ctmp;
    char     ***alval;
    OPT_SCREEN_S *saved_screen;

    if(cmd != MC_EXIT && fixed_var((*cl)->var, NULL, NULL))
      return(rv);

    switch(cmd){
      case MC_ADD:
      case MC_EDIT:
	cntxt = ps->context_list;
	if(!(cntxt && cntxt->use & CNTXT_INCMNG)){
	    q_status_message1(SM_ORDER, 3, 3, _("Turn on incoming folders with Config feature \"%s\""), pretty_feature_name(feature_list_name(F_ENABLE_INCOMING), -1));
	    return(rv);
	}

	saved_screen = opt_screen;

	the_list = adjust_list_of_monitored_incoming(cntxt, ew, V_INCCHECKLIST);

	/* adjust top if it might be necessary */
	for(ctmp = (*cl)->varnamep;
	    ctmp && ctmp->varnamep == (*cl)->varnamep;
	    ctmp = next_confline(ctmp))
	  if(ctmp == opt_screen->top_line)
	    opt_screen->top_line = (*cl)->varnamep;

	if(the_list){
	    alval = ALVAL((*cl)->var, ew);
	    free_list_array(alval);
	    if(!*the_list){
		q_status_message(SM_ORDER, 0, 3, _("Using default, monitor all incoming folders"));
		if(alval){
		    /*
		     * Remove config lines except for first one.
		     */
		    *cl = (*cl)->varnamep;
		    while((*cl)->next && (*cl)->next->varnamep == (*cl)->varnamep)
		      snip_confline(&(*cl)->next);
		}
	    }
	    else
	      config_add_list(ps, cl, the_list, NULL, 0);

	    /* only have to free the top-level pointer */
	    fs_give((void **) &the_list);
	    rv = 1;
	}
	else{
	    if(LVAL((*cl)->var, ew))
	      q_status_message(SM_ORDER, 0, 3, _("List is unchanged"));
	    else
	      q_status_message(SM_ORDER, 0, 3, _("Using default, monitor all incoming folders"));
	}

	opt_screen = saved_screen;
	ps->mangled_screen = 1;
        break;

      default:
	rv = text_tool(ps, cmd, cl, flags);
	/* if we deleted last one, reverts to default */
        if(cmd == MC_DELETE && rv == 1 && (*cl)->varmem == 0
	   && (!(*cl)->next || (*cl)->next->varnamep != (*cl)))
	  q_status_message(SM_ORDER, 0, 3, _("Using default, monitor all incoming folders"));

	break;
    }

    /*
     * This is just like the end of text_tool.
     */
    if(rv == 1){
	/*
	 * Now go and set the current_val based on user_val changes
	 * above.  Turn off command line settings...
	 */
	set_current_val((*cl)->var, TRUE, FALSE);
	fix_side_effects(ps, (*cl)->var, 0);

	if((*cl)->value)
	  fs_give((void **) &(*cl)->value);

	(*cl)->value = pretty_value(ps, *cl);

	exception_override_warning((*cl)->var);
    }

    return(rv);
}
示例#4
0
/*
 * Setup CollectionLists. Build a context list on the fly from the config
 * variable and edit it. This won't include Incoming-Folders because that
 * is a pseudo collection, but that's ok since we can't do the operations
 * on it, anyway. Reset real config list at the end.
 */
void
context_config_screen(struct pine *ps, CONT_SCR_S *cs, int edit_exceptions)
{
    CONTEXT_S    *top, **clist, *cp;
    CONF_S	 *ctmpa, *first_line, *heading;
    OPT_SCREEN_S  screen;
    int           i, readonly_warning, some_defined, ret;
    int           reinit_contexts = 0, prime;
    char        **lval, **lval1, **lval2, ***alval;
    struct variable fake_fspec_var, fake_nspec_var;
    struct variable *fake_fspec, *fake_nspec;

    ew = edit_exceptions ? ps_global->ew_for_except_vars : Main;

    if(ps->restricted)
      readonly_warning = 1;
    else{
	PINERC_S *prc = NULL;

	switch(ew){
	  case Main:
	    prc = ps->prc;
	    break;
	  case Post:
	    prc = ps->post_prc;
	    break;
	  default:
	    break;
	}

	readonly_warning = prc ? prc->readonly : 1;
	if(prc && prc->quit_to_edit){
	    quit_to_edit_msg(prc);
	    return;
	}
    }

go_again:
    top = NULL; ctmpa = NULL; first_line = NULL;
    some_defined = 0, prime = 0;
    fake_fspec = &fake_fspec_var;
    fake_nspec = &fake_nspec_var;
    memset((void *)fake_fspec, 0, sizeof(*fake_fspec));
    memset((void *)fake_nspec, 0, sizeof(*fake_nspec));

    /* so fixed_var() will work right */
    fake_fspec->is_list = 1;
    fake_nspec->is_list = 1;
    if((ps->vars[V_FOLDER_SPEC]).is_fixed){
	fake_fspec->is_fixed = 1;
	if((ps->vars[V_FOLDER_SPEC]).fixed_val.l
	   && (ps->vars[V_FOLDER_SPEC]).fixed_val.l[0]){
	    fake_fspec->fixed_val.l = (char **) fs_get(2 * sizeof(char *));
	    fake_fspec->fixed_val.l[0]
			    = cpystr((ps->vars[V_FOLDER_SPEC]).fixed_val.l[0]);
	    fake_fspec->fixed_val.l[1] = NULL;
	}
    }

    if((ps->vars[V_NEWS_SPEC]).is_fixed){
	fake_nspec->is_fixed = 1;
	if((ps->vars[V_NEWS_SPEC]).fixed_val.l
	   && (ps->vars[V_NEWS_SPEC]).fixed_val.l[0]){
	    fake_nspec->fixed_val.l = (char **) fs_get(2 * sizeof(char *));
	    fake_nspec->fixed_val.l[0] = cpystr(INHERIT);
	    fake_nspec->fixed_val.l[0]
			    = cpystr((ps->vars[V_NEWS_SPEC]).fixed_val.l[0]);
	    fake_nspec->fixed_val.l[1] = NULL;
	}
    }

    clist = &top;
    lval1 = LVAL(&ps->vars[V_FOLDER_SPEC], ew);
    lval2 = LVAL(&ps->vars[V_NEWS_SPEC], ew);

    alval = ALVAL(fake_fspec, ew);
    if(lval1)
      *alval = copy_list_array(lval1);
    else if(!edit_exceptions && ps->VAR_FOLDER_SPEC && ps->VAR_FOLDER_SPEC[0] &&
	    ps->VAR_FOLDER_SPEC[0][0])
      *alval = copy_list_array(ps->VAR_FOLDER_SPEC);
    else
      fake_fspec = NULL;

    if(fake_fspec){
	lval = LVAL(fake_fspec, ew);
	for(i = 0; lval && lval[i]; i++){
	    cp = NULL;
	    if(i == 0 && !strcmp(lval[i], INHERIT)){
		cp = (CONTEXT_S *)fs_get(sizeof(*cp));
		memset((void *)cp, 0, sizeof(*cp));
		cp->use = CNTXT_INHERIT;
		cp->label = cpystr("Default collections are inherited");
	    }
	    else if((cp = new_context(lval[i], &prime)) != NULL){
		cp->var.v = fake_fspec;
		cp->var.i = i;
	    }
	    
	    if(cp){
		*clist    = cp;			/* add it to list   */
		clist     = &cp->next;		/* prepare for next */
	    }
	}

	set_current_val(fake_fspec, FALSE, FALSE);
    }

    alval = ALVAL(fake_nspec, ew);
    if(lval2)
      *alval = copy_list_array(lval2);
    else if(!edit_exceptions && ps->VAR_NEWS_SPEC && ps->VAR_NEWS_SPEC[0] &&
	    ps->VAR_NEWS_SPEC[0][0])
      *alval = copy_list_array(ps->VAR_NEWS_SPEC);
    else
      fake_nspec = NULL;

    if(fake_nspec){
	lval = LVAL(fake_nspec, ew);
	for(i = 0; lval && lval[i]; i++){
	    cp = NULL;
	    if(i == 0 && !strcmp(lval[i], INHERIT)){
		cp = (CONTEXT_S *)fs_get(sizeof(*cp));
		memset((void *)cp, 0, sizeof(*cp));
		cp->use = CNTXT_INHERIT;
		cp->label = cpystr("Default collections are inherited");
	    }
	    else if((cp = new_context(lval[i], &prime)) != NULL){
		cp->var.v = fake_nspec;
		cp->var.i = i;
	    }
	    
	    if(cp){
		*clist    = cp;			/* add it to list   */
		clist     = &cp->next;		/* prepare for next */
	    }
	}

	set_current_val(fake_nspec, FALSE, FALSE);
    }
    
    for(cp = top; cp; cp = cp->next)
      if(!(cp->use & CNTXT_INHERIT)){
	  some_defined++;
	  break;
      }

    if(edit_exceptions && !some_defined){
	q_status_message(SM_ORDER, 3, 7,
 _("No exceptions to edit. First collection exception must be set by editing file"));
	free_contexts(&top);
	if(reinit_contexts){
	    free_contexts(&ps_global->context_list);
	    init_folders(ps_global);
	}

	return;
    }


    /* fix up prev pointers */
    for(cp = top; cp; cp = cp->next)
      if(cp->next)
	cp->next->prev = cp;

    new_confline(&ctmpa);		/* blank line */
    ctmpa->keymenu    = cs->keymenu;
    ctmpa->help       = cs->help.text;
    ctmpa->help_title = cs->help.title;
    ctmpa->tool       = context_config_tool;
    ctmpa->flags     |= (CF_NOSELECT | CF_B_LINE);

    for(cp = top; cp; cp = cp->next){
	new_confline(&ctmpa);
	heading		  = ctmpa;
	if(!(cp->use & CNTXT_INHERIT))
	  ctmpa->value	  = cpystr(cp->nickname ? cp->nickname : cp->context);

	ctmpa->var	  = cp->var.v;
	ctmpa->keymenu    = cs->keymenu;
	ctmpa->help       = cs->help.text;
	ctmpa->help_title = cs->help.title;
	ctmpa->tool       = context_config_tool;
	ctmpa->flags	 |= CF_STARTITEM;
	ctmpa->valoffset  = 4;
	ctmpa->d.c.ct     = cp;
	ctmpa->d.c.cs	  = cs;
	if(cp->use & CNTXT_INHERIT)
	  ctmpa->flags |= CF_INHERIT | CF_NOSELECT;

	if((!first_line && !(cp->use & CNTXT_INHERIT)) ||
	   (!(cp->use & CNTXT_INHERIT) &&
	    cp->var.v &&
	    (cs->starting_var == cp->var.v) &&
	    (cs->starting_varmem == cp->var.i)))
	  first_line = ctmpa;

	/* Add explanatory text */
	new_confline(&ctmpa);
	ctmpa->value	  = cpystr(cp->label ? cp->label : "* * *");
	ctmpa->keymenu	  = cs->keymenu;
	ctmpa->help	  = cs->help.text;
	ctmpa->help_title = cs->help.title;
	ctmpa->tool	  = context_config_tool;
	ctmpa->flags	 |= CF_NOSELECT;
	ctmpa->valoffset  = 8;

	/* Always add blank line, make's shuffling a little easier */
	new_confline(&ctmpa);
	heading->headingp  = ctmpa;		/* use headingp to mark end */
	ctmpa->keymenu	   = cs->keymenu;
	ctmpa->help	   = cs->help.text;
	ctmpa->help_title  = cs->help.title;
	ctmpa->tool	   = context_config_tool;
	ctmpa->flags	  |= CF_NOSELECT | CF_B_LINE;
	ctmpa->valoffset   = 0;
    }

    cs->starting_var = NULL;


    memset(&screen, 0, sizeof(screen));
    screen.ro_warning = readonly_warning;
    ret = conf_scroll_screen(ps, &screen, first_line, cs->title,
			     cs->print_string, 0);

    free_contexts(&top);
    
    if(ret)
      reinit_contexts++;

    /*
     * 15 means the tool wants us to reset and go again. The config var
     * has been changed. The contexts will be built again from the
     * config variable and the real contexts will be rebuilt below.
     * This is easier and safer than having the tools rebuild the context
     * list and the display correct. It's difficult to do because of all
     * the inheriting and defaulting going on.
     */
    if(ret == 15){
	if(edit_exceptions && !LVAL(fake_fspec, ew) && !LVAL(fake_nspec, ew)){
	    if(want_to(_("Really delete last exceptional collection"),
		       'n', 'n', h_config_context_del_except,
		       WT_FLUSH_IN) != 'y'){
		free_variable_values(fake_fspec);
		free_variable_values(fake_nspec);
		goto go_again;
	    }
	}

	/* resolve variable changes */
	if((lval1 && !equal_list_arrays(lval1, LVAL(fake_fspec, ew))) ||
	   (fake_fspec && !equal_list_arrays(ps->VAR_FOLDER_SPEC,
					     LVAL(fake_fspec, ew)))){
	    i = set_variable_list(V_FOLDER_SPEC,
				  LVAL(fake_fspec, ew), TRUE, ew);
	    set_current_val(&ps->vars[V_FOLDER_SPEC], TRUE, FALSE);

	    if(i)
	      q_status_message(SM_ORDER, 3, 3,
			       _("Trouble saving change, cancelled"));
	    else if(!edit_exceptions && lval1 && !LVAL(fake_fspec, ew)){
		cs->starting_var = fake_fspec;
		cs->starting_varmem = 0;
		q_status_message(SM_ORDER, 3, 3,
		       _("Deleted last Folder-Collection, reverting to default"));
	    }
	    else if(!edit_exceptions && !lval1 && !LVAL(fake_fspec, ew)){
		cs->starting_var = fake_fspec;
		cs->starting_varmem = 0;
		q_status_message(SM_ORDER, 3, 3,
	       _("Deleted default Folder-Collection, reverting back to default"));
	    }
	}

	if((lval2 && !equal_list_arrays(lval2, LVAL(fake_nspec, ew))) ||
	   (fake_nspec && !equal_list_arrays(ps->VAR_NEWS_SPEC,
					     LVAL(fake_nspec, ew)))){
	    i = set_variable_list(V_NEWS_SPEC,
				  LVAL(fake_nspec, ew), TRUE, ew);
	    set_news_spec_current_val(TRUE, FALSE);

	    if(i)
	      q_status_message(SM_ORDER, 3, 3,
			       _("Trouble saving change, cancelled"));
	    else if(!edit_exceptions && lval2 && !LVAL(fake_nspec, ew) &&
		    ps->VAR_NEWS_SPEC && ps->VAR_NEWS_SPEC[0] &&
		    ps->VAR_NEWS_SPEC[0][0]){
		cs->starting_var = fake_nspec;
		cs->starting_varmem = 0;
		q_status_message(SM_ORDER, 3, 3,
		       _("Deleted last News-Collection, reverting to default"));
	    }
	    else if(!edit_exceptions && !lval2 && !LVAL(fake_nspec, ew) &&
		    ps->VAR_NEWS_SPEC && ps->VAR_NEWS_SPEC[0] &&
		    ps->VAR_NEWS_SPEC[0][0]){
		cs->starting_var = fake_nspec;
		cs->starting_varmem = 0;
	        q_status_message(SM_ORDER, 3, 3,
	         _("Deleted default News-Collection, reverting back to default"));
	    }
	}

	free_variable_values(fake_fspec);
	free_variable_values(fake_nspec);
	goto go_again;
    }

    ps->mangled_screen = 1;

    /* make the real context list match the changed config variables */
    if(reinit_contexts){
	free_contexts(&ps_global->context_list);
	init_folders(ps_global);
    }
}
示例#5
0
/*----------------------------------------------------------------------
   Function to control flag set/clearing

   Basically, turn the flags into a fake list of features...

   Returns 0 unless user has added a keyword, then 1.

 ----*/
int
flag_maintenance_screen(struct pine *ps, struct flag_screen *flags)
{
    int		  i, lv, lc, maxwidth, offset, need, rv = 0;
    char	  tmp[1200], **p, *spacer;
    CONF_S	 *ctmpa, *first_line;
    struct	  flag_table  *fp;
    OPT_SCREEN_S  screen;

try_again:
    maxwidth = MAX(MIN((ps->ttyo ? ps->ttyo->screen_cols : 80), 150), 30);
    first_line = NULL;
    ctmpa = NULL;

    for(p = flags->explanation; p && *p; p++) {
        new_confline(&ctmpa);
        ctmpa->keymenu   = &flag_keymenu;
        ctmpa->help      = NO_HELP;
        ctmpa->tool      = flag_checkbox_tool;
        ctmpa->flags    |= CF_NOSELECT;
        ctmpa->valoffset = 0;
        ctmpa->value     = cpystr(_(*p));
    }

    /* Now wire flags checkboxes together */
    for(lv = 0, lc = 0, fp = (flags->flag_table ? *flags->flag_table : NULL);
            fp && fp->name; fp++) {	/* longest name */
        if(fp->flag != F_COMMENT) {
            if(lv < (i = utf8_width(_(fp->name))))
                lv = i;
            if(fp->comment && lc < (i = utf8_width(fp->comment)))
                lc = i;
        }
    }

    lv = MIN(lv,100);
    lc = MIN(lc,100);
    if(lc > 0)
        spacer = "    ";
    else
        spacer = "";

    offset = 6;
    if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
        offset -= (need - maxwidth);
        offset = MAX(0,offset);
        if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
            spacer = " ";
            if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
                lc -= (need - maxwidth);
                lc = MAX(0,lc);
                if(lc == 0)
                    spacer = "";
            }
        }
    }

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    ctmpa->value     = cpystr("");

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    utf8_snprintf(tmp, sizeof(tmp), "%*.*w  %s", offset+3, offset+3, _("Set"), _("Flag/Keyword Name"));
    tmp[sizeof(tmp)-1] = '\0';
    ctmpa->value = cpystr(tmp);

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    snprintf(tmp, sizeof(tmp), "%*.*s---  %.*s",
             offset, offset, "",
             lv+lc+strlen(spacer), repeat_char(lv+lc+strlen(spacer), '-'));
    tmp[sizeof(tmp)-1] = '\0';
    ctmpa->value = cpystr(tmp);

    for(fp = (flags->flag_table ? *flags->flag_table : NULL);
            fp && fp->name; fp++) {	/* build the list */
        new_confline(&ctmpa);
        if(!first_line && (fp->flag != F_COMMENT))
            first_line = ctmpa;

        ctmpa->keymenu   = &flag_keymenu;
        ctmpa->tool      = flag_checkbox_tool;
        ctmpa->valoffset = offset;

        if(fp->flag == F_COMMENT) {
            ctmpa->help   = NO_HELP;
            ctmpa->flags |= CF_NOSELECT;
            ctmpa->value  = cpystr(fp->name);
        }
        else {
            ctmpa->help		  = fp->help;
            ctmpa->d.f.ftbl	  = flags->flag_table;
            ctmpa->d.f.fp	  = fp;

            utf8_snprintf(tmp, sizeof(tmp), "[%c]  %-*.*w%s%-*.*w",
                          (fp->set == 0) ? ' ' : (fp->set == 1) ? 'X' : '?',
                          lv, lv, _(fp->name),
                          spacer, lc, lc, fp->comment ? fp->comment : "");
            ctmpa->value = cpystr(tmp);
        }
    }

    memset(&screen, 0, sizeof(screen));
    /*
     * TRANSLATORS: FLAG MAINTENANCE is a screen title.
     * Print something1 using something2.  configuration is something1
     */
    if(conf_scroll_screen(ps, &screen, first_line,
                          _("FLAG MAINTENANCE"),
                          _("configuration"), 0) == FLAG_ADD_RETURN) {
        int flags, r;
        char keyword[500];
        char nickname[500];
        char prompt[500];
        char *error = NULL;
        KEYWORD_S *kw;
        HelpType help;

        /*
         * User is asking to add a new keyword. We will add it to the
         * mailbox if necessary and add it to the keywords list from
         * Setup/Config. Then we will modify the flag_table and present
         * the flag modification screen again.
         */

        ps->mangled_screen = 1;
        keyword[0] = '\0';
        flags = OE_APPEND_CURRENT;
        help = NO_HELP;

        do {
            if(error) {
                q_status_message(SM_ORDER, 3, 4, error);
                fs_give((void **) &error);
            }

            strncpy(prompt, _("Keyword to be added : "), sizeof(prompt)-1);
            prompt[sizeof(prompt)-1] = '\0';
            r = optionally_enter(keyword, -FOOTER_ROWS(ps_global), 0,
                                 sizeof(keyword), prompt, NULL, help, &flags);

            if(r == 3)
                help = help == NO_HELP ? h_type_keyword : NO_HELP;
            else if(r == 1) {
                cmd_cancelled("Add Keyword");
                goto try_again;
            }

            removing_leading_and_trailing_white_space(keyword);

        } while(r == 3 || keyword_check(keyword, &error));

        for(kw = ps->keywords; kw; kw = kw->next) {
            if(kw->kw && !strucmp(kw->kw, keyword)) {
                q_status_message(SM_ORDER, 3, 4, _("Keyword already configured, changing nickname"));
                break;
            }
        }

        snprintf(prompt, sizeof(prompt), _("Optional nickname for \"%s\" : "), keyword);

        nickname[0] = '\0';
        help = NO_HELP;

        do {
            r = optionally_enter(nickname, -FOOTER_ROWS(ps_global), 0,
                                 sizeof(nickname), prompt, NULL, help, &flags);

            if(r == 3)
                help = help == NO_HELP ? h_type_keyword_nickname : NO_HELP;
            else if(r == 1) {
                cmd_cancelled("Add Keyword");
                goto try_again;
            }

            removing_leading_and_trailing_white_space(nickname);

        } while(r == 3);

        if(keyword[0]) {
            char ***alval;
            int offset = -1;
            struct variable *var;

            var = &ps_global->vars[V_KEYWORDS];
            alval = ALVAL(var, Main);

            for(kw = ps->keywords; kw; kw = kw->next) {
                offset++;
                if(kw->kw && !strucmp(kw->kw, keyword)) {
                    /* looks like it should already exist at offset */
                    break;
                }
            }

            if(!kw)
                offset = -1;

            if(offset >= 0 && (*alval) && (*alval)[offset]) {
                fs_give((void **) &(*alval)[offset]);
                (*alval)[offset] = put_pair(nickname, keyword);
            }
            else if(!*alval) {
                offset = 0;
                *alval = (char **) fs_get(2*sizeof(char *));
                (*alval)[offset] = put_pair(nickname, keyword);
                (*alval)[offset+1] = NULL;
            }
            else {
                for(offset=0; (*alval)[offset]; offset++);
                ;

                fs_resize((void **) alval, (offset + 2) * sizeof(char *));
                (*alval)[offset] = put_pair(nickname, keyword);
                (*alval)[offset+1] = NULL;
            }

            set_current_val(var, TRUE, FALSE);
            if(ps_global->prc)
                ps_global->prc->outstanding_pinerc_changes = 1;

            if(ps_global->keywords)
                free_keyword_list(&ps_global->keywords);

            if(var->current_val.l && var->current_val.l[0])
                ps_global->keywords = init_keyword_list(var->current_val.l);

            clear_index_cache(ps_global->mail_stream, 0);

            rv = 1;
        }
    }

    ps->mangled_screen = 1;

    return(rv);
}
示例#6
0
/*
 * Compare saved user_val with current user_val to see if it changed.
 * If any have changed, change it back and take the appropriate action.
 */
void
revert_to_saved_smime_config(struct pine *ps, SAVED_CONFIG_S *vsave)
{
    struct variable *vreal;
    SAVED_CONFIG_S  *v;
    int i, n;
    int changed = 0;
    char *pval, **apval, **lval, ***alval;

    v = vsave;
    for(vreal = ps->vars; vreal->name; vreal++,v++){
	if(!(smime_related_var(ps, vreal) || vreal==&ps->vars[V_FEATURE_LIST]))
	  continue;

	if(vreal->is_list){
	    lval  = LVAL(vreal, ew);
	    alval = ALVAL(vreal, ew);

	    if((v->saved_user_val.l && !lval)
	       || (!v->saved_user_val.l && lval))
	      changed++;
	    else if(!v->saved_user_val.l && !lval)
	      ;/* no change, nothing to do */
	    else
	      for(i = 0; v->saved_user_val.l[i] || lval[i]; i++)
		if((v->saved_user_val.l[i]
		      && (!lval[i]
			 || strcmp(v->saved_user_val.l[i], lval[i])))
		   ||
		     (!v->saved_user_val.l[i] && lval[i])){
		    changed++;
		    break;
		}
	    
	    if(changed){
		char  **list;

		if(alval){
		    if(*alval)
		      free_list_array(alval);
		
		    /* copy back the original one */
		    if(v->saved_user_val.l){
			list = v->saved_user_val.l;
			n = 0;
			/* count how many */
			while(list[n])
			  n++;

			*alval = (char **)fs_get((n+1) * sizeof(char *));

			for(i = 0; i < n; i++)
			  (*alval)[i] = cpystr(v->saved_user_val.l[i]);

			(*alval)[n] = NULL;
		    }
		}
	    }
	}
	else{
	    pval  = PVAL(vreal, ew);
	    apval = APVAL(vreal, ew);

	    if((v->saved_user_val.p &&
	        (!pval || strcmp(v->saved_user_val.p, pval))) ||
	       (!v->saved_user_val.p && pval)){
		/* It changed, fix it */
		changed++;
		if(apval){
		    /* free the changed value */
		    if(*apval)
		      fs_give((void **)apval);

		    if(v->saved_user_val.p)
		      *apval = cpystr(v->saved_user_val.p);
		}
	    }
	}

	if(changed){
	    if(vreal == &ps->vars[V_FEATURE_LIST])
	      set_feature_list_current_val(vreal);
	    else
	      set_current_val(vreal, TRUE, FALSE);

	    fix_side_effects(ps, vreal, 1);
	}
    }
}