rsalz@uunet.uu.net (Rich Salz) (06/27/89)
Submitted-by: storm@texas.dk (Kim F. Storm) Posting-number: Volume 19, Issue 75 Archive-name: nn/part14 #!/bin/sh # this is part 14 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file s-tower32.h continued # CurArch=14 if test ! -r s2_seq_.tmp then echo "Please unpack part 1 first!" exit 1; fi ( read Scheck if test "$Scheck" != $CurArch then echo "Please unpack part $Scheck next!" exit 1; else exit 0; fi ) < s2_seq_.tmp || exit 1 echo "x - Continuing file s-tower32.h" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' >> s-tower32.h X */ X X/* #define HAVE_MKDIR /* */ X X/* X * Define HAVE_GETHOSTNAME if your system provides a BSD like X * gethostname routine. X * Otherwise, define HAVE_UNAME if uname() is avaiable. X * As a final resort, define HOSTNAME to the name of your system. X */ X X#define HAVE_UNAME /* System V */ X X/* X * Define DETATCH_TERMINAL to be a command sequence which X * will detatch a process from the control terminal X * Also include files needed to perform this HERE. X * If not possible, just define it (empty) X */ X X#define DETATCH_TERMINAL setpgrp(); /* System V */ X X/* X * Specify where the Bourne Shell is. X */ X X#define SHELL "/bin/sh" X X/* X * Specify the default mailer to be invoked by nnmail X */ X X#define MAILX "/usr/bin/mailx" /* SV */ X X/* X * Specify the default pager & options. X */ X X#define PAGER "pg -n -s" X X/* X * Specify the default print command and options. X */ X X#define PRINTER "lp -s" X X X/* X * Define the maximum length of any pathname that may occur X */ X X#define FILENAME 128 NO_NEWS_IS_GOOD_NEWS echo "File s-tower32.h is complete" chmod 0644 s-tower32.h || echo "restore of s-tower32.h fails" set `wc -c s-tower32.h`;Sum=$1 if test "$Sum" != "2624" then echo original size 2624, current size $Sum;fi echo "x - extracting s-usg3-1.h (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > s-usg3-1.h && X/* X * This version is for System V Release 3.1 X */ X X X/* X * Include header files containing the following definitions: X * X * off_t, time_t, struct stat X */ X X#include <sys/types.h> X#include <sys/stat.h> X X/* X * Define if your system has system V like ioctls X */ X X#define HAVE_TERMIO /* */ X X/* X * Define to use terminfo database. X * Otherwise, termcap is used X */ X X#define USE_TERMINFO /* */ X X/* X * Specify the library containing the termcap/terminfo access routines. X * Notice: nn does not use curses. X * Notice: You must also specify whether termcap or terminfo is X * used when you edit config.h (see below). X */ X X#define TERMLIB -lcurses X X/* X * Define HAVE_STRCHR if strchr() and strrchr() are available X */ X X#define HAVE_STRCHR /* */ X X/* X * Define if a signal handler has type void (see signal.h) X */ X X#define SIGNAL_HANDLERS_ARE_VOID /* */ X X/* X * Define if signals must be set again after they are caught X */ X X#define RESET_SIGNAL_WHEN_CAUGHT /* */ X X/* X * Define MICRO_ALARM to timeout in 0.1 seconds if possible X */ X X#define MICRO_ALARM() alarm(1) /* System V */ X X/* X * Define if your system has BSD like job control (SIGTSTP works) X */ X X/* #define HAVE_JOBCONTROL /* */ X X/* X * Define if your system provides the "directory(3X)" access routines X * X * If true, include the header file(s) required by the package below X * (remember that <sys/types.h> or equivalent is included above) X * Also typedef Direntry to the proper struct type. X */ X X#define HAVE_DIRECTORY /* */ X X#include <dirent.h> /* System V */ X Xtypedef struct dirent Direntry; /* System V */ X X/* X * Define if your system has a mkdir() library routine X */ X X#define HAVE_MKDIR /* */ X X/* X * Define HAVE_GETHOSTNAME if your system provides a BSD like X * gethostname routine. X * Otherwise, define HAVE_UNAME if uname() is avaiable. X * As a final resort, define HOSTNAME to the name of your system. X */ X X#define HAVE_UNAME /* System V */ X X/* X * Define DETATCH_TERMINAL to be a command sequence which X * will detatch a process from the control terminal X * Also include files needed to perform this HERE. X * If not possible, just define it (empty) X */ X X#define DETATCH_TERMINAL setpgrp(); /* System V */ X X/* X * Specify where the Bourne Shell is. X */ X X#define SHELL "/bin/sh" X X/* X * Specify the default mailer to be invoked by nnmail X */ X X#define MAILX "/usr/bin/mailx" /* SV */ X X/* X * Specify the default pager & options. X */ X X#define PAGER "pg -n -s" X X/* X * Specify the default print command and options. X */ X X#define PRINTER "lp -s" X X X/* X * Define the maximum length of any pathname that may occur X */ X X#define FILENAME 128 NO_NEWS_IS_GOOD_NEWS chmod 0644 s-usg3-1.h || echo "restore of s-usg3-1.h fails" set `wc -c s-usg3-1.h`;Sum=$1 if test "$Sum" != "2611" then echo original size 2611, current size $Sum;fi echo "x - extracting save.c (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > save.c && X#include <signal.h> X#include <errno.h> X#include "config.h" X#include "term.h" X#include "keymap.h" X#include "news.h" X X/* X * save (or print) articles X */ X X/* #define PAGED_OUTPUT /* does not work yet!! */ X Xexport char *default_save_file = "+$F"; Xexport int use_mail_folders = 0; Xexport int save_report = 1; Xexport int quick_save = 0; Xexport int conf_append = 0; X Xexport char *save_counter_format = "%d"; /* format of save counter */ X Xexport char printer[FILENAME] = PRINTER; /* lp -s -ol */ Xexport char *patch_cmd = "patch"; X Xextern int file_completion(); X Ximport char *temp_file; X Xstatic int save_mode; Xstatic char *unshar_cmd; X X#define HEADER_HANDLING 0x0f /* what should we do with the header */ X X#define NO_HEADER 0 /* save without a header */ X#define FULL_HEADER 1 /* save with full header */ X#define SHORT_HEADER 2 /* save with partial header */ X#define SHORT_HEADER_DG 3 /* save with partial header (digest) */ X X X#define SEPARATE_FILES 0x0100 /* save as separate files */ X#define UNIQUE_FILES 0x0200 /* save in unique files */ X#define FILE_IS_NEW 0x0400 /* this is a new file */ X#define APPEND_ARTNUM 0x0800 /* append article number to file name */ X#define IS_PIPE 0x1000 /* output is on pipe */ X#define DO_UNSHAR 0x2000 /* unshar article (or patch) */ X#define DO_PATCH 0x4000 /* patch article */ X X/* open modes for open_news_article for the various HEADER_HANDLINGs */ X Xstatic int open_mode[] = { X SKIP_HEADER, X 0, X FILL_NEWS_HEADER | SKIP_HEADER, X FILL_DIGEST_HEADER | SKIP_HEADER X}; X Xstatic FILE *save_file; /* output stream for saved files */ Xstatic char *save_name; /* save file name */ X X#ifdef PAGED_OUTPUT Xstatic FILE *pager_stream = NULL; /* unshar/patch output stream */ Xstatic char pager_redir[40]; X#endif X Xstatic int counter_index; /* index into save_name of '*' */ Xstatic int uniq_counter; /* separate files counter */ X Xstatic char last_dir[FILENAME] = ""; X Xchar *init_save(command, mode_textp) Xchar command; Xchar **mode_textp; X{ X char *mode_text; X static char last_input[FILENAME] = ""; X static char name_buf[512]; /* buffer for file name & command expansion */ X char *start, *last, *np; X char *ckdir_path(); X X uniq_counter = 0; X X switch (command) { X X case K_SAVE_FULL_HEADER: X save_mode = FULL_HEADER; X mode_text = "Save"; X goto cont_save; X X case K_SAVE_SHORT_HEADER: X save_mode = SHORT_HEADER; X mode_text = "Output"; X goto cont_save; X X case K_SAVE_NO_HEADER: X save_mode = NO_HEADER; X mode_text = "Write"; X X cont_save: X if (quick_save && (current_group->group_flag & G_FOLDER) == 0) { X if (current_group->save_file) X save_name = current_group->save_file; X else X save_name = default_save_file; X strcpy(last_input, save_name); X save_name = last_input; X } else { X prompt("\1%s on\1 (+~|) ", mode_text); X X save_name = get_s(last_input, current_group->save_file, NONE, X file_completion); X if (save_name == NULL || *save_name == NUL) return NULL; X X if (save_name[1] == NUL && save_name[0] == '+') X save_name = default_save_file; X else X if (current_group->save_file == NULL || X strcmp(save_name, current_group->save_file)) X strcpy(last_input, save_name); X } X X if (*save_name == '|') { X mode_text = "Pipe"; X save_name++; X save_mode |= IS_PIPE; X if (*save_name == '|' || *save_name == '*') { X save_mode |= SEPARATE_FILES; X save_name++; X } X } else { X counter_index = strlen(save_name) - 1; X np = save_name + counter_index; X if (*np == '*') X save_mode |= SEPARATE_FILES | UNIQUE_FILES; X else X if (counter_index > 0 && strcmp(--np, "$N") == 0) { X if (current_group->group_flag & G_FOLDER) { X msg("$N is not defined in a folder"); X return NULL; X } X counter_index--; X strcpy(np, "*"); X save_mode |= SEPARATE_FILES | APPEND_ARTNUM; X } X } X break; X X case K_PATCH: X save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR | DO_PATCH; X mode_text = "Patch"; X unshar_cmd = patch_cmd; X goto patch1; X X case K_UNSHAR: X save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR; X mode_text = "Unshar"; X unshar_cmd = SHELL; X X patch1: X prompt("\1%s Directory:\1 ", mode_text); X save_name = get_s(last_dir, NONE, NONE, file_completion); X if (save_name == NULL) return NULL; X if (*save_name == NUL) X save_name = NULL; X else { X strcpy(last_dir, save_name); X } X X break; X X case K_PRINT: X X save_mode = SHORT_HEADER | IS_PIPE; X X prompt("\1Print command:\1 "); X save_name = get_s(NONE, printer, NONE, NO_COMPLETION); X if (save_name == NULL || *save_name == NUL) return NULL; X X strcpy(printer, save_name); X mode_text = "Print"; X break; X X default: X msg("Illegal save command: %d", command); X return NULL; X } X X if (save_name) { X X if (save_mode & IS_PIPE || *save_name == '+' || *save_name == '~') { X if (!expand_file_name(name_buf, save_name)) X return NULL; X if (save_mode & SEPARATE_FILES) X counter_index = strlen(name_buf) - 1; X } else X strcpy(name_buf, save_name); X X save_name = name_buf; X X if (!(save_mode & IS_PIPE)) { X if (file_exist(save_name, (save_mode & DO_UNSHAR) ? "wd" : "wf")) { X if (conf_append && (save_mode & DO_UNSHAR) == 0) { X printf("\rAppend to: %s ? ", save_name); X clrline(); X if (!yes(0)) return NULL; X } X } else { X if (errno != ENOENT) { X msg("Cannot access %s", save_name); X return NULL; X } X X if (save_mode & DO_UNSHAR) { X strcat(save_name, "/"); X } X X start = ckdir_path(save_name); X if (start == NULL) { X msg("No permission"); X return NULL; X } X X last = strrchr(start, '/'); X /* last != NULL => non-existing directories */ X X if (!(save_mode & SEPARATE_FILES) || last) { X printf("\rCreate "); X for (np = save_name; *np; np++) { X if (np == start) putchar('\"'); X putchar(*np); X if ((save_mode & SEPARATE_FILES) && np == last) break; X } X printf("\" ?"); X clrline(); X if (yes(last != NULL) <= 0) return NULL; X } X X if (last && !mkdirs_in_path(save_name, start)) X return NULL; X } X } X } X X if (mode_textp) *mode_textp = mode_text; X X save_mode |= FILE_IS_NEW; /* so save() will open it */ X X#ifdef PAGED_OUTPUT X if (save_mode & DO_UNSHAR) { X int was_raw = no_raw(); X pager_stream = popen(pager, "w"); X if (was_raw) raw(); X X if (pager_stream == NULL) { X pager_redir[0] = NUL; X msg("Warning: Pager '%s' not found"); X } else X sprintf(pager_redir, " 1>&%d 2>&1 ; ", fileno(pager_stream)); X system("fdcheck"); X } X#endif X X return save_name; X} X X Xsave(ah) Xarticle_header *ah; X{ X register FILE *art; X register c, lcount, mode; X news_header_buffer hdrbuf; X int was_raw = 0; X char copybuf[1024]; X X if (ah->a_group) init_group(ah->a_group); X X mode = save_mode & HEADER_HANDLING; X if (mode == SHORT_HEADER && ah->flag & A_DIGEST) X mode = SHORT_HEADER_DG; X X art = open_news_article(ah, open_mode[mode], hdrbuf, (char *)NULL); X if (art == NULL) { X msg("Cannot read %s", group_path_name); X return 0; X } X X if (save_mode & UNIQUE_FILES) { X do { X uniq_counter++; X sprintf(save_name + counter_index, X save_counter_format, uniq_counter); X } while (file_exist(save_name, (char *)NULL)); X X save_mode |= FILE_IS_NEW; X } else X if (save_mode & APPEND_ARTNUM) X sprintf(save_name + counter_index, "%d", ah->a_number); X X if (save_mode & FILE_IS_NEW) X if (save_mode & IS_PIPE) { X if ((save_file = popen(save_name, "w")) == NULL) { X msg("Cannot pipe to %s", save_name); X fclose(art); X return 0; X } X } else X if (save_mode & DO_UNSHAR) { X if ((save_mode & DO_PATCH) == 0 && !unshar_position(art)) { X fclose(art); X return 0; X } X was_raw = no_raw(); X if (save_name) X#ifdef PAGED_OUTPUT X sprintf(copybuf, "cd %s && %s %s", save_name, unshar_cmd, pager_redir); X else X sprintf(copybuf, "%s %s", unshar_cmd, pager_redir); X#else X sprintf(copybuf, X "cd %s && %s | tee %s 2>&1 ; cat %s >> %s.Result ; rm %s", X save_name != NULL ? save_name : ".", unshar_cmd, X temp_file, temp_file, X (save_mode & DO_PATCH) ? "Patch" : "Unshar", X temp_file); X#endif X save_file = popen(copybuf, "w"); X if (save_file == NULL) { X msg("Cannot exec: '%s'", copybuf); X if (was_raw) raw(); X fclose(art); X return 0; X } X#ifdef PAGED_OUTPUT X fprintf(pager_stream, "\r\n%s %s\r\n", X save_mode & DO_PATCH ? "PATCHING FROM" : "UNPACKING", X ah->subject ? ah->subject : "ARTICLE"); X fflush(pager_stream); X#else X printf("\r\n%s %s\r\n", X save_mode & DO_PATCH ? "PATCHING FROM" : "UNPACKING", X ah->subject ? ah->subject : "ARTICLE"); fl; X#endif X } else { X if ((save_file = open_file(save_name, OPEN_APPEND)) == NULL) { X msg("Cannot write %s", save_name); X fclose(art); X return 0; X } X if (ftell(save_file) != (off_t)0) X save_mode &= ~FILE_IS_NEW; X } X X clrline(); X s_pipe = 0; X X if (use_mail_folders && mode != NO_HEADER) { X time_t now; X char *ctime(); X X time(&now); X fprintf(save_file, "From %s %s", X current_group->group_name, ctime(&now)); X } X X if (mode == FULL_HEADER) { X int cnt = ah->fpos - ah->hpos; X while (--cnt >= 0) { X if ((c = getc(art)) == EOF) break; X putc(c, save_file); X } X } else X if (mode == SHORT_HEADER) { X if (news.ng_from) X fprintf(save_file, "From: %s\n", news.ng_from); X if (news.ng_date) X fprintf(save_file, "Date: %s\n", news.ng_date); X if (news.ng_subj) X fprintf(save_file, "Subject: %s\n", news.ng_subj); X fputc(NL, save_file); X } else X if (mode == SHORT_HEADER_DG) { X if (digest.dg_from) X fprintf(save_file, "From: %s\n", digest.dg_from); X if (digest.dg_date) X fprintf(save_file, "Date: %s\n", digest.dg_date); X if (digest.dg_subj) X fprintf(save_file, "Subject: %s\n", digest.dg_subj); X fputc(NL, save_file); X } X X fflush(save_file); X if (s_pipe) goto broken_pipe; X X mode = mode != NO_HEADER && (save_mode & (IS_PIPE | DO_UNSHAR)) == 0; X X lcount = 0; X while (ftell(art) < ah->lpos && fgets(copybuf, 512, art)) { X lcount++; X if (mode && is_header_line(copybuf)) X fputc('~', save_file); X fputs(copybuf, save_file); X if (s_pipe) goto broken_pipe; X } X X if (mode) { X putc(NL, save_file); X lcount++; X } X Xbroken_pipe: X fclose(art); X X if (save_mode & DO_UNSHAR) { X pclose(save_file); X save_file = NULL; X } else { X if (s_pipe) X msg("Command did not read complete article!"); X else X if (save_report) X msg((save_mode & IS_PIPE) ? "%s: %d lines piped" : X (save_mode & FILE_IS_NEW) ? "%s created: %d lines written" : X "%s: %d lines appended", save_name, lcount); X X if (s_pipe || (save_mode & SEPARATE_FILES)) X end_save(); X else X save_mode &= ~FILE_IS_NEW; X } X X#ifdef MAIL_READING X if (mail_auto_delete && (save_mode & IS_PIPE) == 0) X if (current_group->group_flag & G_MAILBOX) X if ((ah->flag & A_CANCEL) == 0) X fcancel(ah); X#endif X if (was_raw) raw(); X X return !s_pipe || (save_mode & SEPARATE_FILES); X} X X Xend_save() X{ X if (save_file) { X if (save_mode & (IS_PIPE | DO_UNSHAR)) X pclose(save_file); X else X fclose(save_file); X save_file = NULL; X } X X#ifdef PAGED_OUTPUT X if (pager_stream != NULL) { X pclose(pager_stream); X pager_stream = NULL; X } X#else X if (save_mode & DO_UNSHAR) { X import char *delayed_msg; X X delayed_msg = (save_mode & DO_PATCH) ? X "Output is saved in Patch.Result" : X "Output is saved in Unshar.Result"; X } X#endif X} X X Xchar *run_mkdir(dir, name_buf) Xchar *dir, *name_buf; X{ X if (dir == NULL) { X prompt("\1Directory: \1"); X dir = get_s(last_dir, NONE, NONE, file_completion); X if (dir == NULL || *dir == NUL) return NULL; X strcpy(last_dir, dir); X } X X if (*dir == '+' || *dir == '~') { X if (!expand_file_name(name_buf, dir)) X return NULL; X dir = name_buf; X } X X if (file_exist(dir, (char *)NULL)) { X msg("Directory %s already exists", dir); X return NULL; X } X X if (mkdir(dir, 0755)) { X msg("Cannot make %s", dir); X return NULL; X } X X return dir; X} X X Xchange_dir(dir, in_init) Xchar *dir; Xint in_init; X{ X char dir_buf[FILENAME]; X X if (dir == NULL) { X prompt("\1Directory: \1"); X dir = get_s(last_dir, NONE, NONE, file_completion); X } X X if (dir == NULL || *dir == NUL) return 0; X X strcpy(last_dir, dir); X X if (*dir == '+' || *dir == '~') { X if (!expand_file_name(dir_buf, dir)) return in_init; X dir = dir_buf; X } X X if (chdir(dir) == 0) { X if (!in_init) msg("Directory: %s", dir); X return 0; X } X X if (in_init) return 1; X X if (errno == EACCES) X msg("Cannot access directory %s", dir); X else { X /* should ask and create directory here */ X msg("Directory not found: %s", dir); X } X X return 0; X} X X X X/* X * return pointer to first path name component, that does not exist X */ X Xstatic char *ckdir_path(name) Xchar *name; X{ X char *slash; X char *component; X X component = name; X X while (slash = strchr(component, '/')) { X if (slash == component) { X /* ...//... */ X component++; X continue; X } X *slash = NUL; X if (file_exist(name, "drx")) { X *slash++ = '/'; X component = slash; X continue; X } X if (file_exist(name, (char *)NULL)) { X *slash = '/'; X return NULL; X } X *slash = '/'; X break; X } X return component; X} X X/* X * create directories in path name, starting from start X */ X Xstatic mkdirs_in_path(name, start) Xchar *name, *start; X{ X char *slash; X char *component; X X component = start; X X while (slash = strchr(component, '/')) { X if (slash == component) { X /* ...//... */ X component++; X continue; X } X *slash = NUL; X if (mkdir(name, 0755)) { X msg("Cannot make %s/", name); X *slash = '/'; X return 0; X } X *slash++ = '/'; X component = slash; X } X return 1; X} X NO_NEWS_IS_GOOD_NEWS chmod 0644 save.c || echo "restore of save.c fails" set `wc -c save.c`;Sum=$1 if test "$Sum" != "13813" then echo original size 13813, current size $Sum;fi echo "x - extracting selection.c (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > selection.c && X/* X * save selected articles (if any) between invocations X */ X X#include "config.h" X#include "articles.h" X X#define SLMAGIC 0x536c6374 X#define GNAME_LGT 32 X Xstatic struct sel_header { X char sl_group[GNAME_LGT]; X int32 sl_magic; X int32 sl_count; X int32 sl_first; X int32 sl_last; X} header; X X#ifndef NETWORK_DATABASE X#undef ntohl X#undef htonl X#undef NETWORK_BYTE_ORDER X#define ntohl(x) (x) X#define htonl(x) (x) X#define NETWORK_BYTE_ORDER X#endif X Xstruct sel_art { X int32 sl_number; X int32 sl_fpos; X int32 sl_flag; X}; X X Xsave_selection(gh, first, last) Xgroup_header *gh; Xarticle_number first, last; X{ X register article_header *ah, **ahp; X register int art; X register int save_count, seen_count, flags; X struct sel_art elem; X FILE *f; X char buffer[16]; X X if (gh->group_flag & (G_FOLDER | G_READ)) return; X X for (save_count = seen_count = 0, art = n_articles; --art >= 0; ) { X flags = articles[art]->flag; X if (flags & A_SEEN) seen_count++; X if (flags & A_SELECT) save_count++; X } X X if (save_count == 0 && X (seen_count == 0 || seen_count == n_articles)) return; X X sprintf(buffer, "S.%d", (int)(gh->group_num)); X f = open_file(relative(nn_directory, buffer), OPEN_CREATE|MUST_EXIST); X X strncpy(header.sl_group, gh->group_name, GNAME_LGT); X header.sl_magic = htonl(SLMAGIC); X header.sl_count = htonl(save_count); X header.sl_first = htonl(first); X header.sl_last = htonl(last); X X fwrite(&header, sizeof(header), 1, f); X X unsort_articles(1); X X for (ahp = articles, art = 0; art < n_articles; ahp++, art++) { X ah = *ahp; X if (elem.sl_flag = htonl(ah->flag & (A_SELECT | A_SEEN))) { X X elem.sl_number = htonl(ah->a_number); X elem.sl_fpos = htonl(ah->fpos); X X fwrite(&elem, sizeof(elem), 1, f); X } X } X X fclose(f); X X gh->group_flag |= G_SELECTION; X} X X Xstatic FILE *sel_file; X Xhas_selection(gh, first_p, last_p) Xgroup_header *gh; Xarticle_number *first_p, *last_p; X{ X FILE *f; X char buffer[16]; X X if (gh->group_flag & (G_FOLDER | G_READ)) return 0; X X sprintf(buffer, "S.%d", (int)(gh->group_num)); X f = open_file(relative(nn_directory, buffer), OPEN_READ|OPEN_UNLINK); X if (f == NULL) return 0; X X if (fread(&header, sizeof(header), 1, f) != 1 X || ntohl(header.sl_magic) != SLMAGIC X || strncmp(header.sl_group, gh->group_name, GNAME_LGT)) { X fclose(f); X return 0; X } X X if ((gh->group_flag & G_SELECTION) == 0) { X clrdisp(); X raw(); X prompt("Group %s: use old selections (%s)? ", X gh->group_name, date_time(m_time(f))); X if (yes(0) <= 0) { X fclose(f); X return 0; X } X } X X#ifndef NETWORK_BYTE_ORDER X header.sl_first = ntohl(header.sl_first); X header.sl_last = ntohl(header.sl_last); X#endif X *first_p = header.sl_first; X *last_p = header.sl_last; X sel_file = f; X X return 1; X} X X Xdo_selections(ok) Xint ok; X{ X register long art; X struct sel_art elem; X register article_header *ah, **ahp; X X if (!ok) goto out; X X elem.sl_number = -1; X X for (ahp = articles, art = 0; art < n_articles; ahp++, art++) { X ah = *ahp; X X if (ah->a_number > header.sl_last) break; X X while (ah->a_number > elem.sl_number) { X if (fread(&elem, sizeof(elem), 1, sel_file) != 1) goto out; X#ifndef NETWORK_BYTE_ORDER X elem.sl_number = ntohl(elem.sl_number); X#endif X } X X#ifndef NETWORK_BYTE_ORDER X elem.sl_fpos = ntohl(elem.sl_fpos); X#endif X while (ah->a_number == elem.sl_number && ah->fpos > elem.sl_fpos) { X if (fread(&elem, sizeof(elem), 1, sel_file) != 1) goto out; X#ifndef NETWORK_BYTE_ORDER X elem.sl_number = ntohl(elem.sl_number); X elem.sl_fpos = ntohl(elem.sl_fpos); X#endif X } X X if (ah->a_number != elem.sl_number || ah->fpos != elem.sl_fpos) X continue; X X ah->flag |= ntohl(elem.sl_flag); X } X Xout: X X fclose(sel_file); X} X NO_NEWS_IS_GOOD_NEWS chmod 0644 selection.c || echo "restore of selection.c fails" set `wc -c selection.c`;Sum=$1 if test "$Sum" != "3865" then echo original size 3865, current size $Sum;fi echo "x - extracting sequence.c (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > sequence.c && X/* X * read presentation sequence file X */ X X#include "config.h" X#include "debug.h" X Xexport group_header *group_sequence; Xexport char *read_mail = NULL; X Xstatic int seq_break_enabled = 1; /* !! enabled */ X Xstatic group_header *tail_sequence = NULL; Xstatic group_header *final_sequence = NULL; X Xstatic int gs_more_groups; X X Xonly_folder_args(args) Xchar **args; X{ X register char *arg; X X while (arg = *args++) { X if (*arg == '+' || *arg == '~' || *arg == '/') continue; X if (file_exist(arg, "fr")) continue; X return 0; X } X return 1; X} X X Xnamed_group_sequence(groups) Xchar **groups; X{ X register group_header *gh; X group_header *get_group_search(); X register char *group; X int found, any, errors; X X group_sequence = NULL; X X any = errors = 0; X while (group = *groups++) { X X if (gh = lookup(group)) { X if (gh->group_flag & G_DONE) continue; X any++; X enter_normal(gh); X continue; X } X X if (file_exist(group, "fr")) { X faked_entry(group, G_FOLDER); X any++; X continue; X } X X if (*group == '+' || *group == '~') { X char exp_file[FILENAME]; X group_header fake_group; X X current_group = &fake_group; X fake_group.group_name = group; X group_file_name = NULL; X if (expand_file_name(exp_file, group) && file_exist(exp_file, "fr")) { X faked_entry(copy_str(exp_file), G_FOLDER); X any++; X continue; X } X X printf("Folder %s not found\n", group); fl; X errors++; X continue; X } X X found = 0; X start_group_search(group); X while (gh = get_group_search()) { X if ((gh->group_flag & G_SUBSCRIPTION) == 0) continue; X found++; X enter_normal(gh); X } X X if (!found) { X printf("Group %s not found\n", group); fl; X errors++; X } else X any++; X } X X end_sequence(); X X if (errors) user_delay(2); X X return any; X} X XFILE *loc_seq_hook = NULL; /* sequence in local "init" file */ XFILE *glob_seq_hook = NULL; /* sequence in global "init" file */ X Xnormal_group_sequence() X{ X register group_header *gh; X X group_sequence = NULL; X gs_more_groups = 1; X X /* visit_p_f returns non-zero if terminated by !! */ X X if (visit_presentation_file(nn_directory, "seq", loc_seq_hook)) X goto final; X X if (visit_presentation_file(lib_directory, "sequence", glob_seq_hook)) X goto final; X X Loop_Groups_Sorted(gh) { X if (gh->group_flag & G_DONE) continue; X X if ((gh->group_flag & G_SUBSCRIPTION) == 0) continue; X X enter_normal(gh); X } X X final: X if (final_sequence) { X enter_normal(final_sequence); X tail_sequence = NULL; X } X X#ifdef MAIL_READING X mail_check(); X#endif X X end_sequence(); X} X Xstatic end_sequence() X{ X register group_header *gh, *backp; X X if (tail_sequence) X tail_sequence->next_group = NULL; X X /* set up backward pointers */ X X backp = NULL; X gh = group_sequence; X while (gh) { X gh->prev_group = backp; X backp = gh; X gh = gh->next_group; X } X X#ifdef SEQ_DUMP X if (Debug & SEQ_DUMP) { X for (gh = group_sequence; gh; gh = gh->next_group) X printf("%s\t", gh->group_name); X putchar(NL); X X nn_exit(0); X } X#endif X X} X X#ifdef MAIL_READING Xstatic mail_check() X{ X static group_header mail_group; X struct stat st; X X if (read_mail == NULL) return; X if (stat(read_mail, &st) < 0) return; X if (st.st_size == 0 || st.st_mtime < st.st_atime) return; X X mail_group.group_name = read_mail; X gh->group_flag = G_FOLDER | G_MAILBOX | G_RC_UPDATED | G_READ; X X /* "invent" an unread article for read_news */ X gh->last_article = 1; X gh->last_l_article = 2; X X X if (tail_sequence) { X mail_group.next_group = group_sequence; X group_sequence = mail_group; X } else X enter_normal(&mail_group); X} X#endif X Xstatic visit_presentation_file(directory, seqfile, hook) Xchar *directory, *seqfile; XFILE *hook; X{ X import int group_name_args; X X register FILE *sf; X register c; X register group_header *gh; X group_header *get_group_search(); X char group[FILENAME]; X char savefile[FILENAME], *dflt_save; X register char *gp; X int mode; X X#define SHOW_NORMAL 0 /* : put this in at current pos */ X#define SHOW_NEVER 1 /* ! : ignore these groups */ X#define SHOW_FIRST 2 /* < : show these groups first */ X#define SHOW_LAST 3 /* > : show this as late as possible */ X X#define SHOW_MODES " !<>" X X if (gs_more_groups == 0) return 0; X X if (hook != NULL) X sf = hook; /* hook to init file */ X else X if ((sf = open_file(relative(directory, seqfile), OPEN_READ)) == NULL) X return 0; X X#ifdef SEQ_TEST X if (Debug & SEQ_TEST) X printf("Sequence file %s/%s\n", directory, seqfile); X#endif X X mode = SHOW_NORMAL; X savefile[0] = NUL; X X while (gs_more_groups) { X X if ((c = getc(sf)) == EOF) break; X if (!isascii(c) || isspace(c)) continue; X X switch (c) { X case '!': X if (mode == SHOW_NEVER && seq_break_enabled) { X fclose(sf); X return 1; X } X X mode = SHOW_NEVER; X continue; X X case '<': X mode = SHOW_FIRST; X continue; X X case '>': X mode = SHOW_LAST; X continue; X X case '@': X seq_break_enabled = 0; X mode = SHOW_NORMAL; X continue; X X case '#': X do c = getc(sf); X while (c != EOF && c != NL); X mode = SHOW_NORMAL; X continue; X X } X X gp = group; X do { X *gp++ = c; X c = getc(sf); X } while (c != EOF && isascii(c) && !isspace(c)); X X *gp = NUL; X X while (c != EOF && (!isascii(c) || isspace(c))) c = getc(sf); X if (c == '+' || c == '~' || c == '/') { X gp = savefile; X if (c == '+') { X c = getc(sf); X if (c == EOF || (isascii(c) && isspace(c))) X goto use_same_savefile; X *gp++ = '+'; X } X do { X *gp++ = c; X c = getc(sf); X } while (c != EOF && isascii(c) && !isspace(c)); X *gp = NUL; X dflt_save = savefile[0] ? copy_str(savefile) : NULL; X } else { X dflt_save = NULL; X if (c != EOF) ungetc(c, sf); X } X X use_same_savefile: X X start_group_search(group); X X while (gh = get_group_search()) { X X gh->save_file = dflt_save; X X if (group_name_args == 0 && X (gh->group_flag & G_SUBSCRIPTION) == 0) continue; X X#ifdef SEQ_TEST X if (Debug & SEQ_TEST && mode != SHOW_NORMAL) X printf("SEQ(%c), %s\n", SHOW_MODES[mode], gh->group_name); X#endif X X switch (mode) { X case SHOW_FIRST: X if (tail_sequence) { X gh->next_group = group_sequence; X group_sequence = gh; X break; X } X /* fall thru */ X X case SHOW_NORMAL: X enter_normal(gh); X break; X X case SHOW_NEVER: X break; X X case SHOW_LAST: X gh->next_group = final_sequence; X final_sequence = gh; X break; X } X } X X mode = SHOW_NORMAL; X } X X fclose(sf); X return 0; X} X X Xstatic enter_normal(gh) Xgroup_header *gh; X{ X gh->group_flag |= G_DONE; X if (tail_sequence) X tail_sequence->next_group = gh; X else X group_sequence = gh; X X tail_sequence = gh; X X#ifdef SEQ_TEST X if (Debug & SEQ_TEST) X printf("SEQ(NORMAL) %s\n", gh->group_name); X#endif X} X X Xstatic faked_entry(name, flag) Xchar *name; Xint flag; X{ X group_header *gh; X X gh = (group_header *)calloc(1, sizeof(group_header)); X mem_check(gh, 1, "group header"); X X gh->group_name = name; X gh->group_flag = flag | G_RC_UPDATED | G_READ; X X /* "invent" an unread article for read_news */ X gh->last_article = 1; X gh->last_l_article = 2; X X enter_normal(gh); X} X X Xstatic char *gs_group; Xstatic int gs_length, gs_index, gs_mode; X X#define GS_PREFIX 1 /* group. */ X#define GS_SUFFIX 2 /* .group */ X#define GS_INFIX 3 /* .group. */ X#define GS_NEW_GROUP 4 /* new group */ X Xstatic start_group_search(group) Xchar *group; X{ X char *dot; X X if (strcmp(group, "NEW") == 0) { X gs_mode = GS_NEW_GROUP; X gs_length = 127; X } else { X gs_mode = GS_PREFIX; X X if (strncmp(group, "all.", 4) == 0) group += 3; X X if (*group == '.') gs_mode = GS_SUFFIX; X X if ((dot = strrchr(group, '.')) != NULL && dot != group) { X if (dot[1] == NUL || strcmp(dot+1, "all") == 0) { X *dot = NUL; X if (gs_mode == GS_SUFFIX) gs_mode = GS_INFIX; X } X } X X gs_length = strlen(group); X gs_group = group; X } X X gs_index = 0; X gs_more_groups = 0; X} X X Xstatic group_header *get_group_search() X{ X register group_header *gh; X register int c, tail; X X while (gs_index < master.number_of_groups) { X gh = sorted_groups[gs_index++]; X if (gh->group_flag & G_DONE) continue; X X gs_more_groups++; X X if ((tail = gh->group_name_length - gs_length) < 0) continue; X X switch (gs_mode) { X X case GS_NEW_GROUP: X if ((gh->group_flag & G_NEW) == 0) continue; X break; X X case GS_PREFIX: X if ((c = (gh->group_name)[gs_length]) != NUL && c != '.') continue; X if (strncmp(gh->group_name, gs_group, gs_length)) continue; X break; X X case GS_SUFFIX: X if (strcmp(gh->group_name + tail, gs_group)) continue; X break; X X case GS_INFIX: X user_error(".name. notation not supported (yet)"); X break; X } X X gs_more_groups--; X gh->group_flag |= G_DONE; X X return gh; X } X X return NULL; X} NO_NEWS_IS_GOOD_NEWS chmod 0644 sequence.c || echo "restore of sequence.c fails" set `wc -c sequence.c`;Sum=$1 if test "$Sum" != "8980" then echo original size 8980, current size $Sum;fi echo "x - extracting term.c (Text)" sed 's/^X//' << 'NO_NEWS_IS_GOOD_NEWS' > term.c && X/* X * terminal interface X */ X X#include <signal.h> X#include <errno.h> X#include "config.h" X#include "term.h" X#include "keymap.h" X X#ifdef RESIZING X#include <sys/ioctl.h> /* for TIOCGWINSZ */ X Xint s_resized; X#endif X Xexport char *term_name; Xexport int show_current_time = 1; Xexport int conf_dont_sleep = 0; Xexport int prompt_length; Xexport int slow_mode = 0; Xexport int any_message = 0; X Xexport char help_key = '?'; Xexport char comp1_key = SP; Xexport char comp2_key = TAB; Xexport char erase_key, kill_key; Xexport char delword_key = CTRL('W'); X X#ifdef USE_TERMINFO X X#include <curses.h> X#ifndef auto_left_margin X#include <term.h> X#endif X X#define HAS_CAP(str) (str && *str) X X#else X X#define USE_TERMCAP X Xchar *tgoto(); Xchar PC; Xchar *BC, *UP; Xshort ospeed; X Xstatic char XBC[64], XUP[64]; Xstatic char cursor_home[64]; Xstatic char cursor_address[64]; Xstatic char clear_screen[64]; Xstatic char clr_eol[64]; Xstatic char clr_eos[64]; Xstatic char enter_standout_mode[64], exit_standout_mode[64]; Xstatic char enter_underline_mode[64], exit_underline_mode[64]; Xstatic char bell[256]; Xstatic char key_down[64], key_up[64], key_right[64], key_left[64]; X Xint magic_cookie_glitch; /* magic cookie size */ X X#define putp(str) tputs(str, 0, outc) X X#define HAS_CAP(str) (*str) X Xstatic outc(c) X{ X putchar(c); X} X X#endif /* USE_TERMCAP */ X Xint Lines, Columns; /* screen size */ Xint cookie_size; /* size of magic cookie */ Xint two_cookies; /* space needed to enter&exit standout mode */ Xint STANDOUT; /* terminal got standout mode */ Xint WRAP; /* terminal got automatic margins */ X X#ifdef HAVE_TERMIO X X#define KEY_BURST 50 /* read bursts of 50 chars (or timeout after 100 ms) */ X X#ifdef USE_TERMCAP X#include <termio.h> X#endif X Xstatic struct termio norm_tty, raw_tty; X X#define IntrC norm_tty.c_cc[VINTR] X#define EraseC norm_tty.c_cc[VERASE] X#define KillC norm_tty.c_cc[VKILL] X#define SuspC CTRL('Z') /* norm_tty.c_cc[SWTCH] */ X X#else /* V7/BSD TTY DRIVER */ X X#include <sgtty.h> X Xstatic struct sgttyb norm_tty, raw_tty; Xstatic struct tchars norm_chars; X X#define IntrC norm_chars.t_intrc X#define EraseC norm_tty.sg_erase X#define KillC norm_tty.sg_kill X X#ifdef TIOCGLTC Xstatic struct ltchars spec_chars; X#define SuspC spec_chars.t_suspc X#else X#define SuspC CTRL('Z') X#endif X X#endif X X#ifdef USE_TERMCAP X Xopt_cap(cap, buf) Xchar *cap, *buf; X{ X char *tgetstr(); X X *buf = NUL; X return tgetstr(cap, &buf) != NULL; X} X Xget_cap(cap, buf) Xchar *cap, *buf; X{ X if (!opt_cap(cap, buf)) X user_error("TERMCAP entry for %s has no '%s' capability", X term_name, cap); X} X X#endif /* USE_TERMCAP */ X Xstatic int multi_keys = 0; X Xstatic struct multi_key { X char *cur_key; X char *keys; X int code; X} multi_key_list[MULTI_KEYS]; X Xenter_multi_key(code, keys) Xint code; Xchar *keys; X{ X register i; X X /* lookup code to see if it is already defined... */ X for (i = 0; i < multi_keys; i++) X if (multi_key_list[i].code == code) X goto replace_key; X X i = multi_keys++; X X /* now i points to matching or empty slot */ X if (i >= MULTI_KEYS) { X /* should never happen */ X log_entry('E', "too many multi keys"); X return; X } X X replace_key: X X multi_key_list[i].keys = keys; X multi_key_list[i].code = code; X} X Xdump_multi_keys() X{ X register i; X register char *cp; X extern char *key_name(); X X clrdisp(); X pg_init(0, 1); X X for (i = 0; i < multi_keys; i++) { X if (pg_next() < 0) break; X printf("%d\t%s\t", i, key_name(multi_key_list[i].code)); X for (cp = multi_key_list[i].keys; *cp; cp++) { X putchar(SP); X fputs(key_name(*cp), stdout); X } X } X X pg_end(); X} X X X#ifdef RESIZING X Xsig_type winch() X{ X struct winsize winsize; X X (void) signal(SIGWINCH, winch); X if (ioctl(0, TIOCGWINSZ, &winsize) >= 0 X && (winsize.ws_row != Lines || winsize.ws_col != Columns)) { X Lines = winsize.ws_row; X Columns = winsize.ws_col; X s_redraw = 1; X s_resized = 1; X } X} X#endif /* RESIZING */ X X Xinit_term() X{ X#ifdef USE_TERMCAP X char tbuf[1024]; X#endif X X if ((term_name = getenv("TERM")) == NULL) X user_error("No TERM variable in enviroment"); X X#ifdef USE_TERMINFO X setupterm(0,1,0); X Columns = columns; X Lines = lines; X cookie_size = magic_cookie_glitch; X WRAP = auto_right_margin; X if (HAS_CAP(flash_screen)) strcpy(bell, flash_screen); X if (! HAS_CAP(cursor_home)) X cursor_home = copy_str(tgoto(cursor_address, 0, 0)); X#else X X if (tgetent(tbuf, term_name) <= 0) X user_error("Unknown terminal type: %s", term_name); X X if (opt_cap("bc", XBC)) BC = XBC; X if (opt_cap("up", XUP)) UP = XUP; X opt_cap("pc", cursor_address); /* temp. usage */ X PC = cursor_address[0]; X X get_cap("cm", cursor_address); X if (!opt_cap("ho", cursor_home)) X strcpy(cursor_home, tgoto(cursor_address, 0, 0)); X X get_cap("cl", clear_screen); X get_cap("ce", clr_eol); X opt_cap("cd", clr_eos); X X#ifdef RESIZING X { X struct winsize winsize; X X if (ioctl(0, TIOCGWINSZ, &winsize) >= 0 X && winsize.ws_row != 0 && winsize.ws_col != 0) { X Lines = winsize.ws_row; X Columns = winsize.ws_col; X (void) signal(SIGWINCH, winch); X#ifdef SV_INTERRUPT X siginterrupt(SIGWINCH, 1); /* make read from tty interruptable */ X#endif /* SV_INTERRUPT */ X } X } X if (Lines == 0 || Columns == 0) { X#endif /* RESIZING */ X Lines = tgetnum("li"); X Columns = tgetnum("co"); X#ifdef RESIZING X } X#endif /* RESIZING */ X X opt_cap("so", enter_standout_mode); X opt_cap("se", exit_standout_mode); X X opt_cap("us", enter_underline_mode); X opt_cap("ue", exit_underline_mode); X X opt_cap("kd", key_down); X opt_cap("ku", key_up); X opt_cap("kr", key_right); X opt_cap("kl", key_left); X X cookie_size = tgetnum("sg"); X X WRAP = tgetflag("am"); X X if (!opt_cap("vb", bell) && !opt_cap("bl", bell)) X strcpy(bell, "\007"); X X#endif /* !USE_TERMINFO */ X X STANDOUT = HAS_CAP(enter_standout_mode); X if (STANDOUT) { X if (cookie_size < 0) cookie_size = 0; X two_cookies = 2 * cookie_size; X } else X cookie_size = two_cookies = 0; X X X#ifdef HAVE_TERMIO X X ioctl(0, TCGETA, &norm_tty); X X raw_tty = norm_tty; X X raw_tty.c_iflag &= ~(BRKINT|INLCR|ICRNL|IGNCR); X raw_tty.c_iflag |= IGNBRK|IGNPAR|ISTRIP; X raw_tty.c_oflag &= ~OPOST; X raw_tty.c_lflag &= ~(ISIG|ICANON|XCASE|ECHO|NOFLSH); X X /* read a maximum of 10 characters in one burst; timeout in 1-200 ms */ X raw_tty.c_cc[VEOF] = KEY_BURST; X raw_tty.c_cc[VEOL] = ((raw_tty.c_cflag & CBAUD) > B1200) ? 1 : 2; X X#else X X ioctl(0, TIOCGETP, &norm_tty); X X ioctl(0, TIOCGETC, &norm_chars); X X#ifdef TIOCGLTC X ioctl(0, TIOCGLTC, &spec_chars); X#endif X X ospeed = norm_tty.sg_ospeed; X if (ospeed < B2400) slow_mode++; X X raw_tty = norm_tty; X X raw_tty.sg_flags |= RAW; X raw_tty.sg_flags &= ~(ECHO|CRMOD); X X#ifdef SV_INTERRUPT X siginterrupt(SIGALRM, 1); /* make read from tty interruptable */ X#endif X#endif X X if (HAS_CAP(key_down)) enter_multi_key(K_down_arrow, key_down); X if (HAS_CAP(key_up)) enter_multi_key(K_up_arrow, key_up); X if (HAS_CAP(key_right)) enter_multi_key(K_right_arrow, key_right); X if (HAS_CAP(key_left)) enter_multi_key(K_left_arrow, key_left); X X erase_key = EraseC; X kill_key = KillC; X} X Xhome() X{ X putp(cursor_home); X} X Xgotoxy(c, l) X{ X putp(tgoto(cursor_address, c, l)); X} X Xclrdisp() X{ X#ifdef USE_TERMINFO X putp(clear_screen); /* tputs is broken on UNISYS I've been told */ X#else X tputs(clear_screen, Lines, outc); X#endif X} X Xclrline() X{ X putp(clr_eol); X fl; X} X Xclrpage(lineno) Xregister int lineno; X{ X register int olineno= lineno; X X if (HAS_CAP(clr_eos)) { X#ifdef USE_TERMINFO X putp(clr_eos); X#else X tputs(clr_eos, Lines - lineno, outc); X#endif X } else { X clrline(); X lineno++; X for (; lineno < Lines; lineno++) { X gotoxy(0, lineno); X putp(clr_eol); X } X gotoxy(0, olineno); X fl; X } X} X Xstatic char so_buf[512], *so_p; Xstatic int so_c, so_l, so_b, so_active = 0; X Xso_gotoxy(c, l, blank) X{ X if (!STANDOUT && c >= 0) { X if (l >= 0) gotoxy(c, l); X return 0; X } X X so_active++; X so_c = c; X so_l = l; X so_b = blank; X so_p = so_buf; X *so_p = NUL; X X return 1; /* not really true if not standout & c < 0 */ X} X X/*VARARGS*/ Xso_printf(va_alist) Xva_dcl X{ X va_list ap; X X va_start(ap); X so_vprintf(va_args1toN); X va_end(ap); X} X Xso_vprintf(va_tail) Xva_tdcl X{ X char *fmt; X X fmt = va_arg1(char *); X X if (!so_active) { X vprintf(fmt, va_args2toN); X return; X } X X vsprintf(so_p, fmt, va_args2toN); X while (*so_p) so_p++; X} X Xso_end() X{ X int len; X X if (!so_active) return; X X if (so_l >= 0) { X X len = so_p - so_buf + two_cookies; X X if (so_c < 0) X so_c = Columns - len - 2; X if (so_c < 0) so_c = 0; X X if (len + so_c >= Columns) { X len = Columns - so_c - two_cookies; X so_buf[len] = NUL; X } X X if (cookie_size) { X gotoxy(so_c + len - cookie_size, so_l); X putp(exit_standout_mode); X } X X gotoxy(so_c, so_l); X X } X X if ((so_b & 1) && (!STANDOUT || !cookie_size)) putchar(SP); X X if (STANDOUT) putp(enter_standout_mode); X X fputs(so_buf, stdout); X X if (STANDOUT) putp(exit_standout_mode); X X if ((so_b & 2) && (!STANDOUT || !cookie_size)) putchar(SP); X X so_active = 0; X} X X X/*VARARGS*/ Xso_printxy(va_alist) Xva_dcl X{ X va_list ap; X int k, l; X X va_start(ap); X X k = va_arg1(int); X l = va_arg2(int); X X so_gotoxy(k, l, 0); X so_vprintf(va_args3toN); X so_end(); X X va_end(ap); X} X Xunderline(on) X{ X if (cookie_size) return 0; X if (! HAS_CAP(enter_underline_mode)) return 0; X putp(on ? enter_underline_mode : exit_underline_mode); X return 1; X} X Xhighlight(on) X{ X if (cookie_size) return 0; X if (! HAS_CAP(enter_standout_mode)) return 0; X putp(on ? enter_standout_mode : exit_standout_mode); X return 1; X} X Xstatic int is_raw = 0; X Xraw() X{ X if (is_raw) return; X X#ifdef HAVE_TERMIO X ioctl(0, TCSETAF, &raw_tty); X#else X ioctl(0, TIOCSETP, &raw_tty); X#endif X is_raw++; X} X Xno_raw() X{ X if (!is_raw) return 0; X X#ifdef HAVE_TERMIO X ioctl(0, TCSETAF, &norm_tty); X#else X ioctl(0, TIOCSETP, &norm_tty); X#endif X is_raw = 0; X X return 1; X} X Xflush_input() X{ X#ifdef HAVE_TERMIO X ioctl(0, TCFLSH, 0); X#else X ioctl(0, TIOCFLUSH, 0); X#endif X} X Xint enable_stop = 1; X X#ifndef KEY_BURST X Xstatic int alarm_on = 0; X Xstatic mk_timeout() X{ X alarm_on = 0; X} X X#endif X Xstatic int do_macro_processing = 1; X Xget_c() X{ X unsigned char c; X int any_multi, key_cnt, mc; X register struct multi_key *mk; X register int i; X#ifdef KEY_BURST X static char cbuf[KEY_BURST], *cp; X static int n = 0; X#else X int n; X unsigned char first_key; X#endif X X next_key: X if (s_hangup) X return K_interrupt; X X#ifdef RESIZING X if (s_resized) { X s_resized = 0; X return GETC_COMMAND | K_REDRAW; X } X#endif X X if (do_macro_processing) X switch (m_getc(&mc)) { X case 0: X break; X case 1: X return mc; X case 2: X return K_interrupt; X } X X for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++) X mk->cur_key = mk->keys; X key_cnt = 0; X X#ifdef KEY_BURST X if (n <= 0) { X n = read(0, cbuf, KEY_BURST); X if (n < 0 && errno != EINTR) s_hangup++; X if (n <= 0) return K_interrupt; X cp = cbuf; X } X X while (--n >= 0) { X c = *cp++; X#else X X while ((n = read(0, &c, 1)) > 0) { X c &= 0177; /* done by ISTRIP on USG systems */ X#endif X X if (c == CTRL('Q') || c == CTRL('S')) X continue; X X any_multi = 0; X for (i = multi_keys, mk = multi_key_list; --i >= 0; mk++) X if (mk->cur_key) { X if (*(mk->cur_key)++ == c) { X if (*(mk->cur_key) == NUL) { X c = mk->code; X goto got_char; X } X any_multi++; X } else X mk->cur_key = NULL; X } X X if (any_multi) { X#ifndef KEY_BURST X if (key_cnt == 0) { X first_key = c; X alarm_on = 1; X signal(SIGALRM, mk_timeout); X MICRO_ALARM(); X } X#endif X key_cnt++; X continue; X } X if (key_cnt == 0) X goto got_char; X X ding(); X flush_input(); X goto next_key; X } X X#ifndef KEY_BURST X if (n < 0) { X if (errno != EINTR) s_hangup++; X return K_interrupt; X } X#endif X X#ifdef RESIZING X if (s_resized) { X s_resized = 0; X return GETC_COMMAND | K_REDRAW; X } X#endif X X#ifndef KEY_BURST X if (n < 0 && key_cnt) X c = first_key; X#endif X Xgot_char: X X#ifndef KEY_BURST X if (alarm_on) { X alarm(0); X alarm_on = 0; X } X#endif X X c = global_key_map[c]; X X if (c == SuspC) { X if (!enable_stop) goto next_key; X if (suspend_nn()) X return GETC_COMMAND | K_REDRAW; X else X goto next_key; X } X X if (c == IntrC) c = K_interrupt; X X return c; X} X X X/* X * read string with completion, pre-filling, and break on first char X * X * dflt is a string that will be use as default value if the X * space bar is hit as the first character. X * X * prefill pre-fill the buffer with .... and print it X * X * break_chars return immediately if one of these characters X * is entered as the first character. X * X * completion is a function that will fill the buffer with a value X * see the group_completion and file_completion routines X * for examples. X */ X Xchar *get_s(dflt, prefill, break_chars, completion) Xchar *dflt, *prefill, *break_chars; Xint (*completion)(); X{ X static char buf[GET_S_BUFFER]; X register char *cp; X register int i, c, lastc; X char *ret_val = buf; X int comp_used, comp_len; X int ostop, max, did_help; X int hit_count; X X switch (m_gets(buf)) { X case 0: X break; X case 1: X return buf; X case 2: X return NULL; X } X X ostop = enable_stop; X enable_stop = 0; X do_macro_processing = 0; X hit_count = 0; X X max = Columns - prompt_length; X X if (max >= FILENAME) max = FILENAME-1; X X i = comp_len = comp_used = did_help = 0; X X if (prefill && prefill[0]) { X while (c = *prefill++) { X if (i == max) break; X X putchar(c); X buf[i] = c; X i++; X } X fl; X } X X if (dflt && *dflt == NUL) X dflt = NULL; X X if (break_chars && *break_chars == NUL) X break_chars = NULL; X X c = NUL; X for(;;) { X lastc = c; X c = get_c(); X if (c & (0200 | GETC_COMMAND)) continue; X X kill_prefill_hack: X X hit_count++; X X if (i == 0) { X if (c == comp1_key && dflt) { X while ((c = *dflt++) != NUL && i < max) { X putchar(c); X buf[i] = c; X i++; X } X fl; X dflt = NULL; X continue; X } X if (cp = break_chars) { X while (*cp) X if (*cp++ == c) { X buf[0] = c; X buf[1] = NUL; X goto out; X } X } X } X X if (completion != NO_COMPLETION) { X if (comp_used && c == erase_key) { X (*completion)(buf, -1); X if (did_help) { clrmsg(i); did_help = 0; } X if (comp_len) { X i -= comp_len; X while (--comp_len >= 0) putchar(BS); X clrline(); X } X comp_len = comp_used = 0; X if (lastc == help_key) goto no_completion; X continue; X } X X if (c == comp1_key || c == comp2_key || c == help_key) { X if (!comp_used || c == comp2_key || X (c == help_key && lastc != c)) { X buf[i] = NUL; NO_NEWS_IS_GOOD_NEWS echo "End of part 14" echo "File term.c is continued in part 15" echo "15" > s2_seq_.tmp exit 0 --- Kim F. Storm storm@texas.dk Tel +45 429 174 00 Texas Instruments, Marielundvej 46E, DK-2730 Herlev, Denmark No news is good news, but nn is better! -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.