Ejemplo n.º 1
0
int main(int argc, char *argv[]) {
    atexit(cleanup);
    sigset_t mask;
    sigfillset(&mask);
    sigdelset(&mask, SIGUSR1);
    sigprocmask(SIG_SETMASK, &mask, NULL);
    struct sigaction act;
    memset(&act, 0, sizeof act);
    act.sa_handler = sigint_handler;
    sigaction(SIGUSR1, &act, NULL);

    srand(time(NULL));

    shm_id = shmget(SHM_KEY, MEM_SIZE, S_IRUSR);
    sem_id = semget(SEM_KEY, 0, S_IWUSR | S_IRUSR);
    if (shm_id < 0 || sem_id < 0) {
        printf("Error while opening shared memory and/or semaphores occurred.\n");
        return 1;
    }

    shm = shmat(shm_id, NULL, 0);
    if (shm == (void *)-1) {
        printf("Error while accessing shared memory occurred.\n");
        return 1;
    }
    struct sembuf sem_op;
    sem_op.sem_flg = 0;
    int task_index;
    int tasks_num;
    struct timeval tval;
    while (1) {
        sem_op.sem_num = 0;
        sem_op.sem_op = -1;
        if (semop(sem_id, &sem_op, 1) == -1)
            on_host_closed();

        sem_op.sem_num = 2;
        if (semop(sem_id, &sem_op, 1) == -1)
            on_host_closed();
        task_index = shm->start_index;
        shm->start_index = (task_index + 1) % ARRAY_LEN;

        tasks_num = shm->end_index - shm->start_index;
        if (tasks_num < 0)
            tasks_num += ARRAY_LEN;

        gettimeofday(&tval, NULL);
        printf("%d %ld.%ld Get task from position %d. Number of waiting tasks: %d.\n", getpid(), tval.tv_sec, tval.tv_usec/1000, task_index, tasks_num);
        fflush(stdout);
        sem_op.sem_num = 2;
        sem_op.sem_op = 1;
        if (semop(sem_id, &sem_op, 1) == -1)
            on_host_closed();
        sem_op.sem_num = 1;
        sem_op.sem_op = 1;
        if (semop(sem_id, &sem_op, 1) == -1)
            on_host_closed();

        nanosleep(&delay, NULL);
    }
}
Ejemplo n.º 2
0
void 
mpls_send(struct attacks *attacks)
{
    sigset_t mask;
    struct mpls_data *mpls_data;
    libnet_ptag_t t;
    libnet_t *lhandler;
    int32_t sent;
    int32_t payload_size=0, packet_size=0;
    u_int8_t *payload=NULL;
    dlist_t *p;
    struct interface_data *iface_data;
    struct interface_data *iface_data2;
    
    pthread_mutex_lock(&attacks->attack_th.finished);

    pthread_detach(pthread_self());

    mpls_data = attacks->data;
    
    sigfillset(&mask);

    if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
    {
       thread_error("mpls_send pthread_sigmask()",errno);
       return;
    }
    
    if (mpls_data->ip_payload && mpls_data->ip_payload[0])
    {
       payload_size = strlen((const char *)mpls_data->ip_payload);
       payload = mpls_data->ip_payload;
    }
       
    
    for (p = attacks->used_ints->list; p; p = dlist_next(attacks->used_ints->list, p)) 
    {
        iface_data = (struct interface_data *) dlist_data(p);
        lhandler = iface_data->libnet_handler;

        switch(mpls_data->proto)
        {
        case IPPROTO_TCP:
            packet_size = LIBNET_TCP_H + payload_size;
            t = libnet_build_tcp(
                mpls_data->src_port,       /* source port */
                mpls_data->dst_port,       /* destination port */
                0x666,                     /* sequence number */
                0x00000000,                /* acknowledgement num */
                TH_SYN,                    /* control flags */
                32767,                     /* window size */
                0,                         /* checksum */
                0,                         /* urgent pointer */
                packet_size,  /* TCP packet size */
                payload,     /* payload */
                payload_size,              /* payload size */
                lhandler,                  /* libnet handle */
                0);                        /* libnet id */
        break;
        
        case IPPROTO_UDP:
            packet_size = LIBNET_UDP_H + payload_size;
            t = libnet_build_udp(
                mpls_data->src_port,       /* source port */
                mpls_data->dst_port,       /* destination port */
                packet_size,  /* UDP packet size */
                0,                         /* checksum */
                payload,     /* payload */
                payload_size,              /* payload size */
                lhandler,                  /* libnet handle */
                0);                        /* libnet id */
        break;
        
        case IPPROTO_ICMP:
            packet_size = LIBNET_ICMPV4_ECHO_H + payload_size;
            t = libnet_build_icmpv4_echo(
                ICMP_ECHO,                     /* type */
                0,                             /* code */
                0,                             /* checksum */
                0x42,                          /* id */
                0x42,                          /* sequence number */
                payload, /* payload */
                payload_size, /* payload size */
                lhandler,                      /* libnet handle */
                0);
        break;
        }
        
        if (t == -1)
        {
            thread_libnet_error("Can't build tcp/udp/icmp header",lhandler);
            libnet_clear_packet(lhandler);
            return;
        }

        t = libnet_build_ipv4(
            LIBNET_IPV4_H + packet_size,  /* length */
            0,                                         /* TOS */
            242,                                       /* IP ID */
            0,                                         /* IP Frag */
            128,                                       /* TTL */
            mpls_data->proto,                          /* protocol */
            0,                                         /* checksum */
            htonl(mpls_data->src_ip),                  /* source IP */
            htonl(mpls_data->dst_ip),                  /* destination IP */
            NULL,                                      /* payload */
            0,                                         /* payload size */
            lhandler,                                  /* libnet handle */
            0);                                        /* libnet id */
        if (t == -1)
        {
            thread_libnet_error("Can't build IP header",lhandler);
            libnet_clear_packet(lhandler);
            return;    
        }


        t = libnet_build_mpls(
            mpls_data->label1,      /* label */
            mpls_data->exp1,        /* experimental */
            LIBNET_MPLS_BOS_ON,     /* bottom of stack */
            mpls_data->ttl1,        /* ttl */
            NULL,                   /* payload */
            0,                      /* payload size */
            lhandler,               /* libnet handle */
            0);                     /* libnet id */
        if (t == -1)
        {
            thread_libnet_error("Can't build MPLS header",lhandler);
            libnet_clear_packet(lhandler);
            return;    
        }
        
        if (mpls_data->double_hdr)
        {
            t = libnet_build_mpls(
                mpls_data->label2,      /* label */
                mpls_data->exp2,        /* experimental */
                LIBNET_MPLS_BOS_OFF,    /* bottom of stack */
                mpls_data->ttl2,        /* ttl */
                NULL,                   /* payload */
                0,                      /* payload size */
                lhandler,               /* libnet handle */
                0);                     /* libnet id */
            if (t == -1)
            {
                thread_libnet_error("Can't build MPLS header",lhandler);
                libnet_clear_packet(lhandler);
                return;    
            }
        }

        t = libnet_build_ethernet(
            mpls_data->mac_dest,      /* ethernet destination */
            mpls_data->mac_source,    /* ethernet source */
            ETHERTYPE_MPLS,           /* protocol type */
            NULL,                     /* payload */
            0,                        /* payload size */
            lhandler,                 /* libnet handle */
            0);                       /* libnet id */
        if (t == -1)
        {
            thread_libnet_error("Can't build Ethernet header",lhandler);
            libnet_clear_packet(lhandler);
            return;    
        }
        
        /*
         *  Write it to the wire.
         */
           sent = libnet_write(lhandler);

           if (sent == -1) 
           {
               thread_libnet_error("libnet_write error", lhandler);
               libnet_clear_packet(lhandler);
               return;
           }

           libnet_clear_packet(lhandler);
           protocols[PROTO_MPLS].packets_out++;
           iface_data2 = interfaces_get_struct(iface_data->ifname);
           iface_data2->packets_out[PROTO_MPLS]++;
    }
}
Ejemplo n.º 3
0
/*
 * Uptime thread...
 */
void *
th_uptime(void *arg)
{
   int ret,n;
   struct timeval timeout;
   sigset_t mask;

write_log(0,"\n th_uptime thread = %d\n",(int)pthread_self());

   sigfillset(&mask);

   if (pthread_sigmask(SIG_BLOCK, &mask, NULL))
   {
      thread_error("th_uptime pthread_sigmask()",errno);
      th_uptime_exit();
   }

   if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL))
   {
      thread_error("th_uptime pthread_setcancelstate()",errno);
      th_uptime_exit();
   }

   pthread_cleanup_push( &th_uptime_clean, (void *)NULL );
   
   if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
   {
      thread_error("th_uptime pthread_setcancelstate()",errno);
      th_uptime_exit();
   }

   if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
   {
      n=errno;
      pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
      thread_error("th_uptime pthread_setcanceltype()",n);
      th_uptime_exit();
   }

   while(1)
   {
      timeout.tv_sec  = 1;
      timeout.tv_usec = 0;

      if ( (ret=select( 0, NULL, NULL, NULL, &timeout ) ) == -1 )
      {
         n=errno;
         thread_error("th_uptime select()",n);
         continue;
      }

      if ( !ret )  /* Timeout, update uptime... */
         uptime++; 
   }

   pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);         

   pthread_cleanup_pop(0);

   return (NULL);
}
Ejemplo n.º 4
0
/**
 * @brief Program entry point.
 * @param argc The argument count
 * @param argv The argument vector
 * @return EXIT_SUCCESS, EXIT_PARITY_ERROR, EXIT_MULTIPLE_ERRORS
**/
int main(int argc, char *argv[])  
{
    uint8_t client_count = 0;
    int shmfd;
    
    
    /* setup signal handlers */
    const int signals[] = {SIGINT, SIGTERM};
    struct sigaction s;

    s.sa_handler = signal_handler;
    s.sa_flags   = 0;
    if(sigfillset(&s.sa_mask) < 0) {
        bail_out(EXIT_FAILURE, "sigfillset");
    }
    for(int i = 0; i < COUNT_OF(signals); i++) {
        if (sigaction(signals[i], &s, NULL) < 0) {
            bail_out(EXIT_FAILURE, "sigaction");
        }
    }
    
    /* Handle arguments */
    if (argc > 0) {
       progname = argv[0]; 
    }
    
    if (argc > 2) {
        fprintf(stderr, "USAGE: %s [input_file]", progname);
        exit(EXIT_FAILURE);
    }

    switch (argc) {
    /* Handle dict input from stdin */
    case 1: 
        printf("Please input your dictionary: \n");
        in_stream = stdin;
        read_dict();
    break;
    /* Handle dict input from file */
    case 2: 
		if ((in_stream = fopen(argv[1], "r")) == NULL)
		{
            bail_out(EXIT_FAILURE, "Invalid File");
		}
        read_dict();
    break;
    default:
        fprintf(stderr, "USAGE: %s [input_file]", progname);
        exit(EXIT_FAILURE);
        break; 
    }

    /* Create a new Shared Memory Segment (shm_open) */
    shmfd = shm_open(SHM_NAME, O_RDWR | O_CREAT | O_EXCL, PERMISSION);

    if (shmfd == (-1)) {
        bail_out(EXIT_FAILURE, "shm_open failed");
    }
    
    /*  Truncate a file to a specified length 
        extend (set size) */ 
    if (ftruncate(shmfd, sizeof *shared) == -1) {
        (void) close(shmfd);
        bail_out(EXIT_FAILURE, "ftruncate failed");
    }

    /* Map shared memory object */
    shared = mmap(NULL, sizeof *shared,
                    PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);

    if (shared == MAP_FAILED) {
        (void) close(shmfd);
        bail_out(EXIT_FAILURE, "MMAP failed");
    }

    if (close(shmfd) == -1) {
        bail_out(EXIT_FAILURE, "close(shmfd) failed");
    }
    
    shared->sc_terminate = -1;

    /* Create new named semaphores */
    s_server = sem_open(S_SERVER, O_CREAT | O_EXCL, PERMISSION, 0);
    s_client = sem_open(S_CLIENT, O_CREAT | O_EXCL, PERMISSION, 1);
    s_return = sem_open(S_RETURN, O_CREAT | O_EXCL, PERMISSION, 0);
    
    if(s_server == SEM_FAILED || 
        s_client == SEM_FAILED || 
        s_return == SEM_FAILED) {
        bail_out(EXIT_FAILURE, "sem_open(3) failed"); 
    }

    sem_set = 1;

    struct ClientList *el_pre = NULL;
    struct ClientList *el_cur = NULL;
    
    /* Keep server open until it gets killed. */
    while (!want_quit) {
        /* Critical section entry. */
        /* Wait until server is allowed to access SHM. */
        if (sem_wait(s_server) == -1) {
            if(errno == EINTR) continue;
            bail_out(EXIT_FAILURE, "sem_wait(3) failed");
        }
        
        /* Setup data for existing client. */
        if (shared->s_id >= 0) {
            el_cur = client_list;
            while (el_cur != NULL && el_cur->server_id != shared->s_id) {
                printf("elpre\n");
                el_pre = el_cur;
                printf("elcur\n");
                el_cur = el_cur->next;
            }

            if (el_cur == NULL) {
                bail_out(EXIT_FAILURE, "Client does not exist");
            }

            el_cur->guess = shared->c_guess;
        }
        
        /* Setup new client to list. */
        if (shared->s_id == -1) {
            /* Allocate element and set to zero. */
            el_cur = 
                 (struct ClientList *) calloc (1, sizeof(struct ClientList)); 
            if (el_cur == NULL) {
                bail_out(EXIT_FAILURE, "calloc(3) failed");
            }

            /* Assign unique ID based on client count. */
            el_cur->server_id = client_count++;
            el_cur->game_count = 0;
            
            /* Add the current element to our list. */
            el_cur->next = client_list;
            client_list = el_cur;
        }
        
        /* Check if client has terminated. */
        if (shared->sc_terminate >= 1) {
            DEBUG("Terminating client...\n");
            /* Remove client from list. */
            if (client_list == el_cur) {
                client_list = el_cur->next;
            } else {
                el_pre->next = el_cur->next;
            }

            free(el_cur);
            /* Free allocated resources. */
            /* Reset sc_terminate. */
            shared->sc_terminate = -1;
            if (sem_post(s_client) == -1) {
                bail_out(EXIT_FAILURE, "sem_post(3) failed");
            }
            /* Skip the rest of the game as we have nothing to do here */
            continue;
        }

        /* Check game status of client. */
        if (shared->status_id == CreateGame) {
            /* Start a new game. */
            DEBUG("Setting up game for client %d\n", shared->s_id);
            create_game(el_cur);
            
        }

        if (shared->status_id == Running) {
            /* Check guess. */
            DEBUG("Checking guess of client %d\n", shared->s_id);
            check_guess(el_cur);
        }
        
        /* Write server answer back into SHM. */
        shared->s_id = el_cur->server_id;
        shared->status_id = el_cur->status_id;
        shared->s_errors = el_cur->errors;
        strncpy(shared->s_word, el_cur->client_word, MAX_DATA);
        
        /* Let the client know that there is an answer. */
		if (sem_post(s_return) == -1) { 
            bail_out(EXIT_FAILURE, "sem_post(3) failed");
        }

        /* critical section end. */

    }
    /* Free stuff */
    free(strings);
}
Ejemplo n.º 5
0
int
my_waitpid (int pid, int *status, int flags)
{
  int ret, out_errno;

  linux_debug ("my_waitpid (%d, 0x%x)\n", pid, flags);

  if (flags & __WALL)
    {
      sigset_t block_mask, org_mask, wake_mask;
      int wnohang;

      wnohang = (flags & WNOHANG) != 0;
      flags &= ~(__WALL | __WCLONE);

      if (!wnohang)
	{
	  flags |= WNOHANG;

	  /* Block all signals while here.  This avoids knowing about
	     LinuxThread's signals.  */
	  sigfillset (&block_mask);
	  sigprocmask (SIG_BLOCK, &block_mask, &org_mask);

	  /* ... except during the sigsuspend below.  */
	  sigemptyset (&wake_mask);
	}

      while (1)
	{
	  /* Since all signals are blocked, there's no need to check
	     for EINTR here.  */
	  ret = waitpid (pid, status, flags);
	  out_errno = errno;

	  if (ret == -1 && out_errno != ECHILD)
	    break;
	  else if (ret > 0)
	    break;

	  if (flags & __WCLONE)
	    {
	      /* We've tried both flavors now.  If WNOHANG is set,
		 there's nothing else to do, just bail out.  */
	      if (wnohang)
		break;

	      linux_debug ("blocking\n");

	      /* Block waiting for signals.  */
	      sigsuspend (&wake_mask);
	    }
	  flags ^= __WCLONE;
	}

      if (!wnohang)
	sigprocmask (SIG_SETMASK, &org_mask, NULL);
    }
  else
    {
      do
	ret = waitpid (pid, status, flags);
      while (ret == -1 && errno == EINTR);
      out_errno = errno;
    }

  linux_debug ("my_waitpid (%d, 0x%x): status(%x), %d\n",
	       pid, flags, status ? *status : -1, ret);

  errno = out_errno;
  return ret;
}
Ejemplo n.º 6
0
int stub_pid1(sd_id128_t uuid) {
        enum {
                STATE_RUNNING,
                STATE_REBOOT,
                STATE_POWEROFF,
        } state = STATE_RUNNING;

        sigset_t fullmask, oldmask, waitmask;
        usec_t quit_usec = USEC_INFINITY;
        pid_t pid;
        int r;

        /* The new environment we set up, on the stack. */
        char new_environment[] =
                "container=systemd-nspawn\0"
                "container_uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

        /* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful
         * for allowing arbitrary processes run in a container, and still have all zombies reaped. */

        assert_se(sigfillset(&fullmask) >= 0);
        assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0);

        pid = fork();
        if (pid < 0)
                return log_error_errno(errno, "Failed to fork child pid: %m");

        if (pid == 0) {
                /* Return in the child */
                assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) >= 0);
                setsid();
                return 0;
        }

        reset_all_signal_handlers();

        log_close();
        close_all_fds(NULL, 0);
        log_open();

        /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
         * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ
         * find them set. */
        sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX);
        reset_environ(new_environment, sizeof(new_environment));

        rename_process("STUBINIT");

        assert_se(sigemptyset(&waitmask) >= 0);
        assert_se(sigset_add_many(&waitmask,
                                  SIGCHLD,          /* posix: process died */
                                  SIGINT,           /* sysv: ctrl-alt-del */
                                  SIGRTMIN+3,       /* systemd: halt */
                                  SIGRTMIN+4,       /* systemd: poweroff */
                                  SIGRTMIN+5,       /* systemd: reboot */
                                  SIGRTMIN+6,       /* systemd: kexec */
                                  SIGRTMIN+13,      /* systemd: halt */
                                  SIGRTMIN+14,      /* systemd: poweroff */
                                  SIGRTMIN+15,      /* systemd: reboot */
                                  SIGRTMIN+16,      /* systemd: kexec */
                                  -1) >= 0);

        /* Note that we ignore SIGTERM (sysv's reexec), SIGHUP (reload), and all other signals here, since we don't
         * support reexec/reloading in this stub process. */

        for (;;) {
                siginfo_t si;
                usec_t current_usec;

                si.si_pid = 0;
                r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG);
                if (r < 0) {
                        r = log_error_errno(errno, "Failed to reap children: %m");
                        goto finish;
                }

                current_usec = now(CLOCK_MONOTONIC);

                if (si.si_pid == pid || current_usec >= quit_usec) {

                        /* The child we started ourselves died or we reached a timeout. */

                        if (state == STATE_REBOOT) { /* dispatch a queued reboot */
                                (void) reboot(RB_AUTOBOOT);
                                r = log_error_errno(errno, "Failed to reboot: %m");
                                goto finish;

                        } else if (state == STATE_POWEROFF)
                                (void) reboot(RB_POWER_OFF); /* if this fails, fall back to normal exit. */

                        if (si.si_pid == pid && si.si_code == CLD_EXITED)
                                r = si.si_status; /* pass on exit code */
                        else
                                r = 255; /* signal, coredump, timeout, … */

                        goto finish;
                }
                if (si.si_pid != 0)
                        /* We reaped something. Retry until there's nothing more to reap. */
                        continue;

                if (quit_usec == USEC_INFINITY)
                        r = sigwaitinfo(&waitmask, &si);
                else {
                        struct timespec ts;
                        r = sigtimedwait(&waitmask, &si, timespec_store(&ts, quit_usec - current_usec));
                }
                if (r < 0) {
                        if (errno == EINTR) /* strace -p attach can result in EINTR, let's handle this nicely. */
                                continue;
                        if (errno == EAGAIN) /* timeout reached */
                                continue;

                        r = log_error_errno(errno, "Failed to wait for signal: %m");
                        goto finish;
                }

                if (si.si_signo == SIGCHLD)
                        continue; /* Let's reap this */

                if (state != STATE_RUNNING)
                        continue;

                /* Would love to use a switch() statement here, but SIGRTMIN is actually a function call, not a
                 * constant… */

                if (si.si_signo == SIGRTMIN+3 ||
                    si.si_signo == SIGRTMIN+4 ||
                    si.si_signo == SIGRTMIN+13 ||
                    si.si_signo == SIGRTMIN+14)

                        state = STATE_POWEROFF;

                else if (si.si_signo == SIGINT ||
                         si.si_signo == SIGRTMIN+5 ||
                         si.si_signo == SIGRTMIN+6 ||
                         si.si_signo == SIGRTMIN+15 ||
                         si.si_signo == SIGRTMIN+16)

                        state = STATE_REBOOT;
                else
                        assert_not_reached("Got unexpected signal");

                r = kill_and_sigcont(pid, SIGTERM);

                /* Let's send a SIGHUP after the SIGTERM, as shells tend to ignore SIGTERM but do react to SIGHUP. We
                 * do it strictly in this order, so that the SIGTERM is dispatched first, and SIGHUP second for those
                 * processes which handle both. That's because services tend to bind configuration reload or something
                 * else to SIGHUP. */

                if (r != -ESRCH)
                        (void) kill(pid, SIGHUP);

                quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC;
        }

finish:
        _exit(r < 0 ? EXIT_FAILURE : r);
}
Ejemplo n.º 7
0
/**
 * Set up log file and run in the backgroud
 */
void daemonize()
{
#ifdef WINDOWS
    if (!debug) {
        int fd;
        FILE *pidfh;

        if ((fd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1) {
            perror("Can't open log file");
            exit(1);
        }
        if (strcmp(pidfile, "")) {
            // Write out the pid file, before we redirect STDERR to the log.
            if ((pidfh = fopen(pidfile, "w")) == NULL) {
                perror("Can't open pid file for writing");
                exit(1);
            }
            fprintf(pidfh, "%d\n", GetCurrentProcessId());
            fclose(pidfh);
        }
        dup2(fd, 2);
        close(fd);
        applog = stderr;
    }
#else  // WINDOWS
    if (!debug) {
        int pid, fd;
        FILE *pidfh;

        if ((fd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0644)) == -1) {
            perror("Can't open log file");
            exit(1);
        }
        if ((pid = fork()) == -1) {
            perror("Couldn't fork");
            exit(1);
        } else if (pid > 0) {
            parent = 1;
            exit(0);
        }
        if (strcmp(pidfile, "")) {
            // Write out the pid file, before we redirect STDERR to the log.
            if ((pidfh = fopen(pidfile, "w")) == NULL) {
                perror("Can't open pid file for writing");
                exit(1);
            }
            fprintf(pidfh, "%d\n", getpid());
            fclose(pidfh);
        }
        setsid();
        dup2(fd, 2);
        close(fd);
        for (fd = 0; fd < 30; fd++) {
            if ((fd != 2) && (fd != listener)) {
                close(fd);
            }
        }
#ifdef VMS
        chdir("SYS$LOGIN");
#else
        chdir("/");
#endif
        umask(0);
        applog = stderr;
    }

    nice(-20);
    {
        struct sigaction act;

        sigfillset(&act.sa_mask);
        act.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART;

        act.sa_handler = gotsig;
        sigaction(SIGINT, &act, NULL);
        sigaction(SIGTERM, &act, NULL);
        act.sa_handler = gotpipe;
        sigaction(SIGPIPE, &act, NULL);
        act.sa_handler = SIG_IGN;
        sigaction(SIGCHLD, &act, NULL);
    }
#endif  // WINDOWS
}
Ejemplo n.º 8
0
int schedule_unload(pid_t pid, FAR struct binary_s *bin)
{
  struct sigaction act;
  struct sigaction oact;
  sigset_t sigset;
  irqstate_t flags;
  int errorcode;
  int ret;

  /* Make sure that SIGCHLD is unmasked */

  (void)sigemptyset(&sigset);
  (void)sigaddset(&sigset, SIGCHLD);
  ret = sigprocmask(SIG_UNBLOCK, &sigset, NULL);
  if (ret != OK)
    {
      /* The errno value will get trashed by the following debug output */

      errorcode = get_errno();
      bvdbg("ERROR: sigprocmask failed: %d\n", ret);
      goto errout;
    }

  /* Add the structure to the list.  We want to do this *before* connecting
   * the signal handler.  This does, however, make error recovery more
   * complex if sigaction() fails below because then we have to remove the
   * unload structure for the list in an unexpected context.
   */

  unload_list_add(pid, bin);

  /* Register the SIGCHLD handler */

  act.sa_sigaction = unload_callback;
  act.sa_flags     = SA_SIGINFO;

  (void)sigfillset(&act.sa_mask);
  (void)sigdelset(&act.sa_mask, SIGCHLD);

  ret = sigaction(SIGCHLD, &act, &oact);
  if (ret != OK)
    {
      /* The errno value will get trashed by the following debug output */

      errorcode = get_errno();
      bvdbg("ERROR: sigaction failed: %d\n" , ret);

      /* Emergency removal from the list */

      flags = irqsave();
      if (unload_list_remove(pid) != bin)
        {
          blldbg("ERROR: Failed to remove structure\n");
        }
      
      goto errout;
    }

  return OK;

errout:
  set_errno(errorcode);
  return ERROR;
}
Ejemplo n.º 9
0
void CnxtAdslLEDTask(void *sem)
{
	BOOL HandShakeLED;
	BOOL ShowtimeLED;

	struct task_struct *tsk = current ;
	tsk->session = 1 ;
	tsk->pgrp = 1 ;
#if defined (CONFIG_CNXT_GSHDSL) || defined (CONFIG_CNXT_GSHDSL_MODULE)
	strcpy ( tsk->comm, "CnxtGshdslLEDTask" ) ;
#else
	strcpy ( tsk->comm, "CnxtAdslLEDTask" ) ;
#endif

	/* sigstop and sigcont will stop and wakeup kupdate */
	spin_lock_irq(&tsk->sigmask_lock);
	sigfillset(&tsk->blocked);
	siginitsetinv(&current->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP));
	recalc_sigpending(tsk);
	spin_unlock_irq(&tsk->sigmask_lock);

	up((struct semaphore *)sem);

	TaskDelayConnect ( GP_TIMER_DMT_LED ) ;
	
	while(1)
	{
		/* Condensed Showtime State to two Booleans - In Showtime and In Training */
		ShowtimeLED= FALSE;
		HandShakeLED= FALSE;

		switch (HWSTATE.dwLineStatus)
		{
			case HW_IO_MODEM_STATUS_ACTIVATED:
				ShowtimeLED= TRUE;
				break;

			case HW_IO_MODEM_STATUS_CHANNEL_ANALYSIS:
			case HW_IO_MODEM_STATUS_TRANSCEIVER_TRAINING:
			case HW_IO_MODEM_STATUS_EXCHANGE:
			case HW_IO_MODEM_STATUS_ACTIVATION:
				HandShakeLED= TRUE;
				break;
		}

		/* Blink Showtime LED if in Training */
		if (ShowtimeLED || HandShakeLED)
		{
			WriteGPIOData( GPOUT_SHOWTIME_LED,LED_ON );
		}

		/* This logic is for a blinking Showtime LED */
		if (!ShowtimeLED)
		{
			WriteGPIOData( GPOUT_SHOWTIME_LED,LED_OFF );
		}

		TaskDelayMsec(LED_DELAY_PERIOD);

	}
}
Ejemplo n.º 10
0
int main(int argc, char *argv[]) {
	static struct sigaction act;

	act.sa_handler = get_signal;
	sigfillset(&(act.sa_mask));
	sigaction(SIGSEGV, &act, NULL);

	int no_curses = 0;

	extern char *optarg;
	extern int optind, optopt;
	int c, refresh_tmp_time = 0;
	char *endptr;
	while ((c = getopt(argc, argv, ":r:ch")) != -1) {
		switch (c) {
		case 'r':
			refresh_tmp_time = (int) strtol(optarg, &endptr, 10);
			if ((refresh_tmp_time) && (refresh_tmp_time < 30)) {
				refresh_time = refresh_tmp_time * 1000;
			}
			break;
		case 'c':
			no_curses = 1;
			break;
		case 'h':
			printf("Usage: dbtop [parameters]\n");
			printf("no parameters - standart ncurses mode\n\n");
			printf("parameters:\n");
			printf("-r interval - refresh interval for ncurses mode(in seconds)\n");
			printf("-c - show one time users list (no ncurses)\n");
			exit(0);
			break;
		}
	}
	_socket = connect_to_server_dbtop();
	in = fdopen(_socket, "r+");
	out = fdopen(_socket, "w");
	if (!in || !out) {
		printf("Can't connect to socket. Maybe governor is not started\n");
		exit(-1);
	}
	if (no_curses) {
		client_type_t ctt = DBTOPCL;
		fwrite(&ctt, sizeof(client_type_t), 1, out);
		fflush(out);
		accounts = NULL;
		recv_accounts = NULL;
		read_info();
		printOneScreenNoCurses();
		exit(0);
	}
	
///    
    /*client_type_t ctt = DBTOP;
	fwrite(&ctt, sizeof(client_type_t), 1, out);
	fflush(out);*/
	accounts = NULL;
	recv_accounts = NULL;
	initscr();
	
	signal(SIGALRM, end_pgm);
	signal(SIGHUP, end_pgm);
	signal(SIGPIPE, end_pgm);
	signal(SIGQUIT, end_pgm);
	signal(SIGTERM, end_pgm);
	signal(SIGINT, end_pgm);
	
	noecho();
	nonl();
	intrflush(stdscr, false);
	keypad(stdscr, true);
	curs_set(0);
	if (has_colors()) {
		start_color();
		use_default_colors();
		init_pair(1, COLOR_GREEN, COLOR_BLUE);
		init_pair(2, COLOR_BLUE, -1);
		init_pair(3, COLOR_RED, -1);
	}
	raw();
	halfdelay(5);
    
    read_keys();
	closesock();
}
Ejemplo n.º 11
0
static pid_t spawn_ras(struct ast_channel *chan, char *args)
{
	pid_t pid;
	int x;	
	char *c;

	char *argv[PPP_MAX_ARGS];
	int argc = 0;
	char *stringp=NULL;
	sigset_t fullset, oldset;

	sigfillset(&fullset);
	pthread_sigmask(SIG_BLOCK, &fullset, &oldset);

	/* Start by forking */
	pid = fork();
	if (pid) {
		pthread_sigmask(SIG_SETMASK, &oldset, NULL);
		return pid;
	}

	/* Restore original signal handlers */
	for (x=0;x<NSIG;x++)
		signal(x, SIG_DFL);

	pthread_sigmask(SIG_UNBLOCK, &fullset, NULL);

	/* Execute RAS on File handles */
	dup2(chan->fds[0], STDIN_FILENO);

	/* Drop high priority */
	if (ast_opt_high_priority)
		ast_set_priority(0);

	/* Close other file descriptors */
	for (x=STDERR_FILENO + 1;x<1024;x++) 
		close(x);

	/* Reset all arguments */
	memset(argv, 0, sizeof(argv));

	/* First argument is executable, followed by standard
	   arguments for dahdi PPP */
	argv[argc++] = PPP_EXEC;
	argv[argc++] = "nodetach";

	/* And all the other arguments */
	stringp=args;
	c = strsep(&stringp, ",");
	while(c && strlen(c) && (argc < (PPP_MAX_ARGS - 4))) {
		argv[argc++] = c;
		c = strsep(&stringp, ",");
	}

	argv[argc++] = "plugin";
	argv[argc++] = "dahdi.so";
	argv[argc++] = "stdin";

	/* Finally launch PPP */
	execv(PPP_EXEC, argv);
	fprintf(stderr, "Failed to exec PPPD!\n");
	exit(1);
}
Ejemplo n.º 12
0
int _SMERP_posixMain( int argc, char* argv[] )
{
// i18n global stuff
	if ( setlocale( LC_ALL, "" ) == NULL )	{
		std::cerr << "Unable to set locale. Falling back to default." << std::endl;
	}
	else	{
		if ( bindtextdomain( "SMERP", "../po" ) == NULL )	{
			std::cerr << "Not enough memory to bind textdomain" << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
		if ( textdomain( "SMERP" ) == NULL )	{
			std::cerr << "Not enough memory to set textdomain" << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
	}
// end of i18n global stuff

	try	{
		_SMERP::Version		appVersion( MAJOR_VERSION, MINOR_VERSION, REVISION_NUMBER );
		_SMERP::CmdLineConfig	cmdLineCfg;
		const char		*configFile;

// it's just a DUMMY for now
		_SMERP::HandlerConfiguration	handlerConfig;

		if ( !cmdLineCfg.parse( argc, argv ))	{	// there was an error parsing the command line
			std::cerr << cmdLineCfg.errMsg() << std::endl << std::endl;
			cmdLineCfg.usage( std::cerr );
			std::cerr << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
// command line has been parsed successfully
// if cmdLineCfg.errMsg() is not empty than we have a warning
		if ( !cmdLineCfg.errMsg().empty() )	// there was a warning parsing the command line
			std::cerr << "BOO:" << cmdLineCfg.errMsg() << std::endl << std::endl;

// if we have to print the version or the help do it and exit
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_VERSION )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl << std::endl;
			return _SMERP::ErrorCodes::OK;
		}
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_HELP )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			cmdLineCfg.usage( std::cout );
			std::cout << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

// decide what configuration file to use
		if ( !cmdLineCfg.cfgFile.empty() )	// if it has been specified than that's The One ! (and only)
			configFile = cmdLineCfg.cfgFile.c_str();
		else
			configFile = _SMERP::CfgFileConfig::chooseFile( DEFAULT_MAIN_CONFIG,
								       DEFAULT_USER_CONFIG,
								       DEFAULT_LOCAL_CONFIG );
		if ( configFile == NULL )	{	// there is no configuration file
			std::cerr << gettext ( "MOMOMO: no configuration file found !" ) << std::endl << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}

		_SMERP::CfgFileConfig	cfgFileCfg;
		if ( !cfgFileCfg.parse( configFile ))	{	// there was an error parsing the configuration file
			std::cerr << cfgFileCfg.errMsg() << std::endl << std::endl;
			return _SMERP::ErrorCodes::FAILURE;
		}
		else if ( !cfgFileCfg.errMsg().empty())
			std::cerr << cfgFileCfg.errMsg() << std::endl;
// configuration file has been parsed successfully
// build the application configuration
		_SMERP::ApplicationConfiguration config( cmdLineCfg, cfgFileCfg);

// now here we know where to log to on stderr
		_SMERP::LogBackend::instance().setConsoleLevel( config.stderrLogLevel );

// Check the configuration
		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::CHECK_CONFIG )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			if ( config.check() )	{
				if ( config.errMsg().empty() )	{
					std::cout << "Configuration OK" << std::endl << std::endl;
					return _SMERP::ErrorCodes::OK;
				}
				else	{
					std::cout << "WARNING: " << config.errMsg() << std::endl << std::endl;
					return _SMERP::ErrorCodes::OK;
				}
			}
			else	{
				std::cout << "ERROR: " << config.errMsg() << std::endl << std::endl;
				return _SMERP::ErrorCodes::OK;
			}
		}

		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::PRINT_CONFIG )	{
			std::cout << std::endl << gettext( "BOBOBO version " )
				<< appVersion.toString() << std::endl;
			config.print( std::cout );
			std::cout << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

		if ( cmdLineCfg.command == _SMERP::CmdLineConfig::TEST_CONFIG )	{
			std::cout << "Not implemented yet" << std::endl << std::endl;
			return _SMERP::ErrorCodes::OK;
		}

		// Daemon stuff
		if( !config.foreground ) {
			// Aba: maybe also in the foreground?
			// try to lock the pidfile, bail out if not possible
			if( boost::filesystem::exists( config.pidFile ) ) {
				boost::interprocess::file_lock lock( config.pidFile.c_str( ) );
				if( lock.try_lock( ) ) {
					std::cerr << "Pidfile is locked, another daemon running?" << std::endl;
					return _SMERP::ErrorCodes::FAILURE;
				}
			}

			// daemonize, lose process group, terminal output, etc.
			if( daemon( 0, 0 ) ) {
				std::cerr << "Daemonizing server failed" << std::endl;
				return _SMERP::ErrorCodes::FAILURE;
			}

			// now here we lost constrol over the console, we should
			// create a temporary logger which at least tells what's
			// going on in the syslog
			_SMERP::LogBackend::instance().setSyslogLevel( config.syslogLogLevel );
			_SMERP::LogBackend::instance().setSyslogFacility( config.syslogFacility );
			_SMERP::LogBackend::instance().setSyslogIdent( config.syslogIdent );

			// if we are root we can drop privileges now
			struct group *groupent;
			struct passwd *passwdent;

			groupent = getgrnam( config.group.c_str( ) );
			passwdent = getpwnam( config.user.c_str( ) );
			if( groupent == NULL || passwdent == NULL ) {
				LOG_CRITICAL << "Illegal group '" << config.group << "' or user '" << config.user << "'";
				return _SMERP::ErrorCodes::FAILURE;
			}

			if( setgid( groupent->gr_gid ) < 0 ) {
				LOG_CRITICAL << "setgid for group '" << config.group << "' failed!";
				return _SMERP::ErrorCodes::FAILURE;
			}

			if( setuid( passwdent->pw_uid ) < 0 ) {
				LOG_CRITICAL << "setgid for user '" << config.user << "' failed!";
				return _SMERP::ErrorCodes::FAILURE;
			}

			// create a pid file and lock id
			std::ofstream pidFile( config.pidFile.c_str( ), std::ios_base::trunc );
			if( !pidFile.good( ) ) {
				LOG_CRITICAL << "Unable to create PID file '" << config.pidFile << "'!";
				return _SMERP::ErrorCodes::FAILURE;
			}
			pidFile << getpid( ) << std::endl;
			pidFile.close( );

			// Create the final logger based on the configuration
			// file logger only here to get the right permissions
			_SMERP::LogBackend::instance().setLogfileLevel( config.logFileLogLevel );
			_SMERP::LogBackend::instance().setLogfileName( config.logFile );
		}

		// Block all signals for background thread.
		sigset_t new_mask;
		sigfillset( &new_mask );
		sigset_t old_mask;
		pthread_sigmask( SIG_BLOCK, &new_mask, &old_mask );

		LOG_NOTICE << "Starting server";

		// Run server in background thread(s).
		_SMERP::ServerHandler	handler( handlerConfig );
		_SMERP::Network::server s( config.address, config.SSLaddress, handler,
					   config.threads, config.maxConnections );
		boost::thread t( boost::bind( &_SMERP::Network::server::run, &s ));

		// Restore previous signals.
		pthread_sigmask( SIG_SETMASK, &old_mask, 0 );

		// Wait for signal indicating time to shut down.
		sigset_t wait_mask;
		sigemptyset( &wait_mask );
		sigaddset( &wait_mask, SIGINT );
		sigaddset( &wait_mask, SIGQUIT );
		sigaddset( &wait_mask, SIGTERM );
		pthread_sigmask( SIG_BLOCK, &wait_mask, 0 );
		int sig = 0;
		sigwait( &wait_mask, &sig );

		// Stop the server.
		LOG_INFO << "Stopping server";
		s.stop();
		t.join();
		LOG_NOTICE << "Server stopped";

		// Daemon stuff
		if( !config.foreground ) {
			(void)remove( config.pidFile.c_str( ) );
		}
	}
	catch (std::exception& e)	{
		// Aba: how to delete the pid file here?
		LOG_ERROR << "posixMain: exception: " << e.what() << "\n";
		return _SMERP::ErrorCodes::FAILURE;
	}

	return _SMERP::ErrorCodes::OK;
}
Ejemplo n.º 13
0
void Sigfillset(sigset_t *set)
{ 
    if (sigfillset(set) < 0)
	unix_error("Sigfillset error");
    return;
}
Ejemplo n.º 14
0
int
_sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
{
	int ret = 0;
	struct sigaction gact;

	/* Check if the signal number is out of range: */
	if (sig < 1 || sig > NSIG) {
		/* Return an invalid argument: */
		errno = EINVAL;
		ret = -1;
	} else {
		if (_thread_initial == NULL)
			_thread_init();

		/*
		 * Check if the existing signal action structure contents are
		 * to be returned: 
		 */
		if (oact != NULL) {
			/* Return the existing signal action contents: */
			oact->sa_handler = _thread_sigact[sig - 1].sa_handler;
			oact->sa_mask = _thread_sigact[sig - 1].sa_mask;
			oact->sa_flags = _thread_sigact[sig - 1].sa_flags;
		}

		/* Check if a signal action was supplied: */
		if (act != NULL) {
			/* Set the new signal handler: */
			_thread_sigact[sig - 1].sa_mask = act->sa_mask;
			_thread_sigact[sig - 1].sa_flags = act->sa_flags;
			_thread_sigact[sig - 1].sa_handler = act->sa_handler;
		}

		/*
		 * Check if the kernel needs to be advised of a change
		 * in signal action:
		 */
		if (act != NULL && sig != _SCHED_SIGNAL && sig != SIGCHLD &&
		    sig != SIGINFO) {
			/*
			 * Ensure the signal handler cannot be interrupted
			 * by other signals.  Always request the POSIX signal
			 * handler arguments.
			 */
			sigfillset(&gact.sa_mask);
			gact.sa_flags = SA_SIGINFO | SA_RESTART;

			/*
			 * Check if the signal handler is being set to
			 * the default or ignore handlers:
			 */
			if (act->sa_handler == SIG_DFL ||
			    act->sa_handler == SIG_IGN)
				/* Specify the built in handler: */
				gact.sa_handler = act->sa_handler;
			else
				/*
				 * Specify the thread kernel signal
				 * handler:
				 */
				gact.sa_handler = (void (*) ()) _thread_sig_handler;

			/* Change the signal action in the kernel: */
		    	if (__sys_sigaction(sig,&gact,NULL) != 0)
				ret = -1;
		}
	}

	/* Return the completion status: */
	return (ret);
}
Ejemplo n.º 15
0
int main(int argc, char *argv[]) {
        _cleanup_udev_unref_ struct udev *udev = NULL;
        _cleanup_udev_event_unref_ struct udev_event *event = NULL;
        _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
        _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL;
        char syspath[UTIL_PATH_SIZE];
        const char *devpath;
        const char *action;
        sigset_t mask, sigmask_orig;
        int err;

        err = fake_filesystems();
        if (err < 0)
                return EXIT_FAILURE;

        udev = udev_new();
        if (udev == NULL)
                return EXIT_FAILURE;

        log_debug("version %s", VERSION);
        mac_selinux_init("/dev");

        sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);

        action = argv[1];
        if (action == NULL) {
                log_error("action missing");
                goto out;
        }

        devpath = argv[2];
        if (devpath == NULL) {
                log_error("devpath missing");
                goto out;
        }

        rules = udev_rules_new(udev, 1);

        strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL);
        dev = udev_device_new_from_syspath(udev, syspath);
        if (dev == NULL) {
                log_debug("unknown device '%s'", devpath);
                goto out;
        }

        udev_device_set_action(dev, action);
        event = udev_event_new(dev);

        sigfillset(&mask);
        sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
        event->fd_signal = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
        if (event->fd_signal < 0) {
                fprintf(stderr, "error creating signalfd\n");
                goto out;
        }

        /* do what devtmpfs usually provides us */
        if (udev_device_get_devnode(dev) != NULL) {
                mode_t mode = 0600;

                if (streq(udev_device_get_subsystem(dev), "block"))
                        mode |= S_IFBLK;
                else
                        mode |= S_IFCHR;

                if (!streq(action, "remove")) {
                        mkdir_parents_label(udev_device_get_devnode(dev), 0755);
                        mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
                } else {
                        unlink(udev_device_get_devnode(dev));
                        rmdir_parents(udev_device_get_devnode(dev), "/");
                }
        }

        udev_event_execute_rules(event,
                                 3 * USEC_PER_SEC, USEC_PER_SEC,
                                 NULL,
                                 rules,
                                 &sigmask_orig);
        udev_event_execute_run(event,
                               3 * USEC_PER_SEC, USEC_PER_SEC,
                               NULL);
out:
        if (event != NULL && event->fd_signal >= 0)
                close(event->fd_signal);
        mac_selinux_finish();

        return err ? EXIT_FAILURE : EXIT_SUCCESS;
}
Ejemplo n.º 16
0
int _aio_init(thread_pool_attr_t *pool_attr)
{
	static thread_pool_attr_t default_pool_attr = {
		  NULL,
		  _aio_block,
		  _aio_unblock,
		  _aio_handler,
		  _aio_context_alloc,
		  _aio_context_free,
		  NULL,
		  3,
		  1,
		  8,
		  10
	};
	struct _aio_control_block *cb;
	struct _aio_context *ctp;
	struct _aio_prio_list *plist;
	sigset_t set, oset;
	int i;
	  
	_mutex_lock(&_aio_init_mutex);
	if (_aio_cb) {
		_mutex_unlock(&_aio_init_mutex);
		return 0;
	}
	
	if ((cb = malloc(sizeof(*_aio_cb))) == NULL) {
		_mutex_unlock(&_aio_init_mutex);
		return -1;
	}
	memset(cb, 0, sizeof(*cb));
	pthread_mutex_init(&cb->cb_mutex, 0);
	(void)pthread_cond_init(&cb->cb_cond, 0);
	
	if (pool_attr == NULL) {
		pool_attr = &default_pool_attr;
	} else {
		pool_attr->block_func = _aio_block;
		pool_attr->context_alloc = _aio_context_alloc;
		pool_attr->unblock_func = _aio_unblock;
		pool_attr->handler_func = _aio_handler;
		pool_attr->context_free = _aio_context_free;
	}
	pool_attr->handle = (void *)cb;

	/* prepare some priority list entries */
	for (i = 0; i < _AIO_PRIO_LIST_LOW; i++) {
		plist = (struct _aio_prio_list *)malloc(sizeof(*plist));
		if (!plist) {
			goto err_ret;
		}
		plist->next = cb->cb_plist_free;
		cb->cb_plist_free = plist;
	}
	cb->cb_nfree = _AIO_PRIO_LIST_LOW;
	
	/* prepare the context */
	cb->ct_free = NULL;
	for (i = 0; i < pool_attr->maximum; i++) {
		if ((ctp = malloc(sizeof(*ctp))) == NULL) {
			goto err_ret;
		}
		ctp->next = cb->ct_free;
		cb->ct_free = ctp;
	}
	
	cb->tp = thread_pool_create(pool_attr, 0);
	if (cb->tp == NULL) {
		goto err_ret;
	}

	/* we can hook _aio_cb now */
	_aio_cb = cb;

	/* start the pool with all sigal blocked */
	if (sigfillset(&set) != 0 || (errno = pthread_sigmask(SIG_BLOCK, &set, &oset)) != EOK) {
		goto err_ret;
	}
	if (thread_pool_start(cb->tp) != EOK) {
		pthread_sigmask(SIG_SETMASK, &oset, NULL);
		goto err_ret;
	}
	pthread_sigmask(SIG_SETMASK, &oset, NULL);
	_mutex_unlock(&_aio_init_mutex);
	return 0;
		
err_ret:
	_mutex_lock(&cb->cb_mutex);
	
	if (cb->tp) {
		(void)thread_pool_destroy(cb->tp);
	}
	
	while ((plist = cb->cb_plist_free)) {
		cb->cb_plist_free = plist->next;
		free(plist);
	}
	
	while ((ctp = cb->ct_free)) {
		cb->ct_free = ctp->next;
		free(ctp);
	}

	pthread_cond_destroy(&cb->cb_cond);
	pthread_mutex_destroy(&cb->cb_mutex);
	
	free(cb);
	_mutex_unlock(&_aio_init_mutex);
	return -1;
}
Ejemplo n.º 17
0
void Subprocess::spawnInternal(
    std::unique_ptr<const char*[]> argv,
    const char* executable,
    Options& options,
    const std::vector<std::string>* env,
    int errFd) {
  // Parent work, pre-fork: create pipes
  std::vector<int> childFds;
  // Close all of the childFds as we leave this scope
  SCOPE_EXIT {
    // These are only pipes, closing them shouldn't fail
    for (int cfd : childFds) {
      CHECK_ERR(::close(cfd));
    }
  };

  int r;
  for (auto& p : options.fdActions_) {
    if (p.second == PIPE_IN || p.second == PIPE_OUT) {
      int fds[2];
      // We're setting both ends of the pipe as close-on-exec. The child
      // doesn't need to reset the flag on its end, as we always dup2() the fd,
      // and dup2() fds don't share the close-on-exec flag.
#if FOLLY_HAVE_PIPE2
      // If possible, set close-on-exec atomically. Otherwise, a concurrent
      // Subprocess invocation can fork() between "pipe" and "fnctl",
      // causing FDs to leak.
      r = ::pipe2(fds, O_CLOEXEC);
      checkUnixError(r, "pipe2");
#else
      r = ::pipe(fds);
      checkUnixError(r, "pipe");
      r = fcntl(fds[0], F_SETFD, FD_CLOEXEC);
      checkUnixError(r, "set FD_CLOEXEC");
      r = fcntl(fds[1], F_SETFD, FD_CLOEXEC);
      checkUnixError(r, "set FD_CLOEXEC");
#endif
      pipes_.emplace_back();
      Pipe& pipe = pipes_.back();
      pipe.direction = p.second;
      int cfd;
      if (p.second == PIPE_IN) {
        // Child gets reading end
        pipe.pipe = folly::File(fds[1], /*owns_fd=*/ true);
        cfd = fds[0];
      } else {
        pipe.pipe = folly::File(fds[0], /*owns_fd=*/ true);
        cfd = fds[1];
      }
      p.second = cfd;  // ensure it gets dup2()ed
      pipe.childFd = p.first;
      childFds.push_back(cfd);
    }
  }

  // This should already be sorted, as options.fdActions_ is
  DCHECK(std::is_sorted(pipes_.begin(), pipes_.end()));

  // Note that the const casts below are legit, per
  // http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html

  char** argVec = const_cast<char**>(argv.get());

  // Set up environment
  std::unique_ptr<const char*[]> envHolder;
  char** envVec;
  if (env) {
    envHolder = cloneStrings(*env);
    envVec = const_cast<char**>(envHolder.get());
  } else {
    envVec = environ;
  }

  // Block all signals around vfork; see http://ewontfix.com/7/.
  //
  // As the child may run in the same address space as the parent until
  // the actual execve() system call, any (custom) signal handlers that
  // the parent has might alter parent's memory if invoked in the child,
  // with undefined results.  So we block all signals in the parent before
  // vfork(), which will cause them to be blocked in the child as well (we
  // rely on the fact that Linux, just like all sane implementations, only
  // clones the calling thread).  Then, in the child, we reset all signals
  // to their default dispositions (while still blocked), and unblock them
  // (so the exec()ed process inherits the parent's signal mask)
  //
  // The parent also unblocks all signals as soon as vfork() returns.
  sigset_t allBlocked;
  r = sigfillset(&allBlocked);
  checkUnixError(r, "sigfillset");
  sigset_t oldSignals;

  r = pthread_sigmask(SIG_SETMASK, &allBlocked, &oldSignals);
  checkPosixError(r, "pthread_sigmask");
  SCOPE_EXIT {
    // Restore signal mask
    r = pthread_sigmask(SIG_SETMASK, &oldSignals, nullptr);
    CHECK_EQ(r, 0) << "pthread_sigmask: " << errnoStr(r);  // shouldn't fail
  };

  // Call c_str() here, as it's not necessarily safe after fork.
  const char* childDir =
    options.childDir_.empty() ? nullptr : options.childDir_.c_str();
  pid_t pid = vfork();
  if (pid == 0) {
    int errnoValue = prepareChild(options, &oldSignals, childDir);
    if (errnoValue != 0) {
      childError(errFd, kChildFailure, errnoValue);
    }

    errnoValue = runChild(executable, argVec, envVec, options);
    // If we get here, exec() failed.
    childError(errFd, kExecFailure, errnoValue);
  }
  // In parent.  Make sure vfork() succeeded.
  checkUnixError(pid, errno, "vfork");

  // Child is alive.  We have to be very careful about throwing after this
  // point.  We are inside the constructor, so if we throw the Subprocess
  // object will have never existed, and the destructor will never be called.
  //
  // We should only throw if we got an error via the errFd, and we know the
  // child has exited and can be immediately waited for.  In all other cases,
  // we have no way of cleaning up the child.
  pid_ = pid;
  returnCode_ = ProcessReturnCode(RV_RUNNING);
}
Ejemplo n.º 18
0
/* Helper: set the signal handler for evsignal to handler in base, so that
 * we can restore the original handler when we clear the current one. */
int
_evsig_set_handler(struct event_base *base,
    int evsignal, void (__cdecl *handler)(int))
{
#ifdef _EVENT_HAVE_SIGACTION
	struct sigaction sa;
#else
	ev_sighandler_t sh;
#endif
	struct evsig_info *sig = &base->sig;
	void *p;

	/*
	 * resize saved signal handler array up to the highest signal number.
	 * a dynamic array is used to keep footprint on the low side.
	 */
	if (evsignal >= sig->sh_old_max) {
		int new_max = evsignal + 1;
		event_debug(("%s: evsignal (%d) >= sh_old_max (%d), resizing",
			    __func__, evsignal, sig->sh_old_max));
		p = mm_realloc(sig->sh_old, new_max * sizeof(*sig->sh_old));
		if (p == NULL) {
			event_warn("realloc");
			return (-1);
		}

		memset((char *)p + sig->sh_old_max * sizeof(*sig->sh_old),
		    0, (new_max - sig->sh_old_max) * sizeof(*sig->sh_old));

		sig->sh_old_max = new_max;
		sig->sh_old = p;
	}

	/* allocate space for previous handler out of dynamic array */
	sig->sh_old[evsignal] = mm_malloc(sizeof *sig->sh_old[evsignal]);
	if (sig->sh_old[evsignal] == NULL) {
		event_warn("malloc");
		return (-1);
	}

	/* save previous handler and setup new handler */
#ifdef _EVENT_HAVE_SIGACTION
	memset(&sa, 0, sizeof(sa));
	sa.sa_handler = handler;
	sa.sa_flags |= SA_RESTART;
	sigfillset(&sa.sa_mask);

	if (sigaction(evsignal, &sa, sig->sh_old[evsignal]) == -1) {
		event_warn("sigaction");
		mm_free(sig->sh_old[evsignal]);
		sig->sh_old[evsignal] = NULL;
		return (-1);
	}
#else
	if ((sh = signal(evsignal, handler)) == SIG_ERR) {
		event_warn("signal");
		mm_free(sig->sh_old[evsignal]);
		sig->sh_old[evsignal] = NULL;
		return (-1);
	}
	*sig->sh_old[evsignal] = sh;
#endif

	return (0);
}
Ejemplo n.º 19
0
static void spawn_pidone(int argc, char **argv, char **envp)
{
    sigset_t set;

    if (getpid() != 1) {
        return;
    }

    sigfillset(&set);
    sigprocmask(SIG_BLOCK, &set, 0);

    main_pid = fork();
    switch (main_pid) {
	case 0:
            sigprocmask(SIG_UNBLOCK, &set, NULL);
            setsid();
            setpgid(0, 0);

            /* Child remains as pacemaker-remoted */
            return;
	case -1:
            perror("fork");
    }

    /* Parent becomes the reaper of zombie processes */
    /* Safe to initialize logging now if needed */

#ifdef HAVE___PROGNAME
    /* Differentiate ourselves in the 'ps' output */
    {
        char *p;
        int i, maxlen;
        char *LastArgv = NULL;
        const char *name = "pcmk-init";

	for(i = 0; i < argc; i++) {
		if(!i || (LastArgv + 1 == argv[i]))
			LastArgv = argv[i] + strlen(argv[i]);
	}

	for(i = 0; envp[i] != NULL; i++) {
		if((LastArgv + 1) == envp[i]) {
			LastArgv = envp[i] + strlen(envp[i]);
		}
	}

        maxlen = (LastArgv - argv[0]) - 2;

        i = strlen(name);
        /* We can overwrite individual argv[] arguments */
        snprintf(argv[0], maxlen, "%s", name);

        /* Now zero out everything else */
        p = &argv[0][i];
        while(p < LastArgv)
            *p++ = '\0';
        argv[1] = NULL;
    }
#endif /* HAVE___PROGNAME */

    while (1) {
	int sig;
	size_t i;

        sigwait(&set, &sig);
        for (i = 0; i < DIMOF(sigmap); i++) {
            if (sigmap[i].sig == sig) {
                sigmap[i].handler();
                break;
            }
        }
    }
}
Ejemplo n.º 20
0
int 
main(int argc, char **argv)
{
	char	program_name[FILENAME_MAX_CHARS];
	char	config_file[FILENAME_MAX_CHARS];

	int	syslog;
	int	loglevel;
	int	logfacility;

	char	c;

 	int	recoveryport;
	int	error;
        int daemon_mode = 0;

 	// init program_name and default config file
	strncpy(program_name, argv[0], FILENAME_MAX_CHARS);
	strncpy(config_file, DEFAULT_CONFIGFILE, FILENAME_MAX_CHARS);

	// init default log settings
	syslog = DEFAULT_USE_SYSLOG;
	loglevel = DEFAULT_LOG_LEVEL;
 	logfacility = DEFAULT_LOG_FACILITY;

	// allow the user to set a special port for login recovery
 	recoveryport = 0;

	//save start time for uptime calculation in status messages
	bgpmon_start_time = time(NULL);

 	// parse command line
	while ((c = getopt (argc, argv, "dl:c:f:hsr:")) != -1) {
		switch (c) {
			case 'c':
				strncpy(config_file, optarg, FILENAME_MAX_CHARS);
				break;
        	 	case 'l':
        	 		loglevel = atoi(optarg);
        	 	   	break;
        	 	case 'f':
        	 		logfacility = atoi(optarg);
        	 	   	break;
        	 	case 's':
        	 	   	syslog = 1;
        	 	   	break;
        	 	case 'r':
        	 		recoveryport = atoi(optarg);
        	 	   	break;
 			case 'd':
				daemon_mode = 1;
                                break;
        	 	case 'h':
        	 	case '?':
        	 	default :
        	 		usage( argv[0] );
        	 	   	break;
 		}
	}

	
	// if optind is less than the number of arguments from the command line (argc), then there
	// is something in the argument string that isn't preceded by valid switch (-c, -l, etc)
	if(optind<argc) {
		usage(argv[0]);
	}

	// initilaze log module
	if (init_log (program_name, syslog, loglevel, logfacility) ) {
		fprintf (stderr, "Failed to initialize log functions!\n");
		exit(1);
	}
#ifdef DEBUG
   	debug (__FUNCTION__, "Successfully initialized log module.");
#endif
	log_msg("BGPmon starting up\n");
        /* Turn into daemon if daemon_mode is set. */
        if (daemon_mode){
          godaemon(RUN_DIR,PID_FILE);
        }
	

        char scratchdir[FILENAME_MAX_CHARS];
        sprintf(scratchdir,"%s/%s",RUN_DIR,"bgpmon");
	// initialize login interface
  	if (initLoginControlSettings(config_file, scratchdir, recoveryport) ) {
           	log_fatal("Unable to initialize login interface");
	};
#ifdef DEBUG
   	debug (__FUNCTION__, "Successfully initialized login module.");
#endif

	// initialize acl
	if(initACLSettings()) {
           	log_fatal("Unable to initialize ACL settings");
	};
#ifdef DEBUG
   	debug (__FUNCTION__, "Successfully initialized acl module.");
#endif

	// initialize the queue information
  	if (initQueueSettings() ) {
           	log_fatal("Unable to initialize queue settings");
	};
#ifdef DEBUG
   	debug (__FUNCTION__, "Successfully initialized queue settings.");
#endif

	// initialize clients control settings
  	if (initClientsControlSettings() ) {
		log_fatal("Unable to initialize client settings");
	};
#ifdef DEBUG
   	debug (__FUNCTION__, "Successfully initialized client settings.");
#endif

	// initialize clients control settings
	if (initMrtControlSettings() ) {
			log_fatal("Unable to initialize mrt settings");
		};
#ifdef DEBUG
	debug (__FUNCTION__, "Successfully initialized mrt settings.");
#endif

	//  initialize chains settings
  	if (initChainsSettings() ) {
		log_fatal("Unable to initialize chain settings");
	};

	// initialize the periodic settings
	if (initPeriodicSettings() ) {
			log_fatal("Unable to initialize periodic settings");
	};
#ifdef DEBUG
	debug (__FUNCTION__, "Successfully initialized periodic settings.");
#endif

	// read in the configuration file and change
	// all relevant settings based on config file
	if (readConfigFile(config_file) ) {
		// if the configuration file is not readable, remove the
		// configuration file and backup a copy
		backupConfigFile(LoginSettings.configFile, LoginSettings.scratchDir);
		saveConfigFile(LoginSettings.configFile);
		log_err("Corrupt Configuration File Moved to %s.  New configuration file written.", LoginSettings.scratchDir);  
	}


	/*
	 * Block signals in initial thread. New threads will
	 * inherit this signal mask. All the signals will be handled
	 * in a dedicated thread
	 */
	sigfillset ( &signalSet );
	pthread_sigmask ( SIG_BLOCK, &signalSet, NULL );

	// launch the signal handling thread
#ifdef DEBUG
	debug(__FUNCTION__, "Creating signal thread...");
#endif
	pthread_t sighandlerThreadID;
	if ((error = pthread_create(&sighandlerThreadID, NULL, sigHandler, config_file)) > 0 )
		log_fatal("Failed to create signal handler thread: %s\n", strerror(error));
#ifdef DEBUG
	debug(__FUNCTION__, "Created signal thread!");
#endif

	// create the system queues
#ifdef DEBUG
	debug(__FUNCTION__, "Creating queues...");
#endif
	/*create the peer queue*/
	peerQueue = createQueue(copyBMF, sizeOfBMF, PEER_QUEUE_NAME, strlen(PEER_QUEUE_NAME), FALSE);

	/*create the label queue*/		  
	labeledQueue = createQueue(copyBMF, sizeOfBMF, LABEL_QUEUE_NAME, strlen(LABEL_QUEUE_NAME), FALSE);

	/*create the xml queue*/
	xmlUQueue = createQueue(copyXML, sizeOfXML, XML_U_QUEUE_NAME, strlen(XML_U_QUEUE_NAME), TRUE);
	xmlRQueue = createQueue(copyXML, sizeOfXML, XML_R_QUEUE_NAME, strlen(XML_R_QUEUE_NAME), TRUE);	
#ifdef DEBUG
        debug(__FUNCTION__, "Created queues!");
#endif

	// launch the peering thread
#ifdef DEBUG
	debug(__FUNCTION__, "Creating peering thread...");
#endif	   
	launchAllPeers();
#ifdef DEBUG
	debug(__FUNCTION__, "Created peering thread!");
#endif

	// launch the labeling thread
#ifdef DEBUG
	debug(__FUNCTION__, "Creating labeling thread...");
#endif	   
	launchLabelingThread();
#ifdef DEBUG
	debug(__FUNCTION__, "Created labeling thread!");
#endif

	// launch the xml thread
#ifdef DEBUG
	debug(__FUNCTION__, "Creating xml thread...");
#endif	   
	launchXMLThread();
#ifdef DEBUG
	debug(__FUNCTION__, "Created xml thread!");
#endif


	// launch the clients control thread
#ifdef DEBUG
        debug(__FUNCTION__, "Creating clients control thread...");
#endif
	launchClientsControlThread();
#ifdef DEBUG
        debug(__FUNCTION__, "Created clients control thread!");
#endif

	// launch the mrt control thread
#ifdef DEBUG
	debug(__FUNCTION__, "Creating mrt control thread...");
#endif
	launchMrtControlThread();
#ifdef DEBUG
	debug(__FUNCTION__, "Created mrt control thread!");
#endif

        // launch the configured chains thread
#ifdef DEBUG
        debug(__FUNCTION__, "Creating threads for each configured chain...");
#endif	
	launchAllChainsThreads();
#ifdef DEBUG
        debug(__FUNCTION__, "Created threads for each configured chain!");
#endif

        // launch the login thread
#ifdef DEBUG
        debug(__FUNCTION__, "Creating login thread...");
#endif
	launchLoginControlThread();
#ifdef DEBUG
        debug(__FUNCTION__, "Created login thread!");
#endif

	// launch the periodic thread
#ifdef DEBUG
	debug(__FUNCTION__, "Creating periodic thread...");
#endif
	LaunchPeriodicThreads();
#ifdef DEBUG
	debug(__FUNCTION__, "Created periodic thread!");
#endif

	// write BGPMON_START message into the Peer Queue
	BMF bmf = createBMF(0, BMF_TYPE_BGPMON_START);
	QueueWriter qw = createQueueWriter(peerQueue);
	writeQueue(qw, bmf);
	destroyQueueWriter(qw);

	// periodically check on the state of each thread
	time_t threadtime;
	time_t currenttime;
	char currenttime_extended[64];
	memset(currenttime_extended, 0, 64);
	char threadtime_extended[64];
	memset(threadtime_extended, 0, 64);
	struct tm * current_tm = NULL;
	struct tm * thread_tm = NULL;
	int *chainIDs;
	long *clientIDs;
	long *mrtIDs;
	int clientcount, chaincount, mrtcount, i;
	while ( TRUE ) 
	{
		// get the current running time to compare the threads
		// last exection time to
		currenttime = time(NULL);
		sleep(THREAD_CHECK_INTERVAL);
		current_tm = localtime(&currenttime);
		strftime(currenttime_extended, sizeof(currenttime_extended), "%Y-%m-%dT%H:%M:%SZ", current_tm);

		// CLI MODULE
			// check the cli listener
			threadtime = getLoginControlLastAction();
			if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL)
			{
				thread_tm = localtime(&threadtime);
				strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
				log_warning("CLI Module is idle: current time = %s, last thread time = %s", currenttime_extended, threadtime_extended);
				//closeBgpmon(config_file);
			}

			// check the individual cli threads for updates
			int clicount = 0;
			long * cliIDs = NULL;
			clicount = getActiveCliIds(&cliIDs);
			if(clicount != -1)
			{
				for ( i=0; i<clicount; i++) 
				{
					threadtime = getCliLastAction(cliIDs[i]);
					if ( difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) 
					{
						thread_tm = localtime(&threadtime);
						strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
						log_warning("Cli %d is idle: current time = %s, last cli %d thread time = %s", cliIDs[i], currenttime_extended, cliIDs[i], threadtime_extended);
					}
				}
				free(cliIDs);
			}

		// CLIENTS MODULE
			// Clients Module
			threadtime = getClientsControlLastAction();
			thread_tm = localtime(&threadtime);
			strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
			if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL)
			{
				thread_tm = localtime(&threadtime);
				strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
				log_warning("Clients Module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended);
				//closeBgpmon(config_file);
			}

			// UPDATE clients
			clientcount = getActiveClientsIDs(&clientIDs, CLIENT_LISTENER_UPDATA);
			if(clientcount != -1)
			{
				for (i = 0; i < clientcount; i++) 
				{
					threadtime = getClientLastAction(clientIDs[i], CLIENT_LISTENER_UPDATA);
					if (difftime(currenttime, threadtime) > THREAD_DEAD_INTERVAL) 
					{
						thread_tm = localtime(&threadtime);
						strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
						log_warning("Updates Client %d is idle: current time = %s, last client %d thread time = %s", clientIDs[i], currenttime_extended, clientIDs[i], threadtime_extended);
					}
				}
				free(clientIDs);
			}

			// RIB clients
			clientcount = getActiveClientsIDs(&clientIDs, CLIENT_LISTENER_RIB);
			if(clientcount != -1)
			{
				for (i = 0; i < clientcount; i++) 
				{
					threadtime = getClientLastAction(clientIDs[i], CLIENT_LISTENER_RIB);
					if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) 
					{
						thread_tm = localtime(&threadtime);
						strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
						log_warning("RIB Client %d is idle: current time = %s, last client %d thread time = %s", clientIDs[i], currenttime_extended, clientIDs[i], threadtime_extended);
					}
				}
				free(clientIDs);
			}

		// PEER MODULE
			for (i=0; i < MAX_SESSION_IDS; i++)
			{
				if( Sessions[i] != NULL && getSessionState(Sessions[i]->sessionID) == stateEstablished)
				{
					threadtime = getSessionLastActionTime(i);
					if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) 
					{
						thread_tm = localtime(&threadtime);
						strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
						log_warning("Peering session %d is idle: current time = %s, last client %d thread time = %s",Sessions[i]->sessionID,  currenttime_extended, Sessions[i]->sessionID, threadtime_extended);
						//closeBgpmon(config_file);
					}
					
				}
			}

		// LABELING MODULE
			threadtime = getLabelThreadLastActionTime();
			if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL)
			{
				thread_tm = localtime(&threadtime);
				strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
				log_warning("Labeling module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended);
				//closeBgpmon(config_file);
			}		

		// XML MODULE
			threadtime = getXMLThreadLastAction();
			if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL)
			{
				thread_tm = localtime(&threadtime);
				strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
				log_warning("XML module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended);
				//closeBgpmon(config_file);
			}				


		// QUAGGA MODULE
			// mrt listener
			threadtime = getMrtControlLastAction();
			if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL)
			{
				thread_tm = localtime(&threadtime);
				strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
				log_warning("MRT module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended);
				//closeBgpmon(config_file);
			}

			// mrt connections
			mrtcount = getActiveMrtsIDs(&mrtIDs);
			if(mrtcount != -1)
			{
				for (i = 0; i < mrtcount; i++) 
				{
					threadtime = getMrtLastAction(mrtIDs[i]);
					if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) 
					{
						thread_tm = localtime(&threadtime);
						strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
						log_warning("MRT client %d is idle: current time = %s, last client %d thread time = %s",mrtIDs[i], currenttime_extended, mrtIDs[i], threadtime_extended);
					}
				}
				free(mrtIDs);
			}

		// CHAIN MODULE
			chaincount = getActiveChainsIDs(&chainIDs);
			if(chaincount != -1)
			{
				for (i = 0; i < chaincount; i++) 
				{
					threadtime = getChainLastAction(chainIDs[i]);
					if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL) 
					{
						thread_tm = localtime(&threadtime);
						strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
						log_warning("BGPmon chain %ld is idle: current time = %s, last client %ld thread time = %s", chainIDs[i], currenttime_extended, chainIDs[i], threadtime_extended);
					}
				}
				free(chainIDs);
			}			

		// PERIODIC MODULE
			// route refresh 
			threadtime = getPeriodicRouteRefreshThreadLastActionTime();
			if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL)
			{
				thread_tm = localtime(&threadtime);
				strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
				log_warning("Route Refresh module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended);
				//closeBgpmon(config_file);
			}		

			// status message
			threadtime = getPeriodicStatusMessageThreadLastActionTime();	
			if (difftime(currenttime,threadtime) > THREAD_DEAD_INTERVAL)
			{
				thread_tm = localtime(&threadtime);
				strftime(threadtime_extended, sizeof(threadtime_extended), "%Y-%m-%dT%H:%M:%SZ", thread_tm);
				log_warning("Status Messages module is idle: current time = %s, last control thread time = %s", currenttime_extended, threadtime_extended);
				//closeBgpmon(config_file);
			}

	}
	
	// should never get here
	log_err( "main: unexpectedly finished");

	return(0);
} 
Ejemplo n.º 21
0
ufw_sk *ufw_socket(int proto, int opts){
	ufw_sk *sk;
	struct node *cur;
	struct linger lg = { 0, 0 };
	struct timeval now;
	char filename[100];
	int on = 1;
	int fd;
	dump_t *dp = NULL;
	struct sigaction handler;

	if(proto != IPPROTO_TCP && proto != IPPROTO_UDP){
		errno = EINVAL;
		if(opts & FATAL)die("proto");
		return NULL;
	}

	fd = socket(PF_INET, SOCK_RAW, proto);
	if(fd < 0){
		if(opts & FATAL)die("socket");
		return NULL;
	}
	setsockopt(fd, SOL_SOCKET, SO_LINGER, &lg, sizeof(lg));
	setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
	setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));

	if(fcntl(fd, F_SETOWN, getpid()) < 0){
		if(opts & FATAL)die("fcntl");
		return NULL;
	}

	if(fcntl(fd, F_SETFL, O_NONBLOCK | O_ASYNC) < 0){
		if(opts & FATAL)die("fcntl");
		return NULL;
	}

	if(fcntl(fd, F_SETSIG, SIGIO) < 0){
		if(opts & FATAL)die("fcntl");
		return NULL;
	}

	if(opts & DUMP_AUTONAME){
		gettimeofday(&now, NULL);
		snprintf(filename, 100, "/tmp/%d.%06d.pcap", (int)now.tv_sec, (int)now.tv_usec);
		dp = dump_open(filename, "w");
		if(!dp){
			if(opts & FATAL)die("%s", filename);
			return NULL;
		}
	}

	cur = malloc(sizeof(struct node) + sizeof(ufw_sk));
	if(!cur){
		if(opts & FATAL)die("malloc");
		return NULL;
	}

	sk = (void *)cur + sizeof(struct node);
	cur->data = sk;
	cur->next = ufwsk_list;
	cur->prev = NULL;
	ufwsk_list = cur;

	sk->fd = fd;
	sk->opts = opts;
	sk->ttl = IPDEFTTL;
	sk->proto = proto;
	sk->saddr = sk->daddr = 0;
	sk->sport = sk->dport = 0;
	sk->window = TCP_MAXWIN;
	sk->first_packet.tv_sec = 0;
	sk->first_packet.tv_usec = 0;
	sk->limit_packet = 0;
	sk->limit_packet_flags = 0;
	sk->limit_byte = 0;
	sk->received = 0;
	sk->dump = dp;

	if(!(opts & SIGIO_MANUAL) && !is_ufw_sigio_handler){
		is_ufw_sigio_handler = 1;
		handler.sa_sigaction = ufw_sigio_handler;
		sigfillset(&handler.sa_mask);
		handler.sa_flags = SA_SIGINFO;
		sigaction(SIGIO, &handler, NULL);
	}

	return sk;
}
Ejemplo n.º 22
0
static void
trap_default_signals(void)
{
  static const int core_signals[] = {
    SIGQUIT,
    SIGILL,
#ifdef SIGEMT
    SIGEMT,
#endif
    SIGFPE,
    SIGBUS,
    SIGSEGV,
#ifdef SIGSYS
    SIGSYS,
#endif
#ifdef SIGXCPU
    SIGXCPU,
#endif
#ifdef SIGXFSZ
    SIGXFSZ,
#endif
  };
  static const int exit_signals[] = {
    SIGHUP,
    SIGINT,
    SIGALRM,
    SIGTERM,
    SIGUSR1,
    SIGUSR2,
#ifdef SIGPOLL
    SIGPOLL, 
#endif
#ifdef SIGVTALRM
    SIGVTALRM,
#endif
#ifdef SIGSTKFLT
    SIGSTKFLT, 
#endif
  };
  static const int ignore_signals[] = {
    SIGPIPE,
  };
  static const struct {
    const int *sigs;
    u_int nsigs;
    void (*handler)(int signo
#ifdef SA_SIGINFO
		    , siginfo_t *info, void *context
#endif
		   );
  } sigmap[] = {
    { core_signals, array_size(core_signals), core_handler},
    { exit_signals, array_size(exit_signals), exit_handler},
    { ignore_signals, array_size(ignore_signals), NULL},
  };
  u_int i;

  for (i = 0; i < array_size(sigmap); i++)
    {
      u_int j;

      for (j = 0; j < sigmap[i].nsigs; j++)
        {
	  struct sigaction oact;
	  if ((sigaction(sigmap[i].sigs[j],NULL,&oact) == 0) &&
	      (oact.sa_handler == SIG_DFL))
	    {
	      struct sigaction act;
	      sigfillset (&act.sa_mask);
	      if (sigmap[i].handler == NULL)
	        {
		  act.sa_handler = SIG_IGN;
		  act.sa_flags = 0;
	        }
	      else
	        {
#ifdef SA_SIGINFO
		  /* Request extra arguments to signal handler. */
		  act.sa_sigaction = sigmap[i].handler;
		  act.sa_flags = SA_SIGINFO;
#else
		  act.sa_handler = sigmap[i].handler;
		  act.sa_flags = 0;
#endif
	        }
	      if (sigaction(sigmap[i].sigs[j],&act,NULL) < 0)
	        zlog_warn("Unable to set signal handler for signal %d: %s",
			  sigmap[i].sigs[j],safe_strerror(errno));

	    }
        }
    }
}
Ejemplo n.º 23
0
/*
 * child_fn() - Inside container
 */
int child_fn(void *arg)
{
	pid_t pid, ppid;
	sigset_t newset;
	struct sigaction sa;
	char buf[5];

	/* Setup pipe read and write ends */
	pid = getpid();
	ppid = getppid();

	if (pid != CHILD_PID || ppid != PARENT_PID) {
		printf("cinit: pidns was not created properly\n");
		exit(1);
	}

	/* Setup pipes to communicate with parent */
	close(cinit_parent[0]);
	close(parent_cinit[1]);

	/* Block SIGUSR1 signal */
	sigemptyset(&newset);
	sigaddset(&newset, SIGUSR1);
	if (sigprocmask(SIG_BLOCK, &newset, 0) == -1) {
		perror("cinit: sigprocmask() failed");
		exit(1);
	}
	tst_resm(TINFO, "cinit: blocked SIGUSR1");

	/* Let parent to queue SIGUSR1 in pending */
	if (write(cinit_parent[1], "c:go", 5) != 5) {
		perror("cinit: pipe is broken to write");
		exit(1);
	}

	/* Check if parent has queued up SIGUSR1 */
	read(parent_cinit[0], buf, 5);
	if (strcmp(buf, "p:go") != 0) {
		printf("cinit: parent did not respond!\n");
		exit(1);
	}

	/* Now redefine handler for SIGUSR1 */
	sa.sa_flags = SA_SIGINFO;
	sigfillset(&sa.sa_mask);
	sa.sa_sigaction = child_signal_handler;
	if (sigaction(SIGUSR1, &sa, NULL) == -1) {
		perror("cinit: sigaction failed");
		exit(1);
	}

	/* Unblock traffic on SIGUSR1 queue */
	tst_resm(TINFO, "cinit: unblocking SIGUSR1");
	sigprocmask(SIG_UNBLOCK, &newset, 0);

	/* Check if new handler is called */
	if (broken == 1) {
		printf("cinit: broken flag didn't change\n");
		exit(1);
	}

	/* Cleanup and exit */
	close(cinit_parent[1]);
	close(parent_cinit[0]);
	exit(0);
}
Ejemplo n.º 24
0
int main()
{
	int cnt = 0;
	int rc;
	pthread_t child_thread;
	struct sigaction act;

	/* Set up main thread to handle SIGALRM */
	act.sa_flags = 0;
	act.sa_handler = sig_handler;
	sigfillset(&act.sa_mask);
	sigaction(SIGALRM, &act, 0);

	printf("main: Initialize barrier with count = 2\n");
	if (pthread_barrier_init(&barrier, NULL, 2) != 0)
	{
		printf("main: Error at pthread_barrier_init()\n");
		return PTS_UNRESOLVED;
	}

	printf("main: create child thread\n");
	thread_state = NOT_CREATED_THREAD;
	if (pthread_create(&child_thread, NULL, fn_chld, NULL) != 0)
	{
		printf("main: Error at pthread_create()\n");
		return PTS_UNRESOLVED;
	}

	/* Expect the child to block*/
	cnt = 0;
	do{
		sleep(1);
	}while (thread_state !=EXITING_THREAD && cnt++ < 2);

	if (thread_state == EXITING_THREAD)
	{
		/* child thread did not block */
		printf("Test FAILED: child thread did not block on "
			"pthread_barrier_wait()\n");
		exit(PTS_FAIL);
	}
	else if (thread_state != ENTERED_THREAD)
	{
		printf("Unexpected thread state\n");
		exit(PTS_UNRESOLVED);
	}

	/* Just in case main gets in a blocked state, send me a SIGALRM after 2 secs */
	alarm(2);

	printf("main: reinitilize barrier while thread is blocking on it\n");
	rc = pthread_barrier_init(&barrier, NULL, 2);

	if (rc == EBUSY)
	{
		printf("main: pthread_barrier_init() correctly got EBUSY");
		printf("Test PASSED\n");
	}
	else
	{
		printf("main: got return code: %d, %s\n", rc, strerror(rc));
		printf("Test PASSED: Note*: Expected EBUSY, but standard says 'may' fail.\n");
	}

	/* Cancel thread in case it is still blocked */
	pthread_cancel(child_thread);

	return PTS_PASS;
}
Ejemplo n.º 25
0
static FILE *
safe_popen(char *cmd)
{
    int p[2], fd, argc;
    pid_t pid;
    char *argv[SAFE_POPEN_MAXARGS + 1];
    FILE *fp;
    static char blank[] = " \t";
    static struct sigaction newact;

    if (pipe(p) < 0)
	return 0;

    fp = fdopen(p[0], "r");
    if (fp == 0) {
	close(p[0]);
	close(p[1]);
	return 0;
    }

    /* Setup signals so that SIGCHLD is ignored as we want to do waitpid */
    newact.sa_handler = SIG_DFL;
    newact.sa_flags = 0;
    sigfillset(&newact.sa_mask);
    sigaction (SIGCHLD, &newact, &oldact);

    pid = fork();
    switch (pid) {
      int ndesc;

      case -1:
	fclose(fp); /* this closes p[0], the fd associated with fp */
	close(p[1]);
	sigaction (SIGCHLD, &oldact, NULL);
	return 0;

      case 0:
	/* dup write-side of pipe to stderr and stdout */
	if (p[1] != 1) dup2(p[1], 1);
	if (p[1] != 2) dup2(p[1], 2);

	/* 
	 * close the other file descriptors, except stdin which we
	 * try reassociating with /dev/null, first (bug 174993)
	 */
	if (!freopen("/dev/null", "r", stdin))
	    close(0);
	ndesc = getdtablesize();
	for (fd = PR_MIN(65536, ndesc); --fd > 2; close(fd));

	/* clean up environment in the child process */
	putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc:/usr/etc");
	putenv("SHELL=/bin/sh");
	putenv("IFS= \t");

	/*
	 * The caller may have passed us a string that is in text
	 * space. It may be illegal to modify the string
	 */
	cmd = strdup(cmd);
	/* format argv */
	argv[0] = strtok(cmd, blank);
	argc = 1;
	while ((argv[argc] = strtok(0, blank)) != 0) {
	    if (++argc == SAFE_POPEN_MAXARGS) {
		argv[argc] = 0;
		break;
	    }
	}

	/* and away we go */
	execvp(argv[0], argv);
	exit(127);
	break;

      default:
	close(p[1]);
	break;
    }

    /* non-zero means there's a cmd running */
    safe_popen_pid = pid;
    return fp;
}
Ejemplo n.º 26
0
void
setsignal(int signo)
{
	int action;
	char *t, tsig;
	struct sigaction act;

	if ((t = trap[signo]) == NULL)
		action = S_DFL;
	else if (*t != '\0')
		action = S_CATCH;
	else
		action = S_IGN;
	if (rootshell && action == S_DFL) {
		switch (signo) {
		case SIGINT:
			if (iflag || minusc || sflag == 0)
				action = S_CATCH;
			break;
		case SIGQUIT:
#ifdef DEBUG
			if (debug)
				break;
#endif
			/* FALLTHROUGH */
		case SIGTERM:
			if (iflag)
				action = S_IGN;
			break;
#if JOBS
		case SIGTSTP:
		case SIGTTOU:
			if (mflag)
				action = S_IGN;
			break;
#endif
		}
	}

	if (signo == SIGCHLD)
		action = S_CATCH;

	t = &sigmode[signo - 1];
	tsig = *t;
	if (tsig == 0) {
		/*
		 * current setting unknown
		 */
		if (sigaction(signo, 0, &act) == -1) {
			/*
			 * Pretend it worked; maybe we should give a warning
			 * here, but other shells don't. We don't alter
			 * sigmode, so that we retry every time.
			 */
			return;
		}
		if (act.sa_handler == SIG_IGN) {
			if (mflag && (signo == SIGTSTP ||
			     signo == SIGTTIN || signo == SIGTTOU)) {
				tsig = S_IGN;	/* don't hard ignore these */
			} else
				tsig = S_HARD_IGN;
		} else {
			tsig = S_RESET;	/* force to be set */
		}
	}
	if (tsig == S_HARD_IGN || tsig == action)
		return;
	switch (action) {
	case S_CATCH:
		act.sa_handler = onsig;
		break;
	case S_IGN:
		act.sa_handler = SIG_IGN;
		break;
	default:
		act.sa_handler = SIG_DFL;
	}
	*t = action;
	act.sa_flags = 0;
	sigfillset(&act.sa_mask);
	sigaction(signo, &act, 0);
}
Ejemplo n.º 27
0
/*
 * Thread for handling command line attacks (TERM_TTY)
 * Use global variable struct term_tty *tty_tmp
 */
void *
th_tty_peer(void *args)
{
   int fail;
   time_t this_time;
   struct cl_args *arguments;
   struct term_tty *tty;
   struct term_node *term_node=NULL;
   sigset_t mask;
   
   terms->work_state = RUNNING;
   
write_log(0, "\n th_tty_peer thread = %d...\n",(int)pthread_self());
   
   sigfillset(&mask);
   
   if (pthread_sigmask(SIG_BLOCK, &mask,NULL))
   {
      thread_error("th_tty_peer pthread_sigmask()",errno);
      th_tty_peer_exit(NULL);
   }   

   if (pthread_mutex_lock(&terms->mutex) != 0)
   {
      thread_error("th_tty_peer pthread_mutex_lock",errno);
      th_tty_peer_exit(NULL);
   }
   
   fail = term_add_node(&term_node, TERM_TTY, (int)NULL, pthread_self());

   if (fail == -1)
   {
      if (pthread_mutex_unlock(&terms->mutex) != 0)
         thread_error("th_tty_peer pthread_mutex_unlock",errno);
      th_tty_peer_exit(term_node);
   }

   if (term_node == NULL)
   {
      write_log(1,"Ouch!! No more than %d %s accepted!!\n",
                  term_type[TERM_TTY].max, term_type[TERM_TTY].name);
      
      if (pthread_mutex_unlock(&terms->mutex) != 0)
         thread_error("th_tty_peer pthread_mutex_unlock",errno);
      th_tty_peer_exit(term_node);
   }

   tty = term_node->specific;

   memcpy(tty,tty_tmp,sizeof(struct term_tty));    

    this_time = time(NULL);
   
#ifdef HAVE_CTIME_R
#ifdef SOLARIS
    ctime_r(&this_time,term_node->since, sizeof(term_node->since));
#else
    ctime_r(&this_time,term_node->since);
#endif
#else
    pthread_mutex_lock(&mutex_ctime);
    strncpy(term_node->since, ctime(&this_time), sizeof(term_node->since));   
    pthread_mutex_unlock(&mutex_ctime);
#endif

    /* Just to remove the cr+lf...*/
    term_node->since[sizeof(term_node->since)-2] = 0;

    /* This is a tty so, man... ;) */
    strncpy(term_node->from_ip, "127.0.0.1", sizeof(term_node->from_ip));

   /* Parse config file */
   if (strlen(tty_tmp->config_file))
      if (parser_read_config_file(tty_tmp, term_node) < 0)
      {
         write_log(0, "Error reading configuration file\n");
         th_tty_peer_exit(term_node);
      }
   
    if (init_attribs(term_node) < 0)        
    {
       if (pthread_mutex_unlock(&terms->mutex) != 0)
         thread_error("th_tty_peer pthread_mutex_unlock",errno);
       th_tty_peer_exit(term_node);
    }

    arguments = args;
    
    /* In command line mode we initialize the values by default */
    if (protocols[arguments->proto_index].init_attribs)
    {
        fail = (*protocols[arguments->proto_index].init_attribs)
            (term_node);
    } else
        write_log(0, "Warning, proto %d has no init_attribs function!!\n", arguments->proto_index);

    /* Choose a parser */
    fail = parser_cl_proto(term_node, arguments->count, arguments->argv_tmp, arguments->proto_index);

   if (pthread_mutex_unlock(&terms->mutex) != 0)
      thread_error("th_tty_peer pthread_mutex_unlock",errno);
   
   if (fail < 0) {
       write_log(0, "Error when parsing...\n");
       th_tty_peer_exit(term_node);
   }
      
   write_log(0, "Entering command line mode...\n");
   /* Execute attack... */
   doloop(term_node, arguments->proto_index);
   
   th_tty_peer_exit(term_node);
   
   return(NULL);
}
Ejemplo n.º 28
0
void afp_over_dsi_sighandlers(AFPObj *obj)
{
    DSI *dsi = (DSI *) obj->dsi;
    struct sigaction action;

    memset(&action, 0, sizeof(action));
    sigfillset(&action.sa_mask);
    action.sa_flags = SA_RESTART;

    /* install SIGHUP */
    action.sa_handler = afp_dsi_reload;
    if ( sigaction( SIGHUP, &action, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
        afp_dsi_die(EXITERR_SYS);
    }

    /* install SIGURG */
    action.sa_handler = afp_dsi_transfer_session;
    if ( sigaction( SIGURG, &action, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
        afp_dsi_die(EXITERR_SYS);
    }

    /* install SIGTERM */
    action.sa_handler = afp_dsi_die;
    if ( sigaction( SIGTERM, &action, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
        afp_dsi_die(EXITERR_SYS);
    }

    /* install SIGQUIT */
    action.sa_handler = ipc_reconnect_handler;
    if ( sigaction(SIGQUIT, &action, NULL ) < 0 ) {
        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
        afp_dsi_die(EXITERR_SYS);
    }

    /* SIGUSR2 - server message support */
    action.sa_handler = afp_dsi_getmesg;
    if ( sigaction( SIGUSR2, &action, NULL) < 0 ) {
        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
        afp_dsi_die(EXITERR_SYS);
    }

    /*  SIGUSR1 - set down in 5 minutes  */
    action.sa_handler = afp_dsi_timedown;
    action.sa_flags = SA_RESTART;
    if ( sigaction( SIGUSR1, &action, NULL) < 0 ) {
        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
        afp_dsi_die(EXITERR_SYS);
    }

    /*  SIGINT - enable max_debug LOGging to /tmp/afpd.PID.XXXXXX */
    action.sa_handler = afp_dsi_debug;
    if ( sigaction( SIGINT, &action, NULL) < 0 ) {
        LOG(log_error, logtype_afpd, "afp_over_dsi: sigaction: %s", strerror(errno) );
        afp_dsi_die(EXITERR_SYS);
    }

#ifndef DEBUGGING
    /* SIGALRM - tickle handler */
    action.sa_handler = alarm_handler;
    if ((sigaction(SIGALRM, &action, NULL) < 0) ||
            (setitimer(ITIMER_REAL, &dsi->timer, NULL) < 0)) {
        afp_dsi_die(EXITERR_SYS);
    }
#endif /* DEBUGGING */
}
Ejemplo n.º 29
0
void *clamukoth(void *arg)
{
	struct thrarg *tharg = (struct thrarg *) arg;
	sigset_t sigset;
        struct sigaction act;
	int eventcnt = 1, extinfo;
	char err[128];
	struct ClamAuthEvent event;

    /* ignore all signals except SIGUSR1 */
    sigfillset(&sigset);
    sigdelset(&sigset, SIGUSR1);
    /* The behavior of a process is undefined after it ignores a 
     * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */
    sigdelset(&sigset, SIGFPE);
    sigdelset(&sigset, SIGILL);
    sigdelset(&sigset, SIGSEGV);
#ifdef SIGBUS    
    sigdelset(&sigset, SIGBUS);
#endif
    pthread_sigmask(SIG_SETMASK, &sigset, NULL);
    memset(&act, 0, sizeof(struct sigaction));
    act.sa_handler = cauth_exit;
    sigfillset(&(act.sa_mask));
    sigaction(SIGUSR1, &act, NULL);
    sigaction(SIGSEGV, &act, NULL);

    extinfo = optget(tharg->opts, "ExtendedDetectionInfo")->enabled;

    cauth_fd = open("/dev/clamauth", O_RDONLY);
    if(cauth_fd == -1) {
	logg("!ClamAuth: Can't open /dev/clamauth\n");
	if(errno == ENOENT)
	    logg("!ClamAuth: Please make sure ClamAuth.kext is loaded\n");
	else if(errno == EACCES)
	    logg("!ClamAuth: This application requires root privileges\n");
	else
	    logg("!ClamAuth: /dev/clamauth: %s\n", cli_strerror(errno, err, sizeof(err)));

	return NULL;
    }

    while(1) {
	if(read(cauth_fd, &event, sizeof(event)) > 0) {
	    if(eventcnt == 1) {
		if(event.action != SUPPORTED_PROTOCOL) {
		    logg("!ClamAuth: Protocol version mismatch (tool: %d, driver: %d)\n", SUPPORTED_PROTOCOL, event.action);
		    close(cauth_fd);
		    return NULL;
		}
		if(strncmp(event.path, "ClamAuth", 8)) {
		    logg("!ClamAuth: Invalid version event\n");
		    close(cauth_fd);
		    return NULL;
		}
		logg("ClamAuth: Driver version: %s, protocol version: %d\n", &event.path[9], event.action);
	    } else {
		cauth_scanfile(event.path, extinfo, tharg);
	    }
	    eventcnt++;
	} else {
	    if(errno == ENODEV) {
		printf("^ClamAuth: ClamAuth module deactivated, terminating\n");
		close(cauth_fd);
		return NULL;
	    }
	}
	usleep(200);
    }
}
Ejemplo n.º 30
0
int
main(int argc, char **argv)
{
	int ch;
	int error = 0;
	extern char *__progname;

	while ((ch = getopt(argc, argv, "abcdDfijkKlmnqrstuv:")) != -1)
		switch (ch) {
		case 'a':
			/* print all commands */
			aflag = 1;
			break;
		case 'b':
			/* sort by per-call user/system time average */
			bflag = 1;
			sa_cmp = cmp_avgusrsys;
			break;
		case 'c':
			/* print percentage total time */
			cflag = 1;
			break;
		case 'd':
			/* sort by averge number of disk I/O ops */
			dflag = 1;
			sa_cmp = cmp_avgdkio;
			break;
		case 'D':
			/* print and sort by total disk I/O ops */
			Dflag = 1;
			sa_cmp = cmp_dkio;
			break;
		case 'f':
			/* force no interactive threshold comprison */
			fflag = 1;
			break;
		case 'i':
			/* do not read in summary file */
			iflag = 1;
			break;
		case 'j':
			/* instead of total minutes, give sec/call */
			jflag = 1;
			break;
		case 'k':
			/* sort by cpu-time average memory usage */
			kflag = 1;
			sa_cmp = cmp_avgcpumem;
			break;
		case 'K':
			/* print and sort by cpu-storage integral */
			sa_cmp = cmp_cpumem;
			Kflag = 1;
			break;
		case 'l':
			/* separate system and user time */
			lflag = 1;
			break;
		case 'm':
			/* print procs and time per-user */
			mflag = 1;
			break;
		case 'n':
			/* sort by number of calls */
			sa_cmp = cmp_calls;
			break;
		case 'q':
			/* quiet; error messages only */
			qflag = 1;
			break;
		case 'r':
			/* reverse order of sort */
			rflag = 1;
			break;
		case 's':
			/* merge accounting file into summaries */
			sflag = 1;
			break;
		case 't':
			/* report ratio of user and system times */
			tflag = 1;
			break;
		case 'u':
			/* first, print uid and command name */
			uflag = 1;
			break;
		case 'v':
			/* cull junk */
			vflag = 1;
			cutoff = atoi(optarg);
			break;
		case '?':
		default:
			(void)fprintf(stderr,
			    "usage: %s [-abcDdfijKklmnqrstu] [-v cutoff]"
			    " [file ...]\n", __progname);
			exit(1);
		}

	argc -= optind;
	argv += optind;

	/* various argument checking */
	if (fflag && !vflag)
		errx(1, "only one of -f requires -v");
	if (fflag && aflag)
		errx(1, "only one of -a and -v may be specified");
	/* XXX need more argument checking */

	if (!uflag) {
		/* initialize tables */
		if ((sflag || (!mflag && !qflag)) && pacct_init() != 0)
			errx(1, "process accounting initialization failed");
		if ((sflag || (mflag && !qflag)) && usracct_init() != 0)
			errx(1, "user accounting initialization failed");
	}

	if (argc == 0) {
		argc = dfltargc;
		argv = dfltargv;
	}

	/* for each file specified */
	for (; argc > 0; argc--, argv++) {
		int	fd;

		/*
		 * load the accounting data from the file.
		 * if it fails, go on to the next file.
		 */
		fd = acct_load(argv[0], sflag);
		if (fd < 0)
			continue;

		if (!uflag && sflag) {
#ifndef DEBUG
			sigset_t nmask, omask;
			int unmask = 1;

			/*
			 * block most signals so we aren't interrupted during
			 * the update.
			 */
			if (sigfillset(&nmask) == -1) {
				warn("sigfillset");
				unmask = 0;
				error = 1;
			}
			if (unmask &&
			    (sigprocmask(SIG_BLOCK, &nmask, &omask) == -1)) {
				warn("couldn't set signal mask ");
				unmask = 0;
				error = 1;
			}
#endif /* DEBUG */

			/*
			 * truncate the accounting data file ASAP, to avoid
			 * losing data.  don't worry about errors in updating
			 * the saved stats; better to underbill than overbill,
			 * but we want every accounting record intact.
			 */
			if (ftruncate(fd, 0) == -1) {
				warn("couldn't truncate %s", *argv);
				error = 1;
			}

			/*
			 * update saved user and process accounting data.
			 * note errors for later.
			 */
			if (pacct_update() != 0 || usracct_update() != 0)
				error = 1;

#ifndef DEBUG
			/*
			 * restore signals
			 */
			if (unmask &&
			    (sigprocmask(SIG_SETMASK, &omask, NULL) == -1)) {
				warn("couldn't restore signal mask");
				error = 1;
			}
#endif /* DEBUG */
		}

		/*
		 * close the opened accounting file
		 */
		if (close(fd) == -1) {
			warn("close %s", *argv);
			error = 1;
		}
	}

	if (!uflag && !qflag) {
		/* print any results we may have obtained. */
		if (!mflag)
			pacct_print();
		else
			usracct_print();
	}

	if (!uflag) {
		/* finally, deallocate databases */
		if (sflag || (!mflag && !qflag))
			pacct_destroy();
		if (sflag || (mflag && !qflag))
			usracct_destroy();
	}

	exit(error);
}