home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / adduser.c next >
Text File  |  1994-09-25  |  24KB  |  783 lines

  1. /*  adduser.c   Program to allow new user accounts to be added to the system.
  2.     Copyright (C) 1990, 1993  Mark Griffith and Bob Billson
  3.  
  4.     This file is part of the OS-9 UUCP package, UUCPbb.
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.     The author of UUCPbb, Bob Billson, can be contacted at:
  21.     bob@kc2wz.bubble.org  or  uunet!kc2wz!bob  or  by snail mail:
  22.     21 Bates Way, Westfield, NJ 07090
  23. */
  24.  
  25. /* Adds a new user to the system by updating the password file and
  26.    creating required user files.  Requires my LOGIN and PASSWORD
  27.    utilities to work correctly.
  28.  
  29.                        * * *  N O T I C E  * * *
  30.  
  31.                   This code assumes the use of Shell+
  32.                   Requires the Kreider library to compile
  33.  
  34.   Mark Griffith
  35.   DeLand, Fl.
  36.  
  37.   91 Jun        o Changes to Mark's code made by Bob Billson
  38.                      <uunet!kc2wz!bob> are indicated by 'REB' 
  39.  
  40.   ?? ??? ??     o Further changes made by Charles Ownes
  41.                      <trystro!czos9!chuck> to make it work more happily
  42.                      with Rick Adams' UUCP are indicated by 'CNO'.
  43.  
  44.              HINT:  If you edit /dd/sys/password by hand, be sure you don't
  45.                     add any extra carrige returns at the end of the file.
  46.                     Each line should end with one carrige return.  There
  47.                     should be no blank lines between entries.  If this 
  48.                     format is not adhered to, ADDUSER will not work
  49.                     properly.  -- CNO
  50.  
  51.   92 Oct 20     o Minor additions to allow compiling with the makefile in
  52.                      Rick Adams' UUCP.
  53.                 o Improved the way chk_uid() picks its own user id.
  54.                 o get_entries() now detects and reports blank lines in the
  55.                      password file.
  56.                 o User's login file script can now be customized. -- REB
  57.  
  58.   93 Feb 14     o User name can now be given on the command line -- REB
  59.  
  60.   93 Sep 4      o Special processing for user named 'daemon' --REB
  61.  
  62.   94 Mar 30     o Added -s option for super user, fixed for OSK -- BGP
  63. */
  64.  
  65. #define MAIN
  66.  
  67. /* To compile for UUCPbb, make the next line '#undef  MARK'
  68.    To compile for Mark's original,  make the next line '#define MARK'  */
  69.  
  70. #undef  MARK
  71.  
  72. /* To send certain login messages to the Speech Sound Pak, make the next
  73.    line '#define SSP'.  ***NOTE*** do this only if you ALWAYS have the SSP in
  74.    place.
  75.  
  76.    If you do NOT wish to send messages to the SSP, make the next line
  77.    '#undef SSP' -- CNO  */
  78. #undef  SSP
  79.  
  80. #ifndef MARK
  81. #include "uucp.h"                                     /* default to Rick's */
  82. #else                                                 /* uucp -- REB       */
  83. #include <stdio.h>
  84. #include <string.h>
  85. #endif
  86. #include <modes.h>
  87. #include <ctype.h>                                    /* Added -- REB */
  88. #include <password.h>
  89. #include <sgstat.h>
  90.  
  91. /* Defines for password file array */
  92.  
  93. #define   NAME      0         /* User name */
  94. #define   PASS      1         /* User password */
  95. #define   ID        2         /* User ID */
  96. #define   PRI       3         /* User priority */
  97. #define   DIRX      4         /* Execution directory */
  98. #define   DIRW      5         /* Working directory */
  99. #define   CMD       6         /* first command to run */
  100. #define   PW_SIZE   7         /* Number of entries */
  101. #define   ON        1
  102. #define   OFF       0
  103.  
  104. /* made direct page -- REB */
  105. QQ char *daemon = "daemon",
  106.         *Sorry = "Sorry, only the Superuser can use this utility!",
  107.         *NewID = "Enter new user ID number\n    ('Q' to quit) or press <ENTER> and I'll pick: ";
  108.  
  109. /*  Change the filenames below as needed ONLY if compiling for Mark's version.
  110.     For UUCPbb: userdir, maildir and logdir are defined in uucp.h PASSWORD and
  111.     PWEMAX are defined in password.h -- REB  */
  112.  
  113. #ifdef MARK
  114. QQ char *userdir  = "/DD/USR",              /* default user directory */
  115.         *logdir   = "/DD/LOG",              /* default user log file */
  116.         *maildir  = "/DD/MAIL";             /* default mail directory */
  117. #else
  118. QQ char *userdir  = USERDIR;
  119. #endif
  120.  
  121. /* these apply to both UUCPbb and Mark's version */
  122. QQ char *passfile = PASSWORD,               /* default password file */
  123.         *motd     = "/DD/SYS/motd";         /* location of motd file */
  124.  
  125. char   pw[PW_SIZE][30],
  126.        tempstr[256], dirname[256],
  127.        u_name[PWEMAX][20],
  128.        mailname[256];                         /* added -- REB */
  129. flag   isdaemon = FALSE;                      /*              */
  130.  
  131. unsigned u_uid[PWEMAX];
  132. #ifdef _OSK
  133. QQ int super = 256;
  134. #else
  135. QQ int super = 1;         /* added -- BGP for super user creation */
  136. #endif
  137. QQ int entries = 0;                        /* made direct page -- REB */
  138. QQ FILE *fp;                               /*                         */
  139. QQ PWENT *entry;                           /*                         */
  140.  
  141.  
  142. main (argc, argv)
  143. int argc;
  144. char *argv[];
  145. {
  146.      register int i;                                /* made register -- REB */
  147.      int path, uloginpath;
  148.      flag ipickit;                                  /* added --REB */
  149.      unsigned userid;
  150.      char *p;
  151.  
  152.      /* Get the user's userid */
  153.      /* Must be the superuser to add a new user */
  154.  
  155.      if ( getuid() )
  156.           exit (_errmsg (0, "%s\n", Sorry));
  157.  
  158.      /* need help? */
  159.      if (argc > 3 || strcmp (argv[1], "-?") == 0)
  160.           usage();
  161.  
  162.      *tempstr = '\0';
  163.  
  164. #ifndef MARK
  165.      if ((maildir = getenv ("MAIL")) != NULL)
  166.           maildir = strdup (maildir);
  167.      else
  168.           fatal ("MAIL is undefined");
  169.  
  170.      if ((logdir = getenv ("LOGDIR")) != NULL)
  171.           logdir = strdup (logdir);
  172.      else
  173.           logdir = LOGDIR;
  174. #endif
  175.      /* allow creation of super users? */
  176.      if (argc >= 2   &&  strcmp (argv[1], "-s") == 0)
  177.        {
  178.           if (argc == 3)
  179.               strcpy (tempstr, argv[2]);
  180.           argc = 1;          /* so that we don't get caught later on -- BGP */
  181.           super = 0;
  182.        }
  183.  
  184.      /* delete a local user? */
  185.      if (argc >= 2  &&  strcmp (argv[1], "-r") == 0)
  186.           if (argc == 3)
  187.                removeuser (argv[2]);
  188.           else
  189.             {
  190.                fputs ("adduser: -r requires a username\n\n", stderr);
  191.                usage();
  192.             }
  193.  
  194.      /* Set up some default password file entries -- edit as you require */
  195.      strcpy (pw[PRI], "128");
  196.      strcpy (pw[DIRX], "/dd/cmds");
  197.      strcat (strcpy (pw[DIRW], userdir), "/");
  198.      strcpy (pw[PASS], "000000");
  199.      get_entries();                          /* read the password file */
  200.  
  201.      /* user name given on command line? --REB */
  202.      if (argc >= 2)
  203.           strcpy (tempstr, argv[1]);
  204.  
  205.      /* Get the new username.  If they enter a 'Q', end the program.
  206.         Otherwise, check to see if the username is already used.  If it is,
  207.         ask them for another one. */
  208.      do
  209.        {
  210.           while (*tempstr == '\0')
  211.             {
  212.                printf ("\nEnter username (Q to quit): ");
  213.                fflush (stdout);
  214.  
  215.                if (mfgets (tempstr, sizeof (tempstr), stdin) == NULL)
  216.                  {
  217.                     errno = 0;
  218.                     fatal ("<ESC> hit...exiting");
  219.                  }
  220.             }
  221.  
  222.           if (*tempstr == 'Q'  ||  *tempstr == 'q')
  223.                exit (0);
  224.        }
  225.      while ( chk_name() );                     /* name already in use? */
  226.  
  227.      if (strucmp (tempstr, daemon) == 0)       /* user 'daemon' is special */
  228.           isdaemon = TRUE;
  229.  
  230.      strcat (pw[DIRW], tempstr);
  231.      strcpy (pw[NAME], tempstr);
  232.  
  233.      /* user ID given on command line? --REB */
  234.      if (argc == 3)
  235.           strcpy (tempstr, argv[2]);
  236.      else
  237.           *tempstr = '\0';
  238.  
  239.      /* Get the new user ID number -- make my own if user enters nothing
  240.         changed -- REB */
  241.      putchar ('\n');
  242.      do
  243.        {
  244.           if (*tempstr == '\0')
  245.             {
  246.                fputs (NewID, stdout);
  247.                fflush (stdout);
  248.  
  249.                if (mfgets (tempstr, sizeof (tempstr), stdin) == NULL)
  250.                  {
  251.                     errno = 0;
  252.                     fatal ("<ESC> hit...exiting");
  253.                  }
  254.  
  255.                if (*tempstr == 'Q'  ||  *tempstr == 'q')
  256.                     exit (0);
  257.                else if (*tempstr == '\0')
  258.                     ipickit = TRUE;
  259.                else
  260.                     ipickit = FALSE;
  261.             }
  262.           else
  263.                ipickit = FALSE;
  264.  
  265. #ifndef _OSK
  266.           userid = (unsigned) atoi (tempstr);
  267. #else
  268.           userid = (unsigned) uIDtoInt (tempstr);
  269. #endif
  270.        }
  271.      while (chk_uid (&userid, ipickit));
  272.  
  273. #ifdef _OSK
  274.      p = InttouID (userid);
  275.      strcpy (pw[ID], p);
  276.      free (p);
  277. #else
  278.      sprintf (pw[ID], "%u", userid);
  279. #endif
  280.      printf ("\nAdding new user '%s' as UID %s\n", pw[NAME], pw[ID]);
  281.  
  282.      /* Create user login file */
  283.      sprintf (tempstr, "%s/%s.login", logdir, pw[NAME]);
  284.  
  285.      if ((path = create (tempstr, S_IREAD+S_IWRITE, S_IREAD+S_IWRITE)) == ERROR)
  286.        {
  287.          sprintf (tempstr, "%s.login already exists\n", pw[NAME]);
  288.          fatal (tempstr);
  289.        }
  290.  
  291.      close (path);
  292.  
  293.      /* Open and add user data to password file */
  294.      if ((fp = fopen (passfile, "a")) == NULL)
  295.           fatal ("can't open password file");
  296.  
  297.      for (i = 0; i < (PW_SIZE - 1); i++)
  298.           fprintf (fp, "%s,", pw[i]);
  299.  
  300.      /* Create the commands the user will use after logging in.
  301.         Changed --REB */
  302. #ifndef _OSK
  303. #  ifdef SHELLPLUS
  304.      /* turn off Shell+ shell variable expansion so MAIL works properly make
  305.         prompt user's name -- REB */
  306.  
  307.      fprintf (fp, "ulogin; ex shell -v p=\"%s\"\n", pw[NAME]);
  308. #  else
  309.      fprintf (fp, "ulogin;ex shell\n");
  310. #  endif
  311. #else
  312.      fprintf (fp, "ulogin;ex shell\n");
  313. #endif
  314.      fclose (fp);
  315.  
  316.      /* Create user directory with owner bits only set. */
  317.      strcpy (tempstr, pw[NAME]);
  318.      sprintf (dirname, "%s/%s", userdir, strupr (tempstr));
  319.      setuid (atoi (pw[ID]));                      /* set uid to new user */
  320.  
  321.      if ((mknod (dirname, S_IREAD+S_IWRITE+S_IEXEC)) == ERROR)
  322.        {
  323.           sprintf (tempstr, "can't create user's home directory...error %d\n",
  324.                    errno);
  325.           fatal (tempstr);
  326.        }
  327.  
  328. #ifndef _OSK
  329.      /* CoCo user needs a UUCP directory in their home directory for UUCPbb */
  330.      sprintf (tempstr, "%s/UUCP", dirname);
  331.  
  332.      if ((mknod (tempstr, S_IREAD+S_IWRITE+S_IEXEC)) == ERROR)
  333.        {
  334.           sprintf (tempstr, "can't create user's home UUCP directory...error %d\n",
  335.                             errno);
  336.           fatal (tempstr);
  337.        }
  338. #endif
  339.  
  340.      /* Create user mail directory with owner bits only set.  Mail directory
  341.         is compatible with UUCPbb --REB */
  342.  
  343.      /* user 'daemon' does not need a mail directory */
  344.      if (!isdaemon)
  345.        {
  346.           strcpy (tempstr, pw[NAME]);
  347.           sprintf (mailname, "%s/%s", maildir, strupr (tempstr));
  348.  
  349.           if ((mknod (mailname, S_IREAD+S_IWRITE+S_IEXEC)) == ERROR)
  350.             {
  351.                sprintf (tempstr,
  352.                         "can't create user's mail directory '%s'...error %d\n",
  353.                         mailname, errno);
  354.                fatal (tempstr);
  355.             }
  356.        }
  357.  
  358.      /*  Setup users login file in their directory */
  359.      sprintf (tempstr, "%s/%s/ulogin", userdir, pw[NAME]);
  360.  
  361.      /* changed -- REB */
  362.      if ((uloginpath = create (tempstr, S_IWRITE, S_IREAD+S_IWRITE)) == ERROR)
  363.        {
  364.           sprintf (tempstr, "Can't create user's ulogin file '%s'...error %d\n",
  365.                   tempstr, errno);
  366.           fatal (tempstr);
  367.        }
  368.  
  369.      /* now turn the path number in a file descriptor for writing -- REB */
  370.      if ((fp = fdopen (uloginpath, "w")) == NULL)
  371.           fatal ("can't create user's 'ulogin' file");
  372.  
  373.      asetuid (0);                              /* set uid back to SuperUser */
  374.  
  375.      /* create user's ulogin file...moved -- REB */
  376.      make_ulogin (fp);
  377.  
  378.      /* make sure all I/O is flushed and chop off any junk at the end
  379.         before we close the file -- REB */
  380.  
  381.      fflush (fp);
  382.      _ss_size (uloginpath, ftell (fp));
  383.      fclose (fp);
  384.  
  385.      printf ("\n\nUser '%s' has been added to the system\n\n", pw[NAME]);
  386.      printf ("**NOTE** the password for user '%s' is NOT set right now.\n",
  387.               pw[NAME]);
  388.      puts ("         You must use the utility PASSWORD to set it.\n");
  389.      free (maildir);
  390.      free (logdir);
  391.      exit (0);
  392. }
  393.  
  394.  
  395.  
  396. /*  Read the password file getting all the usernames and UID there. */
  397.  
  398. int get_entries()
  399. {
  400.      register char *p;
  401.      char tmpstr[PWSIZ];
  402.      int line, badline;
  403.  
  404.      p = tmpstr;
  405.      line = 0;
  406.      badline = FALSE;
  407.  
  408.      if ((fp = fopen (passfile, "r")) == NULL)
  409.        {
  410.           sprintf (tempstr, "can't open password file...error %d\n", errno);
  411.           fatal (tempstr);
  412.        }
  413.  
  414.      while (fgets (p, sizeof (tmpstr), fp) != NULL)
  415.        { 
  416.           ++line;
  417.  
  418.           if (*p == '\n')
  419.             {
  420.                fputs ("adduser: illegal password entry...line", stderr);
  421.                fprintf (stderr, "%d starts with a CR.\n", line);
  422.                badline = TRUE;
  423.             }
  424.        }
  425.      fclose (fp);
  426.  
  427.      if (badline)
  428.        {
  429.           fputs ("There cannot be blank lines anywhere in the ", stderr);
  430.           fputs ("password file.  These lines must\nbe fixed ", stderr);
  431.           fputs ("fixed before continuing.\n", stderr); 
  432.           exit (0);
  433.        }
  434.  
  435.      while((entry = getpwent()) != NULL)
  436.        {
  437.           if (entry == (PWENT *)ERROR)
  438.                fatal ("error in the password file!");
  439.  
  440.           strcpy (u_name[entries], entry->unam);
  441. #ifndef OSK
  442.           u_uid[entries++] = (unsigned) atoi (entry->uid);
  443. #else
  444.           u_uid[entries++] = (unsigned) uIDtoInt (entry->uid);
  445. #endif
  446.        }
  447.      endpwent();
  448. }
  449.  
  450.  
  451.  
  452. /*  Check password file entries. If 'ipickit' is FALSE, see if there is a
  453.     UID of the same number already used.  If 'ipickit' is TRUE, pick the 
  454.     next highest available UID.  If all the UID (0-255) are picked, exit
  455.     with an error.  Global variable 'tempstr' has the user ID to be checked
  456.     on entry.  If the user ID is already used, we exit with 'tempstr' set
  457.     to a NULL string. -- REB  */
  458.  
  459. int chk_uid (uid, ipickit)
  460. int ipickit;
  461. unsigned *uid;
  462. {
  463.      register int i;                            /* made register -- REB */
  464.      unsigned j;                                /* added -- REB */
  465.  
  466.      /* UID was passed to us, is it taken? */
  467.      if (!ipickit)
  468.        {
  469.           for (i = 0; i < entries; i++)
  470.                if (*uid == u_uid[i])
  471.                  {
  472.                     fprintf (stderr, "\nUID '%d' is already used\n\n", *uid);
  473.                     *tempstr = '\0';
  474.                     return (TRUE);
  475.                  }
  476.           return (FALSE);
  477.        }
  478.      else
  479.        {
  480.          /* we have to pick the UID.  find the lowest unused one */
  481.          for (j = super; j < 65536; ++j)
  482.            {
  483.                for (i = 0; i < entries; i++)
  484.                     if (j == u_uid[i])
  485.                          break;
  486.  
  487.                /* didn't find a match, this is our UID */
  488.                if (i == entries)
  489.                  {
  490.                     *uid = j;
  491.                     return (FALSE);
  492.                  }
  493.             }
  494.  
  495.           /* all 65535 user IDs are taken (wow!) */
  496.           fatal ("all user IDs are used");
  497.        }
  498. }
  499.  
  500.  
  501.  
  502. /*  Check the password file entries and see if the username entered is
  503.     already in the file.  global variable 'tempstr' has the username on
  504.     entry.  */
  505.  
  506. int chk_name()
  507. {
  508.      register int i;                           /* made register -- REB */
  509.  
  510.      for (i = 0; i < entries; i++)
  511.           if ((strucmp (tempstr, u_name[i])) == 0)
  512.             {
  513.                fprintf (stderr, "\nUsername '%s' already exists\n", tempstr);
  514.  
  515.                if (strucmp (tempstr, daemon) == 0)
  516.                     exit (0);
  517.                else
  518.                     *tempstr = '\0';
  519.  
  520.                return (TRUE);
  521.             }
  522.      return (FALSE);
  523. }
  524.  
  525.  
  526.  
  527. /* make the user's ulogin file...expanded -- REB */
  528.  
  529. int make_ulogin (fptr)
  530. FILE *fptr;
  531. {
  532.      char script[256], answer, get_yn();
  533.      int done = FALSE;
  534.  
  535.      /* user 'daemon' has a really short login script */
  536.      if (isdaemon)
  537.        {
  538.           fputs ("echo daemon is logged in; echo", fptr);
  539.           return (0);
  540.        }
  541.  
  542.      while (!done)
  543.        {
  544.           /* start script */
  545.           fprintf (fptr, "* Login file for %s *\n", pw[NAME]);
  546.  
  547.  
  548.           cls();
  549.           printf ("Do you wish to customize %s's login script?\n", pw[NAME]);
  550.           fputs ("     (NO means use default script)       y/n --> ", stdout);
  551.           fflush (stdout);
  552.           answer = get_yn();
  553.  
  554.           /* customize our own ulogin script */
  555.           if (answer == 'y')
  556.             {
  557.                cls();
  558.                printf ("                           ");
  559.                ReVOn();
  560.                printf (" Customize ulogin script ");
  561.                ReVOff();
  562.                puts ("\nEnter commands one line at time.  Check for waiting mail has already been");
  563.                puts ("included at the beginning of the script.\n");
  564.                puts ("<ENTER> only for any line ends the customizing.  If you make a mistake, end");
  565.                fputs ("customizing and answer 'N' (no) to 'Script okay?' prompt.  You may then start\nover.\n", stdout);
  566. #ifdef SSP
  567.                puts ("\nYou may send text to the Speech Sound Pak by redirecting it.  For example:");
  568.                puts ("     echo hi there >/ssp");
  569. #endif
  570.                fputs ("\nHit <ENTER> to begin --> ", stdout);
  571.                fflush (stdout);
  572.                answer = getchar();
  573.                cls();
  574.                ReVOn();
  575.                fputs (" ulogin script so far: ", stdout);
  576.                ReVOff();
  577.                puts ("\n");
  578.  
  579.                /* put in the standard stuff */
  580.                fputs ("-x\n", fptr);
  581.                puts ("-x");
  582.                fprintf (fptr, "list %s\n", motd);
  583.                printf ("list %s\n", motd);
  584.                fputs ("echo\n", fptr);
  585.                puts ("echo");
  586. #ifndef SSP
  587.                fprintf (fptr, "echo Hello %s\n", pw[NAME]);
  588.                printf ("echo Hello %s\n", pw[NAME]);
  589. #else
  590.                /* Send 'hello <name>' to speech pak if SSP is set -- CNO */
  591.                fprintf (fptr, "echo Hello %s >/ssp&\n", pw[NAME]);
  592.                printf ("echo Hello %s >/ssp&\n", pw[NAME]);
  593. #endif
  594.                /* This line is specific to the mail utility packaged with the
  595.                   OS9 uucp port.  Added code for Rick Adams' UUCP
  596.                   enhancements -- REB */
  597. #ifdef MARK
  598.                fputs ("lmail -c\n", fptr);          /* Mark's original UUCP */
  599.                puts ("lmail -c");
  600. #else
  601.                fputs ("mailx -c\n", fptr);          /* Rick Adams' UUCP */
  602.                puts ("mailx -c");
  603. #endif
  604.                putchar ('\n');
  605.                ReVOn();
  606.                printf (" Continue script... ");
  607.                ReVOff();
  608.                puts("\n");
  609.  
  610.                for (;;)
  611.                  {
  612.                     fgets (script, sizeof (script), stdin);
  613.  
  614.                     if (*script == '\n')
  615.                          break;
  616.                     else
  617.                          fputs (script, fptr);
  618.                  }
  619.  
  620.                fputs ("\nScript okay?  (y/n) --> ", stdout);
  621.                fflush (stdout);
  622.                answer = get_yn();
  623.  
  624.                if (answer == 'y')
  625.                     done = TRUE;
  626.                else
  627.                     rewind (fptr);               /* try again */
  628.             }
  629.           else
  630.             {
  631.                /* make the default login script */
  632.                fputs ("-x\n", fptr);
  633.                fprintf (fptr, "list %s\n", motd);
  634.                fputs("x\n", fptr);
  635.                fputs ("echo\n", fptr);
  636. #ifndef SSP
  637.                fprintf (fptr, "echo Hello %s\n", pw[NAME]);
  638. #else
  639.                /* Send 'hello <name>' to speech pak if SSP is set -- CNO */
  640.                fprintf (fptr, "echo Hello %s >/ssp&\n", pw[NAME]);
  641. #endif
  642.                /* This line is specific to the mail utility packaged with the
  643.                   OS9 uucp port.  Added code for Rick Adams' UUCP enhancement
  644.                   -- REB */
  645. #ifdef MARK
  646.                fputs ("lmail -c\n", fptr);        /* Mark's original mailer */
  647. #else
  648.                fputs ("mailx -c\n", fptr);        /* UUCPbb */
  649. #endif
  650.                fputs ("echo\n", fptr);
  651.                fputs ("echo Please use the 'bye' command to log off\n\n",
  652.                       fptr);
  653.                done = TRUE;
  654.             }
  655.        }
  656.      fputs ("* End of Script *\n", fptr);
  657.      return (0);
  658. }
  659.  
  660.  
  661.  
  662. /* get a single character response from the user.  Added --REB */
  663.  
  664. char get_yn()
  665. {
  666.      char answer;
  667.  
  668.      echo (OFF);
  669.  
  670.      for (;;)
  671.        {
  672.           while (_gs_rdy (0) <= 0)
  673.                tsleep (4);
  674.  
  675.           read (0, &answer, 1);
  676.           answer &= 0xff;
  677.           answer = tolower (answer);
  678.  
  679.           if (answer == 'y' ||  answer == 'n')
  680.             {
  681.                putchar (answer);
  682.                break;
  683.             }
  684.        }
  685.  
  686.      echo (ON);
  687.      return (answer);
  688. }
  689.  
  690.  
  691.  
  692. /* Turn off or on echo on the standard input path --REB */
  693.  
  694. int echo (onoroff)
  695. int onoroff;
  696. {
  697.      struct sgbuf stdinpath;
  698.  
  699.      _gs_opt (1, &stdinpath);
  700.      stdinpath.sg_echo = onoroff;             /* switch standard input echo */
  701.      _ss_opt (1, &stdinpath);                 /* update the path descriptor */
  702. }
  703.  
  704.  
  705.  
  706. /* Convert a string to upper case.  Returns a pointer to the start of the
  707.    string.  --REB  */
  708.  
  709. char *strupr (string)
  710. char *string;
  711. {
  712.      register char *p;
  713.  
  714.      p = string;
  715.      while (*p)
  716.        {
  717.           *p = toupper (*p);
  718.           ++p;
  719.        }
  720.      return (string);
  721. }
  722.  
  723.  
  724.  
  725. int usage()
  726. {
  727.      char temp[80], *strdetab();
  728.      register char **use;
  729.      static char *usetext[] = {
  730.             "ADDUSER: add a user to or remove a user from the system",
  731.             "Usage: adduser [opts] [<username> [<userid>] ]",
  732.             " ",
  733.             "opts: -r <username>  - remove <username> from the system",
  734.             "      -s  - allow the creation of super users",
  735.             "\t-?\t\t - this message",
  736.             " ",
  737.             "\tacceptable command lines are:",
  738.             "\t   adduser",
  739.             "\t   adduser <username>",
  740.             "\t   adduser <username> <userid>",
  741.             "\t   adduser -r <username>",
  742.             "\t   adduser -s <username>",
  743.             NULL
  744.          };
  745.  
  746.      for (use = usetext; *use != NULL; ++use)
  747.           fprintf (stderr, " %s\n", strdetab (strcpy (temp, *use), 6));
  748.  
  749.      fprintf (stderr, "\nv%s (%s) This is free software released under the GNU General Public\n",
  750.                       version, VERDATE);
  751.      fputs ("License.  Please send suggestions/bug reports to:  bob@kc2wz.bubble.org\n", stderr);
  752.      exit (0);
  753. }
  754.  
  755.  
  756.  
  757. int fatal (msg)
  758. char *msg;
  759. {
  760.      fprintf (stderr, "adduser: %s", msg);
  761.  
  762.      if (errno != 0)
  763.          fprintf (stderr, "...error %d", errno);
  764.  
  765.      putc ('\n', stderr);
  766.      exit (0);
  767. }
  768.  
  769.  
  770.  
  771. int removeuser (username)
  772. char *username;
  773. {
  774.      userbegone (username);
  775.      fatal ("removing user is not implemented yet");
  776. }
  777.  
  778.  
  779.  
  780. int userbegone (name)
  781. {
  782. }
  783.