int main(int argc, char *argv[]) { char const * dir; int root_fd; int this_fd; char * umount_cmd[] = { UMOUNT_PROG, "-l", "-n", ".", 0 }; if (argc<2) { WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); WRITE_MSG(2, " --help' for more information.\n"); return EXIT_FAILURE; } if (strcmp(argv[1], "--help")==0) showHelp(1, argv[0], 0); if (strcmp(argv[1], "--version")==0) showVersion(); dir = argv[1]; if (strcmp(dir, "--")==0 && argc>=3) dir = argv[2]; root_fd = Eopen("/", O_RDONLY, 0); Echroot("."); Echdir(dir); this_fd = Eopen(".", O_RDONLY, 0); Efchdir(root_fd); Echroot("."); Efchdir(this_fd); Eclose(root_fd); Eclose(this_fd); Eexecv(umount_cmd[0], umount_cmd); }
static void printXid(int fd) { xid_t xid = Evc_get_task_xid(0); char buf[sizeof(xid)*3 + 2]; size_t l; l = utilvserver_fmt_long(buf, xid); EwriteAll(fd, buf, l); Eclose(fd); }
/*@-superuser@*/ int initializeSystem(int argc, char *argv[], struct InterfaceInfoList * ifs, struct ServerInfoList * servers, struct FdInfoList * fds) { struct ConfigInfo cfg; pid_t pid, pidfile_pid; int pidfile_fd; cfg.conffile_name = CFG_FILENAME; cfg.do_fork = true; parseCommandline(argc, argv, &cfg); /*@-boundswrite@*/ getConfig(cfg.conffile_name, &cfg); initFDs(fds, &cfg); /*@=boundswrite@*/ pidfile_fd = Eopen(cfg.pidfile_name, O_WRONLY|O_CREAT, 0444); openMsgfile(cfg.logfile_name); *ifs = cfg.interfaces; *servers = cfg.servers; Eclose(0); if (cfg.do_fork) pid = fork(); else pid = 0; pidfile_pid = 0; switch (pid) { case 0 : pidfile_pid = initializeDaemon(&cfg); break; case -1 : perror("fork()"); break; default : pidfile_pid = pid; break; } if (pidfile_pid!=0) { writeUInt(pidfile_fd, pidfile_pid); (void)write(pidfile_fd, "\n", 1); } freeLimitList(&cfg.ulimits); /* It is too late to handle an error here. So just ignore it... */ (void)close(pidfile_fd); return pid; }
static int sendQuitSignal(char const *filename, char const *msg) { int fd; struct sockaddr_un addr; ENSC_INIT_UNIX_SOCK(addr, filename); fd = Esocket(PF_UNIX, SOCK_STREAM, 0); Econnect(fd, &addr, sizeof(addr)); if (msg) EsendAll(fd, msg, strlen(msg)); Eclose(fd); return EXIT_SUCCESS; }
inline static void fillInterfaceInfo(struct InterfaceInfoList *ifs) /*@globals fileSystem, internalState@*/ /*@modifies ifs->dta, fileSystem, internalState@*/ /*@requires maxRead(ifs->dta)==ifs->len /\ maxRead(ifs)==0@*/ { int fd = Esocket(AF_INET, SOCK_DGRAM, 0); size_t i; assert(ifs->len==0 || ifs->dta!=0); for (i=0; i<ifs->len; ++i) { struct ifreq iface; struct InterfaceInfo *ifinfo; assert(ifs->dta!=0); ifinfo = &ifs->dta[i]; memcpy(iface.ifr_name, ifinfo->name, IFNAMSIZ); if (ioctl(fd, SIOCGIFINDEX, &iface)==-1) goto err; if (iface.ifr_ifindex<0) goto err; ifinfo->if_idx = (unsigned int)(iface.ifr_ifindex); if (ioctl(fd, SIOCGIFADDR, &iface)==-1) goto err; ifinfo->if_real_ip = sockaddrToInet4(&iface.ifr_addr); if (ioctl(fd, SIOCGIFMTU, &iface)==-1) goto err; ifinfo->if_mtu = static_cast(size_t)(iface.ifr_mtu); if (!ifinfo->need_mac) ifinfo->if_maclen = 0; else { if (ioctl(fd, SIOCGIFHWADDR, &iface)==-1) goto err; sockaddrToHwAddr(&iface.ifr_hwaddr, ifinfo->if_mac, &ifinfo->if_maclen); } if (ifinfo->if_ip==INADDR_NONE) ifinfo->if_ip = ifinfo->if_real_ip; } Eclose(fd); return; err: perror("ioctl()"); scEXITFATAL("Can not get interface information"); }
int main(int argc, char *argv[]) { bool quiet = false; char const * vserver; VserverTag tag; while (1) { int c = getopt_long(argc, argv, "ql", CMDLINE_OPTIONS, 0); if (c==-1) break; switch (c) { case 'h' : showHelp(1, argv[0], 0); case 'v' : showVersion(); case 'l' : showTags(); case 'q' : quiet = true; break; default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); WRITE_MSG(2, " --help' for more information.\n"); exit(1); break; } } if (optind+2>argc) { execQuery("-", tgSYSINFO, 0, 0); WRITE_MSG(2, "\nAssumed 'SYSINFO' as no other option given; try '--help' for more information.\n"); exit(0); } vserver = argv[optind]; tag = stringToTag(argv[optind+1]); if (tag==tgNONE) { WRITE_MSG(2, "Unknown tag; use '-l' to get list of valid tags\n"); exit(1); } if (quiet) { int fd = Eopen("/dev/null", O_WRONLY, 0644); Edup2(fd, 1); Eclose(fd); } return execQuery(vserver, tag, argc-(optind+2), argv+optind+2); }
static int printSysInfo(char *buf) { int fd = open(PKGDATADIR "/FEATURES.txt", O_RDONLY); struct utsname uts; if (uname(&uts)==-1) perror("uname()"); else { WRITE_MSG(1, "Versions:\n" " Kernel: "); WRITE_STR(1, uts.release); WRITE_MSG(1, "\n" " VS-API: "); memset(buf, 0, 128); if (getAPIVer(buf)) WRITE_STR(1, buf); else WRITE_MSG(1, "???"); WRITE_MSG(1, "\n" " VCI: "); memset(buf, 0, 128); if (getAPIConfig(buf)) WRITE_STR(1, buf); else WRITE_MSG(1, "???"); WRITE_MSG(1, "\n" " util-vserver: " PACKAGE_VERSION "; " __DATE__ ", " __TIME__"\n" "\n"); } if (fd==-1) WRITE_MSG(1, "FEATURES.txt not found\n"); else { off_t l = Elseek(fd, 0, SEEK_END); Elseek(fd, 0, SEEK_SET); { char buf[l]; EreadAll(fd, buf, l); EwriteAll(1, buf, l); } Eclose(fd); } return EXIT_SUCCESS; }
void openMsgfile(/*@in@*//*@null@*/char const *filename) /*@globals msg_fd@*/ /*@modifies msg_fd@*/ { if (filename==0 || filename[0]=='\0') { msg_fd = 2; } else if (strcmp(filename, "/dev/null")==0) { msg_fd = -1; } else { int new_fd; new_fd = Eopen(filename, O_CREAT|O_WRONLY|O_APPEND, 0400); msg_fd = Edup2(new_fd, 2); assert(msg_fd==2); Eclose(new_fd); } }
static void setFromDir(char const *pathname, bool is_missingok, xid_t xid) { struct stat st; size_t i; size_t l_pathname = strlen(pathname); char buf[l_pathname + sizeof("/domainname") + 32]; if (stat(pathname, &st)==-1) { if (errno==ENOENT && is_missingok) return; PERROR_Q(ENSC_WRAPPERS_PREFIX "fstat", pathname); exit(wrapper_exit_code); } memcpy(buf, pathname, l_pathname); if (l_pathname>0 && pathname[l_pathname-1]!='/') buf[l_pathname++] = '/'; for (i=0; i<DIM_OF(UTS_STRINGS); ++i) { char * ptr = buf+l_pathname; int fd; // ignore unimplemented uts-names if (UTS_STRINGS[i]==0) continue; strcpy(ptr, UTS_STRINGS[i]); for (;*ptr;++ptr) *ptr = tolower(*ptr); fd = open(buf, O_RDONLY); if (fd!=-1) { size_t l = Elseek(fd, 0, SEEK_END); char name[l+1]; Elseek(fd,0,SEEK_SET); EreadAll(fd, name, l); while (l>0 && name[l-1]=='\n') --l; name[l] = '\0'; Eclose(fd); if (vc_set_vhi_name(xid, (vc_uts_type)(i), name, l)==-1) { PERROR_U(ENSC_WRAPPERS_PREFIX "vc_set_vhi_name", UTS_STRINGS[i]); exit(wrapper_exit_code); } } } }
inline static pid_t initializeDaemon(/*@in@*/struct ConfigInfo const *cfg) { assert(cfg!=0); if (cfg->do_fork) Esetsid(); Eclose(1); if (cfg->chroot_path[0]!='\0') { Echdir (cfg->chroot_path); Echroot(cfg->chroot_path); } Esetgroups(1, &cfg->gid); Esetgid(cfg->gid); Esetuid(cfg->uid); limitResources(&cfg->ulimits); if (cfg->do_fork) return 0; else return getpid(); }
static void initMtab(struct Configuration const *cfg) { ENSC_PI_DECLARE(mtab_subpath, "apps/init/mtab"); PathInfo mtab_path = cfg->cfgdir; char mtab_buf[ENSC_PI_APPSZ(mtab_path, mtab_subpath)]; PathInfo_append(&mtab_path, &mtab_subpath, mtab_buf); char const * mtab = findMtab(mtab_path.d); pid_t pid; int p[2]; Epipe(p); pid = Efork(); if (pid==0) { Undo_detach(); Eclose(p[1]); Echdir(cfg->vdir); Echroot("."); int fd = Eopen("/etc/mtab", O_WRONLY|O_CREAT, 0644); for (;;) { char buf[4096]; ssize_t len = TEMP_FAILURE_RETRY(read(p[0], buf, sizeof buf)); if (len==0) break; if (len==-1) { perror("vserver-start: initMtab/read():"); _exit(1); } Ewrite(fd, buf, len); } Eclose(fd); Eclose(p[0]); _exit(0); } else { Eclose(p[0]); if (mtab!=0) { int fd = Eopen(mtab, O_RDONLY, 0644); for (;;) { char buf[4096]; ssize_t len = TEMP_FAILURE_RETRY(read(fd, buf, sizeof buf)); if (len==0) break; if (len==-1) { perror("vserver-start: initMtab/read():"); _exit(1); } Ewrite(p[1], buf, len); } Eclose(fd); } Eclose(p[1]); int status; TEMP_FAILURE_RETRY(wait4(pid, &status, 0,0)); if (!WIFEXITED(status) || WEXITSTATUS(status)!=0) { exit(1); } } }