Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (06/28/90)
Submitted-by: Matt Dillon <@uunet.uu.net:overload!dillon> Posting-number: Volume 90, Issue 184 Archive-name: unix/uucp-1.06d/part06 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 12)." # Contents: uucp2/src/anews/showart.c uucp2/src/dmail/commands.c # uucp2/src/dmail/sendmail.c uucp2/src/unix/dcron.c # uucp2/src/uucico/sysdep.c # Wrapped by tadguy@xanth on Thu Jun 28 08:21:27 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'uucp2/src/anews/showart.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/anews/showart.c'\" else echo shar: Extracting \"'uucp2/src/anews/showart.c'\" \(8978 characters\) sed "s/^X//" >'uucp2/src/anews/showart.c' <<'END_OF_FILE' X X/* X * SHOWART.C X */ X X#include "news.h" X#include <ctype.h> X X#define ON scr_inverse_on() X#define OFF scr_inverse_off() X#define Clear_Line printf("\r\x9bK") X#define Clear_Screen printf("\x9bH\x9bJ") X Xextern void scr_inverse_on(), scr_inverse_off(); Xextern void do_help(); Xextern char *get_next_art(); Xextern char *subs(); Xextern char *art2file(); X Xextern char *NewsDir; X Xstatic char *ArtHelp[] = { X "(space) Display next page of current article", X "(return) Display next line of current article (scroll)", X "(backspace) Restart current article", X "n/N Goto the next article", X "d/D Delete this article", X "u/U Undelete this article", X "- Backup to previous article", X "^ Goto the first article", X "(number) Goto the given article number", X "$ Goto next news group", X "r/R Reply -- send mail to the poster of current article", X "f/F Followup -- post a response to the current article", X "p/P Post -- post an article", X "= List article subjects for the remaining articles", X "./> Scan subject of next article, hit return to read it", X ",/< Backup one article, displaying its subject", X "s/S Write the current article to a file", X "w/W Write the current article to a file", X "h/H/? Display help", X "q Quit newsgroup (qq = quit program)", X "Q Quit newsgroup without deleting any articles", X 0 X}; X Xstatic char *suppressed[] = { X "Path", X "Message-ID", X "Message-Id", X "Lines", X "Xref", X "References", X "Nf-From", X "Nf-ID", X "In-reply-to", X "From ", X "Received", X 0 X}; X Xstatic int Xshowheader(register char *p) X{ X register char **pp; X X for (pp = suppressed; *pp != NULL; pp++) { X if (strcmp(*pp, p) == 0) X return (0); X } X return (1); X} X Xstatic int EndOfFile, LineCount, CharCount; Xstatic int LineMax, CharMax; Xstatic long LastLine; X Xstatic void XSetupPage(void) X{ X Clear_Screen; X LineCount = 1, CharCount = 1; X/* FIXME: determine size of page dynamically */ X LineMax = NumRows; X CharMax = NumCols; X raw(stdin); /* permit typeahead while displaying page */ X} X Xstatic int Xoutc(register int c) X{ X if (c == '\t') { X switch(CharCount%8) { X case 1: outc(' '); X case 2: outc(' '); X case 3: outc(' '); X case 4: outc(' '); X case 5: outc(' '); X case 6: outc(' '); X case 7: outc(' '); X case 0: outc(' '); X } X return 0; X } X if (c == '\f') { X LineCount = 999; X c = '\n'; X } X if (CharCount > CharMax) { X ++LineCount; X CharCount = 1; X if (c == '\n') X return (1); X } X putchar(c); X ++CharCount; X if (c == '\n') { X ++LineCount, CharCount = 1; X return (1); X } X return (0); X} X Xstatic void Xputline(register char *prefix, register FILE *fp) X{ X register int c; X X EndOfFile = 0; X X LastLine = ftell(fp); /* remember where this line started */ X X while (*prefix != '\0') { X if (outc(*prefix)) X return; X ++prefix; X } X while ((c = getc(fp)) != EOF) { X if (outc(c)) { X if (c == '\f') { X /* force page break after form feed */ X LastLine = ftell(fp); X } X if ((c = getc(fp)) == EOF) X break; X ungetc(c, fp); X return; X } X } X /* End-of-file */ X EndOfFile = 1; X mark_cur_art(1); X LineCount = 999; X} X Xstatic int XDisplayHdr(register FILE *fp) X{ X register char *p; X register int c, result = 0; X long here; X char buf[100]; X X for (;;) { X /* Evaluate one header line */ X here = ftell(fp); X p = buf; X X do { /* extract command portion */ X if ((c = getc(fp)) == EOF) X return result; X if (c == '\n') { X fseek(fp, here, 0); X return result; X } X *p++ = c; X if (c == ' ') { X ++p; X break; X } X } while (c != ':'); X *--p = '\0'; X X if ((c = getc(fp)) != ' ') /* ignore space after colon */ X ungetc(c, fp); X X /* check for special action on header line */ X if (strcmp(buf, "Subject") == 0) { X ON; X putline("", fp); X OFF; X } else if (strcmp(buf, "Control") == 0) { X ON; X putline("Control: ", fp); X OFF; X result = 1; X } else if (showheader(buf)) { X *p++ = ':'; X *p++ = ' '; X *p = '\0'; X putline(buf, fp); X } else { X /* ignore skipped header, including continuations */ X X do { X while ((c = getc(fp)) != '\n') { X if (c == EOF) X return result; X } X } while ((c = getc(fp)) == '\t' || c == ' '); X X if (c == EOF) X return result; X ungetc(c, fp); X } X X while ((c = getc(fp)) != EOF) { X if (c == '\n') { /* end of headers */ X ungetc(c, fp); X return result; X } X if (c != '\t' && c != ' ') X break; X X /* continuation lines */ X do { X outc(c); X if ((c = getc(fp)) == EOF) X return result; X } while (c != '\n'); X X outc(c); X } X ungetc(c, fp); X } X} X Xstatic void /* minimize swapping if copying on floppies */ Xcopyfile(register FILE *in, char *new) X{ X register char *bp; X register long size = 16*1024; X register FILE *out; X register long i; X int append = 0; X extern void *malloc(); X X if (!*new) X return; X if (access(new, 0) == 0) { X if ((out = fopen(new, "a")) == NULL) { X printf("could not open %s for append\n", new); X return; X } X append = 1; X } else if ((out = fopen(new, "w")) == NULL) { X printf("could not open %s for output\n", new); X return; X } X while ((bp = malloc(size)) == NULL) { X if ((size = size/2) < 1024) { X printf("NO MEMORY TO MAKE COPY!\n"); X fclose(out); X return; X } X } X rewind(in); X while ((i = fread(bp, sizeof(char), size, in)) > 0) X fwrite(bp, sizeof(char), i, out); X fclose(out); free(bp); X printf("Article %sed to %s\n", append ? "append" : "sav", new); X} X Xstatic void /* sends subject via outc() with format "%4s:%s\n" */ Xoutsub(char *s, char *t) X{ X register int i = 4 - strlen(s); X X while (i > 0) X outc(' '), --i; X while (*s != '\0') X outc(*s++); X outc(':'); X while (*t != '\0') X outc(*t++); X outc('\n'); X} X Xvoid XNextArtPage(char *article, char *group) X{ X SetupPage(); X ON; X printf("Article %s of %s (%d unread)", article, group, unread_count()); X OFF; X outc('\n'); X} X Xvoid Xscan_subjects(char *group) X{ X register char *ptr, *s; X register int ch; X X SetupPage(); X while (ptr = get_next_art()) { X if (LineCount >= LineMax) { X ON; X printf("(Hit any key to continue)"); X OFF; X ch = rawch(); X Clear_Line; X if (ch == 'q') X break; X SetupPage(); X } X if ((s = subs(art2file(group, ptr))) != NULL) X outsub(ptr, s); X else X outsub(ptr, "(((No Subject Line Found!!!)))"); X } X} X Xint Xshowart(char *group, char *article) X{ X register FILE *fp; X register int done, ch; X char newname[100]; X X if ((fp = fopen(art2file(group, article), "r")) == NULL) { X printf("Error opening article %s in group %s\n", article, group); X ON; X printf("(Hit any key to continue)"); X OFF; X rawch(); X Clear_Line; /* Erase the prompt */ X fflush(stdout); X return 'n'; X } X X /* display initial page with headers */ X DisplayArt: X X NextArtPage(article, group); X done = DisplayHdr(fp); X while (LineCount < LineMax) X putline("", fp); X X ch = 'd'; X while (done == 0) { X ON; X printf((EndOfFile) ? "===== End of article =====" : "--- More ---"); X OFF; X putchar(' '); X ch = rawch(); X X Clear_Line; /* Erase the prompt */ X fflush(stdout); X X switch (ch) { X case ' ': X if (EndOfFile) { X done = 1; X ch = 'd'; X break; X } X /* fall through to... */ X case '\t': X fseek(fp, LastLine, 0); X NextArtPage(article, group); X while (LineCount < LineMax) X putline("", fp); X break; X X case '\n': X case '\r': X putline("", fp); X break; X X case '\b': X rewind(fp); X goto DisplayArt; X X case 'f': X case 'F': X followup(ch, fp, group); X break; X X case 'r': X case 'R': X reply(ch, fp, group); X break; X X case 'p': X case 'P': X followup(ch, NULL, group); X break; X X case '?': X case 'h': X case 'H': X ON; X printf("%s [%s]?", group, article); X OFF; X do_help(ArtHelp); X break; X X case 'w': X case 'W': X case 's': X case 'S': X ON; X printf("Save article %s as ??", article); X OFF; X putchar(' '); X fflush(stdout); X gets(newname); X copyfile(fp, newname); X break; X X case '=': X scan_subjects(group); X break; X X case 'u': X case 'U': X del_cur_art(0); X break; X X /* move to another article */ X case '-': /* previous article */ X case '$': /* next news group */ X case '0': case '1': case '2': case '3': case '4': X case '5': case '6': case '7': case '8': case '9': X case '.': case '>': case ',': case '<': X hold_cur_art(); X /* fall through to... */ X /* these cases are handled by the group-level processing */ X case 'd': case 'D': /* delete article */ X case 'n': case 'N': /* to next article */ X case 'q': case 'Q': /* quit news */ X case '^': /* first article */ X done = 1; X /* fall through to... */ X default: X break; X } X } X X fclose(fp); X return (ch); X} X END_OF_FILE if test 8978 -ne `wc -c <'uucp2/src/anews/showart.c'`; then echo shar: \"'uucp2/src/anews/showart.c'\" unpacked with wrong size! fi # end of 'uucp2/src/anews/showart.c' fi if test -f 'uucp2/src/dmail/commands.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/dmail/commands.c'\" else echo shar: Extracting \"'uucp2/src/dmail/commands.c'\" \(10526 characters\) sed "s/^X//" >'uucp2/src/dmail/commands.c' <<'END_OF_FILE' X X/* X * COMMANDS.C X * X * $Header: Beta:src/uucp/src/dmail/RCS/commands.c,v 1.1 90/02/02 12:04:08 dillon Exp Locker: dillon $ X * X * (C) Copyright 1985-1990 by Matthew Dillon, All Rights Reserved. X * X * Global Routines: DO_QUIT() X * DO_EXIT() X * DO_CD() X * DO_ECHO() X * DO_GO() X * DO_SOURCE() X * DO_SHELL() X * DO_WRITE() X * DO_DELNEXT() X * DO_NUMBER() X * DO_NEXT() X * DO_HEADER() X * DO_TYPE() X * DO_DELETE() X * DO_UNDELETE() X * DO_MARK() X * DO_BREAK() X * X * Static Routines: None. X * X */ X X#include <stdio.h> X#include <sys/file.h> X#include "dmail.h" X X#define LAST_TYPE 0 X#define LAST_HEADER 1 X Xstatic int Last_operation; Xstatic int Last_deleted = -1; Xstatic char ScrBuf[1024]; X Xvoid Xdo_quit(garbage, com) Xchar *garbage; X{ X int fd, r, back; X char *str; X X push_break(); X if (get_inode (mail_file) == get_inode (output_file)) { X back = save_file (0, 0, ST_DELETED | ST_STORED); X } else { X r = write_file (output_file, O_CREAT, ST_READ, ST_DELETED | ST_STORED); X if (r < 0) { X printf ("Unable to write to %s\n", output_file); X back = save_file (0, 0, ST_DELETED | ST_STORED); X } else { X back = save_file (0, 0, ST_READ | ST_DELETED | ST_STORED); X } X } X if (back < 0) X printf ("Unable to update %s\n", mail_file); X if (back > 0) X printf ("%d kept in %s\n", back, mail_file); X sleep (1); X X /* X * update access time (UNIX, so shell does not report new mail) X */ X X if ((fd = open (mail_file, O_RDONLY, 0)) >= 0) { X read (fd, Buf, 1); X close (fd); X } X if (!com) X done (0); X free_entry(); X if (av[1] == 0) { X if (!Silence) X puts ("NO FROM FILE SPECIFIED"); X av[1] = mail_file; X av[2] = NULL; X } X Did_cd = 0; X mail_file = realloc (mail_file, strlen(av[1]) + 1); X strcpy (mail_file, av[1]); X str = (av[2]) ? av[2] : mail_file; X output_file = realloc (output_file, strlen(str) + 1); X strcpy (output_file, str); X initial_load_mail(); X m_select (Nulav, M_RESET); X pop_break(); X if (!Silence) X printf ("\nRF %-20s WF %-20s\n", mail_file, output_file); X} X Xvoid Xdo_exit(garbage, com) Xchar *garbage; X{ X char *str; X X if (!com) X done (0); X push_break(); X free_entry(); X if (av[1] == 0) { X if (!Silence) X puts ("NO FROM FILE SPECIFIED"); X av[1] = mail_file; X av[2] = NULL; X } X mail_file = realloc (mail_file, strlen(av[1]) + 1); X strcpy (mail_file, av[1]); X str = (av[2]) ? av[2] : mail_file; X output_file = realloc (output_file, strlen(str) + 1); X strcpy (output_file, str); X initial_load_mail(); X m_select (Nulav, M_RESET); X pop_break(); X if (!Silence) X printf ("\nRF %-20s WF %-20s\n", mail_file, output_file); X} X X Xdo_cd() X{ X char *dir = (ac < 2) ? home_dir : av[1]; X X if (chdir(dir) < 0) { X printf ("Cannot CD to %s\n", dir); X return (-1); X } X ++Did_cd; X return (1); X} X X Xdo_echo(str) Xchar *str; X{ X puts (next_word(str)); X fflush(stdout); X return (1); X} X X Xdo_go() X{ X int i; X X if (ac < 2) { X puts ("go to which article?"); X } X rewind_range (1); X i = get_range(); X if (i < 0) { X if (!Silence) X printf ("Message #%d does not exist\n", i); X return (-1); X } X if (i == 0) { X if (!Silence) X puts ("No Message"); X return (-1); X } X Current = indexof(i); X return (1); X} X X Xdo_source(scratch, overide) Xchar *scratch; X{ X char *comline = malloc(1024); X FILE *fi = NULL; X X if (ac < 2) { X puts ("No file argument to source"); X free(comline); X return (-1); X } X if (push_base()) { X push_break(); X pop_base(); X if (fi != NULL) X fclose (fi); X pop_break(); X free(comline); X return (-1); X } X push_break(); X fi = fopen (av[1], "r"); X pop_break(); X if (fi == NULL) { X if (!overide) X printf ("Cannot open %s\n", av[1]); X free(comline); X return (-1); X } X while (fgets (comline, 1024, fi) != NULL) { X comline[strlen(comline) - 1] = '\0'; X if (comline[0] != '#') X exec_command (comline); X } X push_break(); X fclose (fi); X fi = NULL; X free(comline); X pop_break(); X pop_base(); X return (1); X} X X Xdo_shell(str) Xchar *str; X{ X#ifdef UNIX X int pid, ret; X#endif X char *shell, *ptr; X char *args; X X#ifdef AMIGA X shell = ""; X#else X shell = getenv("SHELL"); X#endif X if (shell == NULL) X shell = "/bin/sh"; X ptr = shell + strlen(shell) - 1; X while (ptr > shell && *ptr && *ptr != '/') X --ptr; X args = (strcmp(ptr, "/sh"))? "-fc" : "-c"; X push_break(); X str = next_word (str); X#ifdef UNIX X if (strlen (str)) { X if ((pid = vfork()) == 0) { X execl (shell, shell, args, str, NULL); X _exit (1); X } X } else { X if ((pid = vfork()) == 0) { X execl (shell, shell, NULL); X _exit (1); X } X } X while ((ret = wait(0)) > 0) { X if (ret == pid) X break; X } X#endif X#ifdef AMIGA X Execute(str, NULL, NULL); X#endif X pop_break(); X return (1); X} X X Xdo_write() X{ X char *file; X int r, count = 0; X register int i, j; X X if (ac < 2) { X puts ("You must specify at least a file-name"); X return (-1); X } X file = av[1]; X rewind_range (2); X push_break(); X while (i = get_range()) { X j = indexof (i); X if (j >= 0 && !(Entry[j].status & ST_DELETED)) { X Entry[j].status |= ST_STORED | ST_SCR; X ++count; X } X } X r = write_file (file, O_CREAT, ST_SCR, 0); X rewind_range (2); X if (r > 0) { X while (i = get_range()) { X j = indexof (i); X if (j >= 0) X Entry[j].status &= ~ST_SCR; X } X if (!Silence) X printf ("%d Items written\n", count); X } else { X while (i = get_range()) { X j = indexof (i); X if (j >= 0) X Entry[j].status &= ~(ST_SCR | ST_STORED); X } X printf ("Could not write to file %s\n", file); X } X pop_break(); X return (1); X} X X/* X * DB, added 3 Oct 1988 X */ X Xdo_delprev() X{ X do_mark("", ST_DELETED); X if (Current) X return(do_next("", -1)); X return(-1); X} X Xdo_delnext() X{ X static int warning; X X if (!warning && Last_operation == LAST_HEADER) { X ++warning; X puts ("Note that the next command is displaying headers only at"); X puts ("this point. (one-time warning, NOTHING deleted"); X return (-1); X } X if (do_mark("", ST_DELETED) > 0) X return (do_next("", 1)); X return (-1); X} X X Xdo_number(str, com) Xchar *str; Xint com; X{ X int x; X X x = indexof (atoi(str)); X if (x < 0) { X puts ("Non existant message"); X return (-1); X } X Current = x; X switch (Last_operation) { X case LAST_TYPE: X return (do_type()); X case LAST_HEADER: X return (do_header()); X default: X puts ("Internal Error NEXT"); X return (-1); X } X} X X Xdo_next(str, com) Xchar *str; X{ X int ok; X X push_break(); X if (com > 0) { X if (++Current > Entries) X Current = Entries; X if (fix() < 0) { X puts ("End of file"); X pop_break(); X return (-1); X } X --com; X } X if (com < 0) { X ++com; X ok = 0; X while (--Current >= 0) { X if (Entry[Current].no && !(Entry[Current].status & ST_DELETED)) { X ok = 1; X break; X } X } X if (!ok) { X puts ("Start of file"); X Current = 0; X fix(); X pop_break(); X return (-1); X } X } X pop_break(); X if (!com) { X switch (Last_operation) { X case LAST_TYPE: X return (do_type()); X case LAST_HEADER: X return (do_header()); X } X } X return (1); X} X X Xdo_header() X{ X Last_operation = LAST_HEADER; X if (push_base()) { X push_break(); X pop_base(); X PAGER (-1); X rewind(m_fi); X fflush (stdout); X pop_break(); X return (-1); X } X if (single_position() < 0) X return (-1); X if (Current < 0) { X puts("Software error #commands.0"); X exit(1); X } X PAGER (0); X sprintf (Puf, "MESSAGE HEADER #%d (%d) %s\n", X Entry[Current].no, X Current + 1, X (Entry[Current].status & ST_DELETED) ? " DELETED" : ""); X PAGER (Puf); X sprintf (Puf, "From %s\n", Entry[Current].from); X PAGER (Puf); X while (fgets (ScrBuf, 1024, m_fi) != NULL) { X FPAGER (ScrBuf); X if (*ScrBuf == '\n') { X PAGER (-1); X pop_base(); X return (1); X } X } X PAGER ("END OF FILE ENCOUNTERED"); X PAGER (-1); X pop_base(); X return (-1); X} X Xdo_type() X{ X int i; X X Last_operation = LAST_TYPE; X if (push_base()) { X push_break(); X pop_base(); X PAGER (-1); X rewind(m_fi); X fflush (stdout); X pop_break(); X return (-1); X } X if (single_position() < 0) X return (-1); X if (Current < 0) { X puts("Software Error #commands.1"); X exit(1); X } X if (skip_to_data (m_fi) < 0) { X printf ("Cannot find data for message %d\n", Entry[Current].no); X return (-1); X } X PAGER (0); X sprintf (Puf, "MESSAGE TEXT #%d (%d) %s\n", X Entry[Current].no, X Current + 1, X (Entry[Current].status & ST_DELETED) ? " DELETED" : ""); X PAGER (Puf); X for (i = 0; i < Listsize; ++i) { X if (*Entry[Current].fields[header[i]]) { X sprintf (Puf, "%-10s %s", X Find[header[i]].search, X Entry[Current].fields[header[i]]); X PAGER (Puf); X } X } X PAGER (""); X while ((fgets (ScrBuf, 1024, m_fi) != NULL) && strncmp (ScrBuf, "From ", 5)) X FPAGER (ScrBuf); X Entry[Current].status |= ST_READ; X PAGER (-1); X pop_base(); X return (1); X} X X Xdo_mark(garbage, mask) Xchar *garbage; X{ X int count = 0; X register int i, j; X X rewind_range (1); X push_break(); X while (i = get_range()) { X j = indexof (i); X if (j >= 0) { X if (mask & ST_DELETED) X Last_deleted = j; X if ((Entry[j].status & mask) != mask) { X Entry[j].status |= mask; X if (Entry[j].status & ST_DELETED) X Entry[j].status &= ~(ST_STORED | ST_READ | ST_TAG); X ++count; X } X } X } X if (!Silence) X printf ("%d Items\n", count); X pop_break(); X return (1); X} X X Xdo_unmark(garbage, mask) Xchar *garbage; X{ X int count = 0; X register int i, j; X register struct ENTRY *en; X X push_break(); X if (ac == 1 && (mask & ST_DELETED) && Last_deleted != -1) { X en = &Entry[Last_deleted]; X if (en->no) { X en->status &= ~mask; X printf ("Undeleted last deleted message (# %d)\n", en->no); X Current = Last_deleted; X Last_deleted = -1; X } else { X puts ("Last deleted message not within current select bounds"); X pop_break(); X return (-1); X } X pop_break(); X return (1); X } X rewind_range (1); X while (i = get_range()) { X j = indexof (i); X if (j >= 0) { X if (Entry[j].status & mask) { X Entry[j].status &= ~mask; X ++count; X } X } X } X if (!Silence) X printf ("%d Items\n", count); X pop_break(); X return (1); X} X Xdo_break(garbage, mask) Xchar *garbage; X{ X if (mask) X pop_break(); X else X push_break(); X return (1); X} X Xvoid Xdo_ver() X{ X puts (DVERSION); X} X END_OF_FILE if test 10526 -ne `wc -c <'uucp2/src/dmail/commands.c'`; then echo shar: \"'uucp2/src/dmail/commands.c'\" unpacked with wrong size! fi # end of 'uucp2/src/dmail/commands.c' fi if test -f 'uucp2/src/dmail/sendmail.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/dmail/sendmail.c'\" else echo shar: Extracting \"'uucp2/src/dmail/sendmail.c'\" \(9101 characters\) sed "s/^X//" >'uucp2/src/dmail/sendmail.c' <<'END_OF_FILE' X X/* X * SENDMAIL.C X * X * $Header: Beta:src/uucp/src/dmail/RCS/sendmail.c,v 1.1 90/02/02 12:04:06 dillon Exp Locker: dillon $ X * X * (C) Copyright 1985-1990 by Matthew Dillon, All Rights Reserved. X * X * Global Routines: DO_REPLY() X * DO_MAIL() X * X * Static Routines: WORD_SIZE() X * FOPEN_SCRATCH() X * FREOPEN_SCRATCH() X * FCLOSE_SCRATCH() X * FTERMINATE_SCRATCH() X * DELETE_SCRATCH() X * RUN_VI() X * SEND_MAIL() X * X * X */ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/file.h> X#ifdef UNIX X#include <sys/ioctl.h> X#endif X#include <sys/time.h> X#include <signal.h> X#include "dmail.h" X#include "config.h" X XFILE *fi; Xchar file[64]; X Xvoid fclose_scratch(); Xvoid fopen_scratch(); Xvoid copy_header(); Xvoid send_mail(); X Xdo_reply(garbage, itext) Xchar *garbage; X{ X int i, j; X int anyargs = 0; X int len; X char *ptr; X static char buf[1024]; X char *istr; X X if (!(istr = get_var(LEVEL_SET, "_headchar"))) X istr = ">"; X if (push_base()) { X push_break(); X pop_base(); X fclose_scratch(); X puts ("ABORTED, no mail sent"); X unlink(file); X pop_break(); X return (-1); X } X fopen_scratch(); X strcpy (buf, "To: "); X for (i = 1; i < ac; ++i) { X if (*av[i] >= '0' && *av[i] <= '9') { X if ((j = indexof(atoi(av[i]))) < 0) { X puts ("No such message"); X fclose_scratch(); X unlink(file); X pop_break(); X return (-1); X } X Current = j; X } else { X if (anyargs) X strcat (buf, ", "); X anyargs = 1; X strcat (buf, av[i]); X } X } X len = strlen(buf); X switch (itext) { X case R_FORWARD: X strcat (buf, "\n"); X fputs (buf, fi); X fputs ("Subject: \n", fi); X break; X case R_INCLUDE: X case R_REPLY: X if (anyargs) { X strcat (buf, ", "); X len = strlen(buf); X } X buf[len] = 0; X if (Current >= 0) { X char *rf = get_var(LEVEL_SET, "replyfields"); X if (rf == NULL) X rf = ""; X while (*rf) { /* attempt to find the fields listed */ X char *re; X char *ptr; X char c; X for (re = rf; *re && *re != ' ' && *re != 9; ++re); X c = *re; X *re = 0; X ptr = get_field(rf); X if (*ptr) { X *re = c; X sprintf (buf + len, "%s\n", ptr); X break; X } X *re = c; X while (*re == ' ' || *re == 9) X ++re; X rf = re; X } X if (*rf == 0) { X sprintf (buf + len, "%.*s\n", X word_size(Entry[Current].from), Entry[Current].from); X } X } X fputs (buf, fi); X X fputs ("Cc: ", fi); X ptr = get_field ("Cc:"); X if (*ptr) X fputs (ptr, fi); X X fputs ("\nSubject: Re: ", fi); X fputs (get_field ("Subject:"), fi); X fputs ("\n", fi); X break; X case R_MAIL: X fputs (buf, fi); X fputs ("\n", fi); X fputs ("Cc: \n", fi); X fputs ("Bcc: \n", fi); X fputs ("Subject: \n", fi); X break; X default: X puts ("INTERNAL STUPID MAIL ERROR: REPLY"); X break; X } X fputs ("\n\n", fi); X if (itext == R_FORWARD || itext == R_INCLUDE) { X position_current(); X if (itext == R_FORWARD) { X if (Current >= 0) X fprintf (fi, "ORIGINALLY From %s\n", Entry[Current].from); X } else { X skip_to_data (m_fi); X } X while ((fgets (Buf, MAXFIELDSIZE, m_fi) != NULL) && !isfrom(Buf)) { X if (itext == R_INCLUDE) X fputs(istr, fi); X fputs (Buf, fi); X } X fputs ("\n", fi); X } X copy_header (fi); X fclose_scratch(); X if (itext != R_MAIL) { X push_break(); X if (Current >= 0) { X Entry[Current].status |= ST_SCR; X write_file("t:Original", O_CREAT | O_TRUNC, ST_SCR, 0); X Entry[Current].status &= ~ST_SCR; X } X pop_break(); X } X j = -1; Xloop: X ++j; X if (run_vi() || j) { X push_break(); X switch (do_ask()) { X case 1: X puts ("SENDING.. wait"); X send_mail(); X { X FILE *li = fopen(file, "r"); X char buf[128], *ptr = NULL; X X if (li) { X while (fgets(buf, 128, li) && buf[0] != '\n') { X if (strncmp(buf, "Farchive:", 9) == 0) { X buf[strlen(buf)-1] = '\0'; X for (ptr = buf + 9; *ptr == ' '; ++ptr); X if (ptr[0] == '$') X ptr = get_var(LEVEL_SET, ptr+1); X break; X } X } X fclose(li); X } X archive_mail(ptr); X } X unlink(file); X break; X case 2: X pop_break(); X goto loop; X default: X unlink (file); X break; X } X pop_base(); X pop_break(); X } else { X puts ("File not modified or ABORTED, no mail sent"); X unlink(file); X pop_base(); X } X unlink ("T:Original"); X} X Xdo_ask() X{ X char in[256]; X X if (!S_ask) X return (1); X fputs ("\n(Send, Vi, Quit) ?", stdout); X fflush(stdout); X gets (in); X switch (in[0]) { X case 's': X case 'S': X return (1); X case 'q': X case 'Q': X puts ("ABORT, no mail sent"); X return (3); X case 'v': X case 'V': X default: X return (2); X } X} X X X Xstatic void Xcopy_header(fi) XFILE *fi; X{ X FILE *fs; X char *ptr; X char *tmp = NULL; X X if (ptr = get_var (LEVEL_SET, "header")) { X push_break(); X fs = fopen(ptr, "r"); X if (fs == NULL) { /* check uulib: */ X tmp = malloc(strlen(ptr) + strlen(MakeConfigPath(UULIB, "")) + 1); X sprintf(tmp, "%s%s", MakeConfigPath(UULIB, ""), ptr); X fs = fopen(tmp, "r"); X } X if (fs) { X while (fgets (Buf, MAXFIELDSIZE, fs) != NULL) X fputs (Buf, fi); X fclose (fs); X } else { X printf ("Cannot open header file %d %s\n", strlen(ptr), ptr); X perror ("fopen"); X } X if (tmp) X free(tmp); X pop_break(); X } X} X X Xstatic void Xfopen_scratch() X{ X static int c; X int fd; X X sprintf(file, "t:dmt%d%d", getpid(), c++); X fd = open(file, O_RDWR|O_CREAT|O_TRUNC, 0700); X if (fd < 0) { X perror ("Dmail, cannot open scratch file"); X done (1); X } X#ifdef AMIGA /* fix bug in Lattice C fdopen */ X fi = fopen("nil:", "w"); X fclose(fi); X#endif X fi = fdopen(fd, "w+"); X} X Xstatic void Xfclose_scratch() X{ X if (fi != NULL) { X fflush (fi); X fclose (fi); X fi = NULL; X } X} X X Xstatic Xword_size(str) Xregister char *str; X{ X register int size = 0; X X while (*str) { X if (*str == ' ') X return (size); X ++str; X ++size; X } X return (size); X} X X Xstatic Xrun_vi() X{ X#ifdef UNIX X char buf[64]; X int ret, pid = 0; X#endif X struct stat stat1, stat2; X char *argv[3]; X X argv[0] = visual; X argv[1] = file; X argv[2] = NULL; X if (push_base()) { X push_break(); X pop_base(); X#ifdef UNIX X if (pid) { X kill (pid, SIGKILL); X sprintf (buf, "t:Ex%d", pid); unlink (buf); X sprintf (buf, "t:Rx%d", pid); unlink (buf); X wait(0); X system ("clear; reset ; clear"); X pid = 0; X } X#endif X pop_break(); X return (0); X } X stat1.st_mtime = stat2.st_mtime = stat1.st_ctime = stat2.st_ctime = 0; X stat (file, &stat1); X if (S_novibreak) X push_break(); X X#ifdef UNIX X pid = vfork(); X if (!pid) { X execv (visual, argv); X printf ("Cannot exec visual: %s\n", visual); X _exit (1); X } X while ((ret = wait(0)) > 0) { X if (ret == pid) X break; X } X#endif X#ifdef AMIGA X { X short i; X static char buf[128]; X X strcpy(buf, argv[0]); X for (i = 1; argv[i]; ++i) { X strcat(buf, " "); X strcat(buf, argv[i]); X } X Execute(buf, NULL, NULL); X } X#endif X if (S_novibreak) X pop_break(); X stat (file, &stat2); X pop_base(); X return (!(stat1.st_mtime==stat2.st_mtime)); X} X X X#ifdef UNIX X Xstatic void Xsend_mail() X{ X int fd, stdin_fd; X char *argv[6]; X X push_break(); X argv[0] = S_sendmail; X argv[1] = "-t"; X argv[2] = "-oem"; X argv[3] = "-i"; X if (S_verbose) { X argv[4] = "-v"; X argv[5] = NULL; X } else { X argv[4] = NULL; X } X X fd = open (file, O_RDONLY, 0); X if (fd < 0) { X perror ("Dmail, Cannot open scratch file"); X done (1); X } X lseek(fd, 0L, 0); X X stdin_fd = dup (0); X dup2 (fd, 0); /* STDIN = message file */ X close(fd); /* don't need message file anymore */ X if (!fork()) { X int fd = open("/dev/tty", O_RDWR, 0); X if (fd >= 0) { X ioctl(fd, TIOCNOTTY, 0); X close(fd); X freopen("/dev/null", "w", stdout); X freopen("/dev/null", "w", stderr); X } X execv (S_sendmail, argv); X printf ("Unable to exec sendmail: %s\n", S_sendmail); X _exit (1); X } X dup2 (stdin_fd, 0); /* restore STDIN */ X close(stdin_fd); X if (S_verbose) { X puts ("Waiting for sendmail..."); X wait (0); X puts ("Sendmail done"); X } X pop_break(); X} X X#endif X#ifdef AMIGA X Xstatic void Xsend_mail() X{ X static char Buf[256]; X X push_break(); X sprintf(Buf, "%s < %s%s -f %s", S_sendmail, file, (S_verbose ? " -v" : ""), user_name); X X printf("Sending\n", Buf); X if (Execute(Buf, NULL, NULL) == 0) X printf("Unable to run: %s\n", Buf); X X pop_break(); X} X X#endif X X X X X Xstatic Xarchive_mail(ptr) Xchar *ptr; X{ X FILE *ifi, *ofi; X long tim = time(NULL); X X if (!ptr) X ptr = get_var(LEVEL_SET, "archive"); X if (ptr == NULL || *ptr == '\0') X return(-1); X ifi = fopen(file, "r"); X if (ifi == NULL) { X puts ("Cannot open scratch file"); X return(-1); X } X ofi = fopen(ptr, "a"); X if (ofi == NULL) { X puts ("Cannot open archive file"); X fclose(ifi); X return(-1); X } X sprintf (Buf, "\nFrom %s (ARCHIVE)\n", user_name); X fputs (Buf, ofi); X sprintf (Buf, "Date: %s", ctime(&tim)); X fputs (Buf, ofi); X while (fgets (Buf, MAXFIELDSIZE, ifi)) X fputs (Buf, ofi); X fclose(ofi); X fclose(ifi); X return (1); X} X X END_OF_FILE if test 9101 -ne `wc -c <'uucp2/src/dmail/sendmail.c'`; then echo shar: \"'uucp2/src/dmail/sendmail.c'\" unpacked with wrong size! fi # end of 'uucp2/src/dmail/sendmail.c' fi if test -f 'uucp2/src/unix/dcron.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/unix/dcron.c'\" else echo shar: Extracting \"'uucp2/src/unix/dcron.c'\" \(10992 characters\) sed "s/^X//" >'uucp2/src/unix/dcron.c' <<'END_OF_FILE' X X/* X * DCRON.C V2 X * X * - loads s:crontab or file crontab specified by -f X * - checks the datestamp on s:crontab every 60 seconds and reloads the file X * into memory if changed. X * - every 60 seconds scans the memory-resident image for things to do X * - checks for date changes and doesn't reexecute if changes are X * backwards in time. X * X * DCRON [-d] [-f crontab] logfile X */ X X#include <exec/types.h> X#include <devices/timer.h> X#include <libraries/dos.h> X#include <libraries/dosextens.h> X#include <stdio.h> X#include "protos.h" X Xtypedef struct Node NODE; Xtypedef struct List LIST; Xtypedef struct DateStamp DATESTAMP; Xtypedef struct timerequest IOT; Xtypedef struct MsgPort PORT; Xtypedef struct Process PROC; Xtypedef struct FileInfoBlock FIB; X X X#define CRONTAB "s:crontab" X#define SIGS (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F) X Xtypedef struct { X short min; X short hour; X short day; X short month; X short dow; X} DateAry; X Xtypedef struct { X NODE Node; X UBYTE BitMap[8][8]; /* min, hour, day, month, dow */ X char *Command; X} Command; X Xextern char *malloc(); X XDATESTAMP LastDate; /* Date as of last execution */ XDATESTAMP ModDate; /* Check if system time modified */ XDATESTAMP TabDate; /* Check if crontab modified */ X XLIST CmdList; /* list of commands */ X XIOT Iot; XPORT *TPort; /* Collector plate for IO requests */ Xshort FatalError; /* Uh oh, can't recover */ Xchar *LogFile; Xchar *CronFile = CRONTAB; Xchar XDebug; Xlong NilFH; /* NIL: file handle */ Xshort CronFileExists = 0; /* -1, 0, 1 */ X Xvoid logmessage(); Xvoid LoadCronFile(); Xvoid LoadBitMap(); Xvoid WriteStr(); Xvoid RunCommand(); Xvoid ExecuteCommands(); Xvoid CheckFileModified(); Xvoid DateToDateAry(); Xvoid *GetHead(); Xvoid *GetSucc(); X Xint Xbrk() X{ X return(0); X} X Xvoid Xmain(ac, av) Xshort ac; Xchar *av[]; X{ X PROC *proc = (PROC *)FindTask(NULL); X APTR oldConsoleTask = proc->pr_ConsoleTask; X X onbreak(brk); X NewList(&CmdList); X { X register short i; X X for (i = 1; i < ac; ++i) { X register char *ptr = av[i]; X if (*ptr != '-') { X LogFile = ptr; X continue; X } X while (*++ptr) { X switch(*ptr) { X case 'd': X ++XDebug; X break; X case 'f': X CronFile = av[++i]; X break; X default: X WriteStr(Output(), "bad option\n"); X goto fail; X } X } X } X if (CronFile == NULL) { X puts("-f : expected filename"); X exit(1); X } X } X if (!LogFile) { Xfail: X WriteStr(Output(), "DCron [-d] [-f cronfile] Logfile\n"); X WriteStr(Output(), "DCron, V2.02\n"); X exit(1); X } X if (OpenDevice("timer.device", 0, &Iot, UNIT_VBLANK)) { X logmessage("Unable to open timer.device\n"); X exit(1); X } X if (!DeviceProc("NULL:")) { X logmessage("NULL: device required for dcron to run\n"); X WriteStr(Output(), "NULL: device required to run\n"); X exit(1); X } X proc->pr_ConsoleTask = (APTR)DeviceProc("NULL:"); X fclose(stderr); X X logmessage("Startup: V2.02 (dist: 29 May 1990)\n"); X X NilFH = (long)Open("null:", 1006); X DateStamp(&LastDate); X DateStamp(&ModDate); X TPort = CreatePort(NULL,0); X Iot.tr_time.tv_secs = 2; X Iot.tr_time.tv_micro= 0; X Iot.tr_node.io_Message.mn_ReplyPort = TPort; X Iot.tr_node.io_Command = TR_ADDREQUEST; X SendIO(&Iot); /* timeout */ X X for (;;) { X long mask; X mask = Wait(SIGS | (1 << TPort->mp_SigBit)); X if (mask & (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) { X logmessage("DCRON: Break\n"); X break; X } X if (mask & (SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)) { X logmessage("^E/F force check\n"); X AbortIO(&Iot); /* force execution */ X } X if (FatalError) X break; X if (CheckIO(&Iot)) { /* if file/date modified, force exec. */ X DATESTAMP Ds; X DateAry D1, D2; X int st; X X WaitIO(&Iot); X st = CheckDateChanged(); X CheckFileModified(); X DateStamp(&Ds); X DateToDateAry(&LastDate, &D1); X DateToDateAry(&Ds, &D2); X if (st == 0) X ExecuteCommands(&D1, &D2); X LastDate = Ds; X DateStamp(&Ds); X Iot.tr_time.tv_secs = 61 - Ds.ds_Tick / 50; X Iot.tr_time.tv_micro= 0; X SendIO(&Iot); X } X } X AbortIO(&Iot); X WaitIO(&Iot); X CloseDevice(&Iot); X DeletePort(TPort); X Close(NilFH); X proc->pr_ConsoleTask = oldConsoleTask; X} X X/* X * Returns 0 = execute objects for range X * 1 = do not execute objects for range X */ X XCheckDateChanged() X{ X DATESTAMP Ds; X long xold, xnew; X static char state = 0; X X DateStamp(&Ds); X xold = ModDate.ds_Days * 1440 + ModDate.ds_Minute; X xnew = Ds.ds_Days * 1440 + Ds.ds_Minute; X X /* X * if backwards or more than T+5min X */ X X if (xnew < xold || xnew - 5 > xold) { X DateStamp(&LastDate); X if (state == 0) X logmessage("Date change noted, %d mins\n", xnew - xold + 1); X state = 1; X } else { X state = 0; X } X X /* X * If all is ok or too far away from old date then set new base X * date for next comparison (T +/- 10min) X */ X X if (state == 0 || xold - xnew > 10 || xold - xnew < -10 ) { X ModDate = Ds; X } X return((int)state); X} X Xvoid XCheckFileModified() X{ X char buf[sizeof(FIB)+4]; X long lock; X X if (lock = (long)Lock(CronFile, SHARED_LOCK)) { X register FIB *fib = (FIB *)(((long)buf+3)&~3); X if (Examine(lock, fib)) { X if (CronFileExists < 1 || X fib->fib_Date.ds_Tick != TabDate.ds_Tick || X fib->fib_Date.ds_Minute != TabDate.ds_Minute || X fib->fib_Date.ds_Days != TabDate.ds_Days) X { X if (TabDate.ds_Days) { X logmessage("crontab modification noted\n"); X } X TabDate = fib->fib_Date; X LoadCronFile(); X } X } X UnLock(lock); X } else { X if (CronFileExists >= 0) { X logmessage("unable to lock cronfile %s!\n", CronFile); X CronFileExists = -1; X } X } X} X X/* X * execute commands that fall d1 < cmd <= d2 X */ X Xvoid XExecuteCommands(d1, d2) Xshort *d1, *d2; /* min, hour, day, month, dow */ X{ X Command *cmd; X short i; X short n; X X for (cmd = GetHead(&CmdList); cmd; cmd = GetSucc(&cmd->Node)) { X short ok = 1; X for (i = 0; i < 5; ++i) { X UBYTE *bitmap = cmd->BitMap[i]; X X n = d2[i]; X if (n == d1[i]) { X if ((bitmap[n>>3] & (1 << (n & 7))) == 0) { X ok = 0; X break; X } X } else { X while (n != d1[i]) { X if (bitmap[n>>3] & (1 << (n & 7))) X break; X n = (n - 1) & 63; X } X if (n == d1[i]) { X ok = 0; X break; X } X } X } X if (ok) X RunCommand(cmd->Command); X } X} X Xvoid XRunCommand(cmd) Xchar *cmd; X{ X char buf[256]; X X logmessage("%s\n", cmd); X strcpy(buf, "run "); X strcat(buf, cmd); X Execute(buf, NilFH, NilFH); X} X Xvoid XDateToDateAry(date, da) XDATESTAMP *date; XDateAry *da; X{ X static char dim[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; X long days; X long years; X char leap; X short month; X X days = date->ds_Days + 731; /* 1976 */ X years = days / (365*3+366); /* #quad yrs */ X days -= years * (365*3+366); X leap = (days <= 365); /* is a leap yr*/ X years = 1976 + 4 * years; X dim[1] = 29; X if (leap == 0) { X dim[1] = 28; X days -= 366; X ++years; X years += days / 365; X days %= 365; X } X for (month = 0; (month==1) ? (days >= 28 + leap) : (days >= dim[month]); ++month) X days -= (month==1) ? (28 + leap) : dim[month]; X X da->min = date->ds_Minute % 60; X da->hour = date->ds_Minute / 60; X da->day = days + 1; X da->month = month + 1; X da->dow = date->ds_Days % 7; /* 0 = sunday */ X} X Xvoid XLoadCronFile() X{ X char buf[256]; X long fh; X Command *cmd; X X while (cmd = (Command *)RemHead(&CmdList)) X free(cmd); X X ReadLn(NULL, NULL, 0); X fh = (long)Open(CronFile, 1005); X if (fh == NULL) { X if (CronFileExists != -1) X logmessage("unable to open cronfile %s!\n", CronFile); X CronFileExists = -1; X return; X } X while (ReadLn(fh, buf, 256)) { X char *ptr = buf; X short i; X X if (buf[0] == 0 || buf[0] == '#') X continue; X cmd = (Command *)malloc(sizeof(Command)); X setmem(cmd, sizeof(Command), 0); X X for (i = 0; i < 5; ++i) { /* 5 time fields */ X /* X printf("lb %d\n", i); X */ X LoadBitMap(&ptr, cmd->BitMap[i]); X } X X while (*ptr == ' ' || *ptr == 9) X ++ptr; X cmd->Command = malloc(strlen(ptr) + 1); X strcpy(cmd->Command, ptr); X X /* X for (i = 0; i < 5; ++i) { X for (j = 0; j < 4; ++j) X printf("%02x", cmd->BitMap[i][j]); X printf(" "); X for (j = 4; j < 8; ++j) X printf("%02x", cmd->BitMap[i][j]); X puts(""); X } X X printf("cmd = %s\n", cmd->Command); X */ X X AddTail(&CmdList, &cmd->Node); X } X Close(fh); X CronFileExists = 1; X} X Xvoid XLoadBitMap(pptr, bm) Xchar **pptr; XUBYTE *bm; /* 8 bytes = 64 entries */ X{ X register char *ptr = *pptr; X X while (*ptr == ' ' || *ptr == 9) X ++ptr; X X /* X * looking for *, number range n-n, single numbers, etc... 1,2,8-10 ... X */ X X while (*ptr == '*' || (*ptr >= '0' && *ptr <= '9')) { X short v1, v2; X X v1 = 0; X while (*ptr >= '0' && *ptr <= '9') { X v1 = v1 * 10 + *ptr - '0'; X ++ptr; X } X if (*ptr == '-') { X ++ptr; X v2 = 0; X while (*ptr >= '0' && *ptr <= '9') { X v2 = v2 * 10 + *ptr - '0'; X ++ptr; X } X } else { X v2 = v1; X } X if (*ptr == '*') { X v1 = 0; X v2 = 63; X ++ptr; X } X if (v1 < 0) X v1 = 0; X if (v1 > 63) X v1 = 63; X if (v2 < 0) X v2 = 0; X if (v2 > 63) X v2 = 63; X X --v1; X do { X v1 = (v1 + 1) & 63; X bm[v1>>3] |= (1 << (v1 & 7)); X } while (v1 != v2); X if (*ptr == ',') X ++ptr; X } X *pptr = ptr; X} X X/* X * Poor man's log. Note that the log file is not left open ... this allows X * one to read or tail it at any time. X */ X Xvoid Xlogmessage(ptr, a, b, c, d, e) Xchar *ptr; X{ X char *buf = malloc(512); X DATESTAMP date; X DateAry da; X long fh; X static char *Dow[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; X static char *Miy[] = { "---", "Jan", "Feb", "Mar", "Apr", "May", "Jun", X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; X X if (!buf) X return; X X DateStamp(&date); X DateToDateAry(&date, &da); X X sprintf(buf, "dcron: %s %2ld %s %02ld:%02ld ", X Dow[da.dow], da.day, Miy[da.month], da.hour, da.min X ); X sprintf(buf+strlen(buf), ptr, a, b, c, d, e); X if ((fh = (long)Open(LogFile, 1005)) == NULL) X fh = (long)Open(LogFile, 1006); X if (fh) { X Seek(fh, 0L, 1); X WriteStr(fh, buf); X Close(fh); X } X free(buf); X} X Xvoid XWriteStr(fh, buf) Xlong fh; Xchar *buf; X{ X Write(fh, buf, strlen(buf)); X} X XReadLn(fh, buf, max) Xlong fh; Xchar *buf; Xshort max; X{ X static char Data[1024]; X static short RIdx, RLen; X register short i; X X if (fh == NULL) { X RIdx = RLen = 0; X return(0); X } X for (--max, i = 0; i < max; ++i) { X if (RIdx == RLen) { X RLen = Read(fh, Data, 1024); X RIdx = 0; X if (RLen <= 0) { X buf[i] = 0; X return(0); X } X } X if ((buf[i] = Data[RIdx++]) == '\n') X break; X } X buf[i] = 0; X return(1); X} X END_OF_FILE if test 10992 -ne `wc -c <'uucp2/src/unix/dcron.c'`; then echo shar: \"'uucp2/src/unix/dcron.c'\" unpacked with wrong size! fi # end of 'uucp2/src/unix/dcron.c' fi if test -f 'uucp2/src/uucico/sysdep.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'uucp2/src/uucico/sysdep.c'\" else echo shar: Extracting \"'uucp2/src/uucico/sysdep.c'\" \(11990 characters\) sed "s/^X//" >'uucp2/src/uucico/sysdep.c' <<'END_OF_FILE' X X/* X * SYSDEP.C X * X * $Header: Beta:src/uucp/src/uucico/RCS/sysdep.c,v 1.1 90/02/02 11:56:16 dillon Exp Locker: dillon $ X * X * (C) Copyright 1987 by John Gilmore X * Copying and use of this program are controlled by the terms of the Free X * Software Foundation's GNU Emacs General Public License. X * X * Amiga Changes Copyright 1988 by William Loftus. All rights reserved. X * Additional chgs Copyright 1989 by Matthew Dillon, All Rights Reserved. X */ X X#include "includes.h" X#include <hardware/cia.h> X#include <libraries/dos.h> X#include <pwd.h> X#include "uucp.h" X#include "version.h" X XPrototype int openout(char *, int); XPrototype int sigint(void); XPrototype void cleanup(void); XPrototype int xdatardy(void); XPrototype int xgetc(int); XPrototype int xwrite(const void *, int); XPrototype int xwritea(const void *, int); XPrototype int xxwrite(const void *, int, int); XPrototype void SendBreak(void); XPrototype int CheckCarrier(void); XPrototype void *bzero(void *, long); XPrototype void *bcopy(const void *, void *, long); XPrototype void munge_filename(char *, char *); XPrototype int hangup(void); XPrototype char *work_scan(char *); XPrototype char *work_next(void); XPrototype void amiga_closeopen(char *); XPrototype void amiga_setup(void); XPrototype void set_baud(int); XPrototype void OpenSerial(void); XPrototype void CloseSerial(void); XPrototype void xexit(int); XPrototype void printc(unsigned char); X XIDENT(".03"); X X/* X * Split out of uuslave.c by John Gilmore, 8 August 1987. X * ported to the Amiga by William Loftus, 20 September 1987. X * rewritten by Matthew Dillon, October 1989 X */ X X/* FIXME -- System dependent defines (not really -- should be in a .h) */ X/* X * Timeout for raw characters -- if we don't hear a char within BYTE_TIMEOUT X * seconds, we assume the other side has gone away. Has nothing to do with X * retransmission timeouts (if any!). X */ X Xextern int debug; Xextern int SevenWire; X X#define FAILURE 1 X Xstruct IOExtSer Iosr; Xstruct IOExtSer Iosw; Xstruct IOExtSer Ioss; Xstruct timerequest Iot0; Xchar *OldTaskName; X Xchar *DeviceName = "serial.device"; Xlong DeviceUnit = 0; X Xunsigned char XInBuf[256]; /* for xgetc() */ Xshort XInIdx = 0; Xshort XInLen = 0; Xshort IoswIP = 0; X Xshort InExitRoutine = 0; Xshort debugRead = 0; X Xextern char path[]; Xextern int Getty; Xextern int IgnoreCD; X Xint Xopenout(acu, baud) Xchar *acu; Xint baud; X{ X set_baud(baud); X X return SUCCESS; X} X X/* X * Basement level I/O routines X * X * xwrite() writes a character string to the serial port X * xgetc() returns a character from the serial port, or an EOF for timeout. X * sigint() restores the state of the serial port on exit. X */ X Xint Xsigint() X{ X xexit(1); X return(0); X} X X Xvoid Xcleanup() X{ X xexit(0); X} X Xint Xxdatardy() X{ X if (XInIdx != XInLen) X return(1); X CheckCarrier(); X return (Ioss.IOSer.io_Actual > 0); X} X Xint Xxgetc(byteto) Xint byteto; X{ X int ch, n; X long smask; X long tmask; X short bytetimeout; X Xtop: X if (XInIdx != XInLen) { X if (debug > 8) { X if (debugRead == 0) X printf("\nREAD: "); X debugRead = 1; X printc(XInBuf[XInIdx]); X } X return((int)XInBuf[XInIdx++]); X } X XInIdx = 0; X XInLen = 0; X X if (!CheckCarrier()) /* carrier lost? */ X return(EOF); X X if ((n = Ioss.IOSer.io_Actual) > 0) { /* at least one.. */ X Iosr.IOSer.io_Command = CMD_READ; X Iosr.IOSer.io_Data = (APTR)XInBuf; X if (n > sizeof(XInBuf)) X n = sizeof(XInBuf); X Iosr.IOSer.io_Length = n; X DoIO(&Iosr); X if (Iosr.IOSer.io_Actual > 0) { X if (debug > 8) X printf("(r%d/%d)", n, Iosr.IOSer.io_Actual); X XInIdx = 0; X XInLen = Iosr.IOSer.io_Actual; X goto top; X } X } X X /* X * no bytes ready, byteto is 0 (no wait) X */ X X if (byteto == 0) X return(EOF); X X /* X * no bytes ready, wait for one. X * X * once every 3 seconds check carrier detect. X */ X X bytetimeout = byteto; X Iot0.tr_time.tv_secs = 3; X Iot0.tr_time.tv_micro= 0; X SendIO(&Iot0); X X Iosr.IOSer.io_Command = CMD_READ; X Iosr.IOSer.io_Data = (APTR)XInBuf; X Iosr.IOSer.io_Length = 1; X Iosr.IOSer.io_Actual = 0; /* trying to find a bug... */ X SendIO(&Iosr); X X smask = 1L << Iosr.IOSer.io_Message.mn_ReplyPort->mp_SigBit; X tmask = 1L << Iot0.tr_node.io_Message.mn_ReplyPort->mp_SigBit; X X for (;;) { X long mask = Wait(tmask | smask | SIGBREAKF_CTRL_C); X X if (mask & SIGBREAKF_CTRL_C) { X AbortIO(&Iosr); X WaitIO(&Iosr); X AbortIO(&Iot0); X WaitIO(&Iot0); X xexit(1); X } X if (CheckIO(&Iosr)) { X WaitIO(&Iosr); X AbortIO(&Iot0); X WaitIO(&Iot0); X X ch = (int)XInBuf[0]; X X if (debug > 8) { X if (debugRead == 0) X printf("\nREAD "); X debugRead = 1; X printf("(waitc%d)", Iosr.IOSer.io_Actual); X printc((unsigned char)ch); X } X return(ch); X } X if (CheckIO(&Iot0)) { X WaitIO(&Iot0); X X Iot0.tr_time.tv_secs = 3; X Iot0.tr_time.tv_micro= 0; X X bytetimeout -= Iot0.tr_time.tv_secs; X if (bytetimeout > 0) { X if (CheckCarrier() == 0) { X AbortIO(&Iosr); X WaitIO(&Iosr); X break; X } X SendIO(&Iot0); X } else { X AbortIO(&Iosr); X WaitIO(&Iosr); X if (Iosr.IOSer.io_Actual == 1) X return((int)XInBuf[0]); X break; X } X } X } X if (debug > 8) X printf("\nRecv-EOF\n"); X return(EOF); X} X Xint Xxwrite(buf, ctr) Xconst void *buf; Xint ctr; X{ X return(xxwrite(buf, ctr, 0)); X} X Xint Xxwritea(buf, ctr) Xconst void *buf; Xint ctr; X{ X xxwrite(buf, ctr, 1); X return(ctr); X} X Xint Xxxwrite(buf, ctr, async) Xconst void *buf; Xint ctr; Xint async; X{ X if (debug > 8) { X short i; X if (debugRead) X printf("\nWRITE "); X debugRead = 0; X for (i = 0; i < ctr; ++i) { X printc(((unsigned char *)buf)[i]); X } X printf("\n"); X } X if (IoswIP) { X WaitIO(&Iosw); X IoswIP = 0; X } X X Iosw.IOSer.io_Command = CMD_WRITE; X Iosw.IOSer.io_Length = ctr; X Iosw.IOSer.io_Data = (APTR)buf; X if (async) { X SendIO(&Iosw); X IoswIP = 1; X } else { X DoIO(&Iosw); X } X return ctr; X} X Xvoid XSendBreak() X{ X Ioss.IOSer.io_Command = SDCMD_BREAK; X DoIO(&Ioss); X} X Xint XCheckCarrier() X{ X Ioss.IOSer.io_Command = SDCMD_QUERY; X DoIO(&Ioss); X if (IgnoreCD) X return(1); X if (Ioss.io_Status & CIAF_COMCD) /* non-zero == no carrier */ X return(0); X return(1); X} X Xvoid * Xbzero(s, cnt) Xvoid *s; Xlong cnt; X{ X setmem(s, cnt, 0); X return(s); X} X Xvoid * Xbcopy(from, to, cnt) Xconst void *from; Xvoid *to; Xlong cnt; X{ X movmem(from, to, cnt); X return(to); X} X X/* X * Transform a filename from a uucp packet (in Unix format) into a local X * filename that will work in the local file system. X */ X Xvoid Xmunge_filename(s, d) Xchar *s, *d; X{ X if (*s != '~') { X if (s != d) X strcpy(d, s); X return; X } X X /* X * ~/ ... convert to UUPUB: X * ~user/... convert to <homedir>/... X */ X X { X short i; X short c; X char *t; X struct passwd *pw; X X for (i = 1; s[i] && s[i] != '/'; ++i); X c = s[i]; X X s[i] = 0; X if (i == 1) X pw = NULL; X else X pw = getpwnam(s + 1); X s[i] = c; X X if (c == '/') X ++i; X X if (pw) { X t = malloc(strlen(pw->pw_dir) + strlen(s + i) + 1); X strcpy(t, pw->pw_dir); X } else { X t = malloc(strlen(s + i) + 32); X strcpy(t, GetConfigDir(UUPUB)); X } X strcat(t, s + i); X strcpy(d, t); X free(t); X } X} X Xint Xhangup() X{ X static char buf[128]; X X reset_modem(); X X sprintf(buf, "run >nil: <nil: %s", GetConfigProgram(UUXQT)); X X if (Execute(buf, NULL, NULL) == 0) X puts("Unable to run UUXQT"); X return SUCCESS; X} X Xstatic char names[MAXFILES*16]; Xstatic char *pointers[MAXFILES]; Xstatic int file_pointer; X Xchar * Xwork_scan(system_name) Xchar *system_name; X{ X static char name[128]; X int count; X X file_pointer = 0; X X if (strlen(system_name) > 7) { X system_name[7] = '\0'; X } X X sprintf(name, "%sC.%s#?", MakeConfigPath(UUSPOOL, ""), system_name); X X if (debug > 2) X printf("Looking for %s\n",name); X X count = getfnl(name,names,sizeof(names),0); X X if (count > 0) { X if (strbpl(pointers,MAXFILES,names) != count) { X printf("Too many command files for %s.\n",system_name); X return (char *)NULL; X } X } else { X return (char *)NULL; X } X if (debug > 2) X printf("Found -> %s\n", pointers[file_pointer]); X return (char *)1; X} X Xchar * Xwork_next() X{ X if (debug > 2) X printf("Found -> %s\n", pointers[file_pointer]); X return pointers[file_pointer++]; X} X X/* X * Closing and openning the serial device drops DTR X */ X Xvoid Xamiga_closeopen(str) Xchar *str; X{ X CloseSerial(); X Delay(60); X OpenSerial(); X} X Xvoid Xamiga_setup() X{ X mountrequest(0); /* disallow requesters */ X X OpenSerial(); X X if (OpenDevice(TIMERNAME, UNIT_VBLANK, &Iot0, 0)) { X Iot0.tr_node.io_Device = NULL; X printf("Can't open timer device."); X xexit(1); X } X X Iot0.tr_node.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("UUCICO-Timer", 0L); X Iot0.tr_node.io_Command = TR_ADDREQUEST; X Iot0.tr_node.io_Error = 0; X X { X struct Task *task = (struct Task *)FindTask(NULL); X OldTaskName = task->tc_Node.ln_Name; X task->tc_Node.ln_Name = "uucico"; X } X} X Xvoid Xset_baud(baud) Xint baud; X{ X Iosr.IOSer.io_Command = SDCMD_SETPARAMS; X Iosr.io_SerFlags = SERF_SHARED | SERF_XDISABLED; X Iosr.io_Baud = baud; X Iosr.io_ReadLen = 8L; X Iosr.io_WriteLen = 8L; X Iosr.io_CtlChar = 0x11130000L; X Iosr.io_RBufLen = 4096; X X if (SevenWire) X Iosr.io_SerFlags |= SERF_7WIRE; X X DoIO(&Iosr); X} X Xvoid XOpenSerial() X{ X Iosr.io_SerFlags = SERF_SHARED | SERF_XDISABLED; X Iosr.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Read_RS",0); X X if (SevenWire) X Iosr.io_SerFlags |= SERF_7WIRE; X X if (OpenDevice(DeviceName, DeviceUnit, &Iosr, NULL)) { X Iosr.IOSer.io_Device = NULL; X printf("Can not open serial port for read.\n"); X xexit(TRUE); X } X X /* X * Assume a Getty is running, if the opencount is > 2 then X * assume collision and disallow X */ X X if (Iosr.IOSer.io_Device->dd_Library.lib_OpenCnt > 2) { X CloseDevice(&Iosr); X Iosr.IOSer.io_Device = NULL; X printf("Collision, serial port in use!\n"); X xexit(TRUE); X } X X /* X * The public port 'Lock-<spname>-<unit>' is used to lock the X * serial port (Getty will lock it this way while it is X * receiving an incomming call so if we are Getty assume it X * is already locked) X */ X X if (Getty == 0) X LockSerialPort(DeviceName, DeviceUnit); X X Iosw = Iosr; X Iosw.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Write_RS", 0); X Ioss = Iosw; X X Iosr.IOSer.io_Command = SDCMD_QUERY; X DoIO(&Iosr); X X set_baud(Iosr.io_Baud); X} X Xvoid XCloseSerial() X{ X if (IoswIP) { X WaitIO(&Iosw); X IoswIP = 0; X } X if (Iosr.IOSer.io_Device) { X CloseDevice(&Iosr); X Iosr.IOSer.io_Device = NULL; X if (Getty == 0) X UnLockSerialPort(DeviceName, DeviceUnit); X } X if (Iosr.IOSer.io_Message.mn_ReplyPort) { X DeletePort(Iosr.IOSer.io_Message.mn_ReplyPort); X Iosr.IOSer.io_Message.mn_ReplyPort = NULL; X } X if (Iosw.IOSer.io_Message.mn_ReplyPort) { X DeletePort(Iosw.IOSer.io_Message.mn_ReplyPort); X Iosw.IOSer.io_Message.mn_ReplyPort = NULL; X } X} X Xvoid Xxexit(code) Xint code; X{ X ++InExitRoutine; X X if (InExitRoutine == 1 && code && Iosr.IOSer.io_Device && CheckCarrier()) X reset_modem(); X X CloseSerial(); X X { X struct Task *task = (struct Task *)FindTask(NULL); X if (OldTaskName) X task->tc_Node.ln_Name = OldTaskName; X } X X if (Iot0.tr_node.io_Device) { X CloseDevice(&Iot0); X Iot0.tr_node.io_Device = NULL; X } X if (Iot0.tr_node.io_Message.mn_ReplyPort) { X DeletePort(Iot0.tr_node.io_Message.mn_ReplyPort); X Iot0.tr_node.io_Message.mn_ReplyPort = NULL; X } X chdir(path); X if (code) X printf("\nAbnormal Termination.\n"); X X mountrequest(1); X X UnLockFiles(); /* unlock any hanging locks */ X X exit(code); X} X Xvoid Xprintc(c) Xunsigned char c; X{ X c &= 0x7F; X X if (c < 32) X printf("^%c", c | 0x40); X else if (c == 32) X printf("_"); X else if (c < 128) X printf("%c", c); X else X printf("(%02x)", c); X} X END_OF_FILE if test 11990 -ne `wc -c <'uucp2/src/uucico/sysdep.c'`; then echo shar: \"'uucp2/src/uucico/sysdep.c'\" unpacked with wrong size! fi # end of 'uucp2/src/uucico/sysdep.c' fi echo shar: End of archive 6 \(of 12\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@cs.odu.edu>. Mail comments to the moderator at <amiga-request@cs.odu.edu>. Post requests for sources, and general discussion to comp.sys.amiga.