int our_stat(char *filename, struct stat *sbuf) { #ifdef _WINDOWS LPTSTR f = NULL; int ret = -1; struct _stat s; f = utf8_to_lptstr((LPSTR) filename); if(f){ ret = _tstat(f, &s); sbuf->st_dev = s.st_dev; sbuf->st_ino = s.st_ino; sbuf->st_mode = s.st_mode; sbuf->st_nlink = s.st_nlink; sbuf->st_uid = s.st_uid; sbuf->st_gid = s.st_gid; sbuf->st_rdev = s.st_rdev; sbuf->st_size = s.st_size; sbuf->st_atime = (time_t) s.st_atime; sbuf->st_mtime = (time_t) s.st_mtime; sbuf->st_ctime = (time_t) s.st_ctime; fs_give((void **) &f); } return ret; #else /* UNIX */ return(stat(fname_to_locale(filename), sbuf)); #endif /* UNIX */ }
int our_open(char *path, int flags, mode_t mode) { #ifdef _WINDOWS LPTSTR p = NULL; int ret = -1; /* * Setting the _O_WTEXT flag when opening a file for reading * will cause us to read the first few bytes to check for * a BOM and to translate from that encoding if we find it. * This only works with stream I/O, not low-level read/write. * * When opening for writing the flag _O_U8TEXT will cause * us to put a UTF-8 BOM at the start of the file. * * O_TEXT will cause LF -> CRLF on output, opposite on input * O_BINARY suppresses that. * _O_U8TEXT implies O_TEXT. */ p = utf8_to_lptstr((LPSTR) path); if(p){ ret = _topen(p, flags, mode); fs_give((void **) &p); } return ret; #else /* UNIX */ return(open(fname_to_locale(path), flags, mode)); #endif /* UNIX */ }
/* * 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 }
int our_rename(char *oldpath, char *newpath) { #ifdef _WINDOWS LPTSTR pold = NULL, pnew = NULL; int ret = -1; pold = utf8_to_lptstr((LPSTR) oldpath); pnew = utf8_to_lptstr((LPSTR) newpath); if(pold && pnew) ret = _trename(pold, pnew); if(pold) fs_give((void **) &pold); if(pnew) fs_give((void **) &pnew); return ret; #else /* UNIX */ char *p, *pold; size_t len; int ret = -1; p = fname_to_locale(oldpath); if(p){ len = strlen(p); pold = (char *) fs_get((len+1) * sizeof(char)); strncpy(pold, p, len+1); pold[len] = '\0'; ret = rename(pold, fname_to_locale(newpath)); fs_give((void **) &pold); } return ret; #endif /* UNIX */ }
int our_access(char *path, int mode) { #ifdef _WINDOWS LPTSTR p = NULL; int ret = -1; p = utf8_to_lptstr((LPSTR) path); if(p){ ret = _taccess(p, mode); fs_give((void **) &p); } return ret; #else /* UNIX */ return(access(fname_to_locale(path), mode)); #endif /* UNIX */ }
int our_utime(char *path, struct utimbuf *buf) { #ifdef _WINDOWS LPTSTR p = NULL; int ret = -1; p = utf8_to_lptstr((LPSTR) path); if(p){ ret = _tutime(p, buf); fs_give((void **) &p); } return ret; #else /* UNIX */ return(utime(fname_to_locale(path), buf)); #endif /* UNIX */ }
int our_unlink(char *path) { #ifdef _WINDOWS LPTSTR p = NULL; int ret = -1; p = utf8_to_lptstr((LPSTR) path); if(p){ ret = _tunlink(p); fs_give((void **) &p); } return ret; #else /* UNIX */ return(unlink(fname_to_locale(path))); #endif /* UNIX */ }
int our_mkdir(char *path, mode_t mode) { #ifdef _WINDOWS /* mode is a noop for _WINDOWS */ LPTSTR p = NULL; int ret = -1; p = utf8_to_lptstr((LPSTR) path); if(p){ ret = _tmkdir(p); fs_give((void **) &p); } return ret; #else /* UNIX */ return(mkdir(fname_to_locale(path), mode)); #endif /* UNIX */ }
/* * Given a mime-type, return the file extension if there is one * * Returns: 1 on success, 0 on failure */ int mime_get_os_ext_from_mimetype(char *mime_type, char *file_ext, int file_ext_len) { #ifdef _WINDOWS int ret; LPTSTR x, mime_type_lpt, file_ext_lpt; mime_type_lpt = utf8_to_lptstr(mime_type); if(mime_type_lpt){ if(file_ext){ file_ext_lpt = (LPTSTR) fs_get(file_ext_len * sizeof(TCHAR)); file_ext_lpt[0] = '\0'; } else file_ext_lpt = NULL; } ret = mswin_reg_mime_ext(mime_type_lpt, file_ext_lpt, (size_t) file_ext_len); /* convert answer back to UTF-8 */ if(ret && file_ext_lpt && file_ext){ char *u; u = lptstr_to_utf8(file_ext_lpt); if(u){ strncpy(file_ext, u, file_ext_len); file_ext[file_ext_len-1] = '\0'; fs_give((void **) &u); } } if(mime_type_lpt) fs_give((void **) &mime_type_lpt); if(file_ext_lpt) fs_give((void **) &file_ext_lpt); return ret; #elif OSX_TARGET if(!mime_os_specific_access()) return(0); #ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER CFStringRef mime_ref = NULL, type_id_ref = NULL, ext_ref = NULL; if(!mime_type || !*mime_type) return 0; /* This for if we built on OS X >= 10.3 but run on < 10.3 */ if(&UTTypeCreatePreferredIdentifierForTag == NULL) return 0; if((mime_ref = CFStringCreateWithCString(NULL, mime_type, kCFStringEncodingASCII)) == NULL) return 0; if((type_id_ref = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mime_ref, NULL)) == NULL) return 0; if((ext_ref = UTTypeCopyPreferredTagWithClass(type_id_ref, kUTTagClassFilenameExtension)) == NULL) return 0; if((CFStringGetCString(ext_ref, file_ext, (CFIndex)file_ext_len - 1, kCFStringEncodingASCII)) == false) return 0; file_ext[file_ext_len - 1] = '\0'; return 1; #else return 0; #endif /* AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER */ #else return 0; #endif /* OSX_TARGET */ }
/* * Dialog proc to handle login * * Configures the dialog box on init and retrieves the settings on exit. */ BOOL CALLBACK __export config_dialog_proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { DLG_CONFIGDATA *dlgcfg; BOOL ret = FALSE; int checked, def_rem_fldr = 1, def_diff_fldr = 0; switch (uMsg) { case WM_INITDIALOG: dlgcfg = (DLG_CONFIGDATA *)lParam; SetWindowLong (hDlg, WINDOW_USER_DATA, (LONG) dlgcfg); if(ps_global->install_flag) SetDlgItemText(hDlg, IDC_CONFTEXT, TEXT("Please specify where Alpine should create (or look for) your personal configuration file.")); SetDlgItemText(hDlg, IDC_CONFEFLDRNAME, TEXT("remote_pinerc")); if(*dlgcfg->confpath){ if(dlgcfg->confpath[0] == '{'){ LPTSTR tfldr, p, tfldr2, p2, user; tfldr = utf8_to_lptstr((LPSTR)(dlgcfg->confpath+1)); if(p = _tcschr(tfldr, '}')){ *p++ = '\0'; if(_tcscmp(TEXT("remote_pinerc"), p)){ SetDlgItemText(hDlg, IDC_CONFEFLDRNAME, p); def_diff_fldr = 1; } tfldr2 = _tcsdup(tfldr); for(p = tfldr, p2 = tfldr2; *p; p++) if(*p == '/' && !_tcsnicmp(p, TEXT("/user="******"remote_pinerc")); break; case IDC_CONFRRADIO: case IDC_CONFLRADIO: CheckRadioButton (hDlg, IDC_CONFRRADIO, IDC_CONFLRADIO, wParam); EnableWindow(GetDlgItem(hDlg, IDC_CONFFNTXT), wParam == IDC_CONFRRADIO ? 0 : 1); EnableWindow(GetDlgItem(hDlg, IDC_CONFEFN), wParam == IDC_CONFRRADIO ? 0 : 1); EnableWindow(GetDlgItem(hDlg, IDC_CONFBROWSE), wParam == IDC_CONFRRADIO ? 0 : 1); EnableWindow(GetDlgItem(hDlg, IDC_CONFSRVRTXT), wParam == IDC_CONFRRADIO ? 1 : 0); EnableWindow(GetDlgItem(hDlg, IDC_CONFESERVER), wParam == IDC_CONFRRADIO ? 1 : 0); EnableWindow(GetDlgItem(hDlg, IDC_CONFUNTXT), wParam == IDC_CONFRRADIO ? 1 : 0); EnableWindow(GetDlgItem(hDlg, IDC_CONFEUSERNAME), wParam == IDC_CONFRRADIO ? 1 : 0); EnableWindow(GetDlgItem(hDlg, IDC_CONFDFLTFLDR), wParam == IDC_CONFRRADIO ? 1 : 0); if(wParam == IDC_CONFRRADIO && IsDlgButtonChecked(hDlg, IDC_CONFDFLTFLDR) == BST_UNCHECKED){ EnableWindow(GetDlgItem(hDlg, IDC_CONFFLDRTXT), 1); EnableWindow(GetDlgItem(hDlg, IDC_CONFEFLDRNAME), 1); } else if(wParam == IDC_CONFLRADIO){ EnableWindow(GetDlgItem(hDlg, IDC_CONFFLDRTXT), 0); EnableWindow(GetDlgItem(hDlg, IDC_CONFEFLDRNAME), 0); } break; case IDC_CONFBROWSE: if(1){ TCHAR fn[MAXPATH+1]; OPENFILENAME ofn; fn[0] = '\0'; /* Set up the BIG STRUCTURE. see mswin.c */ memset (&ofn, 0, sizeof(ofn)); ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; ofn.hwndOwner = hDlg; ofn.lpstrFilter = NULL; ofn.lpstrCustomFilter = NULL; ofn.nFilterIndex = 0; ofn.lpstrFile = fn; ofn.nMaxFile = MAXPATH; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.lpstrTitle = TEXT("Select File"); ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; ofn.lpstrDefExt = NULL; if (GetOpenFileName (&ofn)) { SetDlgItemText(hDlg, IDC_CONFEFN, fn); } } break; case IDOK: /* Retrieve the new username/passwd. */ if(IsDlgButtonChecked(hDlg, IDC_CONFDFLTSET) == BST_CHECKED) dlgcfg->setreg = 1; else dlgcfg->setreg = 0; if(IsDlgButtonChecked(hDlg, IDC_CONFRRADIO) == BST_CHECKED){ TCHAR lptstr_buf[MAXPATH+1]; char *utf8_srvr, *utf8_username, *utf8_fldrname; GetDlgItemText(hDlg, IDC_CONFESERVER, lptstr_buf, MAXPATH); lptstr_buf[MAXPATH] = '\0'; utf8_srvr = lptstr_to_utf8(lptstr_buf); removing_leading_and_trailing_white_space(utf8_srvr); if(!*utf8_srvr){ MessageBox(hDlg, TEXT("IMAP Server field empty"), TEXT("Alpine"), MB_ICONWARNING | MB_OK); if(utf8_srvr) fs_give((void **) &utf8_srvr); return(TRUE); } GetDlgItemText(hDlg, IDC_CONFEUSERNAME, lptstr_buf, MAXPATH); lptstr_buf[MAXPATH] = '\0'; utf8_username = lptstr_to_utf8(lptstr_buf); removing_leading_and_trailing_white_space(utf8_username); if(IsDlgButtonChecked(hDlg, IDC_CONFDFLTFLDR) == BST_CHECKED){ utf8_fldrname = cpystr("remote_pinerc"); } else{ GetDlgItemText(hDlg, IDC_CONFEFLDRNAME, lptstr_buf, MAXPATH); lptstr_buf[MAXPATH] = '\0'; utf8_fldrname = lptstr_to_utf8(lptstr_buf); removing_leading_and_trailing_white_space(utf8_fldrname); if(!*utf8_fldrname){ MessageBox(hDlg, TEXT("Configuration Folder Name field empty"), TEXT("Alpine"), MB_ICONWARNING | MB_OK); if(utf8_srvr) fs_give((void **) &utf8_srvr); if(utf8_username) fs_give((void **) &utf8_username); if(utf8_fldrname) fs_give((void **) &utf8_fldrname); return(TRUE); } } if((strlen(utf8_srvr) + strlen(utf8_username) + strlen(utf8_fldrname) + 11) > dlgcfg->confpathlen){ MessageBox(hDlg, TEXT("Config path too long"), TEXT("Alpine"), MB_ICONWARNING | MB_OK); if(utf8_srvr) fs_give((void **) &utf8_srvr); if(utf8_username) fs_give((void **) &utf8_username); if(utf8_fldrname) fs_give((void **) &utf8_fldrname); return(TRUE); } snprintf(dlgcfg->confpath, dlgcfg->confpathlen, "{%s%s%s}%s", utf8_srvr, *utf8_username ? "/user="******"", utf8_username, utf8_fldrname); if(utf8_srvr) fs_give((void **) &utf8_srvr); if(utf8_username) fs_give((void **) &utf8_username); if(utf8_fldrname) fs_give((void **) &utf8_fldrname); } else{ TCHAR lptstr_fn[MAXPATH+1]; char *utf8_fn; GetDlgItemText(hDlg, IDC_CONFEFN, lptstr_fn, MAXPATH); lptstr_fn[MAXPATH] = '\0'; utf8_fn = lptstr_to_utf8(lptstr_fn); removing_leading_and_trailing_white_space(utf8_fn); if(!*utf8_fn){ MessageBox(hDlg, TEXT("Configuration File Name field empty"), TEXT("Alpine"), MB_ICONWARNING | MB_OK); if(utf8_fn) fs_give((void **) &utf8_fn); return(TRUE); } if(strlen(utf8_fn) >= dlgcfg->confpathlen){ MessageBox(hDlg, TEXT("Config path too long"), TEXT("Alpine"), MB_ICONWARNING | MB_OK); if(utf8_fn) fs_give((void **) &utf8_fn); return(TRUE); } strncpy(dlgcfg->confpath, utf8_fn, dlgcfg->confpathlen); dlgcfg->confpath[dlgcfg->confpathlen-1] = '\0'; if(utf8_fn) fs_give((void **) &utf8_fn); } EndDialog (hDlg, LOWORD(wParam)); dlgcfg->rv = 0; ret = TRUE; break; case IDCANCEL: dlgcfg->rv = 1; ret = TRUE; EndDialog (hDlg, LOWORD(wParam)); break; } break; } return (ret); }
FILE * our_fopen(char *path, char *mode) { #ifdef _WINDOWS LPTSTR p = NULL, m = NULL; FILE *ret = NULL; char *mode_with_ccs = NULL; char buf[500]; size_t len; if(mode && (*mode == 'r' || *mode == 'a')){ char *force_bom_check = ", ccs=UNICODE"; if(strchr(mode, 'b')) mode_with_ccs = mode; else{ /* * The docs seem to say that we don't need the ccs parameter and * if the file has a BOM at the beginning it will notice that and * use it. However, we're not seeing that. Instead, what we see is * that giving a parameter of UNICODE causes the desired behavior. * This causes it to check for a BOM and if it finds one it uses it. * If it doesn't find one, it treats the file as ANSI, which is what * we want. */ if((len = strlen(mode) + strlen(force_bom_check)) < sizeof(buf)){ len = sizeof(buf)-1; mode_with_ccs = buf; } else mode_with_ccs = (char *) MemAlloc((len+1) * sizeof(char)); if(mode_with_ccs) snprintf(mode_with_ccs, len+1, "%s%s", mode, force_bom_check); else mode_with_ccs = mode; /* can't happen */ } } else if(mode && (*mode == 'w')){ char *force_utf8 = ", ccs=UTF-8"; if(strchr(mode, 'b')) mode_with_ccs = mode; else{ if((len = strlen(mode) + strlen(force_utf8)) < sizeof(buf)){ len = sizeof(buf)-1; mode_with_ccs = buf; } else mode_with_ccs = (char *) MemAlloc((len+1) * sizeof(char)); if(mode_with_ccs) snprintf(mode_with_ccs, len+1, "%s%s", mode, force_utf8); else mode_with_ccs = mode; /* can't happen */ } } p = utf8_to_lptstr((LPSTR) path); if(p){ m = utf8_to_lptstr((LPSTR) mode_with_ccs); if(m){ ret = _tfopen(p, m); MemFree((void *) m); } fs_give((void **) &p); } if(mode_with_ccs && mode_with_ccs != buf && mode_with_ccs != mode) MemFree((void *) mode_with_ccs); return ret; #else /* UNIX */ return(fopen(fname_to_locale(path), mode)); #endif /* UNIX */ }
/* * Prompt for username and password */ int os_login_dialog (NETMBX *mb, char *user_utf8, int userlen, char *pwd_utf8, int pwdlen, int pwc, int fixuser, int *prespass) { DLGPROC dlgprc; HINSTANCE hInst; HWND hWnd; DLG_LOGINDATA dlgpw; LPTSTR user_lptstr, pwd_lptstr; char *tuser_utf8, *tpwd_utf8; mswin_killsplash(); hInst = (HINSTANCE) mswin_gethinstance (); hWnd = (HWND) mswin_gethwnd (); dlgpw.mb = mb; dlgpw.user = (LPTSTR)fs_get(userlen*sizeof(TCHAR)); user_lptstr = utf8_to_lptstr(user_utf8); _tcsncpy(dlgpw.user, user_lptstr, userlen - 1); dlgpw.user[userlen - 1] = '\0'; fs_give((void **) &user_lptstr); dlgpw.userlen = userlen; dlgpw.pwd = (LPTSTR)fs_get(pwdlen*sizeof(TCHAR)); pwd_lptstr = utf8_to_lptstr(pwd_utf8); _tcsncpy(dlgpw.pwd, pwd_lptstr, pwdlen - 1); dlgpw.pwd[pwdlen - 1] = '\0'; fs_give((void **) &pwd_lptstr); dlgpw.pwdlen = pwdlen; dlgpw.fixuser = fixuser; dlgpw.pwc = pwc; dlgpw.rv = 0; dlgprc = login_dialog_proc; DialogBoxParam (hInst, MAKEINTRESOURCE (ps_global->install_flag ? IDD_LOGINDLG2 : IDD_LOGINDLG), NULL, dlgprc, (LPARAM)&dlgpw); if(dlgpw.rv == 0){ tuser_utf8 = lptstr_to_utf8(dlgpw.user); if(tuser_utf8){ strncpy(user_utf8, tuser_utf8, userlen - 1); user_utf8[userlen - 1] = '\0'; fs_give((void **) &tuser_utf8); } tpwd_utf8 = lptstr_to_utf8(dlgpw.pwd); if(tpwd_utf8){ strncpy(pwd_utf8, tpwd_utf8, pwdlen - 1); pwd_utf8[pwdlen - 1] = '\0'; fs_give((void **) &tpwd_utf8); } if(prespass) (*prespass) = dlgpw.prespass; } return(dlgpw.rv); }
/* * Dialog proc to handle index sort selection. * * Configures the dialog box on init and retrieves the settings on exit. */ BOOL CALLBACK __export args_dialog_proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL ret = FALSE; long i, j, block_size; char **args_text; LPTSTR args_text_lptstr, args_block_lptstr; switch (uMsg) { case WM_INITDIALOG: args_text = (char **)lParam; /* * First convert char *'s over to one big block of * Unicode */ i = 0; while(args_text && *args_text){ i += strlen(*args_text++); i += 2; } block_size = i; args_block_lptstr = (LPTSTR)fs_get((block_size+1)*sizeof(TCHAR)); args_text = (char **)lParam; i = 0; j = 0; while(args_text && *args_text){ args_text_lptstr = utf8_to_lptstr(*args_text++); while(args_text_lptstr[i] && j < block_size){ args_block_lptstr[j++] = args_text_lptstr[i++]; } args_block_lptstr[j++] = '\r'; args_block_lptstr[j++] = '\n'; fs_give((void **) &args_text_lptstr); i = 0; } args_block_lptstr[j] = '\0'; /* and replace everything selected with args_text */ SendDlgItemMessage(hDlg, IDC_ARGTEXT, WM_SETTEXT, (WPARAM) 0, (LPARAM) args_block_lptstr); fs_give((void **)&args_block_lptstr); return (1); case WM_CLOSE : ret = TRUE; EndDialog (hDlg, TRUE); break; case WM_COMMAND: switch (wParam) { case IDOK: ret = TRUE; EndDialog (hDlg, TRUE); break; } break; } return (ret); }
/* * 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); }
/* * Dialog proc to handle login * * Configures the dialog box on init and retrieves the settings on exit. */ BOOL CALLBACK __export login_dialog_proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { DLG_LOGINDATA *dlglogin; BOOL ret = FALSE; TCHAR tcbuf[1024]; NETMBX *mb; LPTSTR user, pwd; LPTSTR host_lptstr; switch (uMsg) { case WM_INITDIALOG: dlglogin = (DLG_LOGINDATA *)lParam; mb = dlglogin->mb; user = dlglogin->user; pwd = dlglogin->pwd; SetWindowLong (hDlg, WINDOW_USER_DATA, (LONG) dlglogin); host_lptstr = utf8_to_lptstr(mb->host); _sntprintf(tcbuf, sizeof(tcbuf), TEXT("Host: %.100s%s"), host_lptstr, !mb->sslflag && !mb->tlsflag ? TEXT(" (INSECURE)") : TEXT("")); fs_give((void **) &host_lptstr); if(mb->sslflag || mb->tlsflag) SetWindowText(hDlg, TEXT("Alpine Login +")); else SetWindowText(hDlg, TEXT("Alpine Insecure Login")); if(dlglogin->pwc){ EnableWindow(GetDlgItem(hDlg, IDC_RPASSWORD),0); EnableWindow(GetDlgItem(hDlg, IDC_RPWTEXT),0); EnableWindow(GetDlgItem(hDlg, IDC_PRESPASS),0); } if(mb->user && *mb->user){ LPTSTR user_lptstr; user_lptstr = utf8_to_lptstr(mb->user); SetDlgItemText(hDlg, IDC_RLOGINE, user_lptstr); if((mb->user && *mb->user) || dlglogin->fixuser) EnableWindow(GetDlgItem(hDlg, IDC_RLOGINE), 0); fs_give((void **) &user_lptstr); } else if(user){ SetDlgItemText(hDlg, IDC_RLOGINE, user); if(dlglogin->fixuser) EnableWindow(GetDlgItem(hDlg, IDC_RLOGINE), 0); } SetDlgItemText(hDlg, IDC_PROMPT, tcbuf); return (1); case WM_COMMAND: dlglogin = (DLG_LOGINDATA *) GetWindowLong (hDlg, WINDOW_USER_DATA); switch (wParam) { case IDOK: /* Retrieve the new username/passwd. */ user = dlglogin->user; pwd = dlglogin->pwd; GetDlgItemText(hDlg, IDC_RLOGINE, user, dlglogin->userlen - 1); GetDlgItemText(hDlg, IDC_RPASSWORD, pwd, dlglogin->pwdlen - 1); user[dlglogin->userlen - 1] = '\0'; pwd[dlglogin->pwdlen - 1] = '\0'; dlglogin->prespass = (IsDlgButtonChecked(hDlg, IDC_PRESPASS) == BST_CHECKED); EndDialog (hDlg, LOWORD(wParam)); dlglogin->rv = 0; ret = TRUE; break; case IDCANCEL: dlglogin->rv = 1; ret = TRUE; EndDialog (hDlg, LOWORD(wParam)); break; } break; } return (ret); }
/* ---------------------------------------------------------------------- Execute the given mailcap command Args: cmd -- the command to execute image_file -- the file the data is in needsterminal -- does this command want to take over the terminal? ----*/ void exec_mailcap_cmd(MCAP_CMD_S *mc_cmd, char *image_file, int needsterminal) { #ifdef _WINDOWS STARTUPINFO start_info; PROCESS_INFORMATION proc_info; WINHAND childProcess; int success = 0; char *cmd; LPTSTR image_file_lpt = NULL; LPTSTR cmd_lpt = NULL; /* no special handling yet, but could be used to replace '*' hack */ if(mc_cmd) cmd = mc_cmd->command; else return; dprint((9, "run_viewer: command=%s\n", cmd ? cmd : "?")) ; if(image_file) image_file_lpt = utf8_to_lptstr(image_file); /* Set to READONLY so the viewer can't try to edit it and keep it around */ if(image_file_lpt) SetFileAttributes(image_file_lpt, FILE_ATTRIBUTE_READONLY); if(*cmd == '*' || (*cmd == '\"' && *(cmd+1) == '*')){ /* * It has been asked that there be the ability to do an * "Open With..." on attachments like you can from the * Windows file browser. After looking into this, it * seems that the only way to do this would be through * an undocumented hack. Here, we would pass "openas" as * the verb to mswin_shell_exec (also some changes in * mswin_shell_exec). Since this is the delicate world * of attachment handling, it seems right not to rely on * a hack. The interface wouldn't be too clean anyways, * as we would have to download the attachment only to * display the "Open With..." dialog. Go figure, some * things Microsoft just wants to keep to themselves. */ /* * 2/1/2007. No idea when the above comment was written, but it is * documented now at least. The below two urls describe the "openas" verb: * * http://blogs.msdn.com/oldnewthing/archive/2004/11/26/270710.aspx * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ * shellcc/platform/shell/programmersguide/shell_basics/ * shell_basics_extending/context.asp */ success = mswin_shell_exec(cmd, &childProcess) == 0; } else{ memset(&proc_info, 0, sizeof(proc_info)); memset(&start_info, 0, sizeof(start_info)); start_info.dwFlags = STARTF_FORCEONFEEDBACK; start_info.wShowWindow = SW_SHOWNORMAL; if(cmd) cmd_lpt = utf8_to_lptstr(cmd); if(CreateProcess(NULL, cmd_lpt, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &start_info, &proc_info) == TRUE){ q_status_message(SM_ORDER, 0, 4, "VIEWER command completed"); dprint ((3, "CreatProcess(%s) Success.\n", cmd ? cmd : "?")); childProcess = proc_info.hProcess; success = 1; } if(cmd_lpt) fs_give((void **) &cmd_lpt); } if(!success){ int rc = (int) GetLastError(); if(image_file_lpt) SetFileAttributes(image_file_lpt, FILE_ATTRIBUTE_NORMAL); our_unlink(image_file); q_status_message2(SM_ORDER, 3, 4, "\007Can't start viewer. %s%s.", (rc == 2 || rc == 3) ? "Viewer not found: " : (rc == 8) ? "Not enough memory" : "Windows error ", (rc == 2 || rc == 3) ? cmd : (rc == 8) ? "" : int2string(rc)); } if(image_file_lpt) fs_give((void **) &image_file_lpt); #elif OSX_TARGET char *command = NULL, *result_file = NULL, *p; char **r_file_h; PIPE_S *syspipe; int mode; if(!mc_cmd) return; if(mc_cmd->special_handling){ char *rhost; if(mime_os_specific_access()) osx_launch_special_handling(mc_cmd, image_file); else{ q_status_message(SM_ORDER, 0, 4, "VIEWER command cancelled"); our_unlink(image_file); } } else { char *cmd = mc_cmd->command; size_t l; l = 32 + strlen(cmd) + (2*strlen(image_file)); p = command = (char *) fs_get((l+1) * sizeof(char)); if(!needsterminal) /* put in background if it doesn't need terminal */ *p++ = '('; snprintf(p, l+1-(p-command), "%s", cmd); p += strlen(p); if(!needsterminal){ if(p-command+2 < l+1){ *p++ = ')'; *p++ = ' '; *p++ = '&'; } } if(p-command < l+1) *p++ = '\n'; if(p-command < l+1) *p = '\0'; dprint((9, "exec_mailcap_cmd: command=%s\n", command ? command : "?")); mode = PIPE_RESET; if(needsterminal == 1) r_file_h = NULL; else{ mode |= PIPE_WRITE | PIPE_STDERR; result_file = temp_nam(NULL, "pine_cmd"); r_file_h = &result_file; } if(syspipe = open_system_pipe(command, r_file_h, NULL, mode, 0, pipe_callback, NULL)){ close_system_pipe(&syspipe, NULL, pipe_callback); if(needsterminal == 1) q_status_message(SM_ORDER, 0, 4, "VIEWER command completed"); else if(needsterminal == 2) display_output_file(result_file, "VIEWER", " command result", 1); else display_output_file(result_file, "VIEWER", " command launched", 1); } else q_status_message1(SM_ORDER, 3, 4, "Cannot spawn command : %s", cmd); fs_give((void **)&command); if(result_file) fs_give((void **)&result_file); } #else char *command = NULL, *result_file = NULL, *p, *cmd, *q, *psef; char **r_file_h; PIPE_S *syspipe; int mode; size_t l; /* no os-specific command handling */ if(mc_cmd) cmd = mc_cmd->command; else return; #ifdef PSEFCMD psef = fs_get((60 + strlen(PSEFCMD) + strlen(image_file))*sizeof(char)); sprintf(psef, "PSEF=`%s | /bin/grep \"%s\" | /bin/grep -v grep`", PSEFCMD, image_file); q = fs_get((80 + 2*strlen(psef))*sizeof(char)); /* bigger than 62 */ sprintf(q, "/bin/sh -c '(%s; while test -n \"$PSEF\" ; do %s ; sleep %d ; done)' ;", psef, psef, ps_global->sleep); fs_give((void **) &psef); #else q = cpystr(""); #endif /* PSEFCMD */ l = 32 + strlen(cmd) + 2*strlen(image_file) + strlen(q); p = command = (char *)fs_get((l+1) * sizeof(char)); if(!needsterminal) /* put in background if it doesn't need terminal */ *p++ = '('; snprintf(p, l+1-(p-command), "%s ; %s rm -f %s", cmd, q, image_file); fs_give((void **)&q); command[l] = '\0'; p += strlen(p); if(!needsterminal && (p-command)+5 < l){ *p++ = ')'; *p++ = ' '; *p++ = '&'; } *p++ = '\n'; *p = '\0'; dprint((9, "exec_mailcap_cmd: command=%s\n", command ? command : "?")); mode = PIPE_RESET; if(needsterminal == 1) r_file_h = NULL; else{ mode |= PIPE_WRITE | PIPE_STDERR; result_file = temp_nam(NULL, "pine_cmd"); r_file_h = &result_file; } if((syspipe = open_system_pipe(command, r_file_h, NULL, mode, 0, pipe_callback, NULL)) != NULL){ close_system_pipe(&syspipe, NULL, pipe_callback); if(needsterminal == 1) q_status_message(SM_ORDER, 0, 4, "VIEWER command completed"); else if(needsterminal == 2) display_output_file(result_file, "VIEWER", " command result", 1); else display_output_file(result_file, "VIEWER", " command launched", 1); } else q_status_message1(SM_ORDER, 3, 4, "Cannot spawn command : %s", cmd); fs_give((void **)&command); if(result_file) fs_give((void **)&result_file); #endif }
/*---------------------------------------------------------------------- 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); }
/*---------------------------------------------------------------------- Prompt user for a choice among alternatives Args -- utf8prompt: The prompt for the question/selection line: The line to prompt on, if negative then relative to bottom esc_list: ESC_KEY_S list of keys dflt: The selection when the <CR> is pressed (should probably be one of the chars in esc_list) on_ctrl_C: The selection when ^C is pressed help_text: Text to be displayed on bottom two lines flags: Logically OR'd flags modifying our behavior to: RB_FLUSH_IN - Discard any pending input chars. RB_ONE_TRY - Only give one chance to answer. Returns on_ctrl_C value if not answered acceptably on first try. RB_NO_NEWMAIL - Quell the usual newmail check. RB_SEQ_SENSITIVE - The caller is sensitive to sequence number changes so return on_ctrl_C if an unsolicited expunge happens while we're viewing a message. RB_RET_HELP - Instead of the regular internal handling way of handling help_text, this just causes radio_buttons to return 3 when help is asked for, so that the caller handles it instead. Note: If there are enough keys in the esc_list to need a second screen, and there is no help, then the 13th key will be put in the help position. Result -- Returns the letter pressed. Will be one of the characters in the esc_list argument, or dflt, or on_ctrl_C, or SEQ_EXCEPTION. This will pause for any new status message to be seen and then prompt the user. The prompt will be truncated to fit on the screen. Redraw and resize are handled along with ^Z suspension. Typing ^G will toggle the help text on and off. Character types that are not buttons will result in a beep (unless one_try is set). ----*/ int radio_buttons(char *utf8prompt, int line, ESCKEY_S *esc_list, int dflt, int on_ctrl_C, HelpType help_text, int flags) { UCS ucs; register int ch, real_line; char *q, *ds = NULL; unsigned maxcol; int max_label, i, start, fkey_table[12]; int km_popped = 0; struct key rb_keys[12]; struct key_menu rb_keymenu; bitmap_t bitmap; struct variable *vars = ps_global->vars; COLOR_PAIR *lastc = NULL, *promptc = NULL; #ifdef _WINDOWS int cursor_shown; if (mswin_usedialog()){ MDlgButton button_list[25]; LPTSTR free_names[25]; LPTSTR free_labels[25]; int b, i, ret; char **help; memset(&free_names, 0, sizeof(LPTSTR) * 25); memset(&free_labels, 0, sizeof(LPTSTR) * 25); memset(&button_list, 0, sizeof (MDlgButton) * 25); b = 0; if(flags & RB_RET_HELP){ if(help_text != NO_HELP) alpine_panic("RET_HELP and help in radio_buttons!"); button_list[b].ch = '?'; button_list[b].rval = 3; button_list[b].name = TEXT("?"); free_labels[b] = utf8_to_lptstr(N_("Help")); button_list[b].label = free_labels[b]; ++b; } for(i = 0; esc_list && esc_list[i].ch != -1 && i < 23; ++i){ if(esc_list[i].ch != -2){ button_list[b].ch = esc_list[i].ch; button_list[b].rval = esc_list[i].rval; free_names[b] = utf8_to_lptstr(esc_list[i].name); button_list[b].name = free_names[b]; free_labels[b] = utf8_to_lptstr(esc_list[i].label); button_list[b].label = free_labels[b]; ++b; } } button_list[b].ch = -1; /* assumption here is that HelpType is char ** */ help = help_text; ret = mswin_select(utf8prompt, button_list, dflt, on_ctrl_C, help, flags); for(i = 0; i < 25; i++){ if(free_names[i]) fs_give((void **) &free_names[i]); if(free_labels[i]) fs_give((void **) &free_labels[i]); } return (ret); } #endif /* _WINDOWS */ suspend_busy_cue(); flush_ordered_messages(); /* show user previous status msgs */ mark_status_dirty(); /* clear message next display call */ real_line = line > 0 ? line : ps_global->ttyo->screen_rows + line; MoveCursor(real_line, RAD_BUT_COL); CleartoEOLN(); /*---- Find widest label ----*/ max_label = 0; for(i = 0; esc_list && esc_list[i].ch != -1 && i < 11; i++){ if(esc_list[i].ch == -2) /* -2 means to skip this key and leave blank */ continue; if(esc_list[i].name) max_label = MAX(max_label, utf8_width(esc_list[i].name)); } if(ps_global->ttyo->screen_cols - max_label - 1 > 0) maxcol = ps_global->ttyo->screen_cols - max_label - 1; else maxcol = 0; /* * We need to be able to truncate q, so copy it in case it is * a readonly string. */ q = cpystr(utf8prompt); /*---- Init structs for keymenu ----*/ for(i = 0; i < 12; i++) memset((void *)&rb_keys[i], 0, sizeof(struct key)); memset((void *)&rb_keymenu, 0, sizeof(struct key_menu)); rb_keymenu.how_many = 1; rb_keymenu.keys = rb_keys; /*---- Setup key menu ----*/ start = 0; clrbitmap(bitmap); memset(fkey_table, NO_OP_COMMAND, 12 * sizeof(int)); if(flags & RB_RET_HELP && help_text != NO_HELP) alpine_panic("RET_HELP and help in radio_buttons!"); /* if shown, always at position 0 */ if(help_text != NO_HELP || flags & RB_RET_HELP){ rb_keymenu.keys[0].name = "?"; rb_keymenu.keys[0].label = N_("Help"); setbitn(0, bitmap); fkey_table[0] = ctrl('G'); start++; } if(on_ctrl_C){ rb_keymenu.keys[1].name = "^C"; rb_keymenu.keys[1].label = N_("Cancel"); setbitn(1, bitmap); fkey_table[1] = ctrl('C'); start++; } start = start ? 2 : 0; /*---- Show the usual possible keys ----*/ for(i=start; esc_list && esc_list[i-start].ch != -1; i++){ /* * If we have an esc_list item we'd like to put in the non-existent * 13th slot, and there is no help, we put it in the help slot * instead. We're hacking now...! * * We may also have invisible esc_list items that don't show up * on the screen. We use this when we have two different keys * which are synonyms, like ^P and KEY_UP. If all the slots are * already full we can still fit invisible keys off the screen to * the right. A key is invisible if it's label is "". */ if(i >= 12){ if(esc_list[i-start].label && esc_list[i-start].label[0] != '\0'){ /* visible */ if(i == 12){ /* special case where we put it in help slot */ if(help_text != NO_HELP) alpine_panic("Programming botch in radio_buttons(): too many keys"); if(esc_list[i-start].ch != -2) setbitn(0, bitmap); /* the help slot */ fkey_table[0] = esc_list[i-start].ch; rb_keymenu.keys[0].name = esc_list[i-start].name; if(esc_list[i-start].ch != -2 && esc_list[i-start].rval == dflt && esc_list[i-start].label){ size_t l; l = strlen(esc_list[i-start].label) + 2; ds = (char *)fs_get((l+1) * sizeof(char)); snprintf(ds, l+1, "[%s]", esc_list[i-start].label); ds[l] = '\0'; rb_keymenu.keys[0].label = ds; } else rb_keymenu.keys[0].label = esc_list[i-start].label; } else alpine_panic("Botch in radio_buttons(): too many keys"); } } else{ if(esc_list[i-start].ch != -2) setbitn(i, bitmap); fkey_table[i] = esc_list[i-start].ch; rb_keymenu.keys[i].name = esc_list[i-start].name; if(esc_list[i-start].ch != -2 && esc_list[i-start].rval == dflt && esc_list[i-start].label){ size_t l; l = strlen(esc_list[i-start].label) + 2; ds = (char *)fs_get((l+1) * sizeof(char)); snprintf(ds, l+1, "[%s]", esc_list[i-start].label); ds[l] = '\0'; rb_keymenu.keys[i].label = ds; } else rb_keymenu.keys[i].label = esc_list[i-start].label; } } for(; i < 12; i++) rb_keymenu.keys[i].name = NULL; ps_global->mangled_footer = 1; #ifdef _WINDOWS cursor_shown = mswin_showcaret(1); #endif if(pico_usingcolor() && VAR_PROMPT_FORE_COLOR && VAR_PROMPT_BACK_COLOR && pico_is_good_color(VAR_PROMPT_FORE_COLOR) && pico_is_good_color(VAR_PROMPT_BACK_COLOR)){ lastc = pico_get_cur_color(); if(lastc){ promptc = new_color_pair(VAR_PROMPT_FORE_COLOR, VAR_PROMPT_BACK_COLOR); (void)pico_set_colorp(promptc, PSC_NONE); } } else StartInverse(); draw_radio_prompt(real_line, RAD_BUT_COL, maxcol, q); while(1){ fflush(stdout); /*---- Paint the keymenu ----*/ if(lastc) (void)pico_set_colorp(lastc, PSC_NONE); else EndInverse(); draw_keymenu(&rb_keymenu, bitmap, ps_global->ttyo->screen_cols, 1 - FOOTER_ROWS(ps_global), 0, FirstMenu); if(promptc) (void)pico_set_colorp(promptc, PSC_NONE); else StartInverse(); MoveCursor(real_line, MIN(RAD_BUT_COL+utf8_width(q), maxcol+1)); if(flags & RB_FLUSH_IN) flush_input(); newcmd: /* Timeout 5 min to keep imap mail stream alive */ ucs = read_char(600); dprint((2, "Want_to read: %s (0x%x)\n", pretty_command(ucs), ucs)); if((ucs < 0x80) && isupper((unsigned char) ucs)) ucs = tolower((unsigned char) ucs); if(F_ON(F_USE_FK,ps_global) && (((ucs < 0x80) && isalpha((unsigned char) ucs) && !strchr("YyNn",(int) ucs)) || ((ucs >= PF1 && ucs <= PF12) && (ucs = fkey_table[ucs - PF1]) == NO_OP_COMMAND))){ /* * The funky test above does two things. It maps * esc_list character commands to function keys, *and* prevents * character commands from input while in function key mode. * NOTE: this breaks if we ever need more than the first * twelve function keys... */ if(flags & RB_ONE_TRY){ ch = ucs = on_ctrl_C; goto out_of_loop; } Writechar(BELL, 0); continue; } switch(ucs){ default: for(i = 0; esc_list && esc_list[i].ch != -1; i++) if(ucs == esc_list[i].ch){ int len, n; MoveCursor(real_line,len=MIN(RAD_BUT_COL+utf8_width(q),maxcol+1)); for(n = 0, len = ps_global->ttyo->screen_cols - len; esc_list[i].label && esc_list[i].label[n] && len > 0; n++, len--) Writechar(esc_list[i].label[n], 0); ch = esc_list[i].rval; goto out_of_loop; } if(flags & RB_ONE_TRY){ ch = on_ctrl_C; goto out_of_loop; } Writechar(BELL, 0); break; case ctrl('M'): case ctrl('J'): ch = dflt; for(i = 0; esc_list && esc_list[i].ch != -1; i++) if(ch == esc_list[i].rval){ int len, n; MoveCursor(real_line,len=MIN(RAD_BUT_COL+utf8_width(q),maxcol+1)); for(n = 0, len = ps_global->ttyo->screen_cols - len; esc_list[i].label && esc_list[i].label[n] && len > 0; n++, len--) Writechar(esc_list[i].label[n], 0); break; } goto out_of_loop; case ctrl('C'): if(on_ctrl_C || (flags & RB_ONE_TRY)){ ch = on_ctrl_C; goto out_of_loop; } Writechar(BELL, 0); break; case '?': case ctrl('G'): if(FOOTER_ROWS(ps_global) == 1 && km_popped == 0){ km_popped++; FOOTER_ROWS(ps_global) = 3; line = -3; real_line = ps_global->ttyo->screen_rows + line; if(lastc) (void)pico_set_colorp(lastc, PSC_NONE); else EndInverse(); clearfooter(ps_global); if(promptc) (void)pico_set_colorp(promptc, PSC_NONE); else StartInverse(); draw_radio_prompt(real_line, RAD_BUT_COL, maxcol, q); break; } if(flags & RB_RET_HELP){ ch = 3; goto out_of_loop; } else if(help_text != NO_HELP && FOOTER_ROWS(ps_global) > 1){ mark_keymenu_dirty(); if(lastc) (void)pico_set_colorp(lastc, PSC_NONE); else EndInverse(); MoveCursor(real_line + 1, RAD_BUT_COL); CleartoEOLN(); MoveCursor(real_line + 2, RAD_BUT_COL); CleartoEOLN(); radio_help(real_line, RAD_BUT_COL, help_text); sleep(5); MoveCursor(real_line, MIN(RAD_BUT_COL+utf8_width(q), maxcol+1)); if(promptc) (void)pico_set_colorp(promptc, PSC_NONE); else StartInverse(); } else Writechar(BELL, 0); break; case NO_OP_COMMAND: goto newcmd; /* misunderstood escape? */ case NO_OP_IDLE: /* UNODIR, keep the stream alive */ if(flags & RB_NO_NEWMAIL) goto newcmd; i = new_mail(0, VeryBadTime, NM_DEFER_SORT); if(sp_expunge_count(ps_global->mail_stream) && flags & RB_SEQ_SENSITIVE){ if(on_ctrl_C) ch = on_ctrl_C; else ch = SEQ_EXCEPTION; goto out_of_loop; } if(i < 0) break; /* no changes, get on with life */ /* Else fall into redraw to adjust displayed numbers and such */ case KEY_RESIZE: case ctrl('L'): real_line = line > 0 ? line : ps_global->ttyo->screen_rows + line; if(lastc) (void)pico_set_colorp(lastc, PSC_NONE); else EndInverse(); ClearScreen(); redraw_titlebar(); if(ps_global->redrawer != NULL) (*ps_global->redrawer)(); if(FOOTER_ROWS(ps_global) == 3 || km_popped) redraw_keymenu(); if(ps_global->ttyo->screen_cols - max_label - 1 > 0) maxcol = ps_global->ttyo->screen_cols - max_label - 1; else maxcol = 0; if(promptc) (void)pico_set_colorp(promptc, PSC_NONE); else StartInverse(); draw_radio_prompt(real_line, RAD_BUT_COL, maxcol, q); break; } /* switch */ } out_of_loop: #ifdef _WINDOWS if(!cursor_shown) mswin_showcaret(0); #endif fs_give((void **) &q); if(ds) fs_give((void **) &ds); if(lastc){ (void) pico_set_colorp(lastc, PSC_NONE); free_color_pair(&lastc); if(promptc) free_color_pair(&promptc); } else EndInverse(); fflush(stdout); resume_busy_cue(0); if(km_popped){ FOOTER_ROWS(ps_global) = 1; clearfooter(ps_global); ps_global->mangled_body = 1; } return(ch); }
/* * Dialog proc to handle flag selection. * * Configures the dialog box on init, adding buttons as needed for * an unknown number of flags. * Retrieves the settings on exit. */ BOOL CALLBACK __export flag_dialog_proc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { DLG_FLAGDATA *dlgflag; BOOL ret = FALSE; int i; struct flag_table *fp; HWND hRB[2], hBtn; RECT rb[2]; UINT bheight, bwidth, bvertSpace; UINT btnOKHeight; int base, line; int bstate; HFONT btnFont; switch (uMsg) { case WM_INITDIALOG: dlgflag = (DLG_FLAGDATA *)lParam; SetWindowLong (hDlg, WINDOW_USER_DATA, (LONG) dlgflag); /* Count buttons */ dlgflag->flagcount = 0; for (fp = dlgflag->ftbl; fp && fp->name; ++fp) ++dlgflag->flagcount; /* Get the positions of the current buttons. */ for (i = 0; i < 2; ++i) { hRB[i] = GetDlgItem (hDlg, IDC_FLAGCOL1 + i); GetBtnPos (hDlg, hRB[i], &rb[i]); } bheight = rb[0].bottom - rb[0].top; bwidth = rb[0].right - rb[0].left; bvertSpace = bheight + 5; btnFont = (HFONT) SendMessage (hRB[0], WM_GETFONT, 0, 0); for (i = 0; i < dlgflag->flagcount; ++i) { LPTSTR fp_name_lptstr; fp = &dlgflag->ftbl[i]; fp_name_lptstr = utf8_to_lptstr(fp->name); if (i < 2) { hBtn = hRB[i]; SetWindowText (hBtn, fp_name_lptstr); } else { base = i % 2; line = i / 2; hBtn = CreateWindow (TEXT("BUTTON"), fp_name_lptstr, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, rb[base].left, rb[base].top + bvertSpace * line, bwidth, bheight, hDlg, (HMENU)NULL, dlgflag->hInstance, NULL); SetWindowLong (hBtn, GWL_ID, IDC_FLAGCOL1 + i); SendMessage (hBtn, WM_SETFONT, (WPARAM)btnFont, MAKELPARAM (0, 0)); } fs_give((void **) &fp_name_lptstr); if (fp->ukn) SendMessage (hBtn, BM_SETSTYLE, (WPARAM)(BS_CHECKBOX | BS_AUTO3STATE), 0); SendMessage (hBtn, BM_SETCHECK, (WPARAM) fp->set == CMD_FLAG_UNKN ? 2 : fp->set ? 1 : 0, 0); ShowWindow (hBtn, SW_SHOW); EnableWindow (hBtn, TRUE); } /* Position the OK and Cancel buttons. */ line = (dlgflag->flagcount + 1) / 2; for (i = 0; i < 2; ++i) { hRB[1] = GetDlgItem (hDlg, i == 0 ? IDOK : IDCANCEL); GetBtnPos (hDlg, hRB[1], &rb[1]); MoveWindow (hRB[1], rb[1].left, rb[0].top + bvertSpace * line, rb[1].right - rb[1].left, rb[1].bottom - rb[1].top, FALSE); btnOKHeight = rb[1].bottom - rb[1].top; } /* Resize whole dialog window. */ GetWindowRect (hDlg, &rb[1]); rb[1].right -= rb[1].left; rb[1].bottom = rb[0].top + bvertSpace * line + btnOKHeight + 10 + GetSystemMetrics (SM_CYCAPTION); MoveWindow (hDlg, rb[1].left, rb[1].top, rb[1].right, rb[1].bottom, TRUE); return (1); case WM_COMMAND: dlgflag = (DLG_FLAGDATA *) GetWindowLong (hDlg, WINDOW_USER_DATA); switch (wParam) { case IDOK: /* Retrieve the button states. */ for (i = 0; i < dlgflag->flagcount; ++i) { fp = &dlgflag->ftbl[i]; bstate = SendMessage (GetDlgItem (hDlg, IDC_FLAGCOL1 + i), BM_GETCHECK, 0, 0); switch (bstate) { case 2: fp->set = CMD_FLAG_UNKN; break; case 1: fp->set = CMD_FLAG_SET; break; case 0: fp->set = CMD_FLAG_CLEAR; break; } } EndDialog (hDlg, TRUE); ret = TRUE; break; case IDCANCEL: EndDialog (hDlg, FALSE); ret = TRUE; break; } break; } return (ret); }