Beispiel #1
0
char *
ldap_translate(char *a, LDAP_SERV_S *info_used)
{
    int i;

    if(info_used){
	if(info_used->mailattr && strucmp(info_used->mailattr, a) == 0)
	  return(_(ldap_trans_table[LDAP_MAIL_ATTR].translated));
	else if(info_used->snattr && strucmp(info_used->snattr, a) == 0)
	  return(_(ldap_trans_table[LDAP_SN_ATTR].translated));
	else if(info_used->gnattr && strucmp(info_used->gnattr, a) == 0)
	  return(_(ldap_trans_table[LDAP_GN_ATTR].translated));
	else if(info_used->cnattr && strucmp(info_used->cnattr, a) == 0)
	  return(_(ldap_trans_table[LDAP_CN_ATTR].translated));
    }

    for(i = 0; ldap_trans_table[i].ldap_ese; i++){
	if(info_used)
	  switch(i){
	    case LDAP_MAIL_ATTR:
	    case LDAP_SN_ATTR:
	    case LDAP_GN_ATTR:
	    case LDAP_CN_ATTR:
	    case LDAP_EMAIL_ATTR:
	      continue;
	  }

	if(strucmp(ldap_trans_table[i].ldap_ese, a) == 0)
	  return(_(ldap_trans_table[i].translated));
    }
    
    return(a);
}
Beispiel #2
0
int
df_valid_test(struct mail_bodystruct *body, char *test)
{
    int passed = 0;

    if(!(passed = !test)){			/* NO test always wins */
	if(!*test){
	    passed++;				/* NULL test also wins! */
	}
	else if(body && !struncmp(test, "_CHARSET(", 9)){
	    char *p = strrindex(test, ')');

	    if(p){
		*p = '\0';			/* tie off user charset */
		if((p = parameter_val(body->parameter,"charset")) != NULL){
		    passed = !strucmp(test + 9, p);
		    fs_give((void **) &p);
		}
		else
		  passed = !strucmp(test + 9, "us-ascii");
	    }
	    else
	      dprint((1,
			 "filter trigger: malformed test: %s\n",
			 test ? test : "?"));
	}
    }

    return(passed);
}
Beispiel #3
0
/* -------------------------------------------------------------------
     Set up the keyboard -- usually enable some function keys  (UNIX)

    Args: struct pine 

So far all we do here is turn on keypad mode for certain terminals

Hack for NCSA telnet on an IBM PC to put the keypad in the right mode.
This is the same for a vtXXX terminal or [zh][12]9's which we have 
a lot of at UW
  ----*/
void
init_keyboard(int use_fkeys)
{
    if(use_fkeys && (!strucmp(term_name,"vt102")
		     || !strucmp(term_name,"vt100")))
      printf("\033\133\071\071\150");
}
Beispiel #4
0
/*----------------------------------------------------------------------
    Actually set up the tty driver                             (UNIX)

   Args: state -- which state to put it in. 1 means go into raw, 0 out of

  Result: returns 0 if successful and < 0 if not.
  ----*/
int
PineRaw(int state)
{
    int result;

    result = Raw(state);
    
    if(result == 0 && state == 1){
	/*
	 * Only go into 8 bit mode if we are doing something other
	 * than plain ASCII. This will save the folks that have
	 * their parity on their serial lines wrong the trouble of
	 * getting it right
	 */
        if((ps_global->keyboard_charmap && ps_global->keyboard_charmap[0] &&
	   strucmp(ps_global->keyboard_charmap, "us-ascii"))
	   || (ps_global->display_charmap && ps_global->display_charmap[0] &&
	       strucmp(ps_global->display_charmap, "us-ascii")))
	  bit_strip_off();

#ifdef	DEBUG
	if(debug < 9)			/* only on if full debugging set */
#endif
	quit_char_off();
	ps_global->low_speed = ttisslow();
	crlf_proc(0);
	xonxoff_proc(F_ON(F_PRESERVE_START_STOP, ps_global));
    }

    return(result);
}
Beispiel #5
0
/*----------------------------------------------------------------------
    Check to see if user is allowed to read or write this folder.

   Args:  s  -- the name to check
 
 Result: Returns 1 if OK
         Returns 0 and posts an error message if access is denied
  ----*/
int
context_allowed(char *s)
{
    struct variable *vars = ps_global ? ps_global->vars : NULL;
    int retval = 1;
    MAILSTREAM stream; /* fake stream for error message in mm_notify */

    if(ps_global
       && ps_global->restricted
       && (strindex("./~", s[0]) || srchstr(s, "/../"))){
	stream.mailbox = s;
	mm_notify(&stream, "Restricted mode doesn't allow operation", WARN);
	retval = 0;
    }
    else if(vars && VAR_OPER_DIR
	    && s[0] != '{' && !(s[0] == '*' && s[1] == '{')
	    && strucmp(s,ps_global->inbox_name) != 0
	    && strcmp(s, ps_global->VAR_INBOX_PATH) != 0){
	char *p, *free_this = NULL;

	p = s;
	if(strindex(s, '~')){
	    p = strindex(s, '~');
	    free_this = (char *)fs_get(strlen(p) + 200);
	    strncpy(free_this, p, strlen(p)+200);
	    fnexpand(free_this, strlen(p)+200);
	    p = free_this;
	}
	else if(p[0] != '/'){  /* add home dir to relative paths */
	    free_this = p = (char *)fs_get(strlen(s)
					    + strlen(ps_global->home_dir) + 2);
	    build_path(p, ps_global->home_dir, s,
		       strlen(s)+strlen(ps_global->home_dir)+2);
	}
	
	if(!in_dir(VAR_OPER_DIR, p)){
	    char err[200];

	    /* TRANSLATORS: User is restricted to operating within a certain directory */
	    snprintf(err, sizeof(err), _("Not allowed outside of %.150s"), VAR_OPER_DIR);
	    stream.mailbox = p;
	    mm_notify(&stream, err, WARN);
	    retval = 0;
	}
	else if(srchstr(p, "/../")){  /* check for .. in path */
	    stream.mailbox = p;
	    mm_notify(&stream, "\"..\" not allowed in name", WARN);
	    retval = 0;
	}

	if(free_this)
	  fs_give((void **)&free_this);
    }
    
    return retval;
}
Beispiel #6
0
/*----------------------------------------------------------------------
      handle hang up signal -- SIGUSR2

Not much to do. Rely on periodic mail file check pointing.
  ----------------------------------------------------------------------*/
static RETSIGTYPE
usr2_signal(int sig)
{
    char        c, *mbox, mboxbuf[20];
    int         i;
    MAILSTREAM *stream;
    NETMBX      mb;

    for(i = 0; i < ps_global->s_pool.nstream; i++) {
        stream = ps_global->s_pool.streams[i];
        if(stream
                && sp_flagged(stream, SP_LOCKED)
                && !sp_dead_stream(stream)
                && !stream->lock
                && !stream->rdonly
                && stream->mailbox
                && (c = *stream->mailbox) != '{' && c != '*') {
            pine_mail_check(stream);		/* write latest state   */
            stream->rdonly = 1;			/* and become read-only */
            (void) pine_mail_ping(stream);
            mbox = stream->mailbox;
            if(!strucmp(stream->mailbox, ps_global->inbox_name)
                    || !strcmp(stream->mailbox, ps_global->VAR_INBOX_PATH)
                    || !strucmp(stream->original_mailbox, ps_global->inbox_name)
                    || !strcmp(stream->original_mailbox, ps_global->VAR_INBOX_PATH))
                mbox = "INBOX";
            else if(mail_valid_net_parse(stream->mailbox, &mb) && mb.mailbox)
                mbox = mb.mailbox;

            q_status_message1(SM_ASYNC, 3, 7,
                              _("Another email program is accessing %s. Session now Read-Only."),
                              short_str((mbox && *mbox) ? mbox : "folder",
                                        mboxbuf, sizeof(mboxbuf), 19, FrontDots));
            dprint((1, "** folder %s went read-only **\n\n",
                    stream->mailbox));
        }
    }
}
Beispiel #7
0
/*
 * Returns the bit position of the keyword in stream, else -1.
 */
int
user_flag_index(MAILSTREAM *stream, char *keyword)
{
    int i, retval = -1;
    char *p;

    if(stream && keyword && keyword[0]){
	for(i = 0; i < NUSERFLAGS; i++)
	  if((p=stream_to_user_flag_name(stream, i)) && !strucmp(keyword, p)){
	      retval = i;
	      break;
	  }
    }

    return(retval);
}
Beispiel #8
0
/*
 * Check whether the pattern "pat" matches this type/subtype.
 * Returns 1 if it does, 0 if not.
 */
int
mc_ctype_match(int type, char *subtype, char *pat)
{
    char *type_name = body_type_names(type);
    int   len = strlen(type_name);

    dprint((5, "mc_ctype_match: %s == %s / %s ?\n",
	       pat ? pat : "?",
	       type_name ? type_name : "?",
	       subtype ? subtype : "?"));

    return(!struncmp(type_name, pat, len)
	   && ((pat[len] == '/'
		&& (!pat[len+1] || pat[len+1] == '*'
		    || !strucmp(subtype, &pat[len+1])))
	       || !pat[len]));
}
Beispiel #9
0
/*
 * Return the command based on either the mimetype or the file
 * extension.  Mime-type always takes precedence.
 *
 *   mime_type - mime-type of the file we're looking at
 *   mime_ext  - file extension given us by the mime data
 *   cmd       - buffer to copy the resulting command into
 *   chk       - whether or not we should check the file extension
 *
 *   Returns: 1 on success, 0 on failure
 */
int
mime_get_os_mimetype_command(char *mime_type, char *mime_ext, char *cmd,
			     int clen, int chk, int *sp_hndlp)
{
#ifdef	_WINDOWS
    int ret;
    LPTSTR mime_type_lpt, mime_ext_lpt;

    mime_type_lpt = utf8_to_lptstr(mime_type);
    mime_ext_lpt = utf8_to_lptstr(mime_ext);

    ret = mswin_reg_viewer(mime_type_lpt, mime_ext_lpt, cmd, clen, chk);

    if(mime_type_lpt)
      fs_give((void **) &mime_type_lpt);

    if(mime_ext_lpt)
      fs_give((void **) &mime_ext_lpt);

    return ret;

#elif	OSX_TARGET

    /* 
     * if we wanted to be more like PC-Pine, we'd try checking
     * the mime-type of mime_ext and seeing if that matches
     * with our mime-type, which is safe for opening
     */
    if(!mime_os_specific_access())
      return(0);

    /* don't want to use Mail or something for a part alpine is good at */
    if(!strucmp(mime_type, "message/rfc822"))
      return(0);

    return(osx_build_mime_type_cmd(mime_type, cmd, clen, sp_hndlp)
	   || (chk && mime_ext && *mime_ext &&
	       osx_build_mime_ext_cmd(mime_ext, cmd, clen, sp_hndlp)));
#else
    return 0;
#endif
}
Beispiel #10
0
int
rfc2231_list_params(PARMLIST_S *plist)
{
    PARAMETER *pp, **ppp;
    int	       i;

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

    for(pp = plist->list; pp; pp = pp->next){
      /* get a name */
      for(i = 0; i < 32; i++)
	if(!(plist->attrib[i] = pp->attribute[i]) ||  pp->attribute[i] == '*'){
	    plist->attrib[i] = '\0';

	    for(ppp = &plist->seen;
		*ppp && strucmp((*ppp)->attribute, plist->attrib);
		ppp = &(*ppp)->next)
	      ;

	    if(!*ppp){
		plist->list = pp->next;
		*ppp = mail_newbody_parameter();	/* add to seen list */
		(*ppp)->attribute = cpystr(plist->attrib);
		plist->value = parameter_val(pp,plist->attrib);
		return(TRUE);
	    }

	    break;
	}

      if(i >= 32)
	q_status_message1(SM_ORDER | SM_DING, 0, 3,
		       "Overly long attachment parameter ignored: %.25s...",
			  pp->attribute);
    }


    return(FALSE);
}
Beispiel #11
0
/*----------------------------------------------------------------------
  Read input characters with lots of processing for arrow keys and such  (UNIX)

 Args:  time_out -- The timeout to for the reads 

 Result: returns the character read. Possible special chars.

    This deals with function and arrow keys as well. 

  The idea is that this routine handles all escape codes so it done in
  only one place. Especially so the back arrow key can work when entering
  things on a line. Also so all function keys can be disabled and not
  cause weird things to happen.
  ---*/
UCS
read_char(int time_out)
{
    UCS status, cc, ch;
    int (*key_rec)(int);

    key_rec = key_recorder;
    if(ps_global->conceal_sensitive_debugging)
      key_rec = NULL;

    /* Get input from initial-keystrokes */
    if(process_config_input(&cc)){
	ch = cc;
	return(ch);
    }

    if((ch = check_for_timeout(time_out)) != READY_TO_READ)
      goto done;
    
    switch(status = kbseq(pine_simple_ttgetc, key_rec, read_bail,
			  ps_global->input_cs, &ch)){
      case KEY_DOUBLE_ESC:
	/*
	 * Special hack to get around comm devices eating control characters.
	 */
	if(check_for_timeout(5) != READY_TO_READ){
	    dprint((9, "Read char: incomplete double escape timed out...\n"));
	    ch = KEY_JUNK;		/* user typed ESC ESC, then stopped */
	    goto done;
	}
	else
	  ch = READ_A_CHAR();

	ch &= 0x7f;

	/* We allow a 3-digit number between 001 and 255 */
	if(isdigit((unsigned char) ch)){
	    int n = 0, i = ch - '0';

	    if(i < 0 || i > 2){
		dprint((9, "Read char: double escape followed by 1st digit not 0, 1, or 2... (%d)\n", i));
		ch = KEY_JUNK;
		goto done;		/* bogus literal char value */
	    }

	    while(n++ < 2){
		if(check_for_timeout(5) != READY_TO_READ
		   || (!isdigit((unsigned char) (ch = READ_A_CHAR()))
		       || (n == 1 && i == 2 && ch > '5')
		       || (n == 2 && i == 25 && ch > '5'))){
		    dprint((9, "Read char: bad double escape, either timed out or too large 3-digit num...\n"));
		    ch = KEY_JUNK;	/* user typed ESC ESC #, stopped */
		    goto done;
		}

		i = (i * 10) + (ch - '0');
	    }

	    ch = i;
	}
	else{	/* or, normal case, ESC ESC c  means ^c */
	    if(islower((unsigned char) ch))	/* canonicalize if alpha */
	      ch = toupper((unsigned char) ch);

	    ch = (isalpha((unsigned char)ch) || ch == '@'
		  || (ch >= '[' && ch <= '_'))
		   ? ctrl(ch) : ((ch == SPACE) ? ctrl('@'): ch);
	    dprint((9, "Read char: this is a successful double escape...\n"));
	}

	goto done;

#ifdef MOUSE
      case KEY_XTERM_MOUSE:
	if(mouseexist()){
	    /*
	     * Special hack to get mouse events from an xterm.
	     * Get the details, then pass it past the keymenu event
	     * handler, and then to the installed handler if there
	     * is one...
	     */
	    static int    down = 0;
	    int           x, y, button;
	    unsigned long cmd;

	    clear_cursor_pos();
	    button = READ_A_CHAR() & 0x03;

	    x = READ_A_CHAR() - '!';
	    y = READ_A_CHAR() - '!';

	    ch = NO_OP_COMMAND;
	    if(button == 0){		/* xterm button 1 down */
		down = 1;
		if(checkmouse(&cmd, 1, x, y))
		  ch = cmd;
	    }
	    else if (down && button == 3){
		down = 0;
		if(checkmouse(&cmd, 0, x, y))
		  ch = cmd;
	    }

	    goto done;
	}

	break;
#endif /* MOUSE */

      case  KEY_UP	:
      case  KEY_DOWN	:
      case  KEY_RIGHT	:
      case  KEY_LEFT	:
      case  KEY_PGUP	:
      case  KEY_PGDN	:
      case  KEY_HOME	:
      case  KEY_END	:
      case  KEY_DEL	:
      case  PF1		:
      case  PF2		:
      case  PF3		:
      case  PF4		:
      case  PF5		:
      case  PF6		:
      case  PF7		:
      case  PF8		:
      case  PF9		:
      case  PF10	:
      case  PF11	:
      case  PF12	:
        dprint((9, "Read char returning: 0x%x %s\n", status, pretty_command(status)));
	return(status);

      case  CTRL_KEY_UP	:
	status = KEY_UP;
        dprint((9, "Read char returning: 0x%x %s (for CTRL_KEY_UP)\n", status, pretty_command(status)));
	return(status);

      case  CTRL_KEY_DOWN	:
	status = KEY_DOWN;
        dprint((9, "Read char returning: 0x%x %s (for CTRL_KEY_DOWN)\n", status, pretty_command(status)));
	return(status);

      case  CTRL_KEY_RIGHT	:
	status = KEY_RIGHT;
        dprint((9, "Read char returning: 0x%x %s (for CTRL_KEY_RIGHT)\n", status, pretty_command(status)));
	return(status);

      case  CTRL_KEY_LEFT	:
	status = KEY_LEFT;
        dprint((9, "Read char returning: 0x%x %s (for CTRL_KEY_LEFT)\n", status, pretty_command(status)));
	return(status);

      case KEY_SWALLOW_Z:
	status = KEY_JUNK;
      case KEY_SWAL_UP:
      case KEY_SWAL_DOWN:
      case KEY_SWAL_LEFT:
      case KEY_SWAL_RIGHT:
	do
	  if(check_for_timeout(2) != READY_TO_READ){
	      status = KEY_JUNK;
	      break;
	  }
	while(!strchr("~qz", READ_A_CHAR()));
	ch = (status == KEY_JUNK) ? status : status - (KEY_SWAL_UP - KEY_UP);
	goto done;

      case KEY_KERMIT:
	do{
	    cc = ch;
	    if(check_for_timeout(2) != READY_TO_READ){
		status = KEY_JUNK;
		break;
	    }
	    else
	      ch = READ_A_CHAR();
	}while(cc != '\033' && ch != '\\');

	ch = KEY_JUNK;
	goto done;

      case BADESC:
	ch = KEY_JUNK;
	goto done;

      case 0: 	/* regular character */
      default:
	/*
	 * we used to strip (ch &= 0x7f;), but this seems much cleaner
	 * in the face of line noise and has the benefit of making it
	 * tougher to emit mistakenly labeled MIME...
	 */
	if((ch & ~0x7f)
	   && ((!ps_global->keyboard_charmap || !strucmp(ps_global->keyboard_charmap, "US-ASCII"))
	       && (!ps_global->display_charmap || !strucmp(ps_global->display_charmap, "US-ASCII")))){
	    dprint((9, "Read char sees ch = 0x%x status=0x%x, returns KEY_JUNK\n", ch, status));
	    return(KEY_JUNK);
	}
	else if(ch == ctrl('Z')){
	    dprint((9, "Read char got ^Z, calling do_suspend\n"));
	    ch = do_suspend();
	    dprint((9, "After do_suspend Read char returns 0x%x %s\n", ch, pretty_command(ch)));
	    return(ch);
	}
#ifdef MOUSE
	else if(ch == ctrl('\\')){
	    int e;

	    dprint((9, "Read char got ^\\, toggle xterm mouse\n"));
	    if(F_ON(F_ENABLE_MOUSE, ps_global)){
		(e=mouseexist()) ? end_mouse() : (void) init_mouse();
		if(e != mouseexist())
		  q_status_message1(SM_ASYNC, 0, 2, "Xterm mouse tracking %s!",
						     mouseexist() ? "on" : "off");
		else if(!e)
		  q_status_message1(SM_ASYNC, 0, 2, "See help for feature \"%s\" ($DISPLAY variable set?)", pretty_feature_name(feature_list_name(F_ENABLE_MOUSE), -1));
	    }
	    else
	      q_status_message1(SM_ASYNC, 0, 2, "Feature \"%s\" not enabled",
				pretty_feature_name(feature_list_name(F_ENABLE_MOUSE), -1));

	    return(NO_OP_COMMAND);
	}
#endif /* MOUSE */


      done:
#ifdef	DEBUG
	if(ps_global->conceal_sensitive_debugging && debug < 10){
	    dprint((9, "Read char returning: <hidden char>\n"));
	}
	else{
	    dprint((9, "Read char returning: 0x%x %s\n", ch, pretty_command(ch)));
	}
#endif

        return(ch);
    }

    /* not reachable */
    return(KEY_JUNK);
}
/*
 * Dialog proc to handle login
 * 
 * Configures the dialog box on init and retrieves the settings on exit.
 */    
BOOL CALLBACK  __export 
config_vars_dialog_proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    DLG_CONFIGVARSDATA *dlgcv;
    BOOL ret = FALSE;
    int usepop = 0;
    char buf[2*MAXPATH+1], *p;
    int buflen = 2*MAXPATH;
#define TCBUFLEN (2*MAXPATH)
    TCHAR tcbuf[TCBUFLEN+1];
    LPTSTR tmp_lptstr;
    char *u;

    switch (uMsg) {
      case WM_INITDIALOG:
  	dlgcv = (DLG_CONFIGVARSDATA *)lParam;
  	SetWindowLong (hDlg, WINDOW_USER_DATA, (LONG) dlgcv);
	if(dlgcv->ivars->pname){
	    tmp_lptstr = utf8_to_lptstr(dlgcv->ivars->pname);
	    if(tmp_lptstr){
		SetDlgItemText(hDlg, IDC_CFV_PNAME, tmp_lptstr);
		fs_give((void **) &tmp_lptstr);
	    }
	}

	if(dlgcv->ivars->userid && dlgcv->ivars->domain){
	    snprintf(buf, sizeof(buf), "%.*s@%.*s", MAXPATH, dlgcv->ivars->userid,
		    MAXPATH, dlgcv->ivars->domain);
	    buf[buflen-1] = '\0';
	    tmp_lptstr = utf8_to_lptstr(buf);
	    if(tmp_lptstr){
		SetDlgItemText(hDlg, IDC_CFV_EMAILADR, tmp_lptstr);
		fs_give((void **) &tmp_lptstr);
	    }
	}

	if(dlgcv->ivars->inboxpath){
	    char *mbx;

	    mbx = dlgcv->ivars->inboxpath;
	    if(*mbx == '{' && (p = strindex(mbx, '}'))
	       && ((*(p+1) == '\0') || !strucmp(p+1, "inbox"))){
		char srvbuf[MAXPATH+1], tuser[MAXPATH+1];
		int i, j, k;

		srvbuf[0] = '\0';
		tuser[0] = '\0';
		strncpy(buf, mbx+1, min(buflen, (int)(p - (mbx+1))));
		buf[min(buflen-1, (int)(p - (mbx+1)))] = '\0';
		for(i = 0, j = 0; buf[i] && j < MAXPATH; i++){
		    if(buf[i] == '/'){
			if(!struncmp("/user="******"/pop3", buf+i, 5)
				&& (!*(buf+5) || (*(buf+5) == '/'))){
			    usepop = 1;
			    i += 4;
			}
			else
			  srvbuf[j++] = buf[i];
		    }
		    else
		      srvbuf[j++] = buf[i];
		}
		srvbuf[j] = '\0';
		if(*srvbuf){
		    tmp_lptstr = utf8_to_lptstr(srvbuf);
		    if(tmp_lptstr){
			SetDlgItemText(hDlg, IDC_CFV_MSERVER, tmp_lptstr);
			fs_give((void **) &tmp_lptstr);
		    }
		}

		if(*tuser){
		    tmp_lptstr = utf8_to_lptstr(tuser);
		    if(tmp_lptstr){
			SetDlgItemText(hDlg, IDC_CFV_LOGIN, tmp_lptstr);
			fs_give((void **) &tmp_lptstr);
		    }
		}
	    }
	    else {
		tmp_lptstr = utf8_to_lptstr(mbx);
		if(tmp_lptstr){
		    SetDlgItemText(hDlg, IDC_CFV_MSERVER, tmp_lptstr);
		    fs_give((void **) &tmp_lptstr);
		}

		if(*mbx != '{' && *mbx != '#')
		  EnableWindow(GetDlgItem(hDlg, IDC_CFV_MSERVER), 0);
	    }
	}
	CheckRadioButton (hDlg, IDC_CFV_IMAP, IDC_CFV_POP3,
			  usepop ? IDC_CFV_POP3 : IDC_CFV_IMAP);
	if(dlgcv->ivars->smtpserver){
	    tmp_lptstr = utf8_to_lptstr(dlgcv->ivars->smtpserver);
	    if(tmp_lptstr){
		SetDlgItemText(hDlg, IDC_CFV_SMTPSERVER, tmp_lptstr);
		fs_give((void **) &tmp_lptstr);
	    }
	}

	if(dlgcv->ivars->defmailclient)
	  CheckDlgButton(hDlg, IDC_CFV_DEFMAILER, BST_CHECKED);
	if(dlgcv->ivars->defnewsclient)
	  CheckDlgButton(hDlg, IDC_CFV_DEFNEWSRDR, BST_CHECKED);
	
 	return (1);
	break;

      case WM_COMMAND:
	dlgcv = (DLG_CONFIGVARSDATA *) GetWindowLong (hDlg, WINDOW_USER_DATA);
	switch (wParam) {
	  case IDOK:
	    /* personal name */
	    GetDlgItemText(hDlg, IDC_CFV_PNAME, tcbuf, TCBUFLEN);
	    tcbuf[TCBUFLEN] = '\0';
	    u = lptstr_to_utf8(tcbuf);
	    if(u){
		removing_leading_and_trailing_white_space(u);
		if(dlgcv->ivars->pname)
		  fs_give((void **)&dlgcv->ivars->pname);

		if(*u){
		    dlgcv->ivars->pname = u;
		    u = NULL;
		}

		if(u)
		  fs_give((void **) &u);
	    }
	    
	    /* user-id and domain */
	    GetDlgItemText(hDlg, IDC_CFV_EMAILADR, tcbuf, TCBUFLEN);
	    tcbuf[TCBUFLEN] = '\0';
	    u = lptstr_to_utf8(tcbuf);
	    if(u){
		removing_leading_and_trailing_white_space(u);
		if(p = strindex(u, '@')){
		    *(p++) = '\0';
		    if(dlgcv->ivars->userid)
		      fs_give((void **)&dlgcv->ivars->userid);

		    if(dlgcv->ivars->domain)
		      fs_give((void **)&dlgcv->ivars->domain);

		    if(*u){
			dlgcv->ivars->userid = u;
			u = NULL;
		    }

		    if(*p)
		      dlgcv->ivars->domain = cpystr(p);
		}
		else{
		    MessageBox(hDlg, TEXT("Invalid email address.  Should be username@domain"),
			       TEXT("Alpine"), MB_ICONWARNING | MB_OK);
		    return(TRUE);
		}

		if(u)
		  fs_give((void **) &u);
	    }

	    /* inbox-path */
	    GetDlgItemText(hDlg, IDC_CFV_MSERVER, tcbuf, TCBUFLEN);
	    tcbuf[TCBUFLEN] = '\0';
	    u = lptstr_to_utf8(tcbuf);
	    if(u){
		removing_leading_and_trailing_white_space(u);
		if(*u == '{' || *u == '#'
		   || !IsWindowEnabled(GetDlgItem(hDlg, IDC_CFV_MSERVER))){
		    if(dlgcv->ivars->inboxpath)
		      fs_give((void **)&dlgcv->ivars->inboxpath);

		    dlgcv->ivars->inboxpath = u;
		    u = NULL;
		}
		else if(*u){
		    char tsrvr[4*MAXPATH+1];
		    int tsrvrlen = 4*MAXPATH;

		    if(dlgcv->ivars->inboxpath)
		      fs_give((void **)&dlgcv->ivars->inboxpath);

		    snprintf(tsrvr, sizeof(tsrvr), "{%s%s", u,
			    IsDlgButtonChecked(hDlg, IDC_CFV_POP3) 
			    == BST_CHECKED ? "/pop3" : "");

		    if(u)
		      fs_give((void **) &u);

		    GetDlgItemText(hDlg, IDC_CFV_LOGIN, tcbuf, TCBUFLEN);
		    tcbuf[TCBUFLEN] = '\0';
		    u = lptstr_to_utf8(tcbuf);
		    if(u){
			removing_leading_and_trailing_white_space(u);
			if(*u){
			    strncat(tsrvr, "/user="******"}inbox", sizeof(tsrvr)-strlen(tsrvr)-1);
			tsrvr[sizeof(tsrvr)-1] = '\0';
			dlgcv->ivars->inboxpath = cpystr(tsrvr);
		    }
		}

		if(u)
		  fs_give((void **) &u);
	    }

	    /* smtp-server */
	    GetDlgItemText(hDlg, IDC_CFV_SMTPSERVER, tcbuf, TCBUFLEN);
	    tcbuf[TCBUFLEN] = '\0';
	    u = lptstr_to_utf8(tcbuf);
	    if(u){
		removing_leading_and_trailing_white_space(u);
		if(dlgcv->ivars->smtpserver)
		  fs_give((void **)&dlgcv->ivars->smtpserver);

		if(*u){
		    dlgcv->ivars->smtpserver = u;
		    u = NULL;
		}

		if(u)
		  fs_give((void **) &u);
	    }

	    dlgcv->ivars->defmailclient =
	      (IsDlgButtonChecked(hDlg, IDC_CFV_DEFMAILER)
	       == BST_CHECKED);
	    dlgcv->ivars->defnewsclient =
	      (IsDlgButtonChecked(hDlg, IDC_CFV_DEFNEWSRDR)
	       == BST_CHECKED);

	    EndDialog (hDlg, LOWORD(wParam));
	    dlgcv->rv = 0;
	    ret = TRUE;
	    break;

	case IDCANCEL:
	    dlgcv->rv = 1;
	    ret = TRUE;
	    EndDialog (hDlg, LOWORD(wParam));
	    break;
        }
	break;
	

    }
    return (ret);
}
Beispiel #13
0
int
rd_prompt_about_forged_remote_data(int reason, REMDATA_S *rd, char *extra)
{
    char      tmp[2000];
    char     *unknown = "<unknown>";
    int       rv = -1;
    char *foldertype, *foldername, *special;

    foldertype = (rd && rd->t.i.special_hdr && !strucmp(rd->t.i.special_hdr, REMOTE_ABOOK_SUBTYPE)) ? "address book" : (rd && rd->t.i.special_hdr && !strucmp(rd->t.i.special_hdr, REMOTE_PINERC_SUBTYPE)) ? "configuration" : "data";
    foldername = (rd && rd->rn) ? rd->rn : unknown;
    special = (rd && rd->t.i.special_hdr) ? rd->t.i.special_hdr : unknown;

    dprint((1, "rd_check_out_forged_remote_data:\n"));
    dprint((1, " reason=%d\n", reason));
    dprint((1, " folder_type=%s\n", foldertype ? foldertype : "?"));
    dprint((1, " remotename=%s\n\n", foldername ? foldername : "?"));

    if(rd && rd->flags & USER_SAID_NO)
      return rv;

    if(reason == -2){
	dprint((1, "The special header \"%s\" is missing from the last message in the folder.\nThis indicates that something is wrong.\nYou should probably answer \"No\"\nso that you don't use the corrupt data.\nThen you should investigate further.\n", special ? special : "?"));
    }
    else if(reason == -1){
	dprint((1,  "The last message in the folder contains \"Received\" headers.\nThis usually indicates that the message was put there by the mail\ndelivery system. Alpine does not add those Received headers.\nYou should probably answer \"No\" so that you don't use the corrupt data.\nThen you should investigate further.\n"));
    }
    else if(reason == 0){
	dprint((1, "The special header \"%s\" in the last message\nin the folder has an unexpected value (%s)\nafter it. This could indicate that something is wrong.\nThis value should not normally be put there by Alpine.\nHowever, since there are no Received lines in the message we choose to\nbelieve that everything is ok and we will proceed.\n",
		special ? special : "?", (extra && *extra) ? extra : "?"));
    }
    else if(reason == 1){
	dprint((1, "The special header \"%s\" in the last message\nin the folder has an unexpected value (1)\nafter it. It appears that it may have been put there by an Pine\nwith a version number less than 4.50.\nSince there are no Received lines in the message we choose to believe that\nthe header was added by an old Pine and we will proceed.\n",
		special ? special : "?"));
    }
    else if(reason > 1){
	dprint((1, "The special header \"%s\" in the last message\nin the folder has an unexpected value (%s)\nafter it. This is the right sort of value that Alpine would normally put there,\nbut it doesn't match the value from the first message in the folder.\nThis may indicate that something is wrong.\nHowever, since there are no Received lines in the message we choose to\nbelieve that everything is ok and we will proceed.\n",
		special ? special : "?", (extra && *extra) ? extra : "?"));
    }

    if(reason >= 0){
	/*
	 * This check should not really be here. We have a cookie that
	 * has the wrong value so something is possibly wrong.
	 * But we are worried that old pines will put the bad value in
	 * there (which they will) and then the questions will bother
	 * users and mystify them. So we're just going to pretend the user
	 * said Yes in this case, and we'll try to fix the cookie.
	 * We still catch Received lines and use that or the complete absence
	 * of a special header as indicators of trouble.
	 */
	rd->flags |= USER_SAID_YES;
	return(1);
    }

    if(ps_global->ttyo){
	SCROLL_S  sargs;
	STORE_S  *in_store, *out_store;
	gf_io_t   pc, gc;
	HANDLE_S *handles = NULL;
	int       the_answer = 'n';

	if(!(in_store = so_get(CharStar, NULL, EDIT_ACCESS)) ||
	   !(out_store = so_get(CharStar, NULL, EDIT_ACCESS)))
	  goto try_wantto;

	/* TRANSLATORS: the first %s is the folder type, it may be address book or
	   configuration. The second %s is the folder name. Of course, the HTML
	   tags should be left as is. */
	snprintf(tmp, sizeof(tmp), _("<HTML><P>The data in the remote %s folder<P><CENTER>%s</CENTER><P>looks suspicious. The reason for the suspicion is<P><CENTER>"),
		foldertype, foldername);
	tmp[sizeof(tmp)-1] = '\0';
	so_puts(in_store, tmp);

	if(reason == -2){
	    snprintf(tmp, sizeof(tmp), _("header \"%s\" is missing</CENTER><P>The special header \"%s\" is missing from the last message in the folder. This indicates that something is wrong. You should probably answer \"No\" so that you don't use the corrupt data. Then you should investigate further."),
		    special, special);
	    tmp[sizeof(tmp)-1] = '\0';
	    so_puts(in_store, tmp);
	}
	else if(reason == -1){
	    so_puts(in_store, _("\"Received\" headers detected</CENTER><P>The last message in the folder contains \"Received\" headers. This usually indicates that the message was put there by the mail delivery system. Alpine does not add those Received headers. You should probably answer \"No\" so that you don't use the corrupt data. Then you should investigate further."));
	}
	else if(reason == 0){
	    snprintf(tmp, sizeof(tmp), _("Unexpected value for header \"%s\"</CENTER><P>The special header \"%s\" in the last message in the folder has an unexpected value (%s) after it. This probably indicates that something is wrong. This value would not normally be put there by Alpine. You should probably answer \"No\" so that you don't use the corrupt data. Then you should investigate further."),
		    special, special, (extra && *extra) ? extra : "?");
	    tmp[sizeof(tmp)-1] = '\0';
	    so_puts(in_store, tmp);
	}
	else if(reason == 1){
	    snprintf(tmp, sizeof(tmp), _("Unexpected value for header \"%s\"</CENTER><P>The special header \"%s\" in the last message in the folder has an unexpected value (1) after it. It appears that it may have been put there by a Pine with a version number less than 4.50. If you believe that you have changed this data with an older Pine more recently than you've changed it with this version of Alpine, then you can probably safely answer \"Yes\". If you do not understand why this has happened, you should probably answer \"No\" so that you don't use the corrupt data. Then you should investigate further."),
		    special, special);
	    tmp[sizeof(tmp)-1] = '\0';
	    so_puts(in_store, tmp);
	}
	else if(reason > 1){
	    snprintf(tmp, sizeof(tmp), _("Unexpected value for header \"%s\"</CENTER><P>The special header \"%s\" in the last message in the folder has an unexpected value (%s) after it. This is the right sort of value that Alpine would normally put there, but it doesn't match the value from the first message in the folder. This may indicate that something is wrong. Unless you understand why this has happened, you should probably answer \"No\" so that you don't use the corrupt data. Then you should investigate further."),
		    special, special, (extra && *extra) ? extra : "?");
	    tmp[sizeof(tmp)-1] = '\0';
	    so_puts(in_store, tmp);
	}

	so_seek(in_store, 0L, 0);
	init_handles(&handles);
	gf_filter_init();
	gf_link_filter(gf_html2plain,
		       gf_html2plain_opt(NULL,
					 ps_global->ttyo->screen_cols, non_messageview_margin(),
					 &handles, NULL, GFHP_LOCAL_HANDLES));
	gf_set_so_readc(&gc, in_store);
	gf_set_so_writec(&pc, out_store);
	gf_pipe(gc, pc);
	gf_clear_so_writec(out_store);
	gf_clear_so_readc(in_store);

	memset(&sargs, 0, sizeof(SCROLL_S));
	sargs.text.handles  = handles;
	sargs.text.text     = so_text(out_store);
	sargs.text.src      = CharStar;
	sargs.bar.title     = _("REMOTE DATA FORGERY WARNING");
	sargs.proc.tool     = rd_answer_forge_warning;
	sargs.proc.data.p   = (void *)&the_answer;
	sargs.keys.menu     = &forge_keymenu;
	setbitmap(sargs.keys.bitmap);

	scrolltool(&sargs);

	if(the_answer == 'y'){
	    rv = 1;
	    rd->flags |= USER_SAID_YES;
	}
	else if(rd)
	  rd->flags |= USER_SAID_NO;

	ps_global->mangled_screen = 1;
	ps_global->painted_body_on_startup = 0;
	ps_global->painted_footer_on_startup = 0;
	so_give(&in_store);
	so_give(&out_store);
	free_handles(&handles);
    }
    else{
	char *p = tmp;

	snprintf(p, sizeof(tmp), _("\nThe data in the remote %s folder\n\n   %s\n\nlooks suspicious. The reason for the suspicion is\n\n   "),
		foldertype, foldername);
	tmp[sizeof(tmp)-1] = '\0';
	p += strlen(p);

	if(reason == -2){
	    snprintf(p, sizeof(tmp)-(p-tmp), _("header \"%s\" is missing\n\nThe special header \"%s\" is missing from the last message\nin the folder. This indicates that something is wrong.\nYou should probably answer \"No\" so that you don't use the corrupt data.\nThen you should investigate further.\n\n"),
		    special, special);
	    tmp[sizeof(tmp)-1] = '\0';
	}
	else if(reason == -1){
	    snprintf(p, sizeof(tmp)-(p-tmp), _("\"Received\" headers detected\n\nThe last message in the folder contains \"Received\" headers.\nThis usually indicates that the message was put there by the\nmail delivery system. Alpine does not add those Received headers.\nYou should probably answer \"No\" so that you don't use the corrupt data.\nThen you should investigate further.\n\n"));
	    tmp[sizeof(tmp)-1] = '\0';
	}
	else if(reason == 0){
	    snprintf(p, sizeof(tmp)-(p-tmp), _("Unexpected value for header \"%s\"\n\nThe special header \"%s\" in the last message in the folder\nhas an unexpected value (%s) after it. This probably\nindicates that something is wrong. This value would not normally be put\nthere by Alpine. You should probably answer \"No\" so that you don't use\nthe corrupt data. Then you should investigate further.\n\n"),
		    special, special, (extra && *extra) ? extra : "?");
	    tmp[sizeof(tmp)-1] = '\0';
	}
	else if(reason == 1){
	    snprintf(p, sizeof(tmp)-(p-tmp), _("Unexpected value for header \"%s\"\n\nThe special header \"%s\" in the last message in the folder\nhas an unexpected value (1) after it. It appears that it may have been\nput there by a Pine with a version number less than 4.50.\nIf you believe that you have changed this data with an older Pine more\nrecently than you've changed it with this version of Alpine, then you can\nprobably safely answer \"Yes\". If you do not understand why this has\nhappened, you should probably answer \"No\" so that you don't use the\ncorrupt data. Then you should investigate further.\n\n"),
		    special, special);
	    tmp[sizeof(tmp)-1] = '\0';
	}
	else if(reason > 1){
	    snprintf(p, sizeof(tmp)-(p-tmp), _("Unexpected value for header \"%s\"\n\nThe special header \"%s\" in the last message in the folder\nhas an unexpected\nvalue (%s) after it. This is\nthe right sort of value that Alpine would normally put there, but it\ndoesn't match the value from the first message in the folder. This may\nindicate that something is wrong. Unless you understand why this has happened,\nyou should probably answer \"No\" so that you don't use the\ncorrupt data. Then you should investigate further.\n\n"),
		    special, special, (extra && *extra) ? extra : "?");
	    tmp[sizeof(tmp)-1] = '\0';
	}

try_wantto:
	p += strlen(p);
	snprintf(p, sizeof(tmp)-(p-tmp), _("Suspicious data in \"%s\": Continue anyway "),
		(rd && rd->t.i.special_hdr) ? rd->t.i.special_hdr
					    : unknown);
	tmp[sizeof(tmp)-1] = '\0';
	if(want_to(tmp, 'n', 'x', NO_HELP, WT_NORM) == 'y'){
	    rv = 1;
	    rd->flags |= USER_SAID_YES;
	}
	else if(rd)
	  rd->flags |= USER_SAID_NO;
    }

    if(rv < 0)
      q_status_message1(SM_ORDER, 1, 3, _("Can't open remote %s"),
			(rd && rd->rn) ? rd->rn : "<noname>");

    return(rv);
}
Beispiel #14
0
/*
 * Break up the ldap-server string stored in the pinerc into its
 * parts. The structure is allocated here and should be freed by the caller.
 *
 * The original string looks like
 *     <servername>[:port] <SPACE> "/base=<base>/impl=1/..."
 *
 * Args  serv_str -- The original string from the pinerc to parse.
 *
 * Returns A pointer to a structure with filled in answers.
 *
 *  Some of the members have defaults. If port is -1, that means to use
 *  the default LDAP_PORT. If base is NULL, use "". Type and srch have
 *  defaults defined in alpine.h. If cust is non-NULL, it overrides type and
 *  srch.
 */
LDAP_SERV_S *
break_up_ldap_server(char *serv_str)
{
    char *lserv;
    char *q, *p, *tail;
    int   i, only_one = 1;
    LDAP_SERV_S *info = NULL;

    if(!serv_str)
      return(info);

    info = (LDAP_SERV_S *)fs_get(sizeof(LDAP_SERV_S));

    /*
     * Initialize to defaults.
     */
    memset((void *)info, 0, sizeof(*info));
    info->port  = -1;
    info->srch  = -1;
    info->type  = -1;
    info->time  = -1;
    info->size  = -1;
    info->scope = -1;

    /* copy the whole string to work on */
    lserv = cpystr(serv_str);
    if(lserv)
      removing_trailing_white_space(lserv);

    if(!lserv || !*lserv || *lserv == '"'){
	if(lserv)
	  fs_give((void **)&lserv);

	if(info)
	  free_ldap_server_info(&info);

	return(NULL);
    }

    tail = lserv;
    while((tail = strindex(tail, SPACE)) != NULL){
	tail++;
	if(*tail == '"' || *tail == '/'){
	    *(tail-1) = '\0';
	    break;
	}
	else
	  only_one = 0;
    }

    /* tail is the part after server[:port] <SPACE> */
    if(tail && *tail){
	removing_leading_white_space(tail);
	(void)removing_double_quotes(tail);
    }

    /* get the optional port number */
    if(only_one && (q = strindex(lserv, ':')) != NULL){
	int ldapport = -1;

	*q = '\0';
	if((ldapport = atoi(q+1)) >= 0)
	  info->port = ldapport;
    }

    /* use lserv for serv even though it has a few extra bytes alloced */
    info->serv = lserv;
    
    if(tail && *tail){
	/* get the search base */
	if((q = srchstr(tail, "/base=")) != NULL)
	  info->base = remove_backslash_escapes(q+6);

	if((q = srchstr(tail, "/binddn=")) != NULL)
	  info->binddn = remove_backslash_escapes(q+8);

	/* get the implicit parameter */
	if((q = srchstr(tail, "/impl=1")) != NULL)
	  info->impl = 1;

	/* get the rhs parameter */
	if((q = srchstr(tail, "/rhs=1")) != NULL)
	  info->rhs = 1;

	/* get the ref parameter */
	if((q = srchstr(tail, "/ref=1")) != NULL)
	  info->ref = 1;

	/* get the nosub parameter */
	if((q = srchstr(tail, "/nosub=1")) != NULL)
	  info->nosub = 1;

	/* get the tls parameter */
	if((q = srchstr(tail, "/tls=1")) != NULL)
	  info->tls = 1;

	/* get the tlsmust parameter */
	if((q = srchstr(tail, "/tlsm=1")) != NULL)
	  info->tlsmust = 1;

	/* get the search type value */
	if((q = srchstr(tail, "/type=")) != NULL){
	    NAMEVAL_S *v;

	    q += 6;
	    if((p = strindex(q, '/')) != NULL)
	      *p = '\0';
	    
	    for(i = 0; (v = ldap_search_types(i)); i++)
	      if(!strucmp(q, v->name)){
		  info->type = v->value;
		  break;
	      }
	    
	    if(p)
	      *p = '/';
	}

	/* get the search rule value */
	if((q = srchstr(tail, "/srch=")) != NULL){
	    NAMEVAL_S *v;

	    q += 6;
	    if((p = strindex(q, '/')) != NULL)
	      *p = '\0';
	    
	    for(i = 0; (v = ldap_search_rules(i)); i++)
	      if(!strucmp(q, v->name)){
		  info->srch = v->value;
		  break;
	      }
	    
	    if(p)
	      *p = '/';
	}

	/* get the scope */
	if((q = srchstr(tail, "/scope=")) != NULL){
	    NAMEVAL_S *v;

	    q += 7;
	    if((p = strindex(q, '/')) != NULL)
	      *p = '\0';
	    
	    for(i = 0; (v = ldap_search_scope(i)); i++)
	      if(!strucmp(q, v->name)){
		  info->scope = v->value;
		  break;
	      }
	    
	    if(p)
	      *p = '/';
	}

	/* get the time limit */
	if((q = srchstr(tail, "/time=")) != NULL){
	    q += 6;
	    if((p = strindex(q, '/')) != NULL)
	      *p = '\0';
	    
	    /* This one's a number */
	    if(*q){
		char *err;

		err = strtoval(q, &i, 0, 500, 0, tmp_20k_buf, SIZEOF_20KBUF, "ldap timelimit");
		if(err){
		  dprint((1, "%s\n", err ? err : "?"));
		}
		else
		  info->time = i;
	    }

	    if(p)
	      *p = '/';
	}

	/* get the size limit */
	if((q = srchstr(tail, "/size=")) != NULL){
	    q += 6;
	    if((p = strindex(q, '/')) != NULL)
	      *p = '\0';
	    
	    /* This one's a number */
	    if(*q){
		char *err;

		err = strtoval(q, &i, 0, 500, 0, tmp_20k_buf, SIZEOF_20KBUF, "ldap sizelimit");
		if(err){
		  dprint((1, "%s\n", err ? err : "?"));
		}
		else
		  info->size = i;
	    }

	    if(p)
	      *p = '/';
	}

	/* get the custom search filter */
	if((q = srchstr(tail, "/cust=")) != NULL)
	  info->cust = remove_backslash_escapes(q+6);

	/* get the nickname */
	if((q = srchstr(tail, "/nick=")) != NULL)
	  info->nick = remove_backslash_escapes(q+6);

	/* get the mail attribute name */
	if((q = srchstr(tail, "/matr=")) != NULL)
	  info->mailattr = remove_backslash_escapes(q+6);

	/* get the sn attribute name */
	if((q = srchstr(tail, "/satr=")) != NULL)
	  info->snattr = remove_backslash_escapes(q+6);

	/* get the gn attribute name */
	if((q = srchstr(tail, "/gatr=")) != NULL)
	  info->gnattr = remove_backslash_escapes(q+6);

	/* get the cn attribute name */
	if((q = srchstr(tail, "/catr=")) != NULL)
	  info->cnattr = remove_backslash_escapes(q+6);

	/* get the backup mail address */
	if((q = srchstr(tail, "/mail=")) != NULL)
	  info->mail = remove_backslash_escapes(q+6);
    }

    return(info);
}
Beispiel #15
0
/*
 * Returns the mailcap entry for type/subtype from the successfull
 * mailcap entry, or NULL if none.  Command string still contains % stuff.
 */
MailcapEntry *
mc_get_command(int type, char *subtype, BODY *body,
	       int check_extension, int *sp_handlingp)
{
    MailcapEntry *mc;
    char	  tmp_subtype[256], tmp_ext[16], *ext = NULL;

    dprint((5, "- mc_get_command(%s/%s) -\n",
	       body_type_names(type),
	       subtype ? subtype : "?"));

    if(type == TYPETEXT
       && (!subtype || !strucmp(subtype, "plain"))
       && F_ON(F_SHOW_TEXTPLAIN_INT, ps_global))
      return(NULL);

    mc_init();

    if(check_extension){
	char     *fname;
	MT_MAP_T  e2b;

	/*
	 * Special handling for when we're looking at what's likely
	 * binary application data. Look for a file name extension
	 * that we might use to hook a helper app to.
	 *
	 * NOTE: This used to preclude an "app/o-s" mailcap entry
	 *       since this took precedence.  Now that there are
	 *       typically two scans through the check_extension
	 *       mechanism, the mailcap entry now takes precedence.
	 */
	if((fname = get_filename_parameter(NULL, 0, body, &e2b.from.ext)) != NULL
	   && e2b.from.ext && e2b.from.ext[0]){
	    if(strlen(e2b.from.ext) < sizeof(tmp_ext) - 2){
		strncpy(ext = tmp_ext, e2b.from.ext - 1, sizeof(tmp_ext)); /* remember it */
		tmp_ext[sizeof(tmp_ext)-1] = '\0';
		if(mt_srch_mime_type(mt_srch_by_ext, &e2b)){
		    type = e2b.to.mime.type;		/* mapped type */
		    strncpy(subtype = tmp_subtype, e2b.to.mime.subtype,
			    sizeof(tmp_subtype)-1);
		    tmp_subtype[sizeof(tmp_subtype)-1] = '\0';
		    fs_give((void **) &e2b.to.mime.subtype);
		    body = NULL;		/* the params no longer apply */
		}
	    }

	    fs_give((void **) &fname);
	}
	else{
	    if(fname)
	      fs_give((void **) &fname);

	    return(NULL);
	}
    }

    for(mc = MailcapData.head; mc; mc = mc->next)
      if(mc_ctype_match(type, subtype, mc->contenttype)
	 && mc_passes_test(mc, type, subtype, body)){
	  dprint((9, 
		     "mc_get_command: type=%s/%s, command=%s\n", 
		     body_type_names(type),
		     subtype ? subtype : "?",
		     mc->command ? mc->command : "?"));
	  return(mc);
      }

    if(mime_os_specific_access()){
	static MailcapEntry  fake_mc;
	static char	     fake_cmd[1024];
	char		     tmp_mime_type[256];

	memset(&fake_mc, 0, sizeof(MailcapEntry));
	fake_cmd[0] = '\0';
	fake_mc.command = fake_cmd;

	snprintf(tmp_mime_type, sizeof(tmp_mime_type), "%s/%s", body_types[type], subtype);
	if(mime_get_os_mimetype_command(tmp_mime_type, ext, fake_cmd,
					sizeof(fake_cmd), check_extension, sp_handlingp))
	  return(&fake_mc);
    }

    return(NULL);
}
Beispiel #16
0
void
mc_build_entry(char **tokens)
{
    MailcapEntry *mc;

    if(!tokens[0]){
	dprint((5, "mailcap: missing content type!\n"));
	return;
    }
    else if(!tokens[1] || !mc_sane_command(tokens[1])){
	dprint((5, "mailcap: missing/bogus command!\n"));
	return;
    }

    mc		    = mc_new_entry();
    mc->contenttype = *tokens++;
    mc->command     = *tokens++;

    dprint((9, "mailcap: content type: %s\n   command: %s\n",
	       mc->contenttype ? mc->contenttype : "?",
	       mc->command ? mc->command : "?"));

    /* grok options  */
    for( ; *tokens; tokens++){
	char *arg;

	/* legit value? */
	if(!isalnum((unsigned char) **tokens)){
	    dprint((5, "Unknown parameter = \"%s\"", *tokens));
	    continue;
	}

	if((arg = strindex(*tokens, '=')) != NULL){
	    *arg = ' ';
	    while(arg > *tokens && isspace((unsigned char) arg[-1]))
	      arg--;

	    *arg++ = '\0';		/* tie off parm arg */
	    while(*arg && isspace((unsigned char) *arg))
	      arg++;

	    if(!*arg)
	      arg = NULL;
	}

	if(!strucmp(*tokens, "needsterminal")){
	    mc->needsterminal = 1;
	    dprint((9, "mailcap: set needsterminal\n"));
	}
	else if(!strucmp(*tokens, "copiousoutput")){
	    mc->needsterminal = 2;
	    dprint((9, "mailcap: set copiousoutput\n"));
	}
	else if(arg && !strucmp(*tokens, "test")){
	    mc->testcommand = arg;
	    dprint((9, "mailcap: testcommand=%s\n",
		       mc->testcommand ? mc->testcommand : "?"));
	}
	else if(arg && !strucmp(*tokens, "description")){
	    mc->label = arg;
	    dprint((9, "mailcap: label=%s\n",
		   mc->label ? mc->label : "?"));
	}
	else if(arg && !strucmp(*tokens, "print")){
	    mc->printcommand = arg;
	    dprint((9, "mailcap: printcommand=%s\n",
		       mc->printcommand ? mc->printcommand : "?"));
	}
	else if(arg && !strucmp(*tokens, "compose")){
	    /* not used */
	    dprint((9, "mailcap: not using compose=%s\n",
		   arg ? arg : "?"));
	}
	else if(arg && !strucmp(arg, "composetyped")){
	    /* not used */
	    dprint((9, "mailcap: not using composetyped=%s\n",
		   arg ? arg : "?"));
	}
	else if(arg && !strucmp(arg, "textualnewlines")){
	    /* not used */
	    dprint((9,
		       "mailcap: not using texttualnewlines=%s\n",
		       arg ? arg : "?"));
	}
	else if(arg && !strucmp(arg, "edit")){
	    /* not used */
	    dprint((9, "mailcap: not using edit=%s\n",
		   arg ? arg : "?"));
	}
	else if(arg && !strucmp(arg, "x11-bitmap")){
	    /* not used */
	    dprint((9, "mailcap: not using x11-bitmap=%s\n",
		   arg ? arg : "?"));
	}
	else
	  dprint((9, "mailcap: ignoring unknown flag: %s\n",
		     arg ? arg : "?"));
    }
}
Beispiel #17
0
/*
 * Format editorial comment about charset mismatch
 */
int
charset_editorial(char *charset, long int msgno, HANDLE_S **handlesp, int flags,
		  int quality, int width, gf_io_t pc)
{
    char     *p, color[64], buf[2048];
    int	      i, n;
    HANDLE_S *h = NULL;

    snprintf(buf, sizeof(buf), CHARSET_DISCLAIMER_1, charset ? charset : "US-ASCII");
    p = &buf[strlen(buf)];

    if(!(ps_global->display_charmap
	 && strucmp(ps_global->display_charmap, "US-ASCII"))
       && handlesp
       && (flags & FM_DISPLAY) == FM_DISPLAY){
	h		      = new_handle(handlesp);
	h->type		      = URL;
	h->h.url.path	      = cpystr("x-alpine-help:h_config_char_set");

	/*
	 * Because this filter comes after the delete_quotes filter, we need
	 * to tell delete_quotes that this handle is used, so it won't
	 * delete it. This is a dangerous thing.
	 */
	h->is_used = 1; 

	if(!(flags & FM_NOCOLOR)
	   && scroll_handle_start_color(color, sizeof(color), &n)){
	    for(i = 0; i < n; i++)
	      if(p-buf < sizeof(buf))
	        *p++ = color[i];
	}
	else if(F_OFF(F_SLCTBL_ITEM_NOBOLD, ps_global)){
	    if(p-buf+1 < sizeof(buf)){
	      *p++ = TAG_EMBED;
	      *p++ = TAG_BOLDON;
	    }
	}

	if(p-buf+1 < sizeof(buf)){
	  *p++ = TAG_EMBED;
	  *p++ = TAG_HANDLE;
	}

	snprintf(p + 1, sizeof(buf)-(p+1-buf), "%d", h->key);
	if(p-buf < sizeof(buf))
	  *p  = strlen(p + 1);

	p  += (*p + 1);
    }

    sstrncpy(&p, CHARSET_DISCLAIMER_2, sizeof(buf)-(p-buf));

    if(h){
	/* in case it was the current selection */
	if(p-buf+1 < sizeof(buf)){
	  *p++ = TAG_EMBED;
	  *p++ = TAG_INVOFF;
	}

	if(scroll_handle_end_color(color, sizeof(color), &n, 0)){
	    for(i = 0; i < n; i++)
	      if(p-buf < sizeof(buf))
	        *p++ = color[i];
	}
	else{
	    if(p-buf+1 < sizeof(buf)){
	      *p++ = TAG_EMBED;
	      *p++ = TAG_BOLDOFF;
	    }
	}

	if(p-buf < sizeof(buf))
	  *p = '\0';
    }

    snprintf(p, sizeof(buf)-(p-buf), CHARSET_DISCLAIMER_3,
	    ps_global->display_charmap ?  ps_global->display_charmap : "US-ASCII",
	    (quality == CV_LOSES_SPECIAL_CHARS) ? "special " : "");

    buf[sizeof(buf)-1] = '\0';

    return(format_editorial(buf, width, flags, handlesp, pc) == NULL
	   && gf_puts(NEWLINE, pc) && gf_puts(NEWLINE, pc));
}
Beispiel #18
0
/*----------------------------------------------------------------------
   Handle fetching and filtering a text message segment to be displayed
   by scrolltool or printed or exported or piped.

Args: att   -- segment to fetch
      msgno -- message number segment is a part of
      pc    -- function to write characters from segment with
      style -- Indicates special handling for error messages
      flags -- Indicates special necessary handling

Returns: 1 if errors encountered, 0 if everything went A-OK

 ----*/     
int
decode_text(ATTACH_S	    *att,
	    long int	     msgno,
	    gf_io_t	     pc,
	    HANDLE_S	   **handlesp,
	    DetachErrStyle   style,
	    int		     flags)
{
    FILTLIST_S	filters[14];
    char       *err, *charset;
    int		filtcnt = 0, error_found = 0, column, wrapit;
    int         is_in_sig = OUT_SIG_BLOCK;
    int         is_flowed_msg = 0, add_me = 1, doraw = RAWSTRING;
    int         is_delsp_yes = 0;
    int         filt_only_c0 = 0;
    char       *parmval;
    char       *free_this = NULL;
    STORE_S    *warn_so = NULL;
    DELQ_S      dq;
    URL_HILITE_S uh;

    column = (flags & FM_DISPLAY) ? ps_global->ttyo->screen_cols : 80;

    if(!(flags & FM_DISPLAY))
      flags |= FM_NOINDENT;

    wrapit = column;

    memset(filters, 0, sizeof(filters));

    /* charset the body part is in */
    charset = parameter_val(att->body->parameter, "charset");

    /* determined if it's flowed, affects wrapping and quote coloring */
    if(att->body->type == TYPETEXT
       && !strucmp(att->body->subtype, "plain")
       && (parmval = parameter_val(att->body->parameter, "format"))){
	if(!strucmp(parmval, "flowed"))
	  is_flowed_msg = 1;
	fs_give((void **) &parmval);

	if(is_flowed_msg){
	    if((parmval = parameter_val(att->body->parameter, "delsp")) != NULL){
		if(!strucmp(parmval, "yes"))
		  is_delsp_yes = 1;

		fs_give((void **) &parmval);
	    }
	}
    }

    if(!ps_global->pass_ctrl_chars){
	filters[filtcnt++].filter = gf_escape_filter;
	filters[filtcnt].filter = gf_control_filter;

	filt_only_c0 = 1;
	filters[filtcnt++].data = gf_control_filter_opt(&filt_only_c0);
    }

    if(flags & FM_DISPLAY)
      filters[filtcnt++].filter = gf_tag_filter;

    /*
     * if it's just plain old text, look for url's
     */
    if(!(att->body->subtype && strucmp(att->body->subtype, "plain"))){
	struct variable *vars = ps_global->vars;

	if((F_ON(F_VIEW_SEL_URL, ps_global)
	    || F_ON(F_VIEW_SEL_URL_HOST, ps_global)
	    || F_ON(F_SCAN_ADDR, ps_global))
	   && handlesp){

	    /*
	     * The url_hilite filter really ought to come
	     * after flowing, because flowing with the DelSp=yes parameter
	     * can reassemble broken urls back into identifiable urls.
	     * We add the preflow filter to do only the reassembly part
	     * of the flowing so that we can spot the urls.
	     * At this time (2005-03-29) we know that Apple Mail does
	     * send mail like this sometimes. This filter removes the
	     * sequence  SP CRLF  if that seems safe.
	     */
	    if(ps_global->full_header != 2 && is_delsp_yes)
              filters[filtcnt++].filter = gf_preflow;

	    filters[filtcnt].filter = gf_line_test;
	    filters[filtcnt++].data = gf_line_test_opt(url_hilite,
						       gf_url_hilite_opt(&uh,handlesp,0));
	}

	if((flags & FM_DISPLAY)
           && !(flags & FM_NOCOLOR)
           && pico_usingcolor()
           && VAR_SPECIAL_TEXT_FORE_COLOR 
           && VAR_SPECIAL_TEXT_BACK_COLOR){
            filters[filtcnt].filter = gf_line_test;
            filters[filtcnt++].data = gf_line_test_opt(color_this_text, NULL);
        }

	/*
	 * First, paint the signature.
	 * Disclaimers noted below for coloring quotes apply here as well.
	 */
	if((flags & FM_DISPLAY)
	   && !(flags & FM_NOCOLOR)
	   && pico_usingcolor()
	   && VAR_SIGNATURE_FORE_COLOR
	   && VAR_SIGNATURE_BACK_COLOR){
	    filters[filtcnt].filter = gf_quote_test;
	    filters[filtcnt++].data = gf_line_test_opt(color_signature,
						       &is_in_sig);
	}

	/*
	 * Gotta be careful with this. The color_a_quote filter adds color
	 * to the beginning and end of the line. This will break some
	 * line_test-style filters which come after it. For example, if they
	 * are looking for something at the start of a line (like color_a_quote
	 * itself). I guess we could fix that by ignoring tags at the
	 * beginning of the line when doing the search.
	 */
	if((flags & FM_DISPLAY)
	   && !(flags & FM_NOCOLOR)
	   && pico_usingcolor()
	   && VAR_QUOTE1_FORE_COLOR
	   && VAR_QUOTE1_BACK_COLOR){
	    add_me = 0;
	    filters[filtcnt].filter = gf_quote_test;
	    filters[filtcnt++].data = gf_line_test_opt(color_a_quote, &is_flowed_msg);
	}
    }
    else if(!strucmp(att->body->subtype, "richtext")){
	int plain_opt;

	plain_opt = !(flags&FM_DISPLAY);

	/* maybe strip everything! */
	filters[filtcnt].filter = gf_rich2plain;
	filters[filtcnt++].data = gf_rich2plain_opt(&plain_opt);
	/* width to use for file or printer */
	if(wrapit - 5 > 0)
	  wrapit -= 5;
    }
    else if(!strucmp(att->body->subtype, "enriched")){
	int plain_opt;

	plain_opt = !(flags&FM_DISPLAY);

	filters[filtcnt].filter = gf_enriched2plain;
	filters[filtcnt++].data = gf_enriched2plain_opt(&plain_opt);
	/* width to use for file or printer */
	if(wrapit - 5 > 0)
	  wrapit -= 5;
    }
    else if(!strucmp(att->body->subtype, "html") && ps_global->full_header < 2){
/*BUG:	    sniff the params for "version=2.0" ala draft-ietf-html-spec-01 */
	int	 opts = 0;

	clear_html_risk();

	if(flags & FM_DISPLAY){
	    gf_io_t	 warn_pc;

	    if(handlesp){		/* pass on handles awareness */
		opts |= GFHP_HANDLES;

		if(F_OFF(F_QUELL_HOST_AFTER_URL, ps_global) && !(flags & FM_HIDESERVER))
		  opts |= GFHP_SHOW_SERVER;
	    }

	    if(!(flags & FM_NOEDITORIAL)){
		warn_so = so_get(CharStar, NULL, EDIT_ACCESS);
		gf_set_so_writec(&warn_pc, warn_so);
		format_editorial(HTML_WARNING, column, flags, handlesp, warn_pc);
		gf_clear_so_writec(warn_so);
		so_puts(warn_so, "\015\012");
		so_writec('\0', warn_so);
	    }
	}
	else
	  opts |= GFHP_STRIPPED;	/* don't embed anything! */

	if(flags & FM_NOHTMLREL)
	  opts |= GFHP_NO_RELATIVE;

	if(flags & FM_HTMLRELATED)
	  opts |= GFHP_RELATED_CONTENT;

	if(flags & FM_HTML)
	  opts |= GFHP_HTML;

	if(flags & FM_HTMLIMAGES)
	  opts |= GFHP_HTML_IMAGES;

	wrapit = 0;		/* wrap already handled! */
	filters[filtcnt].filter = gf_html2plain;
	filters[filtcnt++].data = gf_html2plain_opt(NULL, column,
						    (flags & (FM_NOINDENT | FM_HTML))
						      ? 0
						      : format_view_margin(),
						    handlesp, set_html_risk, opts);

	if(warn_so){
	    filters[filtcnt].filter = gf_prepend_editorial;
	    filters[filtcnt++].data = gf_prepend_editorial_opt(get_html_risk,
							       (char *) so_text(warn_so));
	}
    }

    if (add_me){
      filters[filtcnt].filter = gf_quote_test;
      filters[filtcnt++].data = gf_line_test_opt(select_quote, &doraw);
    }

    /*
     * If the message is not flowed, we do the quote suppression before
     * the wrapping, because the wrapping does not preserve the quote
     * characters at the beginnings of the lines in that case.
     * Otherwise, we defer until after the wrapping.
     *
     * Also, this is a good place to do quote-replacement on nonflowed
     * messages because no other filters depend on the "> ".
     * Quote-replacement is easier in the flowed case and occurs
     * automatically in the flowed wrapping filter.
     */
    if(!is_flowed_msg
       && ps_global->full_header == 0
       && !(att->body->subtype && strucmp(att->body->subtype, "plain"))
       && (flags & FM_DISPLAY)){
	if(ps_global->quote_suppression_threshold != 0){
	    memset(&dq, 0, sizeof(dq));
	    dq.lines = ps_global->quote_suppression_threshold;
	    dq.is_flowed = is_flowed_msg;
	    dq.indent_length = 0;		/* indent didn't happen yet */
	    dq.saved_line = &free_this;
	    dq.handlesp   = handlesp;
	    dq.do_color   = (!(flags & FM_NOCOLOR) && pico_usingcolor());

	    filters[filtcnt].filter = gf_quote_test;
	    filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
	}
	if(ps_global->VAR_QUOTE_REPLACE_STRING
	    && F_ON(F_QUOTE_REPLACE_NOFLOW, ps_global)){
	    filters[filtcnt].filter = gf_line_test;
	    filters[filtcnt++].data = gf_line_test_opt(replace_quotes, NULL);
	}
    }

    if(wrapit && !(flags & FM_NOWRAP)){
	int wrapflags = (flags & FM_DISPLAY) ? (GFW_HANDLES|GFW_SOFTHYPHEN)
					     : GFW_NONE;

	if(flags & FM_DISPLAY
	   && !(flags & FM_NOCOLOR)
	   && pico_usingcolor())
	  wrapflags |= GFW_USECOLOR;

	/* text/flowed (RFC 2646 + draft)? */
	if(ps_global->full_header != 2 && is_flowed_msg){
	    wrapflags |= GFW_FLOWED;

	    if(is_delsp_yes)
	      wrapflags |= GFW_DELSP;
	}

	filters[filtcnt].filter = gf_wrap;
	filters[filtcnt++].data = gf_wrap_filter_opt(wrapit, column,
						     (flags & FM_NOINDENT)
						       ? 0
						       : format_view_margin(),
						     0, wrapflags);
    }

    /*
     * This has to come after wrapping has happened because the user tells
     * us how many quoted lines to display, and we want that number to be
     * the wrapped lines, not the pre-wrapped lines. We do it before the
     * wrapping if the message is not flowed, because the wrapping does not
     * preserve the quote characters at the beginnings of the lines in that
     * case.
     */
    if(is_flowed_msg
       && ps_global->full_header == 0
       && !(att->body->subtype && strucmp(att->body->subtype, "plain"))
       && (flags & FM_DISPLAY)
       && ps_global->quote_suppression_threshold != 0){
	memset(&dq, 0, sizeof(dq));
	dq.lines = ps_global->quote_suppression_threshold;
	dq.is_flowed = is_flowed_msg;
	dq.indent_length = (wrapit && !(flags & FM_NOWRAP)
			    && !(flags & FM_NOINDENT))
			       ? format_view_margin()[0]
			       : 0;
	dq.saved_line = &free_this;
	dq.handlesp   = handlesp;
	dq.do_color   = (!(flags & FM_NOCOLOR) && pico_usingcolor());

	filters[filtcnt].filter = gf_quote_test;
	filters[filtcnt++].data = gf_line_test_opt(delete_quotes, &dq);
    }

    if(charset){
	if(F_OFF(F_QUELL_CHARSET_WARNING, ps_global)
	   && !(flags & FM_NOEDITORIAL)){
	    int rv = TRUE;
	    CONV_TABLE *ct = NULL;

	    /*
	     * Need editorial if message charset is not ascii
	     * and the display charset is not either the same
	     * as the message charset or UTF-8.
	     */
	    if(strucmp(charset, "us-ascii")
	       && !((ps_global->display_charmap
		     && !strucmp(charset, ps_global->display_charmap))
	            || !strucmp("UTF-8", ps_global->display_charmap))){

		/*
		 * This is probably overkill. We're just using this
		 * conversion_table routine to get at the quality.
		 */
		if(ps_global->display_charmap)
		  ct = conversion_table(charset, ps_global->display_charmap);

		rv = charset_editorial(charset, msgno, handlesp, flags,
				       ct ? ct->quality : CV_NO_TRANSLATE_POSSIBLE,
				       column, pc);
	    }
	    if(!rv)
	      goto write_error;
	}

	fs_give((void **) &charset);
    }

    /* Format editorial comment about unknown encoding */
    if(att->body->encoding > ENCQUOTEDPRINTABLE){
	char buf[2048];

	snprintf(buf, sizeof(buf), ENCODING_DISCLAIMER, body_encodings[att->body->encoding]);

	if(!(format_editorial(buf, column, flags, handlesp, pc) == NULL
	     && gf_puts(NEWLINE, pc) && gf_puts(NEWLINE, pc)))
	  goto write_error;
    }

    err = detach(ps_global->mail_stream, msgno, att->number, 0L,
		 NULL, pc, filtcnt ? filters : NULL, 0);
    
    delete_unused_handles(handlesp);
    
    if(free_this)
      fs_give((void **) &free_this);

    if(warn_so)
      so_give(&warn_so);
    
    if(err) {
	error_found++;
	if(style == QStatus) {
	    q_status_message1(SM_ORDER, 3, 4, "%.200s", err);
	} else if(style == InLine) {
	    char buftmp[MAILTMPLEN];

	    snprintf(buftmp, sizeof(buftmp), "%s",
		    att->body->description ? att->body->description : "");
	    snprintf(tmp_20k_buf, SIZEOF_20KBUF, "%s   [Error: %s]  %c%s%c%s%s",
		    NEWLINE, err,
		    att->body->description ? '\"' : ' ',
		    att->body->description ? buftmp : "",
		    att->body->description ? '\"' : ' ',
		    NEWLINE, NEWLINE);
	    if(!gf_puts(tmp_20k_buf, pc))
	      goto write_error;
	}
    }

    if(att->body->subtype
       && (!strucmp(att->body->subtype, "richtext")
	   || !strucmp(att->body->subtype, "enriched"))
       && !(flags & FM_DISPLAY)){
	if(!gf_puts(NEWLINE, pc) || !gf_puts(NEWLINE, pc))
	  goto write_error;
    }

    return(error_found);

  write_error:
    if(style == QStatus)
      q_status_message1(SM_ORDER, 3, 4, "Error writing message: %.200s", 
			error_description(errno));

    return(1);
}
/*----------------------------------------------------------------------
       Get the current window size
  
   Args: ttyo -- pointer to structure to store window size in

  NOTE: we don't override the given values unless we know better
 ----*/
int
get_windsize(struct ttyo *ttyo)
{
    char	fontName[LF_FACESIZE+1];
    char	fontSize[12];
    char	fontStyle[64];
    char        fontCharSet[256];
    char	windowPosition[32], windowPositionReg[32];
    char	foreColor[64], backColor[64];
    int		newRows, newCols;
    char	cursorStyle[32];

    cursorStyle[0] = '\0';

    /* Get the new window parameters and update the 'pinerc' variables. */
    mswin_getwindow(fontName, sizeof(fontName), fontSize, sizeof(fontSize),
		    fontStyle, sizeof(fontStyle),
		    windowPosition, sizeof(windowPosition),
		    foreColor, sizeof(foreColor),
		    backColor, sizeof(backColor),
		    cursorStyle, sizeof(cursorStyle),
		    fontCharSet, sizeof(fontCharSet));

    if(!ps_global->VAR_FONT_NAME
       || strucmp(ps_global->VAR_FONT_NAME, fontName))
      set_variable(V_FONT_NAME, fontName, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_FONT_SIZE
       || strucmp(ps_global->VAR_FONT_SIZE, fontSize))
      set_variable(V_FONT_SIZE, fontSize, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_FONT_STYLE
       || strucmp(ps_global->VAR_FONT_STYLE, fontStyle))
      set_variable(V_FONT_STYLE, fontStyle, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_FONT_CHAR_SET
       || strucmp(ps_global->VAR_FONT_CHAR_SET, fontCharSet))
      set_variable(V_FONT_CHAR_SET, fontCharSet, 1, 0,
		   ps_global->ew_for_except_vars);

    if(strnicmp(windowPosition, "MIN0", 4) && !strchr(windowPosition, '!')){
	   if(F_ON(F_STORE_WINPOS_IN_CONFIG, ps_global)){
	       if(!ps_global->VAR_WINDOW_POSITION
		  || strucmp(ps_global->VAR_WINDOW_POSITION, windowPosition))
		 set_variable(V_WINDOW_POSITION, windowPosition, 1, 0,
			      ps_global->ew_for_except_vars);
	   }
	   else{
	       /*
		* Get the window position stored in the registry.
		*
		* If current window position is not in the registry or is
		* different from what is there, save it.
		*/
	       if((!mswin_reg(MSWR_OP_GET, MSWR_PINE_POS, windowPositionReg,
			      sizeof(windowPositionReg)) ||
		   strucmp(windowPositionReg, windowPosition))
		  && (ps_global->update_registry != UREG_NEVER_SET))
		 mswin_reg(MSWR_OP_SET | MSWR_OP_FORCE, MSWR_PINE_POS, windowPosition,
			   (size_t)NULL);
	   }
    }
    
    mswin_getprintfont(fontName, sizeof(fontName),
		       fontSize, sizeof(fontSize),
		       fontStyle, sizeof(fontStyle),
		       fontCharSet, sizeof(fontCharSet));
    if(!ps_global->VAR_PRINT_FONT_NAME
       || strucmp(ps_global->VAR_PRINT_FONT_NAME, fontName))
      set_variable(V_PRINT_FONT_NAME, fontName, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_PRINT_FONT_SIZE
       || strucmp(ps_global->VAR_PRINT_FONT_SIZE, fontSize))
      set_variable(V_PRINT_FONT_SIZE, fontSize, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_PRINT_FONT_STYLE
       || strucmp(ps_global->VAR_PRINT_FONT_STYLE, fontStyle))
      set_variable(V_PRINT_FONT_STYLE, fontStyle, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_PRINT_FONT_CHAR_SET
       || strucmp(ps_global->VAR_PRINT_FONT_CHAR_SET, fontCharSet))
      set_variable(V_PRINT_FONT_CHAR_SET, fontCharSet, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_NORM_FORE_COLOR
       || strucmp(ps_global->VAR_NORM_FORE_COLOR, foreColor))
      set_variable(V_NORM_FORE_COLOR, foreColor, 1, 0,
		   ps_global->ew_for_except_vars);

    if(!ps_global->VAR_NORM_BACK_COLOR
       || strucmp(ps_global->VAR_NORM_BACK_COLOR, backColor))
      set_variable(V_NORM_BACK_COLOR, backColor, 1, 0,
		   ps_global->ew_for_except_vars);

    if(cursorStyle[0] && !ps_global->VAR_CURSOR_STYLE
       || strucmp(ps_global->VAR_CURSOR_STYLE, cursorStyle))
      set_variable(V_CURSOR_STYLE, cursorStyle, 1, 0,
		   ps_global->ew_for_except_vars);

    /* Get new window size.  Compare to old.  The window may have just
     * moved, in which case we don't bother updating the size. */
    mswin_getscreensize(&newRows, &newCols);
    if (newRows == ttyo->screen_rows && newCols == ttyo->screen_cols)
	    return (NO_OP_COMMAND);

    /* True resize. */
    ttyo->screen_rows = newRows;
    ttyo->screen_cols = newCols;

    if (ttyo->screen_rows > MAX_SCREEN_ROWS)
	ttyo->screen_rows = MAX_SCREEN_ROWS;
    if (ttyo->screen_cols > MAX_SCREEN_COLS)
	ttyo->screen_cols = MAX_SCREEN_COLS;

    return(KEY_RESIZE);
}
Beispiel #20
0
/*----------------------------------------------------------------------
       Open the printer

  Args: desc -- Description of item to print. Should have one trailing blank.

  Return value: < 0 is a failure.
		0 a success.

This does most of the work of popen so we can save the standard output of the
command we execute and send it back to the user.
  ----*/
int
open_printer(char *desc)
{
#ifndef _WINDOWS
    char command[201], prompt[200];
    int  cmd, rc, just_one;
    char *p, *init, *nick;
    char aname[100], wname[100];
    char *printer;
    int	 done = 0, i, lastprinter, cur_printer = 0;
    HelpType help;
    char   **list;
    static ESCKEY_S ekey[] = {
	/* TRANSLATORS: these are command labels for printing screen */
	{'y', 'y', "Y", N_("Yes")},
	{'n', 'n', "N", N_("No")},
	/* TRANSLATORS: go to Previous Printer in list */
	{ctrl('P'), 10, "^P", N_("Prev Printer")},
	{ctrl('N'), 11, "^N", N_("Next Printer")},
	{-2,   0,   NULL, NULL},
	/* TRANSLATORS: use Custom Print command */
	{'c', 'c', "C", N_("CustomPrint")},
	{KEY_UP,    10, "", ""},
	{KEY_DOWN,  11, "", ""},
	{-1, 0, NULL, NULL}};
#define PREV_KEY   2
#define NEXT_KEY   3
#define CUSTOM_KEY 5
#define UP_KEY     6
#define DOWN_KEY   7

    trailer      = NULL;
    init         = NULL;
    nick         = NULL;
    command[sizeof(command)-1] = '\0';

    if(ps_global->VAR_PRINTER == NULL){
        q_status_message(SM_ORDER | SM_DING, 3, 5,
	"No printer has been chosen.  Use SETUP on main menu to make choice.");
	return(-1);
    }

    /* Is there just one print command available? */
    just_one = (ps_global->printer_category!=3&&ps_global->printer_category!=2)
	       || (ps_global->printer_category == 2
		   && !(ps_global->VAR_STANDARD_PRINTER
			&& ps_global->VAR_STANDARD_PRINTER[0]
			&& ps_global->VAR_STANDARD_PRINTER[1]))
	       || (ps_global->printer_category == 3
		   && !(ps_global->VAR_PERSONAL_PRINT_COMMAND
			&& ps_global->VAR_PERSONAL_PRINT_COMMAND[0]
			&& ps_global->VAR_PERSONAL_PRINT_COMMAND[1]));

    if(F_ON(F_CUSTOM_PRINT, ps_global))
      ekey[CUSTOM_KEY].ch = 'c'; /* turn this key on */
    else
      ekey[CUSTOM_KEY].ch = -2;  /* turn this key off */

    if(just_one){
	ekey[PREV_KEY].ch = -2;  /* turn these keys off */
	ekey[NEXT_KEY].ch = -2;
	ekey[UP_KEY].ch   = -2;
	ekey[DOWN_KEY].ch = -2;
    }
    else{
	ekey[PREV_KEY].ch = ctrl('P'); /* turn these keys on */
	ekey[NEXT_KEY].ch = ctrl('N');
	ekey[UP_KEY].ch   = KEY_UP;
	ekey[DOWN_KEY].ch = KEY_DOWN;
	/*
	 * count how many printers in list and find the default in the list
	 */
	if(ps_global->printer_category == 2)
	  list = ps_global->VAR_STANDARD_PRINTER;
	else
	  list = ps_global->VAR_PERSONAL_PRINT_COMMAND;

	for(i = 0; list[i]; i++)
	  if(strcmp(ps_global->VAR_PRINTER, list[i]) == 0)
	    cur_printer = i;
	
	lastprinter = i - 1;
    }

    help = NO_HELP;
    ps_global->mangled_footer = 1;

    while(!done){
	if(init)
	  fs_give((void **)&init);

	if(trailer)
	  fs_give((void **)&trailer);

	if(just_one)
	  printer = ps_global->VAR_PRINTER;
	else
	  printer = list[cur_printer];

	parse_printer(printer, &nick, &p, &init, &trailer, NULL, NULL);
	strncpy(command, p, sizeof(command)-1);
	command[sizeof(command)-1] = '\0';
	fs_give((void **)&p);
	/* TRANSLATORS: Print something1 using something2.
	   For example, Print configuration using printer three. */
	snprintf(prompt, sizeof(prompt), _("Print %s using \"%s\" ? "),
		desc ? desc : "",
		*nick ? nick : command);
	prompt[sizeof(prompt)-1] = '\0';

	fs_give((void **)&nick);
	
	cmd = radio_buttons(prompt, -FOOTER_ROWS(ps_global),
				 ekey, 'y', 'x', help, RB_NORM);
	
	switch(cmd){
	  case 'y':
	    q_status_message1(SM_ORDER, 0, 9,
		"Printing with command \"%s\"", command);
	    done++;
	    break;

	  case 10:
	    cur_printer = (cur_printer>0)
				? (cur_printer-1)
				: lastprinter;
	    break;

	  case 11:
	    cur_printer = (cur_printer<lastprinter)
				? (cur_printer+1)
				: 0;
	    break;

	  case 'n':
	  case 'x':
	    done++;
	    break;

	  case 'c':
	    done++;
	    break;

	  default:
	    break;
	}
    }

    if(cmd == 'c'){
	if(init)
	  fs_give((void **)&init);

	if(trailer)
	  fs_give((void **)&trailer);

	snprintf(prompt, sizeof(prompt), "Enter custom command : ");
	prompt[sizeof(prompt)-1] = '\0';
	command[0] = '\0';
	rc = 1;
	help = NO_HELP;
	while(rc){
	    int flags = OE_APPEND_CURRENT;

	    rc = optionally_enter(command, -FOOTER_ROWS(ps_global), 0,
		sizeof(command), prompt, NULL, help, &flags);
	    
	    if(rc == 1){
		cmd = 'x';
		rc = 0;
	    }
	    else if(rc == 3)
	      help = (help == NO_HELP) ? h_custom_print : NO_HELP;
	    else if(rc == 0){
		removing_trailing_white_space(command);
		removing_leading_white_space(command);
		q_status_message1(SM_ORDER, 0, 9,
		    "Printing with command \"%s\"", command);
	    }
	}
    }

    if(cmd == 'x' || cmd == 'n'){
	q_status_message(SM_ORDER, 0, 2, "Print cancelled");
	if(init)
	  fs_give((void **)&init);

	if(trailer)
	  fs_give((void **)&trailer);

	return(-1);
    }

    display_message('x');

    ps_global->print = (PRINT_S *)fs_get(sizeof(PRINT_S));
    memset(ps_global->print, 0, sizeof(PRINT_S));

    strncpy(aname, ANSI_PRINTER, sizeof(aname)-1);
    aname[sizeof(aname)-1] = '\0';
    strncat(aname, "-no-formfeed", sizeof(aname)-strlen(aname)-1);
    strncpy(wname, WYSE_PRINTER, sizeof(wname)-1);
    wname[sizeof(wname)-1] = '\0';
    strncat(wname, "-no-formfeed", sizeof(wname)-strlen(wname)-1);
    if(strucmp(command, ANSI_PRINTER) == 0
       || strucmp(command, aname) == 0
       || strucmp(command, WYSE_PRINTER) == 0
       || strucmp(command, wname) == 0){
        /*----------- Attached printer ---------*/
        q_status_message(SM_ORDER, 0, 9,
	    "Printing to attached desktop printer...");
        display_message('x');
	xonxoff_proc(1);			/* make sure XON/XOFF used */
	crlf_proc(1);				/* AND LF->CR xlation */
	if(strucmp(command, ANSI_PRINTER) == 0
	   || strucmp(command, aname) == 0){
	    fputs("\033[5i", stdout);
	    ansi_off = 1;
	}
	else{
	    ansi_off = 0;
	    printf("%c", 18); /* aux on for wyse60,
			         Chuck Everett <*****@*****.**> */
	}

        ps_global->print->fp = stdout;
        if(strucmp(command, ANSI_PRINTER) == 0
	   || strucmp(command, WYSE_PRINTER) == 0){
	    /* put formfeed at the end of the trailer string */
	    if(trailer){
		int len = strlen(trailer);

		fs_resize((void **)&trailer, len+2);
		trailer[len] = '\f';
		trailer[len+1] = '\0';
	    }
	    else
	      trailer = cpystr("\f");
	}
    }
    else{
        /*----------- Print by forking off a UNIX command ------------*/
        dprint((4, "Printing using command \"%s\"\n",
	       command ? command : "?"));
	ps_global->print->result = temp_nam(NULL, "pine_prt");
	if(ps_global->print->result &&
	   (ps_global->print->pipe = open_system_pipe(command,
						      &ps_global->print->result, NULL,
						      PIPE_WRITE | PIPE_STDERR, 0,
						      pipe_callback, NULL))){
	    ps_global->print->fp = ps_global->print->pipe->out.f;
	}
	else{
	    if(ps_global->print->result){
		our_unlink(ps_global->print->result);
		fs_give((void **)&ps_global->print->result);
	    }

            q_status_message1(SM_ORDER | SM_DING, 3, 4,
			      "Error opening printer: %s",
                              error_description(errno));
            dprint((2, "Error popening printer \"%s\"\n",
                      error_description(errno)));
	    if(init)
	      fs_give((void **)&init);

	    if(trailer)
	      fs_give((void **)&trailer);
	    
	    return(-1);
        }
    }

    ps_global->print->err = 0;
    if(init){
	if(*init)
	  fputs(init, ps_global->print->fp);

	fs_give((void **)&init);
    }

    cb.cbuf[0] = '\0';
    cb.cbufp   = cb.cbuf;
    cb.cbufend = cb.cbuf;
#else /* _WINDOWS */
    int status;
    LPTSTR desclpt = NULL;

    if(desc)
      desclpt = utf8_to_lptstr(desc);

    if (status = mswin_print_ready (0, desclpt)) {
        q_status_message1(SM_ORDER | SM_DING, 3, 4,
			  "Error starting print job: %s",
			  mswin_print_error(status));
	if(desclpt)
	  fs_give((void **) &desclpt);

        return(-1);
    }

    if(desclpt)
      fs_give((void **) &desclpt);

    q_status_message(SM_ORDER, 0, 9, "Printing to windows printer...");
    display_message('x');

    /* init print control structure */
    ps_global->print = (PRINT_S *)fs_get(sizeof(PRINT_S));
    memset(ps_global->print, 0, sizeof(PRINT_S));

    ps_global->print->err = 0;
#endif /* _WINDOWS */

    return(0);
}
Beispiel #21
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);
}