int topology_parseline(char *line,uint32_t lineno,uint32_t *fip,uint32_t *tip,uint32_t *rid) { char *net; char *p; p = line; while (*p==' ' || *p=='\t') { p++; } if (*p=='#' || *p==0 || *p=='\r' || *p=='\n') { return -1; } net = p; while (*p && *p!=' ' && *p!='\t') { p++; } if (*p==0 || *p=='\r' || *p=='\n') { mfs_arg_syslog(LOG_WARNING,"mfstopology: incomplete definition in line: %"PRIu32,lineno); fprintf(stderr,"mfstopology: incomplete definition in line: %"PRIu32"\n",lineno); return -1; } *p=0; p++; if (topology_parsenet(net,fip,tip)<0) { mfs_arg_syslog(LOG_WARNING,"mfstopology: incorrect ip/network definition in line: %"PRIu32,lineno); fprintf(stderr,"mfstopology: incorrect ip/network definition in line: %"PRIu32"\n",lineno); return -1; } while (*p==' ' || *p=='\t') { p++; } if (*p<'0' || *p>'9') { mfs_arg_syslog(LOG_WARNING,"mfstopology: incorrect rack id in line: %"PRIu32,lineno); fprintf(stderr,"mfstopology: incorrect rack id in line: %"PRIu32"\n",lineno); return -1; } *rid = strtoul(p,&p,10); while (*p==' ' || *p=='\t') { p++; } if (*p && *p!='\r' && *p!='\n' && *p!='#') { mfs_arg_syslog(LOG_WARNING,"mfstopology: garbage found at the end of line: %"PRIu32,lineno); fprintf(stderr,"mfstopology: garbage found at the end of line: %"PRIu32"\n",lineno); return -1; } return 0; }
void matomlserv_reload(void) { char *oldListenHost,*oldListenPort; int newlsock; oldListenHost = ListenHost; oldListenPort = ListenPort; ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*"); ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419"); if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) { free(oldListenHost); free(oldListenPort); mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort); return; } newlsock = tcpsocket(); if (newlsock<0) { mfs_errlog(LOG_WARNING,"master <-> metaloggers module: socket address has changed, but can't create new socket"); free(ListenHost); free(ListenPort); ListenHost = oldListenHost; ListenPort = oldListenPort; return; } tcpnonblock(newlsock); tcpnodelay(newlsock); tcpreuseaddr(newlsock); if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) { mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter"); } if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) { mfs_arg_errlog(LOG_ERR,"master <-> metaloggers module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort); free(ListenHost); free(ListenPort); ListenHost = oldListenHost; ListenPort = oldListenPort; tcpclose(newlsock); return; } mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort); free(oldListenHost); free(oldListenPort); tcpclose(lsock); lsock = newlsock; ChangelogSecondsToRemember = cfg_getuint16("MATOML_LOG_PRESERVE_SECONDS",600); if (ChangelogSecondsToRemember>3600) { syslog(LOG_WARNING,"Number of seconds of change logs to be preserved in master is too big (%"PRIu16") - decreasing to 3600 seconds",ChangelogSecondsToRemember); ChangelogSecondsToRemember=3600; } }
int matomlserv_init(void) { ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*"); ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419"); lsock = tcpsocket(); if (lsock<0) { mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't create socket"); return -1; } tcpnonblock(lsock); tcpnodelay(lsock); tcpreuseaddr(lsock); if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) { mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter"); } if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) { mfs_arg_errlog(LOG_ERR,"master <-> metaloggers module: can't listen on %s:%s",ListenHost,ListenPort); return -1; } mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: listen on %s:%s",ListenHost,ListenPort); matomlservhead = NULL; ChangelogSecondsToRemember = cfg_getuint16("MATOML_LOG_PRESERVE_SECONDS",600); if (ChangelogSecondsToRemember>3600) { syslog(LOG_WARNING,"Number of seconds of change logs to be preserved in master is too big (%"PRIu16") - decreasing to 3600 seconds",ChangelogSecondsToRemember); ChangelogSecondsToRemember=3600; } main_reloadregister(matomlserv_reload); main_destructregister(matomlserv_term); main_canexitregister(matomlserv_canexit); main_pollregister(matomlserv_desc,matomlserv_serve); main_timeregister(TIMEMODE_SKIP_LATE,3600,0,matomlserv_status); return 0; }
int matomlserv_init(void) { ListenHost = cfg_getstr("MATOML_LISTEN_HOST","*"); ListenPort = cfg_getstr("MATOML_LISTEN_PORT","9419"); lsock = tcpsocket(); if (lsock<0) { mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't create socket"); return -1; } tcpnonblock(lsock); tcpnodelay(lsock); tcpreuseaddr(lsock); if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) { mfs_errlog_silent(LOG_NOTICE,"master <-> metaloggers module: can't set accept filter"); } if (tcpstrlisten(lsock,ListenHost,ListenPort,100)<0) { mfs_errlog(LOG_ERR,"master <-> metaloggers module: can't listen on socket"); return -1; } mfs_arg_syslog(LOG_NOTICE,"master <-> metaloggers module: listen on %s:%s",ListenHost,ListenPort); matomlservhead = NULL; main_reloadregister(matomlserv_reload); main_destructregister(matomlserv_term); main_pollregister(matomlserv_desc,matomlserv_serve); main_timeregister(TIMEMODE_SKIP_LATE,3600,0,matomlserv_status); return 0; }
int csserv_init(void) { ListenHost = cfg_getstr("CSSERV_LISTEN_HOST","*"); ListenPort = cfg_getstr("CSSERV_LISTEN_PORT",DEFAULT_CS_DATA_PORT); lsock = tcpsocket(); if (lsock<0) { mfs_errlog(LOG_ERR,"main server module: can't create socket"); return -1; } tcpnonblock(lsock); tcpnodelay(lsock); tcpreuseaddr(lsock); tcpresolve(ListenHost,ListenPort,&mylistenip,&mylistenport,1); if (tcpnumlisten(lsock,mylistenip,mylistenport,100)<0) { mfs_errlog(LOG_ERR,"main server module: can't listen on socket"); return -1; } if (tcpsetacceptfilter(lsock)<0 && errno!=ENOTSUP) { mfs_errlog_silent(LOG_NOTICE,"main server module: can't set accept filter"); } mfs_arg_syslog(LOG_NOTICE,"main server module: listen on %s:%s",ListenHost,ListenPort); csservhead = NULL; main_reload_register(csserv_reload); main_destruct_register(csserv_term); main_poll_register(csserv_desc,csserv_serve); return 0; }
void csserv_reload(void) { char *oldListenHost,*oldListenPort; int newlsock; // ThreadedServer = 1-ThreadedServer; oldListenHost = ListenHost; oldListenPort = ListenPort; ListenHost = cfg_getstr("CSSERV_LISTEN_HOST","*"); ListenPort = cfg_getstr("CSSERV_LISTEN_PORT",DEFAULT_CS_DATA_PORT); if (strcmp(oldListenHost,ListenHost)==0 && strcmp(oldListenPort,ListenPort)==0) { free(oldListenHost); free(oldListenPort); mfs_arg_syslog(LOG_NOTICE,"main server module: socket address hasn't changed (%s:%s)",ListenHost,ListenPort); return; } newlsock = tcpsocket(); if (newlsock<0) { mfs_errlog(LOG_WARNING,"main server module: socket address has changed, but can't create new socket"); free(ListenHost); free(ListenPort); ListenHost = oldListenHost; ListenPort = oldListenPort; return; } tcpnonblock(newlsock); tcpnodelay(newlsock); tcpreuseaddr(newlsock); if (tcpstrlisten(newlsock,ListenHost,ListenPort,100)<0) { mfs_arg_errlog(LOG_ERR,"main server module: socket address has changed, but can't listen on socket (%s:%s)",ListenHost,ListenPort); free(ListenHost); free(ListenPort); ListenHost = oldListenHost; ListenPort = oldListenPort; tcpclose(newlsock); return; } if (tcpsetacceptfilter(newlsock)<0 && errno!=ENOTSUP) { mfs_errlog_silent(LOG_NOTICE,"main server module: can't set accept filter"); } mfs_arg_syslog(LOG_NOTICE,"main server module: socket address has changed, now listen on %s:%s",ListenHost,ListenPort); free(oldListenHost); free(oldListenPort); tcpclose(lsock); lsock = newlsock; }
int masterconn_initconnect(masterconn *eptr) { int status; if (eptr->masteraddrvalid==0) { uint32_t mip,bip; uint16_t mport; if (tcpresolve(BindHost,NULL,&bip,NULL,1)<0) { bip = 0; } eptr->bindip = bip; if (tcpresolve(MasterHost,MasterPort,&mip,&mport,0)>=0) { eptr->masterip = mip; eptr->masterport = mport; eptr->masteraddrvalid = 1; } else { mfs_arg_syslog(LOG_WARNING,"can't resolve master host/port (%s:%s)",MasterHost,MasterPort); return -1; } } eptr->sock=tcpsocket(); if (eptr->sock<0) { mfs_errlog(LOG_WARNING,"create socket, error"); return -1; } if (tcpnonblock(eptr->sock)<0) { mfs_errlog(LOG_WARNING,"set nonblock, error"); tcpclose(eptr->sock); eptr->sock = -1; return -1; } if (eptr->bindip>0) { if (tcpnumbind(eptr->sock,eptr->bindip,0)<0) { mfs_errlog(LOG_WARNING,"can't bind socket to given ip"); tcpclose(eptr->sock); eptr->sock = -1; return -1; } } status = tcpnumconnect(eptr->sock,eptr->masterip,eptr->masterport); if (status<0) { mfs_errlog(LOG_WARNING,"connect failed, error"); tcpclose(eptr->sock); eptr->sock = -1; eptr->masteraddrvalid = 0; return -1; } if (status==0) { syslog(LOG_NOTICE,"connected to Master immediately"); masterconn_connected(eptr); } else { eptr->mode = CONNECTING; eptr->conntime = monotonic_seconds(); syslog(LOG_NOTICE,"connecting ..."); } return 0; }
int initialize(void) { uint32_t i; int ok; ok = 1; for (i=0 ; (long int)(RunTab[i].fn)!=0 && ok ; i++) { now = time(NULL); if (RunTab[i].fn()<0) { mfs_arg_syslog(LOG_ERR,"init: %s failed !!!",RunTab[i].name); ok=0; } } return ok; }
void createpath(const char *filename) { char pathbuff[1024]; const char *src = filename; char *dst = pathbuff; if (*src=='/') *dst++=*src++; while (*src) { while (*src!='/' && *src) { *dst++=*src++; } if (*src=='/') { *dst='\0'; if (mkdir(pathbuff,(mode_t)0777)<0) { if (errno!=EEXIST) { mfs_arg_errlog(LOG_NOTICE,"creating directory %s",pathbuff); } } else { mfs_arg_syslog(LOG_NOTICE,"directory %s has been created",pathbuff); } *dst++=*src++; } } }
int main(int argc,char **argv) { char *logappname; // char *lockfname; char *wrkdir; char *cfgfile; char *appname; int ch; uint8_t runmode; int rundaemon,logundefined; int lockmemory; int32_t nicelevel; uint32_t locktimeout; int fd; uint8_t movewarning; struct rlimit rls; strerr_init(); mycrc32_init(); movewarning = 0; cfgfile=strdup(ETC_PATH "/mfs/" STR(APPNAME) ".cfg"); passert(cfgfile); if ((fd = open(cfgfile,O_RDONLY))<0 && errno==ENOENT) { free(cfgfile); cfgfile=strdup(ETC_PATH "/" STR(APPNAME) ".cfg"); passert(cfgfile); if ((fd = open(cfgfile,O_RDONLY))>=0) { movewarning = 1; } } if (fd>=0) { close(fd); } locktimeout = 1800; rundaemon = 1; runmode = RM_RESTART; logundefined = 0; lockmemory = 0; appname = argv[0]; while ((ch = getopt(argc, argv, "uvdfsc:t:h?")) != -1) { switch(ch) { case 'v': printf("version: %u.%u.%u\n",VERSMAJ,VERSMID,VERSMIN); return 0; case 'd': rundaemon=0; break; case 'f': runmode=RM_START; break; case 's': runmode=RM_STOP; break; case 't': locktimeout=strtoul(optarg,NULL,10); break; case 'c': free(cfgfile); cfgfile = strdup(optarg); passert(cfgfile); movewarning = 0; break; case 'u': logundefined=1; break; default: usage(appname); return 1; } } argc -= optind; argv += optind; if (argc==1) { if (strcasecmp(argv[0],"start")==0) { runmode = RM_START; } else if (strcasecmp(argv[0],"stop")==0) { runmode = RM_STOP; } else if (strcasecmp(argv[0],"restart")==0) { runmode = RM_RESTART; } else if (strcasecmp(argv[0],"reload")==0) { runmode = RM_RELOAD; } else if (strcasecmp(argv[0],"test")==0) { runmode = RM_TEST; } else if (strcasecmp(argv[0],"kill")==0) { runmode = RM_KILL; } else { usage(appname); return 1; } } else if (argc!=0) { usage(appname); return 1; } if (movewarning) { mfs_syslog(LOG_WARNING,"default sysconf path has changed - please move " STR(APPNAME) ".cfg from "ETC_PATH"/ to "ETC_PATH"/mfs/"); } if ((runmode==RM_START || runmode==RM_RESTART) && rundaemon) { makedaemon(); } else { if (runmode==RM_START || runmode==RM_RESTART) { set_signal_handlers(0); } } if (cfg_load(cfgfile,logundefined)==0) { fprintf(stderr,"can't load config file: %s - using defaults\n",cfgfile); } free(cfgfile); logappname = cfg_getstr("SYSLOG_IDENT",STR(APPNAME)); if (rundaemon) { if (logappname[0]) { openlog(logappname, LOG_PID | LOG_NDELAY , LOG_DAEMON); } else { openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON); } } else { #if defined(LOG_PERROR) if (logappname[0]) { openlog(logappname, LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER); } else { openlog(STR(APPNAME), LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER); } #else if (logappname[0]) { openlog(logappname, LOG_PID | LOG_NDELAY, LOG_USER); } else { openlog(STR(APPNAME), LOG_PID | LOG_NDELAY, LOG_USER); } #endif } if (runmode==RM_START || runmode==RM_RESTART) { rls.rlim_cur = MFSMAXFILES; rls.rlim_max = MFSMAXFILES; if (setrlimit(RLIMIT_NOFILE,&rls)<0) { syslog(LOG_NOTICE,"can't change open files limit to %u",MFSMAXFILES); } lockmemory = cfg_getnum("LOCK_MEMORY",0); #ifdef MFS_USE_MEMLOCK if (lockmemory) { rls.rlim_cur = RLIM_INFINITY; rls.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_MEMLOCK,&rls); } #endif nicelevel = cfg_getint32("NICE_LEVEL",-19); setpriority(PRIO_PROCESS,getpid(),nicelevel); } changeugid(); wrkdir = cfg_getstr("DATA_PATH",DATA_PATH); if (runmode==RM_START || runmode==RM_RESTART) { fprintf(stderr,"working directory: %s\n",wrkdir); } if (chdir(wrkdir)<0) { mfs_arg_syslog(LOG_ERR,"can't set working directory to %s",wrkdir); if (rundaemon) { fputc(0,stderr); close_msg_channel(); } closelog(); free(logappname); return 1; } free(wrkdir); umask(cfg_getuint32("FILE_UMASK",027)&077); /* for upgrading from previous versions of MFS */ if (check_old_locks(runmode,locktimeout)<0) { if (rundaemon) { fputc(0,stderr); close_msg_channel(); } closelog(); free(logappname); wdunlock(); return 1; } if (wdlock(runmode,locktimeout)<0) { if (rundaemon) { fputc(0,stderr); close_msg_channel(); } closelog(); free(logappname); wdunlock(); return 1; } remove_old_wdlock(); if (runmode==RM_STOP || runmode==RM_KILL || runmode==RM_RELOAD || runmode==RM_TEST) { if (rundaemon) { close_msg_channel(); } closelog(); free(logappname); wdunlock(); return 0; } #ifdef MFS_USE_MEMLOCK if (lockmemory) { if (getrlimit(RLIMIT_MEMLOCK,&rls)<0) { mfs_errlog(LOG_WARNING,"error getting memory lock limits"); } else { if (rls.rlim_cur!=RLIM_INFINITY && rls.rlim_max==RLIM_INFINITY) { rls.rlim_cur = RLIM_INFINITY; rls.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_MEMLOCK,&rls)<0) { mfs_errlog(LOG_WARNING,"error setting memory lock limit to unlimited"); } } if (getrlimit(RLIMIT_MEMLOCK,&rls)<0) { mfs_errlog(LOG_WARNING,"error getting memory lock limits"); } else { if (rls.rlim_cur!=RLIM_INFINITY) { mfs_errlog(LOG_WARNING,"can't set memory lock limit to unlimited"); } else { if (mlockall(MCL_CURRENT|MCL_FUTURE)<0) { mfs_errlog(LOG_WARNING,"memory lock error"); } else { mfs_syslog(LOG_NOTICE,"process memory was successfully locked in RAM"); } } } } } #else if (lockmemory) { mfs_syslog(LOG_WARNING,"memory lock not supported !!!"); } #endif fprintf(stderr,"initializing %s modules ...\n",logappname); if (initialize()) { if (getrlimit(RLIMIT_NOFILE,&rls)==0) { syslog(LOG_NOTICE,"open files limit: %lu",(unsigned long)(rls.rlim_cur)); } fprintf(stderr,"%s daemon initialized properly\n",logappname); if (rundaemon) { close_msg_channel(); } if (initialize_late()) { mainloop(); ch=0; } else { ch=1; } } else { fprintf(stderr,"error occured during initialization - exiting\n"); if (rundaemon) { fputc(0,stderr); close_msg_channel(); } ch=1; } destruct(); free_all_registered_entries(); signal_cleanup(); cfg_term(); strerr_term(); closelog(); free(logappname); wdunlock(); return ch; }
int check_old_locks(uint8_t runmode,uint32_t timeout) { char str[13]; uint32_t l; pid_t ptk; char *lockfname; lockfname = cfg_getstr("LOCK_FILE",RUN_PATH "/" STR(APPNAME) ".lock"); lfd=open(lockfname,O_RDWR); if (lfd<0) { if (errno==ENOENT) { // no old lock file free(lockfname); return 0; // ok } mfs_arg_errlog(LOG_ERR,"open %s error",lockfname); free(lockfname); return -1; } if (lockf(lfd,F_TLOCK,0)<0) { if (errno!=EAGAIN) { mfs_arg_errlog(LOG_ERR,"lock %s error",lockfname); free(lockfname); return -1; } if (runmode==RM_START) { mfs_syslog(LOG_ERR,"old lockfile is locked - can't start"); free(lockfname); return -1; } if (runmode==RM_STOP || runmode==RM_KILL || runmode==RM_RESTART) { fprintf(stderr,"old lockfile found - trying to kill previous instance using data from old lockfile\n"); } else if (runmode==RM_RELOAD) { fprintf(stderr,"old lockfile found - sending reload signal using data from old lockfile\n"); } l=read(lfd,str,13); if (l==0 || l>=13) { mfs_arg_syslog(LOG_ERR,"wrong pid in old lockfile %s",lockfname); free(lockfname); return -1; } str[l]=0; ptk = strtol(str,NULL,10); if (runmode==RM_RELOAD) { if (kill(ptk,SIGHUP)<0) { mfs_errlog(LOG_WARNING,"can't send reload signal"); free(lockfname); return -1; } fprintf(stderr,"reload signal has beed sent\n"); return 0; } if (runmode==RM_KILL) { fprintf(stderr,"sending SIGKILL to previous instance (pid:%ld)\n",(long int)ptk); if (kill(ptk,SIGKILL)<0) { mfs_errlog(LOG_WARNING,"can't kill previous process"); free(lockfname); return -1; } } else { fprintf(stderr,"sending SIGTERM to previous instance (pid:%ld)\n",(long int)ptk); if (kill(ptk,SIGTERM)<0) { mfs_errlog(LOG_WARNING,"can't kill previous process"); free(lockfname); return -1; } } l=0; fprintf(stderr,"waiting for termination ...\n"); while (lockf(lfd,F_TLOCK,0)<0) { if (errno!=EAGAIN) { mfs_arg_errlog(LOG_ERR,"lock %s error",lockfname); free(lockfname); return -1; } sleep(1); l++; if (l>=timeout) { mfs_arg_syslog(LOG_ERR,"about %"PRIu32" seconds passed and old lockfile is still locked - giving up",l); free(lockfname); return -1; } if (l%10==0) { mfs_arg_syslog(LOG_WARNING,"about %"PRIu32" seconds passed and old lockfile is still locked",l); } } fprintf(stderr,"terminated\n"); } else { fprintf(stderr,"found unlocked old lockfile\n"); if (runmode==RM_RELOAD) { fprintf(stderr,"can't obtain process id using old lockfile\n"); return 0; } } fprintf(stderr,"removing old lockfile\n"); close(lfd); unlink(lockfname); free(lockfname); return 0; }
void changeugid(void) { char pwdgrpbuff[16384]; struct passwd pwd,*pw; struct group grp,*gr; char *wuser; char *wgroup; uid_t wrk_uid; gid_t wrk_gid; int gidok; if (geteuid()==0) { wuser = cfg_getstr("WORKING_USER",DEFAULT_USER); wgroup = cfg_getstr("WORKING_GROUP",DEFAULT_GROUP); gidok = 0; wrk_gid = -1; if (wgroup[0]=='#') { wrk_gid = strtol(wgroup+1,NULL,10); gidok = 1; } else if (wgroup[0]) { getgrnam_r(wgroup,&grp,pwdgrpbuff,16384,&gr); if (gr==NULL) { mfs_arg_syslog(LOG_WARNING,"%s: no such group !!!",wgroup); exit(1); } else { wrk_gid = gr->gr_gid; gidok = 1; } } if (wuser[0]=='#') { wrk_uid = strtol(wuser+1,NULL,10); if (gidok==0) { getpwuid_r(wrk_uid,&pwd,pwdgrpbuff,16384,&pw); if (pw==NULL) { mfs_arg_syslog(LOG_ERR,"%s: no such user id - can't obtain group id",wuser+1); exit(1); } wrk_gid = pw->pw_gid; } } else { getpwnam_r(wuser,&pwd,pwdgrpbuff,16384,&pw); if (pw==NULL) { mfs_arg_syslog(LOG_ERR,"%s: no such user !!!",wuser); exit(1); } wrk_uid = pw->pw_uid; if (gidok==0) { wrk_gid = pw->pw_gid; } } free(wuser); free(wgroup); if (setgid(wrk_gid)<0) { mfs_arg_errlog(LOG_ERR,"can't set gid to %d",(int)wrk_gid); exit(1); } else { syslog(LOG_NOTICE,"set gid to %d",(int)wrk_gid); } if (setuid(wrk_uid)<0) { mfs_arg_errlog(LOG_ERR,"can't set uid to %d",(int)wrk_uid); exit(1); } else { syslog(LOG_NOTICE,"set uid to %d",(int)wrk_uid); } } }
int sclass_load(bio *fd,uint8_t mver,int ignoreflag) { uint8_t *databuff = NULL; const uint8_t *ptr; uint32_t labelmask; uint32_t chunkcount; uint16_t sclassid; uint16_t arch_delay; uint8_t create_mode; uint8_t create_labelscnt; uint8_t keep_labelscnt; uint8_t arch_labelscnt; uint8_t descrleng; uint8_t nleng; uint8_t admin_only; uint8_t name[MAXSCLASSNLENG]; uint8_t i,j; uint8_t orgroup; uint8_t hdrleng; if (mver<0x16) { // skip label descriptions for (i=0 ; i<26 ; i++) { if (bio_read(fd,&descrleng,1)!=1) { int err = errno; fputc('\n',stderr); errno = err; mfs_errlog(LOG_ERR,"loading storage class data: read error"); return -1; } if (descrleng>128) { mfs_syslog(LOG_ERR,"loading storage class data: description too long"); return -1; } bio_skip(fd,descrleng); } } if (mver==0x10) { orgroup = 1; } else { if (bio_read(fd,&orgroup,1)!=1) { int err = errno; fputc('\n',stderr); errno = err; mfs_errlog(LOG_ERR,"loading storage class: read error"); return -1; } if (orgroup>MASKORGROUP) { if (ignoreflag) { mfs_syslog(LOG_ERR,"loading storage class data: too many or-groups - ignore"); } else { mfs_syslog(LOG_ERR,"loading storage class data: too many or-groups"); return -1; } } } if (orgroup<1) { mfs_syslog(LOG_ERR,"loading storage class data: zero or-groups !!!"); return -1; } databuff = malloc(3U*9U*4U*(uint32_t)orgroup); passert(databuff); hdrleng = (mver==0x12)?11:(mver<=0x13)?3:(mver<=0x14)?5:(mver<=0x15)?8:10; while (1) { if (bio_read(fd,databuff,hdrleng)!=hdrleng) { int err = errno; fputc('\n',stderr); errno = err; mfs_errlog(LOG_ERR,"loading storage class data: read error"); free(databuff); databuff=NULL; return -1; } ptr = databuff; sclassid = get16bit(&ptr); if (mver>0x15) { nleng = get8bit(&ptr); admin_only = get8bit(&ptr); create_mode = get8bit(&ptr); arch_delay = get16bit(&ptr); create_labelscnt = get8bit(&ptr); keep_labelscnt = get8bit(&ptr); arch_labelscnt = get8bit(&ptr); chunkcount = 0; } else if (mver>0x14) { nleng = 0; admin_only = 0; create_mode = get8bit(&ptr); arch_delay = get16bit(&ptr); create_labelscnt = get8bit(&ptr); keep_labelscnt = get8bit(&ptr); arch_labelscnt = get8bit(&ptr); chunkcount = 0; } else if (mver>0x13) { nleng = 0; admin_only = 0; create_mode = get8bit(&ptr); create_labelscnt = get8bit(&ptr); keep_labelscnt = get8bit(&ptr); arch_labelscnt = keep_labelscnt; arch_delay = 0; chunkcount = 0; } else { nleng = 0; admin_only = 0; create_labelscnt = get8bit(&ptr); keep_labelscnt = create_labelscnt; arch_labelscnt = create_labelscnt; create_mode = CREATE_MODE_STD; arch_delay = 0; if (mver==0x12) { chunkcount = get32bit(&ptr); ptr+=4; } else { chunkcount = 0; } } if (nleng==0) { if (sclassid>=FIRSTSCLASSID) { nleng = snprintf((char*)name,MAXSCLASSNLENG,"sclass_%"PRIu32,(uint32_t)(sclassid+1-FIRSTSCLASSID)); } else { nleng = 0; } } else { if (bio_read(fd,name,nleng)!=nleng) { int err = errno; fputc('\n',stderr); errno = err; mfs_errlog(LOG_ERR,"loading storage class data: read error"); free(databuff); databuff=NULL; return -1; } } if (sclassid==0 && create_labelscnt==0 && keep_labelscnt==0 && arch_labelscnt==0 && chunkcount==0 && arch_delay==0) { break; } if (create_labelscnt==0 || create_labelscnt>MAXLABELSCNT || keep_labelscnt==0 || keep_labelscnt>MAXLABELSCNT || arch_labelscnt==0 || arch_labelscnt>MAXLABELSCNT) { mfs_arg_syslog(LOG_ERR,"loading storage class data: data format error (sclassid: %"PRIu16" ; create_mode: %"PRIu8" ; create_labelscnt: %"PRIu8" ; keep_labelscnt: %"PRIu8" ; arch_labelscnt: %"PRIu8" ; arch_delay: %"PRIu16")",sclassid,create_mode,create_labelscnt,keep_labelscnt,arch_labelscnt,arch_delay); free(databuff); databuff = NULL; return -1; } if (sclassid==0 || sclassid>=MAXSCLASS || nleng==0) { if (ignoreflag) { mfs_arg_syslog(LOG_ERR,"loading storage class data: bad sclassid (%"PRIu16") - ignore",sclassid); if (mver>0x14) { bio_skip(fd,(create_labelscnt+keep_labelscnt+arch_labelscnt)*4*orgroup); } else if (mver>0x13) { bio_skip(fd,(create_labelscnt+keep_labelscnt)*4*orgroup); } else { bio_skip(fd,(create_labelscnt)*4*orgroup); } continue; } else { mfs_arg_syslog(LOG_ERR,"loading storage class data: bad sclassid (%"PRIu16")",sclassid); free(databuff); databuff=NULL; return -1; } } if (mver>0x14) { if (bio_read(fd,databuff,(create_labelscnt+keep_labelscnt+arch_labelscnt)*4*orgroup)!=(create_labelscnt+keep_labelscnt+arch_labelscnt)*4*orgroup) { int err = errno; fputc('\n',stderr); errno = err; mfs_errlog(LOG_ERR,"loading storage class data: read error"); free(databuff); databuff=NULL; return -1; } } else if (mver>0x13) { if (bio_read(fd,databuff,(create_labelscnt+keep_labelscnt)*4*orgroup)!=(create_labelscnt+keep_labelscnt)*4*orgroup) { int err = errno; fputc('\n',stderr); errno = err; mfs_errlog(LOG_ERR,"loading storage class data: read error"); free(databuff); databuff=NULL; return -1; } } else { if (bio_read(fd,databuff,create_labelscnt*4*orgroup)!=create_labelscnt*4*orgroup) { int err = errno; fputc('\n',stderr); errno = err; mfs_errlog(LOG_ERR,"loading storage class data: read error"); free(databuff); databuff=NULL; return -1; } } if (sclassid>=FIRSTSCLASSID && sclasstab[sclassid].nleng>0) { if (ignoreflag) { mfs_syslog(LOG_ERR,"loading storage class data: repeated sclassid - ignore"); if (chunkcount>0) { bio_skip(fd,chunkcount*8); } continue; } else { mfs_syslog(LOG_ERR,"loading storage class data: repeated sclassid"); free(databuff); databuff=NULL; return -1; } } ptr = databuff; for (i=0 ; i<create_labelscnt ; i++) { for (j=0 ; j<MASKORGROUP ; j++) { if (j<orgroup) { labelmask = get32bit(&ptr); } else { labelmask = 0; } sclasstab[sclassid].create_labelmasks[i][j] = labelmask; } } for (i=0 ; i<keep_labelscnt ; i++) { for (j=0 ; j<MASKORGROUP ; j++) { if (mver>0x13) { if (j<orgroup) { labelmask = get32bit(&ptr); } else { labelmask = 0; } } else { labelmask = sclasstab[sclassid].create_labelmasks[i][j]; } sclasstab[sclassid].keep_labelmasks[i][j] = labelmask; } } for (i=0 ; i<arch_labelscnt ; i++) { for (j=0 ; j<MASKORGROUP ; j++) { if (mver>0x14) { if (j<orgroup) { labelmask = get32bit(&ptr); } else { labelmask = 0; } } else { labelmask = sclasstab[sclassid].keep_labelmasks[i][j]; } sclasstab[sclassid].arch_labelmasks[i][j] = labelmask; } } sclasstab[sclassid].create_mode = create_mode; sclasstab[sclassid].arch_delay = arch_delay; sclasstab[sclassid].create_labelscnt = create_labelscnt; sclasstab[sclassid].keep_labelscnt = keep_labelscnt; sclasstab[sclassid].arch_labelscnt = arch_labelscnt; sclasstab[sclassid].admin_only = admin_only; sclasstab[sclassid].nleng = nleng; memcpy(sclasstab[sclassid].name,name,nleng); sclasstab[sclassid].files = 0; sclasstab[sclassid].directories = 0; sclass_fix_has_labels_fields(sclassid); if (sclassid>=firstneverused) { firstneverused = sclassid+1; } if (chunkcount>0) { bio_skip(fd,chunkcount*8); } } free(databuff); databuff=NULL; return 1; }