utils.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 2006-2007
00005  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00006  *
00007  * $Id: pcscdaemon.c 2377 2007-02-05 13:13:56Z rousseau $
00008  */
00009 
00015 #include <stdio.h>
00016 #include <sys/types.h>
00017 #include <unistd.h>
00018 #include <errno.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <signal.h>
00022 #include <dirent.h>
00023 #include <fcntl.h>
00024 
00025 #include "debug.h"
00026 #include "config.h"
00027 #include "utils.h"
00028 #include "pcscd.h"
00029 #include "sys_generic.h"
00030 
00031 pid_t GetDaemonPid(void)
00032 {
00033     FILE *f;
00034     pid_t pid;
00035 
00036     /* pids are only 15 bits but 4294967296
00037      * (32 bits in case of a new system use it) is on 10 bytes
00038      */
00039     if ((f = fopen(PCSCLITE_RUN_PID, "rb")) != NULL)
00040     {
00041         char pid_ascii[PID_ASCII_SIZE];
00042 
00043         (void)fgets(pid_ascii, PID_ASCII_SIZE, f);
00044         (void)fclose(f);
00045 
00046         pid = atoi(pid_ascii);
00047     }
00048     else
00049     {
00050         Log2(PCSC_LOG_CRITICAL, "Can't open " PCSCLITE_RUN_PID ": %s",
00051             strerror(errno));
00052         return -1;
00053     }
00054 
00055     return pid;
00056 } /* GetDaemonPid */
00057 
00058 int SendHotplugSignal(void)
00059 {
00060     pid_t pid;
00061 
00062     pid = GetDaemonPid();
00063 
00064     if (pid != -1)
00065     {
00066         Log2(PCSC_LOG_INFO, "Send hotplug signal to pcscd (pid=%d)", pid);
00067         if (kill(pid, SIGUSR1) < 0)
00068         {
00069             Log3(PCSC_LOG_CRITICAL, "Can't signal pcscd (pid=%d): %s",
00070                 pid, strerror(errno));
00071             return EXIT_FAILURE ;
00072         }
00073         (void)SYS_Sleep(1);
00074     }
00075 
00076     return EXIT_SUCCESS;
00077 } /* SendHotplugSignal */
00078 
00087 int StatSynchronize(struct pubReaderStatesList *readerState)
00088 {
00089     DIR *dir_fd;
00090     struct dirent *dir;
00091 
00092     if (readerState)
00093         (void)SYS_MMapSynchronize((void *)readerState, SYS_GetPageSize() );
00094 
00095     dir_fd = opendir(PCSCLITE_EVENTS_DIR);
00096     if (NULL == dir_fd)
00097     {
00098         Log2(PCSC_LOG_ERROR, "Can't opendir " PCSCLITE_EVENTS_DIR ": %s",
00099             strerror(errno));
00100         return -1;
00101     }
00102 
00103     while ((dir = readdir(dir_fd)) != NULL)
00104     {
00105         char filename[FILENAME_MAX];
00106         int fd;
00107         char buf[] = { '\0' };
00108         struct stat fstat_buf;
00109 
00110         if ('.' == dir->d_name[0])
00111             continue;
00112 
00113         (void)snprintf(filename, sizeof(filename), "%s/%s", PCSCLITE_EVENTS_DIR,
00114             dir->d_name);
00115         Log2(PCSC_LOG_DEBUG, "status file: %s", filename);
00116 
00117         fd = SYS_OpenFile(filename, O_WRONLY | O_APPEND | O_NONBLOCK, 0);
00118         if (fd < 0)
00119         {
00120             /* ENXIO "No such device or address" is a normal error
00121              * if the client is no more listening the pipe */
00122             Log3(ENXIO == errno ? PCSC_LOG_DEBUG : PCSC_LOG_ERROR,
00123                 "Can't open %s: %s", filename, strerror(errno));
00124         }
00125         else
00126         {
00127             if (fstat(fd, &fstat_buf))
00128             {
00129                 Log3(PCSC_LOG_ERROR, "Can't fstat %s: %s", filename,
00130                     strerror(errno));
00131             }
00132             else
00133             {
00134                 /* check that the file is a FIFO */
00135                 if (!(fstat_buf.st_mode & S_IFIFO))
00136                     Log2(PCSC_LOG_ERROR, "%s is not a fifo", filename);
00137                 else
00138                     (void)SYS_WriteFile(fd, buf, sizeof(buf));
00139             }
00140 
00141             (void)SYS_CloseFile(fd);
00142         }
00143 
00144         if (unlink(filename))
00145             Log3(PCSC_LOG_ERROR, "Can't remove %s: %s", filename,
00146             strerror(errno));
00147     }
00148     (void)closedir(dir_fd);
00149 
00150     return 0;
00151 } /* StatSynchronize */
00152 
00153 
00162 int StatSynchronizeContext(SCARDCONTEXT hContext)
00163 {
00164     char filename[FILENAME_MAX];
00165     int fd;
00166     char buf[] = { '\0' };
00167     struct stat fstat_buf;
00168 
00169     (void)snprintf(filename, sizeof(filename), "%s/event.%d.%ld",
00170         PCSCLITE_EVENTS_DIR, SYS_GetPID(), hContext);
00171     (void)mkfifo(filename, 0644);
00172     fd = SYS_OpenFile(filename, O_WRONLY, 0);
00173 
00174     if (fstat(fd, &fstat_buf))
00175     {
00176         Log3(PCSC_LOG_ERROR, "Can't fstat %s: %s", filename, strerror(errno));
00177     }
00178     else
00179     {
00180         /* check that the file is a FIFO */
00181         if (!(fstat_buf.st_mode & S_IFIFO))
00182             Log2(PCSC_LOG_ERROR, "%s is not a fifo", filename);
00183         else
00184             (void)SYS_WriteFile(fd, buf, sizeof(buf));
00185     }
00186 
00187     (void)SYS_CloseFile(fd);
00188 
00189     return 0;
00190 } /* StatSynchronize */
00191 
00192 
00200 #define OPENCT_FILE "/var/run/openct/status"
00201 int CheckForOpenCT(void)
00202 {
00203     struct stat buf;
00204 
00205     if (0 == stat(OPENCT_FILE, &buf))
00206     {
00207         Log1(PCSC_LOG_CRITICAL, "Remove OpenCT and try again");
00208         return 1;
00209     }
00210 
00211     return 0;
00212 } /* CheckForOpenCT */
00213 

Generated on Mon Aug 17 01:00:11 2009 for pcsc-lite by  doxygen 1.5.9