home *** CD-ROM | disk | FTP | other *** search
- Subject: v19i075: NN, a Usenet news reader, Part14/15
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- 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!
-
-