"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/kernel.c" (13 Jun 2004, 3469 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 "kernel.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** kernel.c - The kernel access threads
    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 <errno.h>
   19 #include <syslog.h>
   20 #include <string.h>
   21 #include <stdlib.h>
   22 
   23 #ifdef HAVE_UNISTD_H
   24 #include <unistd.h>
   25 #endif
   26 
   27 #include <sys/types.h>
   28 #include <netinet/in.h>
   29 #include <arpa/inet.h>
   30 
   31 #include "pidentd.h"
   32 
   33 
   34 int kernel_threads = 4;
   35 int kernel_buffers = 16;
   36 int kernel_attempts = 5;
   37 
   38 
   39 static buffer_t kbuf_request;
   40 static buffer_t kbuf_free;
   41 
   42 
   43 #ifndef HAVE_THREADS
   44 static void *ka_data = NULL;
   45 #endif
   46 
   47 
   48 struct kernel *
   49 kernel_alloc(void)
   50 {
   51     struct kernel *kp;
   52     
   53     kp = (struct kernel *) buffer_get(&kbuf_free);
   54     
   55     avail_init(&kp->av);
   56     
   57     kp->status = -1;
   58     kp->euid = NO_UID;
   59     kp->ruid = NO_UID;
   60 
   61     kp->pid = NO_PID;
   62     kp->cmd = NULL;
   63     kp->argv = NULL;
   64     
   65     return kp;
   66 }
   67 
   68 
   69 void
   70 kernel_free(struct kernel *kp)
   71 {
   72     s_free(kp->cmd);
   73     s_free(kp->argv);
   74     
   75     buffer_put(&kbuf_free, kp);
   76 }
   77 
   78 
   79 static void *
   80 kernel_thread(void *vp)
   81 {
   82     struct kernel *kp;
   83     int attempt;
   84     char buf1[32];
   85 
   86     
   87     if (debug)
   88     fprintf(stderr, "kernel_thread() started\n");
   89 
   90     while ((kp = (struct kernel *) buffer_get(&kbuf_request)) != NULL)
   91     {
   92     if (debug)
   93     {
   94         fprintf(stderr, "remote = %s:%d\n",
   95             s_inet_ntox(&kp->remote, buf1, sizeof(buf1)),
   96             ntohs(SGPORT(kp->remote)));
   97         
   98         fprintf(stderr, "local = %s:%d\n",
   99             s_inet_ntox(&kp->local, buf1, sizeof(buf1)),
  100             ntohs(SGPORT(kp->local)));
  101     }
  102 
  103     attempt = 0;
  104     while (attempt++ < kernel_attempts)
  105     {
  106         kp->status = ka_lookup(vp, kp);
  107         if (debug)
  108         fprintf(stderr, "ka_lookup(), attempt = %d, status = %d\n",
  109             attempt, kp->status);
  110         if (kp->status > 0)
  111         break;
  112 
  113         if (attempt > 2 && (attempt & 1) == 1)
  114         sleep(1); /* Wait for kernel structures to stabilize */
  115     }
  116 
  117     avail_signal(&kp->av);
  118 #ifndef HAVE_THREADS
  119     break;
  120 #endif
  121     }
  122     
  123     if (debug)
  124     fprintf(stderr, "kernel_thread() terminating\n");
  125 
  126     return NULL;
  127 }
  128 
  129 
  130 int
  131 kernel_init(void)
  132 {
  133     int i;
  134     pthread_t tid;
  135     struct kernel *kp;
  136     
  137 
  138     /*
  139     ** Create the request queue
  140     */
  141     if (buffer_init(&kbuf_request, kernel_buffers) < 0)
  142     {
  143     syslog(LOG_ERR, "buffer_create(%d) failed: %m", kernel_buffers);
  144     return -1;
  145     }
  146 
  147 
  148     /*
  149     ** Create the free pool of buffers
  150     */
  151     if (buffer_init(&kbuf_free, kernel_buffers * 2) < 0)
  152     {
  153     syslog(LOG_ERR, "buffer_create(%d) failed: %m", kernel_buffers * 2);
  154     return -1;
  155     }
  156 
  157     for (i = 0; i < kernel_buffers * 2; i++)
  158     {
  159     kp = s_malloc(sizeof(*kp));
  160     buffer_put(&kbuf_free, kp);
  161     }
  162 
  163 
  164 #ifdef HAVE_THREADS
  165     /*
  166     ** Create the kernel accessing thread workpool
  167     */
  168     for (i = 0; i < kernel_threads; i++)
  169     {
  170     void *key = NULL;
  171 
  172     if (ka_open(&key) < 0)
  173         return -1;
  174     
  175     pthread_create(&tid, NULL, &kernel_thread, key);
  176     }
  177     
  178     return 0;
  179 #else
  180     /*
  181     ** Open the kernel devices
  182     */
  183     return ka_open(&ka_data);
  184 #endif
  185 }
  186 
  187 
  188 void
  189 kernel_query(struct kernel *kp)
  190 {
  191     buffer_put(&kbuf_request, kp);
  192 
  193 #ifdef HAVE_THREADS
  194     avail_wait(&kp->av);
  195 #else
  196     kernel_thread(ka_data);
  197 #endif
  198 }
  199 
  200