*/ DEVICE_CMD Quit_IO(REBREQ *dr) /* ***********************************************************************/ { REBDEV *dev = (REBDEV*)dr; // just to keep compiler happy above close_stdio(); CLR_FLAG(dev->flags, RDF_OPEN); return DR_DONE; }
*/ DEVICE_CMD Close_IO(REBREQ *req) /* ***********************************************************************/ { REBDEV *dev = Devices[req->device]; close_stdio(); CLR_FLAG(req->flags, RRF_OPEN); return DR_DONE; }
int main(int argc, char **argv) { int c; int sockfd; struct sockaddr_in servaddr, cliaddr; int n; socklen_t len; char msg[MAX_MSG_LENGTH]; int i; settings_init(); /* process arguments */ while (-1 != (c = getopt(argc, argv, "hp:dl:Lc:n:e:v"))) { switch (c) { case 'h': showusage(); exit(EXIT_SUCCESS); break; case 'p': settings.port = atoi(optarg); break; case 'd': settings.daemon = 1; break; case 'l': settings.ipaddr = strdup(optarg); break; case 'L': settings.localonly = 1; break; case 'c': settings.workernum = atoi(optarg); break; case 'n': settings.queuesize = atoi(optarg); break; case 'e': settings.exepath = strdup(optarg); break; case 'v': settings.verbose++; break; default: //fprintf(stderr, "unknown option -- '%c'\n", c); return 1; } } if (settings.port < 1) { fprintf(stderr, "please use '-p' to specify a port(>1) to listen to\n"); exit(-1); } if (settings.workernum < 1) { fprintf(stderr, "please use '-c' to specify max num(>1) of concurrent workers\n"); exit(-1); } if (settings.queuesize < 1) { fprintf(stderr, "please use '-n' to specify queue size(>1)\n"); exit(-1); } if (settings.exepath == NULL || settings.exepath[0] == '\0') { fprintf(stderr, "empty 'script path', use '-e' to specify it\n"); exit(-1); } if (access(settings.exepath, R_OK | X_OK) != 0) { fprintf(stderr, "script not readble or executable: %s\n", strerror(errno)); exit(-1); } /* print setttngs */ printf("settings:\n"); printf("\tlisten port: %d\n", settings.port); printf("\tdaemon mode: %s\n", ON_OFF(settings.daemon)); printf("\tlisten addr: %s\n", (settings.ipaddr != NULL) ? settings.ipaddr : "INADDR_ANY"); printf("\tlocal only: %s\n", ON_OFF(settings.localonly)); printf("\tworker num %d\n", settings.workernum); printf("\tqueue size %d\n", settings.queuesize); printf("\tscript path: '%s'\n", settings.exepath); printf("\tverbose: %s\n", ON_OFF(settings.verbose)); /* allocate space for queue */ id_queue = (int*)malloc(sizeof(int) * settings.queuesize); if (id_queue == NULL) { fprintf(stderr, "can not allocate memory for id queue\n"); exit(-1); } for (i = 0; i < MAX_IFNUM; i++) { ipaddrs[i] = (char*)malloc(20); bzero(ipaddrs[i], 20); } ifnum = getaddrs(ipaddrs); if (ifnum <= 0) { fprintf(stderr, "can not get ip address of interface(s)\n"); exit(EXIT_FAILURE); } else if (settings.verbose > 0) { printf("ip address of interface(s):\n"); for (i = 0; i < ifnum; i++) { printf("\t%s\n", ipaddrs[i]); } } if (settings.daemon) { if (daemonize()) { fprintf(stderr, "can't run as daemon\n"); exit(EXIT_FAILURE); } printf("run as daemon\n"); } sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { perror("socket error: "); exit(EXIT_FAILURE); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; if (settings.ipaddr != NULL) { if (inet_aton(settings.ipaddr, &(servaddr.sin_addr)) == 0) { fprintf(stderr, "invalid ip address to listen: %s\n", settings.ipaddr); exit(EXIT_FAILURE); } } else { servaddr.sin_addr.s_addr = htonl(INADDR_ANY); } servaddr.sin_port = htons(settings.port); if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) { perror("bind error: "); exit(EXIT_FAILURE); } pthread_mutex_init(&lock, NULL); pthread_cond_init(&cond, NULL); pthread_mutex_init(&workerlock, NULL); pthread_cond_init(&workercond, NULL); pthread_mutex_init(&reaperlock, NULL); pthread_cond_init(&reapercond, NULL); /* start thread to reap children */ do { pthread_t t; pthread_attr_t attr; pthread_attr_init(&attr); if (pthread_create(&t, &attr, reaper_worker, NULL) != 0) { perror("pthread_create error: "); exit(EXIT_FAILURE); } } while (0); /* start thread to scan queue */ do { pthread_t t; pthread_attr_t attr; pthread_attr_init(&attr); if (pthread_create(&t, &attr, scan_worker, NULL) != 0) { perror("pthread_create error: "); exit(EXIT_FAILURE); } } while (0); /* close stdio if verbose == 0*/ if (close_stdio(settings.verbose)) { fprintf(stderr, "can't close fd: 0, 1, 2\n"); exit(EXIT_FAILURE); } len = sizeof(cliaddr); while (1) { n = recvfrom(sockfd, msg, MAX_MSG_LENGTH, 0, (struct sockaddr *)&cliaddr, &len); if (n < 1) { if (settings.verbose > 0) { fprintf(stderr, "recvfrom error\n"); } continue; } if (settings.localonly) { char *from = inet_ntoa(cliaddr.sin_addr); if (is_local_ip(from)) { if (settings.verbose > 0) { fprintf(stderr, "deny msg from %s\n", from); } continue; } } msg[n] = '\0'; if (settings.verbose > 0) { handle_msg(msg, n, inet_ntoa(cliaddr.sin_addr)); } else { handle_msg(msg, n, NULL); } /* sendto(sockfd, msg, n, 0, (struct sockaddr *)&cliaddr, len); */ } return 0; }