void FeedParser::parse_build(XmlReader& xml, const std::string& type, const std::string& href) { Dependencies depends(this->queue, "*"); parse_depends(xml, depends); Driver const *driver = this->ph.get(type); if (!driver) { return; } KImplementation impl(spec.id, this->name, "SOURCE"); impl.values["href"] = href; impl.driver = driver; for (std::size_t i = 0; i < releases.size(); ++i) { impl.version = releases[i].version(); impl.values["tag"] = releases[i].tag(); foreach_variant(variants, [&](KDictionary variant) { if (!spec.query.evaluate(impl.version, variant)) { return; } impl.variant = variant; impl.depends.clear(); impl.conflicts.clear(); depends.replay("*", impl.version, variant, impl.depends, impl.conflicts); db.push_back(impl); }); } }
void FeedParser::parse_components(XmlReader& xml) { while (xml.start_element()) { if (xml.name() == "component" && xml.namespace_uri() == project_ns) { components.emplace_back(this->queue, xml.attribute("name", project_ns)); parse_depends(xml, components.back()); } xml.skip(); } }
void FeedParser::parse_depends(XmlReader& xml, Dependencies& depends) { while (xml.start_element()) { std::string name = xml.name(); if (name == "if") { depends.start_if(xml.attribute("test", project_ns)); parse_depends(xml, depends); depends.end_if(); } else if (name == "elseif") { depends.start_elseif(xml.attribute("test", project_ns)); parse_depends(xml, depends); depends.end_if(); } else if (name == "else") { depends.start_else(); parse_depends(xml, depends); depends.end_if(); } else if (name == "depends") { std::string dep = resolve_uri(spec.id, xml.attribute("href", project_ns)); depends.depends(Spec(dep.c_str())); } else if (name == "conflicts") { std::string dep = resolve_uri(spec.id, xml.attribute("href", project_ns)); depends.conflicts(Spec(dep.c_str())); } xml.skip(); } }
void FeedParser::parse_runtime(XmlReader& xml) { components.emplace_back(this->queue); parse_depends(xml, components.back()); }
PyObject *pkg_info(PyObject *self, PyObject *args) { /* collect package info of packages listed in given .files.tar.gz files * return a list of dict */ int found, existing; char *l = NULL, *p, *v; char pname[ABUFLEN], *fname, *dname; const char *filename=NULL, *pkgname; struct stat st; struct archive *a; struct archive_entry *entry; FILE *stream = NULL; PyObject *ret=NULL, *pkgnames_list=NULL, *pkg=NULL, *waiting_dict=NULL; Py_ssize_t lp, i; if (!PyArg_ParseTuple(args, "sO", &filename, &pkgnames_list)) { PyErr_SetString(PyExc_ValueError, "pkg_info() has invalid arguments"); return NULL; } if (filename == NULL || strlen(filename)<=0) { PyErr_SetString(PyExc_ValueError, "pkg_info() was given an empty files tarball name."); return NULL; } if (!PyList_Check(pkgnames_list)) { PyErr_SetString(PyExc_ValueError, "pkg_info() 2nd argument must be a list"); return NULL; } lp = PyList_Size(pkgnames_list); if ( lp == 0) { return PyList_New(0); } pname[ABUFLEN-1]='\0'; if(stat(filename, &st)==-1 || !S_ISREG(st.st_mode)) { PyErr_Format(PyExc_IOError, "File does not exist: %s\n", filename); return NULL; } ret = PyList_New(0); if (ret == NULL) { goto error; } waiting_dict = PyDict_New(); if (waiting_dict == NULL) { goto error; } a = archive_read_new(); archive_read_support_compression_all(a); archive_read_support_format_all(a); archive_read_open_filename(a, filename, 10240); l = NULL; while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { if(!S_ISREG(archive_entry_filetype(entry))) { archive_read_data_skip(a); continue; } strncpy(pname, archive_entry_pathname(entry), ABUFLEN-1); fname = basename(pname); dname = dirname(pname); if (splitname(dname, &p, &v) == -1) { archive_read_data_skip(a); continue; } found = 0; for (i=0; i<lp; i++) { pkgname = PyString_AsString(PyList_GetItem(pkgnames_list, i)); if (pkgname == NULL) { goto error; } if (strcmp(p, pkgname) == 0) { found = 1; break; } } free(p); free(v); if (!found) { archive_read_data_skip(a); continue; } pkg = PyDict_GetItemString(waiting_dict, pkgname); existing = 1; if (pkg == NULL) { existing = 0; pkg = PyDict_New(); if (pkg == NULL) { goto error; } } if(strcmp(fname, "desc") == 0) { stream = open_archive_stream(a); if (!stream) { PyErr_SetString(PyExc_IOError, "Unable to open archive stream."); goto error; } if (parse_desc(stream, &pkg) == -1) { fclose(stream); if (!existing) Py_DECREF(pkg); continue; } fclose(stream); } else if (strcmp(fname, "depends") == 0) { stream = open_archive_stream(a); if (!stream) { PyErr_SetString(PyExc_IOError, "Unable to open archive stream."); goto error; } if (parse_depends(stream, &pkg) == -1) { fclose(stream); if (!existing) Py_DECREF(pkg); continue; } fclose(stream); } else { archive_read_data_skip(a); continue; } if (existing) { PyList_Append(ret, pkg); PyDict_DelItemString(waiting_dict, pkgname); pkg = NULL; } else { PyDict_SetItemString(waiting_dict, pkgname, pkg); Py_DECREF(pkg); } } if(l) free(l); archive_read_finish(a); /* we discard element still present in waiting_dict because they miss either the desc * or depends values */ Py_DECREF(waiting_dict); return ret; error: Py_XDECREF(ret); Py_XDECREF(waiting_dict); Py_XDECREF(pkg); return NULL; }
int main(int argc, char ** argv) { char * sep; sqlite3 * db = NULL; struct Package current = blank_package; char baseurl[256] = ""; char line[sizeof(current.homepage)]; /* No line will be larger than the largest field */ int code; int chained_call = 0; char * db_path = NULL; /* NOTE: If Package ever contains varible fields, this must be changed */ char sql[sizeof(current) + 8*3*sizeof(char) + 137*sizeof(char) + 256*sizeof(char)]; while((code = getopt(argc, argv, "schd:")) != -1) { switch(code) { case 's': if(db != NULL) { fputs("-d and -s are mutually exclusive\n", stderr); exit(EXIT_FAILURE); } print_sql = 1; break; case 'c': chained_call = 1; break; case 'h': help(); break; case 'd': if(print_sql) { fputs("-d and -s are mutually exclusive\n", stderr); exit(EXIT_FAILURE); } if(sqlite3_open(optarg, &db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } break; default: help(); } } /* Open database */ if(!print_sql && db == NULL && (db_path = get_db_path()) && sqlite3_open(db_path, &db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } if(db_path) { free(db_path); } /* Do everything as one transaction. Many times faster */ safe_execute(db, "BEGIN TRANSACTION;"); /* Create tables if they do not exist */ safe_execute(db, "CREATE TABLE IF NOT EXISTS packages " \ "(package TEXT PRIMARY KEY, name TEXT, version TEXT," \ "maintainer TEXT, installed_size INTEGER, size INTEGER," \ "homepage TEXT, section TEXT, category TEXT, baseurl TEXT,"\ "path TEXT, md5 TEXT, description TEXT, user_rating INTEGER,"\ "user_owns TEXT, status INTEGER, rating INTEGER, price INTEGER);" \ "CREATE TABLE IF NOT EXISTS virtual_packages (package TEXT PRIMARY KEY, is_really TEXT);" \ "CREATE TABLE IF NOT EXISTS depends (package TEXT, depend TEXT, version TEXT);" ); if(!chained_call) { safe_execute(db, "DELETE FROM virtual_packages;"); safe_execute(db, "DELETE FROM depends;"); } /* Loop over lines from stream */ code = 0; while(fgets(line, sizeof(line), stdin)) { if(line[0] == '#') { /* Chomp */ if((sep = strchr(line, '\n'))) { *sep = '\0'; } strncpy(baseurl, line + 1, sizeof(baseurl)-1); /* Blank line means end of this package definition */ } else if(line[0] == '\n') { current.baseurl = baseurl; if(current.package[0] != '\0') { package_insert_sql(¤t, sql, sizeof(sql)); if(print_sql) { puts(sql); } else { if((code = sqlite3_exec(db, sql, NULL, NULL, NULL)) != 0) { if(code == SQLITE_CONSTRAINT) { package_update_sql(¤t, sql, sizeof(sql)); safe_execute(db, sql); } else { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } } } } /* Reset things */ code = 0; current = blank_package; } else { /* Chomp */ if((sep = strchr(line, '\n'))) { *sep = '\0'; } /* Description spans multiple lines at the end, concat stuff */ if(code) { strncat(current.description, "\n", sizeof(current.description)-1); strncat(current.description, line, sizeof(current.description)-1); } else { /* Split on colon */ if((sep = strchr(line, ':'))) { *sep = '\0'; /* Skip over the space too */ sep = sep + 2; /* If we haven't seen the field yet, do a string compare to see if * this is it. Copy remainder of line into struct */ if( current.package[0] == '\0' && strcmp(line, "Package") == 0) { strncpy(current.package, sep, sizeof(current.package)-1); } else if(current.name[0] == '\0' && strcmp(line, "Name") == 0) { strncpy(current.name, sep, sizeof(current.name)-1); } else if(current.category[0] == '\0' && strcmp(line, "Category") == 0) { strncpy(current.category, sep, sizeof(current.category)-1); } else if(current.version[0] == '\0' && strcmp(line, "Version") == 0) { strncpy(current.version, sep, sizeof(current.version)-1); } else if(current.user_owns[0] == '\0' && strcmp(line, "UserOwns") == 0) { strncpy(current.user_owns, sep, sizeof(current.user_owns)-1); } else if(current.section[0] == '\0' && strcmp(line, "Section") == 0) { strncpy(current.section, sep, sizeof(current.section)-1); } else if(current.md5[0] == '\0' && strcmp(line, "MD5sum") == 0) { strncpy(current.md5, sep, sizeof(current.md5)-1); } else if(current.maintainer[0] == '\0' && strcmp(line, "Maintainer") == 0) { strncpy(current.maintainer, sep, sizeof(current.maintainer)-1); } else if(current.path[0] == '\0' && strcmp(line, "Filename") == 0) { strncat(current.path, sep, sizeof(current.path)-1); } else if(current.homepage == '\0' && strcmp(line, "Homepage") == 0) { strncpy(current.homepage, sep, sizeof(current.homepage)-1); } else if(current.rating == 0 && strcmp(line, "Rating") == 0) { current.rating = atoi(sep); } else if(current.user_rating == 0 && strcmp(line, "UserRating") == 0) { current.user_rating = atoi(sep); } else if(current.price == 0 && strcmp(line, "Price") == 0) { current.price = atoi(sep); } else if(current.installed_size == 0 && strcmp(line, "Installed-Size") == 0) { current.installed_size = atoi(sep); } else if(current.size == 0 && strcmp(line, "Size") == 0) { current.size = atoi(sep); } else if( strcmp(line, "Provides") == 0) { sep = strtok(sep, ", "); sql[0] = '\0'; strncpy(sql, "INSERT INTO virtual_packages (package, is_really) VALUES(", sizeof(sql)); quotecat(sql, sep, sizeof(sql), 1); quotecat(sql, current.package, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)); safe_execute(db, sql); while((sep = strtok(NULL, ", ")) != NULL) { sql[0] = '\0'; strncpy(sql, "INSERT INTO virtual_packages (package, is_really) VALUES(", sizeof(sql)); quotecat(sql, sep, sizeof(sql), 1); quotecat(sql, current.package, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)); safe_execute(db, sql); } } else if( strcmp(line, "Depends") == 0) { parse_depends(db, current.package, sep); } else if( strcmp(line, "Description") == 0) { strncpy(current.description, sep, sizeof(current.description)-1); code = 1; } } } /* if code */ } /* if line[0] == '\n' */ } /* while */ /* End the transaction only when all data has been inserted */ safe_execute(db, "END TRANSACTION;"); /* Clean up disk space */ if(!chained_call) { safe_execute(db, "DELETE FROM packages WHERE package='';"); safe_execute(db, "VACUUM;"); } /* Close database */ if(db != NULL && sqlite3_close(db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }