/* ====================================================================== Function: clean_exit Purpose : exit program Input : exit code Output : - Comments: ====================================================================== */ void clean_exit (int exit_code) { int r; // close serials if (g_fd_teleinfo) { // Restore Old parameters. if ( (r = tcsetattr(g_fd_teleinfo, TCSAFLUSH, &g_oldtermios)) < 0 ) log_syslog(stderr, "cannot restore old parameters %s: %s", opts.port, strerror(errno)); // then close tlf_close_serial(g_fd_teleinfo); } // close socket if (g_tlf_sock) close(g_tlf_sock); // Release OLED and Raspberry I/O control display.close(); if ( exit_code == EXIT_SUCCESS) { log_syslog(stdout, "Succeded to do my job\n"); } else { log_syslog(stdout, "Closing teleinfo due to error\n"); } exit(exit_code); }
/* ====================================================================== Function: isr_handler Purpose : Interrupt routine Code for signal Input : - Output : - Comments: ====================================================================== */ void isr_handler (int signum) { // Does we received CTRL-C ? if ( signum==SIGINT || signum==SIGTERM) { // Indicate we want to quit g_exit_pgm = true; log_syslog(NULL, "Received SIGINT/SIGTERM"); } // Our receive buffer is full else if (signum == SIGIO) { log_syslog(NULL, "Received SIGIO"); } }
static void flush_logqueue (void) { int empty; do { pthread_mutex_lock(&logq_lock); empty = log_dequeue(la->buff); pthread_mutex_unlock(&logq_lock); if (!empty) log_syslog(la->buff); } while (empty == 0); }
static void do_log( int priority, const char *format, va_list ap ) { assert( started() ); if ( output & LOGGING_TYPE_FILE ) { log_file( priority, format, ap ); } if ( output & LOGGING_TYPE_SYSLOG ) { log_syslog( priority, format, ap ); } if ( output & LOGGING_TYPE_STDOUT ) { log_stdout( format, ap ); } }
/* ====================================================================== Function: tlf_init_serial Purpose : initialize serial port for receiving teleinfo Input : - Output : Serial Port Handle Comments: - ====================================================================== */ int tlf_init_serial(void) { int tty_fd, r ; struct termios termios ; // Ouverture de la liaison serie (Nouvelle version de config.) if ( (tty_fd = open(opts.port, O_RDONLY | O_NOCTTY)) == -1 ) fatal( "tlf_init_serial %s: %s", opts.port, strerror(errno)); else log_syslog( stdout, "'%s' opened.\n",opts.port); // Get current parameters. if ( (r = tcgetattr(tty_fd, &g_oldtermios)) < 0 ) log_syslog(stderr, "cannot get current parameters %s: %s", opts.port, strerror(errno)); // clear struct bzero(&termios, sizeof(termios)); // Even Parity with 7 bits data termios.c_cflag = (B1200 | PARENB | CS7 | CLOCAL | CREAD) ; //termios.c_iflag = IGNPAR ; termios.c_iflag = (IGNPAR | INPCK | ISTRIP) ; ; termios.c_oflag = 0; // Pas de mode de sortie particulier (mode raw). termios.c_lflag = 0; // non canonique termios.c_cc[VTIME] = 0; /* inter-character timer unused */ termios.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */ tcflush(tty_fd, TCIFLUSH); if ( ( r = tcsetattr(tty_fd,TCSANOW,&termios) < 0 ) ) log_syslog(stderr, "cannot get current parameters %s: %s", opts.port, strerror(errno)); // Sleep 500ms usleep(500000); return tty_fd ; }
/* ====================================================================== Function: tlf_get_frame Purpose : check for teleinfo frame broadcasted on the network Input : true if we need to wait for frame, false if async (take if any) Output : true if frame ok, else false Comments: ====================================================================== */ int tlf_get_frame(char block) { struct sockaddr_in tlf_from; int fromlen = sizeof(tlf_from); int n = 0; int timeout = 100; // (10 * 100ms) int ret =false; char rcv_buff[TELEINFO_BUFSIZE]; // clear ou receive buffer memset(rcv_buff,0, TELEINFO_BUFSIZE ); // do until received or timed out while (n<=0 && timeout--) { // read data received on socket ? n = recvfrom(g_tlf_sock,rcv_buff,TELEINFO_BUFSIZE,0, (struct sockaddr *)&tlf_from,(socklen_t *)&fromlen); // Do we received frame on socket ? if (n > 0) { //log_syslog( stderr, "recvfrom %d buffer='%s'\n",n, rcv_buff); // check the frame and do stuff ret = tlf_check_frame( rcv_buff ); } else { // want to wait frame ? if ( block) { // Letting time to the Operating system doing other jobs // Wait 100ms it won't bother us usleep(100000); } else { break; } } } // check for timed out if (block && timeout<=0) log_syslog( stderr, "tlf_get_frame() Time-Out Expired\n"); return (ret); }
static void log_flush(void) { while (!la->empty) { la->ops[0].sem_op = -1; if (semop(la->semid, la->ops, 1) < 0) { syslog(LOG_ERR, "semop up failed"); exit(1); } log_dequeue(la->buff); la->ops[0].sem_op = 1; if (semop(la->semid, la->ops, 1) < 0) { syslog(LOG_ERR, "semop down failed"); exit(1); } log_syslog(la->buff); } }
static void log_flush(void) { int msglen; while (!la->empty) { la->ops[0].sem_op = -1; if (semop(la->semid, la->ops, 1) < 0) { syslog(LOG_ERR, "semop up failed %d", errno); exit(1); } msglen = log_dequeue(la->buff); la->ops[0].sem_op = 1; if (semop(la->semid, la->ops, 1) < 0) { syslog(LOG_ERR, "semop down failed"); exit(1); } if (msglen) log_syslog(la->buff); } }
int fswc_openlog(fswebcam_config_t *config) { char *s; int r; /* Get the first part of the filename. */ s = argdup(config->logfile, ":", 0, 0); if(!s) { ERROR("Out of memory."); return(-1); } if(!strcasecmp(s, "file")) { free(s); s = argdup(config->logfile, ":", 1, 0); if(!s) { ERROR("No log file was specified."); return(-1); } } else if(!strcasecmp(s, "syslog")) { free(s); log_syslog(1); return(0); } r = log_open(s); free(s); return(r); }
static void authenticate (const struct passwd* pw) { const struct passwd* lpw = NULL; const char* cp, *srvname = NULL; int retval; switch (su_mode) { case SU_MODE: srvname = simulate_login ? PAM_SRVNAME_SU_L : PAM_SRVNAME_SU; break; case RUNUSER_MODE: srvname = simulate_login ? PAM_SRVNAME_RUNUSER_L : PAM_SRVNAME_RUNUSER; break; default: abort(); break; } retval = pam_start (srvname, pw->pw_name, &conv, &pamh); if (is_pam_failure(retval)) { goto done; } if (isatty (0) && (cp = ttyname (0)) != NULL) { const char* tty; if (strncmp (cp, "/dev/", 5) == 0) { tty = cp + 5; } else { tty = cp; } retval = pam_set_item (pamh, PAM_TTY, tty); if (is_pam_failure(retval)) { goto done; } } lpw = current_getpwuid (); if (lpw && lpw->pw_name) { retval = pam_set_item (pamh, PAM_RUSER, (const void*) lpw->pw_name); if (is_pam_failure(retval)) { goto done; } } if (su_mode == RUNUSER_MODE) { /* * This is the only difference between runuser(1) and su(1). The command * runuser(1) does not required authentication, because user is root. */ if (restricted) { errx(EXIT_FAILURE, _("may not be used by non-root users")); } return; } retval = pam_authenticate (pamh, 0); if (is_pam_failure(retval)) { goto done; } retval = pam_acct_mgmt (pamh, 0); if (retval == PAM_NEW_AUTHTOK_REQD) { /* Password has expired. Offer option to change it. */ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK); } done: log_syslog(pw, !is_pam_failure(retval)); if (is_pam_failure(retval)) { const char* msg; log_btmp(pw); msg = pam_strerror(pamh, retval); pam_end(pamh, retval); sleep (getlogindefs_num ("FAIL_DELAY", 1)); errx (EXIT_FAILURE, "%s", msg ? msg : _("incorrect password")); } }
/* ====================================================================== Function: main Purpose : Main entry Point Input : - Output : - Comments: ====================================================================== */ int main(int argc, char **argv) { struct sockaddr_in server; struct sigaction exit_action; int length, flags; int n; unsigned char c; char rcv_buff[TELEINFO_BUFSIZE]; int rcv_idx; char time_str[200]; time_t t; struct tm *tmp; int frame_ok ; rcv_idx = 0; g_fd_teleinfo = 0; g_exit_pgm = false; bzero(rcv_buff, TELEINFO_BUFSIZE); parse_args(argc, argv); // Set up the structure to specify the exit action. exit_action.sa_handler = isr_handler; sigemptyset (&exit_action.sa_mask); exit_action.sa_flags = 0; sigaction (SIGTERM, &exit_action, NULL); sigaction (SIGINT, &exit_action, NULL); // Grab teleinfo frame from network if (opts.mode == MODE_NET ) { // Init Sockets g_tlf_sock=socket(AF_INET, SOCK_DGRAM, 0); if (g_tlf_sock < 0) fatal( "Error Opening Socket %d: %s\n",g_tlf_sock, strerror (errno)); else { if (opts.verbose) log_syslog(stderr, "Opened Socket\n"); } flags = fcntl(g_tlf_sock,F_GETFL,0); fcntl(g_tlf_sock, F_SETFL, flags | O_NONBLOCK); length = sizeof(server); bzero(&server,length); server.sin_family=AF_INET; server.sin_addr.s_addr=INADDR_ANY; server.sin_port=htons(opts.netport); if ( bind(g_tlf_sock,(struct sockaddr *)&server,length) < 0 ) fatal("Error Binding Socket %d : %s\n", g_tlf_sock, strerror (errno)); else { if (opts.verbose) log_syslog(stderr, "Binded on port %d\n",opts.netport); } if (opts.verbose) log_syslog(stdout, "Network Init succeded\n"); } // Grab teleinfo frame from serial device if (opts.mode == MODE_SERIAL) { if ( (g_fd_teleinfo = tlf_init_serial()) >0 ) { if (opts.verbose) log_syslog(stdout, "Serial device %s Init succeded\n", opts.port); } } // SPI if (display.oled_is_spi_proto(opts.oled)) { // SPI change parameters to fit to your LCD if ( !display.init(OLED_SPI_DC,OLED_SPI_RESET,OLED_SPI_CS, opts.oled) ) exit(EXIT_FAILURE); } else { // I2C change parameters to fit to your LCD if ( !display.init(OLED_I2C_RESET,opts.oled) ) exit(EXIT_FAILURE); } display.begin(); display.clearDisplay(); // show display.display(); log_syslog(stdout, "Inits succeded, entering Main loop\n"); if (opts.daemon) { log_syslog(stdout, "Starting as a daemon\n"); daemonize(); } // Do while not end while ( ! g_exit_pgm ) { // by default no frame frame_ok = false; // Grab from network if (opts.mode == MODE_NET ) { // Get frame from network frame_ok = tlf_get_frame(true); } else { // loop from serial port until frame ok while ( ! frame_ok) { // Read from serial port n = read(g_fd_teleinfo, &c, 1); if (n == 0) fatal("nothing to read"); else if (errno == EINTR ) break; else if ( n < 0 ) fatal("read failed: %s", strerror(errno)); //log_syslog(stdout, "%c", c); //printf("%c",c); // What we received ? switch (c) { // start of frame ??? case STX: // Clear buffer, begin to store in it rcv_idx = 0; bzero(rcv_buff, TELEINFO_BUFSIZE); rcv_buff[rcv_idx++]=c; break; // End of frame ? case ETX: // We had STX ? if ( rcv_idx ) { // Store in buffer and proceed rcv_buff[rcv_idx++]=c; // clear the end of buffer (paranoia inside) bzero(&rcv_buff[rcv_idx], TELEINFO_BUFSIZE-rcv_idx); // Is this frame valid ? if ( (length = tlf_check_frame(rcv_buff)) > 0 ) { frame_ok = true; } } // May be begin of the program or other problem. else { rcv_idx = 0; bzero(rcv_buff, TELEINFO_BUFSIZE); } break; // other char ? default: { // If we are in a frame, store data recceived if (rcv_idx) { // If buffer is not full if ( rcv_idx < TELEINFO_BUFSIZE) { // Store data recceived rcv_buff[rcv_idx++]=c; } else { // clear buffer & restart rcv_idx=0; bzero(rcv_buff, TELEINFO_BUFSIZE); } } } break; } } } // while not frame ok from serial // here we received a frame, even serial or from network // If frame ok if ( frame_ok ) { //char oled_buff[1024]; int percent=0; t = time(NULL); tmp = localtime(&t); if (tmp) { if (strftime(time_str, sizeof(time_str), "%d %b %Y %T" , tmp) == 0) strcpy( time_str, "No Time"); } // good full frame received, do whatever you want here //fprintf(stdout, "==========================\nTeleinfo Frame of %d char\n%s\n==========================%s\n", // strlen(rcv_buff), time_str, rcv_buff ); //sprintf( oled_buff, "Creuses %09lu\nPleines %09lu\n%d W %d \n%s\n", // g_values.hchp, g_values.hchc, g_values.papp, (100*g_values.iinst)/g_values.isousc, time_str); //fprintf(stdout, oled_buff); display.clearDisplay(); // clears the screen and buffer display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0,0); // Percent of total power percent = (100.0 * g_values.iinst) / g_values.isousc ; if (display.height() == 32 ) { if (g_values.ptec == PTEC_HP ) display.setTextColor(BLACK, WHITE); // 'inverted' text display.print("Pleines "); display.printf("%09ld\n", g_values.hchp); display.setTextColor(WHITE); // normaltext if (g_values.ptec == PTEC_HC ) display.setTextColor(BLACK, WHITE); // 'inverted' text display.print("Creuses "); display.printf("%09ld\n", g_values.hchc); display.setTextColor(WHITE); // normaltext // Calculate Bargraph display //display.setTextColor(BLACK, WHITE); // 'inverted' text //skip seconds time_str[17] = 0x00; display.printf("%d W %d%% %3d A\n%s", g_values.papp, percent, g_values.iinst, time_str); display.drawVerticalBargraph(114,0,12,32,1, percent); display.display(); display.setTextColor(BLACK, WHITE); // 'inverted' text } else { if (g_values.ptec == PTEC_HP ) display.setTextColor(BLACK, WHITE); // 'inverted' text display.setTextSize(2); display.printf("%09ld\n", g_values.hchp); display.setTextColor(WHITE); // normaltext if (g_values.ptec == PTEC_HC ) display.setTextColor(BLACK, WHITE); // 'inverted' text display.printf("%09ld\n", g_values.hchc); display.setTextColor(WHITE); // normaltext //display.setTextColor(BLACK, WHITE); // 'inverted' text display.setTextSize(1); display.printf("%d W %d%% %3d A\n", g_values.papp, percent, g_values.iinst); display.printf("%s", time_str); // Calculate Bargraph display // Percent of total power display.drawHorizontalBargraph(0, 49,128,14,1, percent); display.display(); display.setTextColor(BLACK, WHITE); // 'inverted' text } } // We want to display results ? if (opts.verbose) { if ( (n = write(STDOUT_FILENO, &c, 1)) <= 0 ) fatal("write to stdout failed: %s", strerror(errno)); } } log_syslog(stderr, "Program terminated\n"); clean_exit(EXIT_SUCCESS); // avoid compiler warning return (0); }
/* ====================================================================== Function: tlf_check_frame Purpose : check for teleinfo frame Input : - Output : the length of valid buffer, 0 otherwhile Comments: ====================================================================== */ int tlf_check_frame( char * pframe) { char * pstart; char * pend; char * pnext; char * ptok; char * pvalue; char * pcheck; char buff[TELEINFO_BUFSIZE]; int frame_err , len; len = strlen(pframe); strncpy( buff, pframe, len+1); pstart = &buff[0]; pend = pstart + len; if (opts.verbose) { fprintf(stdout, "------------------- Received %d char %s Frame.%s\n-------------------", len, opts.mode_str, buff); fflush(stdout); } // just one vefification, buffer should be at least 100 Char if ( pstart && pend && (pend > pstart+100 ) ) { //fprintf(stdout, "Frame to analyse [%d]%s\n", pend-pstart, pstart); //fflush(stdout); // by default no error frame_err = false; //log_syslog(stderr, "Found %d Bytes Frame\n", pend-pstart); // ignore STX pstart++; // Init our pointers ptok = pvalue = pnext = pcheck = NULL; // Loop in buffer while ( pstart < pend ) { // start of token if ( *pstart=='\n' ) { // Position on token ptok = ++pstart; } // start of token value if ( *pstart==' ' && ptok) { // Isolate token name *pstart++ = '\0'; // no value yet, setit ? if (!pvalue) pvalue = pstart; // we had value, so it's checksum else pcheck = pstart; } // new line ? ok we got all we need ? if ( *pstart=='\r' ) { *pstart='\0'; // Good format ? if ( ptok && pvalue && pcheck ) { // Checksum OK if ( tlf_checksum_ok(ptok, pvalue, *pcheck)) { //fprintf(stdout, "%s=%s\n",ptok, pvalue); // In case we need to do things tlf_treat_label(ptok, pvalue); } else { frame_err = true; //fprintf(stdout, "%s=%s BAD",ptok, pvalue); log_syslog(stderr, "tlf_checksum_ok('%s','%s','%c') error\n",ptok, pvalue, *pcheck); } } else { frame_err = true; log_syslog(stderr, "tlf_check_frame() no correct frame '%s'\n",ptok); } // reset data ptok = pvalue = pnext = pcheck = NULL; } // next pstart++; } // no error in this frame ? if (!frame_err) { if (opts.verbose) fprintf(stdout, "Frame OK (%d)\n", len); //debug_dump_sensors(0); return (len); } } else { log_syslog(stderr, "tlf_check_frame() No correct frame found\n"); } return (0); }
int main(int argc, char **argv) { int c; int cnt; char *childArgv[10]; char *buff; int childArgc = 0; int retcode; char *pwdbuf = NULL; struct passwd *pwd = NULL, _pwd; struct login_context cxt = { .tty_mode = TTY_MODE, /* tty chmod() */ .pid = getpid(), /* PID */ .conv = { misc_conv, NULL } /* PAM conversation function */ }; timeout = getlogindefs_num("LOGIN_TIMEOUT", LOGIN_TIMEOUT); signal(SIGALRM, timedout); siginterrupt(SIGALRM, 1); /* we have to interrupt syscalls like ioclt() */ alarm((unsigned int)timeout); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); setpriority(PRIO_PROCESS, 0, 0); initproctitle(argc, argv); /* * -p is used by getty to tell login not to destroy the environment * -f is used to skip a second login authentication * -h is used by other servers to pass the name of the remote * host to login so that it may be placed in utmp and wtmp */ while ((c = getopt(argc, argv, "fHh:pV")) != -1) switch (c) { case 'f': cxt.noauth = 1; break; case 'H': cxt.nohost = 1; break; case 'h': if (getuid()) { fprintf(stderr, _("login: -h for super-user only.\n")); exit(EXIT_FAILURE); } init_remote_info(&cxt, optarg); break; case 'p': cxt.keep_env = 1; break; case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; case '?': default: fprintf(stderr, _("usage: login [ -p ] [ -h host ] [ -H ] [ -f username | username ]\n")); exit(EXIT_FAILURE); } argc -= optind; argv += optind; if (*argv) { char *p = *argv; cxt.username = xstrdup(p); /* wipe name - some people mistype their password here */ /* (of course we are too late, but perhaps this helps a little ..) */ while (*p) *p++ = ' '; } for (cnt = get_fd_tabsize() - 1; cnt > 2; cnt--) close(cnt); setpgrp(); /* set pgid to pid this means that setsid() will fail */ openlog("login", LOG_ODELAY, LOG_AUTHPRIV); init_tty(&cxt); init_loginpam(&cxt); /* login -f, then the user has already been authenticated */ cxt.noauth = cxt.noauth && getuid() == 0 ? 1 : 0; if (!cxt.noauth) loginpam_auth(&cxt); /* * Authentication may be skipped (for example, during krlogin, rlogin, * etc...), but it doesn't mean that we can skip other account checks. * The account could be disabled or password expired (althought * kerberos ticket is valid). -- [email protected] (22-Feb-2006) */ loginpam_acct(&cxt); if (!(cxt.pwd = get_passwd_entry(cxt.username, &pwdbuf, &_pwd))) { warnx(_("\nSession setup problem, abort.")); syslog(LOG_ERR, _("Invalid user name \"%s\" in %s:%d. Abort."), cxt.username, __FUNCTION__, __LINE__); pam_end(cxt.pamh, PAM_SYSTEM_ERR); sleepexit(EXIT_FAILURE); } pwd = cxt.pwd; cxt.username = pwd->pw_name; /* * Initialize the supplementary group list. This should be done before * pam_setcred because the PAM modules might add groups during * pam_setcred. * * For root we don't call initgroups, instead we call setgroups with * group 0. This avoids the need to step through the whole group file, * which can cause problems if NIS, NIS+, LDAP or something similar * is used and the machine has network problems. */ retcode = pwd->pw_uid ? initgroups(cxt.username, pwd->pw_gid) : /* user */ setgroups(0, NULL); /* root */ if (retcode < 0) { syslog(LOG_ERR, _("groups initialization failed: %m")); warnx(_("\nSession setup problem, abort.")); pam_end(cxt.pamh, PAM_SYSTEM_ERR); sleepexit(EXIT_FAILURE); } /* * Open PAM session (after successful authentication and account check) */ loginpam_session(&cxt); /* committed to login -- turn off timeout */ alarm((unsigned int)0); endpwent(); cxt.quiet = get_hushlogin_status(pwd); log_utmp(&cxt); log_audit(&cxt, 1); log_lastlog(&cxt); chown_tty(&cxt); if (setgid(pwd->pw_gid) < 0 && pwd->pw_gid) { syslog(LOG_ALERT, _("setgid() failed")); exit(EXIT_FAILURE); } if (pwd->pw_shell == NULL || *pwd->pw_shell == '\0') pwd->pw_shell = _PATH_BSHELL; init_environ(&cxt); /* init $HOME, $TERM ... */ setproctitle("login", cxt.username); log_syslog(&cxt); if (!cxt.quiet) { motd(); #ifdef LOGIN_STAT_MAIL /* * This turns out to be a bad idea: when the mail spool * is NFS mounted, and the NFS connection hangs, the * login hangs, even root cannot login. * Checking for mail should be done from the shell. */ { struct stat st; char *mail; mail = getenv("MAIL"); if (mail && stat(mail, &st) == 0 && st.st_size != 0) { if (st.st_mtime > st.st_atime) printf(_("You have new mail.\n")); else printf(_("You have mail.\n")); } } #endif } /* * Detach the controlling terminal, fork() and create, new session * and reinilizalize syslog stuff. */ fork_session(&cxt); /* discard permissions last so can't get killed and drop core */ if (setuid(pwd->pw_uid) < 0 && pwd->pw_uid) { syslog(LOG_ALERT, _("setuid() failed")); exit(EXIT_FAILURE); } /* wait until here to change directory! */ if (chdir(pwd->pw_dir) < 0) { warn(_("%s: change directory failed"), pwd->pw_dir); if (!getlogindefs_bool("DEFAULT_HOME", 1)) exit(0); if (chdir("/")) exit(EXIT_FAILURE); pwd->pw_dir = "/"; printf(_("Logging in with home = \"/\".\n")); } /* if the shell field has a space: treat it like a shell script */ if (strchr(pwd->pw_shell, ' ')) { buff = xmalloc(strlen(pwd->pw_shell) + 6); strcpy(buff, "exec "); strcat(buff, pwd->pw_shell); childArgv[childArgc++] = "/bin/sh"; childArgv[childArgc++] = "-sh"; childArgv[childArgc++] = "-c"; childArgv[childArgc++] = buff; } else { char tbuf[PATH_MAX + 2], *p; tbuf[0] = '-'; xstrncpy(tbuf + 1, ((p = strrchr(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell), sizeof(tbuf) - 1); childArgv[childArgc++] = pwd->pw_shell; childArgv[childArgc++] = xstrdup(tbuf); } childArgv[childArgc++] = NULL; execvp(childArgv[0], childArgv + 1); if (!strcmp(childArgv[0], "/bin/sh")) warn(_("couldn't exec shell script")); else warn(_("no shell")); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { int conf_err = 0; int option; int dflag = 0; conf_ruleset_s rset; // Set the default logger to syslog log_syslog(&logger); // Initialize the config and its rulesets conf_init(&conf); conf_rset_init(&rset); // Set the real path conf_set_realpath(&conf, argv[0]); conf_rset_add(&rset, conf_rule_create("root = %s", &conf.document_root)); conf_rset_add(&rset, conf_rule_create("handler = %s", &conf.method)); conf_rset_add(&rset, conf_rule_create("port = %hu", &conf.port)); conf_rset_add(&rset, conf_rule_create("backlog = %d", &conf.backlog)); conf_rset_add(&rset, conf_rule_create("mime = %s", &conf.mime)); conf_rset_add(&rset, conf_rule_create("logfile = %s", &conf.logfile)); if (conf_read(conf.real_path, ".lab3-config", rset) == -1) exit_fatal("The configuration file could not be read"); while((option = getopt(argc, argv, "hp:dl:s:")) != -1) { switch(option) { case 'p': conf_set_port(&conf, optarg); break; case 'd': dflag = 1; break; case 'l': conf_set_logfile(&conf, optarg); if (strncmp(optarg, "stdout", 6) == 0) log_stdout(&logger); else log_file(&logger); break; case 's': conf_set_method(&conf, optarg); break; case 'h': default: usage(argv[0]); exit(EXIT_SUCCESS); } } // Register signal handler for SIGINT signal(SIGINT, sigint_handler); if ((conf_err = conf_validate(conf)) < 0) conf_print_err(conf_err); // Daemonize the process if the dflag is set if (dflag) { log_syslog(&logger); daemonize(); } else { jail_proc(dflag); } server_create(); return 0; }
/* main -- dnsproxy main function */ int main(int argc, char *argv[]) { int ch; struct passwd *pw = NULL; struct sockaddr_in addr; struct event evq, eva; const char *config = "/etc/dnsproxy.conf"; int daemonize = 0; /* Process commandline arguments */ while ((ch = getopt(argc, argv, "c:dhV")) != -1) { switch (ch) { case 'c': config = optarg; break; case 'd': daemonize = 1; break; case 'V': fprintf(stderr, PACKAGE_STRING "\n"); exit(0); /* FALLTHROUGH */ case 'h': default: fprintf(stderr, "usage: dnsproxy [-c file] [-dhV]\n" \ "\t-c file Read configuration from file\n" \ "\t-d Detach and run as a daemon\n" \ "\t-h This help text\n" \ "\t-V Show version information\n"); exit(1); } } /* Parse configuration and check required parameters */ if (!parse(config)) fatal("unable to parse configuration"); if (!authoritative || !recursive) fatal("No authoritative or recursive server defined"); if (!listenat) listenat = strdup("0.0.0.0"); /* Create and bind query socket */ if ((sock_query = socket(AF_INET, SOCK_DGRAM, 0)) == -1) fatal("unable to create socket: %s", strerror(errno)); memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_addr.s_addr = inet_addr(listenat); addr.sin_port = htons(port); addr.sin_family = AF_INET; if (bind(sock_query, (struct sockaddr *)&addr, sizeof(addr)) != 0) fatal("unable to bind socket: %s", strerror(errno)); /* Create and bind answer socket */ if ((sock_answer = socket(AF_INET, SOCK_DGRAM, 0)) == -1) fatal("unable to create socket: %s", strerror(errno)); memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; if (bind(sock_answer, (struct sockaddr *)&addr, sizeof(addr)) != 0) fatal("unable to bind socket: %s", strerror(errno)); /* Fill sockaddr_in structs for both servers */ memset(&authoritative_addr, 0, sizeof(struct sockaddr_in)); authoritative_addr.sin_addr.s_addr = inet_addr(authoritative); authoritative_addr.sin_port = htons(authoritative_port); authoritative_addr.sin_family = AF_INET; memset(&recursive_addr, 0, sizeof(struct sockaddr_in)); recursive_addr.sin_addr.s_addr = inet_addr(recursive); recursive_addr.sin_port = htons(recursive_port); recursive_addr.sin_family = AF_INET; /* Daemonize if requested and switch to syslog */ if (daemonize) { if (daemon(0, 0) == -1) fatal("unable to daemonize"); log_syslog("dnsproxy"); } /* Find less privileged user */ if (user) { pw = getpwnam(user); if (!pw) fatal("unable to find user %s", user); } /* Do a chroot if requested */ if (chrootdir) { if (chdir(chrootdir) || chroot(chrootdir)) fatal("unable to chroot to %s", chrootdir); chdir("/"); } /* Drop privileges */ if (user) { if (setgroups(1, &pw->pw_gid) < 0) fatal("setgroups: %s", strerror(errno)); #if defined(HAVE_SETRESGID) if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) fatal("setresgid: %s", strerror(errno)); #elif defined(HAVE_SETREGID) if (setregid(pw->pw_gid, pw->pw_gid) < 0) fatal("setregid: %s", strerror(errno)); #else if (setegid(pw->pw_gid) < 0) fatal("setegid: %s", strerror(errno)); if (setgid(pw->pw_gid) < 0) fatal("setgid: %s", strerror(errno)); #endif #if defined(HAVE_SETRESUID) if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) fatal("setresuid: %s", strerror(errno)); #elif defined(HAVE_SETREUID) if (setreuid(pw->pw_uid, pw->pw_uid) < 0) fatal("setreuid: %s", strerror(errno)); #else if (seteuid(pw->pw_uid) < 0) fatal("seteuid: %s", strerror(errno)); if (setuid(pw->pw_uid) < 0) fatal("setuid: %s", strerror(errno)); #endif } /* Init event handling */ event_init(); event_set(&evq, sock_query, EV_READ, do_query, &evq); event_add(&evq, NULL); event_set(&eva, sock_answer, EV_READ, do_answer, &eva); event_add(&eva, NULL); /* Zero counters and start statistics timer */ statistics_start(); /* Take care of signals */ if (signal(SIGINT, signal_handler) == SIG_ERR) fatal("unable to mask signal SIGINT: %s", strerror(errno)); if (signal(SIGTERM, signal_handler) == SIG_ERR) fatal("unable to mask signal SIGTERM: %s", strerror(errno)); if (signal(SIGHUP, SIG_IGN) == SIG_ERR) fatal("unable to mask signal SIGHUP: %s", strerror(errno)); event_sigcb = signal_event; /* Start libevent main loop */ event_dispatch(); return 0; }