home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume20 / rc.user < prev    next >
Text File  |  1989-09-17  |  8KB  |  321 lines

  1. Subject:  v20i007:  Allow users to automatically run scripts at boot time
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: sgrimm@sun.com (Steven Grimm)
  7. Posting-number: Volume 20, Issue 7
  8. Archive-name: rc.user
  9.  
  10. This utility package allows users to run shell scripts automatically
  11. at system boot time.  This is useful for everything from restarting
  12. servers (in fact, I developed it for use with the superserver program
  13. appearing here not too long ago) to sending mail notification of
  14. system reboots.  The user interface is similar to Sun's crontab.
  15.  
  16. ---
  17. Steven Grimm                koreth@ssyx.ucsc.edu
  18. Division of Social Sciences        uunet!ucbvax!ucscc!ssyx!koreth
  19. University of California, Santa Cruz    "Pithy quotes are for losers."
  20.  
  21. #!/bin/sh
  22. # shar:    Shell Archiver  (v1.22)
  23. #
  24. #    Run the following text with /bin/sh to create:
  25. #      Makefile
  26. #      rc.users
  27. #      rcuser.1
  28. #      rcuser.c
  29. #
  30. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  31. X#
  32. X# rcuser
  33. X#
  34. X# Installation:
  35. X#
  36. X# Edit this Makefile and rcuser.c to suit your site.
  37. X# Run "make install" as root.
  38. X# Then edit your /etc/rc.local (or other startup script) so that
  39. X#  /etc/rc.users is run at boot time.  Usually you will want it to
  40. X#  be run fairly late in the boot process, in case users want to
  41. X#  talk to other system daemons, etc.  (This could be done by make
  42. X#  install, but it's probably best not to go tweaking peoples'
  43. X#  rc files...)
  44. X#
  45. X
  46. XCFLAGS = -O -s
  47. XBINDIR = /usr/local
  48. X
  49. X# Change this if you want the rc files to be somewhere other than
  50. X# /usr/lib/rc.
  51. XRCDIR = /usr/lib/rc
  52. X
  53. Xrcuser: rcuser.c
  54. X    $(CC) -DRCDIR=\"$(RCDIR)/\" $(CFLAGS) rcuser.c -o $@
  55. X
  56. Xinstall: rcuser
  57. X    install -m 4711 rcuser $(BINDIR)
  58. X    install -c -m 644 rc.users /etc
  59. X    -mkdir $(RCDIR)
  60. X    chmod 755 $(RCDIR)
  61. X    @echo "Remember to edit /etc/rc.local to run /etc/rc.users"
  62. X
  63. Xclean:
  64. X    -/bin/rm -f core rcuser *.o
  65. SHAR_EOF
  66. chmod 0600 Makefile || echo "restore of Makefile fails"
  67. sed 's/^X//' << 'SHAR_EOF' > rc.users &&
  68. X#!/bin/sh
  69. X# Run all the user scripts in /usr/lib/rc.
  70. X
  71. Xcd /usr/lib/rc
  72. X
  73. Xexport USER
  74. X
  75. Xfor USER in *
  76. Xdo
  77. X(
  78. X    /bin/su -f $USER -c "/bin/sh $USER" >/tmp/#rc.$USER 2>&1 </dev/null
  79. X    if test -s /tmp/#rc.$USER; then
  80. X        (echo "Output from your startup file at `date`"; echo "";
  81. X        cat /tmp/#rc.$USER) | mail $USER
  82. X    fi
  83. X    /bin/rm /tmp/#rc.$USER
  84. X) &
  85. Xdone
  86. SHAR_EOF
  87. chmod 0600 rc.users || echo "restore of rc.users fails"
  88. sed 's/^X//' << 'SHAR_EOF' > rcuser.1 &&
  89. X.TH RCUSER 1 "29 March 1988" "Koreth's Nifty Utilities"
  90. X.SH NAME
  91. Xrcuser \- manipulate user system startup files
  92. X.SH SYNOPSIS
  93. X\fBrcuser\fR [\fB\-e\fR|\fB\-l\fR|\fB\-d\fR|\fB\-t\fR [\fIusername\fR]]
  94. X.SH DESCRIPTION
  95. X\fIRcuser\fR allows users to maintain shell scripts which are executed at
  96. Xsystem startup time.  Users' startup scripts are stored in a system directory
  97. X(\fI/usr/lib/rc\fR by default), in filenames matching the usernames of their
  98. Xowners.  Startup files are executed by
  99. X.IR sh (1).
  100. X.LP
  101. XAny output from the users' scripts are mailed to them.
  102. X.LP
  103. XThe superuser may specify a username on the command line; that user's file
  104. Xwill be manipulated.  If no username is specified or \fIrcuser\fR is not
  105. Xinvoked by the superuser, the current user's login name is used.
  106. X.SH OPTIONS
  107. X.IP \-e
  108. XEdit a startup file.  The environment variable VISUAL is used if it exists;
  109. Xotherwise a default editor
  110. X.RI ( vi (1))
  111. Xis used.  If a startup file
  112. Xdoes not exist, it is created by \fIrcuser\fR before the editor is invoked.
  113. X.IP \-l
  114. XList a startup file.  The startup file is copied to standard output, using
  115. X.IR cat (1).
  116. XThis is the default action if no flags are specified on the command line.
  117. X.IP \-d
  118. XDelete a startup file.
  119. X.IP \-t
  120. XTest a startup file.  The file is executed the same way it would be at
  121. Xsystem startup time.  If it doesn't exit fairly quickly and without
  122. Xproducing output, something is probably wrong.  Note that startup files
  123. Xare run with minimal environment strings; this environment is duplicated
  124. Xby \fIrcuser\fR.
  125. X.SH FILES
  126. X.IP /usr/lib/rc
  127. XUser startup directory
  128. X.IP /etc/rc.local
  129. XSystem startup script
  130. X.IP /etc/rc.users
  131. XRuns user startup scripts
  132. X.SH "SEE ALSO"
  133. Xcat(1), vi(1)
  134. X.SH AUTHOR
  135. XSteven Grimm, koreth@ssyx.ucsc.edu
  136. SHAR_EOF
  137. chmod 0600 rcuser.1 || echo "restore of rcuser.1 fails"
  138. sed 's/^X//' << 'SHAR_EOF' > rcuser.c &&
  139. X/*
  140. X** rcuser -- allow users to perform functions at startup time
  141. X**
  142. X** by Steven Grimm, koreth@ssyx.ucsc.edu
  143. X** 3-29-89
  144. X*/
  145. X
  146. X/* Default editor, if VISUAL environment variable isn't set */
  147. X#define VISUAL    "/usr/ucb/vi"
  148. X
  149. X/* Command to display a file */
  150. X#define DISPLAY    "/bin/cat"
  151. X
  152. X/*
  153. X** Command shell to test scripts with.  This should be the same
  154. X** shell that's invoked for user scripts in rc.users.
  155. X*/
  156. X#define SHELL "/bin/sh"
  157. X
  158. X#include <pwd.h>
  159. X#include <stdio.h>
  160. X#include <errno.h>
  161. X#include <sys/file.h>
  162. X#include <sys/param.h>
  163. X
  164. X/* The username and id that we're working on behalf of. */
  165. Xchar *username;
  166. Xint  uid;
  167. Xstruct passwd *pent;
  168. X
  169. Xchar *malloc();
  170. X
  171. X/*
  172. X** Get a user's uid and, if necessary, name
  173. X*/
  174. Xgetuser(name)
  175. Xchar *name;
  176. X{
  177. X    if (name == NULL)
  178. X    {
  179. X        uid = getuid();
  180. X        pent = getpwuid(uid);
  181. X        if (pent != NULL)
  182. X            username = pent->pw_name;
  183. X    }
  184. X    else
  185. X    {
  186. X        username = name;
  187. X        pent = getpwnam(name);
  188. X        if (pent != NULL)
  189. X            uid = pent->pw_uid;
  190. X    }
  191. X}
  192. X
  193. X/*
  194. X** Print an error and exit.
  195. X*/
  196. Xpanic(err)
  197. Xchar *err;
  198. X{
  199. X    perror(err);
  200. X    exit(-1);
  201. X}
  202. X
  203. X/*
  204. X** Print usage and exit.
  205. X*/
  206. Xusage(name)
  207. Xchar *name;
  208. X{
  209. X    fprintf(stderr,"Usage: %s [-l|-e|-d] [user]\n", name);
  210. X    fprintf(stderr,"\t-l - show startup script\n");
  211. X    fprintf(stderr,"\t-e - edit startup script\n");
  212. X    fprintf(stderr,"\t-d - delete startup script\n");
  213. X    fprintf(stderr,"\t-t - test startup script\n");
  214. X    fprintf(stderr,"\n\tusername may only be specified by superuser\n");
  215. X    exit(-1);
  216. X}
  217. X
  218. X/*
  219. X** Create a file, owned by the appropriate user.
  220. X*/
  221. Xcreate(file, uid)
  222. Xchar *file;
  223. Xint uid;
  224. X{
  225. X    int fd;
  226. X
  227. X    fd = open(file, O_WRONLY|O_CREAT, 0600);
  228. X    if (fd == -1)
  229. X        panic(file);
  230. X
  231. X    close(fd);
  232. X    
  233. X/* fchown() is a BSDism */
  234. X    chown(file, uid, -1);
  235. X}
  236. X
  237. Xmain(argc, argv)
  238. Xint argc;
  239. Xchar **argv;
  240. X{
  241. X    char function, filename[MAXPATHLEN], *editor, *getenv();
  242. X
  243. X    if (argc < 2)
  244. X    {
  245. X        getuser(NULL);
  246. X        function = 'l';
  247. X    } else
  248. X        if (argv[1][0] != '-')
  249. X            usage(argv[0]);
  250. X        else
  251. X            switch(argv[1][1]) {
  252. X            case 'l':
  253. X            case 'e':
  254. X            case 'd':
  255. X            case 't':
  256. X                function = argv[1][1];
  257. X                break;
  258. X            default:
  259. X                usage(argv[0]);
  260. X            }
  261. X
  262. X/* If a username is given on the command line, and we are superuser, use it. */
  263. X    if (argc == 3 && getuid() == 0)
  264. X        getuser(argv[2]);
  265. X    else
  266. X        getuser(NULL);
  267. X
  268. X/* Construct the name of the appropriate user's startup file. */
  269. X    strcpy(filename, RCDIR);
  270. X    strncat(filename, username, sizeof(filename)-sizeof(RCDIR)-1);
  271. X
  272. X/* Now, if the function requires it, create the file if it doesn't exist. */
  273. X    if (function == 'e' && access(filename, F_OK) == -1)
  274. X        if (errno == ENOENT)
  275. X            create(filename, uid);
  276. X        else
  277. X            panic(filename);
  278. X
  279. X/* Delete the file if necessary/possible. */
  280. X    if (function == 'd')
  281. X        if (unlink(filename) == -1)
  282. X            panic(filename);
  283. X
  284. X/* That's all we need to be root for, so change our uid to something secure. */
  285. X    setreuid(uid, uid);
  286. X
  287. X/* Now edit or show the file, as appropriate. */
  288. X    if (function == 'l')
  289. X        execl(DISPLAY, DISPLAY, filename, NULL);
  290. X    if (function == 'e')
  291. X    {
  292. X        if ((editor = getenv("VISUAL")) == NULL)
  293. X            editor = VISUAL;
  294. X        execl(editor, editor, filename, NULL);
  295. X    }
  296. X    if (function == 't')
  297. X    {
  298. X/* Duplicate the minimal environment under which the scripts are run */
  299. X        char *env[5];
  300. X
  301. X        env[4] = NULL;
  302. X        env[3] = malloc(strlen(pent->pw_name)+6);
  303. X        sprintf(env[3], "USER=%s", pent->pw_name);
  304. X        env[2] = malloc(strlen(pent->pw_shell)+7);
  305. X        sprintf(env[2], "SHELL=%s", pent->pw_shell);
  306. X        env[1] = malloc(strlen(RCDIR)+4);
  307. X        sprintf(env[1], "PWD=%s", RCDIR);
  308. X        env[1][strlen(RCDIR)+3] = '\0';    /* lop off trailing / */
  309. X        env[0] = malloc(strlen(pent->pw_dir)+6);
  310. X        sprintf(env[0], "HOME=%s", pent->pw_dir);
  311. X        
  312. X        execle(SHELL, SHELL, filename, NULL, env);
  313. X    }
  314. X    exit(0);
  315. X}
  316. X
  317. SHAR_EOF
  318. chmod 0600 rcuser.c || echo "restore of rcuser.c fails"
  319. exit 0
  320.  
  321.