"Fossies" - the Fresh Open Source Software Archive

Member "jed-0.99-19/src/userinfo.c" (14 Dec 2009, 8699 Bytes) of package /linux/misc/jed-0.99-19.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "userinfo.c" see the Fossies "Dox" file reference documentation.

    1 /* -*- mode: C; mode: fold; -*- */
    2 /* Copyright (c) 1999, 2000, 2002, 2003, 2004, 2005, 2006 John E. Davis
    3  * This file is part of JED editor library source.
    4  *
    5  * You may distribute this file under the terms the GNU General Public
    6  * License.  See the file COPYING for more information.
    7  */
    8 #include "config.h"
    9 #include "jed-feat.h"
   10 
   11 /*{{{ Include Files */
   12 #include <stdio.h>
   13 #include <string.h>
   14 
   15 #include <errno.h>
   16 #include <time.h>
   17 
   18 #ifdef HAVE_STDLIB_H
   19 # include <stdlib.h>
   20 #endif
   21 
   22 #ifdef HAVE_UNISTD_H
   23 # include <unistd.h>
   24 #endif
   25 
   26 #include <slang.h>
   27 #include "jdmacros.h"
   28 
   29 #ifdef REAL_UNIX_SYSTEM
   30 # define HAS_TCPIP_CODE     1
   31 # include <netdb.h>
   32 # ifndef h_errno
   33 extern int h_errno;
   34 # endif
   35 # define RESOLVE_DOT_CONF   "/etc/resolv.conf"
   36 #else
   37 # define HAS_TCPIP_CODE     0
   38 #endif
   39 
   40 #ifdef REAL_UNIX_SYSTEM
   41 # include <pwd.h>
   42 # define HAS_PASSWORD_CODE  1
   43 #else
   44 # define HAS_PASSWORD_CODE  0
   45 #endif
   46 
   47 #include "userinfo.h"
   48 #include "misc.h"
   49 
   50 /*}}}*/
   51 
   52 typedef struct
   53 {
   54    char *username;
   55    char *realname;
   56    char *hostname;
   57 }
   58 User_Info_Type;
   59 
   60 User_Info_Type User_Info;
   61 
   62 static int set_user_info (char **what, char *value)
   63 {
   64    if (NULL == (value = SLang_create_slstring (value)))
   65      return -1;
   66    SLang_free_slstring (*what);   /* NULL ok */
   67    *what = value;
   68    return 0;
   69 }
   70 
   71 static int set_hostname (char *name)
   72 {
   73    if (*name == 0) name = "localhost";
   74    return set_user_info (&User_Info.hostname, name);
   75 }
   76 
   77 static int set_username (char *name)
   78 {
   79    return set_user_info (&User_Info.username, name);
   80 }
   81 
   82 static int set_realname (char *name)
   83 {
   84    return set_user_info (&User_Info.realname, name);
   85 }
   86 
   87 
   88 static int is_fqdn (char *h) /*{{{*/
   89 {
   90    char *p;
   91    
   92    p = strchr (h, '.');
   93    if ((p == NULL) || (p == h))
   94      return 0;
   95    
   96    if ((unsigned int)((p - h) + 1) == strlen (h))
   97      return 0;
   98 
   99    /* We may want something more sophisticated here */
  100    return 1;
  101 }
  102 
  103 /*}}}*/
  104 
  105 #ifdef RESOLVE_DOT_CONF
  106 static char *skip_whitespace_chars (char *b)
  107 {
  108    while ((*b == ' ') || (*b == '\t') || (*b == '\n'))
  109      b++;
  110    return b;
  111 }
  112 
  113 static char *skip_non_whitespace_chars (char *b)
  114 {
  115    while (*b && (*b != ' ') && (*b != '\t') && (*b != '\n'))
  116      b++;
  117    return b;
  118 }
  119 #endif
  120 
  121 static int get_domainname (char *dom, unsigned int domlen)
  122 {
  123 #ifdef RESOLVE_DOT_CONF
  124    FILE *fp;
  125    char buf[1024];
  126 
  127    if (NULL == (fp = fopen (RESOLVE_DOT_CONF, "r")))
  128      return -1;
  129 
  130    while (NULL != fgets (buf, sizeof (buf), fp))
  131      {
  132     char *d, *b;
  133 
  134     b = buf;
  135 
  136     if (*b == '#') 
  137       continue;
  138     
  139     b = skip_whitespace_chars (b);
  140 
  141     if (0 != strncmp ("domain", b, 6))
  142       continue;
  143     
  144     b += 6;
  145     if ((*b != ' ') && (*b != '\t'))
  146       continue;
  147 
  148     b = skip_whitespace_chars (b);
  149     
  150     d = b;
  151     b = skip_non_whitespace_chars (b);
  152     
  153     if (b == d) continue;
  154 
  155     *b = 0;
  156     
  157     strncpy (dom, d, domlen);
  158     dom[domlen-1] = 0;
  159     fclose (fp);
  160     return 0;
  161      }
  162    fclose (fp);
  163    return -1;
  164 #else
  165    (void) dom;
  166    (void) domlen;
  167    return -1;
  168 #endif
  169 }
  170 
  171 static char *combine_host_and_domain (char *a, char *b)
  172 {
  173    unsigned int len;
  174    char *c, *cc;
  175 
  176    len = strlen (a) + strlen (b) + 2;
  177    if (NULL == (c = SLmalloc (len)))
  178      return NULL;
  179 
  180    if (*b == '.') b++;
  181    sprintf (c, "%s.%s", a, b);
  182    
  183    cc = SLang_create_slstring (c);
  184    SLfree (c);
  185    return cc;
  186 }
  187 
  188 #ifndef HAVE_GETHOSTNAME
  189 #define gethostname _my_gethostname
  190 static int _my_gethostname (char *buf, unsigned int len)
  191 {
  192    (void) buf;
  193    (void) len;
  194    return -1;
  195 }
  196 #endif
  197 
  198 /* Try to get a fully qualified domain name. */
  199 static char *get_hostname (void)
  200 {
  201 #if HAS_TCPIP_CODE
  202    struct hostent *host_entry = NULL;
  203 #endif
  204    char buf[256], *b;
  205    char domain_name[256];
  206 
  207 
  208 #ifdef JED_HOSTNAME
  209    if (is_fqdn (JED_HOSTNAME))
  210      return SLang_create_slstring (JED_HOSTNAME);
  211 #endif
  212 
  213    b = buf;
  214 
  215    if ((-1 == gethostname (buf, sizeof (buf)))
  216        || (*buf == 0))
  217      {
  218     b = getenv ("HOSTNAME");
  219     if ((b == NULL) || (*b == 0))
  220       return NULL;
  221      }
  222 
  223 #if HAS_TCPIP_CODE
  224    /* gethostname may not provide the full name so use gethostbyname
  225     * to get more information.  Why isn't there a simplified interface to
  226     * get the FQDN!!!!
  227     */
  228    host_entry = gethostbyname (b);
  229 
  230 #if defined(TRY_AGAIN) && !defined(MULTINET)
  231    if ((host_entry == NULL) && (h_errno == TRY_AGAIN))
  232      {
  233     sleep (2);
  234     host_entry = gethostbyname (b);
  235      }
  236 #endif
  237    if ((host_entry != NULL)
  238        && (host_entry->h_name != NULL)
  239        && (host_entry->h_name[0] != 0))
  240      {
  241     char **aliases;
  242 
  243     if (is_fqdn ((char *)host_entry->h_name))
  244       return SLang_create_slstring ((char *)host_entry->h_name);
  245 
  246     if (NULL != (aliases = host_entry->h_aliases))
  247       {
  248          while (*aliases != NULL)
  249            {
  250           if (is_fqdn (*aliases))
  251             return SLang_create_slstring (*aliases);
  252           aliases++;
  253            }
  254       }
  255 
  256     /* We have no FQDN */
  257     b = (char *)host_entry->h_name;
  258      }
  259 #endif                     /* HAS_TCPIP_CODE */
  260 
  261    if (*b == 0)
  262      return NULL;
  263 
  264    if ((0 == is_fqdn (b))
  265        && (0 == get_domainname (domain_name, sizeof (domain_name))))
  266      {
  267     return combine_host_and_domain (b, domain_name);
  268      }
  269 
  270    /* Oh well */
  271    return SLang_create_slstring (b);
  272 }
  273 
  274 
  275 static int get_hostname_info (void)
  276 {
  277    char *host;
  278 
  279    host = get_hostname ();
  280    if (host != NULL)
  281      {
  282     if (-1 == set_hostname (host))
  283       {
  284          SLang_free_slstring (host);
  285          return -1;
  286       }
  287     SLang_free_slstring (host);
  288     return 0;
  289      }
  290    
  291    if (SLang_get_error ())
  292      return -1;
  293 
  294    return set_hostname ("localhost");
  295 }
  296 
  297 static int get_username_info (void)
  298 {
  299    char *name = NULL;
  300 #if HAS_PASSWORD_CODE
  301    struct passwd *pw;
  302 #endif
  303 
  304 #if HAS_PASSWORD_CODE
  305    /* I cannot use getlogin under Unix because some implementations 
  306     * truncate the username to 8 characters.  Besides, I suspect that
  307     * it is equivalent to the following line.
  308     */
  309    /* The man page for getpwuid indicate that the pointer _may_ be to a static
  310     * area.  So, there is nothing to free here.
  311     */
  312    pw = getpwuid (getuid ());
  313    if (pw != NULL)
  314      name = pw->pw_name;
  315 #endif
  316 
  317    if (((name == NULL) || (*name == 0))
  318        && ((name = getenv("USER")) == NULL)
  319        && ((name = getenv("LOGNAME")) == NULL))
  320      name = "unknown";
  321    
  322    if (-1 == set_username (name))
  323      return -1;
  324    
  325    name = getenv ("NAME");
  326 #if HAS_PASSWORD_CODE
  327    if ((name == NULL) 
  328        && (pw != NULL)
  329        && (pw->pw_gecos != NULL))
  330      name = pw->pw_gecos;
  331 #endif
  332    if (name == NULL)
  333      name = "";
  334    
  335    if (-1 == set_realname (name))
  336      return -1;
  337    
  338    return 0;
  339 }
  340 
  341 static int get_user_info (void)
  342 {
  343    if (-1 == get_hostname_info ())
  344      return -1;
  345    
  346    if (-1 == get_username_info ())
  347      return -1;
  348    
  349    return 0;
  350 }
  351 
  352 char *jed_get_username (void)
  353 {
  354    return SLang_create_slstring (User_Info.username);
  355 }
  356 
  357 char *jed_get_hostname (void)
  358 {
  359    return SLang_create_slstring (User_Info.hostname);
  360 }
  361 
  362 static void get_passwd_cmd (char *name) /*{{{*/
  363 {
  364    char *password = NULL;
  365    char *dir = NULL;
  366    char *shell = NULL;
  367    int uid = -1, gid = -1;
  368 #if HAS_PASSWORD_CODE
  369    struct passwd *pwent;
  370 
  371    if (*name == 0)
  372      pwent = getpwuid (getuid ());
  373    else
  374      pwent = getpwnam (name);
  375    
  376    if (pwent != NULL)
  377      {
  378     password = pwent->pw_passwd;
  379     uid = pwent->pw_uid;
  380     gid = pwent->pw_gid;
  381     dir = pwent->pw_dir;
  382     shell = pwent->pw_shell;
  383      }
  384 #endif
  385    if (password == NULL) password = "";
  386    if (dir == NULL) dir = "";
  387    if (shell == NULL) shell = "";
  388    
  389    (void) SLang_push_string (dir);
  390    (void) SLang_push_string (shell);
  391    (void) SLang_push_string (password);
  392    (void) SLang_push_integer (uid);
  393    (void) SLang_push_integer (gid);
  394 }
  395 
  396 /*}}}*/
  397 
  398 static char *get_username_cmd (void)
  399 {
  400    return User_Info.username;
  401 }
  402 static char *get_realname_cmd (void)
  403 {
  404    return User_Info.realname;
  405 }
  406 static char *get_hostname_cmd (void)
  407 {
  408    return User_Info.hostname;
  409 }
  410 static void set_username_cmd (char *s)
  411 {
  412    (void) set_username (s);
  413 }
  414 static void set_realname_cmd (char *s)
  415 {
  416    (void) set_realname (s);
  417 }
  418 static void set_hostname_cmd (char *s)
  419 {
  420    (void) set_hostname (s);
  421 }
  422 
  423 static SLang_Intrin_Fun_Type User_Intrinsics [] =
  424 {
  425    MAKE_INTRINSIC_S("get_passwd_info", get_passwd_cmd, VOID_TYPE),
  426    MAKE_INTRINSIC_0("get_username", get_username_cmd, SLANG_STRING_TYPE),
  427    MAKE_INTRINSIC_0("get_hostname", get_hostname_cmd, SLANG_STRING_TYPE),
  428    MAKE_INTRINSIC_0("get_realname", get_realname_cmd, SLANG_STRING_TYPE),
  429 
  430    MAKE_INTRINSIC_S("set_username", set_username_cmd, SLANG_VOID_TYPE),
  431    MAKE_INTRINSIC_S("set_hostname", set_hostname_cmd, SLANG_VOID_TYPE),
  432    MAKE_INTRINSIC_S("set_realname", set_realname_cmd, SLANG_VOID_TYPE),
  433 
  434    MAKE_INTRINSIC_0(NULL, NULL, 0)
  435 };
  436 
  437 int jed_init_userinfo (void)
  438 {
  439    (void) get_user_info ();
  440 
  441    if (-1 == SLadd_intrin_fun_table (User_Intrinsics, NULL))
  442      return -1;
  443    
  444    return 0;
  445 }