pcsc-lite 1.5.5
|
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 (!S_ISFIFO(fstat_buf.st_mode)) 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 /* remove files older than 60 seconds */ 00145 if ((difftime(time(NULL), fstat_buf.st_atime) > 60) && unlink(filename)) 00146 Log3(PCSC_LOG_ERROR, "Can't remove %s: %s", filename, 00147 strerror(errno)); 00148 } 00149 (void)closedir(dir_fd); 00150 00151 return 0; 00152 } /* StatSynchronize */ 00153 00154 00163 int StatSynchronizeContext(SCARDCONTEXT hContext) 00164 { 00165 char filename[FILENAME_MAX]; 00166 int fd; 00167 char buf[] = { '\0' }; 00168 struct stat fstat_buf; 00169 00170 (void)snprintf(filename, sizeof(filename), "%s/event.%d.%ld", 00171 PCSCLITE_EVENTS_DIR, SYS_GetPID(), hContext); 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