home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / clients / xdm / sessreg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-18  |  8.0 KB  |  359 lines

  1. /*
  2.  * $XConsortium: sessreg.c,v 1.8 91/07/18 22:00:12 rws Exp $
  3.  *
  4.  * Copyright 1990 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Keith Packard, MIT X Consortium
  24.  */
  25.  
  26. /*
  27.  * sessreg
  28.  *
  29.  * simple wtmp/utmp frobber
  30.  *
  31.  * usage: sessreg [ -w <wtmp-file> ] [ -u <utmp-file> ]
  32.  *          [ -l <line> ]
  33.  *          [ -h <host-name> ]                / BSD only
  34.  *          [ -s <slot-number> ] [ -x Xservers-file ]    / BSD only
  35.  *          [ -t <ttys-file> ]                / BSD only
  36.  *              [ -a ] [ -d ] user-name
  37.  *
  38.  * one of -a or -d must be specified
  39.  */
  40.  
  41. # include    <X11/Xos.h>
  42. # include    <X11/Xfuncs.h>
  43. # include    <stdio.h>
  44. # include    <utmp.h>
  45.  
  46. #ifdef SVR4
  47. #define SYSV            /* nice System V utmp interface still the same */
  48. #endif
  49.  
  50. #ifndef WTMP_FILE
  51. # define WTMP_FILE    "/usr/adm/wtmp"
  52. #endif
  53. #ifndef UTMP_FILE
  54. # define UTMP_FILE    "/etc/utmp"
  55. #endif
  56. #ifndef SYSV
  57. # ifndef SERVERS_FILE
  58. #  define SERVERS_FILE    "/usr/lib/X11/xdm/Xservers"
  59. # endif
  60. # ifndef TTYS_FILE
  61. #  define TTYS_FILE    "/etc/ttys"
  62. # endif
  63. #endif
  64.  
  65. #ifdef X_NOT_STDC_ENV
  66. extern long    time ();
  67. #endif
  68. #ifdef X_NOT_POSIX
  69. extern long    lseek ();
  70. extern char    *ttyname ();
  71. #endif
  72.  
  73. int    wflag, uflag, lflag;
  74. char    *wtmp_file, *utmp_file, *line;
  75. int    utmp_none, wtmp_none;
  76. /*
  77.  * BSD specific variables.  To make life much easier for Xstartup/Xreset
  78.  * maintainers, these arguments are accepted but ignored for sysV
  79.  */
  80. int    hflag, sflag, xflag, tflag;
  81. char    *host_name;
  82. int    slot_number;
  83. char    *xservers_file, *ttys_file;
  84. char    *user_name;
  85. int    aflag, dflag;
  86.  
  87. char    *program_name;
  88.  
  89. usage (x)
  90. {
  91.     if (x) {
  92.         fprintf (stderr, "%s: usage %s {-a -d} [-w wtmp-file] [-u utmp-file]\n", program_name, program_name);
  93.         fprintf (stderr, "             [-t ttys-file] [-l line-name] [-h host-name]\n");
  94.         fprintf (stderr, "             [-s slot-number] [-x servers-file] user-name\n");
  95.         exit (1);
  96.     }
  97.     return x;
  98. }
  99.  
  100. char *
  101. getstring (avp, flagp)
  102. char    ***avp;
  103. int    *flagp;
  104. {
  105.     char    **a = *avp;
  106.  
  107.     usage ((*flagp)++);
  108.     if (*++*a)
  109.         return *a;
  110.     ++a;
  111.     usage (!*a);
  112.     *avp = a;
  113.     return *a;
  114. }
  115.  
  116. syserr (x, s)
  117. int    x;
  118. char    *s;
  119. {
  120.     if (x == -1) {
  121.         perror (s);
  122.         exit (1);
  123.     }
  124.     return x;
  125. }
  126.  
  127. sysnerr (x, s)
  128. int    x;
  129. char    *s;
  130. {
  131.     if (x == 0) {
  132.         perror (s);
  133.         exit (1);
  134.     }
  135.     return x;
  136. }
  137.  
  138. main (argc, argv)
  139. int    argc;
  140. char    **argv;
  141. {
  142. #ifndef SYSV
  143.     int        utmp;
  144. #endif
  145.     char        *line_tmp;
  146.     int        wtmp;
  147.     long        current_time;
  148.     struct utmp    utmp_entry;
  149.  
  150.     program_name = argv[0];
  151.     while (*++argv && **argv == '-') {
  152.         switch (*++*argv) {
  153.         case 'w':
  154.             wtmp_file = getstring (&argv, &wflag);
  155.             if (!strcmp (wtmp_file, "none"))
  156.                 wtmp_none = 1;
  157.             break;
  158.         case 'u':
  159.             utmp_file = getstring (&argv, &uflag);
  160.             if (!strcmp (utmp_file, "none"))
  161.                 utmp_none = 1;
  162.             break;
  163.         case 't':
  164.             ttys_file = getstring (&argv, &tflag);
  165.             break;
  166.         case 'l':
  167.             line = getstring (&argv, &lflag);
  168.             break;
  169.         case 'h':
  170.             host_name = getstring (&argv, &hflag);
  171.             break;
  172.         case 's':
  173.             slot_number = atoi (getstring (&argv, &sflag));
  174.             break;
  175.         case 'x':
  176.             xservers_file = getstring (&argv, &xflag);
  177.             break;
  178.         case 'a':
  179.             aflag++;
  180.             break;
  181.         case 'd':
  182.             dflag++;
  183.             break;
  184.         default:
  185.             usage (1);
  186.         }
  187.     }
  188.     usage (!(user_name = *argv++));
  189.     usage (*argv != 0);
  190.     /*
  191.      * complain if neither aflag nor dflag are set,
  192.      * or if both are set.
  193.      */
  194.     usage (!(aflag ^ dflag));
  195.     usage (xflag && !lflag);
  196.     /* set up default file names */
  197.     if (!wflag)
  198.         wtmp_file = WTMP_FILE;
  199.     if (!uflag)
  200.         utmp_file = UTMP_FILE;
  201. #ifndef SYSV
  202.     if (!tflag)
  203.         ttys_file = TTYS_FILE;
  204.     if (!sflag) {
  205.         if (xflag)
  206.             sysnerr (slot_number = Xslot (ttys_file, xservers_file, line), "Xslot");
  207.         else
  208.             sysnerr (slot_number = ttyslot (), "ttyslot");
  209.     }
  210. #endif
  211.     if (!lflag) {
  212.         sysnerr ((int) (line_tmp = ttyname (0)), "ttyname");
  213.         line = rindex (line_tmp, '/');
  214.         if (line)
  215.             line = line + 1;
  216.         else
  217.             line = line_tmp;
  218.     }
  219.     current_time = time ((long *) 0);
  220.     set_utmp (&utmp_entry, line, user_name, host_name, current_time, aflag);
  221.     if (!utmp_none) {
  222. #ifdef SYSV
  223.         utmpname (utmp_file);
  224.         setutent ();
  225.         (void) getutid (&utmp_entry);
  226.         pututline (&utmp_entry);
  227.         endutent ();
  228. #else
  229.         utmp = open (utmp_file, O_RDWR);
  230.         if (utmp != -1) {
  231.             syserr ((int) lseek (utmp, (long) (slot_number - 1) * sizeof (struct utmp), 0), "lseek");
  232.             sysnerr (write (utmp, (char *) &utmp_entry, sizeof (utmp_entry))
  233.                         == sizeof (utmp_entry), "write utmp entry");
  234.             close (utmp);
  235.         }
  236. #endif
  237.     }
  238.     if (!wtmp_none) {
  239.         wtmp = open (wtmp_file, O_WRONLY|O_APPEND);
  240.         if (wtmp != -1) {
  241.             sysnerr (write (wtmp, (char *) &utmp_entry, sizeof (utmp_entry))
  242.                         == sizeof (utmp_entry), "write wtmp entry");
  243.             close (wtmp);
  244.         }
  245.     }
  246.     return 0;
  247. }
  248.  
  249. /*
  250.  * fill in the appropriate records of the utmp entry
  251.  */
  252.  
  253. set_utmp (u, line, user, host, date, addp)
  254. struct utmp    *u;
  255. char        *line, *user, *host;
  256. long        date;
  257. {
  258.     if (line)
  259.         (void) strncpy (u->ut_line, line, sizeof (u->ut_line));
  260.     else
  261.         bzero (u->ut_line, sizeof (u->ut_line));
  262.     if (addp && user)
  263.         (void) strncpy (u->ut_name, user, sizeof (u->ut_name));
  264.     else
  265.         bzero (u->ut_name, sizeof (u->ut_name));
  266. #ifdef SYSV
  267.     if (line) {
  268.         int    i;
  269.         /*
  270.          * this is a bit crufty, but
  271.          * follows the apparent conventions in
  272.          * the ttys file.  ut_id is only 4 bytes
  273.          * long, and the last 4 bytes of the line
  274.          * name are written into it, left justified.
  275.          */
  276.         i = strlen (line);
  277.         if (i >= sizeof (u->ut_id))
  278.             i -= sizeof (u->ut_id);
  279.         else
  280.             i = 0;
  281.         (void) strncpy (u->ut_id, line + i, sizeof (u->ut_id));
  282.     } else
  283.         bzero (u->ut_id, sizeof (u->ut_id));
  284.     if (addp) {
  285.         u->ut_pid = getppid ();
  286.         u->ut_type = USER_PROCESS;
  287.     } else {
  288.         u->ut_pid = 0;
  289.         u->ut_type = DEAD_PROCESS;
  290.     }
  291. #else
  292.     if (addp && host)
  293.         (void) strncpy (u->ut_host, host, sizeof (u->ut_host));
  294.     else
  295.         bzero (u->ut_host, sizeof (u->ut_host));
  296. #endif
  297.     u->ut_time = date;
  298. }
  299.  
  300. #ifndef SYSV
  301. /*
  302.  * compute the slot-number for an X display.  This is computed
  303.  * by counting the lines in /etc/ttys and adding the line-number
  304.  * that the display appears on in Xservers.  This is a poor
  305.  * design, but is limited by the non-existant interface to utmp.
  306.  */
  307.  
  308. Xslot (ttys_file, servers_file, display_name)
  309. char    *ttys_file;
  310. char    *servers_file;
  311. char    *display_name;
  312. {
  313.     FILE    *ttys, *servers;
  314.     int    c;
  315.     int    slot = 1;
  316.     int    column0 = 1;
  317.     char    servers_line[1024];
  318.     char    disp_name[512];
  319.     int    len;
  320.     char    *pos;
  321.  
  322.     /* remove screen number from the display name */
  323.     strcpy(disp_name, display_name);
  324.     pos = rindex(disp_name, ':');
  325.     if (pos) {
  326.         pos = index(pos, '.');
  327.         if (pos)
  328.         *pos = '\0';
  329.     }
  330.     sysnerr (ttys = fopen (ttys_file, "r"), ttys_file);
  331.     while ((c = getc (ttys)) != EOF)
  332.         if (c == '\n') {
  333.             ++slot;
  334.             column0 = 1;
  335.         } else
  336.             column0 = 0;
  337.     if (!column0)
  338.         ++slot;
  339.     (void) fclose (ttys);
  340.     sysnerr (servers = fopen (servers_file, "r"), servers_file);
  341.     len = strlen (disp_name);
  342.     column0 = 1;
  343.     while (fgets (servers_line, sizeof (servers_line), servers)) {
  344.         if (column0 && *servers_line != '#') {
  345.             if (!strncmp (disp_name, servers_line, len) &&
  346.                 (servers_line[len] == ' ' ||
  347.                  servers_line[len] == '\t'))
  348.                 return slot;
  349.             ++slot;
  350.         }
  351.         if (servers_line[strlen(servers_line)-1] != '\n')
  352.             column0 = 0;
  353.         else
  354.             column0 = 1;
  355.     }
  356.     return 0;
  357. }
  358. #endif
  359.