int main(int argc, char * argv[]) { server_configuration config; bzero(&config, sizeof(config)); if(!network_subsystem_init()) { fprintf(stderr, "Network subsystem init failed.\n"); return error_network_subsystem; } if(!read_configuration(argc, argv, &config)) { fprintf(stderr, PROG_NAME ": configuration error! Exit.\n"); return error_config; } if(config.discover) interfaces_discover(0); if(config.print_header_offsets) { print_dhcp_header_offsets(); return 0; } if(!log_init(config.log_file_name, (config.debug_mode ? LOG_DEBUG_FLAG : 0) | (config.log_stdout ? LOG_STDOUT_FLAG : 0), config.uid) ) { fprintf(stderr, "Can't open log file.\n"); return error_log; } log_wr(ILOG, "Program " PROG_NAME " " PROG_VERS " " PROG_DESC " started."); struct sigaction sig_handler_s; sig_handler_s.sa_handler = sig_handler; sigemptyset(&sig_handler_s.sa_mask); sig_handler_s.sa_flags = 0; if(config.daemon) daemonize(); /* Init DHCP cache */ if(config.cache_ttl && !dhcp_cache_init(config.cache_ttl)) { log_wr(CLOG, "Can't init DHCP cache. Exit."); return error_abnormal; } /* STARTING DATABASE CLIENTS */ /* Create array of childen threads */ request_handler_thread_t **handler_threads = (request_handler_thread_t **) malloc(sizeof(request_handler_thread_t *) * config.db_clients_count); CHECK_VALUE(handler_threads, "Can't allocate memory for array of children threads for connecting to DB.", error_memory); /* Create DHCP messages queue */ config.dhcp_queue = dhcp_queue_create("DHCP requests", YES, DEFAULT_QUEUE_MAX_SIZE); CHECK_VALUE(config.dhcp_queue, "Can't create DHCP queue.", error_queue_init); /* Running DB clients */ CHECK_VALUE(run_requests_handlers(handler_threads, &config), "", error_run_db_clients); /* STARTING DHCP PROCESSES */ dhcp_proc_thread_t **dhcp_threads = (dhcp_proc_thread_t**) malloc(sizeof(dhcp_proc_thread_t *) * config.if_count); CHECK_VALUE(dhcp_threads, "Can't allocate memory for array of children threads for " "processing DHCP clients.", error_run_dhcp_procs); CHECK_VALUE(run_dhcp_threads(dhcp_threads, &config, handler_threads), "", error_run_dhcp_procs); /* Set signal handlers */ if( sigaction(SIGINT, &sig_handler_s, NULL) || sigaction(SIGTERM, &sig_handler_s, NULL) || sigaction(SIGUSR1, &sig_handler_s, NULL)) { log_wr(CLOG, "Can't set signal handlers: '%s'", strerror(errno)); return error_abnormal; } #ifndef _WIN32 if(config.uid) { log_wr(DLOG, "Set effective and real user ID to %u.", config.uid); if(setreuid(config.uid, config.uid)) { log_wr(CLOG, "Can't execute setreuid(%u): '%s'", config.uid, strerror(errno)); return 0; } } else log_wr(WLOG, "Running with uid 0 - it is not safe!!! Use configuration directive 'User' for set uid."); #endif int i; for(i = 0; i < config.if_count; ++i) pthread_join(dhcp_threads[i]->thread_id, 0); log_wr(ILOG, "All DHCP threads finished"); for(i = 0; i < config.db_clients_count; ++i) pthread_join(handler_threads[i]->thread_id, 0); log_wr(ILOG, "All DB threads finished."); /* Cleaning up */ /* TODO 30 Need gracefull cleanup database connections and free all allocated memory */ log_wr(ILOG, "Program exited."); log_close(); return EXIT_SUCCESS; }
int main(int argc, char** argv) { int ifd, len = 0, i = 0, selectret = 0, maxfd, retryselect, pid; char buf[BUF_LEN]; char *configdir; char *pidfilename; char *statusfilename; char *statusbin; char *error_str; char *version_str = PACKAGE_STRING; char *pbuf; char *filename; FILE *pidfile; FILE *statusfile; fd_set set; struct inotify_event *event; struct argument *argument = argument_new(); struct pipe_list *pipe_list_cur; struct stat file_stat; struct watchnode *node; /* alloc pipe list */ pipe_list_head = malloc(sizeof(struct pipe_list)); pipe_list_head->next = NULL; /* set up signals for exiting/reaping */ signal(SIGINT, &handle_quit_signal); signal(SIGTERM, &handle_quit_signal); signal(SIGCHLD, &handle_child_signal); signal(SIGHUP, &handle_hup_signal); /* add command line arguments */ argument_register(argument, "help", "Prints this help text.", 0); argument_register(argument, "version", "Prints version information.", 0); argument_register(argument, "daemon", "Run as a daemon.", 0); argument_register(argument, "verbose", "Turns on debug text.", 0); argument_register(argument, "sync", "Sync mode (for debugging).", 0); argument_register(argument, "log-to-stdout", "Deprecated, use \"--log-to=stdout\" instead", 0); argument_register(argument, "log-to", "Log messages with specified way. " #ifdef USE_SYSLOG "Can be: stdout, file, syslog. \"file\" by default.", 1); #else "Can be: stdout, file. \"file\" by default.", 1); #endif if ((error_str = argument_parse(argument, argc, argv))) { fprintf(stderr, "Error in arguments: %s", error_str); free(error_str); return -1; } if (argument_exists(argument, "help")) { char *help_txt = argument_get_help_text(argument); printf("%s", help_txt); free(help_txt); return 0; } if (argument_exists(argument, "version")) { printf("%s\n", version_str); return 0; } if (argument_exists(argument, "verbose")) { verbose = 1; } if (argument_exists(argument, "daemon") && fork()) return 0; if (argument_exists(argument, "sync")) syncmode = 1; if (argument_exists(argument, "log-to-stdout")) fprintf(stderr, "Warning, this option is deprecated, " \ "please use new syntax: \"--log-to=stdout\".\n"); logtype = LOG_FILE; if (argument_exists(argument, "log-to") && \ (log_arg = argument_get_value(argument, "log-to")) != NULL) { if (strcmp(log_arg, "stdout") == 0) logtype = LOG_STDOUT; #ifdef USE_SYSLOG else if (strcmp(log_arg, "syslog") == 0) logtype = LOG_SYS; #endif else /* logtype already set to 'file' above */ fprintf(stderr, "Warning, selected unknown logging type. " \ "Will use \"--log-to=file\" instead.\n"); } /* get config dir (must free this) */ configdir = get_config_dir(); /* if a config file has not been specified, use default */ if (argument_get_extra(argument)) { configfile = strdup(argument_get_extra(argument)); } else { configfile = malloc (strlen(configdir) + strlen ("/config") + 1); sprintf(configfile, "%s/config", configdir); } argument_free(argument); free(configdir); if (access(configfile, R_OK) != 0) { fprintf(stderr, "error: could not open config file: %s\n", configfile); return -1; } /* create a pid file */ pidfilename = get_pid_filename(); if (stat(pidfilename, &file_stat) == 0) /* pidfile exists */ { pidfile = fopen(pidfilename, "r"); if (fscanf(pidfile, "%d", &pid) == 1) /* pidfile has a pid inside */ { char *binaryname; char *scanformat; if ((binaryname = strrchr(argv[0], '/')) != NULL) { binaryname++; } else { binaryname = argv[0]; } scanformat = malloc(strlen("Name: %") + strlen(binaryname) + strlen("s") + 1); statusfilename = malloc(strlen("/proc/") + 6 + strlen("/status") + 1); sprintf(statusfilename, "/proc/%d/status", pid); if (stat(statusfilename, &file_stat) != 0) /* write pid file if the process no longer exists */ { write_pid_file(pidfilename); } else /* process exists, so check owner and binary name */ { statusfile = fopen(statusfilename, "r"); statusbin = malloc(strlen(binaryname) + 2); /* the binary name may start with "fsniper" but be longer */ sprintf(scanformat, "Name: %%%ds", strlen(binaryname) + 1); fscanf(statusfile, scanformat, statusbin); free(statusfilename); fclose(statusfile); fclose(pidfile); if (strcmp(binaryname, statusbin) == 0 && file_stat.st_uid == getuid()) /* exit if the process is fsniper and is owned by the current user */ { printf("%s: already running instance found with pid %d. exiting.\n", binaryname, pid); exit(1); } else /* the pid file contains an old pid, one that isn't fsniper, or one not owned by the current user */ { write_pid_file(pidfilename); } } } else /* pidfile is invalid */ { fclose(pidfile); write_pid_file(pidfilename); } } else /* the pidfile doesn't exist */ { write_pid_file(pidfilename); } free(pidfilename); /* start up log */ if (!log_open()) { fprintf(stderr, "Error: could not start log.\n"); return -1; } ifd = inotify_init(); if (ifd < 0) { perror("inotify_init"); return -1; } if (verbose) log_write("Parsing config file: %s\n", configfile); config = keyval_parse_file(configfile); if ((error_str = keyval_get_error())) { fprintf(stderr, "%s", error_str); free(error_str); exit(1); } validate_config(config); /* add nodes to the inotify descriptor */ g_watchnode = add_watches(ifd); /* wait for events and then handle them */ while (1) { /* set up fds and max */ FD_ZERO(&set); FD_SET(ifd, &set); maxfd = ifd; for (pipe_list_cur = pipe_list_head->next; pipe_list_cur; pipe_list_cur = pipe_list_cur->next) { FD_SET(pipe_list_cur->pfd[0], &set); if (pipe_list_cur->pfd[0] > maxfd) maxfd = pipe_list_cur->pfd[0]; } retryselect = 1; while (retryselect) { /* use select to get activity on any of the fds */ selectret = select(maxfd + 1, &set, NULL, NULL, NULL); if (selectret == -1) { if (errno == EINTR) retryselect = 1; else handle_quit_signal(-2); } else retryselect = 0; } /* handle any events on the inotify fd */ if (FD_ISSET(ifd, &set)) { len = read(ifd, buf, BUF_LEN); while (i < len) { event = (struct inotify_event *) &buf[i]; if (event->len && (event->mask & IN_CLOSE_WRITE || event->mask & IN_MOVED_TO)) { /* if sync mode, just call handle_exec */ if (syncmode == 1) { handle_event(event, fileno(_logfd)); } else { /* create new pipe_list entry */ for (pipe_list_cur = pipe_list_head; pipe_list_cur->next != NULL; pipe_list_cur = pipe_list_cur->next) {} pipe_list_cur->next = malloc(sizeof(struct pipe_list)); pipe_list_cur->next->next = NULL; /* create pipe */ pipe(pipe_list_cur->next->pfd); if (fork() == 0) { /* child, close 0 */ close(pipe_list_cur->next->pfd[0]); log_close(); signal(SIGINT, &handle_child_quit_signal); signal(SIGTERM, &handle_child_quit_signal); handle_event(event, pipe_list_cur->next->pfd[1]); } else { /* parent, close 1 */ close(pipe_list_cur->next->pfd[1]); } } } else if (event->len && (event->mask & IN_CREATE && event->mask & IN_ISDIR)) { for (node = g_watchnode->next; node; node = node->next) if (node->wd == event->wd) break; if (node) { /* combine the name inotify gives with the full path to the file */ filename = malloc(strlen(node->path) + strlen("/") + strlen(event->name) + 1); sprintf(filename, "%s/%s", node->path, event->name); watch_dir(node, ifd, strdup(filename), node->section); free(filename); } } else if (event->len && (event->mask & IN_DELETE && event->mask & IN_ISDIR)) { for (node = g_watchnode->next; node; node = node->next) if (node->wd == event->wd) break; if (node) { /* combine the name inotify gives with the full path to the file */ filename = malloc(strlen(node->path) + strlen("/") + strlen(event->name) + 1); sprintf(filename, "%s/%s", node->path, event->name); unwatch_dir(filename, ifd); free(filename); } } i += EVENT_SIZE + event->len; } i = 0; } /* now lets see if we have any pipe activity */ pipe_list_cur = pipe_list_head->next; while (pipe_list_cur) { if (FD_ISSET(pipe_list_cur->pfd[0], &set)) { len = read(pipe_list_cur->pfd[0], buf, BUF_LEN); if (len == 0) { close(pipe_list_cur->pfd[0]); /* remove this item from the list */ pipe_list_cur = pipe_list_remove(pipe_list_head, pipe_list_cur); } else { /* print it somewhere */ pbuf = malloc(len + 1); snprintf(pbuf, len, "%s", buf); log_write("%s\n", pbuf); free(pbuf); pipe_list_cur = pipe_list_cur->next; } } else { pipe_list_cur = pipe_list_cur->next; } } } }
int run_pelog( int which, /* I (one of PE_*) */ char *specpelog, /* I - script path */ job *pjob, /* I - associated job */ int pe_io_type) /* I */ { struct sigaction act; struct sigaction oldact; char *arg[12]; int fds1 = 0; int fds2 = 0; int fd_input; char resc_list[2048]; char resc_used[2048]; struct stat sbuf; char sid[20]; char exit_stat[11]; int waitst; int isjoined; /* boolean */ char buf[MAXPATHLEN + 1024]; char pelog[MAXPATHLEN + 1024]; uid_t real_uid; gid_t *real_gids = NULL; gid_t real_gid; int num_gids; int jobtypespecified = 0; resource *r; char *EmptyString = ""; int LastArg; int aindex; int rc; char *ptr; int moabenvcnt = 14; /* # of entries in moabenvs */ static char *moabenvs[] = { "MOAB_NODELIST", "MOAB_JOBID", "MOAB_JOBNAME", "MOAB_USER", "MOAB_GROUP", "MOAB_CLASS", "MOAB_TASKMAP", "MOAB_QOS", "MOAB_PARTITION", "MOAB_PROCCOUNT", "MOAB_NODECOUNT", "MOAB_MACHINE", "MOAB_JOBARRAYINDEX", "MOAB_JOBARRAYRANGE" }; if ((pjob == NULL) || (specpelog == NULL) || (specpelog[0] == '\0')) { return(0); } ptr = pjob->ji_wattr[JOB_ATR_jobtype].at_val.at_str; if (ptr != NULL) { jobtypespecified = 1; snprintf(pelog,sizeof(pelog),"%s.%s", specpelog, ptr); } else { snprintf(pelog, sizeof(pelog), "%s", specpelog); } real_uid = getuid(); real_gid = getgid(); if ((num_gids = getgroups(0, real_gids)) < 0) { log_err(errno, __func__, "getgroups failed\n"); return(-1); } /* to support root squashing, become the user before performing file checks */ if ((which == PE_PROLOGUSER) || (which == PE_EPILOGUSER) || (which == PE_PROLOGUSERJOB) || (which == PE_EPILOGUSERJOB)) { real_gids = calloc(num_gids, sizeof(gid_t)); if (real_gids == NULL) { log_err(ENOMEM, __func__, "Cannot allocate memory! FAILURE\n"); return(-1); } if (getgroups(num_gids,real_gids) < 0) { log_err(errno, __func__, "getgroups failed\n"); free(real_gids); return(-1); } /* pjob->ji_grpcache will not be set if using LDAP and LDAP not set */ /* It is possible that ji_grpcache failed to allocate as well. Make sure ji_grpcache is not NULL */ if (pjob->ji_grpcache != NULL) { if (setgroups( pjob->ji_grpcache->gc_ngroup, (gid_t *)pjob->ji_grpcache->gc_groups) != 0) { snprintf(log_buffer,sizeof(log_buffer), "setgroups() for UID = %lu failed: %s\n", (unsigned long)pjob->ji_qs.ji_un.ji_momt.ji_exuid, strerror(errno)); log_err(errno, __func__, log_buffer); undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(-1); } } else { sprintf(log_buffer, "pjob->ji_grpcache is null. check_pwd likely failed."); log_err(-1, __func__, log_buffer); undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(-1); } if (setegid(pjob->ji_qs.ji_un.ji_momt.ji_exgid) != 0) { snprintf(log_buffer,sizeof(log_buffer), "setegid(%lu) for UID = %lu failed: %s\n", (unsigned long)pjob->ji_qs.ji_un.ji_momt.ji_exgid, (unsigned long)pjob->ji_qs.ji_un.ji_momt.ji_exuid, strerror(errno)); log_err(errno, __func__, log_buffer); undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(-1); } if (seteuid(pjob->ji_qs.ji_un.ji_momt.ji_exuid) != 0) { snprintf(log_buffer,sizeof(log_buffer), "seteuid(%lu) failed: %s\n", (unsigned long)pjob->ji_qs.ji_un.ji_momt.ji_exuid, strerror(errno)); log_err(errno, __func__, log_buffer); undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(-1); } } rc = stat(pelog,&sbuf); if ((rc == -1) && (jobtypespecified == 1)) { snprintf(pelog, sizeof(pelog), "%s", specpelog); rc = stat(pelog,&sbuf); } if (rc == -1) { if (errno == ENOENT || errno == EBADF) { /* epilog/prolog script does not exist */ if (LOGLEVEL >= 5) { static char tmpBuf[1024]; sprintf(log_buffer, "%s script '%s' for job %s does not exist (cwd: %s,pid: %d)", PPEType[which], (pelog != NULL) ? pelog : "NULL", (pjob != NULL) ? pjob->ji_qs.ji_jobid : "NULL", getcwd(tmpBuf, sizeof(tmpBuf)), getpid()); log_record(PBSEVENT_SYSTEM, 0, __func__, log_buffer); } #ifdef ENABLE_CSA if ((which == PE_EPILOGUSER) && (!strcmp(pelog, path_epiloguser))) { /* * Add a workload management end record */ if (LOGLEVEL >= 8) { sprintf(log_buffer, "%s calling add_wkm_end from run_pelog() - no user epilog", pjob->ji_qs.ji_jobid); log_err(-1, __func__, log_buffer); } add_wkm_end(pjob->ji_wattr[JOB_ATR_pagg_id].at_val.at_ll, pjob->ji_qs.ji_un.ji_momt.ji_exitstat, pjob->ji_qs.ji_jobid); } #endif /* ENABLE_CSA */ undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(0); } undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(pelog_err(pjob,pelog,errno,"cannot stat")); } if (LOGLEVEL >= 5) { sprintf(log_buffer,"running %s script '%s' for job %s", PPEType[which], (pelog[0] != '\0') ? pelog : "NULL", pjob->ji_qs.ji_jobid); log_ext(-1, __func__, log_buffer, LOG_DEBUG); /* not actually an error--but informational */ } /* script must be owned by root, be regular file, read and execute by user * * and not writeable by group or other */ if (reduceprologchecks == TRUE) { if ((!S_ISREG(sbuf.st_mode)) || (!(sbuf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))) { undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(pelog_err(pjob,pelog,-1,"permission Error")); } } else { if (which == PE_PROLOGUSERJOB || which == PE_EPILOGUSERJOB) { if ((sbuf.st_uid != pjob->ji_qs.ji_un.ji_momt.ji_exuid) || (!S_ISREG(sbuf.st_mode)) || ((sbuf.st_mode & (S_IRUSR | S_IXUSR)) != (S_IRUSR | S_IXUSR)) || (sbuf.st_mode & (S_IWGRP | S_IWOTH))) { undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(pelog_err(pjob,pelog,-1,"permission Error")); } } else if ((sbuf.st_uid != 0) || (!S_ISREG(sbuf.st_mode)) || ((sbuf.st_mode & (S_IRUSR | S_IXUSR)) != (S_IRUSR | S_IXUSR)) ||\ (sbuf.st_mode & (S_IWGRP | S_IWOTH))) { undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(pelog_err(pjob,pelog,-1,"permission Error")); } if ((which == PE_PROLOGUSER) || (which == PE_EPILOGUSER)) { /* script must also be read and execute by other */ if ((sbuf.st_mode & (S_IROTH | S_IXOTH)) != (S_IROTH | S_IXOTH)) { undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(pelog_err(pjob, pelog, -1, "permission Error")); } } } /* END !reduceprologchecks */ fd_input = pe_input(pjob->ji_qs.ji_jobid); if (fd_input < 0) { undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); return(pelog_err(pjob, pelog, -2, "no pro/epilogue input file")); } run_exit = 0; child = fork(); if (child > 0) { int KillSent = FALSE; /* parent - watch for prolog/epilog to complete */ close(fd_input); /* switch back to root if necessary */ undo_set_euid_egid(which,real_uid,real_gid,num_gids,real_gids,__func__); free(real_gids); act.sa_handler = pelogalm; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, &oldact); /* it would be nice if the harvest routine could block for 5 seconds, and if the prolog is not complete in that time, mark job as prolog pending, append prolog child, and continue */ /* main loop should attempt to harvest prolog in non-blocking mode. If unsuccessful after timeout, job should be terminated, and failure reported. If successful, mom should unset prolog pending, and continue with job start sequence. Mom should report job as running while prologpending flag is set. (NOTE: must track per job prolog start time) */ alarm(pe_alarm_time); while (waitpid(child, &waitst, 0) < 0) { if (errno != EINTR) { /* exit loop. non-alarm based failure occurred */ run_exit = -3; MOMPrologFailureCount++; break; } if (run_exit == -4) { if (KillSent == FALSE) { MOMPrologTimeoutCount++; /* timeout occurred */ KillSent = TRUE; /* NOTE: prolog/epilog may be locked in KERNEL space and unkillable */ alarm(5); } else { /* cannot kill prolog/epilog, give up */ run_exit = -5; break; } } } /* END while (wait(&waitst) < 0) */ /* epilog/prolog child completed */ #ifdef ENABLE_CSA if ((which == PE_EPILOGUSER) && (!strcmp(pelog, path_epiloguser))) { /* * Add a workload management end record */ if (LOGLEVEL >= 8) { sprintf(log_buffer, "%s calling add_wkm_end from run_pelog() - after user epilog", pjob->ji_qs.ji_jobid); log_err(-1, __func__, log_buffer); } add_wkm_end(pjob->ji_wattr[JOB_ATR_pagg_id].at_val.at_ll, pjob->ji_qs.ji_un.ji_momt.ji_exitstat, pjob->ji_qs.ji_jobid); } #endif /* ENABLE_CSA */ alarm(0); /* restore the previous handler */ sigaction(SIGALRM, &oldact, 0); if (run_exit == 0) { if (WIFEXITED(waitst)) { run_exit = WEXITSTATUS(waitst); } } } else { /* child - run script */ log_close(0); if (lockfds >= 0) { close(lockfds); lockfds = -1; } net_close(-1); if (fd_input != 0) { close(0); if (dup(fd_input) == -1) {} close(fd_input); } if (pe_io_type == PE_IO_TYPE_NULL) { /* no output, force to /dev/null */ fds1 = open("/dev/null", O_WRONLY, 0600); fds2 = open("/dev/null", O_WRONLY, 0600); } else if (pe_io_type == PE_IO_TYPE_STD) { /* open job standard out/error */ /* * We need to know if files are joined or not. * If they are then open the correct file and duplicate it to the other */ isjoined = is_joined(pjob); switch (isjoined) { case -1: fds2 = open_std_file(pjob, StdErr, O_WRONLY | O_APPEND, pjob->ji_qs.ji_un.ji_momt.ji_exgid); fds1 = dup(fds2); break; case 1: fds1 = open_std_file(pjob, StdOut, O_WRONLY | O_APPEND, pjob->ji_qs.ji_un.ji_momt.ji_exgid); fds2 = dup(fds1); break; default: fds1 = open_std_file(pjob, StdOut, O_WRONLY | O_APPEND, pjob->ji_qs.ji_un.ji_momt.ji_exgid); fds2 = open_std_file(pjob, StdErr, O_WRONLY | O_APPEND, pjob->ji_qs.ji_un.ji_momt.ji_exgid); break; } } if (pe_io_type != PE_IO_TYPE_ASIS) { /* If PE_IO_TYPE_ASIS, leave as is, already open to job */ if (fds1 != 1) { close(1); if (dup(fds1) == -1) {} close(fds1); } if (fds2 != 2) { close(2); if (dup(fds2) == -1) {} close(fds2); } } if ((which == PE_PROLOGUSER) || (which == PE_EPILOGUSER) || (which == PE_PROLOGUSERJOB) || (which == PE_EPILOGUSERJOB)) { if (chdir(pjob->ji_grpcache->gc_homedir) != 0) { /* warn only, no failure */ sprintf(log_buffer, "PBS: chdir to %s failed: %s (running user %s in current directory)", pjob->ji_grpcache->gc_homedir, strerror(errno), which == PE_PROLOGUSER ? "prologue" : "epilogue"); if (write(2, log_buffer, strlen(log_buffer)) == -1) {} fsync(2); } } /* for both prolog and epilog */ if (DEBUGMODE == 1) { fprintf(stderr, "PELOGINFO: script:'%s' jobid:'%s' euser:'******' egroup:'%s' jobname:'%s' SSID:'%ld' RESC:'%s'\n", pelog, pjob->ji_qs.ji_jobid, pjob->ji_wattr[JOB_ATR_euser].at_val.at_str, pjob->ji_wattr[JOB_ATR_egroup].at_val.at_str, pjob->ji_wattr[JOB_ATR_jobname].at_val.at_str, pjob->ji_wattr[JOB_ATR_session_id].at_val.at_long, resc_to_string(pjob, JOB_ATR_resource, resc_list, sizeof(resc_list))); } arg[0] = pelog; arg[1] = pjob->ji_qs.ji_jobid; arg[2] = pjob->ji_wattr[JOB_ATR_euser].at_val.at_str; arg[3] = pjob->ji_wattr[JOB_ATR_egroup].at_val.at_str; arg[4] = pjob->ji_wattr[JOB_ATR_jobname].at_val.at_str; /* NOTE: inside child */ if ((which == PE_EPILOG) || (which == PE_EPILOGUSER) || (which == PE_EPILOGUSERJOB)) { /* for epilog only */ sprintf(sid, "%ld", pjob->ji_wattr[JOB_ATR_session_id].at_val.at_long); sprintf(exit_stat,"%d", pjob->ji_qs.ji_un.ji_momt.ji_exitstat); arg[5] = sid; arg[6] = resc_to_string(pjob, JOB_ATR_resource, resc_list, sizeof(resc_list)); arg[7] = resc_to_string(pjob, JOB_ATR_resc_used, resc_used, sizeof(resc_used)); arg[8] = pjob->ji_wattr[JOB_ATR_in_queue].at_val.at_str; arg[9] = pjob->ji_wattr[JOB_ATR_account].at_val.at_str; arg[10] = exit_stat; arg[11] = NULL; LastArg = 11; } else { /* prolog */ arg[5] = resc_to_string(pjob, JOB_ATR_resource, resc_list, sizeof(resc_list)); arg[6] = pjob->ji_wattr[JOB_ATR_in_queue].at_val.at_str; arg[7] = pjob->ji_wattr[JOB_ATR_account].at_val.at_str; arg[8] = NULL; LastArg = 8; } for (aindex = 0;aindex < LastArg;aindex++) { if (arg[aindex] == NULL) arg[aindex] = EmptyString; } /* END for (aindex) */ /* * Pass Resource_List.nodes request in environment * to allow pro/epi-logue setup/teardown of system * settings. --pw, 2 Jan 02 * Fixed to use putenv for sysV compatibility. * --troy, 11 jun 03 * */ r = find_resc_entry( &pjob->ji_wattr[JOB_ATR_resource], find_resc_def(svr_resc_def, "nodes", svr_resc_size)); if (r != NULL) { /* setenv("PBS_RESOURCE_NODES",r->rs_value.at_val.at_str,1); */ const char *envname = "PBS_RESOURCE_NODES="; char *envstr; envstr = calloc((strlen(envname) + strlen(r->rs_value.at_val.at_str) + 1), sizeof(char)); if (envstr != NULL) { strcpy(envstr,envname); strcat(envstr,r->rs_value.at_val.at_str); /* do _not_ free the string when using putenv */ putenv(envstr); } } /* END if (r != NULL) */ r = find_resc_entry( &pjob->ji_wattr[JOB_ATR_resource], find_resc_def(svr_resc_def, "gres", svr_resc_size)); if (r != NULL) { /* setenv("PBS_RESOURCE_NODES",r->rs_value.at_val.at_str,1); */ const char *envname = "PBS_RESOURCE_GRES="; char *envstr; envstr = calloc((strlen(envname) + strlen(r->rs_value.at_val.at_str) + 1), sizeof(char)); if (envstr != NULL) { strcpy(envstr,envname); strcat(envstr,r->rs_value.at_val.at_str); /* do _not_ free the string when using putenv */ putenv(envstr); } } /* END if (r != NULL) */ if (TTmpDirName(pjob, buf, sizeof(buf))) { const char *envname = "TMPDIR="; char *envstr; envstr = calloc((strlen(envname) + strlen(buf) + 1), sizeof(char)); if (envstr != NULL) { strcpy(envstr,envname); strcat(envstr,buf); /* do _not_ free the string when using putenv */ putenv(envstr); } } /* END if (TTmpDirName(pjob,&buf)) */ /* Set PBS_SCHED_HINT */ { char *envname = "PBS_SCHED_HINT"; char *envval; char *envstr; if ((envval = get_job_envvar(pjob, envname)) != NULL) { envstr = calloc((strlen(envname) + strlen(envval) + 2), sizeof(char)); if (envstr != NULL) { sprintf(envstr,"%s=%s", envname, envval); putenv(envstr); } } } /* Set PBS_NODENUM */ { char *envname = "PBS_NODENUM"; char *envstr; sprintf(buf, "%d", pjob->ji_nodeid); envstr = calloc((strlen(envname) + strlen(buf) + 2), sizeof(char)); if (envstr != NULL) { sprintf(envstr,"%s=%d", envname, pjob->ji_nodeid); putenv(envstr); } } /* Set PBS_MSHOST */ { char *envname = "PBS_MSHOST"; char *envstr; if ((pjob->ji_vnods[0].vn_host != NULL) && (pjob->ji_vnods[0].vn_host->hn_host != NULL)) { envstr = calloc((strlen(envname) + strlen(pjob->ji_vnods[0].vn_host->hn_host) + 2), sizeof(char)); if (envstr != NULL) { sprintf(envstr,"%s=%s", envname, pjob->ji_vnods[0].vn_host->hn_host); putenv(envstr); } } } /* Set PBS_NODEFILE */ { char *envname = "PBS_NODEFILE"; char *envstr; if (pjob->ji_flags & MOM_HAS_NODEFILE) { sprintf(buf, "%s/%s", path_aux, pjob->ji_qs.ji_jobid); envstr = calloc((strlen(envname) + strlen(buf) + 2), sizeof(char)); if (envstr != NULL) { sprintf(envstr,"%s=%s", envname, buf); putenv(envstr); } } } /* Set PBS_O_Workdir */ { char *envname = "PBS_O_WORKDIR"; char *workdir_val; char *envstr; workdir_val = get_job_envvar(pjob,envname); if (workdir_val != NULL) { envstr = calloc((strlen(workdir_val) + strlen(envname) + 2), sizeof(char)); if (envstr != NULL) { sprintf(envstr,"%s=%s", envname, workdir_val); putenv(envstr); } } } /* SET BEOWULF_JOB_MAP */ { struct array_strings *vstrs; int VarIsSet = 0; int j; vstrs = pjob->ji_wattr[JOB_ATR_variables].at_val.at_arst; for (j = 0;j < vstrs->as_usedptr;++j) { if (!strncmp( vstrs->as_string[j], "BEOWULF_JOB_MAP=", strlen("BEOWULF_JOB_MAP="))) { VarIsSet = 1; break; } } if (VarIsSet == 1) { char *envstr; envstr = calloc((strlen(vstrs->as_string[j])), sizeof(char)); if (envstr != NULL) { strcpy(envstr,vstrs->as_string[j]); putenv(envstr); } } } /* Set some Moab env variables if they exist */ if ((which == PE_PROLOG) || (which == PE_EPILOG)) { char *tmp_val; char *envstr; for (aindex=0;aindex<moabenvcnt;aindex++) { tmp_val = get_job_envvar(pjob,moabenvs[aindex]); if (tmp_val != NULL) { envstr = calloc((strlen(tmp_val) + strlen(moabenvs[aindex]) + 2), sizeof(char)); if (envstr != NULL) { sprintf(envstr,"%s=%s", moabenvs[aindex], tmp_val); putenv(envstr); } } } } /* * if we want to run as user then we need to reset real user permissions * since it seems that some OSs use real not effective user id when execv'ing */ if ((which == PE_PROLOGUSER) || (which == PE_EPILOGUSER) || (which == PE_PROLOGUSERJOB) || (which == PE_EPILOGUSERJOB)) { seteuid(pbsuser); setegid(pbsgroup); if (setgid(pjob->ji_qs.ji_un.ji_momt.ji_exgid) != 0) { snprintf(log_buffer,sizeof(log_buffer), "setgid(%lu) for UID = %lu failed: %s\n", (unsigned long)pjob->ji_qs.ji_un.ji_momt.ji_exgid, (unsigned long)pjob->ji_qs.ji_un.ji_momt.ji_exuid, strerror(errno)); log_err(errno, __func__, log_buffer); return(-1); } if (setuid(pjob->ji_qs.ji_un.ji_momt.ji_exuid) != 0) { snprintf(log_buffer,sizeof(log_buffer), "setuid(%lu) failed: %s\n", (unsigned long)pjob->ji_qs.ji_un.ji_momt.ji_exuid, strerror(errno)); log_err(errno, __func__, log_buffer); return(-1); } } execv(pelog,arg); sprintf(log_buffer,"execv of %s failed: %s\n", pelog, strerror(errno)); if (write(2, log_buffer, strlen(log_buffer)) == -1) { /* cannot write message to stderr */ /* NO-OP */ } fsync(2); exit(255); } /* END else () */ switch (run_exit) { case 0: /* SUCCESS */ /* NO-OP */ break; case - 3: pelog_err(pjob, pelog, run_exit, "child wait interrupted"); break; case - 4: pelog_err(pjob, pelog, run_exit, "prolog/epilog timeout occurred, child cleaned up"); break; case - 5: pelog_err(pjob, pelog, run_exit, "prolog/epilog timeout occurred, cannot kill child"); break; default: pelog_err(pjob, pelog, run_exit, "nonzero p/e exit status"); break; } /* END switch (run_exit) */ return(run_exit); } /* END run_pelog() */
int main(int argc, char *argv[]) { struct udev *udev; static const struct option options[] = { { "lock-media", no_argument, NULL, 'l' }, { "unlock-media", no_argument, NULL, 'u' }, { "eject-media", no_argument, NULL, 'e' }, { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; bool eject = false; bool lock = false; bool unlock = false; const char *node = NULL; int fd = -1; int cnt; int rc = 0; log_set_target(LOG_TARGET_AUTO); udev_parse_config(); log_parse_environment(); log_open(); udev = udev_new(); if (udev == NULL) goto exit; for (;;) { int option; option = getopt_long(argc, argv, "deluh", options, NULL); if (option == -1) break; switch (option) { case 'l': lock = true; break; case 'u': unlock = true; break; case 'e': eject = true; break; case 'd': log_set_target(LOG_TARGET_CONSOLE); log_set_max_level(LOG_DEBUG); log_open(); break; case 'h': printf("Usage: cdrom_id [options] <device>\n" " -l,--lock-media lock the media (to enable eject request events)\n" " -u,--unlock-media unlock the media\n" " -e,--eject-media eject the media\n" " -d,--debug debug to stderr\n" " -h,--help print this help text\n\n"); goto exit; default: rc = 1; goto exit; } } node = argv[optind]; if (!node) { log_error("no device"); fprintf(stderr, "no device\n"); rc = 1; goto exit; } initialize_srand(); for (cnt = 20; cnt > 0; cnt--) { struct timespec duration; fd = open(node, O_RDONLY|O_NONBLOCK|O_CLOEXEC|(is_mounted(node) ? 0 : O_EXCL)); if (fd >= 0 || errno != EBUSY) break; duration.tv_sec = 0; duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000); nanosleep(&duration, NULL); } if (fd < 0) { log_debug("unable to open '%s'", node); fprintf(stderr, "unable to open '%s'\n", node); rc = 1; goto exit; } log_debug("probing: '%s'", node); /* same data as original cdrom_id */ if (cd_capability_compat(udev, fd) < 0) { rc = 1; goto exit; } /* check for media - don't bail if there's no media as we still need to * to read profiles */ cd_media_compat(udev, fd); /* check if drive talks MMC */ if (cd_inquiry(udev, fd) < 0) goto work; /* read drive and possibly current profile */ if (cd_profiles(udev, fd) != 0) goto work; /* at this point we are guaranteed to have media in the drive - find out more about it */ /* get session/track info */ cd_media_toc(udev, fd); /* get writable media state */ cd_media_info(udev, fd); work: /* lock the media, so we enable eject button events */ if (lock && cd_media) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)"); media_lock(udev, fd, true); } if (unlock && cd_media) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); media_lock(udev, fd, false); } if (eject) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); media_lock(udev, fd, false); log_debug("START_STOP_UNIT (eject)"); media_eject(udev, fd); } printf("ID_CDROM=1\n"); if (cd_cd_rom) printf("ID_CDROM_CD=1\n"); if (cd_cd_r) printf("ID_CDROM_CD_R=1\n"); if (cd_cd_rw) printf("ID_CDROM_CD_RW=1\n"); if (cd_dvd_rom) printf("ID_CDROM_DVD=1\n"); if (cd_dvd_r) printf("ID_CDROM_DVD_R=1\n"); if (cd_dvd_rw) printf("ID_CDROM_DVD_RW=1\n"); if (cd_dvd_ram) printf("ID_CDROM_DVD_RAM=1\n"); if (cd_dvd_plus_r) printf("ID_CDROM_DVD_PLUS_R=1\n"); if (cd_dvd_plus_rw) printf("ID_CDROM_DVD_PLUS_RW=1\n"); if (cd_dvd_plus_r_dl) printf("ID_CDROM_DVD_PLUS_R_DL=1\n"); if (cd_dvd_plus_rw_dl) printf("ID_CDROM_DVD_PLUS_RW_DL=1\n"); if (cd_bd) printf("ID_CDROM_BD=1\n"); if (cd_bd_r) printf("ID_CDROM_BD_R=1\n"); if (cd_bd_re) printf("ID_CDROM_BD_RE=1\n"); if (cd_hddvd) printf("ID_CDROM_HDDVD=1\n"); if (cd_hddvd_r) printf("ID_CDROM_HDDVD_R=1\n"); if (cd_hddvd_rw) printf("ID_CDROM_HDDVD_RW=1\n"); if (cd_mo) printf("ID_CDROM_MO=1\n"); if (cd_mrw) printf("ID_CDROM_MRW=1\n"); if (cd_mrw_w) printf("ID_CDROM_MRW_W=1\n"); if (cd_media) printf("ID_CDROM_MEDIA=1\n"); if (cd_media_mo) printf("ID_CDROM_MEDIA_MO=1\n"); if (cd_media_mrw) printf("ID_CDROM_MEDIA_MRW=1\n"); if (cd_media_mrw_w) printf("ID_CDROM_MEDIA_MRW_W=1\n"); if (cd_media_cd_rom) printf("ID_CDROM_MEDIA_CD=1\n"); if (cd_media_cd_r) printf("ID_CDROM_MEDIA_CD_R=1\n"); if (cd_media_cd_rw) printf("ID_CDROM_MEDIA_CD_RW=1\n"); if (cd_media_dvd_rom) printf("ID_CDROM_MEDIA_DVD=1\n"); if (cd_media_dvd_r) printf("ID_CDROM_MEDIA_DVD_R=1\n"); if (cd_media_dvd_ram) printf("ID_CDROM_MEDIA_DVD_RAM=1\n"); if (cd_media_dvd_rw) printf("ID_CDROM_MEDIA_DVD_RW=1\n"); if (cd_media_dvd_plus_r) printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n"); if (cd_media_dvd_plus_rw) printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n"); if (cd_media_dvd_plus_rw_dl) printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n"); if (cd_media_dvd_plus_r_dl) printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n"); if (cd_media_bd) printf("ID_CDROM_MEDIA_BD=1\n"); if (cd_media_bd_r) printf("ID_CDROM_MEDIA_BD_R=1\n"); if (cd_media_bd_re) printf("ID_CDROM_MEDIA_BD_RE=1\n"); if (cd_media_hddvd) printf("ID_CDROM_MEDIA_HDDVD=1\n"); if (cd_media_hddvd_r) printf("ID_CDROM_MEDIA_HDDVD_R=1\n"); if (cd_media_hddvd_rw) printf("ID_CDROM_MEDIA_HDDVD_RW=1\n"); if (cd_media_state != NULL) printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state); if (cd_media_session_next > 0) printf("ID_CDROM_MEDIA_SESSION_NEXT=%u\n", cd_media_session_next); if (cd_media_session_count > 0) printf("ID_CDROM_MEDIA_SESSION_COUNT=%u\n", cd_media_session_count); if (cd_media_session_count > 1 && cd_media_session_last_offset > 0) printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset); if (cd_media_track_count > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT=%u\n", cd_media_track_count); if (cd_media_track_count_audio > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%u\n", cd_media_track_count_audio); if (cd_media_track_count_data > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%u\n", cd_media_track_count_data); exit: if (fd >= 0) close(fd); udev_unref(udev); log_close(); return rc; }
/* process HTTP or SSDP requests */ int main(int argc, char **argv) { int ret, i; int shttpl = -1; int smonitor = -1; LIST_HEAD(httplisthead, upnphttp) upnphttphead; struct upnphttp * e = 0; struct upnphttp * next; fd_set readset; /* for select() */ fd_set writeset; struct timeval timeout, timeofday, lastnotifytime = {0, 0}; time_t lastupdatetime = 0; int max_fd = -1; int last_changecnt = 0; pid_t scanner_pid = 0; pthread_t inotify_thread = 0; #ifdef TIVO_SUPPORT uint8_t beacon_interval = 5; int sbeacon = -1; struct sockaddr_in tivo_bcast; struct timeval lastbeacontime = {0, 0}; #endif for (i = 0; i < L_MAX; i++) log_level[i] = E_WARN; init_nls(); ret = init(argc, argv); if (ret != 0) return 1; DPRINTF(E_WARN, L_GENERAL, "Starting " SERVER_NAME " version " MINIDLNA_VERSION ".\n"); if (sqlite3_libversion_number() < 3005001) { DPRINTF(E_WARN, L_GENERAL, "SQLite library is old. Please use version 3.5.1 or newer.\n"); } LIST_INIT(&upnphttphead); ret = open_db(NULL); if (ret == 0) { updateID = sql_get_int_field(db, "SELECT VALUE from SETTINGS where KEY = 'UPDATE_ID'"); if (updateID == -1) ret = -1; } check_db(db, ret, &scanner_pid); #ifdef HAVE_INOTIFY if( GETFLAG(INOTIFY_MASK) ) { if (!sqlite3_threadsafe() || sqlite3_libversion_number() < 3005001) DPRINTF(E_ERROR, L_GENERAL, "SQLite library is not threadsafe! " "Inotify will be disabled.\n"); else if (pthread_create(&inotify_thread, NULL, start_inotify, NULL) != 0) DPRINTF(E_FATAL, L_GENERAL, "ERROR: pthread_create() failed for start_inotify. EXITING\n"); } #endif smonitor = OpenAndConfMonitorSocket(); sssdp = OpenAndConfSSDPReceiveSocket(); if (sssdp < 0) { DPRINTF(E_INFO, L_GENERAL, "Failed to open socket for receiving SSDP. Trying to use MiniSSDPd\n"); if (SubmitServicesToMiniSSDPD(lan_addr[0].str, runtime_vars.port) < 0) DPRINTF(E_FATAL, L_GENERAL, "Failed to connect to MiniSSDPd. EXITING"); } /* open socket for HTTP connections. */ shttpl = OpenAndConfHTTPSocket(runtime_vars.port); if (shttpl < 0) DPRINTF(E_FATAL, L_GENERAL, "Failed to open socket for HTTP. EXITING\n"); DPRINTF(E_WARN, L_GENERAL, "HTTP listening on port %d\n", runtime_vars.port); #ifdef TIVO_SUPPORT if (GETFLAG(TIVO_MASK)) { DPRINTF(E_WARN, L_GENERAL, "TiVo support is enabled.\n"); /* Add TiVo-specific randomize function to sqlite */ ret = sqlite3_create_function(db, "tivorandom", 1, SQLITE_UTF8, NULL, &TiVoRandomSeedFunc, NULL, NULL); if (ret != SQLITE_OK) DPRINTF(E_ERROR, L_TIVO, "ERROR: Failed to add sqlite randomize function for TiVo!\n"); /* open socket for sending Tivo notifications */ sbeacon = OpenAndConfTivoBeaconSocket(); if(sbeacon < 0) DPRINTF(E_FATAL, L_GENERAL, "Failed to open sockets for sending Tivo beacon notify " "messages. EXITING\n"); tivo_bcast.sin_family = AF_INET; tivo_bcast.sin_addr.s_addr = htonl(getBcastAddress()); tivo_bcast.sin_port = htons(2190); } #endif reload_ifaces(0); lastnotifytime.tv_sec = time(NULL) + runtime_vars.notify_interval; /* main loop */ while (!quitting) { /* Check if we need to send SSDP NOTIFY messages and do it if * needed */ if (gettimeofday(&timeofday, 0) < 0) { DPRINTF(E_ERROR, L_GENERAL, "gettimeofday(): %s\n", strerror(errno)); timeout.tv_sec = runtime_vars.notify_interval; timeout.tv_usec = 0; } else { /* the comparison is not very precise but who cares ? */ if (timeofday.tv_sec >= (lastnotifytime.tv_sec + runtime_vars.notify_interval)) { DPRINTF(E_DEBUG, L_SSDP, "Sending SSDP notifies\n"); for (i = 0; i < n_lan_addr; i++) { SendSSDPNotifies(lan_addr[i].snotify, lan_addr[i].str, runtime_vars.port, runtime_vars.notify_interval); } memcpy(&lastnotifytime, &timeofday, sizeof(struct timeval)); timeout.tv_sec = runtime_vars.notify_interval; timeout.tv_usec = 0; } else { timeout.tv_sec = lastnotifytime.tv_sec + runtime_vars.notify_interval - timeofday.tv_sec; if (timeofday.tv_usec > lastnotifytime.tv_usec) { timeout.tv_usec = 1000000 + lastnotifytime.tv_usec - timeofday.tv_usec; timeout.tv_sec--; } else timeout.tv_usec = lastnotifytime.tv_usec - timeofday.tv_usec; } #ifdef TIVO_SUPPORT if (sbeacon >= 0) { if (timeofday.tv_sec >= (lastbeacontime.tv_sec + beacon_interval)) { sendBeaconMessage(sbeacon, &tivo_bcast, sizeof(struct sockaddr_in), 1); memcpy(&lastbeacontime, &timeofday, sizeof(struct timeval)); if (timeout.tv_sec > beacon_interval) { timeout.tv_sec = beacon_interval; timeout.tv_usec = 0; } /* Beacons should be sent every 5 seconds or so for the first minute, * then every minute or so thereafter. */ if (beacon_interval == 5 && (timeofday.tv_sec - startup_time) > 60) beacon_interval = 60; } else if (timeout.tv_sec > (lastbeacontime.tv_sec + beacon_interval + 1 - timeofday.tv_sec)) timeout.tv_sec = lastbeacontime.tv_sec + beacon_interval - timeofday.tv_sec; } #endif } if (scanning) { if (!scanner_pid || kill(scanner_pid, 0) != 0) { scanning = 0; updateID++; } } /* select open sockets (SSDP, HTTP listen, and all HTTP soap sockets) */ FD_ZERO(&readset); if (sssdp >= 0) { FD_SET(sssdp, &readset); max_fd = MAX(max_fd, sssdp); } if (shttpl >= 0) { FD_SET(shttpl, &readset); max_fd = MAX(max_fd, shttpl); } #ifdef TIVO_SUPPORT if (sbeacon >= 0) { FD_SET(sbeacon, &readset); max_fd = MAX(max_fd, sbeacon); } #endif if (smonitor >= 0) { FD_SET(smonitor, &readset); max_fd = MAX(max_fd, smonitor); } i = 0; /* active HTTP connections count */ for (e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) { if ((e->socket >= 0) && (e->state <= 2)) { FD_SET(e->socket, &readset); max_fd = MAX(max_fd, e->socket); i++; } } FD_ZERO(&writeset); upnpevents_selectfds(&readset, &writeset, &max_fd); ret = select(max_fd+1, &readset, &writeset, 0, &timeout); if (ret < 0) { if(quitting) goto shutdown; if(errno == EINTR) continue; DPRINTF(E_ERROR, L_GENERAL, "select(all): %s\n", strerror(errno)); DPRINTF(E_FATAL, L_GENERAL, "Failed to select open sockets. EXITING\n"); } upnpevents_processfds(&readset, &writeset); /* process SSDP packets */ if (sssdp >= 0 && FD_ISSET(sssdp, &readset)) { /*DPRINTF(E_DEBUG, L_GENERAL, "Received SSDP Packet\n");*/ ProcessSSDPRequest(sssdp, (unsigned short)runtime_vars.port); } #ifdef TIVO_SUPPORT if (sbeacon >= 0 && FD_ISSET(sbeacon, &readset)) { /*DPRINTF(E_DEBUG, L_GENERAL, "Received UDP Packet\n");*/ ProcessTiVoBeacon(sbeacon); } #endif if (smonitor >= 0 && FD_ISSET(smonitor, &readset)) { ProcessMonitorEvent(smonitor); } /* increment SystemUpdateID if the content database has changed, * and if there is an active HTTP connection, at most once every 2 seconds */ if (i && (timeofday.tv_sec >= (lastupdatetime + 2))) { if (scanning || sqlite3_total_changes(db) != last_changecnt) { updateID++; last_changecnt = sqlite3_total_changes(db); upnp_event_var_change_notify(EContentDirectory); lastupdatetime = timeofday.tv_sec; } } /* process active HTTP connections */ for (e = upnphttphead.lh_first; e != NULL; e = e->entries.le_next) { if ((e->socket >= 0) && (e->state <= 2) && (FD_ISSET(e->socket, &readset))) Process_upnphttp(e); } /* process incoming HTTP connections */ if (shttpl >= 0 && FD_ISSET(shttpl, &readset)) { int shttp; socklen_t clientnamelen; struct sockaddr_in clientname; clientnamelen = sizeof(struct sockaddr_in); shttp = accept(shttpl, (struct sockaddr *)&clientname, &clientnamelen); if (shttp<0) { DPRINTF(E_ERROR, L_GENERAL, "accept(http): %s\n", strerror(errno)); } else { struct upnphttp * tmp = 0; DPRINTF(E_DEBUG, L_GENERAL, "HTTP connection from %s:%d\n", inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port) ); /*if (fcntl(shttp, F_SETFL, O_NONBLOCK) < 0) { DPRINTF(E_ERROR, L_GENERAL, "fcntl F_SETFL, O_NONBLOCK\n"); }*/ /* Create a new upnphttp object and add it to * the active upnphttp object list */ tmp = New_upnphttp(shttp); if (tmp) { tmp->clientaddr = clientname.sin_addr; LIST_INSERT_HEAD(&upnphttphead, tmp, entries); } else { DPRINTF(E_ERROR, L_GENERAL, "New_upnphttp() failed\n"); close(shttp); } } } /* delete finished HTTP connections */ for (e = upnphttphead.lh_first; e != NULL; e = next) { next = e->entries.le_next; if(e->state >= 100) { LIST_REMOVE(e, entries); Delete_upnphttp(e); } } } shutdown: /* kill the scanner */ if (scanning && scanner_pid) kill(scanner_pid, SIGKILL); /* kill other child processes */ process_reap_children(); free(children); /* close out open sockets */ while (upnphttphead.lh_first != NULL) { e = upnphttphead.lh_first; LIST_REMOVE(e, entries); Delete_upnphttp(e); } if (sssdp >= 0) close(sssdp); if (shttpl >= 0) close(shttpl); #ifdef TIVO_SUPPORT if (sbeacon >= 0) close(sbeacon); #endif for (i = 0; i < n_lan_addr; i++) { SendSSDPGoodbyes(lan_addr[i].snotify); close(lan_addr[i].snotify); } if (inotify_thread) pthread_join(inotify_thread, NULL); sql_exec(db, "UPDATE SETTINGS set VALUE = '%u' where KEY = 'UPDATE_ID'", updateID); sqlite3_close(db); upnpevents_removeSubscribers(); if (pidfilename && unlink(pidfilename) < 0) DPRINTF(E_ERROR, L_GENERAL, "Failed to remove pidfile %s: %s\n", pidfilename, strerror(errno)); log_close(); freeoptions(); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { extern int optind; extern char *optarg; int c, err_flag = 0; char *ext; #ifdef SGDEBUG char logfilename_buffer[_MAX_PATH]; #ifdef WIN32 DWORD tmpPathLen; #endif /* WIN32 */ #endif /* SGDEBUG */ #ifdef SGDEBUG #ifdef WIN32 tmpPathLen = GetTempPath(_MAX_PATH, logfilename_buffer); if (logfilename_buffer[tmpPathLen - 1] != '\\') strcat(logfilename_buffer, "\\"); #else /* !WIN32 */ strcpy(logfilename_buffer, "/tmp/"); #endif /* WIN32 */ strcat(logfilename_buffer, sg_getlogin()); strcat(logfilename_buffer, "-"); strcat(logfilename_buffer, logfilename); if (!log_open(logfilename_buffer)) { /* open failed */ fatal(1, "%s: cannot write to %s\n", progname, logfilename_buffer); } #endif /* SGDEBUG */ while ((c = getopt(argc, argv, OPTS)) != EOF) { switch (c) { case 'h': opt_h = 1; break; case 'q': opt_q = 1; break; case 'v': opt_v = 1; break; case 'g': opt_g = 1; break; case 'a': opt_a = 1; break; case 'e': opt_e = optarg; if (opt_e[0] == '.') opt_e++; break; case 'r': opt_r = 1; break; case 'i': opt_i = 1; break; case 'c': if (opt_d) err_flag = 1; opt_c = 1; break; case 'd': if (opt_c) err_flag = 1; opt_d = 1; break; case 'b': if (opt_f || opt_s || opt_n) err_flag = 1; opt_b = 1; break; case 'f': if (opt_b || opt_s || opt_n) err_flag = 1; opt_f = 1; break; case 's': if (opt_f || opt_b || opt_n) err_flag = 1; opt_s = 1; break; case 'n': if (opt_f || opt_s || opt_b) err_flag = 1; opt_n = 1; break; default: err_flag = 1; } } if (opt_h || opt_v || err_flag) { inform_user("%s version %s (build %d).\n", progname, progver, revision()); if (opt_h || err_flag) fatal(err_flag, usage, progname); else fatal(0, "%s\n%s", copyright, version_info); } if (!(opt_b || opt_f || opt_s || opt_n)) opt_b = 1; /* done setting options */ if (argc == optind) { /* read from stdin and stdout */ outfile = stdout; fprintf(outfile, "/* %s: reading from stdin */\n", progname); using_stdio = 1; inPath = "stdin"; outPath = strdup("stdout"); opt_q = 1; /* force quiet mode */ log_printf("initting...\n"); init_tables(); scan_and_generate(stdin); log_printf("freeing memory...\n"); free_tables(); } else { inform_user("%s version %s (build %d).\n", progname, progver, revision()); /* each bloody file from the command line */ while (optind < argc) { FILE *infile; log_printf("working on %s\n", argv[optind]); /* open for read */ infile = fopen(argv[optind], "r"); if (infile == NULL) { /* open failed */ fatal(1, "%s: cannot open %s\n", progname, argv[optind]); } inPath = basename(argv[optind]); outPath = (char *)malloc(strlen(inPath) + strlen(opt_e) + 2); strcpy(outPath, inPath); /* tie off .h, .hh, .hpp, or .hxx extension */ if (((ext = strrchr(outPath, '.')) != NULL) && (((strlen(ext) == 2) && ((ext[1] == 'H') || (ext[1] == 'h'))) || (((strlen(ext) == 3) && ((ext[1] == 'H') || (ext[1] == 'h')) && ((ext[2] == 'H') || (ext[2] == 'h')))) || ((strlen(ext) == 4) && ((ext[1] == 'H') || (ext[1] == 'h')) && ((((ext[2] == 'P') || (ext[2] == 'p')) && ((ext[3] == 'P') || (ext[3] == 'p'))) || (((ext[2] == 'X') || (ext[2] == 'x')) && ((ext[3] == 'X') || (ext[3] == 'x'))))))) *ext = '\0'; assert(opt_e[0] != '.'); strcat(outPath, "."); strcat(outPath, opt_e); log_printf("initting...\n"); init_tables(); scan_existing_skeleton(); scan_and_generate(infile); log_printf("freeing memory...\n"); free_tables(); clear_skeleton_queue(); fclose(infile); optind++; } } #ifdef SGDEBUG log_flush(); log_close(); #endif /* SGDEBUG */ return 0; }
/** * An internal worker function to perform the logging. * * Takes VA_ARGS similar to vprintf. * * \param _l The logger reference. * \param severity The severity of the message * \param format The message to send * \param ap The va_list for the format paramater * \returns 0 on success, -1 on error. */ static int vlog(int severity, const char *format, va_list ap) { if (logLevel > severity) { return 0; } if (buffer == NULL) { buffer = (char *) g_malloc(INITIAL_BUFFER_SIZE); buffer_size = INITIAL_BUFFER_SIZE; } struct timeval timestamp; // Populate buffer with time stamp if (gettimeofday(×tamp, NULL) != 0) { // Print the message to stderr before erroring out fprintf(stderr, "??.?? PID(%d) %s: [%s] ", getpid(), basename_safe(PROCESS_NAME), log_get_severity_string(severity)); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); fflush(stderr); return -1; } int ret = g_vsnprintf(buffer, buffer_size, format, ap); if (ret < 0) { // Broken implementation of vsnprintf? // Print the message to stderr before erroring out fprintf(stderr, "%ld.%06ld PID(%d) %s: [%s] ", timestamp.tv_sec, timestamp.tv_usec, getpid(), basename_safe(PROCESS_NAME), log_get_severity_string(severity)); vfprintf(stderr, format, ap); fprintf(stderr, "\n"); fflush(stderr); return -1; } if (ret >= buffer_size) { g_free(buffer); buffer = (char *) g_malloc(ret * 2); buffer_size = ret * 2; errno = EAGAIN; return -1; } if (id == NULL) { fprintf(stderr, "%ld.%06ld PID(%d) %s: [%s] %s\n", timestamp.tv_sec, timestamp.tv_usec, getpid(), basename_safe(PROCESS_NAME), log_get_severity_string(severity), buffer); return 0; } log_t log = log_init(NULL, 0); log_set_sender_id(log, id); log_set_severity(log, severity); log_set_timestamp(log, timestamp.tv_sec, timestamp.tv_usec); log_set_message(log, buffer); unsigned int size; char *s = log_serialise(log, &size); log_close(log); ret = transport_send(transport, s, NULL, size); g_free(s); return ret; }
int log_reconfigure(conf_t *conf, void *data) { // Data not used UNUSED(data); // Use defaults if no 'log' section is configured. if (conf_id_count(conf, C_LOG) == 0) { log_close(); log_init(); return KNOT_EOK; } // Find maximum log facility id unsigned files = 0; conf_iter_t iter = conf_iter(conf, C_LOG); while (iter.code == KNOT_EOK) { conf_val_t id = conf_iter_id(conf, &iter); if (get_logtype(conf_str(&id)) == LOGT_FILE) { ++files; } conf_iter_next(conf, &iter); } conf_iter_finish(conf, &iter); // Initialize logsystem struct log_sink *log = sink_setup(files); if (log == NULL) { return KNOT_ENOMEM; } // Setup logs iter = conf_iter(conf, C_LOG); while (iter.code == KNOT_EOK) { conf_val_t id = conf_iter_id(conf, &iter); const char *logname = conf_str(&id); // Get facility. int facility = get_logtype(logname); if (facility == LOGT_FILE) { facility = log_open_file(log, logname); if (facility < 0) { log_error("failed to open log, file '%s'", logname); conf_iter_next(conf, &iter); continue; } } conf_val_t level_val; unsigned level; // Set SERVER logging. level_val = conf_id_get(conf, C_LOG, C_SERVER, &id); level = conf_opt(&level_val); sink_levels_add(log, facility, LOG_SERVER, level); // Set ZONE logging. level_val = conf_id_get(conf, C_LOG, C_ZONE, &id); level = conf_opt(&level_val); sink_levels_add(log, facility, LOG_ZONE, level); // Set ANY logging. level_val = conf_id_get(conf, C_LOG, C_ANY, &id); level = conf_opt(&level_val); sink_levels_add(log, facility, LOG_ANY, level); conf_iter_next(conf, &iter); } conf_iter_finish(conf, &iter); sink_publish(log); return KNOT_EOK; }
/* SYNTAX: LOG OPEN [-noopen] [-autoopen] [-window] [-<server tag>] [-targets <targets>] [-colors] <fname> [<levels>] */ static void cmd_log_open(const char *data) { SERVER_REC *server; GHashTable *optlist; char *targetarg, *fname, *levels, *servertag; void *free_arg; char window[MAX_INT_STRLEN]; LOG_REC *log; int level; if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST | PARAM_FLAG_UNKNOWN_OPTIONS | PARAM_FLAG_OPTIONS | PARAM_FLAG_STRIP_TRAILING_WS, "log open", &optlist, &fname, &levels)) return; if (*fname == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); level = level2bits(levels, NULL); log = log_create_rec(fname, level != 0 ? level : MSGLEVEL_ALL); /* -<server tag> */ server = cmd_options_get_server("log open", optlist, NULL); servertag = server == NULL ? NULL : server->tag; if (g_hash_table_lookup(optlist, "window")) { /* log by window ref# */ targetarg = g_hash_table_lookup(optlist, "targets"); if (targetarg == NULL || !is_numeric(targetarg, '\0')) { ltoa(window, active_win->refnum); targetarg = window; } log_item_add(log, LOG_ITEM_WINDOW_REFNUM, targetarg, servertag); } else { targetarg = g_hash_table_lookup(optlist, "targets"); if (targetarg != NULL && *targetarg != '\0') log_add_targets(log, targetarg, servertag); else if (servertag != NULL) log_add_targets(log, "*", servertag); } if (g_hash_table_lookup(optlist, "autoopen")) log->autoopen = TRUE; if (g_hash_table_lookup(optlist, "colors") == NULL) log->colorizer = log_colorizer_strip; log_update(log); if (log->handle == -1 && g_hash_table_lookup(optlist, "noopen") == NULL) { /* start logging */ if (log_start_logging(log)) { printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE, TXT_LOG_OPENED, fname); } else { log_close(log); } } cmd_params_free(free_arg); }
void log_roll( int max_depth) { int i, suffix_size, file_buf_len, as; int err = 0; char *source = NULL; char *dest = NULL; if (!log_opened) { return; } /* save value of log_auto_switch */ as = log_auto_switch; log_close(1); /* find out how many characters the suffix could be. (save in suffix_size) start at 1 to account for the "." */ for (i = max_depth, suffix_size = 1;i > 0;suffix_size++, i /= 10); /* allocate memory for rolling */ file_buf_len = sizeof(char) * (strlen(logpath) + suffix_size + 1); source = (char*)malloc(file_buf_len); dest = (char*)malloc(file_buf_len); if ((source == NULL) || (dest == NULL)) { err = errno; goto done_roll; } /* call unlink to delete logname.max_depth - it doesn't matter if it doesn't exist, so we'll ignore ENOENT */ sprintf(dest, "%s.%d", logpath, max_depth); if ((unlink(dest) != 0) && (errno != ENOENT)) { err = errno; goto done_roll; } /* logname.max_depth is gone, so roll the rest of the log files */ for (i = max_depth - 1;i >= 0;i--) { if (i == 0) { strcpy(source, logpath); } else { sprintf(source, "%s.%d", logpath, i); } sprintf(dest, "%s.%d", logpath, i + 1); /* rename file if it exists */ if ((rename(source, dest) != 0) && (errno != ENOENT)) { err = errno; goto done_roll; } } /* END for (i) */ done_roll: if (as) { log_open(NULL, log_directory); } else { log_open(logpath, log_directory); } if (source != NULL) free(source); if (dest != NULL) free(dest); if (err != 0) { log_err(err, "log_roll", "error while rollng logs"); } else { log_record( PBSEVENT_SYSTEM, PBS_EVENTCLASS_SERVER, "Log", "Log Rolled"); } return; } /* END log_roll() */
void log_record( int eventtype, /* I */ int objclass, /* I */ char *objname, /* I */ char *text) /* I */ { int tryagain = 2; time_t now; struct tm *ptm; struct tm tmpPtm; int rc = 0; FILE *savlog; char *start = NULL, *end = NULL; size_t nchars; if (log_opened < 1) { return; } now = time((time_t *)0); /* get time for message */ ptm = localtime_r(&now,&tmpPtm); /* Do we need to switch the log? */ if (log_auto_switch && (ptm->tm_yday != log_open_day)) { log_close(1); log_open(NULL, log_directory); if (log_opened < 1) { return; } } /* * Looking for the newline characters and splitting the output message * on them. Sequence "\r\n" is mapped to the single newline. */ start = text; while (1) { for (end = start; *end != '\n' && *end != '\r' && *end != '\0'; end++) ; nchars = end - start; if (*end == '\r' && *(end + 1) == '\n') end++; while (tryagain) { rc = fprintf(logfile, "%02d/%02d/%04d %02d:%02d:%02d;%04x;%10.10s;%s;%s;%s%.*s\n", ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_year + 1900, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, (eventtype & ~PBSEVENT_FORCE), msg_daemonname, class_names[objclass], objname, (text == start ? "" : "[continued]"), (int)nchars, start); if ((rc < 0) && (errno == EPIPE) && (tryagain == 2)) { /* the log file descriptor has been changed--it now points to a socket! * reopen log and leave the previous file descriptor alone--do not close it */ log_opened = 0; log_open(NULL, log_directory); tryagain--; } else { tryagain = 0; } } if (rc < 0) break; if (*end == '\0') break; start = end + 1; } /* END while (1) */ fflush(logfile); if (rc < 0) { rc = errno; clearerr(logfile); savlog = logfile; logfile = fopen("/dev/console", "w"); /* we need to add this check to make sure the disk isn't full so we don't segfault * if we can't open this then we're going to have a nice surprise failure */ if (logfile != NULL) { log_err(rc, "log_record", "PBS cannot write to its log"); fclose(logfile); } logfile = savlog; } return; } /* END log_record() */
int main(int argc, char *argv[]){ struct tvIdParam idp; struct tvWindowParam wip; int tries=0; HDESK hDesk=NULL; HWINSTA hWinsta=NULL; char slogfile[128]; int error=0; snprintf(slogfile,128,"%s.log.txt",argv[0]); log_open(slogfile); //if(check_registry_key(REG_KEY_ID_NAME)){ // goto abort; //} /* Switch to the needed Desktop Station (in order to enumwindows */ hWinsta=OpenWindowStation("winsta0", // _In_ LPTSTR lpszWinSta, TRUE, // _In_ BOOL fInherit, WINSTA_ALL_ACCESS); // _In_ ACCESS_MASK dwDesiredAccess if(!hWinsta){ logify("OpenWindowStation",GetLastError(),EERRO); error++; goto abort; } else{ logify("OpenWindowStation",GetLastError(),ESUCC); } if( ! SetProcessWindowStation(hWinsta)){ logify("SetProcessWindowStation",GetLastError(),EERRO); error++; goto abort; }else{ logify("SetProcessWindowStation",GetLastError(),ESUCC); } /* Open the default Desktop */ hDesk=OpenInputDesktop(0,FALSE,GENERIC_READ); if(!hDesk){ logify("OpenInputDesktop",GetLastError(),EERRO); error++; goto abort; } else{ logify("OpenInputDesktop",GetLastError(),ESUCC); } while(tries < TIMEOUT || TIMEOUT==0){ wip.found=FALSE; wip.hWindow=NULL; *wip.sid=0; if( ! EnumDesktopWindows(hDesk,find_tvWindow,(LPARAM)&wip)){ error++; logify("EnumDesktopWindows",GetLastError(),EERRO); } else{ logify("EnumDesktopWindows",GetLastError(),ESUCC); } if(wip.found){ logify("TeamViewer found",GetLastError(),ESUCC); /* Reset param struct */ idp.count=0; idp.id=0; idp.pass=0; idp.idfound=FALSE; idp.passfound=FALSE; EnumChildWindows(wip.hWindow,find_tvId,(LPARAM)&idp); if(idp.idfound){ add_registry_key(REG_KEY_ID_NAME,idp.id); //printf("TeamViewer ID:%d\n",idp.id); if(idp.passfound){ add_registry_key(REG_KEY_PA_NAME,idp.pass); //printf("TeamViewer PASS:%d\n",idp.pass); } break; } } else { logify("TeamViewer not found",GetLastError(),EERRO); } Sleep(SLEEP); tries++; } abort: if(hDesk) CloseDesktop(hDesk); if(hWinsta) CloseWindowStation(hWinsta); log_close(); return error; }
int main(int argc, char *argv[]) { int c; int log_method = L_STDERR_SYSLOG; char *logfile = PATH_RADVD_LOG; int facility = LOG_FACILITY; char *username = NULL; char *chrootdir = NULL; int configtest = 0; int daemonize = 1; char const *pname = ((pname = strrchr(argv[0], '/')) != NULL) ? pname + 1 : argv[0]; srand((unsigned int)time(NULL)); char const *conf_path = PATH_RADVD_CONF; char const *daemon_pid_file_ident = PATH_RADVD_PID; /* parse args */ #define OPTIONS_STR "d:C:l:m:p:t:u:vhcn" #ifdef HAVE_GETOPT_LONG int opt_idx; while ((c = getopt_long(argc, argv, OPTIONS_STR, prog_opt, &opt_idx)) > 0) #else while ((c = getopt(argc, argv, OPTIONS_STR)) > 0) #endif { switch (c) { case 'C': conf_path = optarg; break; case 'd': set_debuglevel(atoi(optarg)); break; case 'f': facility = atoi(optarg); break; case 'l': logfile = optarg; break; case 'p': daemon_pid_file_ident = optarg; break; case 'm': if (!strcmp(optarg, "syslog")) { log_method = L_SYSLOG; } else if (!strcmp(optarg, "stderr_syslog")) { log_method = L_STDERR_SYSLOG; } else if (!strcmp(optarg, "stderr")) { log_method = L_STDERR; } else if (!strcmp(optarg, "logfile")) { log_method = L_LOGFILE; } else if (!strcmp(optarg, "none")) { log_method = L_NONE; } else { fprintf(stderr, "%s: unknown log method: %s\n", pname, optarg); exit(1); } break; case 't': chrootdir = strdup(optarg); break; case 'u': username = strdup(optarg); break; case 'v': version(); break; case 'c': configtest = 1; break; case 'n': daemonize = 0; break; case 'h': usage(pname); #ifdef HAVE_GETOPT_LONG case ':': fprintf(stderr, "%s: option %s: parameter expected\n", pname, prog_opt[opt_idx].name); exit(1); #endif case '?': exit(1); } } /* TODO: Seems like this chroot'ing should happen *after* daemonizing for * the sake of the PID file. */ if (chrootdir) { if (!username) { fprintf(stderr, "Chroot as root is not safe, exiting\n"); exit(1); } if (chroot(chrootdir) == -1) { perror("chroot"); exit(1); } if (chdir("/") == -1) { perror("chdir"); exit(1); } /* username will be switched later */ } if (configtest) { set_debuglevel(1); log_method = L_STDERR; } if (log_open(log_method, pname, logfile, facility) < 0) { perror("log_open"); exit(1); } if (!configtest) { flog(LOG_INFO, "version %s started", VERSION); } /* check that 'other' cannot write the file * for non-root, also that self/own group can't either */ if (check_conffile_perm(username, conf_path) != 0) { if (get_debuglevel() == 0) { flog(LOG_ERR, "exiting, permissions on conf_file invalid"); exit(1); } else flog(LOG_WARNING, "Insecure file permissions, but continuing anyway"); } /* parse config file */ struct Interface *ifaces = NULL; if ((ifaces = readin_config(conf_path)) == 0) { flog(LOG_ERR, "exiting, failed to read config file"); exit(1); } if (configtest) { free_ifaces(ifaces); exit(0); } /* get a raw socket for sending and receiving ICMPv6 messages */ int sock = open_icmpv6_socket(); if (sock < 0) { perror("open_icmpv6_socket"); exit(1); } /* if we know how to do it, check whether forwarding is enabled */ if (check_ip6_forwarding()) { flog(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway"); } int const pidfd = open_and_lock_pid_file(daemon_pid_file_ident); /* * okay, config file is read in, socket and stuff is setup, so * lets fork now... */ if (daemonize) { pid_t pid = do_daemonize(log_method, daemon_pid_file_ident); if (pid != 0 && pid != -1) { /* We want to see clean output from valgrind, so free username, chrootdir, * and ifaces in the child process. */ if (ifaces) free_ifaces(ifaces); if (username) free(username); if (chrootdir) free(chrootdir); exit(0); } } else { if (0 != write_pid_file(daemon_pid_file_ident, getpid())) { flog(LOG_ERR, "failure writing pid file detected"); exit(-1); } } check_pid_file(daemon_pid_file_ident); #ifdef __linux__ /* for privsep */ { dlog(LOG_DEBUG, 3, "initializing privsep"); int pipefds[2]; if (pipe(pipefds) != 0) { flog(LOG_ERR, "Couldn't create privsep pipe."); return -1; } pid_t pid = fork(); if (pid == -1) { flog(LOG_ERR, "Couldn't fork for privsep."); return -1; } if (pid == 0) { /* We want to see clean output from valgrind, so free username, chrootdir, * and ifaces in the child process. */ if (ifaces) free_ifaces(ifaces); if (username) free(username); if (chrootdir) free(chrootdir); close(pipefds[1]); privsep_init(pipefds[0]); _exit(0); } dlog(LOG_DEBUG, 3, "radvd privsep PID is %d", pid); /* Continue execution (will drop privileges soon) */ close(pipefds[0]); privsep_set_write_fd(pipefds[1]); } #endif if (username) { if (drop_root_privileges(username) < 0) { perror("drop_root_privileges"); flog(LOG_ERR, "unable to drop root privileges"); exit(1); } dlog(LOG_DEBUG, 3, "running as user: %s", username); } setup_ifaces(sock, ifaces); ifaces = main_loop(sock, ifaces, conf_path); stop_adverts(sock, ifaces); flog(LOG_INFO, "removing %s", daemon_pid_file_ident); unlink(daemon_pid_file_ident); close(pidfd); if (ifaces) free_ifaces(ifaces); if (chrootdir) free(chrootdir); if (username) free(username); flog(LOG_INFO, "returning from radvd main"); log_close(); return 0; }
void log_reinit(void) { log_close(); log_init(level_filter); }
void session_free (session * killsess) { server *killserv = killsess->server; session *sess; GSList *list; plugin_emit_dummy_print (killsess, "Close Context"); if (current_tab == killsess) current_tab = NULL; if (killserv->server_session == killsess) killserv->server_session = NULL; if (killserv->front_session == killsess) { /* front_session is closed, find a valid replacement */ killserv->front_session = NULL; list = sess_list; while (list) { sess = (session *) list->data; if (sess != killsess && sess->server == killserv) { killserv->front_session = sess; if (!killserv->server_session) killserv->server_session = sess; break; } list = list->next; } } if (!killserv->server_session) killserv->server_session = killserv->front_session; sess_list = g_slist_remove (sess_list, killsess); if (killsess->type == SESS_CHANNEL) userlist_free (killsess); exec_notify_kill (killsess); log_close (killsess); scrollback_close (killsess); chanopt_save (killsess); send_quit_or_part (killsess); history_free (&killsess->history); if (killsess->topic) free (killsess->topic); if (killsess->current_modes) free (killsess->current_modes); fe_session_callback (killsess); if (current_sess == killsess) { current_sess = NULL; if (sess_list) current_sess = sess_list->data; } free (killsess); if (!sess_list && !in_xchat_exit) xchat_exit (); /* sess_list is empty, quit! */ list = sess_list; while (list) { sess = (session *) list->data; if (sess->server == killserv) return; /* this server is still being used! */ list = list->next; } server_free (killserv); }
int main(int argc, char *argv[]) { char pidstr[16]; ssize_t ret; int c, log_method; char *logfile, *pidfile; int facility, fd; char *username = NULL; char *chrootdir = NULL; int configtest = 0; int singleprocess = 0; #ifdef HAVE_GETOPT_LONG int opt_idx; #endif pname = ((pname=strrchr(argv[0],'/')) != NULL)?pname+1:argv[0]; srand((unsigned int)time(NULL)); log_method = L_STDERR_SYSLOG; logfile = PATH_RADVD_LOG; conf_file = PATH_RADVD_CONF; facility = LOG_FACILITY; pidfile = PATH_RADVD_PID; /* parse args */ #define OPTIONS_STR "d:C:l:m:p:t:u:vhcs" #ifdef HAVE_GETOPT_LONG while ((c = getopt_long(argc, argv, OPTIONS_STR, prog_opt, &opt_idx)) > 0) #else while ((c = getopt(argc, argv, OPTIONS_STR)) > 0) #endif { switch (c) { case 'C': conf_file = optarg; break; case 'd': set_debuglevel(atoi(optarg)); break; case 'f': facility = atoi(optarg); break; case 'l': logfile = optarg; break; case 'p': pidfile = optarg; break; case 'm': if (!strcmp(optarg, "syslog")) { log_method = L_SYSLOG; } else if (!strcmp(optarg, "stderr_syslog")) { log_method = L_STDERR_SYSLOG; } else if (!strcmp(optarg, "stderr")) { log_method = L_STDERR; } else if (!strcmp(optarg, "logfile")) { log_method = L_LOGFILE; } else if (!strcmp(optarg, "none")) { log_method = L_NONE; } else { fprintf(stderr, "%s: unknown log method: %s\n", pname, optarg); exit(1); } break; case 't': chrootdir = strdup(optarg); break; case 'u': username = strdup(optarg); break; case 'v': version(); break; case 'c': configtest = 1; break; case 's': singleprocess = 1; break; case 'h': usage(); #ifdef HAVE_GETOPT_LONG case ':': fprintf(stderr, "%s: option %s: parameter expected\n", pname, prog_opt[opt_idx].name); exit(1); #endif case '?': exit(1); } } if (chrootdir) { if (!username) { fprintf(stderr, "Chroot as root is not safe, exiting\n"); exit(1); } if (chroot(chrootdir) == -1) { perror("chroot"); exit (1); } if (chdir("/") == -1) { perror("chdir"); exit (1); } /* username will be switched later */ } if (configtest) { log_method = L_STDERR; } if (log_open(log_method, pname, logfile, facility) < 0) { perror("log_open"); exit(1); } if (!configtest) { flog(LOG_INFO, "version %s started", VERSION); } /* get a raw socket for sending and receiving ICMPv6 messages */ sock = open_icmpv6_socket(); if (sock < 0) { perror("open_icmpv6_socket"); exit(1); } /* check that 'other' cannot write the file * for non-root, also that self/own group can't either */ if (check_conffile_perm(username, conf_file) < 0) { if (get_debuglevel() == 0) { flog(LOG_ERR, "Exiting, permissions on conf_file invalid.\n"); exit(1); } else flog(LOG_WARNING, "Insecure file permissions, but continuing anyway"); } /* if we know how to do it, check whether forwarding is enabled */ if (check_ip6_forwarding()) { flog(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway."); } /* parse config file */ if (readin_config(conf_file) < 0) { flog(LOG_ERR, "Exiting, failed to read config file.\n"); exit(1); } if (configtest) { fprintf(stderr, "Syntax OK\n"); exit(0); } /* drop root privileges if requested. */ if (username) { if (!singleprocess) { dlog(LOG_DEBUG, 3, "Initializing privsep"); if (privsep_init() < 0) flog(LOG_WARNING, "Failed to initialize privsep."); } if (drop_root_privileges(username) < 0) { perror("drop_root_privileges"); exit(1); } } if ((fd = open(pidfile, O_RDONLY, 0)) > 0) { ret = read(fd, pidstr, sizeof(pidstr) - 1); if (ret < 0) { flog(LOG_ERR, "cannot read radvd pid file, terminating: %s", strerror(errno)); exit(1); } pidstr[ret] = '\0'; if (!kill((pid_t)atol(pidstr), 0)) { flog(LOG_ERR, "radvd already running, terminating."); exit(1); } close(fd); fd = open(pidfile, O_CREAT|O_TRUNC|O_WRONLY, 0644); } else /* FIXME: not atomic if pidfile is on an NFS mounted volume */ fd = open(pidfile, O_CREAT|O_EXCL|O_WRONLY, 0644); if (fd < 0) { flog(LOG_ERR, "cannot create radvd pid file, terminating: %s", strerror(errno)); exit(1); } /* * okay, config file is read in, socket and stuff is setup, so * lets fork now... */ if (get_debuglevel() == 0) { /* Detach from controlling terminal */ if (daemon(0, 0) < 0) perror("daemon"); /* close old logfiles, including stderr */ log_close(); /* reopen logfiles, but don't log to stderr unless explicitly requested */ if (log_method == L_STDERR_SYSLOG) log_method = L_SYSLOG; if (log_open(log_method, pname, logfile, facility) < 0) { perror("log_open"); exit(1); } } /* * config signal handlers */ signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGINT, sigint_handler); signal(SIGUSR1, sigusr1_handler); snprintf(pidstr, sizeof(pidstr), "%ld\n", (long)getpid()); ret = write(fd, pidstr, strlen(pidstr)); if (ret != strlen(pidstr)) { flog(LOG_ERR, "cannot write radvd pid file, terminating: %s", strerror(errno)); exit(1); } close(fd); config_interface(); kickoff_adverts(); main_loop(); stop_adverts(); unlink(pidfile); return 0; }
int main(int argc, char *argv[]) { struct udev *udev; static const struct option options[] = { { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, {} }; const char *command; unsigned int i; int rc = 1; udev = udev_new(); if (udev == NULL) goto out; log_parse_environment(); log_open(); udev_set_log_fn(udev, udev_main_log); label_init("/dev"); for (;;) { int option; option = getopt_long(argc, argv, "+dhV", options, NULL); if (option == -1) break; switch (option) { case 'd': log_set_max_level(LOG_DEBUG); udev_set_log_priority(udev, LOG_DEBUG); break; case 'h': rc = adm_help(udev, argc, argv); goto out; case 'V': rc = adm_version(udev, argc, argv); goto out; default: goto out; } } command = argv[optind]; if (command != NULL) for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) { if (strcmp(udevadm_cmds[i]->name, command) == 0) { argc -= optind; argv += optind; optind = 1; rc = run_command(udev, udevadm_cmds[i], argc, argv); goto out; } } fprintf(stderr, "missing or unknown command\n\n"); adm_help(udev, argc, argv); rc = 2; out: label_finish(); udev_unref(udev); log_close(); return rc; }
int main( int argc, char **argv ) { int i; int use_sudo=0; int create_log=TD_LOG_NONE; int run_setlocale=1; int testdisk_mode=TESTDISK_O_RDONLY|TESTDISK_O_READAHEAD_32K; list_disk_t *list_disk=NULL; list_disk_t *element_disk; const char *logfile="photorec.log"; FILE *log_handle=NULL; int log_errno=0; struct ph_options options={ .paranoid=1, .keep_corrupted_file=0, .mode_ext2=0, .expert=0, .lowmem=0, .verbose=0, .list_file_format=list_file_enable }; struct ph_param params; params.recup_dir=NULL; params.cmd_device=NULL; params.cmd_run=NULL; params.carve_free_space_only=0; /* random (weak is ok) is need fot GPT */ srand(time(NULL)); #ifdef HAVE_SIGACTION /* set up the signal handler for SIGINT & SIGHUP */ sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGINT); sigaddset(&action.sa_mask, SIGHUP); action.sa_handler = sighup_hdlr; action.sa_flags = 0; if(sigaction(SIGINT, &action, NULL)==-1) { printf("Error on SIGACTION call\n"); return -1; } if(sigaction(SIGHUP, &action, NULL)==-1) { printf("Error on SIGACTION call\n"); return -1; } #endif printf("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n",VERSION,TESTDISKDATE); for(i=1;i<argc;i++) { if((strcmp(argv[i],"/logname")==0) ||(strcmp(argv[i],"-logname")==0)) { if(i+2>=argc) { display_help(); free(params.recup_dir); return 1; } logfile=argv[++i]; } else if((strcmp(argv[i],"/log")==0) ||(strcmp(argv[i],"-log")==0)) { if(create_log==TD_LOG_NONE) create_log=TD_LOG_APPEND; } else if((strcmp(argv[i],"/debug")==0) || (strcmp(argv[i],"-debug")==0)) { options.verbose++; if(create_log==TD_LOG_NONE) create_log=TD_LOG_APPEND; } else if(((strcmp(argv[i],"/d")==0)||(strcmp(argv[i],"-d")==0)) &&(i+1<argc)) { int len=strlen(argv[i+1]); if(argv[i+1][len-1]=='\\' || argv[i+1][len-1]=='/') { params.recup_dir=(char *)MALLOC(len + strlen(DEFAULT_RECUP_DIR) + 1); strcpy(params.recup_dir,argv[i+1]); strcat(params.recup_dir,DEFAULT_RECUP_DIR); } else params.recup_dir=strdup(argv[i+1]); i++; } else if((strcmp(argv[i],"/all")==0) || (strcmp(argv[i],"-all")==0)) testdisk_mode|=TESTDISK_O_ALL; else if((strcmp(argv[i],"/direct")==0) || (strcmp(argv[i],"-direct")==0)) testdisk_mode|=TESTDISK_O_DIRECT; else if((strcmp(argv[i],"/help")==0) || (strcmp(argv[i],"-help")==0) || (strcmp(argv[i],"--help")==0) || (strcmp(argv[i],"/h")==0) || (strcmp(argv[i],"-h")==0) || (strcmp(argv[i],"/?")==0) || (strcmp(argv[i],"-?")==0)) { display_help(); free(params.recup_dir); return 0; } else if((strcmp(argv[i],"/version")==0) || (strcmp(argv[i],"-version")==0) || (strcmp(argv[i],"--version")==0) || (strcmp(argv[i],"/v")==0) || (strcmp(argv[i],"-v")==0)) { display_version(); free(params.recup_dir); return 0; } else if((strcmp(argv[i],"/nosetlocale")==0) || (strcmp(argv[i],"-nosetlocale")==0)) run_setlocale=0; else if(strcmp(argv[i],"/cmd")==0) { if(i+2>=argc) { display_help(); free(params.recup_dir); return 1; } { disk_t *disk_car; params.cmd_device=argv[++i]; params.cmd_run=argv[++i]; /* There is no log currently */ disk_car=file_test_availability(params.cmd_device, options.verbose, testdisk_mode); if(disk_car==NULL) { printf("\nUnable to open file or device %s: %s\n", params.cmd_device, strerror(errno)); free(params.recup_dir); return 1; } list_disk=insert_new_disk(list_disk,disk_car); } } else { disk_t *disk_car=file_test_availability(argv[i], options.verbose, testdisk_mode); if(disk_car==NULL) { printf("\nUnable to open file or device %s: %s\n", argv[i], strerror(errno)); free(params.recup_dir); return 1; } list_disk=insert_new_disk(list_disk,disk_car); } } #ifdef ENABLE_DFXML xml_set_command_line(argc, argv); #endif if(create_log!=TD_LOG_NONE) log_handle=log_open(logfile, create_log, &log_errno); #ifdef HAVE_SETLOCALE if(run_setlocale>0) { const char *locale; locale = setlocale (LC_ALL, ""); if (locale==NULL) { locale = setlocale (LC_ALL, NULL); log_error("Failed to set locale, using default '%s'.\n", locale); } else { log_info("Using locale '%s'.\n", locale); } } #endif if(create_log!=TD_LOG_NONE && log_handle==NULL) log_handle=log_open_default(logfile, create_log, &log_errno); #ifdef HAVE_NCURSES /* ncurses need locale for correct unicode support */ if(start_ncurses("PhotoRec", argv[0])) { free(params.recup_dir); return 1; } { const char*filename=logfile; while(create_log!=TD_LOG_NONE && log_handle==NULL) { filename=ask_log_location(filename, log_errno); if(filename!=NULL) log_handle=log_open(filename, create_log, &log_errno); else create_log=TD_LOG_NONE; } } aff_copy(stdscr); wmove(stdscr,5,0); wprintw(stdscr, "Disk identification, please wait...\n"); wrefresh(stdscr); #endif if(log_handle!=NULL) { time_t my_time; #ifdef HAVE_DUP2 dup2(fileno(log_handle),2); #endif my_time=time(NULL); log_info("\n\n%s",ctime(&my_time)); log_info("Command line: PhotoRec"); for(i=1;i<argc;i++) log_info(" %s", argv[i]); log_info("\n\n"); } log_info("PhotoRec %s, Data Recovery Utility, %s\nChristophe GRENIER <*****@*****.**>\nhttp://www.cgsecurity.org\n", VERSION, TESTDISKDATE); log_info("OS: %s\n" , get_os()); log_info("Compiler: %s\n", get_compiler()); log_info("Compilation date: %s\n", get_compilation_date()); log_info("ext2fs lib: %s, ntfs lib: %s, ewf lib: %s, libjpeg: %s\n", td_ext2fs_version(), td_ntfs_version(), td_ewf_version(), td_jpeg_version()); #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP) #else #ifdef HAVE_GETEUID if(geteuid()!=0) { log_warning("User is not root!\n"); } #endif #endif log_flush(); screen_buffer_reset(); /* Scan for available device only if no device or image has been supplied in parameter */ if(list_disk==NULL) list_disk=hd_parse(list_disk, options.verbose, testdisk_mode); hd_update_all_geometry(list_disk, options.verbose); /* Activate the cache, even if photorec has its own */ for(element_disk=list_disk;element_disk!=NULL;element_disk=element_disk->next) { element_disk->disk=new_diskcache(element_disk->disk, testdisk_mode); } log_disk_list(list_disk); reset_list_file_enable(options.list_file_format); file_options_load(options.list_file_format); #ifdef SUDO_BIN if(list_disk==NULL) { #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(DJGPP) #else #ifdef HAVE_GETEUID if(geteuid()!=0) use_sudo=2; #endif #endif } #endif if(use_sudo==0) use_sudo=do_curses_photorec(¶ms, &options, list_disk); #ifdef HAVE_NCURSES end_ncurses(); #endif log_info("PhotoRec exited normally.\n"); if(log_close()!=0) { printf("PhotoRec: Log file corrupted!\n"); } else if(params.cmd_run!=NULL && params.cmd_run[0]!='\0') { printf("PhotoRec syntax error: %s\n", params.cmd_run); } #ifdef SUDO_BIN if(use_sudo>0) { printf("\n"); if(use_sudo>1) printf("No disk found.\n"); printf("PhotoRec will try to restart itself using the sudo command to get\n"); printf("root (superuser) privileges.\n"); printf("\n"); run_sudo(argc, argv); } #endif delete_list_disk(list_disk); free(params.recup_dir); #ifdef ENABLE_DFXML xml_clear_command_line(); #endif return 0; }
static int test_log (void) { Log_method *m; Log_unit *u1, *u2; char buf[1024]; starttesting ("log"); m = log_open ("util-tester", "/dev/stderr:notime"); if (m == NULL) return endtesting(1); u1 = log_unit_init (m, "u1", u1_units, 0x3); if (u1 == NULL) return endtesting(1); u2 = log_unit_init (m, "u2", u2_units, 0x0); if (u2 == NULL) return endtesting(1); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_log (u1, 0x1, "1. this should show"); log_log (u2, 0x1, "X. this should NOT show"); log_set_mask_str (m, NULL, "u1:-debug;u2:+debug"); log_log (u1, 0x1, "X. now this should NOT show"); log_log (u2, 0x1, "2. now this should show"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_set_mask_str (m, NULL, "u1:-debug;u2:-debug"); log_log (u1, 0x1, "X. now this should NOT show"); log_log (u2, 0x1, "X. now this should NOT show"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_set_mask_str (m, NULL, "+debug"); log_log (u1, 0x1, "3. now this should show"); log_log (u2, 0x1, "4. now this should show"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_set_mask_str (m, NULL, "-debug"); log_log (u1, 0x1, "X. now this should NOT show"); log_log (u2, 0x1, "X. now this should NOT show"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_set_mask_str (m, NULL, "+debug,+warning"); log_log (u1, 0x1, "5. now this should show"); log_log (u2, 0x1, "6. now this should show"); log_log (u1, 0x2, "7. now this should show"); log_log (u2, 0x2, "8. now this should show"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_set_mask_str (m, u1, "-debug,-warning"); log_log (u1, 0x1, "X. now this should NOT show"); log_log (u2, 0x1, "9. now this should show"); log_log (u1, 0x2, "X. now this should NOT show"); log_log (u2, 0x2, "10. now this should show"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_set_mask (u1, 0x4 + 0x2 + 0x1); log_set_mask (u2, 0x8 + 0x4 + 0x2 + 0x1); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("%s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, buf); log_set_mask_str (m, NULL, "all"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("all: %s\n", buf); fflush (stdout); log_set_mask_str (m, NULL, "-all"); log_mask2str (m, NULL, buf, sizeof(buf)); printf ("none: %s\n", buf); fflush (stdout); log_close (m); return endtesting (0); }
void session_free (session *killsess) { server *killserv = killsess->server; session *sess; GSList *list; if (current_tab == killsess) current_tab = NULL; if (killserv->server_session == killsess) killserv->server_session = NULL; if (killserv->front_session == killsess) { /* front_session is closed, find a valid replacement */ killserv->front_session = NULL; list = sess_list; while (list) { sess = (session *) list->data; if (sess != killsess && sess->server == killserv) { killserv->front_session = sess; if (!killserv->server_session) killserv->server_session = sess; break; } list = list->next; } } if (!killserv->server_session) killserv->server_session = killserv->front_session; sess_list = g_slist_remove (sess_list, killsess); signal_emit("session destroy", 1, killsess); if (killsess->type == SESS_CHANNEL) userlist_free (killsess); log_close (killsess); scrollback_close (killsess); send_quit_or_part (killsess); history_free (&killsess->history); if (killsess->topic) free (killsess->topic); if (killsess->current_modes) free (killsess->current_modes); fe_session_callback (killsess); if (current_sess == killsess) { current_sess = NULL; if (sess_list) current_sess = sess_list->data; } if (killsess->lastact_elem) { if (killsess->lastact_idx != LACT_NONE) sess_list_by_lastact[killsess->lastact_idx] = g_list_delete_link(sess_list_by_lastact[killsess->lastact_idx], killsess->lastact_elem); else g_list_free_1(killsess->lastact_elem); } free (killsess); if (!sess_list && !in_xchat_exit) xchat_exit (); /* sess_list is empty, quit! */ list = sess_list; while (list) { sess = (session *) list->data; if (sess->server == killserv) return; /* this server is still being used! */ list = list->next; } server_free (killserv); }
int gongfu_log_close() { if( gongfu_log_handle == NULL)return 0; return log_close(gongfu_log_handle); }
int daemonize_trqauthd(const char *server_ip, int server_port, void *(*process_meth)(void *)) { int gid; pid_t pid; int rc; char error_buf[MAX_BUF]; char msg_trqauthddown[MAX_BUF]; char path_log[MAXPATHLEN + 1]; char *log_file=NULL; int eventclass = PBS_EVENTCLASS_TRQAUTHD; const char *path_home = PBS_SERVER_HOME; umask(022); gid = getgid(); /* secure supplemental groups */ if(setgroups(1, (gid_t *)&gid) != 0) { fprintf(stderr, "Unable to drop secondary groups. Some MAC framework is active?\n"); snprintf(error_buf, sizeof(error_buf), "setgroups(group = %lu) failed: %s\n", (unsigned long)gid, strerror(errno)); fprintf(stderr, "%s\n", error_buf); return(1); } if (getenv("PBSDEBUG") != NULL) debug_mode = TRUE; if (debug_mode == FALSE) { pid = fork(); if(pid > 0) { /* parent. We are done */ return(0); } else if (pid < 0) { /* something went wrong */ fprintf(stderr, "fork failed. errno = %d\n", errno); return(PBSE_RMSYSTEM); } else { fprintf(stderr, "trqauthd daemonized - port %d\n", server_port); /* If I made it here I am the child */ fclose(stdin); fclose(stdout); fclose(stderr); /* We closed 0 (stdin), 1 (stdout), and 2 (stderr). fopen should give us 0, 1 and 2 in that order. this is a UNIX practice */ if (fopen("/dev/null", "r") == NULL) perror(__func__); if (fopen("/dev/null", "r") == NULL) perror(__func__); if (fopen("/dev/null", "r") == NULL) perror(__func__); } } else { fprintf(stderr, "trqauthd port: %d\n", server_port); } log_init(NULL, NULL); log_get_set_eventclass(&eventclass, SETV); initialize_globals_for_log(); sprintf(path_log, "%s/%s", path_home, TRQ_LOGFILES); if ((mkdir(path_log, 0755) == -1) && (errno != EEXIST)) { openlog("daemonize_trqauthd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); syslog(LOG_ALERT, "Failed to create client_logs directory: errno: %d", errno); log_err(errno,"daemonize_trqauthd", "Failed to create client_logs directory"); closelog(); } pthread_mutex_lock(log_mutex); log_open(log_file, path_log); pthread_mutex_unlock(log_mutex); /* start the listener */ rc = start_listener(server_ip, server_port, process_meth); if(rc != PBSE_NONE) { openlog("daemonize_trqauthd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); syslog(LOG_ALERT, "trqauthd could not start: %d\n", rc); log_err(rc, "daemonize_trqauthd", (char *)"trqauthd could not start"); pthread_mutex_lock(log_mutex); log_close(1); pthread_mutex_unlock(log_mutex); if (changed_msg_daem && msg_daemonname) { free(msg_daemonname); } clean_log_init_mutex(); exit(-1); } snprintf(msg_trqauthddown, sizeof(msg_trqauthddown), "TORQUE authd daemon shut down and no longer listening on IP:port %s:%d", server_ip, server_port); log_event(PBSEVENT_SYSTEM | PBSEVENT_FORCE, PBS_EVENTCLASS_TRQAUTHD, msg_daemonname, msg_trqauthddown); pthread_mutex_lock(log_mutex); log_close(1); pthread_mutex_unlock(log_mutex); if (changed_msg_daem && msg_daemonname) { free(msg_daemonname); } clean_log_init_mutex(); exit(0); }
//main.c int main(int argc, char** argv) { addInfoLog(0,"==========billingd start=============="); addInfoLog(0,VER); //register the sig signal(SIGTERM, sigproc); signal(SIGHUP, sigproc); options_parse(argc, argv); if( daemon_mode ) daemonize(); if(check_running_pid()) exit(3); syn_time(); fd_table_init(); last_billing_out_time = time(NULL); // time() initialize last_rcv_ok = last_billing_out_time; last_up_time = last_billing_out_time; start_time.uptime_init = 0; start_time.write_init = 0; start_time.uptime_init = readuptime(); start_time.write_init = last_billing_out_time; //parse config file if ( !getBillingConfig(CONFIG_FILE) ) { addInfoLog(2,"Erorr when parsing config file"); exit(0); } if(conf.on_off == 0) { addInfoLog(0,"mod billing set off"); exit(0); } dealwith_folder(); hashtable_init(); billingd_epoll_init(); //fixme: 先写一次日志 addInfoLog(0,"first write billing data\n"); if( !writelog() ) { char errMessage[1024]; snprintf(errMessage, 1024, "[%s][%d]\t%s\n",(char *)__FILE__, __LINE__, "writelog Error"); addInfoLog(2,errMessage); exit(3); } //creat socket int SockFd; if( (SockFd = socket(AF_INET,SOCK_STREAM,0)) < 0 ) { addInfoLog(2,"socket creat error,exit"); exit(0); } struct sockaddr_in ServerAddress; memset(&(ServerAddress), 0, sizeof(ServerAddress)); ServerAddress.sin_family = AF_INET; ServerAddress.sin_port = htons(Port); ServerAddress.sin_addr.s_addr = htonl(INADDR_ANY); int option = 1; if( setsockopt(SockFd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)) < 0 ) { addInfoLog(2,"setsockopt error,exit"); exit(0); } while( bind(SockFd,(struct sockaddr*)&ServerAddress, sizeof(struct sockaddr)) < 0 ) { addInfoLog(2,"socket bind error"); sleep(1); } if( listen(SockFd, 10) < 0 ) { addInfoLog(2,"socket listen error,exit"); exit(0); } // add the socket to epoll to listen new connections billingd_epoll_add(SockFd,EPOLLIN | EPOLLHUP | EPOLLERR); listen_fd = SockFd; time_t checktime; char checkMessage[1024]; uint32_t wait_count = 0; while(1) { checktime = time(NULL); //================= write the billing file according to the system time start======== if (checktime - last_billing_out_time > 599) { addInfoLog(2,"billingd time now has surpass last_write_ok override 600 seconds\n"); if (wait_count < 60 ) { //ensure all data come,wait 60s snprintf(checkMessage, 1024, "data comes,wait all data come[%d][%d]continue",wait_count,conf.interval); addInfoLog(0,checkMessage); wait_count++; } else { addInfoLog(0,"the last data comes ,cut it\n"); wait_count = 0; // count recover flag_cut_point = true; if(!writelog()) { char errMessage_1[1024]; snprintf(errMessage_1, 1024, "[%s][%d]\t%s\n",(char *)__FILE__, __LINE__, "writelog Error"); addInfoLog(2,errMessage_1); exit(3); } } } else if ( checktime - last_billing_out_time < 0) { snprintf(checkMessage, 1024, "[%s][%d]\tchecktime:%d < last_billing_out_time:%d\n",(char *)__FILE__, __LINE__, (int)checktime, (int)last_billing_out_time); addInfoLog(0,checkMessage); syn_time(); // adjust clock if(!writelog()) { char errMessage_1[1024]; snprintf(errMessage_1, 1024, "[%s][%d]\t%s\n",(char *)__FILE__, __LINE__, "writelog Error"); addInfoLog(2,errMessage_1); exit(3); } } //如果现在时间比上次写时间超过interval了, 就写个文件 else if (checktime - last_billing_out_time >= conf.interval ) { char result[200]; snprintf(result,200,"checktime:%d - last_billing_out_time:%d = %d;internal=%d",(int)checktime,(int)last_billing_out_time,(int)(checktime-last_billing_out_time),conf.interval); addInfoLog(1,result); addInfoLog(1,"checktime >= last_billing_out_time + conf.interval"); if(!writelog()) { char errMessage_2[1024]; snprintf(errMessage_2, 1024, "[%s][%d]\t%s\n",(char *)__FILE__, __LINE__, "writelog Error"); addInfoLog(2,errMessage_2); exit(3); } } else { // checktime - last_billing_out_time < conf.interval // do nothing } //================== write the billing file according to the system time end========== //如果需要关闭了, 也先写个文件, 然后退出 if(shutdown_flag == true) { writelog(); log_close(); fd_table_dest(); exit(1); } //如果需要reload, 写个文件, 然后清空配置(regex)链表, 重新load configure, 然后继续 if(reload_flag == true) { if(!writelog()) { char errMessage_3[1024]; snprintf(errMessage_3, 1024, "[%s][%d]\t%s\n",(char *)__FILE__, __LINE__, "writelog Error"); addInfoLog(2,errMessage_3); exit(3); } //释放掉正则连结构 struct billingConfNode* qstart = conf.confHead; struct billingConfNode* ploop = NULL; struct billingConfNode* ptemp = NULL; for( ploop = qstart; ploop; ) { ptemp = ploop->next; cc_free(ploop->regComp); cc_free(ploop); ploop = ptemp; } conf.confHead = NULL; //重新装载配置 if ( !getBillingConfig(CONFIG_FILE) ) { addInfoLog(2,"erorr happens when parsing config file"); exit(0); } reload_flag = false; } /* epoll wait when billing data arrive and new connection come this is a simple epoll,we only focus on read */ billing_epoll_wait(); } }
void cmd_close(void) { #if (USE_TELELOG == 1) log_close(); #endif }
static void check_db(sqlite3 *db, int new_db, pid_t *scanner_pid) { char cmd[PATH_MAX*2]; int ret; #ifdef MD_CHECK_MP struct media_dir_s *media_path = NULL; char **result; int i, rows = 0; if (!new_db) { /* Check if any new media dirs appeared */ media_path = media_dirs; while (media_path) { ret = sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where PATH = %Q", media_path->path); if (ret != media_path->types) { ret = 1; goto rescan; } media_path = media_path->next; } /* Check if any media dirs disappeared */ sql_get_table(db, "SELECT VALUE from SETTINGS where KEY = 'media_dir'", &result, &rows, NULL); for (i=1; i <= rows; i++) { media_path = media_dirs; while (media_path) { if (strcmp(result[i], media_path->path) == 0) break; media_path = media_path->next; } if (!media_path) { ret = 2; sqlite3_free_table(result); goto rescan; } } sqlite3_free_table(result); } #endif ret = db_upgrade(db); if ((ret != 0) || (GETFLAG(UPDATE_SCAN_MASK))) { if (ret != 0) { #ifdef MD_CHECK_MP rescan: #endif if (ret < 0) DPRINTF(E_WARN, L_GENERAL, "Creating new database at %s/files.db\n", db_path); #ifdef MD_CHECK_MP else if (ret == 1) DPRINTF(E_WARN, L_GENERAL, "New media_dir detected; rescanning...\n"); else if (ret == 2) DPRINTF(E_WARN, L_GENERAL, "Removed media_dir detected; rescanning...\n"); #endif else DPRINTF(E_WARN, L_GENERAL, "Database version mismatch (%d=>%d); need to recreate...\n", ret, DB_VERSION); sqlite3_close(db); snprintf(cmd, sizeof(cmd), "rm -rf %s/files.db %s/art_cache", db_path, db_path); if (system(cmd) != 0) DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache! Exiting...\n"); open_db(&db); if (CreateDatabase() != 0) DPRINTF(E_FATAL, L_GENERAL, "ERROR: Failed to create sqlite database! Exiting...\n"); } #if USE_FORK scanning = 1; sqlite3_close(db); *scanner_pid = fork(); open_db(&db); if (*scanner_pid == 0) /* child (scanner) process */ { start_scanner(); sqlite3_close(db); log_close(); freeoptions(); exit(EXIT_SUCCESS); } else if (*scanner_pid < 0) { start_scanner(); } #else start_scanner(); #endif } }
/***************************************************************** Start here *****************************************************************/ int main(int np, char **p) { char src_drive[NAME_LENGTH] = "/dev/hda", /* source drive */ dst_drive[NAME_LENGTH] = "/dev/hdb"; /* destination drive */ int help = 0, /* set to true to indicate problem with command line */ ask_for_partitions = 1, /* default is true; set to false if partitions given on command line */ status, /* error return on I/O operations */ i; /* loop index */ static disk_control_block *src_disk,*dst_disk; static off_t lba = 0, /* a sector LBA address usually found as a loop index */ common, /* number of sectors common to source & destination */ diffs = 0, /* count of sectors that don't match */ src_lba, /* address of current sector on source */ dst_lba, /* address of current sector on destination */ byte_diffs = 0, /* count of bytes that differ between src and dst */ match = 0, /* number of matching sectors */ /* zero .. other apply to dst sectors beyond common area */ zero = 0, /* number of zero filled sectors */ sfill = 0, /* number of sectors filled with src fill char */ dfill = 0, /* number of sectors filled with dst fill char */ ofill = 0, /* number of sectors filled with some other fill char */ other = 0; /* number of remaining (unfilled) sectors */ static unsigned long nz, /* number of zero filled bytes in a sector */ nfill; /* number of fill bytes in a sector */ int big_src = 0, /* true if src bigger than dst */ big_dst = 0, /* true if dst bigger than src */ is_diff, boot_track_too = 0; /* include boot track in compare */ int src_status, dst_status; /* I/O error returns */ static unsigned char *src_buff,*dst_buff; /* sector buffers */ static time_t from; /* run start time */ FILE *log; /* log file */ int is_debug = 0, log_diffs = 0; unsigned char src_fill_char, dst_fill_char; /* fill characters */ int fill_char; int src_px,dst_px; /* partition table indices from command line */ off_t src_base, /* LBA address of source partition */ src_n, /* size (number of sectors in) source partition */ dst_base, /* ditto dst */ dst_n; /* range_ptr is used to track a list of ranges. In this case the ranges are disk areas specified in LBA addresses */ range_ptr d_r = create_range_list(), /* common area sectors that don't match */ zf_r = create_range_list(), /* zero filled sectors */ sf_r = create_range_list(), /* sectors with src-fill */ df_r = create_range_list(), /* sectors with dst-fill */ of_r = create_range_list(), /* sectors with some other fill */ o_r = create_range_list(); /* other (unfilled) sectors */ static char comment[NAME_LENGTH] = "", log_name[NAME_LENGTH] = "cmpptlog.txt", access[2] = "a"; /***************************************************************** get start run time and decode command line *****************************************************************/ time(&from); if (np < 8) { printf ("%s: Missing parameters\n",p[0]); print_help(p[0]); return 1; } /***************************************************************** get fill characters from command line *****************************************************************/ sscanf (p[5],"%2x",&fill_char); src_fill_char = fill_char; sscanf (p[7],"%2x",&fill_char); dst_fill_char = fill_char; /***************************************************************** get options from command line *****************************************************************/ for (i = 8; i < np; i++) { if (strcmp (p[i],"-h") == 0) help = 1; /* ask for help */ else if (strcmp (p[i],"-select") == 0) { /* /select src_ix dst_ix */ i = i + 2; if (i >= np) { printf ("%s -select requires two parameters: src partition index\n", p[0]); printf ("and dst partition index\n"); help = 1; } else { sscanf (p[i-1],"%d",&src_px); sscanf (p[i],"%d",&dst_px); ask_for_partitions = 0; /* we got 'em so don't ask */ } } else if (strcmp (p[i],"-new_log")== 0) access[0] = 'w'; else if (strcmp (p[i], "-log_name") == 0) { if(++i >= np) { printf("%s: -log_name option requires a logfile name\n", p[0]); help = 1; } else strncpy(log_name, p[i], NAME_LENGTH - 1); } else if (strcmp (p[i],"-boot")== 0) boot_track_too = 1; else if (strcmp (p[i],"-comment")== 0) { i++; if ( i>=np){ printf ("%s: comment required with -comment\n", p[0]); help = 1; } else strncpy (comment,p[i], NAME_LENGTH - 1); } else { printf("Invalid parameter: %s\n", p[i]); help = 1; } } /***************************************************************** get source and destination drives (in hex) from command line *****************************************************************/ strncpy(src_drive, p[4], NAME_LENGTH - 1); strncpy(dst_drive, p[6], NAME_LENGTH - 1); if (!strcmp(src_drive, dst_drive)) { help = 1; printf ("Source and destination drives must be different\n"); } /***************************************************************** If there is a problem on command line, then print help message *****************************************************************/ if (help) { print_help(p[0]); return 0; } /***************************************************************** Open log file, source disk and destination disk *****************************************************************/ log = log_open (log_name, access, comment, SCCS_ID, np, p); status = setup_disk (src_drive, "Source disk", log, p, ask_for_partitions, src_px, &src_base, &src_n, &src_disk); status = status || setup_disk (dst_drive, "Destination disk", log, p, ask_for_partitions, dst_px, &dst_base, &dst_n, &dst_disk); if (status) return 1; /***************************************************************** get ready to do the compare see which is bigger: src or dst *****************************************************************/ if (src_n != dst_n) { if ( src_n < dst_n) { common = src_n; big_dst = 1; } else { common = dst_n; big_src = 1; } } else common = src_n; printf ("Source disk fill byte %2X\n", src_fill_char); printf ("Destination disk fill byte %2X\n", dst_fill_char); fprintf (log, "Source disk fill byte %2X\n", src_fill_char); fprintf (log, "Destination disk fill byte %2X\n", dst_fill_char); src_lba = src_base; dst_lba = dst_base; if (boot_track_too) { common += 63; src_lba -= 63; dst_lba -= 63; src_base -= 63; dst_base -= 63; src_n += 63; dst_n += 63; } fprintf (log,"Source base sector %llu Destination base sector %llu\n", src_base,dst_base); /***************************************************************** Main compare loop: for each sector in common read src sector read dst sector if match then increment match count else increment different count *****************************************************************/ for (lba = 0; lba < common; lba++) { feedback (from, 0, lba, big_dst ? dst_n : common); /* give progress feedback to user */ is_diff = 0; src_status = read_lba(src_disk, src_lba++, &src_buff); dst_status = read_lba(dst_disk, dst_lba++, &dst_buff); if (src_status || dst_status) { fprintf (log,"read error at sector %llu: src %d dst %d\n", lba, src_status, dst_status); printf ("read error at lba %llu: src %d dst %d\n", lba, src_status, dst_status); return 1; } /***************************************************************** Compare corresponding sectors *****************************************************************/ for (i = 0; i < BYTES_PER_SECTOR; i++) { if (src_buff[i] != dst_buff[i]) { is_diff = 1; byte_diffs++; } } if (is_diff) { diffs++; add_to_range (d_r,lba); if (log_diffs && (diffs <= 50)) { fprintf (log,"%12llu ",lba); if ((diffs%5) == 0) fprintf (log,"\n"); } } else { match++; } } /***************************************************************** Log results for corresponding sectors *****************************************************************/ if (log_diffs && (diffs)) fprintf (log,"\n"); fprintf (log,"Sectors compared: %12llu\n",common); fprintf (log,"Sectors match: %12llu\n",match); fprintf (log,"Sectors differ: %12llu\n",diffs); fprintf (log,"Bytes differ: %12llu\n",byte_diffs); print_range_list(log,"Diffs range: ",d_r); if (big_src) { fprintf (log,"Source (%llu) has %llu more sectors than destination (%llu)\n", src_n, src_n - dst_n, dst_n); } /***************************************************************** If the destination is larger than the source then look at the remainder of the destination *****************************************************************/ else if (big_dst) { fprintf (log,"Source (%llu) has %llu fewer sectors than destination (%llu)\n", src_n, dst_n - src_n, dst_n); zero = 0; ofill = sfill = dfill = 0; other = 0; printf ("Destination larger than source; scanning %llu sectors\n", dst_n-common); for (lba = common; lba < dst_n; is_debug?(lba+=100):lba++){ feedback (from, 0, lba, dst_n); if((dst_status = read_lba(dst_disk, dst_lba++, &dst_buff))) { fprintf (log,"read error at sector %llu: dst %d\n", lba, dst_status); printf ("read error at lba %llu: dst %d\n", lba, dst_status); } nz = 0; nfill = 0; /***************************************************************** classify sector: count zero bytes and fill bytes how to count fill bytes? the rule is: all bytes after byte [23] are the same. i.e., 488 bytes of the sector are the same. We use 480 to give some slack. *****************************************************************/ for (i = 0; i < BYTES_PER_SECTOR; i++) { if ( dst_buff[i] == 0) nz++; else if (dst_buff[i] == dst_buff[BUFF_OFF]) nfill++; } if (nz == BYTES_PER_SECTOR) { zero++; add_to_range(zf_r,lba); } else if (nfill > 480) { if (dst_buff[BUFF_OFF] == src_fill_char) { sfill++; add_to_range(sf_r,lba); } else if (dst_buff[BUFF_OFF] == dst_fill_char) { dfill++; add_to_range(df_r,lba); } else { ofill++; add_to_range(of_r,lba); } } else { other++; add_to_range (o_r,lba); } } /***************************************************************** log results to log file *****************************************************************/ if (log_diffs && (other)) fprintf (log, "\n"); fprintf (log,"Zero fill: %llu\n", zero); fprintf (log,"Src Byte fill (%02X): %llu\n", src_fill_char, sfill); if (src_fill_char == dst_fill_char) fprintf (log, "Dst Fill Byte same as Src Fill Byte\n"); else fprintf (log, "Dst Byte fill (%02X): %lu\n", dst_fill_char, dfill); fprintf (log,"Other fill: %llu\n", ofill); fprintf (log,"Other no fill: %llu\n", other); print_range_list(log,"Zero fill range: ", zf_r); print_range_list(log,"Src fill range: ", sf_r); print_range_list(log,"Dst fill range: ", df_r); print_range_list(log,"Other fill range: ", of_r); print_range_list(log,"Other not filled range: ", o_r); } log_close(log, from); return 0; }
static void child_process(entry *e) { int stdin_pipe[2], stdout_pipe[2]; char * volatile input_data; char *homedir, *usernm, * volatile mailto; int children = 0; Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd)); setproctitle("running job"); /* discover some useful and important environment settings */ usernm = e->pwd->pw_name; mailto = env_get("MAILTO", e->envp); /* our parent is watching for our death by catching SIGCHLD. we * do not care to watch for our children's deaths this way -- we * use wait() explicitly. so we have to reset the signal (which * was inherited from the parent). */ (void) signal(SIGCHLD, SIG_DFL); /* create some pipes to talk to our future child */ if (pipe(stdin_pipe) == -1) /* child's stdin */ log_it("CRON", getpid(), "error", "create child stdin pipe"); if (pipe(stdout_pipe) == -1) /* child's stdout */ log_it("CRON", getpid(), "error", "create child stdout pipe"); /* since we are a forked process, we can diddle the command string * we were passed -- nobody else is going to use it again, right? * * if a % is present in the command, previous characters are the * command, and subsequent characters are the additional input to * the command. An escaped % will have the escape character stripped * from it. Subsequent %'s will be transformed into newlines, * but that happens later. */ /*local*/{ int escaped = FALSE; int ch; char *p; /* translation: * \% -> % * % -> end of command, following is command input. * \x -> \x for all x != % */ input_data = p = e->cmd; while ((ch = *input_data++) != '\0') { if (escaped) { if (ch != '%') *p++ = '\\'; } else { if (ch == '%') { break; } } if (!(escaped = (ch == '\\'))) { *p++ = ch; } } if (ch == '\0') { /* move pointer back, so that code below * won't think we encountered % sequence */ input_data--; } if (escaped) *p++ = '\\'; *p = '\0'; } /* fork again, this time so we can exec the user's command. */ switch (vfork()) { case -1: log_it("CRON", getpid(), "error", "can't vfork"); exit(ERROR_EXIT); /*NOTREACHED*/ case 0: Debug(DPROC, ("[%ld] grandchild process vfork()'ed\n", (long)getpid())); /* write a log message. we've waited this long to do it * because it was not until now that we knew the PID that * the actual user command shell was going to get and the * PID is part of the log message. */ if ((e->flags & DONT_LOG) == 0) { char *x = mkprints(e->cmd, strlen(e->cmd)); log_it(usernm, getpid(), "CMD START", x); free(x); } /* that's the last thing we'll log. close the log files. */ log_close(); /* get new pgrp, void tty, etc. */ if (setsid() == -1) syslog(LOG_ERR, "setsid() failure: %m"); /* close the pipe ends that we won't use. this doesn't affect * the parent, who has to read and write them; it keeps the * kernel from recording us as a potential client TWICE -- * which would keep it from sending SIGPIPE in otherwise * appropriate circumstances. */ (void)close(stdin_pipe[WRITE_PIPE]); (void)close(stdout_pipe[READ_PIPE]); /* grandchild process. make std{in,out} be the ends of * pipes opened by our daddy; make stderr go to stdout. */ if (stdin_pipe[READ_PIPE] != STDIN) { (void)dup2(stdin_pipe[READ_PIPE], STDIN); (void)close(stdin_pipe[READ_PIPE]); } if (stdout_pipe[WRITE_PIPE] != STDOUT) { (void)dup2(stdout_pipe[WRITE_PIPE], STDOUT); (void)close(stdout_pipe[WRITE_PIPE]); } (void)dup2(STDOUT, STDERR); /* set our directory, uid and gid. Set gid first, since once * we set uid, we've lost root privledges. */ #ifdef LOGIN_CAP { #ifdef BSD_AUTH auth_session_t *as; #endif login_cap_t *lc; char *p; if ((lc = login_getclass(e->pwd->pw_class)) == NULL) { warnx("unable to get login class for `%s'", e->pwd->pw_name); _exit(ERROR_EXIT); } if (setusercontext(lc, e->pwd, e->pwd->pw_uid, LOGIN_SETALL) < 0) { warnx("setusercontext failed for `%s'", e->pwd->pw_name); _exit(ERROR_EXIT); } #ifdef BSD_AUTH as = auth_open(); if (as == NULL || auth_setpwd(as, e->pwd) != 0) { warn("can't malloc"); _exit(ERROR_EXIT); } if (auth_approval(as, lc, usernm, "cron") <= 0) { warnx("approval failed for `%s'", e->pwd->pw_name); _exit(ERROR_EXIT); } auth_close(as); #endif /* BSD_AUTH */ login_close(lc); /* If no PATH specified in crontab file but * we just added one via login.conf, add it to * the crontab environment. */ if (env_get("PATH", e->envp) == NULL) { if ((p = getenv("PATH")) != NULL) e->envp = env_set(e->envp, p); } } #else if (setgid(e->pwd->pw_gid) != 0) { syslog(LOG_ERR, "setgid(%d) failed for %s: %m", e->pwd->pw_gid, e->pwd->pw_name); _exit(ERROR_EXIT); } if (initgroups(usernm, e->pwd->pw_gid) != 0) { syslog(LOG_ERR, "initgroups(%s, %d) failed for %s: %m", usernm, e->pwd->pw_gid, e->pwd->pw_name); _exit(ERROR_EXIT); } #if (defined(BSD)) && (BSD >= 199103) if (setlogin(usernm) < 0) { syslog(LOG_ERR, "setlogin(%s) failure for %s: %m", usernm, e->pwd->pw_name); _exit(ERROR_EXIT); } #endif /* BSD */ if (setuid(e->pwd->pw_uid) != 0) { syslog(LOG_ERR, "setuid(%d) failed for %s: %m", e->pwd->pw_uid, e->pwd->pw_name); _exit(ERROR_EXIT); } /* we aren't root after this... */ #endif /* LOGIN_CAP */ homedir = env_get("HOME", e->envp); if (chdir(homedir) != 0) { syslog(LOG_ERR, "chdir(%s) $HOME failed for %s: %m", homedir, e->pwd->pw_name); _exit(ERROR_EXIT); } #ifdef USE_SIGCHLD /* our grandparent is watching for our death by catching * SIGCHLD. the parent is ignoring SIGCHLD's; we want * to restore default behaviour. */ (void) signal(SIGCHLD, SIG_DFL); #endif (void) signal(SIGHUP, SIG_DFL); /* * Exec the command. */ { char *shell = env_get("SHELL", e->envp); # if DEBUGGING if (DebugFlags & DTEST) { (void)fprintf(stderr, "debug DTEST is on, not exec'ing command.\n"); (void)fprintf(stderr, "\tcmd='%s' shell='%s'\n", e->cmd, shell); _exit(OK_EXIT); } # endif /*DEBUGGING*/ (void)execle(shell, shell, "-c", e->cmd, NULL, e->envp); warn("execl: couldn't exec `%s'", shell); _exit(ERROR_EXIT); } break; default: /* parent process */ break; } children++; /* middle process, child of original cron, parent of process running * the user's command. */ Debug(DPROC, ("[%ld] child continues, closing pipes\n",(long)getpid())); /* close the ends of the pipe that will only be referenced in the * grandchild process... */ (void)close(stdin_pipe[READ_PIPE]); (void)close(stdout_pipe[WRITE_PIPE]); /* * write, to the pipe connected to child's stdin, any input specified * after a % in the crontab entry. while we copy, convert any * additional %'s to newlines. when done, if some characters were * written and the last one wasn't a newline, write a newline. * * Note that if the input data won't fit into one pipe buffer (2K * or 4K on most BSD systems), and the child doesn't read its stdin, * we would block here. thus we must fork again. */ if (*input_data && fork() == 0) { FILE *out = fdopen(stdin_pipe[WRITE_PIPE], "w"); int need_newline = FALSE; int escaped = FALSE; int ch; Debug(DPROC, ("[%ld] child2 sending data to grandchild\n", (long)getpid())); /* close the pipe we don't use, since we inherited it and * are part of its reference count now. */ (void)close(stdout_pipe[READ_PIPE]); /* translation: * \% -> % * % -> \n * \x -> \x for all x != % */ while ((ch = *input_data++) != '\0') { if (escaped) { if (ch != '%') (void)putc('\\', out); } else { if (ch == '%') ch = '\n'; } if (!(escaped = (ch == '\\'))) { (void)putc(ch, out); need_newline = (ch != '\n'); } } if (escaped) (void)putc('\\', out); if (need_newline) (void)putc('\n', out); /* close the pipe, causing an EOF condition. fclose causes * stdin_pipe[WRITE_PIPE] to be closed, too. */ (void)fclose(out); Debug(DPROC, ("[%ld] child2 done sending to grandchild\n", (long)getpid())); exit(0); } /* close the pipe to the grandkiddie's stdin, since its wicked uncle * ernie back there has it open and will close it when he's done. */ (void)close(stdin_pipe[WRITE_PIPE]); children++; /* * read output from the grandchild. it's stderr has been redirected to * it's stdout, which has been redirected to our pipe. if there is any * output, we'll be mailing it to the user whose crontab this is... * when the grandchild exits, we'll get EOF. */ Debug(DPROC, ("[%ld] child reading output from grandchild\n", (long)getpid())); /*local*/{ FILE *in = fdopen(stdout_pipe[READ_PIPE], "r"); int ch = getc(in); if (ch != EOF) { FILE *mail = NULL; int bytes = 1; int status = 0; Debug(DPROC|DEXT, ("[%ld] got data (%x:%c) from grandchild\n", (long)getpid(), ch, ch)); /* get name of recipient. this is MAILTO if set to a * valid local username; USER otherwise. */ if (mailto) { /* MAILTO was present in the environment */ if (!*mailto) { /* ... but it's empty. set to NULL */ mailto = NULL; } } else { /* MAILTO not present, set to USER. */ mailto = usernm; } /* if we are supposed to be mailing, MAILTO will * be non-NULL. only in this case should we set * up the mail command and subjects and stuff... */ if (mailto && safe_p(usernm, mailto)) { char **env; char mailcmd[MAX_COMMAND]; char hostname[MAXHOSTNAMELEN + 1]; (void)gethostname(hostname, MAXHOSTNAMELEN); if (strlens(MAILFMT, MAILARG, NULL) + 1 >= sizeof mailcmd) { warnx("mailcmd too long"); (void) _exit(ERROR_EXIT); } (void)snprintf(mailcmd, sizeof(mailcmd), MAILFMT, MAILARG); if (!(mail = cron_popen(mailcmd, "w", e->pwd))) { warn("cannot run `%s'", mailcmd); (void) _exit(ERROR_EXIT); } (void)fprintf(mail, "From: root (Cron Daemon)\n"); (void)fprintf(mail, "To: %s\n", mailto); (void)fprintf(mail, "Subject: Cron <%s@%s> %s\n", usernm, first_word(hostname, "."), e->cmd); (void)fprintf(mail, "Auto-Submitted: auto-generated\n"); #ifdef MAIL_DATE (void)fprintf(mail, "Date: %s\n", arpadate(&StartTime)); #endif /*MAIL_DATE*/ for (env = e->envp; *env; env++) (void)fprintf(mail, "X-Cron-Env: <%s>\n", *env); (void)fprintf(mail, "\n"); /* this was the first char from the pipe */ (void)putc(ch, mail); } /* we have to read the input pipe no matter whether * we mail or not, but obviously we only write to * mail pipe if we ARE mailing. */ while (EOF != (ch = getc(in))) { bytes++; if (mailto) (void)putc(ch, mail); } /* only close pipe if we opened it -- i.e., we're * mailing... */ if (mailto) { Debug(DPROC, ("[%ld] closing pipe to mail\n", (long)getpid())); /* Note: the pclose will probably see * the termination of the grandchild * in addition to the mail process, since * it (the grandchild) is likely to exit * after closing its stdout. */ status = cron_pclose(mail); } /* if there was output and we could not mail it, * log the facts so the poor user can figure out * what's going on. */ if (mailto && status) { char buf[MAX_TEMPSTR]; (void)snprintf(buf, sizeof(buf), "mailed %d byte%s of output but got status 0x%04x\n", bytes, (bytes==1)?"":"s", status); log_it(usernm, getpid(), "MAIL", buf); } } /*if data from grandchild*/ Debug(DPROC, ("[%ld] got EOF from grandchild\n", (long)getpid())); (void)fclose(in); /* also closes stdout_pipe[READ_PIPE] */ } /* wait for children to die. */ for (; children > 0; children--) { WAIT_T waiter; PID_T pid; Debug(DPROC, ("[%ld] waiting for grandchild #%d to finish\n", (long)getpid(), children)); while ((pid = wait(&waiter)) < OK && errno == EINTR) ; if (pid < OK) { Debug(DPROC, ("[%ld] no more grandchildren--mail written?\n", (long)getpid())); break; } Debug(DPROC, ("[%ld] grandchild #%ld finished, status=%04x", (long)getpid(), (long)pid, WEXITSTATUS(waiter))); if (WIFSIGNALED(waiter) && WCOREDUMP(waiter)) Debug(DPROC, (", dumped core")); Debug(DPROC, ("\n")); } /* Log the time when we finished deadling with the job */ /*local*/{ char *x = mkprints(e->cmd, strlen(e->cmd)); log_it(usernm, getpid(), "CMD FINISH", x); free(x); } }
int log_reopen(void) { log_close(); return log_open(log_method, log_ident, log_file, log_facility); }
static int do_rmmod(int argc, char *argv[]) { struct kmod_ctx *ctx; const char *null_config = NULL; int flags = 0; int i, err, r = 0; for (;;) { int c, idx = 0; c = getopt_long(argc, argv, cmdopts_s, cmdopts, &idx); if (c == -1) break; switch (c) { case 'f': flags |= KMOD_REMOVE_FORCE; break; case 's': use_syslog = 1; break; case 'v': verbose++; break; case 'h': help(); return EXIT_SUCCESS; case 'V': puts(PACKAGE " version " VERSION); return EXIT_SUCCESS; case '?': return EXIT_FAILURE; default: ERR("unexpected getopt_long() value '%c'.\n", c); return EXIT_FAILURE; } } log_open(use_syslog); if (optind >= argc) { ERR("missing module name.\n"); r = EXIT_FAILURE; goto done; } ctx = kmod_new(NULL, &null_config); if (!ctx) { ERR("kmod_new() failed!\n"); r = EXIT_FAILURE; goto done; } log_setup_kmod_log(ctx, verbose); for (i = optind; i < argc; i++) { struct kmod_module *mod; const char *arg = argv[i]; struct stat st; if (stat(arg, &st) == 0) err = kmod_module_new_from_path(ctx, arg, &mod); else err = kmod_module_new_from_name(ctx, arg, &mod); if (err < 0) { ERR("could not use module %s: %s\n", arg, strerror(-err)); break; } if (!(flags & KMOD_REMOVE_FORCE) && check_module_inuse(mod) < 0) { r++; goto next; } err = kmod_module_remove_module(mod, flags); if (err < 0) { ERR("could not remove module %s: %s\n", arg, strerror(-err)); r++; } next: kmod_module_unref(mod); } kmod_unref(ctx); done: log_close(); return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE; }
int main(int argc, char *argv[]) { server_t server; char const *control = SDP_LOCAL_PATH; char const *user = "******", *group = "_sdpd"; char const *sgroup = NULL; int opt; bool detach = true; struct sigaction sa; while ((opt = getopt(argc, argv, "c:dG:g:hu:")) != -1) { switch (opt) { case 'c': /* control */ control = optarg; break; case 'd': /* do not detach */ detach = false; break; case 'G': /* super group */ sgroup = optarg; break; case 'g': /* group */ group = optarg; break; case 'u': /* user */ user = optarg; break; case 'h': default: usage(); /* NOT REACHED */ } } log_open(SDPD, !detach); /* Become daemon if required */ if (detach && daemon(0, 0) < 0) { log_crit("Could not become daemon. %s (%d)", strerror(errno), errno); exit(EXIT_FAILURE); } /* Set signal handlers */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = sighandler; if (sigaction(SIGTERM, &sa, NULL) < 0 || sigaction(SIGHUP, &sa, NULL) < 0 || sigaction(SIGINT, &sa, NULL) < 0) { log_crit("Could not install signal handlers. %s (%d)", strerror(errno), errno); exit(EXIT_FAILURE); } sa.sa_handler = SIG_IGN; if (sigaction(SIGPIPE, &sa, NULL) < 0) { log_crit("Could not install signal handlers. %s (%d)", strerror(errno), errno); exit(EXIT_FAILURE); } /* Initialize server */ if (!server_init(&server, control, sgroup)) exit(EXIT_FAILURE); if ((user != NULL || group != NULL) && !drop_root(user, group)) exit(EXIT_FAILURE); for (done = 0; !done; ) { if (!server_do(&server)) done++; } server_shutdown(&server); log_close(); exit(EXIT_SUCCESS); }