home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / userinfo.C < prev    next >
C/C++ Source or Header  |  1998-11-15  |  7KB  |  309 lines

  1. // $Id: userinfo.C,v 1.19 1998/11/15 11:44:40 zeller Exp $ -*- C++ -*-
  2. // Issue name and e-mail address of building user
  3.  
  4. // Copyright (C) 1998 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char userinfo_rcsid[] = 
  30.     "$Id: userinfo.C,v 1.19 1998/11/15 11:44:40 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "config.h"
  37. #include "hostname.h"
  38. #include "bool.h"
  39.  
  40. extern "C" {
  41. #if HAVE_SYS_TYPES_H
  42. #include <sys/types.h>
  43. #endif
  44. }
  45.  
  46. #if HAVE_UNISTD_H
  47. #include <unistd.h>
  48. #endif
  49.  
  50. #include <stdlib.h>
  51. #include <ctype.h>
  52. #include <pwd.h>
  53.  
  54. #include "hostname.C"
  55.  
  56. // Return true if C is a letter found in real user names.  Any
  57. // non-ASCII characters are considered letters.
  58. inline bool is_letter(char c)
  59. {
  60.     return c != '\0' && (!isascii(c) || isalpha(c) || isspace(c) || 
  61.              c == '.' || c == '-' || c == '\'');
  62. }
  63.  
  64. // Return true if C is a letter not found in e-mail addresses
  65. inline bool is_junk(char c)
  66. {
  67.     return c == '\0' || isspace(c) || c == '\"' || c == '(' 
  68.     || c == ')' || c == ',' || c == ';';
  69. }
  70.  
  71. // Return e-mail address from preferences file DOTRC in HOME dir.
  72. // Format of preferences line is `TAG E-MAIL-ADDRESS'.
  73. static char *email_from_preferences(char *home, char *dotrc, char *tag)
  74. {
  75.     char preferences[BUFSIZ];
  76.     strcpy(preferences, home);
  77.     strcat(preferences, "/");
  78.     strcat(preferences, dotrc);
  79.  
  80.     FILE *fp = fopen(preferences, "r");
  81.     if (fp != NULL)
  82.     {
  83.     char line[BUFSIZ];
  84.     while (fgets(line, sizeof(line), fp) != NULL)
  85.     {
  86.         if (strncmp(line, tag, strlen(tag)) == 0)
  87.         {
  88.         static char buffer[BUFSIZ];
  89.  
  90.         char *s = line + strlen(tag);
  91.         char *t = buffer;
  92.         while (is_junk(*s))
  93.             s++;
  94.         while (!is_junk(*s) && *s != '\0')
  95.             *t++ = tolower(*s++);
  96.         *t++ = '\0';
  97.         fclose(fp);
  98.         return buffer;
  99.         }
  100.     }
  101.  
  102.     fclose(fp);
  103.     }
  104.  
  105.     return 0;
  106. }
  107.  
  108.  
  109. // Return e-mail address from signature file DOTRC in HOME dir.  Find
  110. // the first `@' and return the surrounding string.
  111. static char *email_from_signature(char *home, char *dotrc)
  112. {
  113.     char signature[BUFSIZ];
  114.     strcpy(signature, home);
  115.     strcat(signature, "/");
  116.     strcat(signature, dotrc);
  117.  
  118.     FILE *fp = fopen(signature, "r");
  119.     if (fp != NULL)
  120.     {
  121.     char line[BUFSIZ];
  122.     while (fgets(line, sizeof(line), fp) != NULL)
  123.     {
  124.         char *s = strchr(line, '@');
  125.         if (s != 0)
  126.         {
  127.         static char buffer[BUFSIZ];
  128.         char *t = buffer;
  129.  
  130.         while (!isspace(*s) && s != line)
  131.             s--;
  132.         while (isspace(*s))
  133.             s++;
  134.         while (!isspace(*s) && *s != '\0')
  135.             *t++ = tolower(*s++);
  136.         *t++ = '\0';
  137.         fclose(fp);
  138.         return buffer;
  139.         }
  140.     }
  141.  
  142.     fclose(fp);
  143.     }
  144.  
  145.     return 0;
  146. }
  147.  
  148. // Return e-mail address from PWD at current host.
  149. static char *email_from_pwd(struct passwd *pwd)
  150. {
  151.     static char buffer[BUFSIZ];
  152.     strcpy(buffer, pwd->pw_name);
  153.     strcat(buffer, "@");
  154.     strcat(buffer, fullhostname());
  155.  
  156.     return buffer;
  157. }
  158.  
  159. // Check if S looks like an e-mail address.  S must contain a `@' and
  160. // a `.', neither at the beginning nor at the end.
  161. static bool is_email(char *s)
  162. {
  163.     if (s == 0)
  164.     return false;
  165.  
  166.     char *at = strchr(s, '@');
  167.     if (at == 0 || at == s || at[1] == '\0')
  168.     return false;
  169.  
  170.     char *dot = strchr(s, '.');
  171.     if (dot == 0 || dot == s || dot[1] == '\0')
  172.     return false;
  173.  
  174.     return true;
  175. }
  176.  
  177. // Return an e-mail address for user PWD.
  178. static char *email(struct passwd *pwd)
  179. {
  180.     char *s = 0;
  181.  
  182.     // Try Netscape and Lynx preferences
  183.  
  184.     // Netscape 4.0
  185.     if (!is_email(s))
  186.     s = email_from_preferences(pwd->pw_dir, ".netscape/preferences.js", 
  187.                    "user_pref(\"mail.identity.useremail\",");
  188.  
  189.     // Netscape 3.0
  190.     if (!is_email(s))
  191.     s = email_from_preferences(pwd->pw_dir, ".netscape/preferences", 
  192.                    "EMAIL_ADDRESS:");
  193.  
  194.     // Netscape 2.0 and earlier
  195.     if (!is_email(s))
  196.     s = email_from_preferences(pwd->pw_dir, ".netscape-preferences", 
  197.                    "EMAIL_ADDRESS:");
  198.  
  199.     // Lynx
  200.     if (!is_email(s))
  201.     s = email_from_preferences(pwd->pw_dir, ".lynxrc", 
  202.                    "personal_mail_address=");
  203.  
  204.     // Try .dot files used for e-mail and fingering
  205.     if (!is_email(s))
  206.     s = email_from_signature(pwd->pw_dir, ".signature");
  207.     if (!is_email(s))
  208.     s = email_from_signature(pwd->pw_dir, ".Sig");
  209.     if (!is_email(s))
  210.     s = email_from_signature(pwd->pw_dir, ".project");
  211.     if (!is_email(s))
  212.     s = email_from_signature(pwd->pw_dir, ".plan");
  213.  
  214.     // Try e-mail address from current host name
  215.     if (!is_email(s))
  216.     s = email_from_pwd(pwd);
  217.  
  218.     // Tried it all, and failed :-(
  219.     if (!is_email(s))
  220.     s = "unknown";
  221.  
  222.     return s;
  223. }
  224.  
  225. // Write user information for given ARG
  226. int userinfo(char *arg = 0)
  227. {
  228.     struct passwd *pwd = 0;
  229.  
  230.     if (arg == 0)
  231.     {
  232.     // Get info for current user
  233.     pwd = getpwuid(getuid());
  234.     }
  235.     else if (isdigit(arg[0]))
  236.     {
  237.     // Get info for numerical id
  238.     pwd = getpwuid(atoi(arg));
  239.     }
  240.     else
  241.     {
  242.     // Get info for user name
  243.     pwd = getpwnam(arg);
  244.     }
  245.  
  246.     if (pwd == 0)
  247.     {
  248.     fputs(arg, stderr);
  249.     fputs(": no such passwd entry\n", stderr);
  250.     return 1;
  251.     }
  252.  
  253.     // Issue real name
  254.     char *s = pwd->pw_gecos;
  255.     while (is_letter(*s) || isdigit(*s))
  256.     putchar(*s++);
  257.  
  258.     if (s == pwd->pw_gecos)
  259.     {
  260.     // No real name given; try user id
  261.     if (pwd->pw_name[0])
  262.     {
  263.         s = pwd->pw_name;
  264.         while (is_letter(*s++))
  265.         ;
  266.  
  267.         if (*s != '\0')
  268.         {
  269.         // User id contains non-letters => probably a symbolic
  270.         // name => leave it unchanged.
  271.         fputs(pwd->pw_name, stdout);
  272.         }
  273.         else
  274.         {
  275.         // User id is a real name => capitalize it.
  276.         fputc(toupper(pwd->pw_name[0]), stdout);
  277.         fputs(pwd->pw_name + 1, stdout);
  278.         }
  279.     }
  280.     else
  281.     {
  282.         // No user id.  This is weird.
  283.         fputs("Unknown ", stdout);
  284.     }
  285.     }
  286.  
  287.     // Lookup preferences files for the e-mail address.
  288.     fputs(" <", stdout);
  289.     fputs(email(pwd), stdout);
  290.     fputs(">\n", stdout);
  291.  
  292.     return 0;
  293. }
  294.  
  295.  
  296. // Issue the name of the building user, in the format
  297. // ``REALNAME <USERNAME@HOSTNAME>''
  298. int main(int argc, char *argv[])
  299. {
  300.     if (argc == 1)
  301.     return userinfo();
  302.  
  303.     int ret = 0;
  304.     for (int i = 1; i < argc; i++)
  305.     ret |= userinfo(argv[i]);
  306.  
  307.     return ret;
  308. }
  309.