home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / unix_c / utils / toe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-21  |  9.0 KB  |  325 lines

  1. 21-May-86 08:33:56-MDT,9450;000000000001
  2. Return-Path: <unix-sources-request@BRL.ARPA>
  3. Received: from BRL-SMOKE.ARPA by SIMTEL20.ARPA with TCP; Wed 21 May 86 08:33:22-MDT
  4. Received: from USENET by SMOKE.BRL.ARPA id a015119; 20 May 86 19:23 EDT
  5. From: AAAARRRRGGGGv <argv@sri-spam.arpa>
  6. Newsgroups: net.sources
  7. Subject: from net.jokes
  8. Message-ID: <5779@sri-spam.ARPA>
  9. Date: 17 May 86 02:32:33 GMT
  10. Keywords: watch your toes.
  11. To:       unix-sources@brl-smoke.arpa
  12.  
  13.  
  14. Subject: Re: Unix sources wanted
  15. Newsgroups: net.jokes
  16. Summary: toe.c
  17. References: <8700247@uiucdcsb>
  18.  
  19. ** oh forget it... **
  20.  
  21. Speaking of "finger"-like programs, when I was in school, I made "toe"
  22. which was like finger, but different.  It gave you lots of stuff that
  23. seemed interesting, especially for a social invironment such as our
  24. old open-access PDP-11 running V7 (/etc/passwd was over 3500 lines long;
  25. when I went to school there [UCSC] there were 7500 students).
  26.  
  27.  
  28. #define BSD
  29. /* Program: toe
  30.    Purpose: Just like finger, but different.
  31.         toe must be setuid to root so ~/.toerc file can be opened
  32.         by anyone. Otherwise, the home directory must be
  33.         executable (searchable) and ~/.toerc must be readable.
  34.  
  35.    normal compile: cc -O -s toe.c -o toe
  36.    Written by:  Dan Heller        2/10/85
  37.  
  38. */
  39.  
  40. char *msg[] = {
  41.    "Usage : %s [-Dgdumhv] [userlist]\n",
  42.    "-D : Don't print public dirs (because it can be slow)\n",
  43.    "-d : just print public dirs\n",
  44.    "-g : just print group(s)\n",
  45.    "-u : just print user's id\n",
  46.    "-m : just print if they have mail\n",
  47.    "-h : just print the home dir\n",
  48.    "-v : visual mode. Prints printable versions of ctrl chars\n",
  49.    "-M : Don't do \"more\". Automatically off if any redirects.\n",
  50.    "\nTo make a toefile, create a file called ~/.toerc. If this program\n",
  51.    "is NOT setuid to root, chmod 644 .toerc.\n",
  52.    0 };
  53.  
  54. #define utmpfile  "/etc/utmp"
  55. #define maildir   "/usr/spool/mail"
  56.  
  57. #include <stdio.h>
  58. #include <ctype.h>
  59. #include <utmp.h>
  60. #include <sgtty.h>
  61. #include <signal.h>
  62. #include <sys/time.h>
  63. #include <sys/types.h>
  64. #include <sys/stat.h>
  65. #include <grp.h>
  66. #include <pwd.h>
  67. #if BSD
  68. #include <sys/dir.h>
  69. #else
  70. #include <ndir.h>
  71. #endif
  72.  
  73. /*  convenience  */
  74. #define when break;case
  75. #define otherwise break;default
  76.  
  77. int visual = 0, no_pub = 0, chk_home = 0, chk_grp = 0, chk_pub = 0,
  78.     chk_uid = 0, chk_mail = 0, do_all = 1, do_more = 1;
  79.  
  80. char *unctrl_chars[] = {
  81.     "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K",
  82.     "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
  83.     "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_", " ", "!", "\"", "#",
  84.     "$",  "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0",  "1",
  85.     "2",  "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">",  "?",
  86.     "@",  "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",  "M",
  87.     "N",  "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",  "[",
  88.     "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h",  "i",
  89.     "j",  "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",  "w",
  90.     "x",  "y", "z", "{", "|", "}", "~", "^?"
  91. };
  92. #define unctrl(c)    unctrl_chars[(c) & 0177]
  93.  
  94. FILE *toefile;
  95. long now;
  96.  
  97. struct passwd *entry;
  98. struct Users {
  99.     char *u_login;
  100.     struct Users *u_next;
  101. } *users = NULL;
  102.  
  103. main(argc, argv)
  104. int argc;
  105. char **argv;
  106. {
  107.     char *cmd = *argv;
  108.     struct Users **list;
  109.     int die();
  110.     if (!isatty(0) || !isatty(1) || !isatty(2)) /* check for redirection */
  111.      do_more = 0;
  112.     savetty(), noecho(), crmode();
  113.     signal(SIGINT, die);
  114.     signal(SIGQUIT, die);
  115.     list = &users;
  116.     while (*++argv)
  117.     if (argv[0][0] == '-')
  118.         while(*(++argv[0]))
  119.         switch(*argv[0]) {
  120.             when 'D' :  no_pub = 1;
  121.             when 'g' :  do_all = 0, chk_grp = 1;
  122.             when 'd' :  do_all = 0, chk_pub = 1;
  123.             when 'u' :  do_all = 0, chk_uid = 1;
  124.             when 'm' :  do_all = 0, chk_mail = 1;
  125.             when 'v' :  do_all = 0, visual = 1;
  126.             when 'h' :  do_all = 0, chk_home = 1;
  127.             when 'M' :  do_more = 0;
  128.             otherwise  :
  129.             do_error(cmd);
  130.         }
  131.     else { /* create a linkd list of people to process */
  132.         *list = (struct Users *)malloc(sizeof(struct Users));
  133.         (*list)->u_login = argv[0];
  134.         list = &(*list)->u_next;
  135.     }
  136.  
  137.     *list = NULL; /* terminate the list */
  138.     if (!users) getusers();  /* do everyone logged in */
  139.     do  if (!(entry = getpwnam(users->u_login)))
  140.         fprintf(stderr,"%s: No one by that name here.\n", users->u_login);
  141.     else do_toe(entry);
  142.     while(users = users->u_next);
  143.     die();
  144. }
  145.  
  146. do_error(arg)  /* user messed up command line */
  147. {
  148.     int count = 0;
  149.     while(msg[count])
  150.     printf(msg[count++], arg);
  151.     die();
  152. }
  153.  
  154. do_toe(entry)
  155. struct passwd *entry;
  156. {
  157.     static int counter = 0;
  158.     char c, file[50], grp[30], alias[1024];
  159.     FILE *fp;
  160.     if (counter++) {
  161.     char c;
  162.     printf("\n--next user--('q' to exit)");
  163.     while((c = getchar()) != ' ' && c != '\n' && c != 'q');
  164.     printf("\015                          \015");
  165.     if (c == 'q') die();
  166.     putchar('\n');
  167.     }
  168.     if (do_all) {
  169.     sprintf(file, "%s/.toerc", (entry->pw_uid) ? entry->pw_dir : "");
  170.     if (fp = fopen(file, "r"))
  171.         Fgets(alias, 1024, fp);
  172.     else alias[0] = 0;
  173.     printf("Login name: %-8s\tLogout name: %s\n",
  174.             entry->pw_name, (fp) ? alias : "");
  175.     }
  176.     if (do_all || chk_mail) {
  177.     if (mail(entry->pw_name))
  178.         printf("%s has mail.\t\t\t", entry->pw_name);
  179.     else if (chk_mail) printf("%s has no mail", entry->pw_name);
  180.     if (!do_all) putchar('\n');
  181.     }
  182.     if (do_all || chk_uid) printf("User Id: %d\n", entry->pw_uid);
  183.     if (do_all || chk_home)
  184.     printf("Where %s lives: %s\n", entry->pw_name, entry->pw_dir);
  185.     if (do_all || chk_grp) {
  186.     strcpy(grp, getgrgid(entry->pw_gid)->gr_name);
  187.     printf("Login Group: %s (%d)\n", grp, entry->pw_gid);
  188.     get_groups(entry, grp);
  189.     }
  190.     if ((do_all && !no_pub) || chk_pub) {
  191.     printf("Public directories:\n");
  192.     if (!enterdir(entry->pw_dir)) printf("\tHome directory not public\n");
  193.     }
  194.     if (do_all)
  195.     if (fp) {
  196.         int lines = 0;
  197.         printf("Some extra stuff:\n");
  198.         while((c = getc(fp)) != EOF) {
  199.         if (visual && !isspace(c))
  200.              printf("%s", unctrl(c));
  201.         else putchar(c);
  202.         if (do_more && c == '\n' && ++lines == 22) {
  203.             lines = 0;
  204.             printf("--more--");
  205.             while((c = getchar()) != ' ' && c != '\n' && c != 'n' &&
  206.                c != 'q');
  207.             printf("\015        \015");
  208.             if (c == 'n' || c == 'q') return;
  209.             if (c == '\n') lines = 21;
  210.         }
  211.         }
  212.     } else
  213.         printf("No toes.\n");
  214. }
  215.  
  216. Fgets(string, LEN, fp)
  217. char string[];
  218. FILE *fp;
  219. int LEN;
  220. {
  221.     int count = 0;
  222.     char c, *temp = string;
  223.     *temp = 0;
  224.     while((c = getc(fp)) != EOF && c != '\n' && count < LEN)
  225.     if (visual && !isspace(c))
  226.         strcat(temp, unctrl(c)), count += 1 + (iscntrl(c));
  227.     else *temp++ = c, count++;
  228.     *temp = 0;
  229. }
  230.  
  231. mail(user)
  232. char user[];
  233. {
  234.     struct stat mbox;
  235.     char mail_path[40];
  236.     sprintf(mail_path,"%s/%s", maildir, user);
  237.     if (stat(mail_path, &mbox) != -1)
  238.     if (mbox.st_size > 0) return 1;  /* has mail */
  239.     return 0;  /* no mail */
  240. }
  241.  
  242. enterdir(pathsofar)
  243. char pathsofar[];
  244. {
  245.     FILE *fp;
  246.     struct direct *dp;
  247. #if BSD
  248.     DIR *dirp;
  249. #else
  250.     struct DIR *dirp;
  251. #endif
  252.     struct stat stat_buf;
  253.     char newpath[80];
  254.     stat(pathsofar, &stat_buf);
  255.     if (stat_buf.st_mode & S_IFDIR && (stat_buf.st_mode & 05) == 05)
  256.     printf("\t%s\n", pathsofar + (pathsofar[1] == '/'));
  257.     else return 0;
  258.     if ((dirp = opendir(pathsofar)) == NULL)
  259.     return -1;
  260.     for (dp = readdir(dirp); dp; dp = readdir(dirp))
  261.     if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."))
  262.         sprintf(newpath,"%s/%s",pathsofar,dp->d_name), enterdir(newpath);
  263.     closedir(dirp);
  264.     return 1;
  265. }
  266.  
  267. getusers()
  268. {
  269.     struct utmp buf;
  270.     struct Users **temp;
  271.     FILE *fptr;
  272.  
  273.     temp = &users;
  274.     if ((fptr = fopen(utmpfile, "r")) < 0)
  275.         perror(utmpfile), exit(1);
  276.     while (fread(&buf , sizeof (struct utmp), 1, fptr) > 0)
  277.         if ( buf.ut_name[0] ) {
  278.         *temp = (struct Users *) malloc (sizeof(struct Users));
  279.         (*temp)->u_login = (char *) malloc(strlen(buf.ut_name) + 1);
  280.         strcpy((*temp)->u_login, buf.ut_name);
  281.         temp = &(*temp)->u_next;
  282.     }
  283.     close(fptr);
  284. }
  285.  
  286. get_groups(entry, cur_group)
  287. struct passwd *entry;
  288. char cur_group[];
  289. {
  290.     short first_find = 0;
  291.     struct group *Group;
  292.     while(Group = getgrent())
  293.     while(*(Group->gr_mem)) {
  294.         if (!strcmp(*Group->gr_mem, entry->pw_name) &&
  295.                   strcmp(Group->gr_name, cur_group)) {
  296.         if (!first_find++) printf("Other groups:\n");
  297.         printf("\t%s (%d)\n", Group->gr_name, Group->gr_gid);
  298.         }
  299.         *Group->gr_mem++;
  300.     }
  301.     endgrent();
  302. }
  303.  
  304. die()
  305. {
  306.     putchar('\n');
  307.     resetty(); echo(); nocrmode(); exit(0);
  308. }
  309.  
  310. /* stuff for tty attributes */
  311.  
  312. #define    _dosave_   if (!_savflgs) savetty()
  313.  
  314. struct sgttyb _tty;
  315. int _savflgs = 0;
  316. savetty()  { if (!gtty(0, &_tty)) _savflgs = _tty.sg_flags; }
  317. resetty()  { _tty.sg_flags = _savflgs;   stty(0, &_tty);   }
  318. crmode()   { _dosave_; _tty.sg_flags |= CBREAK;  stty(0, &_tty); }
  319. nocrmode() { _dosave_; _tty.sg_flags &= ~CBREAK; stty(0, &_tty); }
  320. echo()       { _dosave_; _tty.sg_flags |= ECHO;    stty(0, &_tty); }
  321. noecho()   { _dosave_; _tty.sg_flags &= ~ECHO;   stty(0, &_tty); }
  322.  
  323. ------------
  324. dan (argv@sri-spam.arpa)
  325.