#include #include #include #include #include #include #include #include #include #include #include #include #include int logfd,portfd; char *log_name = NULL; char *pidfile_name = NULL; FILE *pidfd = NULL; int main (int argc, char *argv[]) { int i,rc,nread,kq,fflag,flag; pid_t pid; struct kevent ke[4]; struct termios options; char s[512]; char *speed = NULL; char *dev_name = NULL; pidfile_name = "/var/run/logserial.pid"; opterr = 0; fflag = 0; speed = "9600"; while ((flag = getopt(argc, argv, "d:s:l:p:f")) != -1) { switch (flag) { case 'd': dev_name = optarg; break; case 's': speed = optarg; break; case 'l': log_name = optarg; break; case 'p': pidfile_name = optarg; break; case 'f': fflag = 1; break; case '?': if (isprint(optopt)) fprintf(stderr, "Unknown option -%c'.\n", optopt); else fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); return 1; default: break; } } for (; optind < argc; optind++) printf("%s", argv [optind]); if ((dev_name == NULL) | (log_name == NULL)) { printf("usage: logserial -d device name [-s speed of connection] -l logfile name [-f run in foreground][-p pid file]\n"); exit(1); } if (fflag == 0) if (daemon(0, 0) == -1) { openlog("logserial", LOG_PID, LOG_DAEMON); syslog(LOG_ERR, strerror(errno)); exit(1); } pid = getpid(); printf("%d\n", pid); pidfd = fopen(pidfile_name, "w+"); if (pidfd == NULL) { openlog("logserial", LOG_PID, LOG_DAEMON); syslog(LOG_ERR, strerror(errno)); exit(1); } fprintf(pidfd, "%d\n", pid); fclose(pidfd); portfd = open(dev_name, O_RDONLY | O_NOCTTY | O_NDELAY ); if (portfd == -1) { syslog(LOG_ERR, strerror(errno)); exit(1); } tcgetattr(portfd, &options); if (cfsetspeed(&options,strtol(speed, NULL, 10)) == -1) { syslog(LOG_ERR, strerror(errno)); exit(1); } options.c_lflag &= ~ICANON; if (tcsetattr(portfd, TCSANOW, &options) != 0) { syslog(LOG_ERR, strerror(errno)); exit(1); } if ((kq = kqueue())== -1) { syslog(LOG_ERR, strerror(errno)); exit(1); } bzero(&ke, sizeof(ke)); EV_SET(&ke[0], portfd, EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, NULL); EV_SET(&ke[1], SIGHUP, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); EV_SET(&ke[2], SIGTERM, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); EV_SET(&ke[3], SIGINT, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); if (kevent(kq, ke, 4, NULL, 0, NULL) == -1 ) { syslog(LOG_ERR, strerror(errno)); exit(1); } bzero(&ke, sizeof(ke)); if (fcntl(portfd, F_SETFL, FNDELAY | O_NONBLOCK) == -1) { syslog(LOG_ERR, strerror(errno)); exit(1); } logfd = open(log_name, O_RDWR | O_APPEND | O_CREAT, 0666); if (logfd == -1) { syslog(LOG_ERR, strerror(errno)); exit(1); } signal(SIGHUP,SIG_IGN); signal(SIGTERM,SIG_IGN); signal(SIGINT,SIG_IGN); for (;;) { if ((rc=kevent(kq, NULL, 0, ke, 1, NULL)) == -1) { if (errno == EINTR) { syslog(LOG_ERR, "Interrupted kevent call. Strange."); continue; } else { syslog(LOG_ERR, strerror(errno)); exit(1); } } for (i=0; i