int is_included(Path& p,vector<Path>& P){ // Check if any of P[i] or (P[i] XOR P[j]) is included in p int res = 0; for(int i=0;i<P.size();i++){ if(is_included(P[i],p)) { res = 1; } for(int j=0;j<P.size();j++){ Path tmp; path_xor(P[i],P[j],tmp); if(tmp.size()>0){ if(is_included(tmp,p)) { res = 1; } } } } return res; }
static void mark_reenc_glyphs(fo_entry * fo, internalfontnumber f) { int i; char **g; void **aa; assert(fo->fe != NULL); if (is_subsetted(fo->fm)) { assert(is_included(fo->fm)); /* mark glyphs from TeX (externally reencoded characters) */ g = fo->fe->glyph_names; for (i = fo->first_char; i <= fo->last_char; i++) { if (pdfcharmarked(f, i) && g[i] != notdef && (char *) avl_find(fo->fd->gl_tree, g[i]) == NULL) { aa = avl_probe(fo->fd->gl_tree, xstrdup(g[i])); assert(aa != NULL); } } } }
/* This function is a fresh new implementation for a bundle * remove without being tied to verify loop, this means * improved speed and space as well as more roubustness and * flexibility. What it does is basically: * * 1) Read MoM and load all submanifests except the one to be * removed and then consolidate them. * 2) Load the removed bundle submanifest. * 3) Order the file list by filename * 4) Deduplicate removed submanifest file list that happens * to be on the MoM (minus bundle to be removed). * 5) iterate over to be removed bundle submanifest file list * performing a unlink(2) for each filename. * 6) Done. */ int remove_bundle(const char *bundle_name) { int lock_fd; int ret = 0; int current_version = CURRENT_OS_VERSION; struct manifest *current_mom, *bundle_manifest = NULL; ret = swupd_init(&lock_fd); if (ret != 0) { printf("Failed updater initialization, exiting now.\n"); return ret; } /* os-core bundle not allowed to be removed... * although this is going to be caught later because of all files * being marked as 'duplicated' and note removing anything * anyways, better catch here and return success, no extra work to be done. */ if (strcmp(bundle_name, "os-core") == 0) { ret = EBUNDLE_NOT_TRACKED; goto out_free_curl; } if (!is_tracked_bundle(bundle_name)) { ret = EBUNDLE_NOT_TRACKED; goto out_free_curl; } current_version = get_current_version(path_prefix); if (current_version < 0) { printf("Error: Unable to determine current OS version\n"); ret = ECURRENT_VERSION; goto out_free_curl; } swupd_curl_set_current_version(current_version); current_mom = load_mom(current_version); if (!current_mom) { printf("Unable to download/verify %d Manifest.MoM\n", current_version); ret = EMOM_NOTFOUND; goto out_free_curl; } if (!search_bundle_in_manifest(current_mom, bundle_name)) { printf("Bundle name is invalid, aborting removal\n"); ret = EBUNDLE_REMOVE; goto out_free_mom; } /* load all tracked bundles into memory */ read_subscriptions_alt(); /* now popout the one to be removed */ ret = unload_tracked_bundle(bundle_name); if (ret != 0) { goto out_free_mom; } subscription_versions_from_MoM(current_mom, 0); /* load all submanifest minus the one to be removed */ current_mom->submanifests = recurse_manifest(current_mom, NULL); if (!current_mom->submanifests) { printf("Error: Cannot load MoM sub-manifests\n"); ret = ERECURSE_MANIFEST; goto out_free_mom; } if (is_included(bundle_name, current_mom)) { printf("Error: bundle requested to be removed is required by other installed bundles\n"); ret = EBUNDLE_REMOVE; goto out_free_mom; } current_mom->files = files_from_bundles(current_mom->submanifests); current_mom->files = consolidate_files(current_mom->files); /* Now that we have the consolidated list of all files, load bundle to be removed submanifest*/ ret = load_bundle_manifest(bundle_name, current_version, &bundle_manifest); if (ret != 0 || !bundle_manifest) { printf("Error: Cannot load %s sub-manifest (ret = %d)\n", bundle_name, ret); goto out_free_mom; } /* deduplication needs file list sorted by filename, do so */ bundle_manifest->files = list_sort(bundle_manifest->files, file_sort_filename); deduplicate_files_from_manifest(&bundle_manifest, current_mom); printf("Deleting bundle files...\n"); remove_files_in_manifest_from_fs(bundle_manifest); printf("Untracking bundle from system...\n"); rm_bundle_file(bundle_name); printf("Success: Bundle removed\n"); free_manifest(bundle_manifest); out_free_mom: free_manifest(current_mom); out_free_curl: if (ret) { printf("Error: Bundle remove failed\n"); } swupd_deinit(lock_fd); return ret; }
int check_fm_entry(fm_entry * fm, boolean warn) { int a = 0; assert(fm != NULL); if (is_fontfile(fm) && !is_included(fm)) { if (warn) pdftex_warn ("ambiguous entry for `%s': font file present but not included, " "will be treated as font file not present", fm->tfm_name); xfree(fm->ff_name); /* do not set variable |a| as this entry will be still accepted */ } /* if both ps_name and font file are missing, drop this entry */ if (fm->ps_name == NULL && !is_fontfile(fm)) { if (warn) pdftex_warn ("invalid entry for `%s': both ps_name and font file missing", fm->tfm_name); a += 1; } /* TrueType fonts cannot be reencoded without subsetting */ if (is_truetype(fm) && is_reencoded(fm) && !is_subsetted(fm)) { if (warn) pdftex_warn ("invalid entry for `%s': only subsetted TrueType font can be reencoded", fm->tfm_name); a += 2; } /* SlantFont and ExtendFont can be used only with Type1 fonts */ if ((fm->slant != 0 || fm->extend != 0) && !(is_t1fontfile(fm) && is_included(fm))) { if (warn) pdftex_warn ("invalid entry for `%s': SlantFont/ExtendFont can be used only with embedded Type1 fonts", fm->tfm_name); a += 4; } /* the value of SlantFont and ExtendFont must be reasonable */ if (abs(fm->slant) > 1000) { if (warn) pdftex_warn ("invalid entry for `%s': too big value of SlantFont (%g)", fm->tfm_name, fm->slant / 1000.0); a += 8; } if (abs(fm->extend) > 2000) { if (warn) pdftex_warn ("invalid entry for `%s': too big value of ExtendFont (%g)", fm->tfm_name, fm->extend / 1000.0); a += 16; } /* subfonts must be used with subsetted non-reencoded TrueType fonts */ if (fm->pid != -1 && !(is_truetype(fm) && is_subsetted(fm) && !is_reencoded(fm))) { if (warn) pdftex_warn ("invalid entry for `%s': PidEid can be used only with subsetted non-reencoded TrueType fonts", fm->tfm_name); a += 32; } return a; }
int avl_do_entry(fm_entry * fm, int mode) { fm_entry *p; void *a; void **aa; /* handle tfm_name link */ if (strcmp(fm->tfm_name, nontfm)) { p = (fm_entry *) avl_find(tfm_tree, fm); if (p != NULL) { switch (mode) { case FM_DUPIGNORE: pdftex_warn ("fontmap entry for `%s' already exists, duplicates ignored", fm->tfm_name); goto exit; break; case FM_REPLACE: case FM_DELETE: if (p->in_use) { pdftex_warn ("fontmap entry for `%s' has been used, replace/delete not allowed", fm->tfm_name); goto exit; } a = avl_delete(tfm_tree, p); assert(a != NULL); unset_tfmlink(p); if (!has_pslink(p)) delete_fm_entry(p); break; default: assert(0); } } if (mode != FM_DELETE) { aa = avl_probe(tfm_tree, fm); assert(aa != NULL); set_tfmlink(fm); } } /* handle ps_name link */ if (fm->ps_name != NULL) { p = (fm_entry *) avl_find(ps_tree, fm); if (p != NULL) { switch (mode) { case FM_DUPIGNORE: goto exit; break; case FM_REPLACE: case FM_DELETE: if (p->in_use) goto exit; a = avl_delete(ps_tree, p); assert(a != NULL); unset_pslink(p); if (!has_tfmlink(p)) delete_fm_entry(p); break; default: assert(0); } } if (mode != FM_DELETE && is_t1fontfile(fm) && is_included(fm)) { aa = avl_probe(ps_tree, fm); assert(aa != NULL); set_pslink(fm); } } exit: if (!has_tfmlink(fm) && !has_pslink(fm)) /* e. g. after FM_DELETE */ return 1; /* deallocation of fm_entry structure required */ else return 0; }
array_comp_list_t * union_array_comp_list(array_comp_list_t *acl1, array_comp_list_t *acl2, unsigned short int n){ int s1 = acl1->size; if(!s1){ return copy_array_comp_list(acl2); } int s2 = acl2->size; if(!s2){ return copy_array_comp_list(acl1); } unsigned short int * dis_map1 = (unsigned short int *)calloc(s1,sizeof(unsigned short int)); unsigned short int * dis_map2 = (unsigned short int *)calloc(s2,sizeof(unsigned short int)); int tnc = s1+s2; char *overlap_map = (char *)calloc(tnc*tnc,sizeof(char)); comp_list_t * cl1 = acl1->head; for(int i = 0; i < s1; i++){ comp_list_t *cl2 = acl2->head; for(int j = 0; j < s2; j++){ if(is_included(cl1,cl2,n)){ dis_map2[j]++; //continue; } else if(is_included(cl2,cl1,n)){ dis_map1[i]++; //continue; } else if(is_disjoint(cl1,cl2,n)){ dis_map1[i]++; dis_map2[j]++; //continue; } else{ overlap_map[tnc*i + (s1+j)] = 1; overlap_map[tnc*(s1+j) + i] = 1; } cl2 = cl2->next; } cl1 = cl1->next; } array_comp_list_t *res = create_array_comp_list(); cl1 = acl1->head; for(int i = 0; i < s1; i++){ if(dis_map1[i]==s2){ //comp_list_t *dst = create_comp_list(); comp_list_t *dst = copy_comp_list(cl1); insert_comp_list(res,dst); } cl1 = cl1->next; } comp_list_t *cl2 = acl2->head; for(int i = 0; i < s2; i++){ if(dis_map2[i]==s1){ //comp_list_t *dst = create_comp_list(); comp_list_t *dst = copy_comp_list(cl2); insert_comp_list(res,dst); } cl2 = cl2->next; } array_comp_list_t * acl = extract_comps(overlap_map,tnc); comp_list_t *cl = acl->head; for(int i = 0; i < acl->size; i++){ comp_t *c = cl->head; int s = cl->size; unsigned short int * om1 = (unsigned short int *)calloc(s1,sizeof(unsigned short int)); unsigned short int * om2 = (unsigned short int *)calloc(s2,sizeof(unsigned short int)); for(int j = 0; j < s; j++){ unsigned short int num = c->num; if(num>=s1){ om2[num-s1] = 1; } else{ om1[num] = 1; } c = c->next; } comp_list_t * res1 = comp_array_union_direct(acl1,acl2,om1,om2,n); //comp_list_t *dst = create_comp_list(); //comp_list_t * dst = copy_comp_list(res1); free(om1); free(om2); insert_comp_list(res,res1); cl = cl->next; } free(overlap_map); free(dis_map1); free(dis_map2); free_array_comp_list(acl); return res; }
int mtrropt(u64t wc_addr, u64t wc_len, u32t *memlimit) { u32t reg; int ii, sv4idx = 0; mtrrentry save4[16]; memset(&save4,0,sizeof(save4)); *memlimit = 0; if (is_included(wc_addr,wc_len)<0 && is_intersection(wc_addr, wc_len)<0 && is_regavail(®)) { mtrr[reg].start = wc_addr; mtrr[reg].len = wc_len; mtrr[reg].cache = MTRRF_WC; mtrr[reg].on = 1; return 0; } // video memory in not in 4th GB if (wc_addr<_3GbLL || wc_addr+wc_len>_4GbLL) return OPTERR_VIDMEM3GB; /* turn off previous write combine on the same memory, but leave this block to catch low UC border successfully */ ii = is_include(wc_addr, wc_len); if (ii>=0 && mtrr[ii].cache==MTRRF_WC) mtrr[ii].cache=MTRRF_UC; // only WB and UC allowed in first 4Gb for (ii=0; ii<regs; ii++) if (mtrr[ii].on && mtrr[ii].cache!=MTRRF_UC && mtrr[ii].cache!=MTRRF_WB && mtrr[ii].start<_4GbLL) return OPTERR_UNKCT; // is block intersected with someone? ii = is_intersection(wc_addr, wc_len); if (ii>=0) return OPTERR_INTERSECT; // remove/truncate all above 4Gb (but save it) for (ii=0; ii<regs; ii++) if (mtrr[ii].on) if (mtrr[ii].start<_4GbLL && mtrr[ii].start+mtrr[ii].len>_4GbLL) { u64t newlen = _4GbLL - mtrr[ii].start, remain = mtrr[ii].len - newlen; if (!is_power2(newlen)) return OPTERR_SPLIT4GB; mtrr[ii].len = newlen; // save block if (is_power2(remain)) { save4[sv4idx].start = _4GbLL; save4[sv4idx].len = remain; save4[sv4idx].cache = mtrr[ii].cache; sv4idx++; } else if (is_power2(remain/3)) { } } else if (mtrr[ii].start>=_4GbLL || mtrr[ii].start+mtrr[ii].len>_4GbLL) { save4[sv4idx].start = mtrr[ii].start; save4[sv4idx].len = mtrr[ii].len; save4[sv4idx].cache = mtrr[ii].cache; sv4idx++; clearreg(ii); } u64t wbend = 0, ucstart = FFFF64; // searching for upper WB border for (ii=0; ii<regs; ii++) if (mtrr[ii].on) if (mtrr[ii].cache==MTRRF_WB) if (mtrr[ii].start+mtrr[ii].len > wbend) wbend = mtrr[ii].start+mtrr[ii].len; // searching for lower UC border (but ignore small blocks) for (ii=0; ii<regs; ii++) if (mtrr[ii].on) if (mtrr[ii].cache==MTRRF_UC) { int pwr = bsf64(mtrr[ii].len); if (pwr>=27) { if (ucstart>mtrr[ii].start) ucstart = mtrr[ii].start; clearreg(ii); } } // pass #2 - removing small blocks above selected border for (ii=0; ii<regs; ii++) if (mtrr[ii].on) if (mtrr[ii].cache==MTRRF_UC && ucstart<=mtrr[ii].start) clearreg(ii); // if no UC entries - use the end of WB as border if (ucstart>wbend) ucstart = wbend; // this can occur on small video memory size (<128Mb) if (wc_addr<ucstart) return OPTERR_BELOWUC; // build new WB list if (ucstart<wbend) { if (ucstart<_1GbLL) return OPTERR_LOWUC; for (ii=0; ii<regs; ii++) if (mtrr[ii].on) if (mtrr[ii].cache==MTRRF_WB) clearreg(ii); int regsfree = regsavail() - sv4idx - 1; log_it(2, "regs free: %i \n", regsfree); // force 3 registers (some memory above 4Gb can be lost) if (regsfree<3) regsfree = 3; // split memory to list u64t nextpos = 0; ii = 0; for (u64t size=_2GbLL; size>=_64MbLL; size>>=1) { if (ucstart>=size) { if (!is_regavail(®)) return OPTERR_NOREG; mtrr[reg].start = nextpos; nextpos += (mtrr[reg].len = size); mtrr[reg].cache = MTRRF_WB; mtrr[reg].on = 1; ucstart -= size; // use only 3 mtrr regs if (++ii==regsfree) break; } } // save memlimit value *memlimit = nextpos>>20; /** and again removing small blocks above selected border... splitted blocks sum can be smaller than previously selected UC border and some blocks can be cleared here */ for (ii=0; ii<regs; ii++) if (mtrr[ii].on) if (mtrr[ii].cache==MTRRF_UC && nextpos<=mtrr[ii].start) clearreg(ii); } // final check if (is_included(wc_addr,wc_len)>=0 || is_intersection(wc_addr,wc_len)>=0 || is_include(wc_addr,wc_len)>=0) return OPTERR_OPTERR; // add entry if (is_regavail(®)) { mtrr[reg].start = wc_addr; mtrr[reg].len = wc_len; mtrr[reg].cache = MTRRF_WC; mtrr[reg].on = 1; } // restore some of above 4Gb memory blocks if (sv4idx && regsavail()>0) { for (ii=0; ii<sv4idx; ii++) { if (!is_regavail(®)) break; mtrr[reg].start = save4[ii].start; mtrr[reg].len = save4[ii].len; mtrr[reg].cache = save4[ii].cache; mtrr[reg].on = 1; } // check lost items for included UC entries while (ii<sv4idx) { if (mtrr[ii].cache==MTRRF_UC) { int idx = is_included(save4[ii].start,save4[ii].len); if (idx<0) idx = is_intersection(save4[ii].start,save4[ii].len); // check it multiple times (for intersection) if (idx>=0) { clearreg(idx); continue; } } ii++; } } return 0; }
int is_subsetable(fm_entry * fm) { assert(is_included(fm)); return is_subsetted(fm); }
int is_subsetable(int i) { fm_entry *fm = fm_tab + i; return is_included(fm) && is_subsetted(fm); }