"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/support.c" (14 Jan 2000, 8527 Bytes) of package /linux/misc/old/pidentd-3.0.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 "support.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** support.c - Miscellaneous support functions.
    3 **
    4 ** Copyright (c) 1997 Peter Eriksson <pen@lysator.liu.se>
    5 **
    6 ** This program is free software; you can redistribute it and/or
    7 ** modify it as you wish - as long as you don't claim that you wrote
    8 ** it.
    9 **
   10 ** This program is distributed in the hope that it will be useful,
   11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   13 */
   14 
   15 #include "config.h"
   16 
   17 #include <stdio.h>
   18 #include <ctype.h>
   19 #include <string.h>
   20 #include <errno.h>
   21 #include <syslog.h>
   22 #include <pwd.h>
   23 
   24 #include <sys/types.h>
   25 #include <netinet/in.h>
   26 #include <arpa/inet.h>
   27 
   28 #include "pidentd.h"
   29 
   30 #ifdef HAVE_UNAME
   31 #include <sys/utsname.h>
   32 #endif
   33 
   34 
   35 /*
   36 ** Get the OS name and version number
   37 */
   38 char *
   39 osinfo_get(char *buf)
   40 {
   41 #ifdef HAVE_UNAME
   42     struct utsname ub;
   43 
   44     if (uname(&ub) < 0)
   45     return NULL;
   46 #ifndef _AIX
   47     sprintf(buf, "%s %s", ub.sysname, ub.release);
   48 #else
   49     sprintf(buf, "%s %s.%s", ub.sysname, ub.version, ub.release);
   50 #endif
   51 #else
   52     strcpy(buf, "<unknown>");
   53 #endif
   54 
   55     return buf;
   56 }
   57 
   58 
   59 
   60 /*
   61 ** Classify what type of socket the file descript "fd" is
   62 */
   63 int
   64 socktype(int fd)
   65 {
   66     struct sockaddr_in remote_sin, local_sin;
   67     socklen_t len;
   68     int code;
   69 
   70 
   71     /* Try to get the local socket adress and port number */
   72     len = sizeof(local_sin);
   73     code = getsockname(fd, (struct sockaddr *) &local_sin, &len);
   74     if (code < 0)
   75     {
   76     if (errno == ENOTSOCK || errno == EINVAL)
   77         /* Not a TCP/IP socket */
   78         return SOCKTYPE_NOTSOCKET; 
   79     else
   80         return -1;
   81     }
   82 
   83      
   84     /* Try to get the remote socket adress and port number */
   85     len = sizeof(remote_sin);
   86     code = getpeername(fd, (struct sockaddr *) &remote_sin, &len);
   87     if (code < 0)
   88     {
   89     if (errno == ENOTCONN)
   90         /* Locally bound TCP socket, awaiting connections */
   91         return SOCKTYPE_LISTEN; 
   92     else
   93         return -1;
   94     }
   95     
   96     /* Established TCP connection */
   97     return SOCKTYPE_CONNECTED; 
   98 }
   99 
  100 
  101 
  102 /*
  103 ** A slightly safer strtok_r() function
  104 */
  105 char *
  106 s_strtok_r(char *s, const char *d, char **bp)
  107 {
  108     char *cp;
  109 
  110     
  111     if (d == NULL || bp == NULL)
  112     return NULL;
  113     
  114     if (s == NULL)
  115     s = *bp;
  116 
  117     if (s == NULL)
  118     return NULL;
  119     
  120     s += strspn(s, d);
  121     if (*s == '\0')
  122     return NULL;
  123 
  124     cp = s;
  125     s = strpbrk(cp, d);
  126     if (s == NULL)
  127     *bp = strchr(cp, 0);
  128     else
  129     {
  130     *s++ = '\0';
  131     *bp = s;
  132     }
  133     
  134     return cp;
  135 }
  136 
  137 
  138 
  139 
  140 #if !defined(HAVE_GETPWNAM_R) || !defined(HAVE_GETPWUID_R)
  141 static pthread_mutex_t pwd_lock;
  142 static pthread_once_t pwd_once = PTHREAD_ONCE_INIT;
  143 
  144 static void
  145 pwd_lock_init(void)
  146 {
  147     pthread_mutex_init(&pwd_lock, NULL);
  148 }
  149 
  150 static char *
  151 strcopy(const char *str, char **buf, size_t *avail)
  152 {
  153     char *start;
  154     size_t len;
  155 
  156     
  157     if (str == NULL)
  158     return NULL;
  159 
  160     len = strlen(str)+1;
  161     if (len > *avail)
  162     return NULL;
  163 
  164     start = *buf;
  165     
  166     memcpy(*buf, str, len);
  167     *avail -= len;
  168     *buf += len;
  169     
  170     return start;
  171 }
  172 #endif
  173 
  174 
  175 int
  176 s_getpwnam_r(const char *name,
  177        struct passwd *pwd,
  178        char *buffer, size_t bufsize,
  179        struct passwd **result)
  180 {
  181 #ifdef HAVE_GETPWNAM_R
  182     int code;
  183 
  184     
  185     memset(pwd, 0, sizeof(*pwd));
  186     memset(buffer, 0, bufsize);
  187 
  188 #ifdef HAVE_UI_GETPW /* Unix International / Solaris / UnixWare */
  189     
  190     while ((*result = getpwnam_r(name, pwd, buffer, bufsize)) == NULL &&
  191        errno == EINTR)
  192     ;
  193 
  194     if (*result == NULL)
  195     code = errno;
  196     else
  197     code = 0;
  198     
  199 #elif HAVE_DCE_GETPW /* DCE/CMA */
  200     
  201     while ((code = getpwnam_r(name, pwd, buffer, bufsize)) != 0 &&
  202        errno == EINTR)
  203     ;
  204     if (code == 0)
  205     *result = pwd;
  206     else
  207     code = errno;
  208     
  209 #else /* Posix version */
  210     
  211     while ((code = getpwnam_r(name, pwd, buffer, bufsize, result)) == EINTR)
  212     ;
  213 
  214 #endif
  215     
  216     return code;
  217     
  218 #else /* No reentrant getpw*_r calls available */
  219     
  220     struct passwd *pp;
  221 
  222     pthread_once(&pwd_once, pwd_lock_init);
  223     
  224     pthread_mutex_lock(&pwd_lock);
  225     
  226     pp = getpwnam(name);
  227     if (pp == NULL)
  228     {
  229     pthread_mutex_unlock(&pwd_lock);
  230     *result = NULL;
  231     return -1;
  232     }
  233 
  234     memset(pwd, 0, sizeof(*pwd));
  235     
  236     pwd->pw_name = strcopy(pp->pw_name, &buffer, &bufsize);
  237     pwd->pw_passwd = strcopy(pp->pw_passwd, &buffer, &bufsize);
  238     pwd->pw_uid = pp->pw_uid;
  239     pwd->pw_gid = pp->pw_gid;
  240     pwd->pw_gecos = strcopy(pp->pw_gecos, &buffer, &bufsize);
  241     pwd->pw_dir = strcopy(pp->pw_dir, &buffer, &bufsize);
  242     pwd->pw_shell = strcopy(pp->pw_shell, &buffer, &bufsize);
  243 
  244     *result = pwd;
  245     
  246     pthread_mutex_unlock(&pwd_lock);
  247     return 0;
  248 #endif
  249 }
  250 
  251 
  252 
  253 int
  254 s_getpwuid_r(uid_t uid,
  255          struct passwd *pwd,
  256          char *buffer, size_t bufsize,
  257          struct passwd **result)
  258 {
  259 #ifdef HAVE_GETPWUID_R
  260     int code;
  261 
  262     
  263     memset(pwd, 0, sizeof(*pwd));
  264     memset(buffer, 0, bufsize);
  265 
  266 #ifdef HAVE_UI_GETPW /* Unix International / Solaris / UnixWare */
  267     
  268     while ((*result = getpwuid_r(uid, pwd, buffer, bufsize)) == NULL &&
  269        errno == EINTR)
  270     ;
  271 
  272     if (*result == NULL)
  273     code = errno;
  274     else
  275     code = 0;
  276     
  277 #elif HAVE_DCE_GETPW /* DCE/CMA */
  278     
  279     while ((code = getpwuid_r(uid, pwd, buffer, bufsize)) != 0 &&
  280        errno == EINTR)
  281     ;
  282     if (code == 0)
  283     *result = pwd;
  284     else
  285     code = errno;
  286     
  287 #else /* Posix version */
  288     
  289     while ((code = getpwuid_r(uid, pwd, buffer, bufsize, result)) == EINTR)
  290     ;
  291     
  292 #endif
  293     
  294     return code;
  295     
  296 #else
  297     struct passwd *pp;
  298 
  299     pthread_once(&pwd_once, pwd_lock_init);
  300     pthread_mutex_lock(&pwd_lock);
  301 
  302     pp = getpwuid(uid);
  303     if (pp == NULL)
  304     {
  305     pthread_mutex_unlock(&pwd_lock);
  306 
  307     *result = NULL;
  308     return -1;
  309     }
  310 
  311     memset(pwd, 0, sizeof(*pwd));
  312     
  313     pwd->pw_name = strcopy(pp->pw_name, &buffer, &bufsize);
  314     pwd->pw_passwd = strcopy(pp->pw_passwd, &buffer, &bufsize);
  315     pwd->pw_uid = pp->pw_uid;
  316     pwd->pw_gid = pp->pw_gid;
  317     pwd->pw_gecos = strcopy(pp->pw_gecos, &buffer, &bufsize);
  318     pwd->pw_dir = strcopy(pp->pw_dir, &buffer, &bufsize);
  319     pwd->pw_shell = strcopy(pp->pw_shell, &buffer, &bufsize);
  320 
  321     *result = pwd;
  322     
  323     pthread_mutex_unlock(&pwd_lock);
  324     
  325     return 0;
  326 #endif
  327 }
  328 
  329 
  330 
  331 int
  332 s_strcasecmp(const char *s1, const char *s2)
  333 {
  334     int i;
  335 
  336     while ((i = (*s1 - *s2)) == 0 && *s1)
  337     {
  338     ++s1;
  339     ++s2;
  340     }
  341 
  342     return i;
  343 }
  344 
  345     
  346 
  347 void
  348 s_openlog(const char *ident, int logopt, int facility)
  349 {
  350     openlog(ident, logopt
  351 #ifdef LOG_DAEMON
  352         , facility
  353 #endif
  354         );
  355 }
  356 
  357 
  358 #ifdef LOG_KERN
  359 static struct logfacname
  360 {
  361     const char *name;
  362     int code;
  363 } facility[] =
  364 {
  365     { "kern",   LOG_KERN },
  366     { "user",   LOG_USER },
  367     { "mail",   LOG_MAIL },
  368     { "daemon", LOG_DAEMON },
  369     { "auth",   LOG_AUTH },
  370     { "syslog", LOG_SYSLOG },
  371     { "lpr",    LOG_LPR },
  372 #ifdef LOG_NEWS
  373     { "news",   LOG_NEWS },
  374 #endif
  375 #ifdef LOG_UUCP
  376     { "uucp",   LOG_UUCP },
  377 #endif
  378 #ifdef LOG_CRON
  379     { "cron",   LOG_CRON },
  380 #endif
  381     { "local0", LOG_LOCAL0 },
  382     { "local1", LOG_LOCAL1 },
  383     { "local2", LOG_LOCAL2 },
  384     { "local3", LOG_LOCAL3 },
  385     { "local4", LOG_LOCAL4 },
  386     { "local5", LOG_LOCAL5 },
  387     { "local6", LOG_LOCAL6 },
  388     { "local7", LOG_LOCAL7 },
  389     { NULL, -1 }
  390 };
  391 
  392 
  393 int
  394 syslog_str2fac(const char *name)
  395 {
  396     int i;
  397 
  398     if (name == NULL)
  399     return -1;
  400     
  401     for (i = 0; facility[i].name != NULL &&
  402          s_strcasecmp(facility[i].name, name) != 0; i++)
  403     ;
  404 
  405     return facility[i].code;
  406 }
  407 
  408 #else /* !LOG_KERN */
  409 
  410 int
  411 syslog_str2fac(const char *name)
  412 {
  413     return 0;
  414 }
  415 #endif
  416 
  417 
  418 #ifdef LOG_EMERG
  419 static struct loglevname
  420 {
  421     const char *name;
  422     int level;
  423 } level[] =
  424 {
  425     { "emerg",   LOG_EMERG },
  426     { "alert",   LOG_ALERT },
  427     { "crit",    LOG_CRIT },
  428     { "err",     LOG_ERR },
  429     { "warning", LOG_WARNING },
  430     { "notice",  LOG_NOTICE },
  431     { "info",    LOG_INFO },
  432     { "debug",   LOG_DEBUG },
  433 
  434     { NULL, -1 }
  435 };
  436 
  437 
  438 int
  439 syslog_str2lev(const char *name)
  440 {
  441     int i;
  442 
  443     if (name == NULL)
  444     return -1;
  445     
  446     for (i = 0; level[i].name != NULL &&
  447          s_strcasecmp(level[i].name, name) != 0; i++)
  448     ;
  449 
  450     return level[i].level;
  451 }
  452 
  453 #else /* !LOG_KERN */
  454 
  455 int
  456 syslog_str2fac(const char *name)
  457 {
  458     return 0;
  459 }
  460 #endif
  461 
  462 
  463 
  464 /*
  465 ** An MT-safe version of inet_ntoa() for IPv4/inet_ntop() for IPv6 (is safe)
  466 */
  467 const char *
  468 s_inet_ntox(struct sockaddr_gen *ia,
  469         char *buf,
  470         size_t bufsize)
  471 {
  472 
  473 #ifdef HAVE_IPV6
  474     return inet_ntop(SGFAM(*ia), SGADDRP(*ia), buf, bufsize);
  475 #else
  476     unsigned char *bp;
  477 
  478     bp = (unsigned char *) SGADDRP(*ia);
  479     
  480     if (s_snprintf(buf, bufsize, "%u.%u.%u.%u", bp[0], bp[1], bp[2], bp[3]) < 0)
  481     return NULL;
  482 
  483     return buf;
  484 #endif
  485 }