minit.c
86badd32
 /*
c858e9b6
  * minit.c
e6a800d5
  * Copyright (C) 2008-2012 KLab Inc.
86badd32
  */
 #include "makuosan.h"
ab81b188
 #ifdef HAVE_SYS_PRCTL_H
 #include <sys/prctl.h>
 #endif
86badd32
 
84aa6542
 static void version_print()
 {
   printf("makuosan version %s\n", PACKAGE_VERSION);
 }
 
e5b6322e
 static void usage()
 {
84aa6542
   version_print();
   printf("(Multicasts All-Kinds of Updating Operation for Servers on Administered Network)\n\n");
e5b6322e
   printf("usage: makuosan [OPTION]\n");
5900834d
   printf("  -d num       # loglevel(0-9)\n");
   printf("  -u uid       # user\n");
   printf("  -g gid       # group\n");
   printf("  -G gid,..    # groups\n");
   printf("  -b dir       # base dir\n");
   printf("  -p port      # port number       (default: 5000)\n");
   printf("  -m addr      # multicast address (default: 224.0.0.108)\n");
   printf("  -i addr      # interface address (default: 0.0.0.0)\n");
   printf("  -l addr      # listen address    (default: 127.0.0.1)\n");
   printf("  -U path      # unix domain socket\n");
   printf("  -k file      # key file (encrypt password)\n");
   printf("  -K file      # key file (console password)\n");
   printf("  -f num       # parallel send count(default: 5) \n");
   printf("  -R num       # recv buffer size [bytes]\n");
   printf("  -S num       # send buffer size [bytes]\n");
   printf("  -T num       # traffic rate     [Mbps]\n");
   printf("  -n           # don't fork\n");
   printf("  -r           # don't recv\n");
   printf("  -s           # don't send\n");
   printf("  -o           # don't listen (console off mode)\n");
   printf("  -O           # owner match limitation mode\n");
   printf("  -c --chroot  # chroot to base dir\n");
1200e0a9
   printf("  -C --core    # enable core\n");
5900834d
   printf("  -V --version # version\n"); 
   printf("  -h --help    # help\n\n"); 
e5b6322e
   exit(0);
 }
 
 static void signal_handler(int n)
86badd32
 {
   switch(n){
     case SIGINT:
     case SIGTERM:
       loop_flag = 0;
       break;
     case SIGPIPE:
       break;
     case SIGUSR1:
e6a800d5
       if(log_level<9){
         log_level++;
86badd32
       }
       break;
     case SIGUSR2:
e6a800d5
       if(log_level>0){
         log_level--;
86badd32
       }
       break;
   }
 }
 
 static void minit_option_setdefault()
 {
   int i;
   memset(&moption, 0, sizeof(moption));
   moption.maddr.sin_family      = AF_INET;
   moption.maddr.sin_addr.s_addr = inet_addr(MAKUO_MCAST_ADDR);
   moption.maddr.sin_port        = htons(MAKUO_MCAST_PORT);
5900834d
   moption.iaddr.sin_family      = AF_INET;
   moption.iaddr.sin_addr.s_addr = INADDR_ANY;
   moption.iaddr.sin_port        = htons(MAKUO_MCAST_PORT);
86badd32
   moption.laddr.sin_family      = AF_INET;
292bc66c
   moption.laddr.sin_addr.s_addr = inet_addr(MAKUO_LOCAL_ADDR);
86badd32
   moption.laddr.sin_port        = htons(MAKUO_MCAST_PORT);
   moption.uaddr.sun_family      = AF_UNIX;
   moption.uaddr.sun_path[0]     = 0;
   moption.loglevel              = 0;
   moption.dontrecv              = 0;
   moption.dontsend              = 0;
   moption.dontfork              = 0;
   moption.cryptena              = 0;
   moption.comm_ena              = 1;
66158b71
   moption.core_ena              = 0;
   moption.coresize              = 0;
86badd32
   moption.commpass              = 0;
634a23d7
   moption.ownmatch              = 0;
5cf3fe0f
   moption.parallel              = 5;
0fe1cc19
   moption.recvsize              = 0;
   moption.sendsize              = 0;
1615a78a
   moption.sendrate              = 0;
86badd32
   moption.chroot                = 0;
   moption.uid                   = geteuid();
   moption.gid                   = getegid();
e5b6322e
   moption.gids                  = NULL;
86badd32
   getcwd(moption.base_dir, PATH_MAX);
   for(i=0;i<MAX_COMM;i++){
05348f1d
     moption.comm[i].no = i;
86badd32
     moption.comm[i].fd[0] = -1;
     moption.comm[i].fd[1] = -1;
   }
efce2c7f
   uname(&moption.uts);
86badd32
 }
 
c2cdbd80
 static int minit_option_setuid(char *name)
 {
   struct passwd *pw;
   if(*name >= '0' && *name <= '9'){
     moption.uid = atoi(name);
   }else{
1b4c64d4
     if((pw = getpwnam(name))){
c2cdbd80
       moption.uid = pw->pw_uid;
       moption.gid = pw->pw_gid;
     }else{
       lprintf(0,"[error] %s: not found user %s\n", __func__, name);
       return(1);
     }
   }
   return(0);
 }
 
 static int minit_option_setgid(char *name)
 {
   struct group *gr;
   if(*name >= '0' && *name <='9'){
     moption.gid = atoi(name);
   }else{
1b4c64d4
     if((gr = getgrnam(name))){
c2cdbd80
       moption.gid = gr->gr_gid;
     }else{
       lprintf(0,"[error] %s: not found group %s\n", __func__, name);
       return(1);
     }
   }
   return(0);
 }
 
 static int minit_option_setgids(char *name)
 {
   char *p;
   gid_t gid;
   size_t num;
   struct group *g;
   char buff[1024];
 
   if(moption.gids){
     free(moption.gids);
   }
   moption.gids = NULL;
   moption.gidn = 0;
 
   if(!name){
     return(0);
   }
 
   if(strlen(name) >= sizeof(buff)){
     lprintf(0, "[error] %s: gids too long %s\n", __func__, name);
     return(1);
   }
 
   num = 0;
   strcpy(buff, name);
   p = strtok(buff,",");
   while(p){
     p = strtok(NULL,",");
     num++;
   }
   if(!num){
     return(0);
   }
   moption.gidn = num;
   moption.gids = malloc(sizeof(gid_t) * num);
  
   num = 0; 
   strcpy(buff, name);
   p = strtok(buff,",");
   while(p){
     if(*p >= '0' && *p <= '9'){
       gid = atoi(p);
1b4c64d4
       if((g = getgrgid(gid))){
c2cdbd80
         moption.gids[num] = gid;
         strcpy(moption.grnames[num], g->gr_name);
       }else{
         lprintf(0, "[error] %s: not found group %s\n", __func__, p);
         return(1);
       }
     }else{
1b4c64d4
       if((g = getgrnam(p))){
c2cdbd80
         moption.gids[num] = g->gr_gid;
         strcpy(moption.grnames[num], p);
       }else{
         lprintf(0, "[error] %s: not found group %s\n", __func__, p);
         return(1);
       }
     }
     p = strtok(NULL,",");
     num++;
   }
   return(0);
 }
 
86badd32
 static void minit_option_getenv()
 {
   char *env;
 
1b4c64d4
   if((env=getenv("MAKUOSAN_BASE"))){
36959136
     if(*env){
       realpath(env, moption.base_dir);
     }
05348f1d
   }
1b4c64d4
   if((env=getenv("MAKUOSAN_PORT"))){
36959136
     if(*env && atoi(env)){
5bb20f6d
       moption.maddr.sin_port = htons(atoi(env));
       moption.laddr.sin_port = htons(atoi(env));
     }
86badd32
   }
1b4c64d4
   if((env=getenv("MAKUOSAN_USER"))){
36959136
     if(*env && minit_option_setuid(env)){
c2cdbd80
       exit(1);
86badd32
     }
   }
1b4c64d4
   if((env=getenv("MAKUOSAN_GROUP"))){
36959136
     if(*env && minit_option_setgid(env)){
c2cdbd80
       exit(1);
86badd32
     }
   }
1b4c64d4
   if((env=getenv("MAKUOSAN_GROUPS"))){
36959136
     if(*env && minit_option_setgids(env)){
c2cdbd80
       exit(1);
     }
e5b6322e
   }
1b4c64d4
   if((env=getenv("MAKUOSAN_SOCK"))){
86badd32
     strcpy(moption.uaddr.sun_path, env);
   }
1b4c64d4
   if((env=getenv("MAKUOSAN_RCVBUF"))){
0fe1cc19
     moption.recvsize = atoi(env);
d7aa38bf
   }
1b4c64d4
   if((env=getenv("MAKUOSAN_SNDBUF"))){
0fe1cc19
     moption.sendsize = atoi(env);
d7aa38bf
   }
86badd32
 }
 
 static void minit_signal()
 {
   struct sigaction sig;
   memset(&sig, 0, sizeof(sig));
   sig.sa_handler = signal_handler;
   if(sigaction(SIGINT,  &sig, NULL) == -1){
8f9aeac1
     lprintf(0, "%s: sigaction error SIGINT\n", __func__);
86badd32
     exit(1);
   }
   if(sigaction(SIGTERM, &sig, NULL) == -1){
8f9aeac1
     lprintf(0, "%s: sigaction error SIGTERM\n", __func__);
86badd32
     exit(1);
   }
   if(sigaction(SIGPIPE, &sig, NULL) == -1){
8f9aeac1
     lprintf(0, "%s: sigaction error SIGPIPE\n", __func__);
86badd32
     exit(1);
   }
   if(sigaction(SIGUSR1, &sig, NULL) == -1){
8f9aeac1
     lprintf(0, "%s: sigaction error SIGUSR1\n", __func__);
86badd32
     exit(1);
   }
   if(sigaction(SIGUSR2, &sig, NULL) == -1){
8f9aeac1
     lprintf(0, "%s: sigaction error SIGUSR2\n", __func__);
86badd32
     exit(1);
   }
 }
 
 static void minit_password(char *filename, int n)
 {
   int i;
   int f;
   char buff[64];
   MD5_CTX ctx;
 
   f = open(filename, O_RDONLY);
   if(f == -1){
c2cdbd80
     lprintf(0, "[error] %s: file open error %s\n", __func__, filename);
86badd32
     exit(1);
   }
   memset(buff, 0, sizeof(buff));
   i = read(f, buff, sizeof(buff) - 1);
   if(i == -1){
c2cdbd80
     lprintf(0, "[error] %s: file read error %s\n", __func__, filename);
86badd32
     exit(1);
   }
   if(i < 4){
c2cdbd80
     lprintf(0, "[error] %s: password too short %s\n", __func__, filename);
86badd32
     exit(1);
   }
   while(i--){
     if(buff[i] == '\r')
       buff[i] = 0;
     if(buff[i] == '\n')
       buff[i] = 0;
   }
   MD5_Init(&ctx);
   MD5_Update(&ctx, buff, strlen(buff));
43a6533f
   MD5_Final((unsigned char *)(moption.password[n]), &ctx);
86badd32
   if(read(f, buff, sizeof(buff))){
c2cdbd80
     lprintf(0, "[error] %s: password too long %s\n", __func__, filename);
86badd32
     exit(1);
   }
   close(f);
 }
 
 static void minit_getopt(int argc, char *argv[])
 {
   int r;
5900834d
   struct option opt[]={
1b4c64d4
     {"chroot",  0, NULL, 'c'},
ab81b188
     {"core",    0, NULL, 'C'},
1b4c64d4
     {"help",    0, NULL, 'h'},
     {"version", 0, NULL, 'V'},
     {0, 0, 0, 0}
5900834d
   };
 
ab81b188
   while((r=getopt_long(argc, argv, "T:R:S:f:u:g:G:d:b:p:m:i:l:U:k:K:VhnsroOcC", opt, NULL)) != -1){
86badd32
     switch(r){
84aa6542
       case 'V':
         version_print();
         exit(0);
 
86badd32
       case 'h':
84aa6542
         usage();
         exit(0);
86badd32
 
1615a78a
       case 'T':
46e655e5
         moption.sendrate = atoi(optarg) * 1024 * 1024 / 8;
1615a78a
         break;
 
d7aa38bf
       case 'R':
0fe1cc19
         moption.recvsize = atoi(optarg);
d7aa38bf
         break;
 
       case 'S':
0fe1cc19
         moption.sendsize = atoi(optarg);
d7aa38bf
         break;
 
abce546a
       case 'f':
         moption.parallel = atoi(optarg);
         if(moption.parallel < 1){
           moption.parallel = 1;
         }
         if(moption.parallel >= MAKUO_PARALLEL_MAX){
           moption.parallel = MAKUO_PARALLEL_MAX - 1;
         }
         break;
 
86badd32
       case 'n':
         moption.dontfork = 1;
         break;
 
       case 's':
         moption.dontsend = 1;
         break;
 
       case 'r':
         moption.dontrecv = 1;
         break;
 
       case 'o':
         moption.comm_ena = 0;
         break;
 
ab81b188
       case 'C':
         moption.core_ena = 1;
         break;
 
86badd32
       case 'c':
         moption.chroot = 1;
         break;
 
       case 'd':
         moption.loglevel = atoi(optarg);
         break;
 
       case 'u':
c2cdbd80
         if(minit_option_setuid(optarg)){
           exit(1);
86badd32
         }
         break;
 
       case 'g':
c2cdbd80
         if(minit_option_setgid(optarg)){
           exit(1);
86badd32
         }
         break;
 
e5b6322e
       case 'G':
c2cdbd80
         if(minit_option_setgids(optarg)){
e5b6322e
           exit(1);
         }
         break;
 
86badd32
       case 'b':
         realpath(optarg, moption.base_dir);
         break;
 
       case 'm':
         moption.maddr.sin_addr.s_addr = inet_addr(optarg);
         break;
 
5900834d
       case 'i':
         moption.iaddr.sin_addr.s_addr = inet_addr(optarg);
         break;
 
86badd32
       case 'l':
         moption.laddr.sin_addr.s_addr = inet_addr(optarg);
         break;
 
       case 'U':
         strcpy(moption.uaddr.sun_path, optarg);
         break;
 
       case 'p':
         moption.laddr.sin_port = htons(atoi(optarg));
         moption.maddr.sin_port = htons(atoi(optarg));
         break;
 
       case 'K':
         moption.commpass = 1;
         minit_password(optarg, 0);
         break;
 
       case 'k':
         moption.cryptena = 1;
         minit_password(optarg, 1);
         break;
 
634a23d7
       case 'O':
         moption.ownmatch = 1;
         break;
5bb20f6d
   
86badd32
       case '?':
         exit(1);
     }
   }
e6a800d5
   log_level = moption.loglevel;
86badd32
 }
 
 static void minit_syslog()
 {
   openlog("makuosan", LOG_NDELAY, LOG_DAEMON);
 }
 
 static void minit_socket()
 {
   int  s;
1b4c64d4
   char lpen  = 0;
   char mttl  = 1;
d7aa38bf
   socklen_t slen;
86badd32
   struct ip_mreq mg;
   struct sockaddr_in addr;
   mg.imr_multiaddr.s_addr = moption.maddr.sin_addr.s_addr;
5900834d
   mg.imr_interface.s_addr = moption.iaddr.sin_addr.s_addr;
86badd32
   addr.sin_family         = AF_INET;
   addr.sin_port           = moption.maddr.sin_port; 
   addr.sin_addr.s_addr    = INADDR_ANY;
 
   s=socket(AF_INET, SOCK_DGRAM, 0);
   if(s == -1){
8f9aeac1
     lprintf(0, "%s: can't create multicast socket\n", __func__);
86badd32
     exit(1);
   }
0fe1cc19
   if(moption.recvsize){
     if(setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void *)&(moption.recvsize), sizeof(moption.recvsize)) == -1){
d7aa38bf
       lprintf(0, "%s: setsockopt SO_RCVBUF error\n", __func__);
       exit(1);
     }
   }
0fe1cc19
   slen=sizeof(moption.recvsize);
   if(getsockopt(s, SOL_SOCKET, SO_RCVBUF, (void *)&(moption.recvsize), &slen) == -1){
     lprintf(0, "%s: getsockopt SO_RCVBUF error\n", __func__);
     exit(1);
   }
153ee7c1
   moption.recvsize /= 2;
0fe1cc19
   if(moption.sendsize){
     if(setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void *)&(moption.sendsize), sizeof(moption.sendsize)) == -1){
d7aa38bf
       lprintf(0, "%s: setsockopt SO_SNDBUF error\n", __func__);
       exit(1);
     }
   }
0fe1cc19
   slen=sizeof(moption.sendsize);
   if(getsockopt(s, SOL_SOCKET, SO_SNDBUF, (void *)&(moption.sendsize), &slen) == -1){
     lprintf(0, "%s: getsockopt SO_SNDBUF error\n", __func__);
     exit(1);
   }
153ee7c1
   moption.sendsize /= 2;
810b92ac
   if(fcntl(s, F_SETFL , O_NONBLOCK)){
     lprintf(0, "%s: fcntl error\n", __func__);
     exit(1);
   }
86badd32
   if(bind(s, (struct sockaddr*)&addr, sizeof(addr)) == -1){
8f9aeac1
     lprintf(0, "%s: bind error\n", __func__);
86badd32
     exit(1);
   }
   if(setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mg, sizeof(mg)) == -1){
8f9aeac1
     lprintf(0, "%s: IP_ADD_MEMBERSHIP error\n", __func__);
86badd32
     exit(1);
   }
   if(setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,   (void *)&mg.imr_interface.s_addr, sizeof(mg.imr_interface.s_addr)) == -1){
8f9aeac1
     lprintf(0, "%s: IP_MULTICAST_IF error\n", __func__);
86badd32
     exit(1);
   }
   if(setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&lpen, sizeof(lpen)) == -1){
8f9aeac1
     lprintf(0, "%s: IP_MULTICAST_LOOP error\n", __func__);
86badd32
     exit(1);
   }
   if(setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,  (void *)&mttl, sizeof(mttl)) == -1){
8f9aeac1
     lprintf(0, "%s: IP_MULTICAST_TTL error\n", __func__);
86badd32
     exit(1);
   }
   moption.mcsocket = s;
 }
 
 static void minit_console()
 {
   int s;
   int reuse = 1;
 
   if(!moption.comm_ena){
     moption.lisocket = -1;
     return;
   }
 
   if(moption.uaddr.sun_path[0]){
     s=socket(AF_UNIX,SOCK_STREAM,0);
     if(!connect(s, (struct sockaddr*)&moption.uaddr, sizeof(moption.uaddr))){
8f9aeac1
       lprintf(0, "%s: can't create %s\n", __func__, moption.uaddr.sun_path);
86badd32
       exit(1);
     }
     close(s);
     unlink(moption.uaddr.sun_path);
     s=socket(AF_UNIX,SOCK_STREAM,0);
     if(s == -1){
8f9aeac1
       lprintf(0, "%s: can't create listen socket\n", __func__);
86badd32
       exit(1);
     }
     if(bind(s, (struct sockaddr*)&moption.uaddr, sizeof(moption.uaddr)) == -1){
8f9aeac1
       lprintf(0, "%s: bind error\n", __func__);
86badd32
       exit(1);
     }
     chmod(moption.uaddr.sun_path , S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
     chown(moption.uaddr.sun_path , moption.uid, moption.gid);
   }else{
     s=socket(AF_INET,SOCK_STREAM,0);
     if(s == -1){
8f9aeac1
       lprintf(0, "%s: can't create listen socket\n", __func__);
86badd32
       exit(1);
     }
     if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse)) == -1){
8f9aeac1
       lprintf(0, "%s: SO_REUSEADDR error\n", __func__);
86badd32
       exit(1);
     }
     if(bind(s, (struct sockaddr*)&moption.laddr, sizeof(moption.laddr)) == -1){
8f9aeac1
       lprintf(0, "%s: bind error\n", __func__);
86badd32
       exit(1);
     }
   }
   if(listen(s,5) == -1){
8f9aeac1
     lprintf(0, "%s: listen error\n", __func__);
86badd32
     exit(1);
   }
   moption.lisocket = s;
 }
 
 static void minit_chdir()
 {
   if(chdir(moption.base_dir) == -1){
8f9aeac1
     lprintf(0, "%s: can't chdir %s\n", __func__,  moption.base_dir);
86badd32
     exit(1);
   }
   getcwd(moption.real_dir, PATH_MAX);
 }
 
 static void minit_chroot()
 {
8f9aeac1
   char tz[256];
86badd32
   if(moption.chroot){
     tzset();
59081d17
     sprintf(tz, "%s%+ld", tzname[0], timezone/3600);
8f9aeac1
     setenv("TZ", tz, 0);
59081d17
     tzset();
86badd32
     if(chroot(moption.base_dir) == -1){
ace75127
       fprintf(stderr, "%s: can't chroot %s\n", __func__, moption.base_dir);
c2cdbd80
       exit(1);
86badd32
     }
   }
   getcwd(moption.base_dir, PATH_MAX);
 }
 
36b9b084
 static void minit_getguid()
86badd32
 {
c2cdbd80
   struct passwd *pw;
   struct group  *gr;
1b4c64d4
   if((pw = getpwuid(moption.uid))){
c2cdbd80
     strcpy(moption.user_name, pw->pw_name);
   }
1b4c64d4
   if((gr = getgrgid(moption.gid))){
c2cdbd80
     strcpy(moption.group_name,gr->gr_name);
   }
36b9b084
 }
 
 static void minit_setguid()
 {
   size_t num;
05348f1d
   if(set_guid(moption.uid, moption.gid, moption.gidn, moption.gids) == -1){
e5b6322e
     fprintf(stderr, "%s: can't setguid %d:%d", __func__, moption.uid, moption.gid);
05348f1d
     if(moption.gidn){
       for(num=0;num<moption.gidn;num++){
e5b6322e
         fprintf(stderr, ",%d", moption.gids[num]);
       }
     }
     fprintf(stderr, "\n");
c2cdbd80
     exit(1);
86badd32
   }
12b02b9d
 }
 
 static void minit_enable_core()
 {
ab81b188
   struct rlimit r = {0, 0};
12b02b9d
   if(getrlimit(RLIMIT_CORE, &r) == -1){
     fprintf(stderr, "%s: getrlimit error: %s\n", __func__, strerror(errno));
     exit(1);
   }
ab81b188
   moption.coresize = (int)(r.rlim_cur);
   if(!moption.core_ena){
     return;
   }
 #ifdef HAVE_SYS_PRCTL_H
   if(prctl(PR_SET_DUMPABLE, 1) == -1){
     fprintf(stderr, "%s: prctl error: %s\n", __func__, strerror(errno));
   }
 #endif
   r.rlim_cur = r.rlim_max;
12b02b9d
   if(setrlimit(RLIMIT_CORE, &r) == -1){
     fprintf(stderr, "%s: setrlimit error: %s\n", __func__, strerror(errno));
     exit(1);
   }
   r.rlim_cur = 0;
   r.rlim_max = 0;
   if(getrlimit(RLIMIT_CORE, &r) == -1){
     fprintf(stderr, "%s: getrlimit error: %s\n", __func__, strerror(errno));
     exit(1);
   }
   moption.coresize = (int)(r.rlim_cur);
86badd32
 }
 
 static void minit_daemonize()
 {
   int pid;
36959136
   if(moption.dontfork){
     lprintf(0, "pid       : %d\n", getpid());
86badd32
     return;
36959136
   }
86badd32
 
   pid = fork();
   if(pid == -1){
ace75127
     fprintf(stderr, "%s: can't fork()\n", __func__);
86badd32
     exit(1); 
   }
   if(pid)
     _exit(0);
   setsid();
   pid=fork();
   if(pid == -1){
ace75127
     fprintf(stderr, "%s: can't fork()\n", __func__);
86badd32
     exit(1); 
   }
36959136
   if(pid){
     lprintf(0, "pid       : %d\n",pid);
86badd32
     _exit(0);
36959136
   }
86badd32
 
   /*----- daemon process -----*/
   close(2);
   close(1);
   close(0);
   open("/dev/null",O_RDWR); /* new stdin  */
   dup(0);                   /* new stdout */
   dup(0);                   /* new stderr */
 }
 
 static void minit_bootlog()
 {
e5b6322e
   int i;
751c3d2a
 
c510892b
   lprintf(0, "makuosan version %s\n", PACKAGE_VERSION);
efce2c7f
   lprintf(0, "sysname   : %s\n", moption.uts.sysname);
dbdc4e5a
   lprintf(0, "loglevel  : %d\n", moption.loglevel);
ab81b188
   if(moption.coresize == (int)RLIM_INFINITY){
09c0d8c1
     lprintf(0, "coresize  : unlimited\n");
   }else{
     lprintf(0, "coresize  : %d\n", moption.coresize);
   }
e5b6322e
   if(moption.chroot){
     lprintf(0, "chroot    : %s\n", moption.real_dir);
   }else{
     lprintf(0, "base dir  : %s\n", moption.base_dir);
   }
dbdc4e5a
   lprintf(0, "multicast : %s\n", inet_ntoa(moption.maddr.sin_addr));
5900834d
   lprintf(0, "interface : %s\n", inet_ntoa(moption.iaddr.sin_addr));
dbdc4e5a
   lprintf(0, "port      : %d\n", ntohs(moption.maddr.sin_port));
36b9b084
   lprintf(0, "uid       : %d(%s)\n", moption.uid, moption.user_name);
38605fc1
   lprintf(0, "gid       : %d(%s)"  , moption.gid, moption.group_name);
e5b6322e
   if(moption.gids){
c2cdbd80
     for(i=0;i<moption.gidn;i++){
38605fc1
       lprintf(0, ", %d(%s)", moption.gids[i], moption.grnames[i]);
e5b6322e
     }
   }
38605fc1
   lprintf(0, "\n");
0fe1cc19
   lprintf(0, "rcvbuf    : %d\n", moption.recvsize);
   lprintf(0, "sndbuf    : %d\n", moption.sendsize);
dbdc4e5a
   lprintf(0, "parallel  : %d\n", moption.parallel);
38605fc1
   lprintf(0, "don't recv: %s\n", yesno(moption.dontrecv));
   lprintf(0, "don't send: %s\n", yesno(moption.dontsend));
   lprintf(0, "don't fork: %s\n", yesno(moption.dontfork));
   lprintf(0, "encrypt   : %s\n", yesno(moption.cryptena));
   lprintf(0, "console   : %s\n", yesno(moption.comm_ena));
   lprintf(0, "passwoed  : %s\n", yesno(moption.commpass));
   lprintf(0, "ownermatch: %s\n", yesno(moption.ownmatch));
1615a78a
   if(moption.sendrate){
46e655e5
     lprintf(0, "rate      : %d[Mbps]\n", moption.sendrate * 8 / 1024 / 1024);
1615a78a
   }
86badd32
   if(moption.comm_ena){
     if(moption.uaddr.sun_path[0]){
       lprintf(0,"listen    : %s\n", moption.uaddr.sun_path);
     }else{
       lprintf(0,"listen    : %s\n", inet_ntoa(moption.laddr.sin_addr));
     }
   }
 }
 
 /*
  *  まくお初期化関数
8120e18c
  *  mainから呼び出される
86badd32
  */
 void minit(int argc, char *argv[])
 {
ace75127
   if(argc == 1){
e5b6322e
     usage(); /* and exit */
   }
   minit_option_setdefault(); /* 各オプションのデフォルト値を設定   */
   minit_option_getenv();     /* 環境変数からオプションを読み込む   */
   minit_getopt(argc, argv);  /* コマンドラインオプションを読み込む */
   minit_syslog();            /* syslogの使用を開始                 */
   minit_socket();            /* マルチキャストソケットの初期化     */
   minit_console();           /* コンソールソケットの初期化         */
   minit_signal();            /* シグナルハンドラを設定             */
   minit_chdir();             /* カレントディレクトリを変更         */
36b9b084
   minit_getguid();           /*                                    */
e5b6322e
   minit_chroot();            /*                                    */
   minit_setguid();           /*                                    */
66158b71
   minit_enable_core();       /* コアサイズのリミットを解除         */
e5b6322e
   minit_bootlog();           /* ブートメッセージを出力する         */
   minit_daemonize();         /*                                    */
86badd32
 }
efce2c7f