static void test_get_process_cmdline_harder(void) { char path[] = "/tmp/test-cmdlineXXXXXX"; _cleanup_close_ int fd = -1; _cleanup_free_ char *line = NULL; pid_t pid; if (geteuid() != 0) return; #ifdef HAVE_VALGRIND_VALGRIND_H /* valgrind patches open(/proc//cmdline) * so, test_get_process_cmdline_harder fails always * See https://github.com/systemd/systemd/pull/3555#issuecomment-226564908 */ if (RUNNING_ON_VALGRIND) return; #endif pid = fork(); if (pid > 0) { siginfo_t si; (void) wait_for_terminate(pid, &si); assert_se(si.si_code == CLD_EXITED); assert_se(si.si_status == 0); return; } assert_se(pid == 0); assert_se(unshare(CLONE_NEWNS) >= 0); fd = mkostemp(path, O_CLOEXEC); assert_se(fd >= 0); assert_se(mount(path, "/proc/self/cmdline", "bind", MS_BIND, NULL) >= 0); assert_se(unlink(path) >= 0); assert_se(prctl(PR_SET_NAME, "testa") >= 0); assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT); assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0); assert_se(streq(line, "[testa]")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 1, true, &line) >= 0); assert_se(streq(line, "")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 2, true, &line) >= 0); assert_se(streq(line, "[")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 3, true, &line) >= 0); assert_se(streq(line, "[.")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 4, true, &line) >= 0); assert_se(streq(line, "[..")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 5, true, &line) >= 0); assert_se(streq(line, "[...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 6, true, &line) >= 0); assert_se(streq(line, "[...]")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 7, true, &line) >= 0); assert_se(streq(line, "[t...]")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 8, true, &line) >= 0); assert_se(streq(line, "[testa]")); line = mfree(line); assert_se(write(fd, "\0\0\0\0\0\0\0\0\0", 10) == 10); assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT); assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0); assert_se(streq(line, "[testa]")); line = mfree(line); assert_se(write(fd, "foo\0bar\0\0\0\0\0", 10) == 10); assert_se(get_process_cmdline(getpid(), 0, false, &line) >= 0); assert_se(streq(line, "foo bar")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0); assert_se(streq(line, "foo bar")); line = mfree(line); assert_se(write(fd, "quux", 4) == 4); assert_se(get_process_cmdline(getpid(), 0, false, &line) >= 0); assert_se(streq(line, "foo bar quux")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0); assert_se(streq(line, "foo bar quux")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 1, true, &line) >= 0); assert_se(streq(line, "")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 2, true, &line) >= 0); assert_se(streq(line, ".")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 3, true, &line) >= 0); assert_se(streq(line, "..")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 4, true, &line) >= 0); assert_se(streq(line, "...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 5, true, &line) >= 0); assert_se(streq(line, "f...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 6, true, &line) >= 0); assert_se(streq(line, "fo...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 7, true, &line) >= 0); assert_se(streq(line, "foo...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 8, true, &line) >= 0); assert_se(streq(line, "foo...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 9, true, &line) >= 0); assert_se(streq(line, "foo b...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 10, true, &line) >= 0); assert_se(streq(line, "foo ba...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 11, true, &line) >= 0); assert_se(streq(line, "foo bar...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 12, true, &line) >= 0); assert_se(streq(line, "foo bar...")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 13, true, &line) >= 0); assert_se(streq(line, "foo bar quux")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 14, true, &line) >= 0); assert_se(streq(line, "foo bar quux")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 1000, true, &line) >= 0); assert_se(streq(line, "foo bar quux")); line = mfree(line); assert_se(ftruncate(fd, 0) >= 0); assert_se(prctl(PR_SET_NAME, "aaaa bbbb cccc") >= 0); assert_se(get_process_cmdline(getpid(), 0, false, &line) == -ENOENT); assert_se(get_process_cmdline(getpid(), 0, true, &line) >= 0); assert_se(streq(line, "[aaaa bbbb cccc]")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 10, true, &line) >= 0); assert_se(streq(line, "[aaaa...]")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 11, true, &line) >= 0); assert_se(streq(line, "[aaaa...]")); line = mfree(line); assert_se(get_process_cmdline(getpid(), 12, true, &line) >= 0); assert_se(streq(line, "[aaaa b...]")); line = mfree(line); safe_close(fd); _exit(0); }
static void test_config_parse_rlimit(void) { struct rlimit * rl[_RLIMIT_MAX] = {}; assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55:66", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55); assert_se(rl[RLIMIT_NOFILE]->rlim_max == 66); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity:infinity", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max); rl[RLIMIT_NOFILE]->rlim_cur = 10; rl[RLIMIT_NOFILE]->rlim_max = 20; /* Invalid values don't change rl */ assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "10:20:30", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10); assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "wat:wat", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10); assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "66:wat", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10); assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "200:100", rl, NULL) >= 0); assert_se(rl[RLIMIT_NOFILE]); assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 10); assert_se(rl[RLIMIT_NOFILE]->rlim_max == 20); rl[RLIMIT_NOFILE] = mfree(rl[RLIMIT_NOFILE]); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0); assert_se(rl[RLIMIT_CPU]); assert_se(rl[RLIMIT_CPU]->rlim_cur == 56); assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "57s", rl, NULL) >= 0); assert_se(rl[RLIMIT_CPU]); assert_se(rl[RLIMIT_CPU]->rlim_cur == 57); assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "40s:1m", rl, NULL) >= 0); assert_se(rl[RLIMIT_CPU]); assert_se(rl[RLIMIT_CPU]->rlim_cur == 40); assert_se(rl[RLIMIT_CPU]->rlim_max == 60); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "infinity", rl, NULL) >= 0); assert_se(rl[RLIMIT_CPU]); assert_se(rl[RLIMIT_CPU]->rlim_cur == RLIM_INFINITY); assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "1234ms", rl, NULL) >= 0); assert_se(rl[RLIMIT_CPU]); assert_se(rl[RLIMIT_CPU]->rlim_cur == 2); assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max); rl[RLIMIT_CPU] = mfree(rl[RLIMIT_CPU]); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58", rl, NULL) >= 0); assert_se(rl[RLIMIT_RTTIME]); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58:60", rl, NULL) >= 0); assert_se(rl[RLIMIT_RTTIME]); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58); assert_se(rl[RLIMIT_RTTIME]->rlim_max == 60); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s", rl, NULL) >= 0); assert_se(rl[RLIMIT_RTTIME]); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s:123s", rl, NULL) >= 0); assert_se(rl[RLIMIT_RTTIME]); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC); assert_se(rl[RLIMIT_RTTIME]->rlim_max == 123 * USEC_PER_SEC); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity", rl, NULL) >= 0); assert_se(rl[RLIMIT_RTTIME]); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity:infinity", rl, NULL) >= 0); assert_se(rl[RLIMIT_RTTIME]); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "2345ms", rl, NULL) >= 0); assert_se(rl[RLIMIT_RTTIME]); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 2345 * USEC_PER_MSEC); assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max); rl[RLIMIT_RTTIME] = mfree(rl[RLIMIT_RTTIME]); }
static int set_machine_info(Context *c, sd_bus_message *m, int prop, sd_bus_message_handler_t cb, sd_bus_error *error) { int interactive; const char *name; int r; assert(c); assert(m); r = sd_bus_message_read(m, "sb", &name, &interactive); if (r < 0) return r; if (isempty(name)) name = NULL; if (streq_ptr(name, c->data[prop])) return sd_bus_reply_method_return(m, NULL); /* Since the pretty hostname should always be changed at the * same time as the static one, use the same policy action for * both... */ r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, prop == PROP_PRETTY_HOSTNAME ? "org.freedesktop.hostname1.set-static-hostname" : "org.freedesktop.hostname1.set-machine-info", NULL, interactive, UID_INVALID, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ if (isempty(name)) { c->data[prop] = mfree(c->data[prop]); } else { char *h; /* The icon name might ultimately be used as file * name, so better be safe than sorry */ if (prop == PROP_ICON_NAME && !filename_is_valid(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid icon name '%s'", name); if (prop == PROP_PRETTY_HOSTNAME && string_has_cc(name, NULL)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid pretty host name '%s'", name); if (prop == PROP_CHASSIS && !valid_chassis(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid chassis '%s'", name); if (prop == PROP_DEPLOYMENT && !valid_deployment(name)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid deployment '%s'", name); if (prop == PROP_LOCATION && string_has_cc(name, NULL)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid location '%s'", name); h = strdup(name); if (!h) return -ENOMEM; free(c->data[prop]); c->data[prop] = h; } r = context_write_data_machine_info(c); if (r < 0) { log_error_errno(r, "Failed to write machine info: %m"); return sd_bus_error_set_errnof(error, r, "Failed to write machine info: %s", strerror(-r)); } log_info("Changed %s to '%s'", prop == PROP_PRETTY_HOSTNAME ? "pretty host name" : prop == PROP_DEPLOYMENT ? "deployment" : prop == PROP_LOCATION ? "location" : prop == PROP_CHASSIS ? "chassis" : "icon name", strna(c->data[prop])); (void) sd_bus_emit_properties_changed( sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", prop == PROP_PRETTY_HOSTNAME ? "PrettyHostname" : prop == PROP_DEPLOYMENT ? "Deployment" : prop == PROP_LOCATION ? "Location" : prop == PROP_CHASSIS ? "Chassis" : "IconName" , NULL); return sd_bus_reply_method_return(m, NULL); }
// returns false and sets g_errno on error bool Title::setTitle ( Xml *xml, Words *words, int32_t maxTitleLen, Query *query, LinkInfo *linkInfo, Url *firstUrl, const char *filteredRootTitleBuf, int32_t filteredRootTitleBufSize, uint8_t contentType, uint8_t langId, int32_t niceness ) { // make Msg20.cpp faster if it is just has // Msg20Request::m_setForLinkInfo set to true, no need to extricate a title. if ( maxTitleLen <= 0 ) { return true; } m_niceness = niceness; m_maxTitleLen = maxTitleLen; // if this is too big the "first line" algo can be huge!!! // and really slow everything way down with a huge title candidate int32_t maxTitleWords = 128; // assume no title reset(); int32_t NW = words->getNumWords(); // // now get all the candidates // // . allow up to 100 title CANDIDATES // . "as" is the word # of the first word in the candidate // . "bs" is the word # of the last word IN the candidate PLUS ONE int32_t n = 0; int32_t as[MAX_TIT_CANDIDATES]; int32_t bs[MAX_TIT_CANDIDATES]; float scores[MAX_TIT_CANDIDATES]; Words *cptrs[MAX_TIT_CANDIDATES]; int32_t types[MAX_TIT_CANDIDATES]; int32_t parent[MAX_TIT_CANDIDATES]; // record the scoring algos effects float baseScore [MAX_TIT_CANDIDATES]; float noCapsBoost [MAX_TIT_CANDIDATES]; float qtermsBoost [MAX_TIT_CANDIDATES]; float inCommonCandBoost[MAX_TIT_CANDIDATES]; // reset these for ( int32_t i = 0 ; i < MAX_TIT_CANDIDATES ; i++ ) { // assume no parent parent[i] = -1; } // xml and words class for each link info, rss item Xml tx[MAX_TIT_CANDIDATES]; Words tw[MAX_TIT_CANDIDATES]; int32_t ti = 0; // restrict how many link texts and rss blobs we check for titles // because title recs like www.google.com have hundreds and can // really slow things down to like 50ms for title generation int32_t kcount = 0; int32_t rcount = 0; //int64_t x = gettimeofdayInMilliseconds(); // . get every link text // . TODO: repeat for linkInfo2, the imported link text for ( Inlink *k = NULL; linkInfo && (k = linkInfo->getNextInlink(k)) ; ) { // breathe QUICKPOLL(m_niceness); // fast skip check for link text if ( k->size_linkText >= 3 && ++kcount >= 20 ) continue; // fast skip check for rss item if ( k->size_rssItem > 10 && ++rcount >= 20 ) continue; // set Url Url u; u.set( k->getUrl(), k->size_urlBuf ); // is it the same host as us? bool sh = true; // skip if not from same host and should be if ( firstUrl->getHostLen() != u.getHostLen() ) { sh = false; } // skip if not from same host and should be if ( strncmp( firstUrl->getHost(), u.getHost(), u.getHostLen() ) ) { sh = false; } // get the link text if ( k->size_linkText >= 3 ) { char *p = k->getLinkText(); int32_t plen = k->size_linkText - 1; if ( ! verifyUtf8 ( p , plen ) ) { log("title: set4 bad link text from url=%s", k->getUrl()); continue; } // now the words. if ( !tw[ti].set( k->getLinkText(), k->size_linkText - 1, true, 0 ) ) { return false; } // set the bookends, it is the whole thing cptrs [n] = &tw[ti]; as [n] = 0; bs [n] = tw[ti].getNumWords(); // score higher if same host if ( sh ) scores[n] = 1.05; // do not count so high if remote! else scores[n] = 0.80; // set the type if ( sh ) types [n] = TT_LINKTEXTLOCAL; else types [n] = TT_LINKTEXTREMOTE; // another candidate n++; // use xml and words ti++; // break out if too many already. save some for below. if ( n + 30 >= MAX_TIT_CANDIDATES ) break; } // get the rss item if ( k->size_rssItem <= 10 ) continue; // . returns false and sets g_errno on error // . use a 0 for niceness if ( ! k->setXmlFromRSS ( &tx[ti] , 0 ) ) return false; // get the word range int32_t tslen; bool isHtmlEnc; char *ts = tx[ti].getRSSTitle ( &tslen , &isHtmlEnc ); // skip if not in the rss if ( ! ts ) continue; // skip if empty if ( tslen <= 0 ) continue; // now set words to that if ( !tw[ti].set( ts, tslen, true, 0 ) ) { return false; } // point to that cptrs [n] = &tw[ti]; as [n] = 0; bs [n] = tw[ti].getNumWords(); // increment since we are using it ti++; // base score for rss title if ( sh ) scores[n] = 5.0; // if not same host, treat like link text else scores[n] = 2.0; // set the type if ( sh ) types [n] = TT_RSSITEMLOCAL; else types [n] = TT_RSSITEMREMOTE; // advance n++; // break out if too many already. save some for below. if ( n + 30 >= MAX_TIT_CANDIDATES ) break; } //logf(LOG_DEBUG,"title: took1=%" PRId64,gettimeofdayInMilliseconds()-x); //x = gettimeofdayInMilliseconds(); // . set the flags array // . indicates what words are in title candidates already, but // that is set below // . up here we set words that are not allowed to be in candidates, // like words that are in a link that is not a self link // . alloc for it char *flags = NULL; char localBuf[10000]; int32_t need = words->getNumWords(); if ( need <= 10000 ) { flags = (char *)localBuf; } else { flags = (char *)mmalloc(need,"TITLEflags"); } if ( ! flags ) { return false; } // clear it memset ( flags , 0 , need ); // check tags in body nodeid_t *tids = words->getTagIds(); // scan to set link text flags // loop over all "words" in the html body char inLink = false; char selfLink = false; for ( int32_t i = 0 ; i < NW ; i++ ) { // breathe QUICKPOLL(m_niceness); // if in a link that is not self link, cannot be in a candidate if ( inLink && ! selfLink ) { flags[i] |= 0x02; } // out of a link if ( tids[i] == (TAG_A | BACKBIT) ) { inLink = false; } // if not start of <a> tag, skip it if ( tids[i] != TAG_A ) { continue; } // flag it inLink = true; // get the node in the xml int32_t xn = words->getNodes()[i]; // is it a self link? int32_t len; char *link = xml->getString(xn,"href",&len); // . set the url class to this // . TODO: use the base url in the doc Url u; u.set( link, len, true, false ); // compare selfLink = u.equals ( firstUrl ); // skip if not selfLink if ( ! selfLink ) { continue; } // if it is a selflink , check for an "onClick" tag in the // anchor tag to fix that Mixx issue for: // http://www.npr.org/templates/story/story.php?storyId=5417137 int32_t oclen; char *oc = xml->getString(xn,"onclick",&oclen); if ( ! oc ) { oc = xml->getString(xn,"onClick",&oclen); } // assume not a self link if we see that... if ( oc ) { selfLink = false; } // if this <a href> link has a "title" attribute, use that // instead! that thing is solid gold. int32_t atlen; char *atitle = xml->getString(xn,"title",&atlen); // stop and use that, this thing is gold! if ( ! atitle || atlen <= 0 ) { continue; } // craziness? ignore it... if ( atlen > 400 ) { continue; } // if it contains permanent, permalink or share, ignore it! if ( strncasestr ( atitle, "permalink", atlen ) || strncasestr ( atitle,"permanent", atlen) || strncasestr ( atitle,"share", atlen) ) { continue; } // do not count the link text as viable selfLink = false; // aw, dammit if ( ti >= MAX_TIT_CANDIDATES ) { continue; } // other dammit if ( n >= MAX_TIT_CANDIDATES ) { break; } // ok, process it if ( ! tw[ti].set ( atitle, atlen, true, 0 )) { return false; } // set the bookends, it is the whole thing cptrs [n] = &tw[ti]; as [n] = 0; bs [n] = tw[ti].getNumWords(); scores [n] = 3.0; // not ALWAYS solid gold! types [n] = TT_TITLEATT; // we are using the words class ti++; // advance n++; // break out if too many already. save some for below. if ( n + 20 >= MAX_TIT_CANDIDATES ) { break; } } //logf(LOG_DEBUG,"title: took2=%" PRId64,gettimeofdayInMilliseconds()-x); //x = gettimeofdayInMilliseconds(); //int64_t *wids = WW->getWordIds(); // . find the last positive scoring guy // . do not consider title candidates after "r" if "r" is non-zero // . FIXES http://larvatusprodeo.net/2009/01/07/partisanship-politics-and-participation/ // the candidate # of the title tag int32_t tti = -1; // allow up to 4 tags from each type char table[512]; // sanity check if ( getNumXmlNodes() > 512 ) { char *xx=NULL;*xx=0; } // clear table counts memset ( table , 0 , 512 ); // the first word char *wstart = NULL; if ( NW > 0 ) { wstart = words->getWord(0); } // loop over all "words" in the html body for ( int32_t i = 0 ; i < NW ; i++ ) { // come back up here if we encounter another "title-ish" tag // within our first alleged "title-ish" tag subloop: // stop after 30k of text if ( words->getWord(i) - wstart > 200000 ) { break; // 1106 } // get the tag id minus the back tag bit nodeid_t tid = tids[i] & BACKBITCOMP; // pen up and pen down for these comment like tags if ( tid == TAG_SCRIPT || tid == TAG_STYLE ) { // ignore "titles" in script or style tags if ( ! (tids[i] & BACKBIT) ) { continue; } } /// @todo ALC we should allow more tags than just title/link // skip if not a good tag. if (tid != TAG_TITLE && tid != TAG_A) { continue; } // must NOT be a back tag if ( tids[i] & BACKBIT ) { continue; } // skip if we hit our limit if ( table[tid] >= 4 ) { continue; } // skip over tag/word #i i++; // no words in links, unless it is a self link if ( i < NW && (flags[i] & 0x02) ) { continue; } // the start should be here int32_t start = -1; // do not go too far int32_t max = i + 200; // find the corresponding back tag for it for ( ; i < NW && i < max ; i++ ) { // hey we got it, BUT we got no alnum word first // so the thing was empty, so loop back to subloop if ( (tids[i] & BACKBITCOMP) == tid && (tids[i] & BACKBIT ) && start == -1 ) { goto subloop; } // if we hit another title-ish tag, loop back up if ( (tids[i] & BACKBITCOMP) == TAG_TITLE || (tids[i] & BACKBITCOMP) == TAG_A ) { // if no alnum text, restart at the top if ( start == -1 ) { goto subloop; } // otherwise, break out and see if title works break; } // if we hit a breaking tag... if ( isBreakingTagId ( tids[i] & BACKBITCOMP ) && // do not consider <span> tags breaking for // our purposes. i saw a <h1><span> setup before. tids[i] != TAG_SPAN ) { break; } // skip if not alnum word if ( ! words->isAlnum(i) ) { continue; } // if we hit an alnum word, break out if ( start == -1 ) { start = i; } } // if no start was found, must have had a 0 score in there if ( start == -1 ) { continue; } // if we exhausted the doc, we are done if ( i >= NW ) { break; } // skip if way too big! if ( i >= max ) { continue; } // if was too long do not consider a title if ( i - start > 300 ) { continue; } // . skip if too many bytes // . this does not include the length of word #i, but #(i-1) if ( words->getStringSize ( start , i ) > 1000 ) { continue; } // when using pdftohtml, the title tag is the filename when PDF property does not have title tag if ( tid == TAG_TITLE && contentType == CT_PDF ) { // skip if title == '/in.[0-9]*' char* title_start = words->getWord(start); char* title_end = words->getWord(i); size_t title_size = title_end - title_start; const char* result = strnstr( title_start, "/in.", title_size ); if (result != NULL) { char* endp = NULL; // do some further verification to avoid screwing up title if ((strtoll(result + 4, &endp, 10) > 0) && (endp == title_end)) { continue; } } } // count it table[tid]++; // max it out if we are positive scoring. stop after the // first positive scoring guy in a section. this might // hurt the "Hamlet" thing though... // store a point to the title tag guy. Msg20.cpp needs this // because the zak's proximity algo uses it in Summary.cpp // and in Msg20.cpp // only get the first one! often the 2nd on is in an iframe!! which we now expand into here. if ( tid == TAG_TITLE && m_titleTagStart == -1 ) { m_titleTagStart = start; m_titleTagEnd = i; // save the candidate # because we always use this // as the title if we are a root if ( tti < 0 ) { tti = n; } } // point to words class of the body that was passed in to us cptrs[n] = words; as[n] = start; bs[n] = i; if ( tid == TAG_B ) { types[n] = TT_BOLDTAG; scores[n] = 1.0; } else if ( tid == TAG_H1 ) { types[n] = TT_HTAG; scores[n] = 1.8; } else if ( tid == TAG_H2 ) { types[n] = TT_HTAG; scores[n] = 1.7; } else if ( tid == TAG_H3 ) { types[n] = TT_HTAG; scores[n] = 1.6; } else if ( tid == TAG_TITLE ) { types[n] = TT_TITLETAG; scores[n] = 3.0; } else if ( tid == TAG_DIV ) { types[n] = TT_DIVTAG; scores[n] = 1.0; } else if ( tid == TAG_TD ) { types[n] = TT_TDTAG; scores[n] = 1.0; } else if ( tid == TAG_P ) { types[n] = TT_PTAG; scores[n] = 1.0; } else if ( tid == TAG_FONT ) { types[n] = TT_FONTTAG; scores[n] = 1.0; } else if ( tid == TAG_A ) { types[n] = TT_ATAG; // . self link is very powerful BUT // http://www.npr.org/templates/story/story.php?storyId=5417137 // doesn't use it right! so use // 1.3 instead of 3.0. that has an "onClick" thing in the // <a> tag, so check for that! // this was bad for // http://www.spiritualwoman.net/?cat=191 // so i am demoting from 3.0 to 1.5 scores[n] = 1.5; } // count it n++; // start loop over at tag #i, for loop does an i++, so negate // that so this will work i--; // break out if too many already. save some for below. if ( n + 10 >= MAX_TIT_CANDIDATES ) { break; } } //logf(LOG_DEBUG,"title: took3=%" PRId64,gettimeofdayInMilliseconds()-x); //x = gettimeofdayInMilliseconds(); // to handle text documents, throw in the first line of text // as a title candidate, just make the score really low bool textDoc = (contentType == CT_UNKNOWN || contentType == CT_TEXT); if (textDoc) { // make "i" point to first alphabetical word in the document int32_t i ; for ( i = 0 ; i < NW && !words->isAlpha(i) ; i++); // if we got a first alphabetical word, then assume that to be the start of our title if ( i < NW && n < MAX_TIT_CANDIDATES ) { // first word in title is "t0" int32_t t0 = i; // find end of first line int32_t numWords = 0; // set i to the end now. we MUST find a \n to terminate the // title, otherwise we will not have a valid title while (i < NW && numWords < maxTitleWords && (words->isAlnum(i) || !words->hasChar(i, '\n'))) { if(words->isAlnum(i)) { numWords++; } ++i; } // "t1" is the end int32_t t1 = -1; // we must have found our \n in order to set "t1" if (i <= NW && numWords < maxTitleWords ) { t1 = i; } // set the ptrs cptrs [n] = words; // this is the last resort i guess... scores [n] = 0.5; types [n] = TT_FIRSTLINE; as [n] = t0; bs [n] = t1; // add it as a candidate if t0 and t1 were valid if (t0 >= 0 && t1 > t0) { n++; } } } //logf(LOG_DEBUG,"title: took4=%" PRId64,gettimeofdayInMilliseconds()-x); //x = gettimeofdayInMilliseconds(); { // now add the last url path to contain underscores or hyphens char *pstart = firstUrl->getPath(); // get first url Url *fu = firstUrl; // start at the end char *p = fu->getUrl() + fu->getUrlLen(); // end pointer char *pend = NULL; // come up here for each path component while ( p >= pstart ) { // save end pend = p; // skip over / if ( *p == '/' ) { p--; } // now go back to next / int32_t count = 0; for ( ; p >= pstart && *p !='/' ; p-- ) { if ( *p == '_' || *p == '-' ) { count++; } } // did we get it? if ( count > 0 ) { break; } } // did we get any? if ( p > pstart && n < MAX_TIT_CANDIDATES ) { // now set words to that if ( ! tw[ti].set ( p, (pend - p), true, 0 )) { return false; } // point to that cptrs [n] = &tw[ti]; as [n] = 0; bs [n] = tw[ti].getNumWords(); scores [n] = 1.0; types [n] = TT_URLPATH; // increment since we are using it ti++; // advance n++; } } // save old n int32_t oldn = n; // . do not split titles if we are a root url maps.yahoo.com was getting "Maps" for the title if ( firstUrl->isRoot() ) { oldn = -2; } // point to list of \0 separated titles const char *rootTitleBuf = NULL; const char *rootTitleBufEnd = NULL; // get the root title if we are not root! if (filteredRootTitleBuf) { #ifdef _VALGRIND_ VALGRIND_CHECK_MEM_IS_DEFINED(filteredRootTitleBuf,filteredRootTitleBufSize); #endif // point to list of \0 separated titles rootTitleBuf = filteredRootTitleBuf; rootTitleBufEnd = filteredRootTitleBuf + filteredRootTitleBufSize; } { Matches m; if ( rootTitleBuf && query ) { m.setQuery ( query ); } // convert into an array int32_t nr = 0; const char *pr = rootTitleBuf; const char *rootTitles[20]; int32_t rootTitleLens[20]; // loop over each root title segment for ( ; pr && pr < rootTitleBufEnd ; pr += strnlen(pr,rootTitleBufEnd-pr) + 1 ) { // if we had a query... if ( query ) { // reset it m.reset(); // see if root title segment has query terms in it m.addMatches ( const_cast<char*>(pr), strnlen(pr,rootTitleBufEnd-pr), MF_TITLEGEN, m_niceness ); // if matches query, do NOT add it, we only add it for // removing from the title of the page... if ( m.getNumMatches() ) { continue; } } // point to it. it should start with an alnum already // since it is the "filtered" list of root titles... // if not, fix it in xmldoc then. rootTitles [nr] = pr; rootTitleLens[nr] = gbstrlen(pr); // advance nr++; // no breaching if ( nr >= 20 ) break; } // now split up candidates in children candidates by tokenizing // using :, | and - as delimters. // the hyphen must have a space on at least one side, so "cd-rom" does // not create a pair of tokens... // FIX: for the title: // Best Careers 2009: Librarian - US News and World Report // we need to recognize "Best Careers 2009: Librarian" as a subtitle // otherwise we don't get it as the title. so my question is are we // going to have to do all the permutations at some point? for now // let's just add in pairs... for ( int32_t i = 0 ; i < oldn && n + 3 < MAX_TIT_CANDIDATES ; i++ ) { // stop if no root title segments if ( nr <= 0 ) break; // get the word info Words *w = cptrs[i]; int32_t a = as[i]; int32_t b = bs[i]; // init int32_t lasta = a; char prev = false; // char length in bytes //int32_t charlen = 1; // see how many we add int32_t added = 0; char *skipTo = NULL; bool qualified = true; // . scan the words looking for a token // . sometimes the candidates end in ": " so put in "k < b-1" // . made this from k<b-1 to k<b to fix // "Hot Tub Time Machine (2010) - IMDb" to strip IMDb for ( int32_t k = a ; k < b && n + 3 < MAX_TIT_CANDIDATES; k++){ // get word char *wp = w->getWord(k); // skip if not alnum if ( ! w->isAlnum(k) ) { // in order for next alnum word to // qualify for "clipping" if it matches // the root title, there has to be more // than just spaces here, some punct. // otherwise title // "T. D. Jakes: Biography from Answers.com" // becomes // "T. D. Jakes: Biography from" qualified=isWordQualified(wp,w->getWordLen(k)); continue; } // gotta be qualified! if ( ! qualified ) continue; // skip if in root title if ( skipTo && wp < skipTo ) continue; // does this match any root page title segments? int32_t j; for ( j = 0 ; j < nr ; j++ ) { // . compare to root title // . break out if we matched! if ( ! strncmp( wp, rootTitles[j], rootTitleLens[j] ) ) { break; } } // if we did not match a root title segment, // keep on chugging if ( j >= nr ) continue; // . we got a root title match! // . skip over skipTo = wp + rootTitleLens[j]; // must land on qualified punct then!! int32_t e = k+1; for ( ; e<b && w->getWord(e)<skipTo ; e++ ); // ok, word #e must be a qualified punct if ( e<b && ! isWordQualified(w->getWord(e),w->getWordLen(e))) // assume no match then!! continue; // if we had a previous guy, reset the end of the // previous candidate if ( prev ) { bs[n-2] = k; bs[n-1] = k; } // . ok, we got two more candidates // . well, only one more if this is not the 1st time if ( ! prev ) { cptrs [n] = cptrs [i]; scores [n] = scores [i]; types [n] = types [i]; as [n] = lasta; bs [n] = k; parent [n] = i; n++; added++; } // the 2nd one cptrs [n] = cptrs [i]; scores [n] = scores [i]; types [n] = types [i]; as [n] = e + 1; bs [n] = bs [i]; parent [n] = i; n++; added++; // now add in the last pair as a whole token cptrs [n] = cptrs [i]; scores [n] = scores [i]; types [n] = types [i]; as [n] = lasta; bs [n] = bs [i]; parent [n] = i; n++; added++; // nuke the current candidate then since it got // split up to not contain the root title... //cptrs[i] = NULL; // update this lasta = k+1; // if we encounter another delimeter we will have to revise bs[n-1], so note that prev = true; } // nuke the current candidate then since it got // split up to not contain the root title... if ( added ) { scores[i] = 0.001; //cptrs[i] = NULL; } // erase the pair if that there was only one token if ( added == 3 ) n--; } } for ( int32_t i = 0 ; i < n ; i++ ) baseScore[i] = scores[i]; // // . now punish by 0.85 for every lower case non-stop word it has // . reward by 1.1 if has a non-stopword in the query // for ( int32_t i = 0 ; i < n ; i++ ) { // point to the words Words *w = cptrs[i]; // skip if got nuked above if ( ! w ) { continue; } // the word ptrs char **wptrs = w->getWordPtrs(); // skip if empty if ( w->getNumWords() <= 0 ) { continue; } // get the word boundaries int32_t a = as[i]; int32_t b = bs[i]; // record the boosts float ncb = 1.0; float qtb = 1.0; // a flag char uncapped = false; // scan the words in this title candidate for ( int32_t j = a ; j < b ; j++ ) { // skip stop words if ( w->isQueryStopWord( j, langId ) ) { continue; } // punish if uncapitalized non-stopword if ( ! w->isCapitalized(j) ) { uncapped = true; } // skip if no query if ( ! query ) { continue; } int64_t wid = w->getWordId(j); // reward if in the query if ( query->getWordNum(wid) >= 0 ) { qtb *= 1.5; scores[i] *= 1.5; } } // . only punish once if missing a capitalized word hurts us for: // http://content-uk.cricinfo.com/ausvrsa2008_09/engine/current/match/351682.html if ( uncapped ) { ncb *= 1.00; scores[i] *= 1.00; } // punish if a http:// title thingy char *s = wptrs[a]; int32_t size = w->getStringSize(a,b); if ( size > 9 && memcmp("http://", s, 7) == 0 ) { ncb *= .10; } if ( size > 14 && memcmp("h\0t\0t\0p\0:\0/\0/", s, 14) == 0 ) { ncb *= .10; } // set these guys scores[i] *= ncb; noCapsBoost[i] = ncb; qtermsBoost[i] = qtb; } // . now compare each candidate to the other candidates // . give a boost if matches for ( int32_t i = 0 ; i < n ; i++ ) { // point to the words Words *w1 = cptrs[i]; // skip if got nuked above if ( ! w1 ) { continue; } int32_t a1 = as[i]; int32_t b1 = bs[i]; // reset some flags char localFlag1 = 0; char localFlag2 = 0; // record the boost float iccb = 1.0; // total boost float total = 1.0; // to each other candidate for ( int32_t j = 0 ; j < n ; j++ ) { // not to ourselves if ( j == i ) { continue; } // or our derivatives if ( parent[j] == i ) { continue; } // or derivates to their parent if ( parent[i] == j ) { continue; } // only check parents now. do not check kids. // this was only for when doing percent contained // not getSimilarity() per se //if ( parent[j] != -1 ) continue; // TODO: do not accumulate boosts from a parent // and its kids, subtitles... // // do not compare type X to type Y if ( types[i] == TT_TITLETAG ) { if ( types[j] == TT_TITLETAG ) { continue; } } // do not compare a div candidate to another div cand // http://friendfeed.com/foxiewire?start=30 // likewise, a TD to another TD // http://content-uk.cricinfo.com/ausvrsa2008_09/engine/match/351681.html // ... etc. if ( types[i] == TT_BOLDTAG || types[i] == TT_HTAG || types[i] == TT_DIVTAG || types[i] == TT_TDTAG || types[i] == TT_FONTTAG ) { if ( types[j] == types[i] ) continue; } // . do not compare one kid to another kid // . i.e. if we got "x | y" as a title and "x | z" // as a link text, it will emphasize "x" too much // http://content-uk.cricinfo.com/ausvrsa2008_09/engine/current/match/351682.html if ( parent[j] != -1 && parent[i] != -1 ) continue; // . body type tags are mostly mutually exclusive // . for the legacy.com url mentioned below, we have // good stuff in <td> tags, so this hurts us... // . but for the sake of // http://larvatusprodeo.net/2009/01/07/partisanship-politics-and-participation/ // i put bold tags back if ( types[i] == TT_LINKTEXTLOCAL ) { if ( types[j] == TT_LINKTEXTLOCAL ) continue; } if ( types[i] == TT_RSSITEMLOCAL ) { if ( types[j] == TT_RSSITEMLOCAL ) continue; } // only compare to one local link text for each i if ( types[j] == TT_LINKTEXTLOCAL && localFlag1 ) { continue; } if ( types[j] == TT_RSSITEMLOCAL && localFlag2 ) { continue; } if ( types[j] == TT_LINKTEXTLOCAL ) { localFlag1 = 1; } if ( types[j] == TT_RSSITEMLOCAL ) { localFlag2 = 1; } // not link title attr to link title attr either // fixes http://www.spiritualwoman.net/?cat=191 if ( types[i] == TT_TITLEATT && types[j] == TT_TITLEATT ) continue; // get our words Words *w2 = cptrs[j]; // skip if got nuked above if ( ! w2 ) continue; int32_t a2 = as [j]; int32_t b2 = bs [j]; // how similar is title #i to title #j ? float fp = getSimilarity ( w2 , a2 , b2 , w1 , a1 , b1 ); // error? if ( fp == -1.0 ) return false; // custom boosting... float boost = 1.0; if ( fp >= .95 ) boost = 3.0; else if ( fp >= .90 ) boost = 2.0; else if ( fp >= .85 ) boost = 1.5; else if ( fp >= .80 ) boost = 1.4; else if ( fp >= .75 ) boost = 1.3; else if ( fp >= .70 ) boost = 1.2; else if ( fp >= .60 ) boost = 1.1; else if ( fp >= .50 ) boost = 1.08; else if ( fp >= .40 ) boost = 1.04; // limit total total *= boost; if ( total > 100.0 ) break; // if you are matching the url path, that is pretty // good so give more! // actually, that would hurt: // http://michellemalkin.com/2008/12/29/gag-worthy/ // custom boosting! if ( fp > 0.0 && g_conf.m_logDebugTitle ) logf(LOG_DEBUG,"title: i=%" PRId32" j=%" PRId32" fp=%.02f " "b=%.02f", i,j,fp,boost); // apply it scores[i] *= boost; iccb *= boost; } inCommonCandBoost[i] = iccb; } //logf(LOG_DEBUG,"title: took7=%" PRId64,gettimeofdayInMilliseconds()-x); //x = gettimeofdayInMilliseconds(); // loop over all n candidates for ( int32_t i = 0 ; i < n ; i++ ) { // skip if not in the document body if ( cptrs[i] != words ) continue; // point to the words int32_t a1 = as [i]; int32_t b1 = bs [i]; // . loop through this candidates words // . TODO: use memset here? for ( int32_t j = a1 ; j <= b1 && j < NW ; j++ ) { // flag it flags[j] |= 0x01; } } // free our stuff if ( flags!=localBuf ) { mfree (flags, need, "TITLEflags"); } // now get the highest scoring candidate title float max = -1.0; int32_t winner = -1; for ( int32_t i = 0 ; i < n ; i++ ) { // skip if got nuked if ( ! cptrs[i] ) { continue; } if ( winner != -1 && scores[i] <= max ) { continue; } // url path's cannot be titles in and of themselves if ( types[i] == TT_URLPATH ) { continue; } // skip if empty basically, like if title was exact // copy of root, then the whole thing got nuked and // some empty string added, where a > b if ( as[i] >= bs[i] ) { continue; } // got one max = scores[i]; // save it winner = i; } // if we are a root, always pick the title tag as the title if ( oldn == -2 && tti >= 0 ) { winner = tti; } // if no winner, all done. no title if ( winner == -1 ) { // last resort use file name if ((contentType == CT_PDF) && (firstUrl->getFilenameLen() != 0)) { Words w; w.set(firstUrl->getFilename(), firstUrl->getFilenameLen(), true); if (!copyTitle(&w, 0, w.getNumWords())) { return false; } } return true; } // point to the words class of the winner Words *w = cptrs[winner]; // skip if got nuked above if ( ! w ) { char *xx=NULL;*xx=0; } // need to make our own Pos class if title not from body Pos tp; if ( w != words ) { // set "Scores" ptr to NULL. we assume all are positive scores if ( ! tp.set ( w ) ) { return false; } } // the string ranges from word #a up to and including word #b int32_t a = as[winner]; int32_t b = bs[winner]; // sanity check if ( a < 0 || b > w->getNumWords() ) { char*xx=NULL;*xx=0; } // save the title if ( ! copyTitle(w, a, b) ) { return false; } /* // debug logging SafeBuf sb; SafeBuf *pbuf = &sb; log("title: candidates for %s",xd->getFirstUrl()->getUrl() ); pbuf->safePrintf("<div stype=\"border:1px solid black\">"); pbuf->safePrintf("<b>***Finding Title***</b><br>\n"); pbuf->safePrintf("<table cellpadding=5 border=2><tr>" "<td colspan=20><center><b>Title Generation</b>" "</center></td>" "</tr>\n<tr>" "<td>#</td>" "<td>type</td>" "<td>parent</td>" "<td>base score</td>" "<td>format penalty</td>" "<td>query term boost</td>" "<td>candidate intersection boost</td>" "<td>FINAL SCORE</td>" "<td>title</td>" "</tr>\n" ); // print out all candidates for ( int32_t i = 0 ; i < n ; i++ ) { char *ts = "unknown"; if ( types[i] == TT_LINKTEXTLOCAL ) ts = "local inlink text"; if ( types[i] == TT_LINKTEXTREMOTE ) ts = "remote inlink text"; if ( types[i] == TT_RSSITEMLOCAL ) ts = "local rss title"; if ( types[i] == TT_RSSITEMREMOTE ) ts = "remote rss title"; if ( types[i] == TT_BOLDTAG ) ts = "bold tag"; if ( types[i] == TT_HTAG ) ts = "header tag"; if ( types[i] == TT_TITLETAG ) ts = "title tag"; if ( types[i] == TT_FIRSTLINE ) ts = "first line in text"; if ( types[i] == TT_FONTTAG ) ts = "font tag"; if ( types[i] == TT_ATAG ) ts = "anchor tag"; if ( types[i] == TT_DIVTAG ) ts = "div tag"; if ( types[i] == TT_TDTAG ) ts = "td tag"; if ( types[i] == TT_PTAG ) ts = "p tag"; if ( types[i] == TT_URLPATH ) ts = "url path"; if ( types[i] == TT_TITLEATT ) ts = "title attribute"; // get the title pbuf->safePrintf( "<tr>" "<td>#%" PRId32"</td>" "<td><nobr>%s</nobr></td>" "<td>%" PRId32"</td>" "<td>%0.2f</td>" // baseScore "<td>%0.2f</td>" "<td>%0.2f</td>" "<td>%0.2f</td>" "<td>%0.2f</td>" "<td>", i, ts , parent[i], baseScore[i], noCapsBoost[i], qtermsBoost[i], inCommonCandBoost[i], scores[i]); // ptrs Words *w = cptrs[i]; int32_t a = as[i]; int32_t b = bs[i]; // skip if no words if ( w->getNumWords() <= 0 ) continue; // the word ptrs char **wptrs = w->getWordPtrs(); // string ptrs char *ptr = wptrs[a];//w->getWord(a); int32_t size = w->getStringSize(a,b); // it is utf8 pbuf->safeMemcpy ( ptr , size ); // end the line pbuf->safePrintf("</td></tr>\n"); } pbuf->safePrintf("</table>\n<br>\n"); // log these for now log("title: %s",sb.getBufStart()); */ return true; }
// . but now that we may get a list remotely to fix data corruption, // this may indeed block bool Msg3::doneScanning ( ) { QUICKPOLL(m_niceness); // . did we have any error on any scan? // . if so, repeat ALL of the scans g_errno = m_errno; // 2 retry is the default int32_t max = 2; // see if explicitly provided by the caller if ( m_maxRetries >= 0 ) max = m_maxRetries; // now use -1 (no max) as the default no matter what max = -1; // ENOMEM is particulary contagious, so watch out with it... if ( g_errno == ENOMEM && m_maxRetries == -1 ) max = 0; // msg0 sets maxRetries to 2, don't let max stay set to -1 if ( g_errno == ENOMEM && m_maxRetries != -1 ) max = m_maxRetries; // when thread cannot alloc enough read buf it keeps the read buf // set to NULL and BigFile.cpp sets g_errno to EBUFTOOSMALL if ( g_errno == EBUFTOOSMALL && m_maxRetries == -1 ) max = 0; // msg0 sets maxRetries to 2, don't let max stay set to -1 if ( g_errno == EBUFTOOSMALL && m_maxRetries != -1 ) max = m_maxRetries; // . if no thread slots available, that hogs up serious memory. // the size of Msg3 is 82k, so having just 5000 of them is 430MB. // . i just made Msg3 alloc mem when it needs more than about 2k // so this problem is greatly reduced, therefore let's keep // retrying... forever if no thread slots in thread queue since // we become the thread queue in a way. if ( g_errno == ENOTHREADSLOTS ) max = -1; // this is set above if the map has the same consecutive key repeated // and the read is enormous if ( g_errno == ECORRUPTDATA ) max = 0; // usually bad disk failures, don't retry those forever //if ( g_errno == EIO ) max = 3; // no, now our hitachis return these even when they're good so // we have to keep retrying forever if ( g_errno == EIO ) max = -1; // count these so we do not take drives offline just because // kernel ring buffer complains... if ( g_errno == EIO ) g_numIOErrors++; // bail early on high priority reads for these errors if ( g_errno == EDISKSTUCK && m_niceness == 0 ) max = 0; if ( g_errno == EIO && m_niceness == 0 ) max = 0; // how does this happen? we should never bail out on a low priority // disk read... we just wait for it to complete... if ( g_errno == EDISKSTUCK && m_niceness != 0 ) { char *xx=NULL;*xx=0;} // on I/O, give up at call it corrupt after a while. some hitachis // have I/O errros on little spots, like gk88, maybe we can fix him if ( g_errno == EIO && m_retryNum >= 5 ) { m_errno = ECORRUPTDATA; m_hadCorruption = true; // do not do any retries any more max = 0; } // convert m_errno to ECORRUPTDATA if it is EBUFTOOSMALL and the // max of the bytesToRead are over 500MB. // if bytesToRead was ludicrous, then assume that the data file // was corrupted, the map was regenerated and it patched // over the corrupted bits which were 500MB or more in size. // we cannot practically allocate that much, so let's just // give back an empty buffer. treat it like corruption... // the way it patches is to store the same key over all the corrupted // pages, which can get pretty big. so if you read a range with that // key you will be hurting!! // this may be the same scenario as when the rdbmap has consecutive // same keys. see above where we set m_errno to ECORRUPTDATA... if ( g_errno == EBUFTOOSMALL ) { int32_t biggest = 0; for ( int32_t i = 0 ; i < m_numFileNums ; i++ ) { if ( m_scans[i].m_bytesToRead < biggest ) continue; biggest = m_scans[i].m_bytesToRead; } if ( biggest > 500000000 ) { log("db: Max read size was %" PRId32" > 500000000. Assuming " "corrupt data in data file.",biggest); m_errno = ECORRUPTDATA; m_hadCorruption = true; // do not do any retries on this, the read was > 500MB max = 0; } } // if shutting down gb then limit to 20 so we can shutdown because // it can't shutdown until all threads are out of the queue i think if ( g_process.m_mode == EXIT_MODE && max < 0 ) { //log("msg3: forcing retries to 0 because shutting down"); max = 0; } // get base, returns NULL and sets g_errno to ENOCOLLREC on error RdbBase *base = getRdbBase( m_rdbId, m_collnum ); if ( ! base ) { return true; } // this really slows things down because it blocks the cpu so // leave it out for now #ifdef GBSANITYCHECK // check for corruption here, do not do it again in Msg5 if we pass if ( ! g_errno ) { // && g_conf.m_doErrorCorrection ) { int32_t i; for ( i = 0 ; i < m_numFileNums ; i++ ) if ( ! m_lists[i].checkList_r ( false, false ) ) break; if ( i < m_numFileNums ) { g_errno = ECORRUPTDATA; m_errno = ECORRUPTDATA; max = g_conf.m_corruptRetries; // try 100 times log("db: Encountered corrupt list in file %s.", base->getFile(m_fileNums[i])->getFilename()); } else m_listsChecked = true; } #endif // try to fix this error i've seen if ( g_errno == EBADENGINEER && max == -1 ) max = 100; // . if we had a ETRYAGAIN error, then try again now // . it usually means the whole file or a part of it was deleted // before we could finish reading it, so we should re-read all now // . RdbMerge deletes BigFiles after it merges them and also chops // off file heads // . now that we have threads i'd imagine we'd get EBADFD or something // . i've also seen "illegal seek" as well if ( m_errno && (m_retryNum < max || max < 0) && // this will complete in due time, we can't call a sleep wrapper // on it because the read is really still pending... m_errno != EDISKSTUCK ) { // print the error static time_t s_time = 0; time_t now = getTime(); if ( now - s_time > 5 || g_errno != ENOTHREADSLOTS ) { log("net: Had error reading %s: %s. Retrying. " "(retry #%" PRId32")", base->m_dbname,mstrerror(m_errno) , m_retryNum ); s_time = now; } // send email alert if in an infinite loop, but don't send // more than once every 2 hours static int32_t s_lastSendTime = 0; if ( m_retryNum == 100 && getTime() - s_lastSendTime > 3600*2){ // remove this for now it is going off all the time //g_pingServer.sendEmail(NULL,//g_hostdb.getMyHost(), // "100 read retries",true); s_lastSendTime = getTime(); } // clear g_errno cuz we should for call to readList() g_errno = 0; // free the list buffer since if we have 1000 Msg3s retrying // it will totally use all of our memory for ( int32_t i = 0 ; i < m_numChunks ; i++ ) m_lists[i].destructor(); // count retries m_retryNum++; // backoff scheme, wait 100ms more each time int32_t wait ; if ( m_retryNum == 1 ) wait = 10; else wait = 200 * m_retryNum; // . don't wait more than 10 secs between tries // . i've seen gf0 and gf16 get mega saturated if ( wait > 10000 ) wait = 10000; // wait 500 ms if ( g_loop.registerSleepCallback ( wait , // ms this , doneSleepingWrapper3, m_niceness)) return false; // otherwise, registration failed log( "net: Failed to register sleep callback for retry. " "Abandoning read. This is bad."); // return, g_errno should be set g_errno = EBUFTOOSMALL; m_errno = EBUFTOOSMALL; return true; } // if we got an error and should not retry any more then give up if ( g_errno ) { log( "net: Had error reading %s: %s. Giving up after %" PRId32" " "retries.", base->m_dbname,mstrerror(g_errno) , m_retryNum ); return true; } // note it if the retry finally worked if ( m_retryNum > 0 ) log(LOG_INFO,"disk: Read succeeded after retrying %" PRId32" times.", (int32_t)m_retryNum); // count total bytes for logging int32_t count = 0; // . constrain all lists to make merging easier // . if we have only one list, then that's nice cuz the constrain // will allow us to send it right away w/ zero copying // . if we have only 1 list, it won't be merged into a final list, // that is, we'll just set m_list = &m_lists[i] for ( int32_t i = 0 ; i < m_numFileNums ; i++ ) { QUICKPOLL(m_niceness); // count total bytes for logging count += m_lists[i].getListSize(); // . hint offset is relative to the offset of first key we read // . if that key was only 6 bytes RdbScan shift the list buf // down 6 bytes to make the first key 12 bytes... a // requirement for all RdbLists // . don't inc it, though, if it was 0, pointing to the start // of the list because our shift won't affect that if ( m_scans[i].m_shifted == 6 && m_hintOffsets[i] > 0 ) m_hintOffsets[i] += 6; // posdb double compression if ( m_scans[i].m_shifted == 12 && m_hintOffsets[i] > 0 ) m_hintOffsets[i] += 12; // . don't constrain on minRecSizes here because it may // make our endKey smaller, which will cause problems // when Msg5 merges these lists. // . If all lists have different endKeys RdbList's merge // chooses the min and will merge in recs beyond that // causing a bad list BECAUSE we don't check to make // sure that recs we are adding are below the endKey // . if we only read from one file then constrain based // on minRecSizes so we can send the list back w/o merging // OR if just merging with RdbTree's list int32_t mrs ; // . constrain to m_minRecSizesOrig, not m_minRecSizes cuz // that could be adjusted by compensateForNegativeRecs() // . but, really, they should be the same if we only read from // the root file if ( m_numFileNums == 1 ) mrs = m_minRecSizesOrig; else mrs = -1; // . this returns false and sets g_errno on error // . like if data is corrupt BigFile *ff = base->getFile(m_fileNums[i]); // if we did a merge really quick and delete one of the // files we were reading, i've seen 'ff' be NULL char *filename = "lostfilename"; if ( ff ) filename = ff->getFilename(); // compute cache info RdbCache *rpc = getDiskPageCache ( m_rdbId ); if ( ! m_allowPageCache ) rpc = NULL; int64_t vfd ; if ( ff ) vfd = ff->getVfd(); key192_t ck ; if ( ff ) ck = makeCacheKey ( vfd , m_scans[i].m_offset , m_scans[i].m_bytesToRead ); if ( m_validateCache && ff && rpc && vfd != -1 ) { bool inCache; char *rec; int32_t recSize; inCache = rpc->getRecord ( (collnum_t)0 , // collnum (char *)&ck , &rec , &recSize , true , // copy? -1 , // maxAge, none true ); // inccounts? if ( inCache && // 1st byte is RdbScan::m_shifted ( m_lists[i].m_listSize != recSize-1 || memcmp ( m_lists[i].m_list , rec+1,recSize-1) || *rec != m_scans[i].m_shifted ) ) { log("msg3: cache did not validate"); char *xx=NULL;*xx=0; } mfree ( rec , recSize , "vca" ); } /////// // // STORE IN PAGE CACHE // /////// // store what we read in the cache. don't bother storing // if it was a retry, just in case something strange happened. // store pre-constrain call is more efficient. if ( m_retryNum<=0 && ff && rpc && vfd != -1 && ! m_scans[i].m_inPageCache ) rpc->addRecord ( (collnum_t)0 , // collnum (char *)&ck , // rec1 is this little thingy &m_scans[i].m_shifted, 1, // rec2 m_lists[i].getList() , m_lists[i].getListSize() , 0 ); // timestamp. 0 = now QUICKPOLL(m_niceness); // if from our 'page' cache, no need to constrain if ( ! m_lists[i].constrain ( m_startKey , m_constrainKey , // m_endKey mrs , // m_minRecSizes m_hintOffsets[i] , //m_hintKeys [i] , &m_hintKeys [i*m_ks] , filename,//ff->getFilename() , m_niceness ) ) { log("net: Had error while constraining list read from " "%s: %s/%s. vfd=%" PRId32" parts=%" PRId32". " "This is likely caused by corrupted " "data on disk.", mstrerror(g_errno), ff->getDir(), ff->getFilename(), ff->m_vfd , (int32_t)ff->m_numParts ); continue; } } // print the time if ( g_conf.m_logTimingDb ) { int64_t now = gettimeofdayInMilliseconds(); int64_t took = now - m_startTime; log(LOG_TIMING, "net: Took %" PRId64" ms to read %" PRId32" lists of %" PRId32" bytes total" " from %s (niceness=%" PRId32").", took,m_numFileNums,count,base->m_dbname,m_niceness); } return true; }
static void raw_pull_job_on_finished(PullJob *j) { RawPull *i; int r; assert(j); assert(j->userdata); i = j->userdata; if (j == i->roothash_job) { if (j->error != 0) log_info_errno(j->error, "Root hash file could not be retrieved, proceeding without."); } else if (j == i->settings_job) { if (j->error != 0) log_info_errno(j->error, "Settings file could not be retrieved, proceeding without."); } else if (j->error != 0 && j != i->signature_job) { if (j == i->checksum_job) log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)"); else log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)"); r = j->error; goto finish; } /* This is invoked if either the download completed * successfully, or the download was skipped because we * already have the etag. In this case ->etag_exists is * true. * * We only do something when we got all three files */ if (!raw_pull_is_done(i)) return; if (i->signature_job && i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) { log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)"); r = i->signature_job->error; goto finish; } if (i->roothash_job) i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd); if (i->settings_job) i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd); r = raw_pull_determine_path(i, ".raw", &i->final_path); if (r < 0) goto finish; if (!i->raw_job->etag_exists) { /* This is a new download, verify it, and move it into place */ assert(i->raw_job->disk_fd >= 0); raw_pull_report_progress(i, RAW_VERIFYING); r = pull_verify(i->raw_job, i->roothash_job, i->settings_job, i->checksum_job, i->signature_job); if (r < 0) goto finish; raw_pull_report_progress(i, RAW_UNPACKING); r = raw_pull_maybe_convert_qcow2(i); if (r < 0) goto finish; raw_pull_report_progress(i, RAW_FINALIZING); r = import_make_read_only_fd(i->raw_job->disk_fd); if (r < 0) goto finish; r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path); if (r < 0) { log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path); goto finish; } i->temp_path = mfree(i->temp_path); if (i->roothash_job && i->roothash_job->error == 0) { r = raw_pull_rename_auxiliary_file(i, ".roothash", &i->roothash_temp_path, &i->roothash_path); if (r < 0) goto finish; } if (i->settings_job && i->settings_job->error == 0) { r = raw_pull_rename_auxiliary_file(i, ".nspawn", &i->settings_temp_path, &i->settings_path); if (r < 0) goto finish; } } raw_pull_report_progress(i, RAW_COPYING); r = raw_pull_make_local_copy(i); if (r < 0) goto finish; r = 0; finish: if (i->on_finished) i->on_finished(i, r, i->userdata); else sd_event_exit(i->event, r); }
/* Go through the file and parse each line */ int config_parse(const char *unit, const char *filename, FILE *f, const char *sections, ConfigItemLookup lookup, const void *table, ConfigParseFlags flags, void *userdata) { _cleanup_free_ char *section = NULL, *continuation = NULL; _cleanup_fclose_ FILE *ours = NULL; unsigned line = 0, section_line = 0; bool section_ignored = false; int r; assert(filename); assert(lookup); if (!f) { f = ours = fopen(filename, "re"); if (!f) { /* Only log on request, except for ENOENT, * since we return 0 to the caller. */ if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT) log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno, "Failed to open configuration file '%s': %m", filename); return errno == ENOENT ? 0 : -errno; } } fd_warn_permissions(filename, fileno(f)); for (;;) { _cleanup_free_ char *buf = NULL; bool escaped = false; char *l, *p, *e; r = read_line(f, LONG_LINE_MAX, &buf); if (r == 0) break; if (r == -ENOBUFS) { if (flags & CONFIG_PARSE_WARN) log_error_errno(r, "%s:%u: Line too long", filename, line); return r; } if (r < 0) { if (CONFIG_PARSE_WARN) log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line); return r; } l = buf; if (!(flags & CONFIG_PARSE_REFUSE_BOM)) { char *q; q = startswith(buf, UTF8_BYTE_ORDER_MARK); if (q) { l = q; flags |= CONFIG_PARSE_REFUSE_BOM; } } if (continuation) { if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) { if (flags & CONFIG_PARSE_WARN) log_error("%s:%u: Continuation line too long", filename, line); return -ENOBUFS; } if (!strextend(&continuation, l, NULL)) { if (flags & CONFIG_PARSE_WARN) log_oom(); return -ENOMEM; } p = continuation; } else p = l; for (e = p; *e; e++) { if (escaped) escaped = false; else if (*e == '\\') escaped = true; } if (escaped) { *(e-1) = ' '; if (!continuation) { continuation = strdup(l); if (!continuation) { if (flags & CONFIG_PARSE_WARN) log_oom(); return -ENOMEM; } } continue; } r = parse_line(unit, filename, ++line, sections, lookup, table, flags, §ion, §ion_line, §ion_ignored, p, userdata); if (r < 0) { if (flags & CONFIG_PARSE_WARN) log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line); return r; } continuation = mfree(continuation); } if (continuation) { r = parse_line(unit, filename, ++line, sections, lookup, table, flags, §ion, §ion_line, §ion_ignored, continuation, userdata); if (r < 0) { if (flags & CONFIG_PARSE_WARN) log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line); return r; } } return 0; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_ROOT, ARG_LOCALE, ARG_LOCALE_MESSAGES, ARG_KEYMAP, ARG_TIMEZONE, ARG_HOSTNAME, ARG_MACHINE_ID, ARG_ROOT_PASSWORD, ARG_ROOT_PASSWORD_FILE, ARG_PROMPT, ARG_PROMPT_LOCALE, ARG_PROMPT_KEYMAP, ARG_PROMPT_TIMEZONE, ARG_PROMPT_HOSTNAME, ARG_PROMPT_ROOT_PASSWORD, ARG_COPY, ARG_COPY_LOCALE, ARG_COPY_KEYMAP, ARG_COPY_TIMEZONE, ARG_COPY_ROOT_PASSWORD, ARG_SETUP_MACHINE_ID, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "root", required_argument, NULL, ARG_ROOT }, { "locale", required_argument, NULL, ARG_LOCALE }, { "locale-messages", required_argument, NULL, ARG_LOCALE_MESSAGES }, { "keymap", required_argument, NULL, ARG_KEYMAP }, { "timezone", required_argument, NULL, ARG_TIMEZONE }, { "hostname", required_argument, NULL, ARG_HOSTNAME }, { "machine-id", required_argument, NULL, ARG_MACHINE_ID }, { "root-password", required_argument, NULL, ARG_ROOT_PASSWORD }, { "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE }, { "prompt", no_argument, NULL, ARG_PROMPT }, { "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE }, { "prompt-keymap", no_argument, NULL, ARG_PROMPT_KEYMAP }, { "prompt-timezone", no_argument, NULL, ARG_PROMPT_TIMEZONE }, { "prompt-hostname", no_argument, NULL, ARG_PROMPT_HOSTNAME }, { "prompt-root-password", no_argument, NULL, ARG_PROMPT_ROOT_PASSWORD }, { "copy", no_argument, NULL, ARG_COPY }, { "copy-locale", no_argument, NULL, ARG_COPY_LOCALE }, { "copy-keymap", no_argument, NULL, ARG_COPY_KEYMAP }, { "copy-timezone", no_argument, NULL, ARG_COPY_TIMEZONE }, { "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD }, { "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID }, {} }; int r, c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': return help(); case ARG_VERSION: return version(); case ARG_ROOT: r = parse_path_argument_and_warn(optarg, true, &arg_root); if (r < 0) return r; break; case ARG_LOCALE: if (!locale_is_valid(optarg)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not valid.", optarg); r = free_and_strdup(&arg_locale, optarg); if (r < 0) return log_oom(); break; case ARG_LOCALE_MESSAGES: if (!locale_is_valid(optarg)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Locale %s is not valid.", optarg); r = free_and_strdup(&arg_locale_messages, optarg); if (r < 0) return log_oom(); break; case ARG_KEYMAP: if (!keymap_is_valid(optarg)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Keymap %s is not valid.", optarg); r = free_and_strdup(&arg_keymap, optarg); if (r < 0) return log_oom(); break; case ARG_TIMEZONE: if (!timezone_is_valid(optarg, LOG_ERR)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Timezone %s is not valid.", optarg); r = free_and_strdup(&arg_timezone, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD: r = free_and_strdup(&arg_root_password, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD_FILE: arg_root_password = mfree(arg_root_password); r = read_one_line_file(optarg, &arg_root_password); if (r < 0) return log_error_errno(r, "Failed to read %s: %m", optarg); break; case ARG_HOSTNAME: if (!hostname_is_valid(optarg, true)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Host name %s is not valid.", optarg); hostname_cleanup(optarg); r = free_and_strdup(&arg_hostname, optarg); if (r < 0) return log_oom(); break; case ARG_MACHINE_ID: if (sd_id128_from_string(optarg, &arg_machine_id) < 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse machine id %s.", optarg); break; case ARG_PROMPT: arg_prompt_locale = arg_prompt_keymap = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true; break; case ARG_PROMPT_LOCALE: arg_prompt_locale = true; break; case ARG_PROMPT_KEYMAP: arg_prompt_keymap = true; break; case ARG_PROMPT_TIMEZONE: arg_prompt_timezone = true; break; case ARG_PROMPT_HOSTNAME: arg_prompt_hostname = true; break; case ARG_PROMPT_ROOT_PASSWORD: arg_prompt_root_password = true; break; case ARG_COPY: arg_copy_locale = arg_copy_keymap = arg_copy_timezone = arg_copy_root_password = true; break; case ARG_COPY_LOCALE: arg_copy_locale = true; break; case ARG_COPY_KEYMAP: arg_copy_keymap = true; break; case ARG_COPY_TIMEZONE: arg_copy_timezone = true; break; case ARG_COPY_ROOT_PASSWORD: arg_copy_root_password = true; break; case ARG_SETUP_MACHINE_ID: r = sd_id128_randomize(&arg_machine_id); if (r < 0) return log_error_errno(r, "Failed to generate randomized machine ID: %m"); break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
// . parse an incoming request // . return false and set g_errno on error // . CAUTION: we destroy "req" by replacing it's last char with a \0 // . last char must be \n or \r for it to be a proper request anyway bool HttpRequest::set ( char *origReq , long origReqLen , TcpSocket *sock ) { // reset number of cgi field terms reset(); if ( ! m_reqBuf.reserve ( origReqLen + 1 ) ) { log("http: failed to copy request: %s",mstrerror(g_errno)); return false; } // copy it to avoid mangling it m_reqBuf.safeMemcpy ( origReq , origReqLen ); // NULL term m_reqBuf.pushChar('\0'); m_reqBufValid = true; // and point to that char *req = m_reqBuf.getBufStart(); long reqLen = m_reqBuf.length() - 1; // save this m_userIP = 0; if ( sock ) m_userIP = sock->m_ip; m_isSSL = 0; if ( sock ) m_isSSL = (bool)sock->m_ssl; // TcpServer should always give us a NULL terminated request if ( req[reqLen] != '\0' ) { char *xx = NULL; *xx = 0; } // how long is the first line, the primary request long i; // for ( i = 0 ; i<reqLen && i<MAX_REQ_LEN && // req[i]!='\n' && req[i]!='\r'; i++); // . now fill up m_buf, used to log the request // . make sure the url was encoded correctly // . we don't want assholes encoding every char so we can't see what // url they are submitting to be spidered/indexed // . also, don't de-code encoded ' ' '+' '?' '=' '&' because that would // change the meaning of the url // . and finally, non-ascii chars that don't display correctly // . this should NULL terminate m_buf, too // . turn this off for now, just try to log a different way // m_bufLen = urlNormCode ( m_buf , MAX_REQ_LEN - 1 , req , i ); // ensure it's big enough to be a valid request if ( reqLen < 5 ) { log("http: got reqlen<5 = %s",req); g_errno = EBADREQUEST; return false; } // or if first line too long //if ( i >= 1024 ) { g_errno = EBADREQUEST; return false; } // get the type, must be GET or HEAD if ( strncmp ( req , "GET " , 4 ) == 0 ) m_requestType = 0; // these means a compressed reply was requested. use by query // compression proxies. else if ( strncmp ( req , "ZET " , 4 ) == 0 ) m_requestType = 0; else if ( strncmp ( req , "HEAD " , 5 ) == 0 ) m_requestType = 1; else if ( strncmp ( req , "POST " , 5 ) == 0 ) m_requestType = 2; else { log("http: got bad request cmd: %s",req); g_errno = EBADREQUEST; return false; } // . NULL terminate the request (a destructive operation!) // . this removes the last \n in the trailing \r\n // . shit, but it f***s up POST requests if ( m_requestType != 2 ) { req [ reqLen - 1 ] = '\0'; reqLen--; } // POST requests can be absolutely huge if you are injecting a 100MB // file, so limit our strstrs to the end of the mime char *d = NULL; char dc; // check for body if it was a POST request if ( m_requestType == 2 ) { d = strstr ( req , "\r\n\r\n" ); if ( d ) { dc = *d; *d = '\0'; } else log("http: Got POST request without \\r\\n\\r\\n."); } // . point to the file path // . skip over the "GET " long filenameStart = 4 ; // skip over extra char if it's a "HEAD " request if ( m_requestType == 1 || m_requestType == 2 ) filenameStart++; // are we a redirect? i = filenameStart; m_redirLen = 0; if ( strncmp ( &req[i] , "/?redir=" , 8 ) == 0 ) { for ( long k = i+8; k<reqLen && m_redirLen<126 ; k++) { if ( req[k] == '\r' ) break; if ( req[k] == '\n' ) break; if ( req[k] == '\t' ) break; if ( req[k] == ' ' ) break; m_redir[m_redirLen++] = req[k]; } } m_redir[m_redirLen] = '\0'; // find a \n space \r or ? that delimits the filename for ( i = filenameStart ; i < reqLen ; i++ ) { if ( is_wspace_a ( req [ i ] ) ) break; if ( req [ i ] == '?' ) break; } // now calc the filename length m_filenameLen = i - filenameStart; // return false and set g_errno if it's 0 if ( m_filenameLen <= 0 ) { log("http: got filenameLen<=0: %s",req); g_errno = EBADREQUEST; return false; } // . bitch if too big // . leave room for strcatting "index.html" below if ( m_filenameLen >= MAX_HTTP_FILENAME_LEN - 10 ) { log("http: got filenameLen>=max"); g_errno = EBADREQUEST; return false; } // . decode the filename into m_filename and reassign it's length // . decode %2F to / , etc... m_filenameLen = urlDecode(m_filename,req+filenameStart,m_filenameLen); // NULL terminate m_filename m_filename [ m_filenameLen ] = '\0'; // does it have a file extension AFTER the last / in the filename? bool hasExtension = false; for ( long j = m_filenameLen-1 ; j >= 0 ; j-- ) { if ( m_filename[j] == '.' ) { hasExtension = true; break; } if ( m_filename[j] == '/' ) break; } // if it has no file extension append a /index.html if ( ! hasExtension && m_filename [ m_filenameLen - 1 ] == '/' ) { strcat ( m_filename , "index.html" ); m_filenameLen = gbstrlen ( m_filename ); } // set file offset/size defaults m_fileOffset = 0; // -1 means ALL the file from m_fileOffset onwards m_fileSize = -1; // "e" points to where the range actually starts, if any //char *e; // . TODO: speed up by doing one strstr for Range: and maybe range: // . do they have a Range: 0-100\n in the mime denoting a partial get? //char *s = strstr ( req ,"Range:bytes=" ); //e = s + 12; // try alternate formats //if ( ! s ) { s = strstr ( req ,"Range: bytes=" ); e = s + 13; } //if ( ! s ) { s = strstr ( req ,"Range: " ); e = s + 7; } // parse out the range if we got one //if ( s ) { // long x = 0; // sscanf ( e ,"%li-%li" , &m_fileOffset , &x ); // // get all file if range's 2nd number is non-existant // if ( x == 0 ) m_fileSize = -1; // else m_fileSize = x - m_fileOffset; // // ensure legitimacy // if ( m_fileOffset < 0 ) m_fileOffset = 0; //} // reset our hostname m_hostLen = 0; // assume request is NOT from local network //m_isAdmin = false; m_isLocal = false; // get the virtual hostname they want to use char *s = strstr ( req ,"Host:" ); // try alternate formats if ( ! s ) s = strstr ( req , "host:" ); // must be on its own line, otherwise it's not valid if ( s && s > req && *(s-1) !='\n' ) s = NULL; // parse out the host if we got one if ( s ) { // skip field name, host: s += 5; // skip e to beginning of the host name after "host:" while ( *s==' ' || *s=='\t' ) s++; // find end of the host name char *end = s; while ( *end && !is_wspace_a(*end) ) end++; // . now *end should be \0, \n, \r, ' ', ... // . get host len m_hostLen = end - s; // truncate if too big if ( m_hostLen >= 255 ) m_hostLen = 254; // copy into hostname memcpy ( m_host , s , m_hostLen ); } // NULL terminate it m_host [ m_hostLen ] = '\0'; // get Referer: field s = strstr ( req ,"Referer:" ); // find another if ( ! s ) s = strstr ( req ,"referer:" ); // must be on its own line, otherwise it's not valid if ( s && s > req && *(s-1) !='\n' ) s = NULL; // assume no referer m_refLen = 0; // parse out the referer if we got one if ( s ) { // skip field name, referer: s += 8; // skip e to beginning of the host name after ':' while ( *s==' ' || *s=='\t' ) s++; // find end of the host name char *end = s; while ( *end && !is_wspace_a(*end) ) end++; // . now *end should be \0, \n, \r, ' ', ... // . get len m_refLen = end - s; // truncate if too big if ( m_refLen >= 255 ) m_refLen = 254; // copy into m_ref memcpy ( m_ref , s , m_refLen ); } // NULL terminate it m_ref [ m_refLen ] = '\0'; // get User-Agent: field s = strstr ( req ,"User-Agent:" ); // find another if ( ! s ) s = strstr ( req ,"user-agent:" ); // must be on its own line, otherwise it's not valid if ( s && s > req && *(s-1) !='\n' ) s = NULL; // assume empty long len = 0; // parse out the referer if we got one if ( s ) { // skip field name, referer: s += 11; // skip e to beginning of the host name after ':' while ( *s==' ' || *s=='\t' ) s++; // find end of the agent name char *end = s; while ( *end && *end!='\n' && *end!='\r' ) end++; // . now *end should be \0, \n, \r, ' ', ... // . get agent len len = end - s; // truncate if too big if ( len > 127 ) len = 127; // copy into m_userAgent memcpy ( m_userAgent , s , len ); } // NULL terminate it m_userAgent [ len ] = '\0'; m_isMSIE = false; if ( strstr ( m_userAgent , "MSIE" ) ) m_isMSIE = true; // get Cookie: field s = strstr ( req, "Cookie:" ); // find another if ( !s ) s = strstr ( req, "cookie:" ); // must be on its own line, otherwise it's not valid if ( s && s > req && *(s-1) != '\n' ) s = NULL; // assume empty // m_cookieBufLen = 0; m_cookiePtr = s; // parse out the cookie if we got one if ( s ) { // skip field name, Cookie: s += 7; // skip s to beginning of cookie after ':' while ( *s == ' ' || *s == '\t' ) s++; // find end of the cookie char *end = s; while ( *end && *end != '\n' && *end != '\r' ) end++; // save length m_cookieLen = end - m_cookiePtr; // get cookie len //m_cookieBufLen = end - s; // trunc if too big //if (m_cookieBufLen > 1023) m_cookieBufLen = 1023; // copy into m_cookieBuf //memcpy(m_cookieBuf, s, m_cookieBufLen); } // NULL terminate it if ( m_cookiePtr ) m_cookiePtr[m_cookieLen] = '\0'; //m_cookieBuf[m_cookieBufLen] = '\0'; // convert every '&' in cookie to a \0 for parsing the fields // for ( long j = 0 ; j < m_cookieBufLen ; j++ ) // if ( m_cookieBuf[j] == '&' ) m_cookieBuf[j] = '\0'; // mark it as cgi if it has a ? bool isCgi = ( req [ i ] == '?' ) ; // reset m_filename length to exclude the ?* stuff if ( isCgi ) { // skip over the '?' i++; // find a space the delmits end of cgi long j; for ( j = i; j < reqLen; j++) if (is_wspace_a(req[j])) break; // now add it if ( ! addCgi ( &req[i] , j-i ) ) return false; // update i i = j; } // . set path ptrs // . the whole /cgi/14.cgi?coll=xxx&..... thang m_path = req + filenameStart; m_plen = i - filenameStart; // we're local if hostname is 192.168.[0|1].y //if ( strncmp(iptoa(sock->m_ip),"192.168.1.",10) == 0) { // m_isAdmin = true; m_isLocal = true; } //if ( strncmp(iptoa(sock->m_ip),"192.168.0.",10) == 0) { // m_isAdmin = true; m_isLocal = true; } //if(strncmp(iptoa(sock->m_ip),"192.168.1.",10) == 0) m_isLocal = true; //if(strncmp(iptoa(sock->m_ip),"192.168.0.",10) == 0) m_isLocal = true; if ( sock && strncmp(iptoa(sock->m_ip),"192.168.",8) == 0) m_isLocal = true; if ( sock && strncmp(iptoa(sock->m_ip),"10.",3) == 0) m_isLocal = true; // steve cook's comcast at home: // if ( sock && strncmp(iptoa(sock->m_ip),"68.35.100.143",13) == 0) // m_isLocal = true; // procog's ip // if ( sock && strncmp(iptoa(sock->m_ip),"216.168.36.21",13) == 0) // m_isLocal = true; // roadrunner ip // if ( sock && strncmp(iptoa(sock->m_ip),"66.162.42.131",13) == 0) // m_isLocal = true; // cnsp ip //if ( sock && strncmp(iptoa(sock->m_ip),"67.130.216.27",13) == 0) // m_isLocal = true; // emily parker //if ( sock && strncmp(iptoa(sock->m_ip),"69.92.68.202",12) == 0) //m_isLocal = true; // 127.0.0.1 if ( sock && sock->m_ip == 16777343 ) m_isLocal = true; // steve cook's webserver //if ( sock && strncmp(iptoa(sock->m_ip),"216.168.36.21",13) == 0) // m_isLocal = true; // . also if we're coming from lenny at my house consider it local // . this is a security risk, however... TODO: FIX!!! //if ( sock->m_ip == atoip ("68.35.105.199" , 13 ) ) m_isAdmin = true; // . TODO: now add any cgi data from a POST..... // . look after the mime //char *d = NULL; // check for body if it was a POST request //if ( m_requestType == 2 ) d = strstr ( req , "\r\n\r\n" ); // now put d's char back, just in case... does it really matter? if ( d ) *d = dc; // return true now if no cgi stuff to parse if ( d ) { char *post = d + 4; long postLen = reqLen-(d+4-req) ; // post sometimes has a \r or\n after it while ( postLen > 0 && post[postLen-1]=='\r' ) postLen--; // add it to m_cgiBuf, filter and everything if ( ! addCgi ( post , postLen ) ) return false; } // sometimes i don't want to be admin //if ( getLong ( "admin" , 1 ) == 0 ) m_isAdmin = false; // success ///// // Handle Extra parms... char *ep = g_conf.m_extraParms; char *epend = g_conf.m_extraParms + g_conf.m_extraParmsLen; char *qstr = m_cgiBuf; long qlen = m_cgiBufLen; while (ep < epend){ char buf[AUTOBAN_TEXT_SIZE]; long bufLen = 0; // get next substring while (*ep && ep < epend && *ep != ' ' && *ep != '\n'){ buf[bufLen++] = *ep++; } // skip whitespace while (*ep && ep < epend && *ep == ' '){ ep++; } // null terminate buf[bufLen] = '\0'; // No match if (!bufLen || !strnstr(qstr, qlen, buf)){ // skip to end of line while (*ep && ep < epend && *ep != '\n') ep++; // skip newline while (*ep && ep < epend && *ep == '\n') ep++; // try next substr continue; } // found a match... // get parm string bufLen = 0; while (*ep && ep < epend && *ep != '\n'){ buf[bufLen++] = *ep++; } buf[bufLen] = '\0'; // skip newline while (*ep && ep < epend && *ep == '\n') ep++; logf(LOG_DEBUG, "query: appending \"%s\" to query", buf); long newSize = m_cgiBuf2Size + bufLen+1; char *newBuf = (char*)mmalloc(newSize, "extraParms"); if (!newBuf){ return log("query: unable to allocate %ld bytes " "for extraParms", newSize); } char *p = newBuf; if (m_cgiBuf2Size) { memcpy(newBuf, m_cgiBuf2, m_cgiBuf2Size); p += m_cgiBuf2Size-1; mfree(m_cgiBuf2, m_cgiBuf2Size, "extraParms"); m_cgiBuf2 = NULL; m_cgiBuf2Size = 0; } memcpy(p, buf, bufLen); m_cgiBuf2 = newBuf; m_cgiBuf2Size = newSize; p += bufLen; *p = '\0'; } // Put '\0' back into the HttpRequest buffer... if (m_cgiBuf){ // do not mangle the "ucontent"! long cgiBufLen = m_cgiBufLen; cgiBufLen -= m_ucontentLen; char *buf = m_cgiBuf; for (long i = 0; i < cgiBufLen ; i++) if (buf[i] == '&') buf[i] = '\0'; // don't decode the ucontent= field! long decodeLen = m_cgiBufLen; // so subtract that if ( m_ucontent ) decodeLen -= m_ucontentLen; // decode everything long len = urlDecode ( m_cgiBuf , m_cgiBuf , decodeLen ); // we're parsing crap after the null if the last parm // has no value //memset(m_cgiBuf+len, '\0', m_cgiBufLen-len); m_cgiBufLen = len; // ensure that is null i guess if ( ! m_ucontent ) m_cgiBuf[len] = '\0'; } if (m_cgiBuf2){ char *buf = m_cgiBuf2; for (long i = 0; i < m_cgiBuf2Size-1 ; i++) if (buf[i] == '&') buf[i] = '\0'; long len = urlDecode ( m_cgiBuf2 , m_cgiBuf2 , m_cgiBuf2Size); memset(m_cgiBuf2+len, '\0', m_cgiBuf2Size-len); } // . parse the fields after the ? in a cgi filename // . or fields in the content if it's a POST // . m_cgiBuf must be and is NULL terminated for this parseFields ( m_cgiBuf , m_cgiBufLen ); // Add extra parms to the request. if (m_cgiBuf2Size){ parseFields(m_cgiBuf2, m_cgiBuf2Size); } // urldecode the cookie buf too!! if ( m_cookiePtr ) { char *p = m_cookiePtr; for (long i = 0; i < m_cookieLen ; i++) { //if (p[i] == '&') p[i] = '\0'; // cookies are separated with ';' in the request only if (p[i] == ';') p[i] = '\0'; // a hack for the metacookie=.... // which uses &'s to separate its subcookies // this is a hack for msie's limit of 50 cookies if ( p[i] == '&' ) p[i] = '\0'; // set m_metaCookie to start of meta cookie if ( p[i] == 'm' && p[i+1] == 'e' && strncmp(p,"metacookie",10) == 0 ) m_metaCookie = p; } long len = urlDecode ( m_cookiePtr , m_cookiePtr, m_cookieLen ); // we're parsing crap after the null if the last parm // has no value memset(m_cookiePtr+len, '\0', m_cookieLen-len); m_cookieLen = len; } return true; }
void PDFDocSaveUnPackedUnLinearized(PDFDocHandle Doc, PDFStreamHandle Strm) { char str[128]; ppUns32 i, xrefoffset; ppUns32 k; PDFCosHandle obj,wrk, ar, z, cr; PDFCosHandle tobj; PDFID ID, EID; char *pstr; TPDFCryptoType ncr, *UsedCrypto = NULL; ppBool crypting = false, delID = false; char c; #ifndef NOT_USE_SIGN sha1_Context hctx; PDFStreamHandle ms = NULL; int fs, s1, o2, s2, hlen = SHA1_HASHSIZE; ppUns8 hash[SHA1_HASHSIZE]; #endif _CosNullNew (Doc, cr); _CosNullNew (Doc, tobj); #ifndef NOT_USE_SIGN if ( _DOC->Signed ){ sig_AddSigDict ( Doc ); sig_AddSigAnnot ( Doc ); sig_UpdateAcroForm ( Doc ); sig_UpdatePageAnnots ( Doc ); ms = ULStreamMemNew ( _LIB, 0 ); } #endif if ( _DOC->Remove ){ PDFDocRemoveUnUsed ( Doc, NULL ); k = 1; for ( i = 1; i < _DOC->Size; i++ ){ if ( ( ( CosDoc ) Doc )->Entries[i].Used != etFree ) ( ( CosDoc ) Doc )->Entries[i].Additional = k++; else ( ( CosDoc ) Doc )->Entries[i].Additional = 0x7FFFFFFF; } PDFDocRenumAllObjects ( Doc ); PDFDocPackFree ( ( CosDoc ) Doc ); } if ( _DOC->UseOldSecurity ){ if ( _DOC->Crypted ){ crypting = true; UsedCrypto = &( _DOC->CryptoInfo ); }; } else{ if ( _DOC->NewCrypted ){ crypting = true; ULSetNewCryptoData( Doc, &ncr ); UsedCrypto = &ncr; delID = true; }; }; PDFTRY ( _LIB ){ if ( crypting ){ cr = ULPrepareCryptoDictionary (Doc, UsedCrypto ); EID= _CosObjFullID (cr); }; if (((CosDoc)Doc)->Version >= 9){ _CosDictAppend(_DOC->Root,Extensions,obj = CosDictNew(Doc,false,1)); _CosDictAppend(obj,ADBE,wrk = CosDictNew(Doc,false,2)); _CosDictAppend(wrk,BaseVersion,CosNameNew(Doc, false,ULStringToAtom(_LIB,"1.7"))); _CosDictAppend(wrk,ExtensionLevel, CosIntNew(Doc,false,3)); } /* #ifndef NOT_USE_SIGN if ( _DOC->Signed ){ sig_AddSigDict ( Doc ); sig_AddSigAnnot ( Doc ); sig_UpdateAcroForm ( Doc ); sig_UpdatePageAnnots ( Doc ); ms = ULStreamMemNew ( _LIB, 0 ); } #endif*/ _CosNullNew(Doc, z); _CosNullNew(Doc, ar); PDFTRY ( _LIB ){ tobj = CosDictNew ( Doc, false, 4 ); _CosDictAppend ( tobj, Size, CosIntNew ( Doc, false, _DOC->Size ) ); _CosDictAppend ( tobj, Root, _DOC->Root ); _CosDictAppend ( tobj, Info, _DOC->Info ); if ( crypting ) _CosDictAppend ( tobj, Encrypt, cr ); _CosDictAppend ( tobj, ID, ( ar = CosArrayNew ( Doc, false, 2 ) ) ); if ( crypting ) z = CosCopy ( Doc, UsedCrypto->FileID ); else z = ULCreateFileID ( Doc, PDFEngine ); _CosStringHex(z) = true; CosArrayAppend ( ar, z ); CosArrayAppend ( ar, CosCopy (Doc, z ) ); } PDFEXCEPT ( _LIB ){ CosFree ( tobj ); CosFree ( z ); PDFRERAISE ( _LIB ); } PDFTRYEND ( _LIB ); #ifndef NOT_USE_SIGN if ( _DOC->Signed ) sha1_Init ( &hctx ); #endif SULStrToStrm ( Strm, "%PDF-1." ); c =(ppInt8)( _DOC->Version + '0'); SULStrmWriteChar ( Strm, c ); SULStrToStrm ( Strm, "\r\n" ); SULStrToStrm ( Strm, "%\330\302\300\314\r\n" ); for ( i = 1; i < _DOC->Size; i++ ){ if ( _DOC->Entries[i].Used != etFree ){ #ifndef NOT_USE_SIGN if ( _DOC->Signed && _CosObjID( _DOC->SigCtx->Sign) == i ) break; #endif obj = CosGetFromDoc ( Doc, i ); if ( crypting ){ obj = CosCopy( Doc, obj ); ID.ID = i; ID.GenID = _DOC->Entries[i].Generation; if ( i != EID.ID ) CosCryptObject ( obj, UsedCrypto, ID, true ); }; _DOC->Entries[i].Offset = ULStreamGetPosition ( Strm ); ULitostr ( i, str ); SULStrToStrm ( Strm, str ); SULStrToStrm ( Strm, " " ); ULitostr ( _DOC->Entries[i].Generation, str ); SULStrToStrm ( Strm, str ); if ( _CosGetType ( obj ) < CosName ) SULStrToStrm ( Strm, " obj " ) else SULStrToStrm ( Strm, " obj" ) #ifndef NOT_USE_SIGN if ( _DOC->Signed ){ CosCopyObjToStream (obj, ms ); sha1_Update ( &hctx, ( ppUns8 *) ULStrmGetMem ( ms ), ULStreamGetSize ( ms ) ); ULStreamCopyToStream ( ms, Strm ); ULStreamClear ( ms, 0 ); } else #endif CosCopyObjToStream (obj, Strm ); if ( crypting ) CosFree ( obj ); SULStrToStrm ( Strm, "\nendobj\n" ); }; }; #ifndef NOT_USE_SIGN if ( _DOC->Signed ){ fs = ULStreamGetPosition ( Strm ); TailPass ( Doc, i, tobj, UsedCrypto, EID, &fs, &s1, &o2, NULL ); s2 = fs - o2; sig_UpdateByteRange ( Doc, s1, o2, s2 ); fs = ULStreamGetPosition ( Strm ); TailPass ( Doc, i, tobj, UsedCrypto, EID, &fs, &s1, &o2, &hctx ); sha1_Finish ( &hctx, hash ); sig_UpdateContents ( Doc, hash, hlen ); for ( ; i < _DOC->Size; i++ ){ if ( _DOC->Entries[i].Used != etFree ){ obj = CosGetFromDoc ( Doc, i ); if ( crypting ){ obj = CosCopy( Doc, obj ); ID.ID = i; ID.GenID = _DOC->Entries[i].Generation; if ( i != EID.ID ) CosCryptObject ( obj, UsedCrypto, ID, true ); } _DOC->Entries[i].Offset = ULStreamGetPosition ( Strm ); ULitostr ( i, str ); ULStrToStrm ( Strm, str ); ULStrToStrm ( Strm, " " ); ULitostr ( _DOC->Entries[i].Generation, str ); ULStrToStrm ( Strm, str ); if ( _CosGetType ( obj ) < CosName ) ULStrToStrm ( Strm, " obj " ); else ULStrToStrm ( Strm, " obj" ); CosCopyObjToStream ( obj, Strm ); if ( crypting ) CosFree ( obj ); ULStrToStrm ( Strm, "\nendobj\n" ); } } } #endif xrefoffset = ULStreamGetPosition ( Strm ); ULStrToStrm ( Strm, "xref\r\n0 " ); ULitostr ( _DOC->Size, str ); ULStrToStrm ( Strm, str ); ULStrToStrm ( Strm, "\r\n0000000000 65535 f\r\n" ); for ( i = 1; i < _DOC->Size; i++ ){ if ( _DOC->Entries[i].Used != etFree ){ pstr = ULIntToStrWithZero ( _LIB, _DOC->Entries[i].Offset, 10 ); ULStrToStrm ( Strm, pstr ); mfree ( _LIB, pstr ); ULStreamWriteChar ( Strm, ' ' ); } else ULStrToStrm ( Strm, "0000000000 " ); if ( _DOC->Entries[i].Generation == 0xFFFF ) pstr = ULIntToStrWithZero ( _LIB, 0, 5 ); else pstr = ULIntToStrWithZero ( _LIB, _DOC->Entries[i].Generation, 5 ); ULStrToStrm ( Strm, pstr ); mfree ( _LIB, pstr ); _DOC->Entries[i].Used != etFree ? ULStrToStrm ( Strm, " n\r\n" ) : ULStrToStrm ( Strm, " f\r\n" ); } ULStrToStrm ( Strm, "trailer\r\n" ); CosCopyObjToStream ( tobj, Strm ); CosFree ( tobj ); ULStrToStrm ( Strm, "\r\nstartxref\r\n" ); ULIntToStrm ( Strm, xrefoffset ); ULStrToStrm ( Strm, "\r\n%%EOF" ); if ( crypting ) PDFDocDeleteObjEx ( Doc, EID.ID); #ifndef NOT_USE_SIGN if ( _DOC->Signed ) ULStreamClose ( ms ); #endif } PDFEXCEPT ( _LIB ){ CosFree ( ncr.FileID ); #ifndef NOT_USE_SIGN if ( ms ) ULStreamClose ( ms ); #endif CosFree ( tobj ); PDFRERAISE ( _LIB ); } PDFTRYEND ( _LIB ); if ( delID ) CosFree ( ncr.FileID ); }
// // new code for drawing graph in html with absolute divs instead // of using GIF plotter library which had issues // void Stats::printGraphInHtml ( SafeBuf &sb ) { // gif size char tmp[64]; sprintf ( tmp , "%lix%li", (long)DX+40 , (long)DY+40 ); // "1040x440" // 20 pixel borders //int bx = 10; //int by = 30; // define the space with boundaries 100 unit wide boundaries //plotter.space ( -bx , -by , DX + bx , DY + by ); // draw the x-axis //plotter.line ( 0 , 0 , DX , 0 ); // draw the y-axis //plotter.line ( 0 , 0 , 0 , DY ); // find time ranges long long t2 = 0; for ( long i = 0 ; i < MAX_POINTS ; i++ ) { // skip empties if ( m_pts[i].m_startTime == 0 ) continue; // set min/max if ( m_pts[i].m_endTime > t2 ) t2 = m_pts[i].m_endTime; } // now compute the start time for the graph long long t1 = 0x7fffffffffffffffLL; // now recompute t1 for ( long i = 0 ; i < MAX_POINTS ; i++ ) { // skip empties if ( m_pts[i].m_startTime == 0 ) continue; // can't be behind more than 1 second if ( m_pts[i].m_startTime < t2 - DT ) continue; // otherwise, it's a candidate for the first time if ( m_pts[i].m_startTime < t1 ) t1 = m_pts[i].m_startTime; } // // main graphing window // sb.safePrintf("<div style=\"position:relative;" "background-color:#c0c0c0;" // match style of tables "border-radius:10px;" "border:#6060f0 2px solid;" //"overflow-y:hidden;" "overflow-x:hidden;" "z-index:-10;" // the tick marks we print below are based on it // being a window of the last 20 seconds... and using // DX pixels "min-width:%lipx;" "min-height:%lipx;" //"width:100%%;" //"min-height:600px;" //"margin-top:10px;" "margin-bottom:10px;" //"margin-right:10px;" //"margin-left:10px;" "\">" ,(long)DX ,(long)DY +20); // add 10 more for "2s" labels etc. // 10 x-axis tick marks for ( int x = DX/20 ; x <= DX ; x += DX/20 ) { // tick mark //plotter.line ( x , -20 , x , 20 ); sb.safePrintf("<div style=\"position:absolute;" "left:%li;" "bottom:0;" "background-color:#000000;" "z-index:110;" "min-height:20px;" "min-width:3px;\"></div>\n" , (long)x-1 ); // generate label //char buf [ 32 ]; //sprintf ( buf , "%li" , // (long)(DT * (long long)x / (long long)DX) ); // LABEL sb.safePrintf("<div style=\"position:absolute;" "left:%li;" "bottom:20;" //"background-color:#000000;" "z-index:110;" "min-height:20px;" "min-width:3px;\">%lis</div>\n" , (long)x-10 // the label: ,(long)(DT * (long long)x / (long long)DX)/1000 ); // move cursor //plotter.move ( x , -by / 2 - 9 ); // plot label //plotter.alabel ( 'c' , 'c' , buf ); } // . each line consists of several points // . we need to know each point for adding otherlines // . is about [400/6][1024] = 70k // . each line can contain multiple data points // . each data point is expressed as a horizontal line segment void *lrgBuf; long lrgSize = 0; lrgSize += MAX_LINES * MAX_POINTS * sizeof(StatPoint *); lrgSize += MAX_LINES * sizeof(long); lrgBuf = (char *) mmalloc(lrgSize, "Stats.cpp"); if (! lrgBuf) { log("could not allocate memory for local buffer in Stats.cpp" "%li bytes needed", lrgSize); return; } char *lrgPtr = (char *)lrgBuf; StatPoint **points = (StatPoint **)lrgPtr; lrgPtr += MAX_LINES * MAX_POINTS * sizeof(StatPoint *); long *numPoints = (long *)lrgPtr; lrgPtr += MAX_LINES * sizeof(long); memset ( (char *)numPoints , 0 , MAX_LINES * sizeof(long) ); // store the data points into "lines" long count = MAX_POINTS; for ( long i = m_next ; count >= 0 ; i++ , count-- ) { // wrap around the array if ( i >= MAX_POINTS ) i = 0; // skip point if empty if ( m_pts[i].m_startTime == 0 ) continue; // skip if too early if ( m_pts[i].m_endTime < t1 ) continue; // . find the lowest line the will hold us // . this adds point to points[x][n] where x is determined addPoint ( points , numPoints , &m_pts[i] ); } int y1 = 21; // plot the points (lines) in each line for ( long i = 0 ; i < MAX_LINES ; i++ ) { // increase vert y1 += MAX_WIDTH + 1; // wrap back down if necessary if ( y1 >= DY ) y1 = 21; // plt all points in this row for ( long j = 0 ; j < numPoints[i] ; j++ ) { // get the point StatPoint *p = points[MAX_POINTS * i + j]; // transform time to x coordinates int x1 = (p->m_startTime - t1) * (long long)DX / DT; int x2 = (p->m_endTime - t1) * (long long)DX / DT; // if x2 is negative, skip it if ( x2 < 0 ) continue; // if x1 is negative, boost it to -2 if ( x1 < 0 ) x1 = -2; // . line thickness is function of read/write size // . take logs int w = (int)log(((double)p->m_numBytes)/8192.0) + 3; //log("log of %li is %i",m_pts[i].m_numBytes,w); if ( w < 3 ) w = 3; if ( w > MAX_WIDTH ) w = MAX_WIDTH; //plotter.linewidth ( w ); // use the color specified from addStat_r() for this line/pt //plotter.pencolor ( ((p->m_color >> 16) & 0xff) << 8 , // ((p->m_color >> 8) & 0xff) << 8 , // ((p->m_color >> 0) & 0xff) << 8 ); // ensure at least 3 units wide for visibility if ( x2 < x1 + 3 ) x2 = x1 + 3; // . flip the y so we don't have to scroll the browser down // . DY does not include the axis and tick marks long fy1 = DY - y1 + 20 ; // plot it //plotter.line ( x1 , fy1 , x2 , fy1 ); drawLine2 ( sb , x1 , x2 , fy1 , p->m_color , w ); // debug msg //log("line (%i,%i, %i,%i) ", x1 , vert , x2 , vert ); //log("bytes = %li width = %li ", m_pts[i].m_numBytes,w); //log("st=%i, end=%i color=%lx " , // (int)m_pts[i].m_startTime , // (int)m_pts[i].m_endTime , // m_pts[i].m_color ); } } sb.safePrintf("</div>\n"); mfree(lrgBuf, lrgSize, "Stats.cpp"); }
void TailPass(PDFDocHandle Doc, int start, PDFCosHandle tobj, TPDFCryptoType *crypto, PDFID EID, int *fsize, int *s1, int *o2, sha1_Context *ctx) { PDFStreamHandle strm= NULL; PDFCosHandle obj ; PDFID ID; ppBool crypting; char str[128], *pstr, *p, *q; ppUns32 i, l; _CosNullNew(Doc, obj); crypting = (ppBool)( crypto != NULL ); PDFTRY ( _LIB ){ strm = ULStreamMemNew ( _LIB, 0 ); obj = CosGetFromDoc ( Doc, start); if ( crypting ){ obj= CosCopy( Doc, obj ); ID.ID = start; ID.GenID = _DOC->Entries[start].Generation; CosCryptObject ( obj, crypto, ID, true ); } _DOC->Entries[start].Offset = *fsize; ULitostr ( start, str ); ULStrToStrm ( strm, str ); ULStrToStrm ( strm, " " ); ULitostr ( _DOC->Entries[start].Generation, str ); ULStrToStrm ( strm, str ); if ( _CosGetType ( obj ) < CosName ) ULStrToStrm ( strm, " obj " ); else ULStrToStrm ( strm, " obj" ); CosCopyObjToStream ( obj, strm ); if ( crypting ) CosFree ( obj ); ULStrToStrm ( strm, "\nendobj\n" ); p = ( char * ) ULStrmGetMem ( strm ); q = strstr ( p, "/Contents" ); q += strlen ( "/Contents" ); ( *s1 ) = *fsize + ( int ) ( q - p ); if ( ctx != NULL ) sha1_Update ( ctx, (ppUns8 *) p, ( int ) ( q - p ) ); q = strchr ( p, '>' ); l = ULStreamGetSize ( strm ); if ( ctx != NULL ) sha1_Update ( ctx, (ppUns8 *) (q + 1), l - ( int ) ( q - p ) - 1 ); ( *o2 ) = *fsize + ( int ) ( q - p ) + 1; ( *fsize ) += ULStreamGetSize ( strm ); ULStreamClear ( strm, 0 ); for ( i = start + 1; i < _DOC->Size; i++ ){ if ( _DOC->Entries[i].Used != etFree ){ obj = CosGetFromDoc ( Doc, i ); if ( crypting ){ obj = CosCopy ( Doc, obj ); ID.ID = i; ID.GenID = _DOC->Entries[i].Generation; if ( i != EID.ID ) CosCryptObject ( obj, crypto, ID, true ); } _DOC->Entries[i].Offset = *fsize; ULitostr ( i, str ); ULStrToStrm ( strm, str ); ULStrToStrm ( strm, " " ); ULitostr ( _DOC->Entries[i].Generation, str ); ULStrToStrm ( strm, str ); if ( _CosGetType ( obj ) < CosName ) ULStrToStrm ( strm, " obj " ); else ULStrToStrm ( strm, " obj" ); CosCopyObjToStream ( obj, strm ); if ( crypting ) CosFree ( obj ); ULStrToStrm ( strm, "\nendobj\n" ); ( *fsize ) += ULStreamGetSize ( strm ); if ( ctx != NULL ) sha1_Update ( ctx, ( ppUns8 * ) ULStrmGetMem ( strm ), ULStreamGetSize ( strm ) ); ULStreamClear ( strm, 0 ); } } ULStrToStrm ( strm, "xref\r\n0 " ); ULitostr ( _DOC->Size, str ); ULStrToStrm ( strm, str ); ULStrToStrm ( strm, "\r\n0000000000 65535 f\r\n" ); for ( i = 1; i < _DOC->Size; i++ ){ if ( _DOC->Entries[i].Used != etFree ){ pstr = ULIntToStrWithZero ( _LIB, _DOC->Entries[i].Offset, 10 ); ULStrToStrm ( strm, pstr ); mfree ( _LIB, pstr ); ULStreamWriteChar ( strm, ' ' ); } else ULStrToStrm ( strm, "0000000000 " ); if ( _DOC->Entries[i].Generation == 0xFFFF ) pstr = ULIntToStrWithZero ( _LIB, 0, 5 ); else pstr = ULIntToStrWithZero ( _LIB, _DOC->Entries[i].Generation, 5 ); ULStrToStrm ( strm, pstr ); mfree ( _LIB, pstr ); if ( _DOC->Entries[i].Used != etFree ) ULStrToStrm ( strm, " n\r\n" ); else ULStrToStrm ( strm, " f\r\n" ); } ULStrToStrm ( strm, "trailer\r\n" ); CosCopyObjToStream (tobj, strm ); ULStrToStrm ( strm, "\r\nstartxref\r\n" ); ULIntToStrm ( strm, *fsize ); ULStrToStrm ( strm, "\r\n%%EOF" ); ( *fsize ) += ULStreamGetSize ( strm ); if ( ctx != NULL ) sha1_Update ( ctx, ( ppUns8 * ) ULStrmGetMem ( strm ), ULStreamGetSize ( strm ) ); ULStreamClose ( strm ); } PDFEXCEPT ( _LIB ){ if ( strm ) ULStreamClose ( strm ); if ( crypting ) CosFree ( obj ); PDFRERAISE ( _LIB ); } PDFTRYEND ( _LIB ); }
Blaster::~Blaster() { if (m_buf1) mfree(m_buf1,m_bufSize1,"blaster1"); if (m_buf2) mfree(m_buf2,m_bufSize2,"blaster2"); }
void CountryCode::freeRegexTable(void) { if(!s_countryRegex) return; for(int x = 1; x < s_numCountryCodes; x++) regfree(&s_countryRegex[x]); mfree(s_countryRegex, s_numCountryCodes * sizeof(regex_t), "CountryRegex"); }
void gc(void) { int i, j; U *p; // tag everything for (i = 0; i < mcount; i++) { p = mem[i]; for (j = 0; j < N; j++) p[j].tag = 1; } // untag what's used untag(p0); untag(p1); untag(p2); untag(p3); untag(p4); untag(p5); untag(p6); untag(p7); untag(p8); untag(p9); untag(one); untag(zero); untag(imaginaryunit); for (i = 0; i < NSYM; i++) { untag(binding[i]); untag(arglist[i]); } for (i = 0; i < tos; i++) untag(stack[i]); for (i = (int) (frame - stack); i < TOS; i++) untag(stack[i]); // collect everything that's still tagged free_count = 0; for (i = 0; i < mcount; i++) { p = mem[i]; for (j = 0; j < N; j++) { if (p[j].tag == 0) continue; // still tagged so it's unused, put on free list switch (p[j].k) { case TENSOR: free(p[j].u.tensor); break; case STR: free(p[j].u.str); break; case NUM: mfree(p[j].u.q.a); mfree(p[j].u.q.b); break; } p[j].k = CONS; // so no double free occurs above p[j].u.cons.cdr = free_list; free_list = p + j; free_count++; } } }
int HECMW_vis_surface_compute(Surface *sff, struct hecmwST_local_mesh *mesh, struct hecmwST_result_data *data, int *bdflag, int *sum_v, int *sum_t, int *tvertex, int *tpatch, double *minc, double *maxc, Result *result, int sf_i, int mynode, HECMW_Comm VIS_COMM) { /* in_volume */ int i, j, k, mm; Point **CS_verts_head; Polygon **CS_polys_head; int alpha_index, beta_index; int sum_verts; int sum_table; Point **CS_verts_tail, **CS_verts_refer; Polygon **CS_polys_tail; Cube_polygons alpha_cube, beta_cube; int n_elem, tmp_int; Cell *cell; Tetra *tetra; int disamb_flag; Polygon *CS_polys, *CS_polys_tmp; Point *CS_verts, *CS_verts_tmp; int sum_polys, poly_num; int aplist_size, bplist_size, cplist_size; int num_nh_verts, num_nh_patch; /* vertex on patches generated in non-hexahedra */ int flag_hexa, flag_tetra; Hash_vertex *vertex_hash_table; Tetra_point *tetra_point; Head_patch_tetra *head_patch_tetra; Tetra_point *p1, *p2; Patch_tetra *t1, *t2; Hash_vertex *h1, *h2; int minus_patch; double tmp_data[9]; int tn_component, c_base; double tmp; sum_verts = 0; num_nh_verts = 0; num_nh_patch = 0; sum_polys = 0; n_elem = mesh->n_elem; tn_component = 0; for (i = 0; i < data->nn_component; i++) tn_component += data->nn_dof[i]; /* prism = (Prism *)HECMW_malloc(sizeof(Prism)); */ if (mesh->elem_type[0] > 300) { flag_hexa = 0; flag_tetra = 0; disamb_flag = 1; /* fprintf(stderr, "sff inf: color=%d color_sub=%d con=%lf %lf %lf% lf\n", sff->color_comp, sff->color_subcomp, sff->cont_equ[6], sff->cont_equ[7], sff->cont_equ[8],sff->cont_equ[9]); sprintf(test_file, "test_ucd.%d.%d.inp", time_step, mynode); write_mesh_display(test_file, mesh, data); HECMW_Barrier(VIS_COMM); */ /* for(i = 0; i < mesh->ne_internal; i++) { tmp_int=mesh->elem_internal_list[i]-1; */ for (i = 0; i < mesh->n_elem; i++) if (mesh->elem_ID[i * 2 + 1] == mynode) { tmp_int = i; if ((mesh->elem_type[tmp_int] == 361) || (mesh->elem_type[tmp_int] == 362) || (mesh->elem_type[tmp_int] == 351) || (mesh->elem_type[tmp_int] == 352)) { if (flag_hexa == 0) { flag_hexa = 1; CS_polys_head = (Polygon **)HECMW_malloc(sizeof(Polygon *)); CS_verts_head = (Point **)HECMW_calloc(TABLE_SIZE, sizeof(Point *)); sum_table = TABLE_SIZE; CS_verts_tail = (Point **)HECMW_calloc(sum_table, sizeof(Point *)); CS_verts_refer = (Point **)HECMW_calloc(sum_table, sizeof(Point *)); for (j = 0; j < sum_table; j++) { if ((CS_verts_refer[j] = CS_verts_tail[j] = CS_verts_head[j] = alloc_verts(VERTEX_PACK)) == NULL) HECMW_vis_memory_exit("verts for hexahedra"); } CS_polys_tail = (Polygon **)HECMW_malloc(sizeof(Polygon *)); if ((*CS_polys_tail = *CS_polys_head = alloc_polygons(POLYGON_PACK)) == NULL) HECMW_vis_memory_exit("CS_polys_tail"); alpha_cube.isosurf = (int **)HECMW_malloc(sizeof(int *)); beta_cube.isosurf = (int **)HECMW_malloc(sizeof(int *)); cell = (Cell *)HECMW_malloc(sizeof(Cell)); } get_data(sff, mesh, data, tmp_int, cell, tn_component); if (sff->surface_style == 2) { alpha_index = make_tile(mesh, cell, sff->iso_value, 0, &alpha_cube, disamb_flag); beta_index = make_tile(mesh, cell, sff->iso_value, 1, &beta_cube, disamb_flag); if (alpha_index && beta_index) { if ((alpha_index + beta_index) == HEX_NODE_INDEX) { if (!merge_vol_iso(0, cell, sff->iso_value, &alpha_cube, 0, &beta_cube, bdflag[i], &sum_verts, CS_verts_tail, CS_verts_refer, CS_verts_head, CS_polys_tail)) { return 0; } } } } else if (sff->surface_style == 3) { alpha_index = make_tile(mesh, cell, 0, 0, &alpha_cube, disamb_flag); beta_index = make_tile(mesh, cell, 0, 1, &beta_cube, disamb_flag); if (alpha_index && beta_index) { if ((alpha_index + beta_index) == HEX_NODE_INDEX) { if (!merge_vol_iso(0, cell, 0, &alpha_cube, 0, &beta_cube, bdflag[i], &sum_verts, CS_verts_tail, CS_verts_refer, CS_verts_head, CS_polys_tail)) { return 0; } } } } } else if ((mesh->elem_type[tmp_int] == 341) || (mesh->elem_type[tmp_int] == 342)) { /* tetrahedra */ if (flag_tetra == 0) { flag_tetra = 1; /* initialize */ tetra = (Tetra *)HECMW_malloc(sizeof(Tetra)); vertex_hash_table = (Hash_vertex *)HECMW_calloc( mesh->n_node * 2, sizeof(Hash_vertex)); tetra_point = (Tetra_point *)HECMW_malloc(sizeof(Tetra_point)); head_patch_tetra = (Head_patch_tetra *)HECMW_malloc(sizeof(Head_patch_tetra)); if ((vertex_hash_table == NULL) || (tetra == NULL) || (tetra_point == NULL) || (head_patch_tetra == NULL)) HECMW_vis_memory_exit("initialize tetra"); for (j = 0; j < mesh->n_node * 2; j++) { vertex_hash_table[j].ident = 0; vertex_hash_table[j].next_vertex = NULL; } tetra_point->ident = 0; head_patch_tetra->num_patch = 0; } get_tetra_data(sff, mesh, data, tmp_int, tetra, tn_component); if (sff->surface_style == 3) sff->iso_value = 0.0; find_intersection_tetra(tetra, sff->iso_value, tetra_point, head_patch_tetra, vertex_hash_table); } } if (flag_tetra == 1) { num_nh_verts = tetra_point->ident; num_nh_patch = head_patch_tetra->num_patch; HECMW_free(tetra); for (j = 0; j < mesh->n_node * 2; j++) { h1 = vertex_hash_table[j].next_vertex; for (i = 0; i < vertex_hash_table[j].ident; i++) { h2 = h1->next_vertex; HECMW_free(h1); h1 = h2; } } HECMW_free(vertex_hash_table); } if (flag_hexa > 0) { mfree(alpha_cube.isosurf); mfree(beta_cube.isosurf); mfree(CS_verts_tail); mfree(CS_verts_refer); mfree(CS_polys_tail); *sum_v = sum_verts; *sum_t = sum_table; HECMW_free(cell); CS_polys = *CS_polys_head; sum_polys = 0; aplist_size = bplist_size = cplist_size = 1; while (CS_polys->plist != NULL) { switch (CS_polys->type) { case 0: aplist_size += CS_polys->plist[0] + 1; sum_polys++; break; case 1: bplist_size += CS_polys->plist[0] + 1; sum_polys++; break; case 2: cplist_size += (CS_polys->plist[0] - 2) * 4; sum_polys += CS_polys->plist[0] - 2; break; } CS_polys = CS_polys->nextpolygon; } } /*sum_polys=sum_polys*2;*/ if ((sum_verts + num_nh_verts) > 0) { result[sf_i].n_vertex = sum_verts + num_nh_verts; result[sf_i].n_patch = sum_polys + num_nh_patch; result[sf_i].vertex = (double *)HECMW_calloc(result[sf_i].n_vertex * 3, sizeof(double)); result[sf_i].patch = (int *)HECMW_calloc(result[sf_i].n_patch * 3, sizeof(int)); result[sf_i].color = (double *)HECMW_calloc(result[sf_i].n_vertex, sizeof(double)); if ((result[sf_i].vertex == NULL) || (result[sf_i].patch == NULL) || (result[sf_i].color == NULL)) HECMW_vis_memory_exit("result"); } mm = 0; if (sum_verts > 0) { /* make main vertex table of CS */ for (i = 0; i < sum_table; i++) { CS_verts_tmp = CS_verts = CS_verts_head[i]; j = 0; while (CS_verts->ident != 0) { /* verts_geom[CS_verts->ident] = CS_verts->geom; verts_field[CS_verts->ident] = CS_verts->field; verts_color[CS_verts->ident] = CS_verts->cdata; fprintf(vfile, " %d %lf %lf %lf\n", *tvertex+CS_verts->ident, verts_geom[CS_verts->ident].x, verts_geom[CS_verts->ident].y, verts_geom[CS_verts->ident].z); */ result[sf_i].vertex[mm * 3] = CS_verts->geom.x; result[sf_i].vertex[mm * 3 + 1] = CS_verts->geom.y; result[sf_i].vertex[mm * 3 + 2] = CS_verts->geom.z; result[sf_i].color[mm] = CS_verts->cdata; mm++; CS_verts = CS_verts->nextpoint; if (!((++j) % VERTEX_PACK)) { mfree(CS_verts_tmp); CS_verts_tmp = CS_verts; } } mfree(CS_verts_tmp); } mfree(CS_verts_head); /* make polygon table and decide vertex ID of each object (alpha,beta,cross) */ /* trilist=(Triangle *)HECMW_calloc(sum_polys+1,sizeof(Triangle)); */ CS_polys_tmp = CS_polys = *CS_polys_head; i = 0; poly_num = 1; minus_patch = 0; while (CS_polys->plist != NULL) { switch (CS_polys->type) { case 0: /* fprintf(pfile, "%d ", poly_num+(*tpatch)); */ k = -1; for (j = 1; j <= CS_polys->plist[0]; j++) { k++; /* fprintf(pfile, "%d ", (*tvertex)+CS_polys->plist[j]); trilist[poly_num -1].vertex[k]=CS_polys->plist[j]; */ if ((sff->output_type == 1) || (sff->output_type == 2)) result[sf_i].patch[(poly_num - 1) * 3 + k] = *tvertex + CS_polys->plist[j]; else result[sf_i].patch[(poly_num - 1) * 3 + k] = CS_polys->plist[j]; tmp_data[k * 3] = result[sf_i].vertex[(CS_polys->plist[j] - 1) * 3]; tmp_data[k * 3 + 1] = result[sf_i].vertex[(CS_polys->plist[j] - 1) * 3 + 1]; tmp_data[k * 3 + 2] = result[sf_i].vertex[(CS_polys->plist[j] - 1) * 3 + 2]; } if (((fabs(tmp_data[0] - tmp_data[3]) < EPSILON) && (fabs(tmp_data[1] - tmp_data[4]) < EPSILON) && (fabs(tmp_data[2] - tmp_data[5]) < EPSILON)) || ((fabs(tmp_data[0] - tmp_data[6]) < EPSILON) && (fabs(tmp_data[1] - tmp_data[7]) < EPSILON) && (fabs(tmp_data[2] - tmp_data[8]) < EPSILON)) || ((fabs(tmp_data[6] - tmp_data[3]) < EPSILON) && (fabs(tmp_data[7] - tmp_data[4]) < EPSILON) && (fabs(tmp_data[8] - tmp_data[5]) < EPSILON))) minus_patch++; else poly_num++; break; } CS_polys = CS_polys->nextpolygon; if (!((++i) % POLYGON_PACK)) { mfree(CS_polys_tmp->plist); mfree(CS_polys_tmp); CS_polys_tmp = CS_polys; } } /*#ifdef DEBUG fprintf(stderr, "the previous patch num is %d now is %d\n", result[sf_i].n_patch, result[sf_i].n_patch-minus_patch); #endif */ result[sf_i].n_patch -= minus_patch; mfree(CS_polys_tmp); } if (num_nh_verts > 0) { p1 = tetra_point->nextpoint; for (i = 0; i < tetra_point->ident; i++) { for (j = 0; j < 3; j++) result[sf_i].vertex[(sum_verts + p1->ident) * 3 + j] = p1->geom[j]; result[sf_i].color[sum_verts + p1->ident] = p1->cdata; p2 = p1; p1 = p1->nextpoint; HECMW_free(p2); } HECMW_free(tetra_point); } if (num_nh_patch > 0) { t1 = head_patch_tetra->patch_link; for (i = 0; i < head_patch_tetra->num_patch; i++) { for (j = 0; j < 3; j++) { if (sff->output_type == 3) result[sf_i].patch[(sum_polys - minus_patch + i) * 3 + j] = t1->patch[j] + 1 + sum_verts; else result[sf_i].patch[(sum_polys - minus_patch + i) * 3 + j] = *tvertex + t1->patch[j] + 1 + sum_verts; } t2 = t1; t1 = t1->next_patch; HECMW_free(t2); } HECMW_free(head_patch_tetra); } /* fprintf(stderr, "On surface %d PE %d: n_vertex is %d n_patch is %d\n", sf_i, mynode, result[sf_i].n_vertex, result[sf_i].n_patch); */ if (result[sf_i].n_vertex > 0) { *minc = *maxc = result[sf_i].color[0]; for (i = 1; i <= result[sf_i].n_vertex; i++) { if (result[sf_i].color[i - 1] < (*minc)) (*minc) = result[sf_i].color[i - 1]; if (result[sf_i].color[i - 1] > (*maxc)) (*maxc) = result[sf_i].color[i - 1]; } /* #ifdef DEBUG fprintf(stderr,"On surface %d PE %d: minimum color=%lf maximum color=%lf\n", sf_i, mynode, *minc,*maxc); #endif */ } } /* endof if elem_type>300 */ else if ((mesh->elem_type[0] > 200) && (mesh->elem_type[0] < 300)) { result[sf_i].n_patch = 0; for (i = 0; i < n_elem; i++) { if (mesh->elem_type[i] == 231) result[sf_i].n_patch++; else if (mesh->elem_type[i] == 241) result[sf_i].n_patch += 2; } result[sf_i].n_vertex = mesh->n_node; result[sf_i].vertex = (double *)HECMW_calloc(mesh->n_node * 3, sizeof(double)); result[sf_i].color = (double *)HECMW_calloc(mesh->n_node, sizeof(double)); result[sf_i].patch = (int *)HECMW_calloc(result[sf_i].n_patch * 3, sizeof(int)); if ((result[sf_i].vertex == NULL) || (result[sf_i].color == NULL) || (result[sf_i].patch == NULL)) HECMW_vis_memory_exit("result: vertex, color and patch"); for (i = 0; i < mesh->n_node; i++) { for (j = 0; j < 3; j++) result[sf_i].vertex[i * 3 + j] = mesh->node[i * 3 + j]; } if (data->nn_dof[sff->color_comp] == 1) { c_base = 0; for (i = 0; i < sff->color_comp; i++) c_base += data->nn_dof[i]; } else if (data->nn_dof[sff->color_comp] > 1) { c_base = 0; for (i = 0; i < sff->color_comp; i++) c_base += data->nn_dof[i]; } if ((data->nn_dof[sff->color_comp] > 1) && (sff->color_subcomp == 0)) { for (i = 0; i < mesh->n_node; i++) { result[sf_i].color[i] = 0.0; for (j = 0; j < data->nn_dof[sff->color_comp]; j++) { tmp = data->node_val_item[c_base + i * tn_component + j]; result[sf_i].color[i] += tmp * tmp; } result[sf_i].color[i] = sqrt(result[sf_i].color[i]); } } else if (data->nn_dof[sff->color_comp] > 1) { for (i = 0; i < mesh->n_node; i++) { result[sf_i].color[i] = data->node_val_item[c_base + i * tn_component + (sff->color_subcomp - 1)]; } } else if (data->nn_dof[sff->color_comp] == 1) { for (i = 0; i < mesh->n_node; i++) { result[sf_i].color[i] = data->node_val_item[c_base + i * tn_component]; } } poly_num = 0; for (i = 0; i < n_elem; i++) { if (mesh->elem_type[i] == 231) { for (j = 0; j < 3; j++) result->patch[poly_num * 3 + j] = mesh->elem_node_item[mesh->elem_node_index[i] + j] + *tvertex; poly_num++; } else if (mesh->elem_type[i] == 241) { for (j = 0; j < 3; j++) result->patch[poly_num * 3 + j] = mesh->elem_node_item[mesh->elem_node_index[i] + j] + *tvertex; poly_num++; result->patch[poly_num * 3 + 0] = mesh->elem_node_item[mesh->elem_node_index[i] + 0] + *tvertex; result->patch[poly_num * 3 + 1] = mesh->elem_node_item[mesh->elem_node_index[i] + 2] + *tvertex; result->patch[poly_num * 3 + 2] = mesh->elem_node_item[mesh->elem_node_index[i] + 3] + *tvertex; poly_num++; } } /* fprintf(stderr, "n_vertex is %d n_patch is %d\n", result[sf_i].n_vertex, result[sf_i].n_patch); */ if (result[sf_i].n_vertex > 0) { *minc = *maxc = result[sf_i].color[0]; for (i = 1; i <= result[sf_i].n_vertex; i++) { if (result[sf_i].color[i - 1] < (*minc)) (*minc) = result[sf_i].color[i - 1]; if (result[sf_i].color[i - 1] > (*maxc)) (*maxc) = result[sf_i].color[i - 1]; } /* #ifdef DEBUG fprintf(stderr,"On surface %d PE %d: minimum color=%lf maximum color=%lf\n", sf_i, mynode, *minc,*maxc); #endif */ } } (*tvertex) += result[sf_i].n_vertex; (*tpatch) += result[sf_i].n_patch; /* if(sum_verts>0) { *minv=mincolor; *maxv=maxcolor; } mfree(verts_info); mfree(verts_geom); mfree(verts_field); mfree(verts_color); mfree(trilist); */ return (1); }
int peer_kill(struct peer *p) { if(!p) return 0; if(__sync_bool_compare_and_swap(&p->status,PEER_CONNECTED,PEER_DISCONNECTED)) { close(p->sd); fdev_del(&p->ioev); log_error(p->ns->log,"ns peer socket closed,peer ip:%s.", inet_ntoa(p->addr.sin_addr)); //push one msg to notify disconnect if(!p->ns->close_func) { struct msg_t *msg = (struct msg_t *)mmalloc(p->ns->allocator, sizeof(struct msg_t)); msg->buf = NULL; msg->len = 0; msg->peer_id = p->id; msg->type = MSG_DISCONNECT; queue_push(p->ns->recv_queue,msg); log_error(p->ns->log,"ns push notify msg for client:%s disconneced.", inet_ntoa(p->addr.sin_addr)); } else { log_error(p->ns->log,"ns call close_func for client:%s disconneced.", inet_ntoa(p->addr.sin_addr)); p->ns->close_func(p->ns,p->id); } } if(__sync_bool_compare_and_swap(&p->refcount,0,1)) { log_error(p->ns->log,"ns peer freed,peer ip:%s.", inet_ntoa(p->addr.sin_addr)); iobuf_free(p->allocator,&p->recvbuf); iobuf_free(p->allocator,&p->sendbuf); //free send queue struct msg_t *msg = NULL,*next = NULL; thread_mutex_lock(p->sq_mutex); msg = BTPDQ_FIRST(&p->send_queue); while(msg){ next = BTPDQ_NEXT(msg,msg_entry); BTPDQ_REMOVE(&p->send_queue,msg,msg_entry); mfree(p->allocator,msg->buf); mfree(p->allocator,msg); msg = next; } thread_mutex_unlock(p->sq_mutex); thread_mutex_destroy(p->mpool_mutex); thread_mutex_destroy(p->sq_mutex); allocator_destroy(p->allocator); mfree(p->ns->allocator,p); thread_mutex_lock(p->ns->ptbl_mutex); ptbl_remove(p->ns->ptbl,&p->id); p->ns->npeers--; thread_mutex_unlock(p->ns->ptbl_mutex); } return 0; }
void handleRequest ( UdpSlot *slot , int32_t netnice ) { char *p = slot->m_readBuf; int32_t numBytes = *(int32_t*)p; p += sizeof(int32_t); char *filename = g_hostdb.m_logFilename; // running just ./gb will log to stderr... if ( strcmp(filename ,"/dev/stderr") == 0 ) { g_errno = EBADFILE; log(LOG_ERROR,"%s:%s:%d: call sendErrorReply.", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot, g_errno ); return; } int32_t fd = open ( filename , O_RDONLY , getFileCreationFlags() ); // S_IRUSR |S_IWUSR |S_IRGRP |S_IWGRP| S_IROTH ); if ( ! fd ) { log(LOG_DEBUG, "logviewer: Failed to open %s for reading: ", filename); g_errno = EBADFILE; log(LOG_ERROR,"%s:%s:%d: call sendErrorReply.", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot, g_errno ); return; } char stackSpace[LOG_WINDOW]; char *buf = stackSpace; char *allocBuf = NULL; int32_t allocBufSize = 0; if(numBytes > LOG_WINDOW) { buf = (char*)mmalloc(numBytes, "Msg1fA"); if(!buf) { log(LOG_INFO, "admin: malloc of %" PRId32" bytes failed " "for logview," " falling back on stack buffer.", numBytes); buf = stackSpace; numBytes = LOG_WINDOW; } else { allocBuf = buf; allocBufSize = numBytes; } } lseek(fd, -1 * numBytes, SEEK_END); if(errno == EINVAL) { //oops! we seeked to before the begining of the file //log(LOG_WARN, "bad seek!"); lseek(fd, 0, SEEK_SET); } int32_t numRead = read(fd, buf, numBytes-1); close(fd); if(numRead > 0) buf[numRead-1] = '\0'; else { buf[0] = '\0'; numRead = 0; if(allocBuf) mfree(allocBuf, allocBufSize, "Msg1fA"); allocBufSize = 0; allocBuf = NULL; log(LOG_ERROR,"%s:%s:%d: call sendErrorReply.", __FILE__, __func__, __LINE__); g_udpServer.sendErrorReply ( slot, EBADFILE ); return; } //log(LOG_DEBUG, "bytes read! %" PRId32" ", numRead); g_udpServer.sendReply_ass (buf, numRead, allocBuf,allocBufSize, slot); //send }
/* Parse a single logical line */ static int parse_line( const char* unit, const char *filename, unsigned line, const char *sections, ConfigItemLookup lookup, const void *table, ConfigParseFlags flags, char **section, unsigned *section_line, bool *section_ignored, char *l, void *userdata) { char *e, *include; assert(filename); assert(line > 0); assert(lookup); assert(l); l = strstrip(l); if (!*l) return 0; if (strchr(COMMENTS "\n", *l)) return 0; include = first_word(l, ".include"); if (include) { _cleanup_free_ char *fn = NULL; /* .includes are a bad idea, we only support them here * for historical reasons. They create cyclic include * problems and make it difficult to detect * configuration file changes with an easy * stat(). Better approaches, such as .d/ drop-in * snippets exist. * * Support for them should be eventually removed. */ if (!(flags & CONFIG_PARSE_ALLOW_INCLUDE)) { log_syntax(unit, LOG_ERR, filename, line, 0, ".include not allowed here. Ignoring."); return 0; } log_syntax(unit, LOG_WARNING, filename, line, 0, ".include directives are deprecated, and support for them will be removed in a future version of systemd. " "Please use drop-in files instead."); fn = file_in_same_dir(filename, strstrip(include)); if (!fn) return -ENOMEM; return config_parse(unit, fn, NULL, sections, lookup, table, flags, userdata); } if (!utf8_is_valid(l)) return log_syntax_invalid_utf8(unit, LOG_WARNING, filename, line, l); if (*l == '[') { size_t k; char *n; k = strlen(l); assert(k > 0); if (l[k-1] != ']') { log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid section header '%s'", l); return -EBADMSG; } n = strndup(l+1, k-2); if (!n) return -ENOMEM; if (sections && !nulstr_contains(sections, n)) { if (!(flags & CONFIG_PARSE_RELAXED) && !startswith(n, "X-")) log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown section '%s'. Ignoring.", n); free(n); *section = mfree(*section); *section_line = 0; *section_ignored = true; } else { free_and_replace(*section, n); *section_line = line; *section_ignored = false; } return 0; } if (sections && !*section) { if (!(flags & CONFIG_PARSE_RELAXED) && !*section_ignored) log_syntax(unit, LOG_WARNING, filename, line, 0, "Assignment outside of section. Ignoring."); return 0; } e = strchr(l, '='); if (!e) { log_syntax(unit, LOG_WARNING, filename, line, 0, "Missing '='."); return -EINVAL; } *e = 0; e++; return next_assignment(unit, filename, line, lookup, table, *section, *section_line, strstrip(l), strstrip(e), flags, userdata); }
static void context_free_x11(Context *c) { c->x11_layout = mfree(c->x11_layout); c->x11_options = mfree(c->x11_options); c->x11_model = mfree(c->x11_model); c->x11_variant = mfree(c->x11_variant); }
static void ntp_status_info_clear(NTPStatusInfo *p) { p->server_address = mfree(p->server_address); }
static void context_free_vconsole(Context *c) { c->vc_keymap = mfree(c->vc_keymap); c->vc_keymap_toggle = mfree(c->vc_keymap_toggle); }
void MemPool::reset ( ) { if ( m_mem ) mfree ( m_mem , m_memSize , "MemPool" ); m_mem = NULL; m_memSize = 0; }
static void context_free_locale(Context *c) { int p; for (p = 0; p < _VARIABLE_LC_MAX; p++) c->locale[p] = mfree(c->locale[p]); }
static void read_stream_control (MelodyLine *ml) { MelodyEvent *me = mmalloc (sizeof(MelodyEvent)); StreamControl *sc = &me->u.s; /* for ease of access */ int c; char *p, *str = NULL; me->type = EV_STREAM; me->line = line_no; me->col = col_no; sc->text = NULL; switch (c = nd_gc()) { case 'Z': gc(); sc->type = SC_ZERONOTE; break; case '[': gc(); sc->type = SC_BEAMSTART; break; case ']': gc(); sc->type = SC_BEAMSTOP; if (nd_gc() == '-') { gc(); if (nd_gc() != '[') { error (me->line, me->col, "syntax error in melody line:" " expected `[' after `]-'"); return; } sc->type = SC_BEAMBREAK; gc(); } break; case '/': gc(); sc->type = SC_SLURSTART; break; case '\\': gc(); sc->type = SC_SLURSTOP; break; case '(': gc(); sc->type = SC_NTUPLET; sc->ntuplet_denom = 0; while ( (c=gc()) >= '0' && c <= '9') sc->ntuplet_denom = (10*sc->ntuplet_denom) + c-'0'; if (c != '/') { error (me->line, me->col, "expected `/' after numerator of n-tuplet"); return; } sc->ntuplet_num = 0; while ( (c=gc()) >= '0' && c <= '9') sc->ntuplet_num = (10*sc->ntuplet_num) + c-'0'; if (c != ':') { error (me->line, me->col, "expected `:' after denominator of n-tuplet"); return; } wrk.factor = lcm (wrk.factor, sc->ntuplet_denom); break; case ')': gc(); sc->type = SC_NTUPLET_END; break; case '<': gc(); /* Could be <p>, <d>, <8va>, <8vb>, <,>, </>, <~> */ switch (c = gc()) { case 'P': sc->type = SC_FORCE_DOWN; break; case 'D': sc->type = SC_FORCE_UP; break; case '8': if (gc() != 'V') { error (me->line, me->col, "syntax error in melody line:" " expected `v' after `<8'"); return; } c = gc(); if (c == 'A') sc->type = SC_8VA; else if (c == 'B') sc->type = SC_8VB; else { error (me->line, me->col, "syntax error in melody line:" " expected `a' or `b' after `<8v'"); return; } break; case ',': sc->type = SC_BREATH; break; case '/': sc->type = SC_GENPAUSE; break; case 'U': if (nd_gc() == '!') { sc->type = SC_INVTURN; gc(); } else sc->type = SC_TURN; break; default: error (me->line, me->col, "syntax error in melody line:" " expected `p', `d', `8', `,', `/' or `u' after `<'"); return; } if (gc() != '>') { error (me->line, me->col, "syntax error in melody line:" " expected `>' to end `<...>' control"); return; } break; case '"': /* It's some kind of quoted string; get it into memory first. */ getword (&str); /* Check if the string is actually empty. */ if (!str[0] || !str[1] || str[1] == '"') { error (me->line, me->col, "quoted string is empty"); return; } /* Check the second character, because it's general. */ if (str[1] != '<' && str[1] != '>' && str[2] != ' ') { error (me->line, me->col, "expected space in quoted string after `%c'", str[1]); return; } /* Remove the trailing quote. */ str[strlen(str)-1] = '\0'; /* Could be dynamics, lyrics, above or below text, cresc or dim. */ switch (str[1]) { case '<': case '>': /* cresc or dim */ if (str[2]) { error (me->line, me->col, "unexpected text after `%c' in quoted string", str[0]); return; } sc->type = (str[1] == '<' ? SC_CRESC : SC_DIM); break; case 'D': case 'd': /* dynamics */ p = str+3; while (*p && !isspace(*p)) { static const char *const dynamic_str = "fmpsz"; char *q = strchr(dynamic_str, *p); if (!q) { error (me->line, me->col, "character `%c' not a valid dynamic", *p); return; } *p++ = q - dynamic_str + '\xD1'; } sc->type = SC_DYNAMIC; sc->text = dupstr (str+3); break; case 'L': case 'l': case 'A': case 'a': case 'B': case 'b': sc->text = dupstr (str+3); sc->type = (str[1]=='L' || str[1]=='l' ? SC_LYRICS : str[1]=='A' || str[1]=='a' ? SC_TEXT_ABOVE : str[1]=='B' || str[1]=='b' ? SC_TEXT_BELOW : -1); break; } break; default: /* should never happen */ gc(); fatal(me->line, me->col, "internal fault: reached `default'" " clause in `read_stream_control': char %d", c); break; /* *certainly* shouldn't reach this! */ } add_event (ml, me); mfree (str); }
/* Go through the file and parse each line */ int config_parse(const char *unit, const char *filename, FILE *f, const char *sections, ConfigItemLookup lookup, const void *table, bool relaxed, bool allow_include, bool warn, void *userdata) { _cleanup_free_ char *section = NULL, *continuation = NULL; _cleanup_fclose_ FILE *ours = NULL; unsigned line = 0, section_line = 0; bool section_ignored = false, allow_bom = true; int r; assert(filename); assert(lookup); if (!f) { f = ours = fopen(filename, "re"); if (!f) { /* Only log on request, except for ENOENT, * since we return 0 to the caller. */ if (warn || errno == ENOENT) log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR, "Failed to open configuration file '%s': %m", filename); return errno == ENOENT ? 0 : -errno; } } fd_warn_permissions(filename, fileno(f)); for (;;) { char buf[LINE_MAX], *l, *p, *c = NULL, *e; bool escaped = false; if (!fgets(buf, sizeof buf, f)) { if (feof(f)) break; return log_error_errno(errno, "Failed to read configuration file '%s': %m", filename); } l = buf; if (allow_bom && startswith(l, UTF8_BYTE_ORDER_MARK)) l += strlen(UTF8_BYTE_ORDER_MARK); allow_bom = false; truncate_nl(l); if (continuation) { c = strappend(continuation, l); if (!c) { if (warn) log_oom(); return -ENOMEM; } continuation = mfree(continuation); p = c; } else p = l; for (e = p; *e; e++) { if (escaped) escaped = false; else if (*e == '\\') escaped = true; } if (escaped) { *(e-1) = ' '; if (c) continuation = c; else { continuation = strdup(l); if (!continuation) { if (warn) log_oom(); return -ENOMEM; } } continue; } r = parse_line(unit, filename, ++line, sections, lookup, table, relaxed, allow_include, §ion, §ion_line, §ion_ignored, p, userdata); free(c); if (r < 0) { if (warn) log_warning_errno(r, "Failed to parse file '%s': %m", filename); return r; } } return 0; }
static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) { Context *c = userdata; const char *name; int interactive; int r; assert(m); assert(c); r = sd_bus_message_read(m, "sb", &name, &interactive); if (r < 0) return r; if (isempty(name)) name = NULL; if (streq_ptr(name, c->data[PROP_STATIC_HOSTNAME])) return sd_bus_reply_method_return(m, NULL); r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.set-static-hostname", NULL, interactive, UID_INVALID, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ if (isempty(name)) { c->data[PROP_STATIC_HOSTNAME] = mfree(c->data[PROP_STATIC_HOSTNAME]); } else { char *h; if (!hostname_is_valid(name, false)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid static hostname '%s'", name); h = strdup(name); if (!h) return -ENOMEM; free(c->data[PROP_STATIC_HOSTNAME]); c->data[PROP_STATIC_HOSTNAME] = h; } r = context_update_kernel_hostname(c); if (r < 0) { log_error_errno(r, "Failed to set host name: %m"); return sd_bus_error_set_errnof(error, r, "Failed to set hostname: %s", strerror(-r)); } r = context_write_data_static_hostname(c); if (r < 0) { log_error_errno(r, "Failed to write static host name: %m"); return sd_bus_error_set_errnof(error, r, "Failed to set static hostname: %s", strerror(-r)); } log_info("Changed static host name to '%s'", strna(c->data[PROP_STATIC_HOSTNAME])); (void) sd_bus_emit_properties_changed(sd_bus_message_get_bus(m), "/org/freedesktop/hostname1", "org.freedesktop.hostname1", "StaticHostname", NULL); return sd_bus_reply_method_return(m, NULL); }
/* free_sres frees parameters required by libSRES and calls libSRES's deinitialization function parameters: sp: parameters required by libSRES returns: nothing notes: todo: */ void free_sres (sres_params& sp) { mfree(sp.trsfm); mfree(sp.lb); mfree(sp.ub); ESDeInitial(sp.param, sp.population, sp.stats); }
void Pos::reset() { if ( m_buf && m_needsFree ) mfree ( m_buf , m_bufSize , "Pos" ); m_buf = NULL; }
// print out the mem table // but combine allocs with the same label // sort by mem allocated bool Mem::printMemBreakdownTable ( SafeBuf* sb, char *lightblue, char *darkblue) { char *ss = ""; sb->safePrintf ( "<table>" "<table %s>" "<tr>" "<td colspan=3 bgcolor=#%s>" "<center><b>Mem Breakdown%s</b></td></tr>\n" "<tr bgcolor=#%s>" "<td><b>allocator</b></td>" "<td><b>num allocs</b></td>" "<td><b>allocated</b></td>" "</tr>" , TABLE_STYLE, darkblue , ss , darkblue ); int32_t n = m_numAllocated * 2; MemEntry *e = (MemEntry *)mcalloc ( sizeof(MemEntry) * n , "Mem" ); if ( ! e ) { log("admin: Could not alloc %" PRId32" bytes for mem table.", (int32_t)sizeof(MemEntry)*n); return false; } // hash em up, combine allocs of like label together for this hash for ( int32_t i = 0 ; i < (int32_t)m_memtablesize ; i++ ) { // skip empty buckets if ( ! s_mptrs[i] ) continue; // get label ptr, use as a hash char *label = &s_labels[i*16]; int32_t h = hash32n ( label ); if ( h == 0 ) h = 1; // accumulate the size int32_t b = (uint32_t)h % n; // . chain till we find it or hit empty // . use the label as an indicator if bucket is full or empty while ( e[b].m_hash && e[b].m_hash != h ) if ( ++b >= n ) b = 0; // add it in e[b].m_hash = h; e[b].m_label = label; e[b].m_allocated += s_sizes[i]; e[b].m_numAllocs++; } // get the top 20 users of mem MemEntry *winners [ PRINT_TOP ]; int32_t i = 0; int32_t count = 0; for ( ; i < n && count < PRINT_TOP ; i++ ) // if non-empty, add to winners array if ( e[i].m_hash ) winners [ count++ ] = &e[i]; // compute new min int32_t min = 0x7fffffff; int32_t mini = -1000; for ( int32_t j = 0 ; j < count ; j++ ) { if ( winners[j]->m_allocated > min ) continue; min = winners[j]->m_allocated; mini = j; } // now the rest must compete for ( ; i < n ; i++ ) { // if empty skip if ( ! e[i].m_hash ) continue; //if ( e[i].m_allocated > 120 && e[i].m_allocated < 2760 ) // log("hey %" PRId32, e[i].m_allocated); // skip if not a winner if ( e[i].m_allocated <= min ) continue; // replace the lowest winner winners[mini] = &e[i]; // compute new min min = 0x7fffffff; for ( int32_t j = 0 ; j < count ; j++ ) { if ( winners[j]->m_allocated > min ) continue; min = winners[j]->m_allocated; mini = j; } } // now sort them bool flag = true; while ( flag ) { flag = false; for ( int32_t i = 1 ; i < count ; i++ ) { // no need to swap? if ( winners[i-1]->m_allocated >= winners[i]->m_allocated ) continue; // swap flag = true; MemEntry *tmp = winners[i-1]; winners[i-1] = winners[i]; winners[i ] = tmp; } } // now print into buffer for ( int32_t i = 0 ; i < count ; i++ ) sb->safePrintf ( "<tr bgcolor=%s>" "<td>%s</td>" "<td>%" PRId32"</td>" "<td>%" PRId32"</td>" "</tr>\n", LIGHT_BLUE, winners[i]->m_label, winners[i]->m_numAllocs, winners[i]->m_allocated); sb->safePrintf ( "</table>\n"); // don't forget to release this mem mfree ( e , (int32_t)sizeof(MemEntry) * n , "Mem" ); return true; }