void handle_sigusr2() { if(level.num==3) level.num=0; else level.num=level.num+1; setloglevel(level.num); }
int main(int argc, char **argv) { setloglevel(LOG_DBG); struct OPTION *op = setOPTION(argc, argv); NET *net = preprocess_NET(op); int *status = preprocess_STATUS(net); process(net, op->rate_infect, op->rate_recover, op->STEP, status); free(status); freeNET(net); freeOPTION(op); releaselog(); return 0; }
int main(int argc, char *argv[]) { std::ifstream input; std::ofstream output; int cntr = 0; setloglevel(0); if (argc < 2) { print_usage(argv[0]); return -1; } //open input file input.open(argv[1], std::ios::in); if (!input.is_open()) { log(ERROR) << "Error opening input source " << argv[1] << ".\n"; return -1; } //declare our input buffers listing program; std::string buffer; //read input, parsing each string and then passing it into the instruction factory cntr = 0; while(std::getline(input,buffer)) { ++cntr; if (program.factory(buffer) != 0) { log(ERROR) << "Error reading line " << cntr << ". Instruction not recognized.\n"; log(ERROR) << "Line " << cntr << ": " << buffer << std::endl; return -1; } } //print out all instructions; cntr = 0; program.print(); return 0; }
/** * @brief Read in a list of array and check for each of the arrays whether they are in LMC form or not * @param argc * @param argv[] * @return */ int main (int argc, char *argv[]) { char *fname; int correct = 0, wrong = 0; /* parse command line options */ AnyOption opt; opt.setFlag ("help", 'h'); /* a flag (takes no argument), supporting long and short form */ opt.setOption ("loglevel", 'l'); opt.setOption ("oaconfig", 'c'); opt.setOption ("check"); opt.setOption ("strength", 's'); opt.setOption ("prune", 'p'); opt.setOption ("output", 'o'); opt.setOption ("mode", 'm'); opt.addUsage ("oacheck: Check arrays for LMC form or reduce to LMC form"); opt.addUsage ("Usage: oacheck [OPTIONS] [ARRAYFILE]"); opt.addUsage (""); opt.addUsage (" -h --help Prints this help"); opt.addUsage (" -l [LEVEL] --loglevel [LEVEL] Set loglevel to number"); opt.addUsage (" -s [STRENGTH] --strength [STRENGTH] Set strength to use in checking"); std::string ss = " --check [MODE] Select mode: "; ss += printfstring ("%d (default: check ), %d (reduce to LMC form), %d (apply random transformation and reduce)", MODE_CHECK, MODE_REDUCE, MODE_REDUCERANDOM); // for (int i = 3; i < ncheckopts; ++i) ss += printfstring (", %d (%s)", static_cast< checkmode_t > (i), modeString ((checkmode_t)i).c_str ()); opt.addUsage (ss.c_str ()); opt.addUsage (" -o [OUTPUTFILE] Output file for LMC reduction"); opt.processCommandArgs (argc, argv); algorithm_t algmethod = (algorithm_t)opt.getIntValue ("mode", MODE_AUTOSELECT); int loglevel = NORMAL; if (opt.getValue ("loglevel") != NULL || opt.getValue ('l') != NULL) loglevel = atoi (opt.getValue ('l')); // set custom loglevel setloglevel (loglevel); if (checkloglevel (QUIET)) { print_copyright (); } if (opt.getFlag ("help") || opt.getFlag ('h') || opt.getArgc () == 0) { opt.printUsage (); return 0; } checkmode_t mode = MODE_CHECK; if (opt.getValue ("check") != NULL) mode = (checkmode_t)atoi (opt.getValue ("check")); // set custom loglevel if (mode >= ncheckopts) mode = MODE_CHECK; logstream (QUIET) << "#time start: " << currenttime () << std::endl; double t = get_time_ms (); t = 1e3 * (t - floor (t)); srand (t); int prune = opt.getIntValue ('p', 0); fname = opt.getArgv (0); setloglevel (loglevel); int strength = opt.getIntValue ('s', 2); if (strength < 1 || strength > 10) { printf ("Strength specfied (t=%d) is invalid\n", strength); exit (1); } else { log_print (NORMAL, "Using strength %d to increase speed of checking arrays\n", strength); } arraylist_t outputlist; char *outputfile = 0; bool writeoutput = false; if (opt.getValue ("output") != NULL) { writeoutput = true; outputfile = opt.getValue ('o'); } arrayfile_t *afile = new arrayfile_t (fname); if (!afile->isopen ()) { printf ("Problem opening %s\n", fname); exit (1); } logstream (NORMAL) << "Check mode: " << mode << " (" << modeString (mode) << ")" << endl; /* start checking */ double Tstart = get_time_ms (), dt; int index; array_link al (afile->nrows, afile->ncols, -1); for (int i = 0; i < afile->narrays; i++) { index = afile->read_array (al); array_t *array = al.array; arraydata_t arrayclass = arraylink2arraydata (al, 0, strength); arrayclass.lmc_overflow_check (); OAextend oaextend; lmc_t result = LMC_NONSENSE; LMCreduction_t *reduction = new LMCreduction_t (&arrayclass); LMCreduction_t *randtest = new LMCreduction_t (&arrayclass); array_link test_arraylink = al.clone(); array_t *testarray = test_arraylink.array; randtest->transformation->randomize (); reduction->setArray ( al); /* variables needed within the switch statement */ switch (mode) { case MODE_CHECK: { /* LMC test with reduction code */ reduction->mode = OA_TEST; result = LMCcheck(al, arrayclass, oaextend, *reduction); break; } case MODE_CHECKJ4: { /* LMC test with special code */ reduction->mode = OA_TEST; reduction->init_state = COPY; oaextend.setAlgorithm (MODE_J4, &arrayclass); result = LMCcheck (al, arrayclass, oaextend, *reduction); break; } case MODE_REDUCEJ4: { /* LMC test with special code */ reduction->mode = OA_REDUCE; reduction->setArray (al); result = LMCcheckj4 (al, arrayclass, *reduction, oaextend); break; } case MODE_CHECK_SYMMETRY: { myprintf("MODE_CHECK_SYMMETRY not supported any more"); exit(1); } case MODE_CHECKJ5X: { oaextend.setAlgorithm (MODE_J5ORDERX, &arrayclass); /* LMC test with special code */ reduction->mode = OA_TEST; reduction->init_state = COPY; result = LMCcheck (al, arrayclass, oaextend, *reduction); break; } case MODE_CHECKJ5XFAST: { oaextend.setAlgorithm (MODE_J5ORDERX, &arrayclass); /* LMC test with special code */ reduction->mode = OA_TEST; reduction->init_state = COPY; if (1) { array_link al (array, arrayclass.N, arrayclass.ncols, al.INDEX_NONE); reduction->updateSDpointer (al); } result = LMCcheck (al, arrayclass, oaextend, *reduction); break; } case MODE_REDUCEJ5X: { OAextend oaextend; oaextend.setAlgorithm (MODE_J5ORDERX, &arrayclass); /* LMC test with special code */ printf ("oacheck: WARNING: MODE_CHECKJ5X: untested code, not complete\n"); reduction->mode = OA_REDUCE; result = LMCcheck (al, arrayclass, oaextend, *reduction); break; } case MODE_REDUCE: /* LMC reduction */ { reduction->mode = OA_REDUCE; copy_array(array, reduction->array, arrayclass.N, arrayclass.ncols); dyndata_t dynd = dyndata_t(arrayclass.N); result = LMCreduction(array, array, &arrayclass, &dynd, reduction, oaextend); break; } case MODE_REDUCERANDOM: { /* random LMC reduction */ oaextend.setAlgorithm(MODE_ORIGINAL, &arrayclass); reduction->mode = OA_REDUCE; randtest->transformation->apply(array, testarray); copy_array(testarray, reduction->array, arrayclass.N, arrayclass.ncols); reduction->init_state = INIT; array_link alp = arrayclass.create_root(arrayclass.ncols, 1000); reduction->setArray(alp); dyndata_t dynd = dyndata_t(arrayclass.N); result = LMCreduction(testarray, testarray, &arrayclass, &dynd, reduction, oaextend); if (log_print(NORMAL, "")) { reduction->transformation->show(); } } break; case MODE_REDUCETRAIN: /* LMC reduction with train*/ reduction->mode = OA_REDUCE; result = LMCreduction_train (al, &arrayclass, reduction, oaextend); break; case MODE_REDUCETRAINRANDOM: /* random LMC reduction with train*/ reduction->mode = OA_REDUCE; randtest->transformation->apply (array, testarray); result = LMCreduction_train (test_arraylink, &arrayclass, reduction, oaextend); break; case MODE_HADAMARD: myprintf("MODE_HADAMARD not supported any more\n"); exit(1); default: result = LMC_NONSENSE; std::cout << "function " << __FUNCTION__ << "line " << __LINE__ << "Unknown mode" << std::endl; exit (1); break; } bool aequal; switch (mode) { case MODE_CHECK: if (result == LMC_LESS) { ++wrong; log_print (NORMAL, "Found array nr %i/%i NOT in lmc form:\n", i, afile->narrays); } else { ++correct; log_print (NORMAL, "Found array nr %i/%i in lmc form.\n", i, afile->narrays); } break; case MODE_CHECKJ4: case MODE_CHECKJ5X: case MODE_CHECKJ5XFAST: case MODE_CHECK_SYMMETRY: if (result == LMC_LESS) { ++wrong; log_print (NORMAL, "Found array nr %i/%i NOT in minimal form:\n", i, afile->narrays); } else { ++correct; log_print (NORMAL, "Found array nr %i/%i in minimal form.\n", i, afile->narrays); } break; case MODE_REDUCE: case MODE_REDUCEJ4: case MODE_REDUCEJ5X: case MODE_REDUCETRAIN: aequal = std::equal (array, array + arrayclass.N * arrayclass.ncols, reduction->array); if ((!aequal) || reduction->state == REDUCTION_CHANGED) { ++wrong; log_print (QUIET, "Reduced array %i/%i to lmc form.\n", i, afile->narrays); if (checkloglevel (NORMAL)) { log_print (QUIET, "Original:\n"); print_array (array, afile->nrows, afile->ncols); print_array ("Reduction:\n", reduction->array, afile->nrows, afile->ncols); printf ("---------------\n"); } if (checkloglevel (DEBUG)) { cout << "Transformation: " << endl; reduction->transformation->show (cout); rowindex_t row; colindex_t column; array_diff (array, reduction->array, arrayclass.N, arrayclass.ncols, row, column); cout << "Difference at: "; printf (" row %d, col %d\n", row, column); } } else { ++correct; log_print (QUIET, "Array %i/%i was already in lmc form:\n", i, afile->narrays); } break; case MODE_REDUCETRAINRANDOM: case MODE_REDUCERANDOM: case MODE_REDUCEJ4RANDOM: aequal = std::equal (array, array + arrayclass.N * arrayclass.ncols, reduction->array); if (!aequal) { ++wrong; log_print (SYSTEM, "Array %i/%i: reduced random transformation not equal to original (BUG!)\n", i, afile->narrays); if (checkloglevel (NORMAL)) { print_array ("Original:\n", array, afile->nrows, afile->ncols); print_array ("Randomized:\n", testarray, afile->nrows, afile->ncols); print_array ("Reduction:\n", reduction->array, afile->nrows, afile->ncols); printf ("---------------\n"); } } else { ++correct; log_print (QUIET, "Array %i/%i: reduced random transformation to original\n", i, afile->narrays); } break; case MODE_HADAMARD: break; default: std::cout << "function " << __FUNCTION__ << "line " << __LINE__ << "unknown mode" << std::endl; break; } array_link al = array_link ((carray_t *)reduction->array, afile->nrows, afile->ncols, -1); if (result == LMC_MORE || !prune) { outputlist.push_back (al); } delete randtest; delete reduction; destroy_array (testarray); } afile->closefile (); delete afile; if (writeoutput) { logstream (NORMAL) << "Writing output (" << outputlist.size () << " arrays)" << endl; writearrayfile (outputfile, outputlist); } logstream (QUIET) << "#time end: " << currenttime () << std::endl; return 0; }
int main(int argc, char **argv) { options_t options; int doversion = 0; int dohelp = 0; int userclasses = 0; int opt; int option_index = 0; char prefix[IF_NAMESIZE + 3]; pid_t pid; int debug = 0; int i; int pidfd = -1; int sig = 0; const struct option longopts[] = { {"arp", no_argument, NULL, 'a'}, {"script", required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, {"hostname", optional_argument, NULL, 'h'}, {"classid", optional_argument, NULL, 'i'}, {"release", no_argument, NULL, 'k'}, {"leasetime", required_argument, NULL, 'l'}, {"metric", required_argument, NULL, 'm'}, {"renew", no_argument, NULL, 'n'}, {"persistent", no_argument, NULL, 'p'}, {"inform", optional_argument, NULL, 's'}, {"request", optional_argument, NULL, 'r'}, {"timeout", required_argument, NULL, 't'}, {"userclass", required_argument, NULL, 'u'}, {"exit", no_argument, NULL, 'x'}, {"lastlease", no_argument, NULL, 'E'}, {"fqdn", required_argument, NULL, 'F'}, {"nogateway", no_argument, NULL, 'G'}, {"sethostname", no_argument, NULL, 'H'}, {"clientid", optional_argument, NULL, 'I'}, {"noipv4ll", no_argument, NULL, 'L'}, {"nomtu", no_argument, NULL, 'M'}, {"nontp", no_argument, NULL, 'N'}, {"nodns", no_argument, NULL, 'R'}, {"test", no_argument, NULL, 'T'}, {"nonis", no_argument, NULL, 'Y'}, {"help", no_argument, &dohelp, 1}, {"version", no_argument, &doversion, 1}, {NULL, 0, NULL, 0} }; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) close (i); openlog (PACKAGE, LOG_PID, LOG_LOCAL0); memset (&options, 0, sizeof (options_t)); options.script = (char *) DEFAULT_SCRIPT; snprintf (options.classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options.classid_len = strlen (options.classid); options.doarp = true; options.dodns = true; options.domtu = true; options.donis = true; options.dontp = true; options.dogateway = true; options.daemonise = true; options.doinform = false; options.doipv4ll = true; options.timeout = DEFAULT_TIMEOUT; gethostname (options.hostname, sizeof (options.hostname)); if (strcmp (options.hostname, "(none)") == 0 || strcmp (options.hostname, "localhost") == 0) memset (options.hostname, 0, sizeof (options.hostname)); /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ while ((opt = getopt_long(argc, argv, "c:dh:i:kl:m:npr:s:t:u:xAEF:GHI:LMNRTY", longopts, &option_index)) != -1) { switch (opt) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'c': options.script = optarg; break; case 'd': debug++; switch (debug) { case 1: setloglevel (LOG_DEBUG); break; case 2: options.daemonise = false; break; } break; case 'h': if (! optarg) memset (options.hostname, 0, sizeof (options.hostname)); else if (strlen (optarg) > MAXHOSTNAMELEN) { logger (LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, MAXHOSTNAMELEN); exit (EXIT_FAILURE); } else strlcpy (options.hostname, optarg, sizeof (options.hostname)); break; case 'i': if (! optarg) { memset (options.classid, 0, sizeof (options.classid)); options.classid_len = 0; } else if (strlen (optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else options.classid_len = strlcpy (options.classid, optarg, sizeof (options.classid)); break; case 'k': sig = SIGHUP; break; case 'l': STRINGINT (optarg, options.leasetime); if (options.leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT (optarg, options.metric); break; case 'n': sig = SIGALRM; break; case 'p': options.persistent = true; break; case 's': options.doinform = true; if (! optarg || strlen (optarg) == 0) { options.request_address.s_addr = 0; break; } else { char *slash = strchr (optarg, '/'); if (slash) { int cidr; /* nullify the slash, so the -r option can read the * address */ *slash++ = '\0'; if (sscanf (slash, "%d", &cidr) != 1) { logger (LOG_ERR, "`%s' is not a valid CIDR", slash); exit (EXIT_FAILURE); } options.request_netmask = inet_cidrtoaddr (cidr); } /* fall through */ } case 'r': if (! options.doinform) options.dorequest = true; if (strlen (optarg) > 0 && ! inet_aton (optarg, &options.request_address)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options.timeout); if (options.timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options.userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options.userclass + offset + 1 , optarg, strlen (optarg)); options.userclass[offset] = strlen (optarg); options.userclass_len += (strlen (optarg)) + 1; } break; case 'x': sig = SIGTERM; break; case 'A': #ifndef ENABLE_ARP logger (LOG_ERR, "arp support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options.doarp = false; break; case 'E': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options.dolastlease = true; break; case 'F': if (strncmp (optarg, "none", strlen (optarg)) == 0) options.fqdn = FQDN_NONE; else if (strncmp (optarg, "ptr", strlen (optarg)) == 0) options.fqdn = FQDN_PTR; else if (strncmp (optarg, "both", strlen (optarg)) == 0) options.fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options.dogateway = false; break; case 'H': options.dohostname++; break; case 'I': if (optarg) { if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } options.clientid_len = strlcpy (options.clientid, optarg, sizeof (options.clientid)); /* empty string disabled duid */ if (options.clientid_len == 0) options.clientid_len = -1; } else { memset (options.clientid, 0, sizeof (options.clientid)); options.clientid_len = -1; } break; case 'L': options.doipv4ll = false; break; case 'M': options.domtu = false; break; case 'N': options.dontp = false; break; case 'R': options.dodns = false; break; case 'T': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options.test = true; options.persistent = true; break; case 'Y': options.donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } } if (doversion) printf (""PACKAGE" "VERSION"\n"); if (dohelp) usage (); if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } strlcpy (options.interface, argv[optind], sizeof (options.interface)); } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified"); exit (EXIT_FAILURE); } if (strchr (options.hostname, '.')) { if (options.fqdn == FQDN_DISABLE) options.fqdn = FQDN_BOTH; } else options.fqdn = FQDN_DISABLE; if (options.request_address.s_addr == 0 && options.doinform) { if ((options.request_address.s_addr = get_address (options.interface)) != 0) options.keep_address = true; } if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } snprintf (prefix, IF_NAMESIZE, "%s: ", options.interface); setlogprefix (prefix); snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE, options.interface); chdir ("/"); umask (022); if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", CONFIGDIR, strerror (errno)); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno)); exit (EXIT_FAILURE); } if (options.test) { if (options.dorequest || options.doinform) { logger (LOG_ERR, "cannot test with --inform or --request"); exit (EXIT_FAILURE); } if (options.dolastlease) { logger (LOG_ERR, "cannot test with --lastlease"); exit (EXIT_FAILURE); } if (sig != 0) { logger (LOG_ERR, "cannot test with --release or --renew"); exit (EXIT_FAILURE); } } if (sig != 0 ) { int killed = -1; pid = read_pid (options.pidfile); if (pid != 0) logger (LOG_INFO, "sending signal %d to pid %d", sig, pid); if (! pid || (killed = kill (pid, sig))) logger (sig == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); if (pid != 0 && (sig != SIGALRM || killed != 0)) unlink (options.pidfile); if (killed == 0) exit (EXIT_SUCCESS); if (sig != SIGALRM) exit (EXIT_FAILURE); } if (! options.test) { if ((pid = read_pid (options.pidfile)) > 0 && kill (pid, 0) == 0) { logger (LOG_ERR, ""PACKAGE" already running on pid %d (%s)", pid, options.pidfile); exit (EXIT_FAILURE); } pidfd = open (options.pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0660); if (pidfd == -1) { logger (LOG_ERR, "open `%s': %s", options.pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* Lock the file so that only one instance of dhcpcd runs on an interface */ if (flock (pidfd, LOCK_EX | LOCK_NB) == -1) { logger (LOG_ERR, "flock `%s': %s", options.pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* dhcpcd.sh should not interhit this fd */ if ((i = fcntl (pidfd, F_GETFD, 0)) == -1 || fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) == -1) logger (LOG_ERR, "fcntl: %s", strerror (errno)); logger (LOG_INFO, PACKAGE " " VERSION " starting"); } /* Seed random */ srandomdev (); if (dhcp_run (&options, &pidfd)) { if (pidfd > -1) close (pidfd); unlink (options.pidfile); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }
int main(int argc, char **argv) { options_t options; /* Sanitize our fd's */ int zero; if ((zero = open (_PATH_DEVNULL, O_RDWR, 0)) >= 0) { while (zero < 3) zero = dup (zero); close(zero); } openlog (PACKAGE, LOG_PID, LOG_LOCAL0); memset (&options, 0, sizeof (options_t)); options.script = DEFAULT_SCRIPT; snprintf (options.classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options.doarp = false; options.dodns = true; options.dontp = true; options.dogateway = true; options.timeout = DEFAULT_TIMEOUT; int doversion = 0; int dohelp = 0; int userclasses = 0; const struct option longopts[] = { {"arp", no_argument, NULL, 'a'}, {"script",required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, {"hostname", required_argument, NULL, 'h'}, {"classid", required_argument, NULL, 'i'}, {"release", no_argument, NULL, 'k'}, {"leasetime", required_argument, NULL, 'l'}, {"metric", required_argument, NULL, 'm'}, {"renew", no_argument, NULL, 'n'}, {"persistent", no_argument, NULL, 'p'}, {"request", required_argument, NULL, 's'}, {"timeout", required_argument, NULL, 't'}, {"userclass", required_argument, NULL, 'u'}, {"fqdn", optional_argument, NULL, 'F'}, {"nogateway", no_argument, NULL, 'G'}, {"sethostname", no_argument, NULL, 'H'}, {"clientid", required_argument, NULL, 'I'}, {"nontp", no_argument, NULL, 'N'}, {"nodns", no_argument, NULL, 'R'}, {"nonis", no_argument, NULL, 'Y'}, {"help", no_argument, &dohelp, 1}, {"version", no_argument, &doversion, 1}, {NULL, 0, NULL, 0} }; int ch; int option_index = 0; while ((ch = getopt_long(argc, argv, "ac:dh:i:kl:m:nps:t:u:F:GHI:NRY", longopts, &option_index)) != -1) switch (ch) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'a': options.doarp = true; break; case 'c': options.script = optarg; break; case 'd': setloglevel(LOG_DEBUG); break; case 'h': if (strlen (optarg) > HOSTNAME_MAX_LEN) { logger(LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, HOSTNAME_MAX_LEN); exit (EXIT_FAILURE); } else options.hostname = optarg; break; case 'i': if (strlen(optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else sprintf(options.classid, "%s", optarg); break; case 'k': options.signal = SIGHUP; break; case 'l': STRINGINT (optarg, options.leasetime); if (options.leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT(optarg, options.metric); break; case 'n': options.signal = SIGALRM; break; case 'p': options.persistent = true; break; case 's': if (! inet_aton (optarg, &options.requestaddress)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options.timeout); if (options.timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int i; int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options.userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options.userclass + offset + 1 , optarg, strlen (optarg)); options.userclass[offset] = strlen (optarg); } break; case 'F': if (strcmp (optarg, "none") == 0) options.fqdn = FQDN_NONE; else if (strcmp (optarg, "ptr") == 0) options.fqdn = FQDN_PTR; else if (strcmp (optarg, "both") == 0) options.fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options.dogateway = false; break; case 'H': options.dohostname = true; break; case 'I': if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } else sprintf(options.clientid, "%s", optarg); break; case 'N': options.dontp = false; break; case 'R': options.dodns = false; break; case 'Y': options.donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } if (doversion) printf (""PACKAGE" "VERSION"\n"); if (dohelp) usage (); if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } options.interface = argv[optind]; } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified", options.interface); exit (EXIT_FAILURE); } if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } char prefix[IF_NAMESIZE + 3]; snprintf (prefix, IF_NAMESIZE, "%s: ", options.interface); setlogprefix (prefix); snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE, options.interface); if (options.signal != 0) exit (kill_pid (options.pidfile, options.signal)); umask (022); if (readpid (options.pidfile)) { logger (LOG_ERR, ""PACKAGE" already running (%s)", options.pidfile); exit (EXIT_FAILURE); } if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger( LOG_ERR, "mkdir(\"%s\",0): %m\n", CONFIGDIR); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %m\n", ETCDIR); exit (EXIT_FAILURE); } logger (LOG_INFO, PACKAGE " " VERSION " starting"); if (dhcp_run (&options)) exit (EXIT_FAILURE); exit (EXIT_SUCCESS); }
int main(int argc, char **argv) { options_t *options; int userclasses = 0; int opt; int option_index = 0; char *prefix; pid_t pid; int debug = 0; int i; int pidfd = -1; int sig = 0; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) close (i); openlog (PACKAGE, LOG_PID, LOG_LOCAL0); options = xmalloc (sizeof (options_t)); memset (options, 0, sizeof (options_t)); options->script = (char *) DEFAULT_SCRIPT; snprintf (options->classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options->classid_len = strlen (options->classid); options->doarp = true; options->dodns = true; options->domtu = true; options->donis = true; options->dontp = true; options->dogateway = true; options->daemonise = true; options->doinform = false; options->doipv4ll = true; options->timeout = DEFAULT_TIMEOUT; gethostname (options->hostname, sizeof (options->hostname)); if (strcmp (options->hostname, "(none)") == 0 || strcmp (options->hostname, "localhost") == 0) memset (options->hostname, 0, sizeof (options->hostname)); /* Don't set any optional arguments here so we retain POSIX * compatibility with getopt */ while ((opt = getopt_long(argc, argv, EXTRA_OPTS "c:dh:i:kl:m:npr:s:t:u:xAEF:GHI:LMNRTY", longopts, &option_index)) != -1) { switch (opt) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'c': options->script = optarg; break; case 'd': debug++; switch (debug) { case 1: setloglevel (LOG_DEBUG); break; case 2: options->daemonise = false; break; } break; #ifdef THERE_IS_NO_FORK case 'f': options->daemonised = true; close_fds (); break; case 'g': dhcpcd_skiproutes = xstrdup (optarg); break; #endif case 'h': if (! optarg) memset (options->hostname, 0, sizeof (options->hostname)); else if (strlen (optarg) > MAXHOSTNAMELEN) { logger (LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, MAXHOSTNAMELEN); exit (EXIT_FAILURE); } else strlcpy (options->hostname, optarg, sizeof (options->hostname)); break; case 'i': if (! optarg) { memset (options->classid, 0, sizeof (options->classid)); options->classid_len = 0; } else if (strlen (optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else options->classid_len = strlcpy (options->classid, optarg, sizeof (options->classid)); break; case 'k': sig = SIGHUP; break; case 'l': STRINGINT (optarg, options->leasetime); if (options->leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT (optarg, options->metric); break; case 'n': sig = SIGALRM; break; case 'p': options->persistent = true; break; case 's': options->doinform = true; options->doarp = false; if (! optarg || strlen (optarg) == 0) { options->request_address.s_addr = 0; break; } else { char *slash = strchr (optarg, '/'); if (slash) { int cidr; /* nullify the slash, so the -r option can read the * address */ *slash++ = '\0'; if (sscanf (slash, "%d", &cidr) != 1 || inet_cidrtoaddr (cidr, &options->request_netmask) != 0) { logger (LOG_ERR, "`%s' is not a valid CIDR", slash); exit (EXIT_FAILURE); } } /* fall through */ } case 'r': if (! options->doinform) options->dorequest = true; if (strlen (optarg) > 0 && ! inet_aton (optarg, &options->request_address)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options->timeout); if (options->timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options->userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options->userclass + offset + 1 , optarg, strlen (optarg)); options->userclass[offset] = strlen (optarg); options->userclass_len += (strlen (optarg)) + 1; } break; case 'x': sig = SIGTERM; break; case 'A': #ifndef ENABLE_ARP logger (LOG_ERR, "arp support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options->doarp = false; break; case 'E': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options->dolastlease = true; break; case 'F': if (strncmp (optarg, "none", strlen (optarg)) == 0) options->fqdn = FQDN_NONE; else if (strncmp (optarg, "ptr", strlen (optarg)) == 0) options->fqdn = FQDN_PTR; else if (strncmp (optarg, "both", strlen (optarg)) == 0) options->fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options->dogateway = false; break; case 'H': options->dohostname++; break; case 'I': if (optarg) { if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } options->clientid_len = strlcpy (options->clientid, optarg, sizeof (options->clientid)); /* empty string disabled duid */ if (options->clientid_len == 0) options->clientid_len = -1; } else { memset (options->clientid, 0, sizeof (options->clientid)); options->clientid_len = -1; } break; case 'L': options->doipv4ll = false; break; case 'M': options->domtu = false; break; case 'N': options->dontp = false; break; case 'R': options->dodns = false; break; case 'T': #ifndef ENABLE_INFO logger (LOG_ERR, "info support not compiled into dhcpcd"); exit (EXIT_FAILURE); #endif options->test = true; options->persistent = true; break; case 'Y': options->donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } } if (doversion) { printf (""PACKAGE" "VERSION"\n"); printf ("Compile time options:" #ifdef ENABLE_ARP " ARP" #endif #ifdef ENABLE_DUID " DUID" #endif #ifdef ENABLE_INFO " INFO" #endif #ifdef ENABLE_INFO_COMPAT " INFO_COMPAT" #endif #ifdef ENABLE_IPV4LL " IPV4LL" #endif #ifdef ENABLE_NIS " NIS" #endif #ifdef ENABLE_NTP " NTP" #endif #ifdef THERE_IS_NO_FORK " THERE_IS_NO_FORK" #endif "\n"); } if (dohelp) usage (); #ifdef THERE_IS_NO_FORK dhcpcd_argv = argv; dhcpcd_argc = argc; /* We need the full path to the dhcpcd */ if (*argv[0] == '/') strlcpy (dhcpcd, argv[0], sizeof (dhcpcd)); else { char pwd[PATH_MAX]; if (! getcwd (pwd, PATH_MAX)) { logger (LOG_ERR, "getcwd: %s", strerror (errno)); exit (EXIT_FAILURE); } snprintf (dhcpcd, sizeof (dhcpcd), "%s/%s", pwd, argv[0]); } #endif if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } strlcpy (options->interface, argv[optind], sizeof (options->interface)); } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified"); exit (EXIT_FAILURE); } if (strchr (options->hostname, '.')) { if (options->fqdn == FQDN_DISABLE) options->fqdn = FQDN_BOTH; } else options->fqdn = FQDN_DISABLE; if (options->request_address.s_addr == 0 && options->doinform) { if ((options->request_address.s_addr = get_address (options->interface)) != 0) options->keep_address = true; } if (IN_LINKLOCAL (options->request_address.s_addr)) { logger (LOG_ERR, "you are not allowed to request a link local address"); exit (EXIT_FAILURE); } if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } prefix = xmalloc (sizeof (char) * (IF_NAMESIZE + 3)); snprintf (prefix, IF_NAMESIZE, "%s: ", options->interface); setlogprefix (prefix); snprintf (options->pidfile, sizeof (options->pidfile), PIDFILE, options->interface); free (prefix); chdir ("/"); umask (022); if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", CONFIGDIR, strerror (errno)); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno)); exit (EXIT_FAILURE); } if (options->test) { if (options->dorequest || options->doinform) { logger (LOG_ERR, "cannot test with --inform or --request"); exit (EXIT_FAILURE); } if (options->dolastlease) { logger (LOG_ERR, "cannot test with --lastlease"); exit (EXIT_FAILURE); } if (sig != 0) { logger (LOG_ERR, "cannot test with --release or --renew"); exit (EXIT_FAILURE); } } if (sig != 0) { int killed = -1; pid = read_pid (options->pidfile); if (pid != 0) logger (LOG_INFO, "sending signal %d to pid %d", sig, pid); if (! pid || (killed = kill (pid, sig))) logger (sig == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); if (pid != 0 && (sig != SIGALRM || killed != 0)) unlink (options->pidfile); if (killed == 0) exit (EXIT_SUCCESS); if (sig != SIGALRM) exit (EXIT_FAILURE); } if (! options->test && ! options->daemonised) { if ((pid = read_pid (options->pidfile)) > 0 && kill (pid, 0) == 0) { logger (LOG_ERR, ""PACKAGE" already running on pid %d (%s)", pid, options->pidfile); exit (EXIT_FAILURE); } pidfd = open (options->pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0660); if (pidfd == -1) { logger (LOG_ERR, "open `%s': %s", options->pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* Lock the file so that only one instance of dhcpcd runs on an interface */ if (flock (pidfd, LOCK_EX | LOCK_NB) == -1) { logger (LOG_ERR, "flock `%s': %s", options->pidfile, strerror (errno)); exit (EXIT_FAILURE); } /* dhcpcd.sh should not interhit this fd */ if ((i = fcntl (pidfd, F_GETFD, 0)) == -1 || fcntl (pidfd, F_SETFD, i | FD_CLOEXEC) == -1) logger (LOG_ERR, "fcntl: %s", strerror (errno)); writepid (pidfd, getpid ()); logger (LOG_INFO, PACKAGE " " VERSION " starting"); } /* Seed random */ srandomdev (); i = EXIT_FAILURE; if (dhcp_run (options, &pidfd) == 0) i = EXIT_SUCCESS; /* If we didn't daemonise then we need to punt the pidfile now */ if (pidfd > -1) { close (pidfd); unlink (options->pidfile); } free (options); #ifdef THERE_IS_NO_FORK /* There may have been an error before the dhcp_run function * clears this, so just do it here to be safe */ free (dhcpcd_skiproutes); #endif logger (LOG_INFO, "exiting"); exit (i); }
/*main loop, message sender, etc.pp.*/ int main(int argc,char**argv) { int c,optindex=1; struct dhcp_msg *msg; /*parse options*/ argv0=*argv; while(1){ c=getopt_long(argc,argv,shortopt,longopt,&optindex); if(c==-1)break; switch(c){ case 'p':getprefix=1;break; case 'P':getprefix=0;break; case 'a':getaddress=1;break; case 'A':getaddress=0;break; case 'd':getdns=1;break; case 'D':getdns=0;break; case 'r':retries=atoi(optarg);break; case 'l':localid=optarg;break; case 'u':setduid(optarg);break; case 'c':userapid=1;break; case 'C':userapid=0;break; case 'L':setloglevel(optarg);break; default: fprintf(stderr,"Syntax error in arguments.\n"); printhelp(); return 1; break; case 'h': printhelp(); return 0; break; } } if((optind+2)!=argc){ fprintf(stderr,"Syntax error.\n"); printhelp(); return 1; } device=argv[optind]; script=argv[optind+1]; if(DUIDLEN==0){ if(localid) setlocalid(localid); else initlocalid(); } /*init socket*/ initsocket(DHCP_CLIENTPORT,device); if(sockfd<0){ td_log(LOGERROR,"unable to allocate socket, exiting."); exit(1); } /*init my own stuff*/ inititems(); /*init SOLICIT/IREQ msg*/ if(!getaddress && !getprefix){ msg=newmessage(MSG_IREQUEST); addrecvfilter(MSG_REPLY); }else{ msg=newmessage(MSG_SOLICIT); addrecvfilter(MSG_ADVERTISE); } COMPAREMSGID=1; settargetserver(&msg->msg_peer); messageaddopt(msg,OPT_CLIENTID); if(getdns){ messageaddoptrequest(msg,OPT_DNS_SERVER); messageaddoptrequest(msg,OPT_DNS_NAME); } if(getaddress)messageaddopt(msg,OPT_IANA); if(getprefix)messageaddopt(msg,OPT_IAPD); if(userapid&&(getaddress||getprefix))messageaddopt(msg,OPT_RAPIDCOMMIT); /*start main loop*/ for(c=0;c<retries;c++){ sendmessage(msg); fd_set rfd,xfd; struct timeval tv; int sret; //wait for event FD_ZERO(&rfd); FD_ZERO(&xfd); FD_SET(sockfd,&rfd); FD_SET(sockfd,&xfd); tv.tv_sec=1; tv.tv_usec=0; sret=select(sockfd+1,&rfd,0,&xfd,&tv); //check for errors if(sret<0){ int e=errno; if(e==EAGAIN)continue; td_log(LOGERROR,"Error caught: %s\n",strerror(e)); return 1; } //check for event if(sret>0){ if(FD_ISSET(sockfd,&rfd)){ struct dhcp_msg*msg2; msg2=readmessage(); if(msg2) if(handlemessage(msg2,msg)==0)break; } if(FD_ISSET(sockfd,&xfd)){ td_log(LOGERROR,"Exception on socket caught.\n"); return 1; } }else td_log(LOGDEBUG,"timeout, iteration %i",c); } /*execute script*/ return execscript(); }
/** unittest for oapackage * * Returns UNITTEST_SUCCESS if all tests are ok. * */ int oaunittest (int verbose, int writetests = 0, int randval = 0) { double t0 = get_time_ms (); const char *bstr = "OA unittest"; cprintf (verbose, "%s: start\n", bstr); srand (randval); int allgood = UNITTEST_SUCCESS; Combinations::initialize_number_combinations (20); /* constructors */ { cprintf (verbose, "%s: interaction matrices\n", bstr); array_link al = exampleArray (2); Eigen::MatrixXd m1 = array2xfeigen (al); Eigen::MatrixXd m2 = arraylink2eigen (array2xf (al)); Eigen::MatrixXd dm = m1 - m2; int sum = dm.sum (); myassert (sum == 0, "unittest error: construction of interaction matrices\n"); } cprintf(verbose, "%s: reduceConferenceTransformation\n", bstr); myassert(unittest_reduceConferenceTransformation()==0, "unittest unittest_reduceConferenceTransformation failed"); /* constructors */ { cprintf (verbose, "%s: array manipulation operations\n", bstr); test_array_manipulation (verbose); } /* double conference matrices */ { cprintf (verbose, "%s: double conference matrices\n", bstr); array_link al = exampleArray (36, verbose); myassert (al.is_conference (2), "check on double conference design type"); myassert (testLMC0checkDC (al, verbose >= 2), "testLMC0checkDC"); } /* conference matrices */ { cprintf (verbose, "%s: conference matrices\n", bstr); int N = 4; conference_t ctype (N, N, 0); arraylist_t kk; array_link al = ctype.create_root (); kk.push_back (al); for (int extcol = 2; extcol < N; extcol++) { kk = extend_conference (kk, ctype, 0); } myassert (kk.size () == 1, "unittest error: conference matrices for N=4\n"); } { cprintf (verbose, "%s: generators for conference matrix extensions\n", bstr); test_conference_candidate_generators (verbose); } { cprintf (verbose, "%s: conference matrix Fvalues\n", bstr); array_link al = exampleArray (22, 0); if (verbose >= 2) al.show (); if (0) { std::vector< int > f3 = al.FvaluesConference (3); if (verbose >= 2) { printf ("F3: "); display_vector (f3); printf ("\n"); } } const int N = al.n_rows; jstructconference_t js (N, 4); std::vector< int > f4 = al.FvaluesConference (4); std::vector< int > j4 = js.Jvalues (); if (verbose >= 2) { printf ("j4: "); display_vector (j4); printf ("\n"); printf ("F4: "); display_vector (f4); printf ("\n"); } myassert (j4[0] == 28, "unittest error: conference matricex F values: j4[0]\n"); myassert (f4[0] == 0, "unittest error: conference matricex F values: f4[0] \n"); myassert (f4[1] == 0, "unittest error: conference matricex F values: j4[1]\n"); } { cprintf (verbose, "%s: LMC0 check for arrays in C(4, 3)\n", bstr); array_link al = exampleArray (28, 1); if (verbose >= 2) al.showarray (); lmc_t r = LMC0check (al, verbose); if (verbose >= 2) printf ("LMC0check: result %d\n", r); myassert (r >= LMC_EQUAL, "LMC0 check\n"); al = exampleArray (29, 1); if (verbose >= 2) al.showarray (); r = LMC0check (al, verbose); if (verbose >= 2) printf ("LMC0check: result %d (LMC_LESS %d)\n", r, LMC_LESS); myassert (r == LMC_LESS, "LMC0 check of example array 29\n"); } { cprintf (verbose, "%s: LMC0 check\n", bstr); array_link al = exampleArray (31, 1); if (verbose >= 2) al.showarray (); conference_transformation_t T (al); for (int i = 0; i < 80; i++) { T.randomize (); array_link alx = T.apply (al); lmc_t r = LMC0check (alx, verbose); if (verbose >= 2) { printfd ("%d: transformed array: r %d\n", i, r); alx.showarray (); } if (alx == al) myassert (r >= LMC_EQUAL, "result should be LMC_MORE\n"); else { myassert (r == LMC_LESS, "result should be LMC_LESS\n"); } } } { cprintf (verbose, "%s: random transformation for conference matrices\n", bstr); array_link al = exampleArray (19, 1); conference_transformation_t T (al); // T.randomizerowflips(); T.randomize (); conference_transformation_t Ti = T.inverse (); array_link alx = Ti.apply (T.apply (al)); if (0) { printf ("input array:\n"); al.showarray (); T.show (); printf ("transformed array:\n"); T.apply (al).showarray (); Ti.show (); alx.showarray (); } myassert (alx == al, "transformation of conference matrix\n"); } /* constructors */ { cprintf (verbose, "%s: constructors\n", bstr); array_transformation_t t; conference_transformation_t ct; } /* J-characteristics */ { cprintf (verbose, "%s: J-characteristics\n", bstr); array_link al = exampleArray (8, 1); const int mm[] = {-1, -1, 0, 0, 8, 16, 0, -1}; for (int jj = 2; jj < 7; jj++) { std::vector< int > jx = al.Jcharacteristics (jj); int j5max = vectormax (jx, 0); if (verbose >= 2) { printf ("oaunittest: jj %d: j5max %d\n", jj, j5max); } if (j5max != mm[jj]) { printfd ("j5max %d (should be %d)\n", j5max, mm[jj]); allgood = UNITTEST_FAIL; return allgood; } } } { cprintf (verbose, "%s: array transformations\n", bstr); const int N = 9; const int t = 3; arraydata_t adataX (3, N, t, 4); array_link al (adataX.N, adataX.ncols, -1); al.create_root (adataX); if (checkTransformationInverse (al)) allgood = UNITTEST_FAIL; if (checkTransformationComposition (al, verbose >= 2)) allgood = UNITTEST_FAIL; al = exampleArray (5, 1); if (checkTransformationInverse (al)) allgood = UNITTEST_FAIL; if (checkTransformationComposition (al)) allgood = UNITTEST_FAIL; for (int i = 0; i < 15; i++) { al = exampleArray (18, 0); if (checkConferenceComposition (al)) allgood = UNITTEST_FAIL; if (checkConferenceInverse (al)) allgood = UNITTEST_FAIL; al = exampleArray (19, 0); if (checkConferenceComposition (al)) allgood = UNITTEST_FAIL; if (checkConferenceInverse (al)) allgood = UNITTEST_FAIL; } } { cprintf (verbose, "%s: rank \n", bstr); const int idx[10] = {0, 1, 2, 3, 4, 6, 7, 8, 9}; const int rr[10] = {4, 11, 13, 18, 16, 4, 4, 29, 29}; for (int ii = 0; ii < 9; ii++) { array_link al = exampleArray (idx[ii], 0); myassert (al.is2level (), "unittest error: input array is not 2-level\n"); int r = arrayrankColPivQR (array2xf (al)); int r3 = (array2xf (al)).rank (); myassert (r == r3, "unittest error: rank of array"); if (verbose >= 2) { al.showarray (); printf ("unittest: rank of array %d: %d\n", idx[ii], r); } myassert (rr[ii] == r, "unittest error: rank of example matrix\n"); } } { cprintf (verbose, "%s: Doptimize \n", bstr); const int N = 40; const int t = 0; arraydata_t arrayclass (2, N, t, 6); std::vector< double > alpha (3); alpha[0] = 1; alpha[1] = 1; alpha[2] = 0; int niter = 5000; double t00 = get_time_ms (); DoptimReturn rr = Doptimize (arrayclass, 10, alpha, 0, DOPTIM_AUTOMATIC, niter); array_t ss[7] = {3, 3, 2, 2, 2, 2, 2}; arraydata_t arrayclassmixed (ss, 36, t, 5); rr = Doptimize (arrayclassmixed, 10, alpha, 0, DOPTIM_AUTOMATIC, niter); cprintf (verbose, "%s: Doptimize time %.3f [s] \n", bstr, get_time_ms () - t00); } { cprintf (verbose, "%s: J-characteristics for conference matrix\n", bstr); array_link al = exampleArray (19, 0); std::vector< int > j2 = Jcharacteristics_conference (al, 2); std::vector< int > j3 = Jcharacteristics_conference (al, 3); myassert (j2[0] == 0, "j2 value incorrect"); myassert (j2[1] == 0, "j2 value incorrect"); myassert (std::abs (j3[0]) == 1, "j3 value incorrect"); if (verbose >= 2) { al.showarray (); printf ("j2: "); display_vector (j2); printf ("\n"); printf ("j3: "); display_vector (j3); printf ("\n"); } } { // test PEC sequence cprintf (verbose, "%s: PEC sequence\n", bstr); for (int ii = 0; ii < 5; ii++) { array_link al = exampleArray (ii, 0); std::vector< double > pec = PECsequence (al); printf ("oaunittest: PEC for array %d: ", ii); display_vector (pec); printf (" \n"); } } { cprintf (verbose, "%s: D-efficiency test\n", bstr); // D-efficiency near-zero test { array_link al = exampleArray (14); double D = al.Defficiency (); std::vector< double > dd = al.Defficiencies (); printf ("D %f, D (method 2) %f\n", D, dd[0]); assert (fabs (D - dd[0]) < 1e-4); } { array_link al = exampleArray (15); double D = al.Defficiency (); std::vector< double > dd = al.Defficiencies (); printf ("D %f, D (method 2) %f\n", D, dd[0]); assert (fabs (D - dd[0]) < 1e-4); assert (fabs (D - 0.335063) < 1e-3); } } arraydata_t adata (2, 20, 2, 6); OAextend oaextendx; oaextendx.setAlgorithm ((algorithm_t)MODE_ORIGINAL, &adata); std::vector< arraylist_t > aa (adata.ncols + 1); printf ("OA unittest: create root array\n"); create_root (&adata, aa[adata.strength]); /** Test extend of arrays **/ { cprintf (verbose, "%s: extend arrays\n", bstr); setloglevel (SYSTEM); for (int kk = adata.strength; kk < adata.ncols; kk++) { aa[kk + 1] = extend_arraylist (aa[kk], adata, oaextendx); printf (" extend: column %d->%d: %ld->%ld arrays\n", kk, kk + 1, aa[kk].size (), aa[kk + 1].size ()); } if (aa[adata.ncols].size () != 75) { printf ("extended ?? to %d arrays\n", (int)aa[adata.ncols].size ()); } myassert (aa[adata.ncols].size () == 75, "number of arrays is incorrect"); aa[adata.ncols].size (); setloglevel (QUIET); } { cprintf (verbose, "%s: test LMC check\n", bstr); array_link al = exampleArray (1, 1); lmc_t r = LMCcheckOriginal (al); myassert (r != LMC_LESS, "LMC check of array in normal form"); for (int i = 0; i < 20; i++) { array_link alx = al.randomperm (); if (alx == al) continue; lmc_t r = LMCcheckOriginal (alx); myassert (r == LMC_LESS, "randomized array cannot be in minimal form"); } } { /** Test dof **/ cprintf (verbose, "%s: test delete-one-factor reduction\n", bstr); array_link al = exampleArray (4); cprintf (verbose >= 2, "LMC: \n"); al.reduceLMC (); cprintf (verbose >= 2, "DOP: \n"); al.reduceDOP (); } arraylist_t lst; { /** Test different methods **/ cprintf (verbose, "%s: test 2 different methods\n", bstr); const int s = 2; arraydata_t adata (s, 32, 3, 10); arraydata_t adata2 (s, 32, 3, 10); OAextend oaextendx; oaextendx.setAlgorithm ((algorithm_t)MODE_ORIGINAL, &adata); OAextend oaextendx2; oaextendx2.setAlgorithm ((algorithm_t)MODE_LMC_2LEVEL, &adata2); printf ("OA unittest: test 2-level algorithm on %s\n", adata.showstr ().c_str ()); std::vector< arraylist_t > aa (adata.ncols + 1); create_root (&adata, aa[adata.strength]); std::vector< arraylist_t > aa2 (adata.ncols + 1); create_root (&adata, aa2[adata.strength]); setloglevel (SYSTEM); for (int kk = adata.strength; kk < adata.ncols; kk++) { aa[kk + 1] = extend_arraylist (aa[kk], adata, oaextendx); aa2[kk + 1] = extend_arraylist (aa2[kk], adata2, oaextendx2); printf (" extend: column %d->%d: %ld->%ld arrays, 2-level method %ld->%ld arrays\n", kk, kk + 1, (long) aa[kk].size (), (long)aa[kk + 1].size (), aa2[kk].size (), aa2[kk + 1].size ()); if (aa[kk + 1] != aa2[kk + 1]) { printf ("oaunittest: error: 2-level algorithm unequal to original algorithm\n"); exit (1); } } setloglevel (QUIET); lst = aa[8]; } { cprintf (verbose, "%s: rank calculation using rankStructure\n", bstr); for (int i = 0; i < 27; i++) { array_link al = exampleArray (i, 0); if (al.n_columns < 5) continue; al = exampleArray (i, 1); rankStructure rs; rs.verbose = 0; int r = array2xf (al).rank (); int rc = rs.rankxf (al); if (verbose >= 2) { printf ("rank of example array %d: %d %d\n", i, r, rc); if (verbose >= 3) { al.showproperties (); } } myassert (r == rc, "rank calculations"); } } { cprintf (verbose, "%s: test dtable creation\n", bstr); for (int i = 0; i < 4; i++) { array_link al = exampleArray (5); array_link dtable = createJdtable (al); } } { cprintf (verbose, "%s: test Pareto calculation\n", bstr); double t0x = get_time_ms (); int nn = lst.size (); for (int k = 0; k < 5; k++) { for (int i = 0; i < nn; i++) { lst.push_back (lst[i]); } } Pareto< mvalue_t< long >, long > r = parsePareto (lst, 1); cprintf (verbose, "%s: test Pareto %d/%d: %.3f [s]\n", bstr, r.number (), r.numberindices (), (get_time_ms () - t0x)); } { cprintf (verbose, "%s: check reduction transformation\n", bstr); array_link al = exampleArray (6).reduceLMC (); arraydata_t adata = arraylink2arraydata (al); LMCreduction_t reduction (&adata); reduction.mode = OA_REDUCE; reduction.init_state = COPY; OAextend oaextend; oaextend.setAlgorithm (MODE_ORIGINAL, &adata); array_link alr = al.randomperm (); array_link al2 = reduction.transformation->apply (al); lmc_t tmp = LMCcheck (alr, adata, oaextend, reduction); array_link alx = reduction.transformation->apply (alr); bool c = alx == al; if (!c) { printf ("oaunittest: error: reduction of randomized array failed!\n"); printf ("-- al \n"); al.showarraycompact (); printf ("-- alr \n"); alr.showarraycompact (); printf ("-- alx \n"); alx.showarraycompact (); allgood = UNITTEST_FAIL; } } { cprintf (verbose, "%s: reduce randomized array\n", bstr); array_link al = exampleArray (3); arraydata_t adata = arraylink2arraydata (al); LMCreduction_t reduction (&adata); for (int ii = 0; ii < 50; ii++) { reduction.transformation->randomize (); array_link al2 = reduction.transformation->apply (al); array_link alr = al2.reduceLMC (); if (0) { printf ("\n reduction complete:\n"); al2.showarray (); printf (" --->\n"); alr.showarray (); } bool c = (al == alr); if (!c) { printf ("oaunittest: error: reduction of randomized array failed!\n"); allgood = UNITTEST_FAIL; } } } /* Calculate symmetry group */ { cprintf (verbose, "%s: calculate symmetry group\n", bstr); array_link al = exampleArray (2); symmetry_group sg = al.row_symmetry_group (); assert (sg.permsize () == sg.permsize_large ().toLong ()); // symmetry_group std::vector< int > vv; vv.push_back (0); vv.push_back (0); vv.push_back (1); symmetry_group sg2 (vv); assert (sg2.permsize () == 2); if (verbose >= 2) printf ("sg2: %ld\n", sg2.permsize ()); assert (sg2.ngroups == 2); } /* Test efficiencies */ { cprintf (verbose, "%s: efficiencies\n", bstr); std::vector< double > d; int vb = 1; array_link al; if (1) { al = exampleArray (9, vb); al.showproperties (); d = al.Defficiencies (0, 1); if (verbose >= 2) printf (" efficiencies: D %f Ds %f D1 %f Ds0 %f\n", d[0], d[1], d[2], d[3]); if (fabs (d[0] - al.Defficiency ()) > 1e-10) { printf ("oaunittest: error: Defficiency not good!\n"); allgood = UNITTEST_FAIL; } } al = exampleArray (8, vb); al.showproperties (); d = al.Defficiencies (); if (verbose >= 2) printf (" efficiencies: D %f Ds %f D1 %f\n", d[0], d[1], d[2]); if (fabs (d[0] - al.Defficiency ()) > 1e-10) { printf ("oaunittest: error: Defficiency of examlple array 8 not good!\n"); } al = exampleArray (13, vb); if (verbose >= 3) { al.showarray (); al.showproperties (); } d = al.Defficiencies (0, 1); if (verbose >= 2) printf (" efficiencies: D %f Ds %f D1 %f\n", d[0], d[1], d[2]); if ((fabs (d[0] - 0.939014) > 1e-4) || (fabs (d[3] - 0.896812) > 1e-4) || (fabs (d[2] - 1) > 1e-4)) { printf ("ERROR: D-efficiencies of example array 13 incorrect! \n"); d = al.Defficiencies (2, 1); printf (" efficiencies: D %f Ds %f D1 %f Ds0 %f\n", d[0], d[1], d[2], d[3]); allgood = UNITTEST_FAIL; exit (1); } for (int ii = 11; ii < 11; ii++) { printf ("ii %d: ", ii); al = exampleArray (ii, vb); al.showarray (); al.showproperties (); d = al.Defficiencies (); if (verbose >= 2) printf (" efficiencies: D %f Ds %f D1 %f\n", d[0], d[1], d[2]); } } { cprintf (verbose, "%s: test robustness\n", bstr); array_link A (0, 8, 0); printf ("should return an error\n "); A.Defficiencies (); A = array_link (1, 8, 0); printf ("should return an error\n "); A.at (0, 0) = -2; A.Defficiencies (); } { cprintf (verbose, "%s: test nauty\n", bstr); array_link alr = exampleArray (7, 0); if (unittest_nautynormalform (alr, 1) == 0) { printf ("oaunittest: error: unittest_nautynormalform returns an error!\n"); } } #ifdef HAVE_BOOST if (writetests) { cprintf (verbose, "OA unittest: reading and writing of files\n"); boost::filesystem::path tmpdir = boost::filesystem::temp_directory_path (); boost::filesystem::path temp = boost::filesystem::unique_path ("test-%%%%%%%.oa"); const std::string tempstr = (tmpdir / temp).native (); if (verbose >= 2) printf ("generate text OA file: %s\n", tempstr.c_str ()); int nrows = 16; int ncols = 8; int narrays = 10; arrayfile_t afile (tempstr.c_str (), nrows, ncols, narrays, ATEXT); for (int i = 0; i < narrays; i++) { array_link al (nrows, ncols, array_link::INDEX_DEFAULT); afile.append_array (al); } afile.closefile (); arrayfile_t af (tempstr.c_str (), 0); std::cout << " " << af.showstr () << std::endl; af.closefile (); // check read/write of binary file arraylist_t ll0; ll0.push_back (exampleArray (7)); ll0.push_back (exampleArray (7).randomcolperm ()); writearrayfile (tempstr.c_str (), ll0, ABINARY); arraylist_t ll = readarrayfile (tempstr.c_str ()); myassert (ll0.size () == ll.size (), "read and write of arrays: size of list"); for (size_t i = 0; i < ll0.size (); i++) { myassert (ll0[i] == ll[i], "read and write of arrays: array unequal"); } ll0.resize (0); ll0.push_back (exampleArray (24)); writearrayfile (tempstr.c_str (), ll0, ABINARY_DIFFZERO); ll = readarrayfile (tempstr.c_str ()); myassert (ll0.size () == ll.size (), "read and write of arrays: size of list"); for (size_t i = 0; i < ll0.size (); i++) { myassert (ll0[i] == ll[i], "read and write of arrays: array unequal"); } } #endif { cprintf (verbose, "OA unittest: test nauty\n"); array_link al = exampleArray (5, 2); arraydata_t arrayclass = arraylink2arraydata (al); for (int i = 0; i < 20; i++) { array_link alx = al; alx.randomperm (); array_transformation_t t1 = reduceOAnauty (al); array_link alr1 = t1.apply (al); array_transformation_t t2 = reduceOAnauty (alx); array_link alr2 = t2.apply (alx); if (alr1 != alr2) printf ("oaunittest: error: Nauty reductions unequal!\n"); allgood = UNITTEST_FAIL; } } cprintf (verbose, "OA unittest: complete %.3f [s]!\n", (get_time_ms () - t0)); cprintf (verbose, "OA unittest: also run ptest.py to perform checks!\n"); if (allgood) { printf ("OA unittest: all tests ok\n"); return UNITTEST_SUCCESS; } else { printf ("OA unittest: ERROR!\n"); return UNITTEST_FAIL; } }
/** * @brief Main function for oaextendmpi and oaextendsingle * @param argc * @param argv[] * @return */ int main (int argc, char *argv[]) { #ifdef OAEXTEND_SINGLECORE const int n_processors = 1; const int this_rank = 0; #else MPI::Init (argc, argv); const int n_processors = MPI::COMM_WORLD.Get_size (); const int this_rank = MPI::COMM_WORLD.Get_rank (); #endif // printf("MPI: this_rank %d\n", this_rank); /*----------SET STARTING ARRAY(S)-----------*/ if (this_rank != MASTER) { #ifdef OAEXTEND_MULTICORE slave_print (QUIET, "M: running core %d/%d\n", this_rank, n_processors); #endif algorithm_t algorithm = MODE_INVALID; AnyOption *opt = parseOptions (argc, argv, algorithm); OAextend oaextend; oaextend.setAlgorithm (algorithm); #ifdef OAEXTEND_MULTICORE log_print (NORMAL, "slave: receiving algorithm int\n"); algorithm = (algorithm_t)receive_int_slave (); oaextend.setAlgorithm (algorithm); // printf("slave %d: receive algorithm %d\n", this_rank, algorithm); #endif extend_slave_code (this_rank, oaextend); delete opt; } else { double Tstart = get_time_ms (); int nr_extensions; arraylist_t solutions, extensions; algorithm_t algorithm = MODE_INVALID; AnyOption *opt = parseOptions (argc, argv, algorithm); print_copyright (); int loglevel = opt->getIntValue ('l', NORMAL); setloglevel (loglevel); int dosort = opt->getIntValue ('s', 1); int userowsymm = opt->getIntValue ("rowsymmetry", 1); int maxk = opt->getIntValue ("maxk", 100000); int initcolprev = opt->getIntValue ("initcolprev", 1); const bool streaming = opt->getFlag ("streaming"); bool restart = false; if (opt->getValue ("restart") != NULL || opt->getValue ('r') != NULL) { restart = true; } const char *oaconfigfile = opt->getStringValue ('c', "oaconfig.txt"); const char *resultprefix = opt->getStringValue ('o', "result"); arrayfile::arrayfilemode_t mode = arrayfile_t::parseModeString (opt->getStringValue ('f', "T")); OAextend oaextend; oaextend.setAlgorithm (algorithm); if (streaming) { logstream (SYSTEM) << "operating in streaming mode, sorting of arrays will not work " << std::endl; oaextend.extendarraymode = OAextend::STOREARRAY; } // J5_45 int xx = opt->getFlag ('x'); if (xx) { oaextend.j5structure = J5_45; } if (userowsymm == 0) { oaextend.use_row_symmetry = userowsymm; printf ("use row symmetry -> %d\n", oaextend.use_row_symmetry); } if (opt->getFlag ('g')) { std::cout << "only generating arrays (no LMC check)" << endl; oaextend.checkarrays = 0; } if (opt->getFlag ("help") || (opt->getValue ("coptions") != NULL)) { if (opt->getFlag ("help")) { opt->printUsage (); } if (opt->getValue ("coptions") != NULL) { print_options (cout); } } else { logstream (QUIET) << "#time start: " << currenttime () << std::endl; arraydata_t *ad; ad = readConfigFile (oaconfigfile); ad->lmc_overflow_check (); if (ad == 0) { return 1; } log_print (NORMAL, "Using design file: %s (runs %d, strength %d)\n", oaconfigfile, ad->N, ad->strength); if (oaextend.getAlgorithm () == MODE_AUTOSELECT) { oaextend.setAlgorithmAuto (ad); } #ifdef OAEXTEND_SINGLECORE if (initcolprev == 0) { log_print (NORMAL, "setting oaextend.init_column_previous to %d\n", INITCOLUMN_ZERO); oaextend.init_column_previous = INITCOLUMN_ZERO; } #endif #ifdef OAEXTEND_MULTICORE int alg = oaextend.getAlgorithm (); for (int i = 0; i < n_processors; i++) { if (i == MASTER) { continue; } log_print (NORMAL, "MASTER: sending algorithm %d to slave %d\n", alg, i); send_int (alg, i); } #endif colindex_t col_start; log_print (SYSTEM, "using algorithm %d (%s)\n", oaextend.getAlgorithm (), oaextend.getAlgorithmName ().c_str ()); if (log_print (NORMAL, "")) { cout << oaextend.__repr__ (); } if (restart) { // start from result file int initres = init_restart (opt->getValue ('r'), col_start, solutions); if (initres == 1) { // check if restarting went OK logstream (SYSTEM) << "Problem with restart from " << opt->getValue ('r') << "" << endl; #ifdef OAEXTEND_MPI MPI_Abort (MPI_COMM_WORLD, 1); #endif exit (1); } if (dosort) { double Ttmp = get_time_ms (); sort (solutions.begin (), solutions.end ()); // solutions.sort(); log_print (QUIET, " sorting of initial solutions: %.3f [s]\n", get_time_ms () - Ttmp); } // check that oaconfig agrees with loaded arrays if (solutions.size () > 0) { if (ad->N != solutions[0].n_rows) { printf ("Problem: oaconfig does not agree with loaded arrays!\n"); // free_sols(solutions); ?? solutions.clear (); } } } else { // starting with root if (check_divisibility (ad) == false) { log_print (SYSTEM, "ERROR: Failed divisibility test!\n"); #ifdef OAEXTEND_MPI MPI_Abort (MPI_COMM_WORLD, 1); #endif exit (1); } create_root (ad, solutions); col_start = ad->strength; } /*-----------MAIN EXTENSION LOOP-------------*/ log_print (SYSTEM, "M: running with %d procs\n", n_processors); maxk = std::min (maxk, ad->ncols); time_t seconds; for (colindex_t current_col = col_start; current_col < maxk; current_col++) { fflush (stdout); arraydata_t *adcol = new arraydata_t (ad, current_col + 1); if (streaming) { string fname = resultprefix; fname += "-streaming"; fname += "-" + oafilestring (ad); logstream (NORMAL) << "oaextend: streaming mode: create file " << fname << std::endl; int nb = arrayfile_t::arrayNbits (*ad); oaextend.storefile.createfile (fname, adcol->N, ad->ncols, -1, ABINARY, nb); } log_print (SYSTEM, "Starting with column %d (%d, total time: %.2f [s])\n", current_col + 1, (int)solutions.size (), get_time_ms () - Tstart); nr_extensions = 0; arraylist_t::const_iterator cur_extension; int csol = 0; for (cur_extension = solutions.begin (); cur_extension != solutions.end (); cur_extension++) { print_progress (csol, solutions, extensions, Tstart, current_col); logstream (NORMAL) << cur_extension[0]; if (n_processors == 1) { nr_extensions += extend_array (*cur_extension, adcol, current_col, extensions, oaextend); } else { #ifdef OAEXTEND_MPI throw_runtime_exception("mpi version of oextend is no longer supported"); double Ttmp = get_time_ms (); int slave = collect_solutions_single (extensions, adcol); log_print (DEBUG, " time: %.2f, collect time %.2f\n", (get_time_ms () - Tstart), (get_time_ms () - Ttmp)); /* OPTIMIZE: send multiple arrays to slave 1 once step */ extend_array_mpi (cur_extension->array, 1, adcol, current_col, slave); #endif } #ifdef OAEXTEND_MPI if ((csol + 1) % nsolsync == 0) { collect_solutions_all (extensions, adcol); } #endif // OPTIMIZE: periodically write part of the solutions to disk csol++; /* increase current solution */ } #ifdef OAEXTEND_MPI collect_solutions_all (extensions, adcol); #endif if (checkloglevel (NORMAL)) { csol = 0; for (cur_extension = extensions.begin (); cur_extension != extensions.end (); cur_extension++) { log_print (DEBUG, "%i: -----\n", ++csol); logstream (DEBUG) << cur_extension[0]; } } if (dosort) { log_print (DEBUG, "Sorting solutions, necessary for multi-processor code\n"); double Ttmp = get_time_ms (); sort (extensions.begin (), extensions.end ()); log_print (DEBUG, " sorting time: %.3f [s]\n", get_time_ms () - Ttmp); } save_arrays (extensions, adcol, resultprefix, mode); solutions.swap (extensions); // swap old and newly found solutions extensions.clear (); // clear old to free up space for new extensions log_print (SYSTEM, "Done with column %i, total of %i solutions (time %.2f s))\n", current_col + 1, (int)solutions.size (), get_time_ms () - Tstart); delete adcol; #ifdef OAANALYZE_DISCR logstream (NORMAL) << "Discriminant: " << endl; print_discriminant (ad->N, current_col + 1); #endif } /*------------------------*/ time (&seconds); struct tm *tminfo; tminfo = localtime (&seconds); log_print (SYSTEM, "TIME: %.2f s, %s", get_time_ms () - Tstart, asctime (tminfo)); logstream (QUIET) << "#time end: " << currenttime () << std::endl; logstream (QUIET) << "#time total: " << printfstring ("%.1f", get_time_ms () - Tstart) << " [s]" << std::endl; solutions.clear (); delete ad; #ifdef OAEXTEND_MPI stop_slaves (); #endif } delete opt; } /* end of master code */ #ifdef OAEXTEND_MPI MPI_Finalize (); #endif return 0; }
int main(int argc, char **argv) { options_t options; int doversion = 0; int dohelp = 0; int userclasses = 0; int ch; int option_index = 0; char prefix[IF_NAMESIZE + 3]; pid_t pid; int debug = 0; int i; const struct option longopts[] = { {"arp", no_argument, NULL, 'a'}, {"script", required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, {"hostname", required_argument, NULL, 'h'}, {"classid", required_argument, NULL, 'i'}, {"release", no_argument, NULL, 'k'}, {"leasetime", required_argument, NULL, 'l'}, {"metric", required_argument, NULL, 'm'}, {"renew", no_argument, NULL, 'n'}, {"persistent", no_argument, NULL, 'p'}, {"request", required_argument, NULL, 's'}, {"timeout", required_argument, NULL, 't'}, {"userclass", required_argument, NULL, 'u'}, {"fqdn", optional_argument, NULL, 'F'}, {"nogateway", no_argument, NULL, 'G'}, {"sethostname", no_argument, NULL, 'H'}, {"clientid", required_argument, NULL, 'I'}, {"nomtu", no_argument, NULL, 'M'}, {"nontp", no_argument, NULL, 'N'}, {"nodns", no_argument, NULL, 'R'}, {"nonis", no_argument, NULL, 'Y'}, {"help", no_argument, &dohelp, 1}, {"version", no_argument, &doversion, 1}, {NULL, 0, NULL, 0} }; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) close (i); openlog (PACKAGE, LOG_PID, LOG_LOCAL0); memset (&options, 0, sizeof (options_t)); options.script = (char *) DEFAULT_SCRIPT; snprintf (options.classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options.doarp = false; options.dodns = true; options.domtu = true; options.donis = true; options.dontp = true; options.dogateway = true; options.daemonise = true; options.timeout = DEFAULT_TIMEOUT; while ((ch = getopt_long(argc, argv, "ac:dh:i:kl:m:nps:t:u:F:GHI:MNRY", longopts, &option_index)) != -1) switch (ch) { case 0: if (longopts[option_index].flag) break; logger (LOG_ERR, "option `%s' should set a flag", longopts[option_index].name); exit (EXIT_FAILURE); break; case 'a': options.doarp = true; break; case 'c': options.script = optarg; break; case 'd': debug++; switch (debug) { case 1: setloglevel (LOG_DEBUG); break; case 2: options.daemonise = false; break; } break; case 'h': if (strlen (optarg) > sizeof (options.hostname)) { logger (LOG_ERR, "`%s' too long for HostName string, max is %d", optarg, sizeof (options.hostname)); exit (EXIT_FAILURE); } else strlcpy (options.hostname, optarg, sizeof (options.hostname)); break; case 'i': if (strlen (optarg) > CLASS_ID_MAX_LEN) { logger (LOG_ERR, "`%s' too long for ClassID string, max is %d", optarg, CLASS_ID_MAX_LEN); exit (EXIT_FAILURE); } else strlcpy (options.classid, optarg, sizeof (options.classid)); break; case 'k': options.signal = SIGHUP; break; case 'l': STRINGINT (optarg, options.leasetime); if (options.leasetime <= 0) { logger (LOG_ERR, "leasetime must be a positive value"); exit (EXIT_FAILURE); } break; case 'm': STRINGINT (optarg, options.metric); break; case 'n': options.signal = SIGALRM; break; case 'p': options.persistent = true; break; case 's': if (! inet_aton (optarg, &options.requestaddress)) { logger (LOG_ERR, "`%s' is not a valid IP address", optarg); exit (EXIT_FAILURE); } break; case 't': STRINGINT (optarg, options.timeout); if (options.timeout < 0) { logger (LOG_ERR, "timeout must be a positive value"); exit (EXIT_FAILURE); } break; case 'u': { int offset = 0; for (i = 0; i < userclasses; i++) offset += (int) options.userclass[offset] + 1; if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) { logger (LOG_ERR, "userclass overrun, max is %d", USERCLASS_MAX_LEN); exit (EXIT_FAILURE); } userclasses++; memcpy (options.userclass + offset + 1 , optarg, strlen (optarg)); options.userclass[offset] = strlen (optarg); options.userclass_len += (strlen (optarg)) + 1; } break; case 'F': if (strncmp (optarg, "none", strlen (optarg)) == 0) options.fqdn = FQDN_NONE; else if (strncmp (optarg, "ptr", strlen (optarg)) == 0) options.fqdn = FQDN_PTR; else if (strncmp (optarg, "both", strlen (optarg)) == 0) options.fqdn = FQDN_BOTH; else { logger (LOG_ERR, "invalid value `%s' for FQDN", optarg); exit (EXIT_FAILURE); } break; case 'G': options.dogateway = false; break; case 'H': options.dohostname = true; break; case 'I': if (strlen (optarg) > CLIENT_ID_MAX_LEN) { logger (LOG_ERR, "`%s' is too long for ClientID, max is %d", optarg, CLIENT_ID_MAX_LEN); exit (EXIT_FAILURE); } else strlcpy (options.clientid, optarg, sizeof (options.clientid)); break; case 'M': options.domtu = false; break; case 'N': options.dontp = false; break; case 'R': options.dodns = false; break; case 'Y': options.donis = false; break; case '?': usage (); exit (EXIT_FAILURE); default: usage (); exit (EXIT_FAILURE); } if (doversion) printf (""PACKAGE" "VERSION"\n"); if (dohelp) usage (); if (optind < argc) { if (strlen (argv[optind]) > IF_NAMESIZE) { logger (LOG_ERR, "`%s' is too long for an interface name (max=%d)", argv[optind], IF_NAMESIZE); exit (EXIT_FAILURE); } strlcpy (options.interface, argv[optind], sizeof (options.interface)); } else { /* If only version was requested then exit now */ if (doversion || dohelp) exit (EXIT_SUCCESS); logger (LOG_ERR, "no interface specified"); exit (EXIT_FAILURE); } /* If we are given a hostname use it and set FQDN if it contains a . */ if (! options.hostname[0]) { gethostname (options.hostname, sizeof (options.hostname)); if (strcmp (options.hostname, "(none)") == 0 || strcmp (options.hostname, "localhost") == 0) memset (options.hostname, 0, sizeof (options.hostname)); } if (strchr (options.hostname, '.')) { if (options.fqdn == FQDN_DISABLE) options.fqdn = FQDN_BOTH; } else options.fqdn = FQDN_DISABLE; if (geteuid ()) { logger (LOG_ERR, "you need to be root to run "PACKAGE); exit (EXIT_FAILURE); } snprintf (prefix, IF_NAMESIZE, "%s: ", options.interface); setlogprefix (prefix); snprintf (options.pidfile, sizeof (options.pidfile), PIDFILE, options.interface); if (options.signal != 0) { int killed = -1; pid = read_pid (options.pidfile); if (pid != 0) logger (LOG_INFO, "sending signal %d to pid %d", options.signal, pid); if (! pid || (killed = kill (pid, options.signal))) logger (options.signal == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); if (pid != 0 && (options.signal != SIGALRM || killed != 0)) unlink (options.pidfile); if (killed == 0) exit (EXIT_SUCCESS); if (options.signal != SIGALRM) exit (EXIT_FAILURE); } chdir ("/"); umask (022); if (mkdir (CONFIGDIR, S_IRUSR |S_IWUSR |S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", CONFIGDIR, strerror (errno)); exit (EXIT_FAILURE); } if (mkdir (ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST ) { logger (LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror (errno)); exit (EXIT_FAILURE); } if ((pid = read_pid (options.pidfile)) > 0 && kill (pid, 0) == 0) { logger (LOG_ERR, ""PACKAGE" already running (%s)", options.pidfile); exit (EXIT_FAILURE); } make_pid (options.pidfile); logger (LOG_INFO, PACKAGE " " VERSION " starting"); if (dhcp_run (&options)) { unlink (options.pidfile); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }