static int parse_entry(const char **ep, struct authlist_entry *entry) { if (istag(ep, tag_everybody)) entry->kind = AUTHLIST_KIND_EVERYBODY; else if (istag(ep, tag_nobody)) entry->kind = AUTHLIST_KIND_NOBODY; else if (istag_col(ep, tag_uid)) return parse_id(ep, entry, AUTHLIST_KIND_UID); else if (istag_col(ep, tag_nouid)) return parse_id(ep, entry, AUTHLIST_KIND_NOUID); else if (istag_col(ep, tag_gid)) return parse_id(ep, entry, AUTHLIST_KIND_GID); else if (istag_col(ep, tag_nogid)) return parse_id(ep, entry, AUTHLIST_KIND_NOGID); else return -EINVAL; return 0; }
int repo_add_content(Repo *repo, FILE *fp, int flags) { Pool *pool = repo->pool; char *line, *linep; int aline; Solvable *s; struct parsedata pd; Repodata *data; Id handle = 0; int contentstyle = 0; char *descrdir = 0; char *datadir = 0; char *defvendor = 0; int i = 0; int res = 0; /* architectures we use the first architecture in BASEARCHS or noarch for the product. At the end we create (clone) the product for each one of the remaining architectures we allow max 4 archs */ unsigned int numotherarchs = 0; Id *otherarchs = 0; memset(&pd, 0, sizeof(pd)); line = solv_malloc(1024); aline = 1024; pd.repo = repo; linep = line; s = 0; data = repo_add_repodata(repo, flags); for (;;) { char *key, *value; /* read line into big-enough buffer */ if (linep - line + 16 > aline) { aline = linep - line; line = solv_realloc(line, aline + 512); linep = line + aline; aline += 512; } if (!fgets(linep, aline - (linep - line), fp)) break; linep += strlen(linep); if (linep == line || linep[-1] != '\n') continue; while ( --linep > line && ( linep[-1] == ' ' || linep[-1] == '\t' ) ) ; /* skip trailing ws */ *linep = 0; linep = line; /* expect "key value" lines */ value = line; key = splitword(&value); if (key) { #if 0 fprintf (stderr, "key %s, value %s\n", key, value); #endif #define istag(x) (!strcmp (key, x)) #define code10 (contentstyle == 10) #define code11 (contentstyle == 11) if (istag ("CONTENTSTYLE")) { if (contentstyle) pool_debug(pool, SOLV_ERROR, "repo_content: 'CONTENTSTYLE' must be first line of 'content'\n"); contentstyle = atoi(value); continue; } if (!contentstyle) contentstyle = 10; /* repository tags */ /* we also replicate some of them into the product solvables * to be backward compatible */ if (istag ("REPOID")) { repodata_add_poolstr_array(data, SOLVID_META, REPOSITORY_REPOID, value); continue; } if (istag ("REPOKEYWORDS")) { add_multiple_strings(data, SOLVID_META, REPOSITORY_KEYWORDS, value); continue; } if (istag ("DISTRO")) { Id dh = repodata_new_handle(data); char *p; /* like with createrepo --distro */ if ((p = strchr(value, ',')) != 0) { *p++ = 0; if (*value) repodata_set_poolstr(data, dh, REPOSITORY_PRODUCT_CPEID, value); } else p = value; if (*p) repodata_set_str(data, dh, REPOSITORY_PRODUCT_LABEL, p); repodata_add_flexarray(data, SOLVID_META, REPOSITORY_DISTROS, dh); continue; } if (istag ("DESCRDIR")) { if (descrdir) free(descrdir); else repodata_set_str(data, SOLVID_META, SUSETAGS_DESCRDIR, value); if (s) repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, value); descrdir = solv_strdup(value); continue; } if (istag ("DATADIR")) { if (datadir) free(datadir); else repodata_set_str(data, SOLVID_META, SUSETAGS_DATADIR, value); if (s) repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, value); datadir = solv_strdup(value); continue; } if (istag ("VENDOR")) { if (defvendor) free(defvendor); else repodata_set_poolstr(data, SOLVID_META, SUSETAGS_DEFAULTVENDOR, value); if (s) s->vendor = pool_str2id(pool, value, 1); defvendor = solv_strdup(value); continue; } if (istag ("META") || istag ("HASH") || istag ("KEY")) { char *checksumtype, *checksum; Id fh, type; int l; if ((checksumtype = splitword(&value)) == 0) continue; if ((checksum = splitword(&value)) == 0) continue; if (!*value) continue; type = solv_chksum_str2type(checksumtype); if (!type) { pool_error(pool, -1, "%s: unknown checksum type '%s'", value, checksumtype); res = 1; continue; } l = solv_chksum_len(type); if (strlen(checksum) != 2 * l) { pool_error(pool, -1, "%s: invalid checksum length for %s", value, checksumtype); res = 1; continue; } fh = repodata_new_handle(data); repodata_set_poolstr(data, fh, SUSETAGS_FILE_TYPE, key); repodata_set_str(data, fh, SUSETAGS_FILE_NAME, value); repodata_set_checksum(data, fh, SUSETAGS_FILE_CHECKSUM, type, checksum); repodata_add_flexarray(data, SOLVID_META, SUSETAGS_FILE, fh); continue; } /* product tags */ if ((code10 && istag ("PRODUCT")) || (code11 && istag ("NAME"))) { if (s && !s->name) { /* this solvable was created without seeing a PRODUCT entry, just set the name and continue */ s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1); continue; } if (s) { /* finish old solvable */ if (!s->arch) s->arch = ARCH_NOARCH; if (!s->evr) s->evr = ID_EMPTY; if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); if (code10) s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0); } /* create new solvable */ s = pool_id2solvable(pool, repo_add_solvable(repo)); handle = s - pool->solvables; s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1); if (datadir) repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, datadir); if (descrdir) repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, descrdir); if (defvendor) s->vendor = pool_str2id(pool, defvendor, 1); continue; } /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable from here on. */ if (!s) { s = pool_id2solvable(pool, repo_add_solvable(repo)); handle = s - pool->solvables; } if (istag ("VERSION")) pd.tmpvers = solv_strdup(value); else if (istag ("RELEASE")) pd.tmprel = solv_strdup(value); else if (code11 && istag ("DISTRIBUTION")) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_DISTRIBUTION, value); else if (istag ("UPDATEURLS")) add_multiple_urls(data, handle, value, pool_str2id(pool, "update", 1)); else if (istag ("EXTRAURLS")) add_multiple_urls(data, handle, value, pool_str2id(pool, "extra", 1)); else if (istag ("OPTIONALURLS")) add_multiple_urls(data, handle, value, pool_str2id(pool, "optional", 1)); else if (istag ("RELNOTESURL")) add_multiple_urls(data, handle, value, pool_str2id(pool, "releasenotes", 1)); else if (istag ("SHORTLABEL")) repodata_set_str(data, s - pool->solvables, PRODUCT_SHORTLABEL, value); else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */ repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, value); else if (!strncmp (key, "LABEL.", 6)) repodata_set_str(data, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value); else if (istag ("FLAGS")) add_multiple_strings(data, handle, PRODUCT_FLAGS, value); else if (istag ("VENDOR")) /* actually already handled above */ s->vendor = pool_str2id(pool, value, 1); else if (istag ("BASEARCHS")) { char *arch; if ((arch = splitword(&value)) != 0) { s->arch = pool_str2id(pool, arch, 1); while ((arch = splitword(&value)) != 0) { otherarchs = solv_extend(otherarchs, numotherarchs, 1, sizeof(Id), 7); otherarchs[numotherarchs++] = pool_str2id(pool, arch, 1); } } } if (!code10) continue; /* * Every tag below is Code10 only * */ if (istag ("ARCH")) /* Theoretically we want to have the best arch of the given modifiers which still is compatible with the system arch. We don't know the latter here, though. */ s->arch = ARCH_NOARCH; else if (istag ("PREREQUIRES")) s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER); else if (istag ("REQUIRES")) s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER); else if (istag ("PROVIDES")) s->provides = adddep(pool, &pd, s->provides, value, 0); else if (istag ("CONFLICTS")) s->conflicts = adddep(pool, &pd, s->conflicts, value, 0); else if (istag ("OBSOLETES")) s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0); else if (istag ("RECOMMENDS")) s->recommends = adddep(pool, &pd, s->recommends, value, 0); else if (istag ("SUGGESTS")) s->suggests = adddep(pool, &pd, s->suggests, value, 0); else if (istag ("SUPPLEMENTS")) s->supplements = adddep(pool, &pd, s->supplements, value, 0); else if (istag ("ENHANCES")) s->enhances = adddep(pool, &pd, s->enhances, value, 0); /* FRESHENS doesn't seem to exist. */ else if (istag ("TYPE")) repodata_set_str(data, s - pool->solvables, PRODUCT_TYPE, value); /* XXX do something about LINGUAS and ARCH? * <ma>: Don't think so. zypp does not use or propagate them. */ #undef istag } else pool_debug(pool, SOLV_ERROR, "repo_content: malformed line: %s\n", line); } if (datadir) free(datadir); if (descrdir) free(descrdir); if (defvendor) free(defvendor); if (s && !s->name) { pool_debug(pool, SOLV_ERROR, "repo_content: 'content' incomplete, no product solvable created!\n"); repo_free_solvable(repo, s - pool->solvables, 1); s = 0; } if (s) { if (pd.tmprel) s->evr = makeevr(pool, join(&pd, pd.tmpvers, "-", pd.tmprel)); else s->evr = makeevr(pool, pd.tmpvers); pd.tmpvers = solv_free((void *)pd.tmpvers); pd.tmprel = solv_free((void *)pd.tmprel); if (!s->arch) s->arch = ARCH_NOARCH; if (!s->evr) s->evr = ID_EMPTY; if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); if (code10) s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0); /* now for every other arch, clone the product except the architecture */ for (i = 0; i < numotherarchs; ++i) { Solvable *p = pool_id2solvable(pool, repo_add_solvable(repo)); p->name = s->name; p->evr = s->evr; p->vendor = s->vendor; p->arch = otherarchs[i]; /* self provides */ if (s->name && p->arch != ARCH_SRC && p->arch != ARCH_NOSRC) p->provides = repo_addid_dep(repo, p->provides, pool_rel2id(pool, p->name, p->evr, REL_EQ, 1), 0); /* now merge the attributes */ repodata_merge_attrs(data, p - pool->solvables, s - pool->solvables); } } if (pd.tmp) solv_free(pd.tmp); solv_free(line); solv_free(otherarchs); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); return res; }
void Html::skipTag() { enum TagState // what parsing state we're in { TStagstart, // start of tag name TStag, // in a tag name TSrest, // following tag name }; enum TagState state = TStagstart; int inot; unsigned char *tagstart = NULL; int taglen = 0; p++; inot = 0; if (*p == '/') { inot = 1; p++; } while (1) { switch (*p) { case '>': // found end of tag p++; break; case '"': case '\'': state = TSrest; skipString(); continue; case '<': if (p[1] == '!' && isCommentStart()) { // Comments start with <!-- scanComment(); } else if (p[1] == '/' && istagstart(*skipWhite(p + 2))) { error("nested tag"); skipTag(); } else if (istagstart(*skipWhite(p + 1))) { error("nested tag"); skipTag(); } // Treat comments as if they were whitespace state = TSrest; continue; case 0: case 0x1a: error("end of file before end of tag"); break; // end of file case '\r': if (p[1] == '\n') goto Ldefault; case '\n': linnum++; // Always extract new lines, so that code lexer counts the // lines right. dbuf->writeByte(*p); state = TSrest; // end of tag p++; continue; case ' ': case '\t': case '\f': case '\v': if (state == TStagstart) { p++; continue; } default: Ldefault: switch (state) { case TStagstart: // start of tag name assert(istagstart(*p)); state = TStag; tagstart = p; taglen = 0; break; case TStag: if (istag(*p)) { // Continuing tag name taglen++; } else { // End of tag name state = TSrest; } break; case TSrest: break; } p++; continue; } break; } // See if we parsed a <code> or </code> tag if (taglen && memicmp((char *) tagstart, (char *) "CODE", taglen) == 0 && *(p - 2) != '/') // ignore "<code />" (XHTML) { if (inot) { inCode--; if (inCode < 0) inCode = 0; // ignore extra </code>'s } else inCode++; } }