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 185
Archive-name: unix/uucp-1.06d/part07
#!/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 7 (of 12)."
# Contents: uucp2/src/dmail/execom.c uucp2/src/dmail/load_mail.c
# uucp2/src/uuser/uuser.c
# Wrapped by tadguy@xanth on Thu Jun 28 08:21:29 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'uucp2/src/dmail/execom.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'uucp2/src/dmail/execom.c'\"
else
echo shar: Extracting \"'uucp2/src/dmail/execom.c'\" \(12837 characters\)
sed "s/^X//" >'uucp2/src/dmail/execom.c' <<'END_OF_FILE'
X
X/*
X * EXECOM.C
X *
X * $Header: Beta:src/uucp/src/dmail/RCS/execom.c,v 1.1 90/02/02 12:03:41 dillon Exp Locker: dillon $
X *
X * (C) Copyright 1985-1990 by Matthew Dillon, All Rights Reserved.
X *
X * Routines to parse and execute command lines.
X *
X * Global Routines: DO_COMMAND()
X * EXEC_COMMAND()
X * FIX()
X *
X * Static Routines: E_COMMAND()
X * BREAKOUT()
X * FIND_COMMAND()
X */
X
X
X#include <pwd.h>
X#include <stdio.h>
X#include <string.h>
X#include "dmail.h"
X#include "execom.h"
X
X#define F_EXACT 0
X#define F_ABBR 1
X#define SCRBUF 1024
X
Xextern char *breakout();
X
Xextern int do_quit(), do_exit(), do_help(), do_list(), do_setlist();
Xextern int do_select(), do_type(), do_header(), do_next(), do_mark();
Xextern int do_unmark(), do_reply(), do_delnext(), do_rlist();
Xextern int do_write(), do_shell(), do_set_var(), do_unset_var();
Xextern int do_number(), do_cd(), do_source(), do_defer(), do_echo();
Xextern int do_go(), do_break();
X
Xextern int do_if(), do_else(), do_endif();
Xextern int do_ver(), do_delprev();
X
Xstruct COMMAND Command[] = {
X do_number , 0, 0, "",
X do_mark , 0, ST_DELETED, "delete",
X do_unmark , 0, ST_DELETED, "undelete",
X do_header , 0, 0, "header",
X do_type , 0, 0, "type",
X do_echo , 0, 0, "echo",
X do_go , 0, 0, "go",
X do_reply , 0, R_REPLY, "reply",
X do_reply , 0, R_INCLUDE, "Reply",
X do_reply , 0, R_MAIL, "mail",
X do_reply , 0, R_FORWARD, "forward",
X do_select , 0, 0, "select",
X do_select , 0, 1, "reselect",
X do_defer , 0, 1, "defer",
X do_list , 0, 0, "list",
X do_rlist , 0, 0, "rlist",
X do_next , 0, 1, "next",
X do_next , 0, -1, "back",
X do_next , 0, 2, "_next",
X do_next , 0, -2, "_back",
X do_delnext , 0, 0, "dt",
X do_delprev , 0, 0, "db",
X do_set_var , 0, 0, "set",
X do_unset_var, 0, 0, "unset",
X do_set_var , 0, 1, "alias",
X do_unset_var, 0, 1, "unalias",
X do_set_var , C_NO, 2, "malias",
X do_unset_var, C_NO, 2, "munalias",
X do_setlist , 0, 0, "setlist",
X do_cd , 0, 0, "cd",
X do_source , 0, 0, "source",
X do_unmark , 0, ST_READ | ST_STORED,"preserve",
X do_mark , 0, ST_READ, "mark",
X do_mark , 0, ST_TAG, "tag",
X do_unmark , 0, ST_TAG, "untag",
X do_unmark , 0, ST_STORED, "unwrite",
X do_write , 0, 0, "write",
X do_shell , 0, 0, "!",
X do_exit , 0, 0, "x",
X do_quit , 0, 0, "quit",
X do_exit , 0, 1, "xswitch",
X do_quit , 0, 1, "qswitch",
X do_help , 0, 0, "help",
X do_help , 0, 0, "?",
X do_break , 0, 0, "nobreak",
X do_break , 0, 1, "breakok",
X do_if , C_COND, 0, "if",
X do_else , C_COND, 0, "else",
X do_endif , C_COND, 0, "endif",
X do_ver , 0, 0, "version",
X NULL , 0, 0, NULL };
X
Xchar *Desc[] = {
X "",
X "<list> mark messages for deletion",
X "<list> UNDELETE & UNMARK messages",
X "[msg] Display header of a message",
X "[msg] type a message",
X "args.... Echo to the screen",
X "# Go to a message, don't print out",
X " reply to mail",
X " reply to mail, include recv'd text",
X "user user ... send mail to users",
X "user user ... forward mail to users",
X "Field [!]match [match][ , Field match.] SELECT from entire message list",
X "Field [!]match [match][ , Field match.] SELECT from current message list",
X " De-select any read messages",
X "<list> list mail as specified by SETLIST",
X "[+/-][N] list relative to current position",
X "[msg] type/header next or message #",
X "[msg] type/header previous or message #",
X "[msg] go to next or message #",
X "[msg] go to previous or message #",
X " delete current, type next",
X " delete current, type prev",
X "[var [string]] set a variable",
X "var var var ... unset a variable",
X "[var [string]] set an alias",
X "var var var ... unset an alias",
X "[var [string]] set a mail alias",
X "var var var ... unset a mail alias",
X "[-s] [cols] Field [cols] Field... SET LIST format for LIST",
X "path CD to a directory",
X "file Source a file",
X "<list> UNREAD & UNMARK messages",
X "<list> mark messages as 'read'",
X "<list> tag messages for whatever",
X "<list> untag messages",
X "<list> unwrite messages",
X "file <list> append messages to a file, delete on quit",
X "[command] execute a shell [command]",
X " EXIT, do not save changes",
X " QUIT, update files",
X "from to Exit and switch to a new from/to file",
X "from to Quit and switch to a new from/to file",
X "[topic] help on a topic",
X "[topic] alternate form of HELP",
X " Disable INTR (stackable)",
X " Enable INTR (stackable)",
X "[!]variable conditionals (stackable)",
X "",
X "",
X " Print the version number",
X NULL };
X
X
Xdo_command()
X{
X static char comline[1024];
X
X if (Current >= 0 && Current < Entries)
X printf("%3d:", Entry[Current].no);
X else
X printf("nul:");
X fflush (stdout);
X if (gets (comline) == NULL)
X done (1);
X exec_command(comline);
X return (1);
X}
X
X
X
X/*
X * EXEC_COMMAND()
X *
X *
X */
X
X
Xstruct MLIST {
X struct MLIST *next;
X};
X
Xstatic struct MLIST *Mlist;
X
Xchar *
Xmpush(amount)
Xint amount;
X{
X struct MLIST *ml;
X
X push_break();
X ml = (struct MLIST *)malloc (amount + sizeof(*Mlist));
X ml->next = Mlist;
X Mlist = ml;
X pop_break();
X return ((char *)Mlist + sizeof(*Mlist));
X}
X
X
Xchar *
Xmpop()
X{
X char *old = NULL;
X
X push_break();
X if (Mlist == NULL) {
X puts ("MLIST INTERNAL ERROR");
X } else {
X old = (char *)Mlist + sizeof(*Mlist);
X xfree (Mlist);
X Mlist = Mlist->next;
X }
X pop_break();
X return (old);
X}
X
Xvoid
Xmrm()
X{
X push_break();
X while (Mlist) {
X xfree (Mlist);
X Mlist = Mlist->next;
X }
X pop_break();
X}
X
X
Xexec_command(base)
Xchar *base;
X{
X char *str;
X int i;
X
X if (push_base()) {
X push_break();
X pop_base();
X mrm();
X pop_break();
X return (-1);
X }
X strcpy (str = mpush(strlen(base) + 1), base);
X i = e_command(str);
X if (mpop() != str)
X puts ("POP ERROR");
X pop_base();
X return (i);
X}
X
X
Xstatic
Xe_command(base)
Xchar *base;
X{
X char *com, *start, *avline, *alias;
X int flag = 0;
X int i, pcount, len, ccno;
X
Xloop:
X com = breakout (&base, &flag);
X if (*com == '\0') {
X if (flag > 1)
X return (1);
X goto loop;
X }
X if ((ccno = find_command(com, F_EXACT)) < 0) {
X if (*com == '$')
X alias = get_var (LEVEL_SET, com + 1);
X else
X alias = get_var (LEVEL_ALIAS, com);
X if (alias == NULL) {
X if ((ccno = find_command (com, F_ABBR)) < 0) {
X if (!XDisable)
X printf ("%s Command Not found\n", com);
X return (XDisable ? 1 : -1);
X } else {
X goto good_command;
X }
X }
X
X /* At this point, base points to arguments */
X
X start = (flag == 0) ? base : "";
X while (flag == 0) { /* find ';' or end of string */
X flag = -1; /* disable breakout's "" terminator */
X breakout (&base, &flag);
X }
X
X /*
X * At this point, start points to all arguments, base set up for next
X * string
X */
X
X if (*alias == '%') {
X int xx = 0;
X char *select;
X
X alias = strcpy (mpush (strlen(alias) + 1), alias);
X select = breakout (&alias, &xx);
X set_var (LEVEL_SET, select + 1, start);
X i = e_command (alias);
X unset_var (LEVEL_SET, select + 1);
X mpop();
X } else {
X com = mpush (strlen(alias) + strlen(start) + 2);
X strcpy (com, alias);
X strcat (com, (flag == 1) ? ";" : " ");
X strcat (com, start);
X i = e_command (com);
X if (mpop() != com)
X puts ("ME BAE ERROR");
X }
X if (i < 0)
X return (-1);
X if (flag > 1)
X return (1);
X goto loop;
X }
Xgood_command:
X if (XDisable && (Command[ccno].stat & C_COND) == 0) {
X while (flag < 1)
X breakout (&base, &flag);
X if (flag > 1)
X return (1);
X goto loop;
X }
X if (Command[ccno].stat & C_NO && XDebug == 0) {
X printf ("%s Is currently being developed\n", Command[ccno].name);
X return (-1);
X }
X if (XDebug)
X printf ("Good command, Raw: %s\n", com);
X i = pcount = 0;
X av[i] = mpush (strlen(com) + 1);
X ++pcount;
X strcpy (av[i++], com);
X while (flag < 1) {
X com = breakout (&base, &flag);
X if (XDebug)
X printf ("BREAKOUT %d %s\n", strlen(com), com);
X if (*com == '\0')
X continue;
X switch (*com) {
X case '~':
X if (com[1] == '/' || com[1] == '\0') {
X av[i] = mpush (strlen(home_dir) + strlen(com + 1) + 1);
X ++pcount;
X strcpy (av[i], home_dir);
X strcat (av[i], com + 1);
X } else {
X struct passwd *passwd;
X char *user = com;
X
X while (*com) {
X if (*com == '/') {
X *com = '\0';
X ++com;
X break;
X }
X ++com;
X }
X if ((passwd = getpwnam(user)) == NULL) {
X printf ("USER %s Not found\n", user);
X while (pcount--)
X mpop();
X return (-1);
X }
X av[i] = mpush (strlen(passwd->pw_dir) + strlen(com) + 2);
X ++pcount;
X strcpy (av[i], passwd->pw_dir);
X if (*com) {
X strcat (av[i], "/");
X strcat (av[i], com);
X }
X }
X break;
X case '\"':
X av[i] = com + 1;
X while (*++com && *com != '\"');
X *com = '\0';
X break;
X case '$':
X if (*(com + 1) == '$') {
X av[i] = getenv(com + 2);
X if (av[i] == NULL) {
X printf ("Env. Var %s not found\n", com + 2);
X av[i] = com;
X }
X#ifdef AMIGA
X av[i] = strcpy (mpush(strlen(av[i]) + 1), av[i]);
X ++pcount;
X#endif
X } else {
X av[i] = get_var (LEVEL_SET, com + 1);
X if (av[i] == NULL)
X av[i] = com;
X av[i] = strcpy (mpush(strlen(av[i]) + 1), av[i]);
X ++pcount;
X }
X break;
X default:
X av[i] = com;
X break;
X }
X ++i;
X }
X av[i] = NULL;
X ac = i;
X for (len = 0, i = 0; i < ac; ++i)
X len += strlen (av[i]) + 1;
X avline = mpush (len + 1);
X *avline = '\0';
X for (i = 0; i < ac; ++i) {
X strcat (avline, av[i]);
X if (i + 1 < ac)
X strcat (avline, " ");
X }
X if (XDebug)
X printf ("DEST: %s\n", avline);
X i = (*Command[ccno].func)(avline, Command[ccno].val);
X if (mpop() != avline)
X puts ("AVLINE ERROR");
X while (pcount--)
X mpop();
X fix();
X if (i < 0)
X return (i);
X if (flag < 2)
X goto loop;
X return (1);
X}
X
X
X/*
X * BREAKOUT
X *
X * Breakout next argument. If FLAG is set to 1 on return, the argument
X * returned is the last in the command. If FLAG is set to 2 on return, the
X * argument returned is the last, period.
X *
X */
X
Xstatic char *
Xbreakout(base, flag)
Xint *flag;
Xchar **base;
X{
X register char *str, *scr;
X
Xloop:
X str = *base; /* next start */
X while (*str == ' ' || *str == 9) /* skip spaces and such */
X ++str;
X switch (*str) {
X case '\0': /* no more arguments */
X *flag = 2;
X *base = str;
X return (str);
X case ';': /* no more args in this command */
X *flag = 1;
X *str = '\0';
X *base = str + 1;
X return (str);
X }
X scr = str;
X for (;;) { /* valid argument of somesort */
X switch (*scr) {
X case ' ':
X case 9:
X if (*flag >= 0)
X *scr = '\0';
X *base = scr + 1;
X *flag = 0;
X return (str);
X case '\"':
X ++scr;
X while (*scr && (*scr++ != '\"')); /* place to end of quote */
X break;
X case '\0':
X *flag = 2;
X *base = scr;
X return (str);
X case ';':
X *flag = 1;
X *base = scr + 1;
X *scr = '\0';
X return (str);
X default:
X ++scr;
X }
X }
X}
X
X
X
Xfix()
X{
X register int i;
X
X for (i = (Current < 0) ? 0 : Current; i < Entries; ++i) {
X if (Entry[i].no && !(Entry[i].status & ST_DELETED)) {
X Current = i;
X return (1);
X }
X }
X if (Current >= Entries) {
X Current = Entries - 1;
X /* Can become -1 if no entries */
X }
X for (i = Current; i >= 0; --i) {
X if (Entry[i].no && !(Entry[i].status & ST_DELETED)) {
X Current = i;
X return (-1);
X }
X }
X Current = -1;
X return (-1);
X}
X
X
Xstatic
Xfind_command(str, arg)
Xchar *str;
Xint arg;
X{
X int i;
X int len = strlen (str);
X
X if (*str >= '0' && *str <= '9')
X return (0);
X for (i = 0; Command[i].func; ++i) {
X if (strncmp (str, Command[i].name, len) == 0) {
X if (arg == F_ABBR)
X return (i);
X if (strcmp (str, Command[i].name) == 0)
X return (i);
X return (-1);
X }
X }
X return (-1);
X}
X
END_OF_FILE
if test 12837 -ne `wc -c <'uucp2/src/dmail/execom.c'`; then
echo shar: \"'uucp2/src/dmail/execom.c'\" unpacked with wrong size!
fi
# end of 'uucp2/src/dmail/execom.c'
fi
if test -f 'uucp2/src/dmail/load_mail.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'uucp2/src/dmail/load_mail.c'\"
else
echo shar: Extracting \"'uucp2/src/dmail/load_mail.c'\" \(13945 characters\)
sed "s/^X//" >'uucp2/src/dmail/load_mail.c' <<'END_OF_FILE'
X
X/*
X * LOAD_MAIL.C
X *
X * $Header: Beta:src/uucp/src/dmail/RCS/load_mail.c,v 1.1 90/02/02 12:03:35 dillon Exp Locker: dillon $
X *
X * (C) Copyright 1985-1990 by Matthew Dillon, All Rights Reserved.
X *
X * file-io routines to scan the mail file and load required information.
X *
X *
X * Global Routines: HOLD_LOAD() hold on loading mail after change
X * NOHOLD_LOAD() hold off.. load if changes
X * LOAD_CHANGES() reload mail if changed
X * LOAD_MAIL() load/reload mail
X * SAVE_FILE() save mail items back to spool
X * CHECK_NEW_MAIL() check for new mail
X * WRITE_FILE() append mail items to a file
X * GET_EXTRA_OVR() ret index of Field (create if not)
X * ADD_EXTRA() add another field (reloads mail)
X * DELETE_EXTRA() delete a field
X * GET_EXTRA() ret index of Field, or error
X * M_SELECT() select on current message list
X *
X *
X * Static Routines: LOAD_HASH() load hash table from fields list
X * FREE_ENTRY() unload EVERYTHING
X * FREE_TABLE() unload all Fields table
X * LOAD_FILE() raw file loading/counting
X *
X *
X */
X
X#include <stdio.h>
X#include <sys/file.h>
X#include "dmail.h"
X
Xvoid do_flock();
Xvoid free_table();
Xvoid load_hash();
X
X#define NOHOLD 0
X#define HOLD 1
X
X#define NO_BASE 0
X#define NO_FIELDS 1
X#define ENTRY_OK 2
X
Xstruct FIND Find[MAXTYPE + 1] = {
X "From:" , 5, 1, 0,
X "To:" , 3, 1, 0,
X "Subject:", 8, 1, 0 };
X
Xstatic int File_size;
Xstatic int changed, load_hold;
Xstatic int Hash[256];
X
Xstatic char *quo_quo = "";
X
Xvoid
Xhold_load()
X{
X load_hold = 1;
X}
X
Xvoid
Xnohold_load()
X{
X void load_changes();
X load_hold = 0;
X load_changes();
X}
X
Xvoid
Xload_changes()
X{
X if (changed && !load_hold)
X load_mail(Entries, 1);
X}
X
Xinitial_load_mail()
X{
X if (load_mail (0, 0) < 0)
X return (-1);
X return ((Entries) ? 1 : -1);
X}
X
X
Xstatic
Xload_mail(at, from0)
X{
X FILE *fi;
X int i, count, file_size;
X
X if (No_load_mail)
X return (-1);
X push_break();
X load_hash();
X if (from0)
X free_table (0, HOLD);
X else
X free_table (at, NOHOLD);
X fi = fopen (mail_file, "r+");
X if (m_fi != NULL)
X fclose (m_fi);
X m_fi = fopen (mail_file, "r+");
X if (fi == NULL || m_fi == NULL) {
X pop_break();
X return (-1);
X }
X do_flock (fileno(m_fi), LOCK_EX);
X if (at)
X fseek (fi, Entry[at].fpos, 0);
X else
X fseek (fi, 0, 0);
X count = Entries;
X while (search_from(fi))
X ++count;
X if (Entries != count) {
X if (!lmessage_overide)
X printf ("%d Other Items loaded\n", count - Entries);
X lmessage_overide = 0;
X Entry = (struct ENTRY *)realloc (Entry, sizeof(*Entry) * (count + 1));
X bzero (&Entry[Entries], sizeof(*Entry) * (count + 1 - Entries));
X }
X Entries = count;
X for (i = at; i < Entries; ++i) {
X Entry[i].no = 0;
X Entry[i].status = 0;
X }
X Entry[i].fpos = File_size = file_size = ftell (fi);
X fclose (fi);
X load_file ((from0) ? 0 : at);
X if (file_size != File_size) { /* Last entry incomplete? */
X free_table (Entries - 1, NOHOLD);
X }
X changed = 0;
X if (SelAll)
X m_select (Nulav, 0);
X flock (fileno(m_fi), LOCK_UN);
X pop_break();
X return (1);
X}
X
Xvoid
Xdo_flock(fd, stat)
X{
X if (flock(fd, stat | LOCK_NB) < 0) {
X puts ("File in use, Waiting for lock");
X flock (fd, stat);
X puts ("Have lock");
X }
X}
X
Xstatic
Xload_file(at)
Xint at;
X{
X FILE *fi;
X char *next, *ptr;
X int i, bit, maxbit, len, count, havefrom;
X
X maxbit = 0;
X for (i = 0; Find[i].search != NULL; ++i)
X maxbit = (maxbit << 1) | 1;
X fi = fopen (mail_file, "r");
X count = -1;
X havefrom = 0;
X while (havefrom || search_from (fi)) {
X havefrom = 0;
X if (++count >= Entries)
X break;
X len = strlen(Buf) - 1;
X Buf[len] = '\0';
X next = next_word(Buf);
X len -= next - Buf;
X Entry[count].fpos = ftell (fi);
X Entry[count].from = malloc (len + 1);
X bcopy (next, Entry[count].from, len + 1);
X
X /* SEARCH FIELD LIST */
X
X bit = 0;
X if (XDebug)
X printf ("No %d ---------------------\n", count + 1);
X while (fgets (Buf, MAXFIELDSIZE, fi) != NULL) {
X if (Buf[0] == '\n')
X break;
X if (isfrom(Buf)) {
X havefrom = 1;
X break;
X }
X len = strlen(Buf) - 1;
X Buf[len] = '\0';
X if (XDebug)
X printf ("CHECK: %s\n", Buf);
X next = next_word(Buf);
X len -= next - Buf;
X if (Hash[*Buf] == 0)
X continue;
X if (Hash[*Buf] > 0) {
X i = Hash[*Buf] & 0xff;
X if (strncmp (Find[i].search, Buf, Find[i].len) == 0)
X goto found;
X continue;
X }
X for (i = -Hash[*Buf] & 0xff; Find[i].search; ++i) {
X if (*Find[i].search != *Buf)
X break;
X if (strncmp (Find[i].search, Buf, Find[i].len) == 0)
X goto found;
X }
X continue;
Xfound:
X if (XDebug)
X printf ("Found: %d %s\n", i, Buf);
X if (Find[i].notnew == 0) {
X Find[i].notnew = 1;
X ptr = Buf;
X while (*ptr && *ptr != ':')
X ++ptr;
X ++ptr;
X Find[i].search =
X realloc (Find[i].search, ptr - Buf + 1);
X strncpy (Find[i].search, Buf, ptr - Buf);
X *(Find[i].search + (ptr - Buf)) = '\0';
X Find[i].len = strlen(Find[i].search);
X }
X compile_field (Buf, fi);
X Entry[count].fields[i] =
X malloc (strlen(next) + 1);
X strcpy (Entry[count].fields[i], next);
X if ((bit |= (1 << i)) == maxbit)
X break;
X }
X if (bit != maxbit) {
X for (i = 0; Find[i].search != NULL; ++i) {
X if (((1 << i) & bit) == 0) {
X Entry[count].fields[i] = quo_quo;
X }
X }
X }
X }
X File_size = ftell (fi);
X fclose (fi);
X return (1);
X}
X
X
Xstatic void
Xload_hash()
X{
X register int i, c;
X
X bzero (Hash, sizeof(Hash));
X for (i = 0; Find[i].search; ++i) {
X c = *Find[i].search;
X if (Hash[c] > 0)
X Hash[c] = -Hash[c];
X if (Hash[c] == 0)
X Hash[c] = i | 0x100;
X }
X}
X
X
Xvoid
Xfree_entry()
X{
X free_table(0, NOHOLD);
X Entry = (struct ENTRY *)realloc (Entry, sizeof(*Entry));
X bzero (Entry[0].fields, sizeof(Entry[0].fields));
X File_size = Entries = 0;
X Entry->status = Entry->no = Entry->fpos = Current = 0;
X Listsize = 3;
X if (m_fi) {
X fclose (m_fi);
X m_fi = NULL;
X }
X}
X
X
Xstatic void
Xfree_table(at, hold)
X{
X int i, j;
X
X for (i = at; i < Entries; ++i) {
X xfree (Entry[i].from);
X for (j = 0; Find[j].search != NULL; ++j) {
X if (Entry[i].fields[j] != quo_quo)
X xfree (Entry[i].fields[j]);
X }
X }
X Entries = (hold == HOLD) ? Entries : at;
X File_size = (at) ? Entry[Entries].fpos : 0;
X}
X
Xstatic
Xsearch_from(fi)
XFILE *fi;
X{
X while (fgets (Buf, MAXFIELDSIZE, fi) != NULL) {
X if (isfrom (Buf))
X return (1);
X }
X return (0);
X}
X
X
Xsave_file(reload, mark, notmark)
X{
X FILE *fiscr;
X int fdscr;
X int i, count;
X char scratch[64];
X
X for (i = 0; i < Entries; ++i) {
X if ((Entry[i].status & mark) != mark ||
X (~Entry[i].status & notmark) != notmark)
X break;
X }
X if (i == Entries) {
X m_select (Nulav, M_RESET);
X puts ("No Changes Made");
X return (Entries);
X }
X if (m_fi == NULL)
X return (-1);
X count = 0;
X sprintf(scratch, "t:dmail%d", getpid());
X do_flock (fileno(m_fi), LOCK_EX);
X fdscr = open (scratch, O_RDWR | O_CREAT | O_TRUNC, MAILMODE);
X#ifdef AMIGA /* fix bug in Lattice C fdopen */
X fiscr = fopen("nil:", "w");
X fclose(fiscr);
X#endif
X fiscr = fdopen (fdscr, "a+");
X for (i = 0; i < Entries; ++i) {
X if ((Entry[i].status & mark) == mark &&
X (~Entry[i].status & notmark) == notmark) {
X ++count;
X fputs ("From ", fiscr);
X fputs (Entry[i].from, fiscr);
X putc ('\n', fiscr);
X fseek (m_fi, Entry[i].fpos, 0);
X while (fgets (Buf, MAXFIELDSIZE, m_fi) != NULL) {
X if (isfrom(Buf))
X break;
X fputs (Buf, fiscr);
X }
X }
X }
X
X /*
X * If new mail has come in, append to the scratch file as well.
X * NOTE: for some machines like the Amiga an already open descriptor
X * does not know about any new data, thus we cannot simply
X * use m_fi .
X */
X
X {
X FILE *fi;
X
X if (fi = fopen(mail_file, "r")) {
X fseek(fi, File_size, 0);
X while (fgets(Buf, MAXFIELDSIZE, fi))
X fputs(Buf, fiscr);
X fclose(fi);
X }
X }
X
X /* Write scratch file back to mail file, or try to */
X
X fflush (fiscr);
X fflush (m_fi);
X
X lseek (fdscr, 0 ,0);
X#ifdef UNIX
X lseek (fileno(m_fi), 0, 0);
X while ((i = read (fdscr, Buf, MAXFIELDSIZE)) > 0)
X write (fileno(m_fi), Buf, i);
X ftruncate (fileno(m_fi), lseek (fileno(m_fi), 0, 1));
X#else
X fclose(m_fi);
X if (m_fi = fopen (mail_file, "w")) {
X while ((i = read (fdscr, Buf, MAXFIELDSIZE)) > 0)
X write (fileno(m_fi), Buf, i);
X fclose(m_fi);
X m_fi = fopen (mail_file, "r+");
X }
X if (m_fi == NULL) {
X printf("Unable to re-open %s !\n", mail_file);
X return(-1);
X }
X#endif
X if (lseek (fileno(m_fi), 0, 2) == 0 && !reload) {
X if (Did_cd == 0) {
X fclose(m_fi);
X m_fi = NULL;
X if (unlink (mail_file) == 0)
X printf ("%s Removed\n", mail_file);
X else
X printf ("0 messages left in %s\n", mail_file);
X }
X }
X fclose (fiscr);
X if (m_fi)
X fclose (m_fi); /* Effectively unlocks the descriptor */
X m_fi = NULL;
X unlink (scratch);
X if (reload) {
X free_entry();
X load_mail(0, 0);
X }
X m_select (Nulav, M_RESET);
X return (count);
X}
X
Xvoid
Xcheck_new_mail()
X{
X FILE *fi;
X
X push_break();
X if (m_fi == NULL) {
X m_fi = fopen (mail_file, "r+");
X if (m_fi == NULL) {
X pop_break();
X return;
X }
X }
X if (fi = fopen(mail_file, "r")) {
X if (fseek(fi, 0, 2) < 0 || ftell(fi) != File_size)
X load_mail(Entries, 1);
X fclose(fi);
X }
X pop_break();
X}
X
X
Xwrite_file(file, modes, mark, notmark)
Xchar *file;
X{
X int i, fd = 1, notopen = 1;
X FILE *fi = NULL;
X
X for (i = 0; i < Entries; ++i) {
X if ((Entry[i].status & mark) == mark &&
X (~Entry[i].status & notmark) == notmark) {
X if (notopen) {
X notopen = 0;
X fd = open (file, O_APPEND | O_WRONLY | modes, MAILMODE);
X if (fd < 0)
X return (-1);
X do_flock (fd, LOCK_EX);
X#ifdef AMIGA /* fix bug in Lattice C fdopen */
X fi = fopen("nil:", "w");
X fclose(fi);
X#endif
X fi = fdopen (fd, "a");
X
X#ifdef NOTDEF
X if (fi) {
X printf("ptr %08lx\n", fi->_ptr);
X printf("rcnt %08lx\n", fi->_rcnt);
X printf("wcnt %08lx\n", fi->_wcnt);
X printf("base %08lx\n", fi->_base);
X printf("size %08lx\n", fi->_size);
X printf("flag %08lx\n", fi->_flag);
X printf("file %08lx\n", fi->_file);
X return(-1);
X }
X#endif
X }
X fputs ("From ", fi);
X fputs (Entry[i].from, fi);
X putc ('\n', fi);
X if (m_fi) {
X fseek (m_fi, Entry[i].fpos, 0);
X while (fgets (Buf, MAXFIELDSIZE, m_fi) != NULL) {
X if (isfrom(Buf))
X break;
X fputs (Buf, fi);
X }
X }
X }
X }
X if (!notopen)
X fclose (fi);
X return (1);
X}
X
X/*
X * Basic scheme: Each entry has a fields list. Each entry in the fields list
X * is guarenteed to be a valid malloc'd pointer (except some may be set to
X * quo_quo).
X *
X * The find[] struct array holds the field name and length, the index
X * corresponding to the index into the field[] in an Entry.
X *
X * The header and width arrays hold the list format.
X */
X
Xget_extra_ovr(str)
Xchar *str;
X{
X register int i;
X
X i = get_extra (str);
X if (i < 0) {
X i = add_extra (str);
X load_changes();
X }
X return (i);
X}
X
X
X/*
X * If there's room to add it, append to end.
X * Else Find oldest field which doesn't exist in the setlist and replace it
X * with the new one.
X */
X
Xadd_extra(str)
Xchar *str;
X{
X register int i, j, j_age, k;
X
X for (i = EXSTART; i < MAXTYPE; ++i) {
X if (Find[i].search == NULL)
X break;
X ++Find[i].age;
X }
X if (i == MAXTYPE) { /* No room to add onto end */
X j = j_age = -1;
X for (i = EXSTART; i < MAXTYPE; ++i) {
X for (k = 0; k < Listsize; ++k) {
X if (i == header[k])
X break;
X }
X if (k == Listsize && Find[i].age > j_age) {
X j = i;
X j_age = Find[i].age;
X }
X }
X i = j;
X }
X if (i < 0)
X return (-1);
X push_break();
X if (Find[i].search != NULL)
X xfree (Find[i].search);
X Find[i].len = strlen(str);
X Find[i].search = malloc (Find[i].len + 1);
X Find[i].notnew = Find[i].age = 0;
X strcpy (Find[i].search, str);
X changed = 1;
X for (j = 0; j < Entries; ++j) {
X if (Entry[j].fields[i] && Entry[j].fields[i] != quo_quo)
X xfree (Entry[j].fields[i]);
X Entry[j].fields[i] = quo_quo;
X }
X pop_break();
X return (i);
X}
X
X
Xget_extra(str)
Xchar *str;
X{
X int i;
X
X for (i = 0; Find[i].search; ++i) {
X if (strncmp (str, Find[i].search, strlen(str)) == 0) {
X Find[i].age = 0;
X return (i);
X }
X }
X return (-1);
X}
X
X
Xm_select(sav, mode)
Xregister char *sav[];
X{
X char *ptr, *dest;
X char l_map[256];
X int idx[MAXLIST], ix = 0;
X int ok, not, len, scr;
X register int i, j, avi;
X
X for (i = 0;i < 256; ++i)
X l_map[i] = i;
X for (i = 'A'; i <= 'Z'; ++i)
X l_map[i] += 'a' - 'A';
X hold_load();
X i = 0;
X idx[ix++] = get_extra_ovr (sav[i++]);
X for (; sav[i]; ++i) {
X if (strcmp (sav[i], ",") == 0 && sav[i + 1])
X idx[ix++] = get_extra_ovr (sav[++i]);
X }
X idx[ix] = -1;
X nohold_load();
X j = 1;
X push_break();
X for (i = 0; i < Entries; ++i) {
X if (mode == M_CONT && Entry[i].no == 0)
X continue;
X ix = ok = 0;
X avi = 1;
X while ((ptr = sav[avi]) != NULL) {
X if (ptr[0] == ',' && ptr[1] == '\0' && sav[avi+1]) {
X ++ix;
X avi += 2;
X continue;
X }
X if (not = (*ptr == '!'))
X ++ptr;
X len = strlen (ptr);
X dest = Entry[i].fields[idx[ix]];
X if (*ptr == '\0') {
X ok = 1;
X goto gotit;
X }
X while (*dest) {
X scr = 0;
X while (l_map[dest[scr]] == l_map[ptr[scr]] && ptr[scr])
X ++scr;
X if (ptr[scr] == '\0') {
X ok = 1;
X goto gotit;
X }
X ++dest;
X }
X ++avi;
X }
Xgotit:
X Entry[i].no = (ok ^ not) ? j++ : 0;
X }
X pop_break();
X if (Current < 0)
X Current = 0;
X if (Entries) {
X if (Entry[Current].no == 0) {
X Current = indexof (1);
X if (Current < 0) {
X Current = 0;
X return (-1);
X }
X }
X } else {
X Current = -1;
X }
X return (1);
X}
X
X
END_OF_FILE
if test 13945 -ne `wc -c <'uucp2/src/dmail/load_mail.c'`; then
echo shar: \"'uucp2/src/dmail/load_mail.c'\" unpacked with wrong size!
fi
# end of 'uucp2/src/dmail/load_mail.c'
fi
if test -f 'uucp2/src/uuser/uuser.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'uucp2/src/uuser/uuser.c'\"
else
echo shar: Extracting \"'uucp2/src/uuser/uuser.c'\" \(13776 characters\)
sed "s/^X//" >'uucp2/src/uuser/uuser.c' <<'END_OF_FILE'
X
X/*
X * UUSER.C UUSER:devicename/unitnumber/options
X * UUSER:serial.device/0/R1000
X *
X * $Header: Beta:src/uucp/src/uuser/RCS/uuser.c,v 1.1 90/02/02 12:10:15 dillon Exp Locker: dillon $
X *
X * (C) Copyright 1989-1990 by Matthew Dillon, All Rights Reserved.
X *
X * options:
X * Rn Set read timeout when no data available to n millisecs
X * C0 Ignore carrier detect
X *
X * features:
X * 1K asynchronous write capability (write 0 bytes to sync up)
X * programmable read-timeout (Getty starts procs up w/ 1sec to)
X *
X * combined together, you can easily implement 100% efficient
X * protocols even with that 1 second read timeout!
X */
X
X#include <exec/types.h>
X#include <exec/memory.h>
X#include <devices/serial.h>
X#include <devices/timer.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X#include <hardware/cia.h>
X#include <stdio.h>
X#include "protos.h"
X#include "version.h"
X
XIDENT(".02");
X
X#define WRITEBUFSIZE 1024
X#define MPC (MEMF_PUBLIC|MEMF_CLEAR) /* options to AllocMem() */
X
X#define BTOC(x, type) ((type *)((long)x << 2))
X#define CTOB(x) ((BPTR)((long)x >> 2))
X
X#define DOS_FALSE 0L
X#define DOS_TRUE -1L
X
Xtypedef struct IOExtSer IOS;
Xtypedef struct timerequest IOT;
Xtypedef struct IORequest IOR;
Xtypedef struct timeval TimeVal;
X
Xtypedef struct FileLock LOCK;
Xtypedef struct DosPacket Packet;
Xtypedef struct Process PROC;
Xtypedef struct DeviceNode DEVNODE;
Xtypedef struct FileHandle FH;
Xtypedef struct Message MSG;
Xtypedef struct Node NODE;
Xtypedef struct List LIST;
Xtypedef struct MsgPort PORT;
X
Xtypedef struct SHandle {
X NODE Node;
X IOT Iot; /* wait-for-char and read req */
X IOS Ios;
X IOS Iosr; /* 1005 */
X IOS Iosw; /* 1005,1006 */
X char IotIP;
X char IosrIP;
X char IoswIP;
X char RxIn[1]; /* one char buffer */
X char *TxOut; /* asynch write buffer */
X Packet *RPacket; /* current pending read packet */
X Packet *WPacket; /* current pending write packet */
X short Flags;
X LIST RxWait; /* requests waiting for data */
X LIST TxWait; /* requests waiting to write */
X LIST CxWait; /* wait for char */
X TimeVal ReadTo;
X} SHandle;
X
X#define HF_IGNORECD 0x01
X#define HF_CDLOST 0x02
X#define HF_RTO 0x04
X#define HF_DONTLOCK 0x08 /* if G option for from-getty */
X
Xextern Packet *taskwait(); /* wait for a message */
X
X/* long SysBase; /* required to make Exec calls */
Xchar ScrBuf[256]; /* Scratch buffer */
XPORT *IoSink;
XLIST HanList;
XLIST NodList;
XIOT Iot; /* Iot master, also used for CD */
Xchar IotIP;
X
Xvoid AttemptRead();
Xvoid AttemptWrite();
Xvoid AbortPackets();
Xvoid StartTimer();
X
Xvoid
X_main()
X{
X PROC *myproc;
X DEVNODE *mynode;
X UBYTE notdone;
X long mask;
X
X/* SysBase = *(long *)4; */
X IoSink = CreatePort(NULL, 0L);
X NewList(&HanList);
X NewList(&NodList);
X
X Iot.tr_node.io_Message.mn_ReplyPort = IoSink;
X OpenDevice("timer.device", UNIT_VBLANK, &Iot.tr_node, 0L);
X Iot.tr_node.io_Command = TR_ADDREQUEST;
X Iot.tr_time.tv_secs = 4;
X Iot.tr_time.tv_micro= 0;
X SendIO(&Iot);
X IotIP = 1;
X
X myproc = (PROC *)FindTask(0L);
X
X /*
X * INITIAL STARTUP MESSAGE
X */
X
X {
X Packet *mypkt;
X
X mypkt = taskwait(myproc);
X mynode = BTOC(mypkt->dp_Arg3, DEVNODE);
X mynode->dn_Task = &myproc->pr_MsgPort;
X returnpkt(mypkt, myproc, DOS_TRUE, 0L);
X }
X
Xloop:
X notdone = 1;
X mask = (1 << IoSink->mp_SigBit) | (1 << myproc->pr_MsgPort.mp_SigBit);
X while (notdone) {
X Packet *mypkt; /* dos packet received */
X IOR *ior;
X SHandle *handle;
X long type; /* type of packet */
X
X ior = (IOR *)GetMsg(IoSink);
X mypkt = (Packet *)GetMsg(&myproc->pr_MsgPort);
X if (mypkt)
X mypkt = (Packet *)(((MSG *)mypkt)->mn_Node.ln_Name);
X while (mypkt == NULL && ior == NULL) {
X Wait(mask);
X ior = (IOR *)GetMsg(IoSink);
X mypkt = (Packet *)GetMsg(&myproc->pr_MsgPort);
X if (mypkt)
X mypkt = (Packet *)(((MSG *)mypkt)->mn_Node.ln_Name);
X }
X
X /*
X * Make sure there is at least one free node in node list
X */
X
X if (NodList.lh_Head == (NODE *)&NodList.lh_Tail) {
X NODE *pknode = AllocMem(sizeof(NODE), MPC);
X AddTail(&NodList, pknode);
X }
X
X /*
X * Returned IO request, sift through lists to find it.
X */
X
X if (ior) {
X if (ior == &Iot.tr_node) { /* Check for carrier lost */
X for (handle = (SHandle *)HanList.lh_Head; handle != (SHandle *)&HanList.lh_Tail; handle = (SHandle *)handle->Node.ln_Succ) {
X if (!(handle->Flags & HF_IGNORECD) && !(handle->Flags & HF_CDLOST)) {
X handle->Ios.IOSer.io_Command = SDCMD_QUERY;
X DoIO((IOR *)&handle->Ios);
X if (handle->Ios.io_Status & CIAF_COMCD) {
X handle->Flags |= HF_CDLOST;
X AbortPackets(handle, myproc);
X }
X }
X }
X if (HanList.lh_Head == (NODE *)&HanList.lh_Tail) {
X IotIP = 0;
X } else {
X Iot.tr_time.tv_secs = 4;
X Iot.tr_time.tv_micro= 0;
X SendIO(&Iot.tr_node);
X IotIP = 1;
X }
X } else
X for (handle = (SHandle *)HanList.lh_Head; handle != (SHandle *)&HanList.lh_Tail; handle = (SHandle *)handle->Node.ln_Succ) {
X if (ior == (IOR *)&handle->Iosr) {
X handle->IosrIP = 0;
X if (handle->RPacket) {
X returnpkt(handle->RPacket, myproc, handle->Iosr.IOSer.io_Actual, 0L);
X handle->RPacket = NULL;
X }
X if (handle->IotIP) {
X AbortIO(&handle->Iot.tr_node);
X WaitIO(&handle->Iot.tr_node);
X handle->IotIP = 0;
X }
X AttemptRead(handle, myproc);
X }
X if (ior == (IOR *)&handle->Iosw) {
X handle->IoswIP = 0;
X if (handle->WPacket) {
X handle->Iosw.IOSer.io_Data = (APTR)handle->TxOut;
X handle->Iosw.IOSer.io_Length= handle->WPacket->dp_Arg3 - handle->WPacket->dp_Res1;
X SendIO((IOR *)&handle->Iosw);
X handle->IoswIP = 1;
X handle->WPacket->dp_Res1 = handle->WPacket->dp_Arg3;
X returnpktplain(handle->WPacket, myproc);
X handle->WPacket = NULL;
X } else {
X AttemptWrite(handle, myproc);
X }
X }
X if (ior == (IOR *)&handle->Iot.tr_node) {
X handle->IotIP = 0;
X if ((handle->Flags & HF_RTO) && handle->IosrIP) {
X AbortIO((IOR *)&handle->Iosr);
X }
X }
X }
X }
X
X if (mypkt) {
X mypkt->dp_Res1 = DOS_TRUE; /* default return value */
X mypkt->dp_Res2 = 0; /* default no error */
X type = mypkt->dp_Type; /* packet type */
X
X /*
X * Extract pipe pointer (only applies to read/write)
X */
X
X handle = (SHandle *)mypkt->dp_Arg1; /* READ/WRITE only */
X
X switch(type) {
X case ACTION_FINDINPUT:
X case ACTION_FINDOUTPUT:
X case ACTION_FINDUPDATE:
X if (IotIP == 0)
X StartTimer(4);
X {
X FH *fh = BTOC(mypkt->dp_Arg1, FH);
X char *path = BTOC(mypkt->dp_Arg3, char);
X char *unit;
X long n;
X
X movmem(path + 1, ScrBuf, *path);
X ScrBuf[*path] = 0;
X path = ScrBuf;
X
X handle = AllocMem(sizeof(SHandle), MPC);
X
X if (strcmp(ScrBuf, "*") == 0)
X strcpy(ScrBuf, "serial.device/0");
X for (unit = path; *unit && *unit != '/'; ++unit) {
X if (*unit == ':')
X path = unit + 1;
X }
X if (*unit == '/') {
X char *opts;
X
X *unit = 0;
X ++unit;
X for (opts = unit; *opts && *opts != '/'; ++opts);
X while (*opts) {
X n = atoi(opts + 1);
X switch(*opts) {
X case '/':
X break;
X case 'R':
X handle->ReadTo.tv_secs = n / 1000;
X handle->ReadTo.tv_micro= (n % 1000) * 1000;
X handle->Flags |= HF_RTO;
X break;
X case 'C':
X handle->Flags |= HF_IGNORECD;
X break;
X case 'G':
X if (n)
X handle->Flags |= HF_DONTLOCK;
X break;
X }
X ++opts;
X }
X }
X
X /* proc = (PROC *)mypkt->dp_Port->mp_SigTask; */
X
X /*
X * Open the device
X */
X
X handle->Ios.IOSer.io_Message.mn_ReplyPort = IoSink;
X handle->Ios.io_SerFlags = SERF_XDISABLED | SERF_RAD_BOOGIE | SERF_SHARED;
X if (OpenDevice(path, atoi(unit), (IOR *)&handle->Ios, 0L)) {
X FreeMem(handle, sizeof(SHandle));
X mypkt->dp_Res1 = DOS_FALSE;
X mypkt->dp_Res2 = ERROR_OBJECT_NOT_FOUND;
X returnpktplain(mypkt, myproc);
X break;
X }
X fh->fh_Arg1 = (long)handle;
X fh->fh_Port = (struct MsgPort *)DOS_TRUE;
X
X handle->Iosr = handle->Ios;
X handle->Iosw = handle->Ios;
X handle->Iosr.IOSer.io_Command = CMD_READ;
X handle->Iosw.IOSer.io_Command = CMD_WRITE;
X handle->Iot = Iot;
X NewList(&handle->RxWait);
X NewList(&handle->TxWait);
X NewList(&handle->CxWait);
X AddTail(&HanList, &handle->Node);
X returnpktplain(mypkt, myproc);
X }
X break;
X case ACTION_END:
X Remove(&handle->Node);
X AbortPackets(handle, myproc);
X if (handle->IotIP) {
X AbortIO((IOR *)&handle->Iot);
X WaitIO((IOR *)&handle->Iot);
X handle->IotIP = 0;
X }
X CloseDevice((IOR *)&handle->Ios);
X returnpktplain(mypkt, myproc);
X if (handle->TxOut)
X FreeMem(handle->TxOut, WRITEBUFSIZE);
X FreeMem(handle, sizeof(SHandle));
X break;
X case ACTION_READ:
X {
X NODE *pknode = RemHead(&NodList);
X mypkt->dp_Res1 = 0;
X pknode->ln_Name = (char *)mypkt;
X AddTail(&handle->RxWait, pknode);
X AttemptRead(handle, myproc);
X }
X break;
X case ACTION_WRITE:
X {
X NODE *pknode = RemHead(&NodList);
X mypkt->dp_Res1 = 0;
X pknode->ln_Name = (char *)mypkt;
X AddTail(&handle->TxWait, pknode);
X AttemptWrite(handle, myproc);
X }
X break;
X case ACTION_WAIT_CHAR:
X default:
X returnpkt(mypkt, myproc, DOS_FALSE, ERROR_ACTION_NOT_KNOWN);
X break;
X }
X }
X }
X
X /*
X * Can only exit if no messages pending. There might be a window
X * here, but there is nothing that can be done about it.
X */
X
X Forbid();
X if (taskpktrdy(myproc)) {
X Permit();
X goto loop;
X }
X mynode->dn_Task = FALSE;
X Permit();
X
X if (IotIP) {
X AbortIO(&Iot.tr_node);
X WaitIO(&Iot.tr_node);
X }
X CloseDevice(&Iot.tr_node);
X
X /* we are a process "so we fall off the end of the world" */
X /* MUST fall through */
X}
X
Xvoid
XAttemptRead(handle, myproc)
XSHandle *handle;
XPROC *myproc;
X{
X Packet *mypkt;
X NODE *pknode;
X
X if (handle->Flags & HF_CDLOST) {
X AbortPackets(handle, myproc);
X return;
X }
Xloop:
X if (handle->IosrIP == 0 && (pknode = RemHead(&handle->RxWait))) {
X long n;
X
X AddTail(&NodList, pknode);
X
X mypkt = (Packet *)pknode->ln_Name;
X
X /*
X * special case. If you read 0 bytes, 0 is returned if data
X * is pending, else -1, and NO timeout occurs.
X */
X
X handle->Ios.IOSer.io_Command = SDCMD_QUERY;
X DoIO((IOR *)&handle->Ios);
X
X if (mypkt->dp_Arg3 == 0) {
X if (handle->Ios.IOSer.io_Actual > 0)
X returnpkt(mypkt, myproc, DOS_FALSE, 0L); /* 0=data rdy */
X else
X returnpkt(mypkt, myproc, DOS_TRUE, 0L); /* -1=data not rdy */
X goto loop;
X }
X
X if ((n = handle->Ios.IOSer.io_Actual) > 0) {
X if (n > mypkt->dp_Arg3)
X n = mypkt->dp_Arg3;
X handle->Iosr.IOSer.io_Data = (APTR)mypkt->dp_Arg2;
X handle->Iosr.IOSer.io_Length = n;
X DoIO((IOR *)&handle->Iosr);
X mypkt->dp_Res1 = handle->Iosr.IOSer.io_Actual;
X returnpktplain(mypkt, myproc);
X goto loop;
X }
X handle->Iosr.IOSer.io_Data = (APTR)mypkt->dp_Arg2;
X handle->Iosr.IOSer.io_Length = 1;
X SendIO((IOR *)&handle->Iosr);
X handle->IosrIP = 1;
X handle->RPacket = mypkt;
X
X if (handle->Flags & HF_RTO) {
X if (handle->IotIP) {
X AbortIO(&handle->Iot.tr_node);
X WaitIO(&handle->Iot.tr_node);
X }
X handle->Iot.tr_time = handle->ReadTo;
X SendIO(&handle->Iot.tr_node);
X handle->IotIP = 1;
X }
X }
X}
X
Xvoid
XAttemptWrite(handle, myproc)
XSHandle *handle;
XPROC *myproc;
X{
X Packet *mypkt;
X NODE *pknode;
X
X if (handle->Flags & HF_CDLOST) {
X AbortPackets(handle, myproc);
X return;
X }
X if (handle->IoswIP == 0 && (pknode = RemHead(&handle->TxWait))) {
X AddTail(&NodList, pknode);
X
X mypkt = (Packet *)pknode->ln_Name;
X
X if (handle->TxOut == NULL)
X handle->TxOut = AllocMem(WRITEBUFSIZE, MPC);
X
X if (mypkt->dp_Arg3 <= WRITEBUFSIZE) { /* fully asynch */
X movmem((char *)mypkt->dp_Arg2, handle->TxOut, mypkt->dp_Arg3);
X handle->Iosw.IOSer.io_Data = (APTR)handle->TxOut;
X handle->Iosw.IOSer.io_Length = mypkt->dp_Arg3;
X SendIO(&handle->Iosw);
X mypkt->dp_Res1 = mypkt->dp_Arg3;
X returnpktplain(mypkt, myproc);
X handle->WPacket = NULL;
X } else { /* semi-asynch */
X long n = mypkt->dp_Arg3 - WRITEBUFSIZE;
X handle->Iosw.IOSer.io_Data = (APTR)mypkt->dp_Arg2;
X handle->Iosw.IOSer.io_Length = n;
X SendIO(&handle->Iosw);
X movmem((char *)mypkt->dp_Arg2 + n, handle->TxOut, WRITEBUFSIZE);
X mypkt->dp_Res1 += n;
X handle->WPacket = mypkt;
X }
X handle->IoswIP = 1;
X }
X}
X
Xvoid
XAbortPackets(handle, myproc)
XSHandle *handle;
X{
X NODE *pknode;
X Packet *mypkt;
X
X if (handle->RPacket)
X returnpktplain(handle->RPacket, myproc);
X
X if (handle->WPacket)
X returnpktplain(handle->WPacket, myproc);
X
X if (handle->IosrIP) {
X AbortIO((IOR *)&handle->Iosr);
X WaitIO((IOR *)&handle->Iosr);
X handle->IosrIP = 0;
X }
X if (handle->IoswIP) {
X AbortIO((IOR *)&handle->Iosw);
X WaitIO((IOR *)&handle->Iosw);
X handle->IoswIP = 0;
X }
X
X handle->RPacket = NULL;
X handle->WPacket = NULL;
X
X while (pknode = RemHead(&handle->RxWait)) {
X mypkt = (Packet *)pknode->ln_Name;
X if (mypkt->dp_Arg3 == 0)
X mypkt->dp_Res1 = 0; /* for poll, return data rdy */
X else
X mypkt->dp_Res1 = -1;
X returnpktplain(mypkt, myproc);
X AddTail(&NodList, pknode);
X }
X
X while (pknode = RemHead(&handle->TxWait)) {
X mypkt = (Packet *)pknode->ln_Name;
X mypkt->dp_Res1 = -1;
X returnpktplain(mypkt, myproc);
X AddTail(&NodList, pknode);
X }
X}
X
Xvoid
XStartTimer(secs)
X{
X if (IotIP) {
X AbortIO(&Iot.tr_node);
X WaitIO(&Iot.tr_node);
X }
X Iot.tr_time.tv_secs = secs;
X Iot.tr_time.tv_micro= 0;
X SendIO(&Iot.tr_node);
X IotIP = 1;
X}
X
X
END_OF_FILE
if test 13776 -ne `wc -c <'uucp2/src/uuser/uuser.c'`; then
echo shar: \"'uucp2/src/uuser/uuser.c'\" unpacked with wrong size!
fi
# end of 'uucp2/src/uuser/uuser.c'
fi
echo shar: End of archive 7 \(of 12\).
cp /dev/null ark7isdone
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.