Logo Search packages:      
Sourcecode: casu version File versions  Download package

to.c

/*
 *  CaSU - communications & status utilities.
 *  Copyright (C) 1992, 1993, 1994 Luke Mewburn <lm@rmit.edu.au>
 *    incorporating:
 *       flon - lists your friends who are logged on.
 *       to - send a short message to a friend
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#define _MAIN_
#include "casu.h"

#ifdef M_SYSV
    utmp_s  Kludge;
#endif /* for SCO */


static      int   argc;
static      char  **argv;

/*
 * add_alist_ent -      add an alias/userid pair to the global linked list;
 *                if alias is empty, just add - as it's an exclude entry,
 *                not an alias.
 */
static void
add_alist_ent(alias, userid, them)
    char    *alias, *userid;
    user_t  *them;
{
    alist *p = them->aliases;

    if (alias[0])       /* find matching alias */
    {
      while (p != NULL)
      {
          if (strcmp(p->alias, alias) == 0)
            break;
          p = p->next;
      }
    }
    else                /* find matching exclude entry */
    {
      while (p != NULL)
      {
          if ((!p->alias[0]) && (strcmp(p->userid, userid) == 0))
            break;
          p = p->next;
      }
    }
    if (p == NULL)            /* not found - add new element */
    {
      p = (alist *) malloc (sizeof(alist));
      if (p == NULL)
          errexit(strerror(errno), NULL);
      p->next = them->aliases;
      them->aliases = p;
    }
    strnc0py(p->alias, alias, sizeof(p->alias) - 1);
    strnc0py(p->userid, userid, sizeof(p->userid) - 1);
} /* add_alist_ent */


/*
 * remove_alist_ent - remove an alias/userid pair from the global linked list;
 */
static void
remove_alist_ent(user, them, rm_type)
    char    *user;
    user_t  *them;
#define REMOVE_EXCLUDE  0
#define REMOVE_ALIAS    1
    int           rm_type;    /* 1 == remove alias, 0 === remove exclude */
{
    alist *p = them->aliases, *last;

    last = NULL;
    while (p != NULL)               /* find relevant entry */
    {
      if (rm_type == REMOVE_ALIAS)
      {
          if (strcmp(p->alias, user) == 0)
            break;
      }
      else  /* REMOVE_EXCLUDE */
          if ((! p->alias[0]) && (strcmp(p->userid, user) == 0))
            break;
      last = p;
      p = p->next;
    }
    if (p == NULL)                  /* not there - complain */
    {
      if (rm_type == REMOVE_ALIAS)
          errmesg("alias not found", user);
      else
          errmesg("exclude entry not found", user);
      return;
    }
    if (last != NULL)               /* de-link it from the list */
      last->next = p->next;
    else
      them->aliases = p->next;      /* don't bother free()ing it... */
} /* remove_alist_ent */


/*
 * get_pwent -    get an appropriate entry from the password file.
 *          if given NULL, assume it's for this user
 */
static struct passwd *
get_pwent(nam)
    char *nam;
{
    struct passwd *pwent;
    if (nam == NULL)
      pwent = getpwuid(getuid());
    else
      pwent = getpwnam(nam);
    return pwent;
} /* get_pwent */


/*
 * load_rcfile - read in the rcfile for the respective user
 *          into the data struct. if nam == NULL, also add
 *          aliases to the global list;
 */
static void
load_rcfile(them, nam)
     user_t *them;
     char   *nam;
{
    FILE          *fp;
    char          buf[LINESIZ + 1], rcfile[MAXPATHLEN + 1];
    char          user[UT_NAMESIZE + 1], alias[ALIASLEN + 1];
    struct stat         sbuf;
    int                 ch;
    struct passwd *pwent;
    static char         aliasfmt[16];     /* see below */

    if (!aliasfmt[0])
      sprintf(aliasfmt, "%%%ds %%%ds", ALIASLEN, UT_NAMESIZE);

    them->yes[0] = '\0';            /* clear everything */
    them->no[0] = '\0';
    them->gone[0] = '\0';
    them->idle[0] = '\0';
    them->dotuser[0] = '\0';
    them->dottty[0] = '\0';
    them->exclude[0] = '\0';
    them->aliases = NULL;

    pwent = get_pwent(nam);         /* get info from /etc/passwd */
    if (!pwent)
      if (!nam)
          errexit("you don't exist", NULL);
      else
          errexit("doesn't exist", nam);
    strnc0py(them->name,
          convert_realname(pwent->pw_gecos, pwent->pw_name, pwent->pw_uid),
          sizeof(them->name) - 1);
    strnc0py(them->userid, pwent->pw_name, sizeof(them->userid) - 1);
    strnc0py(them->homedir, pwent->pw_dir, sizeof(them->homedir) - 1);

    strnc0py(rcfile, pwent->pw_dir, sizeof(rcfile) - 1);
    if (strlen(rcfile) + strlen(STRtorc) >= sizeof(rcfile) - 1)
      errexit("filename is too long", STRtorc);
    strcat(rcfile, STRtorc);
    if (stat(rcfile, &sbuf) == -1)  /* open their .torc */
      return;
    fp = fopen(rcfile, "r");
    if (fp == NULL)
      return;
    while (fgets(buf, sizeof(buf), fp) != NULL)
    {                         /* read it in */
      if (strlen(buf) == sizeof(buf) - 1 )
          while ((ch = fgetc(fp)) != EOF)
            if (ch == '\n')
                break;        /* gobble extra chars */
      buf[strlen(buf) - 1] = '\0';
      ch = isupper(buf[0]) ? tolower(buf[0]) : buf[0];
      switch (ch)
      {
      case '.':               /* . user */
          strnc0py(them->dotuser, buf + (buf[1] == ' ' ? 2 : 1),
                  sizeof(them->dotuser) - 1);
          break;
      case ':':               /* . tty */
          strnc0py(them->dottty, buf + 2, sizeof(them->dottty) - 1);
          break;
      case 'y':               /* yes AR */
          strnc0py(them->yes, buf + 2, sizeof(them->yes) - 1);
          break;
      case 'n':               /* no AR */
          strnc0py(them->no, buf + 2, sizeof(them->no) - 1);
          break;
      case 'g':               /* gone AR */
          strnc0py(them->gone, buf + 2, sizeof(them->gone) - 1);
          break;
      case 'i':               /* idle AR */
          strnc0py(them->idle, buf + 2, sizeof(them->idle) - 1);
          break;
      case 'x':               /* exclude AR */
          strnc0py(them->exclude, buf + 2, sizeof(them->exclude) - 1);
          break;
      case 'p':               /* pseudonym/name/whatever */
          strnc0py(them->name, buf + 2, sizeof(them->name) - 1);
          flags |= PSEUDO_MOD;
          break;
      case 'a':               /* add an alias */
          if (nam == NULL)    /* only add aliases to sender's struct */
          {
            sscanf(buf + 1, aliasfmt, alias, user);
            add_alist_ent(alias, user, them);
          }
          break;
      case 'e':         /* add an exclude entry */
          add_alist_ent("", buf + 2, them);
          break;
      default:
          if (flags & DEBUG)
          {
            buf[1] = '\0';    /* so errmesg doesn't die */
            errmesg("illegal specifier (DEBUG)", buf);
          }
          break;
      }
    } /* while */
} /* load_rcfile */


/*
 * dump_status -  dump status of user rec.
 */
static void
dump_status(me)
    user_t  *me;
{
    struct stat sbuf;

    if (!me->tty)
      printf("Not attached to a tty.\n");
    else
    {
      if (stat(me->tty, &sbuf) == -1)
          errmesg(strerror(errno), me->tty);
      else
          printf("Incoming messages are %sabled.\n",
                (sbuf.st_mode & MESGS_ON) ? "en" : "dis");
    }
    printf("Name:      %s\n", me->name);
    if (me->tty)
      printf("Terminal:  %s\n", me->tty);
    if (me->dotuser[0] != '\0')
    {
      if (me->dottty[0] != '\0')
          printf("Last user: %s (%s)\n", me->dotuser, me->dottty);
      else
          printf("Last user: %s\n", me->dotuser);
    }
    if (me->yes[0] != '\0')
      printf("Mesg ON autoreply:  %s\n", me->yes);
    if (me->no[0] != '\0')
      printf("Mesg OFF autoreply: %s\n", me->no);
    if (me->gone[0] != '\0')
      printf("Gone autoreply:     %s\n", me->gone);
    if (me->idle[0] != '\0')
      printf("Idle autoreply:     %s\n", me->idle);
    if (me->exclude[0] != '\0')
      printf("Exclude autoreply:  %s\n", me->exclude);
} /* dump_status */


/*
 * process_options -    parse the options available
 */
static void
process_options(me, you)
    user_t  *me, *you;
{
    int           ch;

    opterr=1;
    while ((ch = getopt(argc, argv, "a:bde:E:hlnrt:u:yvP:I:Y:N:G:X:V")) != -1)
    {
      switch (ch)
      {
      case 'a':
          if (argc == optind)
          {
            fprintf(stderr, "Usage: %s -a alias userid\n", progname);
            flags |= ERROR;
            break;
          }
          add_alist_ent(optarg, argv[optind++], me);
          flags |= DB_MOD;
          break;
      case 'b':
          flags |= BEEP;
          break;
      case 'd':
          flags |= DEBUG;
          break;
      case 'e':
          add_alist_ent("", optarg, me);
          flags |= DB_MOD;
          break;
      case 'E':
          remove_alist_ent(optarg, me, REMOVE_EXCLUDE);
          flags |= DB_MOD;
          break;
      case 'l':
          flags |= LISTALIAS;
          break;
      case 'h':
          flags |= HELP;
          break;
      case 'n':
          flags &= ~MESG_Y;
          flags |= MESG_N;
          break;
      case 'y':
          flags |= MESG_Y;
          flags &= ~MESG_N;
          break;
      case 'r':
          flags |= STATUS;
          break;
      case 't':
          you->tty = optarg;
          flags |= DB_MOD;
          break;
      case 'u':
          remove_alist_ent(optarg, me, REMOVE_ALIAS);
          flags |= DB_MOD;
          break;
      case 'v':
      case 'V':
          flags |= LISTVERS;
          break;
      case 'Y':
          strnc0py(me->yes, optarg, sizeof(me->yes) - 1);
          flags |= DB_MOD;
          break;
      case 'P':
          strnc0py(me->name, optarg, sizeof(me->name) - 1);
          flags |= (PSEUDO_MOD + DB_MOD);
          break;
      case 'N':
          strnc0py(me->no, optarg, sizeof(me->no) - 1);
          flags |= DB_MOD;
          break;
      case 'G':
          strnc0py(me->gone, optarg, sizeof(me->gone) - 1);
          flags |= DB_MOD;
          break;
      case 'I':
          strnc0py(me->idle, optarg, sizeof(me->idle) - 1);
          flags |= DB_MOD;
          break;
      case 'X':
          strnc0py(me->exclude, optarg, sizeof(me->exclude) - 1);
          flags |= DB_MOD;
          break;
      case '?':
          flags |= ERROR;
          break;
      }
    }

    if (flags & DEBUG)
      printf("DEBUG: argc %d  optind %d  flags %d \n", argc, optind, flags);

            /* barf if just -b, -t ttyxx, or no args */
    if (   (argc == optind)         /* non-productive usage */
      && ((flags & BEEP) || (you->tty) || (argc == 1)))
      flags |= ERROR;

    if (flags & (MESG_Y + MESG_N))  /* change tty mode */
    {
      struct stat sbuf;
      if (!me->tty)
          errmesg("unable to change status of tty - no such tty", NULL);
      else
          if (stat(me->tty, &sbuf) == -1)
            errmesg(strerror(errno), me->tty);
          else
          {
            if (flags & MESG_N)
                sbuf.st_mode &= ~MESGS_ON;
            else
                sbuf.st_mode |= MESGS_ON;
            chmod(me->tty, sbuf.st_mode);
          }
    }

    if (flags & STATUS)             /* show status */
      dump_status(me);

    if (flags & LISTALIAS)          /* list aliases */
    {
      alist *p = me->aliases;
      if (p)
          printf("UserID\t  Alias\n------\t  -----\n");
      else
          printf("No aliases defined.\n");
      while (p)
      {
          printf("%s\t  %s\n", p->userid, p->alias[0] ? p->alias
                                          : "** EXCLUDED **");
          p = p->next;
      }
    }

    if (flags & (ERROR + LISTVERS + HELP))
    {
      fprintf(stderr, "\
Usage: %s [-a alias user] [-u alias] [-bdlnyr] [-G gone] [-Y yes] [-N no]\n\
\t[-I idle] [-X exclude] [-P pseudo] [-e user] [-E user] [-t term]\n\
\t[-h] -[vV]  [user [message]]\n\
", progname);
      if (flags & (HELP))
      {
          fprintf(stderr, "\
\n\
To - send a short message to another user\n\
\n\
Usage:  %s [options] user [message] \tsends message to user (*)\n\
\n\
if user is `.', then send message to the last user you sent to.\n\
\n\
options can be:\n\
      -a alias user     add an alias to your .torc\n\
      -u alias    unalias an alias\n\
      -b          beep other user with message\n\
      -e user           add `user' to the exclude list\n\
      -E user           remove `user' from the exclude list\n\
      -h          this help page\n\
      -n          turn messages off\n\
      -y          turn messages on\n\
      -l          list aliases\n\
      -r          list status\n\
      -t term           send to tty `term'\n\
      -P name           set pseudonym to name\n\
      -I mesg           set `idle' autoreply to mesg\n\
      -G mesg           set `gone' autoreply to mesg\n\
      -N mesg           set `mesg n' autoreply to mesg\n\
      -Y mesg           set `mesg y' autoreply to mesg\n\
      -X mesg           set `exclude' autoreply to mesg\n\
      -V          version infomation\n\
\n\
The options can be used in conjunction with each other.\n\
\n\
(*) Reads message from terminal if you don't specify one.\n\
", progname);
      }
      if (flags & (HELP + LISTVERS))
      {
          fprintf(stderr, "\
\n\
%s version %s, %s.\n\
Copyright (C) 1993, 1994 Luke Mewburn\n\
Email: <lm@rmit.edu.au>\n\
This is free software, and you are welcome to redistribute it under certain\n\
conditions. See version 2 of the GNU Public License for more details.\n\
", progname, VERSION, RELDATE);
      }
      exit((flags & ERROR ) != 0);
    }
} /* process_options */


/*
 * lookup_user -  find a user and put info in user_t struct
 */
static int
lookup_user(me, you)
    user_t *me, *you;
{
    alist         *p = me->aliases;
    struct passwd *pwent;
    char          *target;
    
    if (argc > optind)
      target = argv[optind++];
    else
      return 0;
    if (strcmp(target, ".") == 0)   /* is a .user */
    {
      if (me->dotuser[0] == '\0')
      {
          errmesg("no `.' user defined", NULL);
          return 0;
      }
      target = me->dotuser;
      if ((!you->tty) && (me->dottty[0] != '\0'))
          you->tty = me->dottty;    /* use last tty */
    }
    else                      /* is it an alias? */
    {
      while (p)
      {
          if (strcmp(target, p->alias) == 0)
          {
            target = p->userid;
            break;
          }
          p = p->next;
      }
    }
    pwent = get_pwent(target);            /* check if user */
    if (! pwent)
    {
      errmesg("doesn't exist", target);
      return 0;
    }
    strnc0py(you->name,
          convert_realname(pwent->pw_gecos, pwent->pw_name, pwent->pw_uid),
          sizeof(you->name) - 1);
    strnc0py(you->userid, pwent->pw_name, sizeof(you->userid) - 1);
    strnc0py(you->homedir, pwent->pw_dir, sizeof(you->homedir) - 1);
    if (target != me->dotuser)
    {
      strnc0py(me->dotuser, target, sizeof(me->dotuser) - 1);
      flags |= DB_MOD;
    }
    return 1;
} /* lookup_user */


/*
 * update_torc -  write out change .torc file
 */
static void
update_torc(me)
    user_t *me;
{
    FILE    *fp;
    alist   *p = me->aliases;
    char    rcfile[MAXPATHLEN + 1];
    struct stat   sbuf;

    if (!(flags & DB_MOD))    /* only write if info was modified */
      return;

    strnc0py(rcfile, me->homedir, sizeof(rcfile) - 1);
    if (strlen(rcfile) + strlen(STRtorc) >= sizeof(rcfile) - 1)
      errexit("filename is too long", STRtorc);
    strcat(rcfile, STRtorc);

#if TTY_RESTRICTED
    setgid(getgid());         /* so a new .torc has user's group, not `tty' */
#endif /* TTY_RESTRICTED */
    fp = fopen(rcfile, "w");
    if (fp == NULL)
      errexit(strerror(errno), NULL);
    if (me->dotuser[0] != '\0')
      fprintf(fp, ". %s\n", me->dotuser);
    if (me->dottty[0] != '\0')
      fprintf(fp, ": %s\n", me->dottty);
    if (flags & PSEUDO_MOD)
      if (me->name[0] != '\0')
          fprintf(fp, "P %s\n", me->name);
    if (me->yes[0] != '\0')
      fprintf(fp, "Y %s\n", me->yes);
    if (me->idle[0] != '\0')
      fprintf(fp, "I %s\n", me->idle);
    if (me->no[0] != '\0')
      fprintf(fp, "N %s\n", me->no);
    if (me->gone[0] != '\0')
      fprintf(fp, "G %s\n", me->gone);
    if (me->exclude[0] != '\0')
      fprintf(fp, "X %s\n", me->exclude);
    while (p)
    {
      if (p->alias[0])  /* exclude entries have this field empty */
          fprintf(fp, "a %s %s\n", p->alias, p->userid);
      else
          fprintf(fp, "e %s\n", p->userid);
      p = p->next;
    }
    if (stat(rcfile, &sbuf) != -1)  /* set the file to be world readable */
    {
      sbuf.st_mode |= 0444;
      chmod(rcfile, sbuf.st_mode);
    }
    fclose(fp);
} /* update_torc */


/*
 * filter_buf - remove control characters from a NUL terminated char buffer
 */

static void
filter_buf(buf)
    char *buf;
{
    int i;
    for (i = 0; i < strlen(buf); i++)
      if (! (isprint(buf[i]) || buf[i] == '\t'))
          buf[i] = '?';
} /* filter_buf */


/*
 * construct_message -  build message from argv[], or read it from stdin
 */
static void
construct_message(me)
    user_t *me;
{
    int           i, pos, len;

    me->message[0] = '\0';
    if (argc != optind)       /* build up message from argv[] */
    {
      pos = len = 0;
      for (i = optind; i < argc; i++)
      {
          len = strlen(argv[i]);
          if (len + pos > sizeof(me->message) - 1)
            break;
          strnc0py(me->message + pos, argv[i], len);
          pos += len;
          me->message[pos++] = ' ';
      }
      me->message[pos] = '\0';
    }
    else                /* interactively grab message */
    {
      if (!me->tty)           /* don't read message from non-terminal */
      {
          strnc0py(me->message, "I would like to talk to you",
                        sizeof(me->message) - 1);
          return;
      }
      printf("Message: ");
      if (fgets(me->message, sizeof(me->message), stdin) == NULL)
      {
          strnc0py(me->message, "I would like to talk to you",
                        sizeof(me->message) - 1);
          return;
      }
      len = strlen(me->message);
      if (me->message[len - 1] == '\n')
          me->message[--len] = '\0';
    }
} /* construct_message */


/*
 * send_message - send the message...
 */
static void
send_message(me, you)
    user_t *me, *you;
{
    utmp_s *            utent;
    char          host[MAXHOSTNAMELEN + 2];
    static char         tty[sizeof(_PATH_DEV) + UT_LINESIZE + 1]=_PATH_DEV;
    char          *autoreply, *timestr, *hostp;
    int                 res;
    FILE *        fp;
    time_t        now;
    alist         *pers;
    struct stat         stbuf;
#if HAVE_UNAME
    struct utsname      unamebuf;
#endif /* HAVE_UNAME */
    static struct {
      char        tty[sizeof(tty)];
      time_t            idle;
      int         res;
    } cur;

    host[sizeof(host) - 1] = '\0';  /* get hostname _somehow_ */
    host[0] ='@';
#if HAVE_GETHOSTNAME
    if (gethostname(host + 1, sizeof(host) - 2) == -1)
      host[0] = '\0';
#else /* !HAVE_GETHOSTNAME */
#   if HAVE_UNAME
    if (uname(&unamebuf) == 0)
      strnc0py(host + 1, unamebuf.nodename, sizeof(host) - 2);
    else    /* fallthru #endif */
#   endif /* HAVE_UNAME */
    host[0] = '\0';
#endif  /* !HAVE_GETHOSTNAME */
    hostp = strchr(host, '.');            /* remove any domain info */
    if (hostp)
      *hostp = '\0';

    now = time(NULL);
    timestr = ctime(&now) + 11;
    timestr[5] = '\0';

    cur.res = 0;
    load_rcfile(you, you->userid);
    construct_message(me);
    if (flags & DEBUG)
      printf("DEBUG: me->message is :%s:\n", me->message);
    pers = you->aliases;
    while (pers)        /* see if they're excluding you */
    {
      if ((strcmp(me->userid, pers->userid) == 0) && (! pers->alias[0]))
      {
          cur.res |= R_EXCLUDE;
          goto do_autoreply;        /* don't bother attempting to send */
      }
      pers = pers->next;
    }

    while ((utent = getutent()) != NULL)
    {
      if (NULL_UTMP_ENTRY(utent))
          continue;
      if (flags & DEBUG)
          printf("DEBUG: checking %s %s\n", utent->ut_name, utent->ut_line);
      if (strncmp(utent->ut_name, you->userid, sizeof(utent->ut_name) -1))
          continue;           /* not them */
      cur.res |= R_IS_ON;
      strcpy(&tty[sizeof(_PATH_DEV) - 1], utent->ut_line);
      if (you->tty)           /* want specific tty */
      {
          if (strcmp(utent->ut_line, you->tty) == 0)
          {
            cur.res |= R_HAVETTY;
            if (flags & DEBUG)
                printf("DEBUG: user on specific tty: %s\n", you->tty);
            continue;
          }
      }
      if (me->tty && strcmp(me->tty, tty) == 0)
          continue;           /* don't do my current terminal */
      res = stat(tty, &stbuf);
      if ((!cur.idle || ((res != -1) && (stbuf.st_atime > cur.idle)))
                      && (stbuf.st_mode & MESGS_ON))
      {
          strcpy(cur.tty, utent->ut_line);      /* remember idle info */
          cur.res |= R_VALIDTTY;
          if (res != -1)
            cur.idle = stbuf.st_atime;
      }
    } /* while */
    if (! (cur.res & R_IS_ON))
      goto do_autoreply;            /* no further attempts to send... */

    filter_buf(me->name);
    filter_buf(me->message);
    filter_buf(you->name);

    if (you->tty)
    {
      if (cur.res & R_HAVETTY)      /* user is on specified tty */
      {
          strcpy(&tty[sizeof(_PATH_DEV) - 1], you->tty);
          strcpy(cur.tty, you->tty);
          cur.res |= R_VALIDTTY;
          if (stat(tty, &stbuf) != -1)
            cur.idle = stbuf.st_atime;
          else
            cur.idle = 0;
      }
      else                    /* user not on specified tty */
      {
          if (you->tty == me->dottty)     /* user is dotuser */
            printf("Warning: %s isn't on %s, using %s instead.\n",
                  you->name, you->tty, cur.tty);
          else
            cur.res &= ~R_VALIDTTY; /* -t tty was used, but not on it */
      }
    }

                              /* if valid tty, attempt to send */
    strcpy(&tty[sizeof(_PATH_DEV) - 1], cur.tty);
    if ((cur.res & R_VALIDTTY) && ((fp = fopen(tty, "a")) != NULL))
    {
      cur.res |= R_SENT;
      if (flags & BEEP)
          fprintf(fp, "%c", BELL);  /* Beep! */

      if (!me->tty)
          me->tty = "/dev/tty??";   /* hmm... stdin wasn't stdin */
      fprintf(fp, "\r-=> From %s (%s%s) on %s at %s :- \n\r",
            me->name, me->userid, host,
            &me->tty[sizeof(_PATH_DEV) - 1], timestr);
      fprintf(fp, "%s  \n\r", me->message);
      fclose(fp);
    }

do_autoreply:                 /* argh! a goto... makes life easier though */
    autoreply = NULL;
    if (cur.res & R_EXCLUDE)        /* They don't like you */
    {
      printf("%s: %s (%s) has excluded you as a sender.\n",
                  progname, you->name, you->userid);
      autoreply = you->exclude;
    }
    else if (! (cur.res & R_IS_ON)) /* They're not on */
    {
      printf("%s: %s (%s) isn't logged on.\n",
                  progname, you->name, you->userid);
      autoreply = you->gone;
    }
    else if (! (cur.res & R_SENT))  /* Didn't work for other reason */
    {
      if (cur.res & R_VALIDTTY)
      {
          printf("%s: Access to %s's (%s) terminal denied.\n",
                  progname, you->name, you->userid);
          autoreply = you->no;
      }
      else
      {
          if ((strncmp(me->userid, you->userid, sizeof(me->userid) - 1) == 0))
#if 0 /* XXX: what is the next line doing??? lm, 940412 */
            || (!you->tty && !(cur.res & R_HAVETTY)))
                              /* only if >1 usernames on same uid */
#endif
            printf("%s: You are only logged on once.\n", progname);
          else if (!you->tty)       /* mesg n on their only session */
          {
            printf("%s: Access to %s's (%s) terminal denied.\n",
                      progname, you->name, you->userid);
            autoreply = you->no;
          }
          else                /* not on specific tty */
            printf("%s: %s (%s) isn't logged onto the tty '%s'.\n",
                  progname, you->name, you->userid, you->tty);
      }
    }
    else                      /* Actually got through */
    {
      if (cur.idle)                 /* Have an idle message */
      {
          if (now - cur.idle > min_idle)
            if (strlen(you->idle))
                autoreply = you->idle;
      }
      if (autoreply == NULL)
          autoreply = you->yes;
      if (stat(me->tty, &stbuf) != -1)
      {
          if (! (stbuf.st_mode & MESGS_ON))     /* Just to let you know... */
            printf("Warning: you have your messages disabled. %s can't reply.\n", you->name);
      }
      printf("Message sent to %s (%s%s) on %s.\n",    /* Print results */
                  you->name, you->userid, host, cur.tty);
            /* record where the message really went */
      if (strncmp(me->dottty, cur.tty, sizeof(me->dottty)) != 0)
      {
          strnc0py(me->dottty, cur.tty, sizeof(me->dottty) - 1);
          flags |= DB_MOD;
      }
    }
    if (autoreply && strlen(autoreply))         /* An autoreply exists */
    {
      filter_buf(autoreply);              /* Remove illegal chars */
      printf("-=> Auto-reply from %s :-\n%s\n", you->name, autoreply);
    }
    endutent();
} /* send_message */


/*
 *    main function
 */
int
main(margc, margv)
    int margc;
    char *margv[];
{
    user_t  me_s, *me = &me_s;
    user_t  you_s, *you = &you_s;
    char    *p;

    min_idle = MINIDLE;
    argc = margc;
    argv = margv;
    me->tty = ttyname(0);           /* me->tty is full path */
    you->tty = NULL;                /* you->tty is just basename */
    progname = argv[0];                   /* Basename invocation name */
    if ((p = strrchr(progname, '/')) != NULL)
      progname = ++p;
    flags = 0;

    load_rcfile(me, NULL);
    if (  ((p = getenv("PSEUDONYM")) != NULL)   /* Get default name for you */
      || ((p = getenv("NAME")) != NULL))
    {
      if (  (strcmp(me->name, p) != 0)
          && (!(flags & PSEUDO_MOD)))
      {
          strnc0py(me->name, p, sizeof(me->name) - 1);
          flags |= (PSEUDO_MOD + DB_MOD);
      }
    }
    process_options(me, you);
    if (lookup_user(me, you))
      send_message(me, you);
    update_torc(me);
    return 0;
} /* main */

Generated by  Doxygen 1.6.0   Back to index