This is misc.c in view mode; [Download] [Up]
/* Copyright (c) 1995 John E. Davis (davis@space.mit.edu) * All rights reserved. */ #include "config.h" #include "features.h" #include <stdio.h> #include <string.h> #include <stdarg.h> #include <signal.h> #include <ctype.h> #include <errno.h> #ifdef HAVE_STDLIB_H # include <stdlib.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #ifndef VMS # include <pwd.h> # include <sys/types.h> # include <sys/stat.h> #else # include <stat.h> # include <unixio.h> #endif #include <slang.h> #include "jdmacros.h" #include "misc.h" #include "group.h" #include "slrn.h" #include "post.h" #include "server.h" #if SLRN_HAS_MIME #include "mime.h" #endif #ifdef VMS /* valid filname chars for unix equiv of vms filename */ #define VALID_FILENAME_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_-/" #endif static int Error_Present; int Slrn_Full_Screen_Update = 1; int Slrn_User_Wants_Confirmation = 1; #ifndef VMS char *Slrn_SendMail_Command; #endif char *Slrn_Editor; void slrn_set_color (int color) { #if 0 if (SLtt_Use_Ansi_Colors == 0) { if (color >= STATUS_COLOR) SLsmg_reverse_video (); else SLsmg_normal_video (); } else #endif SLsmg_set_color (color); } void slrn_redraw (void) { SLsmg_cls (); Slrn_Full_Screen_Update = 1; if ((Slrn_Current_Mode != NULL) && (Slrn_Current_Mode->redraw_fun != NULL)) (*Slrn_Current_Mode->redraw_fun) (); slrn_smg_refresh (); } int Slrn_Message_Present; void slrn_clear_message (void) { Slrn_Message_Present = Error_Present = 0; /* SLang_Error = 0; */ SLKeyBoard_Quit = 0; if ((Slrn_TT_Initialized & 1) == 0) return; SLsmg_gotorc (SLtt_Screen_Rows - 1, 0); SLsmg_erase_eol (); } int slrn_message (char *fmt, ...) { int ok; va_list ap; if (Error_Present) return -1; if (Slrn_TT_Initialized & 1) { ok = Slrn_Suspension_Ok; if (ok) slrn_set_suspension (0); SLsmg_gotorc (SLtt_Screen_Rows - 1, 0); slrn_set_color (0); va_start(ap, fmt); (void) SLsmg_vprintf(fmt, ap); SLsmg_erase_eol (); Slrn_Message_Present = 1; if (ok) slrn_set_suspension (1); } else { va_start(ap, fmt); (void) vfprintf(stderr, fmt, ap); va_end(ap); putc ('\n', stderr); } return 0; } extern void slrn_error (char *fmt, ...) { va_list ap; if ((Slrn_TT_Initialized & 1) == 0) { va_start(ap, fmt); (void) vfprintf(stderr, fmt, ap); va_end(ap); putc ('\n', stderr); } else { int ok; if (Error_Present) return; ok = Slrn_Suspension_Ok; if (ok) slrn_set_suspension (0); SLtt_beep (); slrn_clear_message (); Error_Present = 1; Slrn_Message_Present = 1; slrn_set_color (ERROR_COLOR); va_start(ap, fmt); (void) SLsmg_vprintf(fmt, ap); va_end(ap); slrn_set_color (0); SLang_flush_input (); if (ok) slrn_set_suspension (1); } if (SLang_Error == 0) SLang_Error = INTRINSIC_ERROR; } void slrn_print_percent (int row, int col, int n, int nmax, int width) { SLsmg_erase_eol (); SLsmg_gotorc (row, col); SLsmg_printf ("-- %d/%d", n, nmax); if (n == 1) { #if 1 SLsmg_write_string ( (n + width > nmax) ? " (All)" : " (Top)" ); #else SLsmg_printf (" (Top)"); #endif } else if (n + width > nmax) SLsmg_write_string(" (Bot)"); else SLsmg_printf(" (%d%%)", ((n + width - 1) * 100) / nmax); SLsmg_erase_eol (); } static void fixup_path (char *path) { int len; len = strlen (path); if (len == 0) return; if (path[len - 1] == '/') return; path[len] = '/'; path[len + 1] = 0; } #ifdef VMS static void vms_fix_name(char *name) { int idx, pos; pos = strspn(name, VALID_FILENAME_CHARS); if (pos == strlen(name)) return; for(idx=pos;idx<strlen(name);idx++) if (!(isdigit(name[idx]) || isalpha(name[idx]) || (name[idx] == '$') || (name[idx] == '_') || (name[idx] == '-') || (name[idx] == '/'))) name[idx] = '-'; } static char Copystr[256]; static int vms_copyname1 (char *name) { strcpy(Copystr, name); return(1); } static int vms_copyname2 (char *name, int type) { strcpy(Copystr, name); return(1); } #endif void slrn_make_home_filename (char *name, char *file) { char *home; #ifndef VMS if ( #ifdef __os2__ (*name == '/') || (*name == '\\') || (*(name + 1) == ':') || ((*name == '.') && (*(name + 1) == '/')) || ((*name == '.') && (*(name + 1) == '\\')) #else (*name == '/') || ((*name == '.') && (*(name + 1) == '/')) #endif ) { strcpy (file, name); return; } if (NULL == (home = getenv ("SLRNHOME"))) home = getenv ("HOME"); *file = 0; if (home != NULL) strcpy (file, home); fixup_path (file); strcat (file, name); #else char *cp, *cp1; static char fname[256]; char fn[256], fn1[256]; int rc, idx; strcpy (fn1, name); if (NULL != slrn_strchr (name, ':')) { strcpy (file, name); return; } if (NULL == (home = getenv ("SLRNHOME"))) home = getenv ("HOME"); *file = 0; if (NULL != (cp = slrn_strchr (fn1, '/'))) { # ifdef __DECC *cp = '\0'; cp++; cp1 = decc$translate_vms(home); if (cp1 == 0 || (int)cp1 == -1) { /* error translating */ } else { strcpy(fname, cp1); strcat(cp1, "/"); } strcat (cp1, fn1); vms_fix_name (cp1); rc = decc$to_vms(cp1, vms_copyname2, 0, 2); if (rc > 0) { strcpy(fname, Copystr); rc = mkdir(fname, 0755); } strcat(fname, cp); # else *cp = '\0'; cp++; cp1 = shell$translate_vms(home); if (cp1 == 0 || (int)cp1 == -1) { /* error translating */ } else { strcpy(fname, cp1); strcat(cp1, "/"); } strcat (cp1, fn1); vms_fix_name (cp1); rc = shell$to_vms(cp1, vms_copyname2, 0, 2); if (rc > 0) { strcpy(fname, Copystr); rc = mkdir(fname, 0755); } strcat(fname, cp); # endif strcpy(file,fname); } else { if (home != NULL) strcpy(file, home); strcat(file, name); } #endif /* VMS */ } int slrn_make_home_dirname (char *name, char *dir) { /* This needs modified to deal with VMS directory syntax */ #ifndef VMS slrn_make_home_filename (name, dir); #else char *home, *cp; char fn[256]; static char fname[256]; int rc, idx, len; if (NULL != slrn_strchr (name, ':')) { strcpy (dir, name); return; } home = getenv ("HOME"); *dir = 0; if (cp = strchr(name,'/')) { #ifdef __DECC cp = decc$translate_vms(home); if (cp == 0 || (int)cp == -1) { /* error translating */ } else { strcpy(fname, cp); strcat(cp, "/"); } strcat (cp, name); vms_fix_name (cp); rc = decc$to_vms(cp, vms_copyname2, 0, 2); if (rc > 0) { strcpy(fname, Copystr); rc = mkdir(fname, 0755); } #else if (shell$from_vms(home, vms_copyname1, 0)) { if (Copystr != NULL) strcpy (fn, Copystr); strcat(fn, "/"); } strcat (fn, name); vms_fix_name(fn); if (shell$to_vms(fn, vms_copyname1, 0)) strcpy(fname, Copystr); #endif strcpy(dir,fname); } else { if (home != NULL) { strcpy(dir, home); len = strlen(dir) - 1; if (dir[len] == ']') { dir[len] = '.'; strcat(dir, name); strcat(dir, "]"); } else strcat(dir, name); } else strcat(dir, name); } #endif /* VMS */ return 0; } FILE *slrn_open_tmpfile (char *file, char *mode) { FILE *fp = NULL; #ifdef _AIX /* AIX doesn't have mktemp() */ char *f = tempnam (NULL, "SLRN"); if (f != NULL) { strcpy (file, f); fp = fopen (f, mode); free (f); } #else char *dir; # ifdef __os2__ dir = getenv ("TMP"); if (dir == NULL) # endif dir = getenv ("TMPDIR"); # ifdef VMS if (dir == NULL) dir = "SYS$LOGIN:"; sprintf (file, "%sSLRN%uXXXXXX", dir, (unsigned int) getpid ()); # else if (dir == NULL) dir = "/tmp"; sprintf (file, "%s/SLRN%uXXXXXX", dir, (unsigned int) getpid ()); # endif if (NULL != mktemp (file)) fp = fopen (file, mode); #endif return fp; } FILE *slrn_open_home_file (char *name, char *mode, char *file, int create_flag) { slrn_make_home_filename (name, file); #ifdef VMS if (create_flag) { FILE *fp = fopen (file, mode, "fop=cif"); if (fp == NULL) perror ("fopen"); return fp; } #endif return fopen (file, mode); } /* invoke the editor */ int slrn_posix_system (char *cmd, int reset) { int init_mode = Slrn_TT_Initialized; #ifndef VMS void (*sint)(int); void (*squit)(int); int ret; sint = signal (SIGINT, SIG_IGN); squit = signal (SIGQUIT, SIG_IGN); if (reset) slrn_reset_display (0); ret = system (cmd); signal (SIGINT, sint); # ifdef SIGQUIT signal (SIGQUIT, squit); # endif #else int ret; if (reset) slrn_reset_display (0); ret = system (cmd); #endif if (reset) slrn_init_display (init_mode, 0); return ret; } static int create_edit_command (char *edit, char *cmd, char *file, unsigned int line) { int d, s; char ch, *p = edit; /* Look for %d and %s */ d = s = 0; while (0 != (ch = *p++)) { if (ch != '%') continue; ch = *p; if (!d && (ch == 'd')) { *p = 'u'; /* map %d to %u (unsigned) */ if (s == 0) d = 1; else d = 2; } else if (!s && (ch == 's')) { if (d == 0) s = 1; else s = 2; } else { slrn_error ("Invalid Editor definition."); return 0; } p++; } /* No %d, %s */ if ((d == 0) && (s == 0)) { sprintf (cmd, "%s %s", edit, file); } else if (d == 0) { sprintf (cmd, edit, file); } else if (s == 0) { sprintf (cmd, edit, (int) line); strcat (edit, " "); strcat (edit, file); } else /* d and s */ { if (d == 1) sprintf (cmd, edit, line, file); else sprintf (cmd, edit, file, line); } return 1; } int slrn_edit_file (char *file, unsigned int line) { char buf[512]; char editbuf[512]; int ret; char *editor = Slrn_Editor; if ((editor == NULL) && (NULL == (editor = getenv("SLRN_EDITOR"))) && (NULL == (editor = getenv("SLANG_EDITOR"))) && (NULL == (editor = getenv("EDITOR"))) && (NULL == (editor = getenv("VISUAL")))) { #ifdef VMS editor = "edit"; #else # ifdef __os2__ editor = "e"; # else # ifdef unix editor = "vi"; # endif # endif #endif } strcpy (editbuf, editor); if (0 == create_edit_command(editbuf, buf, file, line)) return -1; ret = slrn_posix_system (buf, 1); /* Am I the only one who thinks this is a good idea?? */ if (Slrn_TT_Initialized) while (SLang_input_pending (5)) { SLang_flush_input (); } /* slrn_redraw (); */ return ret; } void slrn_suspend_cmd (void) { slrn_suspend (0); } char slrn_get_response (char *valid_chars, char *str, ...) { char ch; va_list ap; char *v; /* if (SLang_Error) return -1; */ while (1) { if (Slrn_TT_Initialized == 0) { char buf[256]; va_start(ap, str); (void) vfprintf(stdout, str, ap); va_end(ap); fflush (stdout); *buf = 0; (void) fgets (buf, sizeof(buf), stdin); ch = *buf; } else { SLang_flush_input (); slrn_clear_message (); va_start(ap, str); (void) SLsmg_vprintf(str, ap); va_end(ap); slrn_smg_refresh (); ch = SLang_getkey (); slrn_clear_message (); SLang_Error = SLKeyBoard_Quit = 0; } v = valid_chars; while (*v) { if (*v == ch) return ch; v++; } slrn_error ("Invalid response! Try again."); if (Slrn_TT_Initialized & 1) { slrn_smg_refresh (); (void) SLang_input_pending (15); } } } int slrn_get_yesno (int dflt, char *str, ...) { va_list ap; char buf[512]; char ch, rsp; char *fmt; /* if (SLang_Error) return -1; */ va_start(ap, str); (void) vsprintf(buf, str, ap); va_end(ap); if (dflt) { ch = 'y'; fmt = "? ([y]/n)"; } else { ch = 'n'; fmt = "? (y/[n])"; } strcat (buf, fmt); rsp = slrn_get_response ("yYnN\r", buf); if (rsp == '\r') rsp = ch; else rsp |= 0x20; if (rsp == 'n') return 0; return 1; } int slrn_get_yesno_cancel (char *str, ...) { va_list ap; char buf[512]; if (SLang_Error) return -1; va_start(ap, str); (void) vsprintf(buf, str, ap); va_end(ap); strcat (buf, "? [Y]-es, N-o, C-ancel"); switch (slrn_get_response ("\007yYnNcC\r", buf)) { case '\r': case 'Y': case 'y': return 1; case 'n': case 'N': return 0; default: return -1; } } Slrn_User_Info_Type Slrn_User_Info = { NULL, /* realname */ NULL, /* username */ "", /* host */ NULL, /* reply to */ NULL, /* org */ NULL, /* followup_string */ NULL /* signature */ }; #if defined(VMS) && defined(MULTINET) # include "multinet_root:[multinet.include]netdb.h" #else # include <netdb.h> # ifndef h_errno extern int h_errno; # endif #endif char *slrn_make_startup_string (char *s) { char *ss; ss = (char *) SLMALLOC (strlen (s) + 1); if (ss == NULL) { slrn_exit_error ("Out of memory."); } strcpy (ss, s); return ss; } char *slrn_skip_whitespace (char *b) { register char ch; while (((ch = *b) == ' ') || (ch == '\t') || (ch == '\n')) b++; return b; } /* returns a pointer to the end of the string */ char *slrn_trim_string (char *smin) { register char *s, ch; if (smin == NULL) return NULL; s = smin + strlen (smin); while (s > smin) { s--; ch = *s; if ((ch == ' ') || (ch == '\n') || (ch == '\t')) { *s = 0; continue; } s++; break; } return s; } char *slrn_strchr (char *s, char ch) { register char ch1; while (((ch1 = *s) != 0) && (ch != ch1)) s++; if (ch1 == 0) return NULL; return s; } int slrn_is_fqdn (char *h) { char *p; /* Believe it or not, I have come across one system with a '(' character * as part of the hostname!!! I suppose that I should also check for * other strange characters as well. This is an issue since a message * id will be composed from the fqdn. For that reason, such names will * be rejected. Sigh. */ if ((NULL != slrn_strchr (h, '(')) || (NULL != slrn_strchr (h, '@'))) return 0; p = slrn_strchr (h, '.'); return ((p != NULL) && (p != h)); } void slrn_get_user_info (void) { struct hostent *host_entry; char *name, *host; #ifndef VMS struct passwd *pw; pw = getpwuid (getuid ()); #endif /* Fill in what is assumed to be non-NULL by rest of program. */ Slrn_User_Info.followup_string = slrn_make_startup_string ("In article %m, %r wrote:"); Slrn_Courtesy_CC_Message = slrn_make_startup_string ("[This message has also been posted.]"); /* Now get default values for rest. */ host = Slrn_User_Info.host; /* gethostname may not provide the full name so use gethostbyname * to get more information. Why isn't there a simplified interface to * get the FQDN!!!! */ host_entry = NULL; if (-1 != gethostname (host, MAX_HOST_NAME_LEN)) host_entry = gethostbyname (host); #ifdef TRY_AGAIN if ((host_entry == NULL) && (h_errno == TRY_AGAIN)) { sleep (2); host_entry = gethostbyname (host); } #endif if ((host_entry == NULL) || (host_entry->h_name == NULL)) *host = 0; else { if (slrn_is_fqdn ((char *)host_entry->h_name)) { Slrn_User_Info.posting_host = slrn_make_startup_string ((char *)host_entry->h_name); } else { char **aliases; aliases = host_entry->h_aliases; if (aliases != NULL) while (*aliases != NULL) { if (slrn_is_fqdn (*aliases)) { Slrn_User_Info.posting_host = slrn_make_startup_string (*aliases); break; } aliases++; } } if (Slrn_User_Info.posting_host == NULL) { strcpy (host, (char *) host_entry->h_name); } else strcpy (host, Slrn_User_Info.posting_host); } #if defined(USE_DOMAIN_NAME) && defined(MY_DOMAIN_NAME) if (*host && (0 == slrn_is_fqdn (host))) { char *my_domain_name; unsigned int len; len = strlen (host); my_domain_name = MY_DOMAIN_NAME; if (*my_domain_name != '.') { host[len++] = '.'; } strcpy (host + len, my_domain_name); } #endif /* If a value was compiled in, use it. */ #ifdef OUR_HOSTNAME # ifdef unix /* If the value is a file, read the file for the FQDN */ if (OUR_HOSTNAME[0] == '/') { FILE *fp; if (NULL != (fp = fopen(OUR_HOSTNAME, "r"))) { char tmphost[MAX_HOST_NAME_LEN]; if (fgets(tmphost, MAX_HOST_NAME_LEN , fp) != NULL) { char *p; if ((p = slrn_strchr (tmphost, '\n')) != NULL) *p = '\0'; /* If the entry is valid, we're done */ if (slrn_is_fqdn(tmphost)) strcpy(host, tmphost); } fclose(fp); } } else # endif if (slrn_is_fqdn (OUR_HOSTNAME) && strlen(OUR_HOSTNAME) < MAX_HOST_NAME_LEN) strcpy (host, OUR_HOSTNAME); #endif /* Allow user chance to over ride this. Until now, host was a pointer * to Slrn_User_Info.host. */ if ((NULL != (host = getenv ("HOSTNAME"))) && slrn_is_fqdn (host)) { strncpy (Slrn_User_Info.host, host, MAX_HOST_NAME_LEN); Slrn_User_Info.host[MAX_HOST_NAME_LEN - 1] = 0; } if ( #ifdef VMS ((name = getlogin()) == NULL) #else /* I cannot use getlogin under Unix because some implementations * truncate the username to 8 characters. Besides, I suspect that * it is equivalent to the following line. */ ((pw == NULL) || (NULL == (name = pw->pw_name)) || (*name == 0)) #endif && ((name = getenv("USER")) == NULL) && ((name = getenv("LOGNAME")) == NULL)) name = ""; Slrn_User_Info.username = slrn_make_startup_string (name); if ((Slrn_User_Info.replyto = getenv ("REPLYTO")) == NULL) Slrn_User_Info.replyto = ""; Slrn_User_Info.replyto = slrn_make_startup_string (Slrn_User_Info.replyto); #ifdef VMS Slrn_User_Info.realname = fix_fullname(get_uaf_fullname()); #else if (((Slrn_User_Info.realname = getenv ("NAME")) == NULL) && ((pw == NULL) || ((Slrn_User_Info.realname = pw->pw_gecos) == NULL))) { Slrn_User_Info.realname = ""; } #endif Slrn_User_Info.realname = slrn_make_startup_string (Slrn_User_Info.realname); /* truncate at character used to delineate extra gecos fields */ name = Slrn_User_Info.realname; while (*name && (*name != ',')) name++; *name = 0; Slrn_User_Info.org = getenv ("ORGANIZATION"); #ifdef OUR_ORGANIZATION if (Slrn_User_Info.org == NULL) Slrn_User_Info.org = OUR_ORGANIZATION; #endif if (Slrn_User_Info.org != NULL) { /* Check to see if this is an organization file. */ char orgbuf[512]; if (*Slrn_User_Info.org == '/') { FILE *fporg; if (NULL != (fporg = fopen (Slrn_User_Info.org, "r"))) { if (NULL != fgets (orgbuf, sizeof (orgbuf) - 1, fporg)) { unsigned int orglen = strlen (orgbuf); if (orglen && (orgbuf[orglen - 1] == '\n')) orgbuf[orglen - 1] = 0; Slrn_User_Info.org = orgbuf; } slrn_fclose (fporg); } } Slrn_User_Info.org = slrn_make_startup_string (Slrn_User_Info.org); } Slrn_User_Info.signature = slrn_make_startup_string (SLRN_SIGNATURE_FILE); #if SLRN_HAS_MIME Slrn_Mime_Display_Charset = slrn_make_startup_string ("iso-8859-1"); #endif #ifdef SLRN_SENDMAIL_COMMAND Slrn_SendMail_Command = slrn_make_startup_string (SLRN_SENDMAIL_COMMAND); #endif } void update_top_status_line (void) { if (Slrn_Full_Screen_Update == 0) return; SLsmg_gotorc (0, 0); slrn_set_color (MENU_COLOR); SLsmg_printf ("\ slrn %s ** Press '?' for help, 'q' to quit. ** Server: %s", Slrn_Version, Slrn_Server_Obj->sv_name); SLsmg_erase_eol (); slrn_set_color (0); } static void rline_update (unsigned char *buf, int len, int col) { SLsmg_gotorc (SLtt_Screen_Rows - 1, 0); SLsmg_write_nchars ((char *) buf, len); SLsmg_erase_eol (); SLsmg_gotorc (SLtt_Screen_Rows - 1, col); slrn_smg_refresh (); } SLang_RLine_Info_Type *Slrn_Keymap_RLI; static SLang_RLine_Info_Type *init_readline (void) { unsigned char *buf = NULL; SLang_RLine_Info_Type *rli; if ((NULL == (rli = (SLang_RLine_Info_Type *) SLMALLOC (sizeof(SLang_RLine_Info_Type)))) || (NULL == (buf = (unsigned char *) SLMALLOC (256)))) { if (rli != NULL) SLFREE (rli); fprintf(stderr, "malloc error.\n"); return NULL; } SLMEMSET ((char *) rli, 0, sizeof (SLang_RLine_Info_Type)); rli->buf = buf; rli->buf_len = 255; rli->tab = 8; rli->dhscroll = 20; rli->getkey = SLang_getkey; rli->tt_goto_column = NULL; rli->update_hook = rline_update; if (SLang_init_readline (rli) < 0) { SLFREE (rli); SLFREE (buf); rli = NULL; } return rli; } int slrn_init_readline (void) { if ((Slrn_Keymap_RLI == NULL) && (NULL == (Slrn_Keymap_RLI = init_readline ()))) return -1; return 0; } int slrn_read_input (char *prompt, char *str, int trim_flag) { int i; Slrn_Keymap_RLI->edit_width = SLtt_Screen_Cols - 1; Slrn_Keymap_RLI->prompt = prompt; *Slrn_Keymap_RLI->buf = 0; if (*str) { strcpy ((char *) Slrn_Keymap_RLI->buf, str); Slrn_Keymap_RLI->point = 0; /* strlen (str); */ } *str = 0; slrn_enable_mouse (0); i = SLang_read_line (Slrn_Keymap_RLI); slrn_enable_mouse (1); if ((i >= 0) && !SLang_Error && !SLKeyBoard_Quit) { char *b = (char *) Slrn_Keymap_RLI->buf; /* SLang_rline_save_line (Slrn_Keymap_RLI); */ if (trim_flag) { slrn_trim_string (b); b = slrn_skip_whitespace (b); } strcpy (str, b); i = strlen (str); } if (SLKeyBoard_Quit) i = -1; SLang_Error = SLKeyBoard_Quit = 0; /* put cursor at edge of screen to comfort user */ SLsmg_gotorc (SLtt_Screen_Rows - 1, 0); slrn_smg_refresh (); return i; } int slrn_read_integer (char *prompt, int *dflt, int *np) { char buf[256]; char str[256]; int n; if (dflt != NULL) { sprintf (buf, "%s (default: %d) ", prompt, *dflt); } else strcpy (buf, prompt); *str = 0; if (-1 == (n = slrn_read_input (buf, str, 1))) { slrn_error ("Abort!"); return -1; } if (1 != sscanf(str, "%d", &n)) { if ((*str == 0) && (dflt != NULL)) n = *dflt; else { slrn_error ("Integer expected."); return -1; } } *np = n; return 0; } int slrn_mail_file (char *file, int edit, unsigned int editline, char *to, char *subject) { char buf[256]; if (edit) { if (slrn_edit_file (file, editline) < 0) return -1; while (1) { char rsp; rsp = slrn_get_response ("yYnNeE", "Mail the message? y/n/e(dit)"); rsp |= 0x20; if (rsp == 'n') return -1; if (rsp == 'y') break; if (slrn_edit_file (file, 1) < 0) return -1; } } slrn_message ("Sending..."); slrn_smg_refresh (); #ifdef VMS sprintf(buf, "%s\"%s\"", MAIL_PROTOCOL, to); vms_send_mail( buf, subject, file ); #else /* What I need to do is to open the file and feed it line by line to the * sendmail program. This way I can strip out blank headers. */ if (Slrn_Use_Mime) { FILE *fp, *pp; int header = 1; char line[1024]; fp = fopen (file, "r"); if (fp == NULL) return (-1); slrn_mime_scan_file (fp); pp = slrn_popen (Slrn_SendMail_Command, "w"); if (pp == NULL) { slrn_fclose (fp); return (-1); } while (fgets (line, sizeof(line), fp) != NULL) { int len = strlen (line); line[len - 1] = 0; if (header) { if (line[0] == 0) { header = 0; slrn_mime_add_headers (pp); fp = slrn_mime_encode (fp); } slrn_mime_header_encode (line, sizeof(line)); } fputs (line, pp); putc('\n', pp); } slrn_pclose (pp); slrn_fclose (fp); } else { #ifdef __os2__ sprintf (buf, "%s -af %s", Slrn_SendMail_Command, file); #else sprintf (buf, "%s < %s", Slrn_SendMail_Command, file); #endif slrn_posix_system (buf, 0); } #endif /* NOT VMS */ slrn_message ("Sending...done"); return 0; } char *slrn_fix_regexp (char *pat) { static char newpat[256]; char *p, ch; p = newpat; *p++ = '^'; while ((ch = *pat++) != 0) { if (ch == '.') { *p++ = '\\'; } else if (ch == '*') { *p++ = '.'; } *p++ = ch; } *p = 0; return newpat; } SLRegexp_Type *slrn_compile_regexp_pattern (char *pat) { static unsigned char compiled_pattern_buf [512]; static SLRegexp_Type re; re.pat = (unsigned char *) pat; re.buf = compiled_pattern_buf; re.buf_len = sizeof (compiled_pattern_buf); re.case_sensitive = 0; if (0 != SLang_regexp_compile (&re)) { slrn_error ("Invalid regular expression or expression too long."); return NULL; } return &re; } unsigned char *slrn_regexp_match (SLRegexp_Type *re, char *str) { unsigned int len; if ((str == NULL) || (re->min_length > (len = strlen (str)))) return NULL; return SLang_regexp_match ((unsigned char *)str, len, re); } int slrn_file_exists (char *file) { struct stat st; int m; #ifdef _S_IFDIR # ifndef S_IFDIR # define S_IFDIR _S_IFDIR # endif #endif #ifndef S_ISDIR # ifdef S_IFDIR # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) # else # define S_ISDIR(m) 0 # endif #endif if (stat(file, &st) < 0) return 0; m = st.st_mode; if (S_ISDIR(m)) return (2); return 1; } void slrn_get_mouse_rc (int *rp, int *cp) { int r, c; c = (unsigned char) SLang_getkey () - 32; r = (unsigned char) SLang_getkey () - 32; if (cp != NULL) *cp = c; if (rp != NULL) *rp = r; } #if SLRN_HAS_PIPING int slrn_pclose (FILE *fp) { int ret; if (fp == NULL) return -1; ret = pclose (fp); if (ret) { char buf[256]; fprintf (stderr, "Command returned non-zero exit status. Press RETURN.\n"); fgets (buf, 255, stdin); } slrn_init_display (3, 0); return 0; } FILE *slrn_popen (char *cmd, char *mode) { FILE *fp; slrn_reset_display (0); fp = popen (cmd, mode); if (fp == NULL) { char buf[256]; fprintf (stderr, "Command %s failed to run. Press RETURN.\n", cmd); fgets (buf, 255, stdin); slrn_init_display (3, 0); } return fp; } #endif int slrn_delete_file (char *f) { #ifdef VMS return delete(f); #else return unlink(f); #endif } char *slrn_simple_strtok (char *s, char *chp) { static char *s1; char ch = *chp; if (s == NULL) { if (s1 == NULL) return NULL; s = s1; } else s1 = s; while (*s1 && (*s1 != ch)) s1++; if (*s1 == 0) { s1 = NULL; } else *s1++ = 0; return s; } int slrn_fclose (FILE *fp) { if (0 == fclose (fp)) return 0; slrn_error ("Error closing file. File system full? (errno = %d)", errno); return -1; } void slrn_do_key (SLKeyMap_List_Type *map) { SLang_Key_Type *key; static SLKeyMap_List_Type *last_map; static SLang_Key_Type *last_key; key = SLang_do_key (map, (int (*)(void)) SLang_getkey); if (Slrn_Message_Present || SLang_Error) { #if SLRN_HAS_SLANG if (SLang_Error) SLang_restart (0); #endif slrn_clear_message (); } SLang_Error = SLKeyBoard_Quit = 0; if ((key == NULL) || (key->type == 0)) { SLtt_beep (); return; } if (key->type == SLKEY_F_INTRINSIC) { if ((map == last_map) && (key->f.f == (FVOID_STAR) slrn_repeat_last_key)) key = last_key; /* set now to avoid problems with recursive call */ last_key = key; last_map = map; if (key->type == SLKEY_F_INTRINSIC) { (((void (*)(void))(key->f.f)) ()); return; } } /* Otherwise we have interpreted key. */ #if SLRN_HAS_SLANG last_key = key; last_map = map; Slrn_Full_Screen_Update = 1; if ((*key->f.s == '.') || !SLang_execute_function (key->f.s)) SLang_load_string(key->f.s); #endif }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.