|
@@ -0,0 +1,317 @@
|
|
|
|
+--- a/libopkg/parse_util.c
|
|
|
|
++++ b/libopkg/parse_util.c
|
|
|
|
+@@ -22,6 +22,7 @@
|
|
|
|
+ #include "libbb/libbb.h"
|
|
|
|
+
|
|
|
|
+ #include "parse_util.h"
|
|
|
|
++#include "pkg_parse.h"
|
|
|
|
+
|
|
|
|
+ int
|
|
|
|
+ is_field(const char *type, const char *line)
|
|
|
|
+@@ -86,3 +87,84 @@ parse_list(const char *raw, unsigned int
|
|
|
|
+ *count = line_count;
|
|
|
|
+ return depends;
|
|
|
|
+ }
|
|
|
|
++
|
|
|
|
++int
|
|
|
|
++parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
|
|
|
|
++ char **buf0, size_t buf0len)
|
|
|
|
++{
|
|
|
|
++ int ret, lineno;
|
|
|
|
++ char *buf, *nl;
|
|
|
|
++ size_t buflen;
|
|
|
|
++
|
|
|
|
++ lineno = 1;
|
|
|
|
++ ret = 0;
|
|
|
|
++
|
|
|
|
++ buflen = buf0len;
|
|
|
|
++ buf = *buf0;
|
|
|
|
++ buf[0] = '\0';
|
|
|
|
++
|
|
|
|
++ while (1) {
|
|
|
|
++ if (fgets(buf, (int)buflen, fp) == NULL) {
|
|
|
|
++ if (ferror(fp)) {
|
|
|
|
++ opkg_perror(ERROR, "fgets");
|
|
|
|
++ ret = -1;
|
|
|
|
++ } else if (strlen(*buf0) == buf0len-1) {
|
|
|
|
++ opkg_msg(ERROR, "Missing new line character"
|
|
|
|
++ " at end of file!\n");
|
|
|
|
++ parse_line(item, *buf0, mask);
|
|
|
|
++ }
|
|
|
|
++ break;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ nl = strchr(buf, '\n');
|
|
|
|
++ if (nl == NULL) {
|
|
|
|
++ if (strlen(buf) < buflen-1) {
|
|
|
|
++ /*
|
|
|
|
++ * Line could be exactly buflen-1 long and
|
|
|
|
++ * missing a newline, but we won't know until
|
|
|
|
++ * fgets fails to read more data.
|
|
|
|
++ */
|
|
|
|
++ opkg_msg(ERROR, "Missing new line character"
|
|
|
|
++ " at end of file!\n");
|
|
|
|
++ parse_line(item, *buf0, mask);
|
|
|
|
++ break;
|
|
|
|
++ }
|
|
|
|
++ if (buf0len >= EXCESSIVE_LINE_LEN) {
|
|
|
|
++ opkg_msg(ERROR, "Excessively long line at "
|
|
|
|
++ "%d. Corrupt file?\n",
|
|
|
|
++ lineno);
|
|
|
|
++ ret = -1;
|
|
|
|
++ break;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ /*
|
|
|
|
++ * Realloc and point buf past the data already read,
|
|
|
|
++ * at the NULL terminator inserted by fgets.
|
|
|
|
++ * |<--------------- buf0len ----------------->|
|
|
|
|
++ * | |<------- buflen ---->|
|
|
|
|
++ * |---------------------|---------------------|
|
|
|
|
++ * buf0 buf
|
|
|
|
++ */
|
|
|
|
++ buflen = buf0len +1;
|
|
|
|
++ buf0len *= 2;
|
|
|
|
++ *buf0 = xrealloc(*buf0, buf0len);
|
|
|
|
++ buf = *buf0 + buflen -2;
|
|
|
|
++
|
|
|
|
++ continue;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ *nl = '\0';
|
|
|
|
++
|
|
|
|
++ lineno++;
|
|
|
|
++
|
|
|
|
++ if (parse_line(item, *buf0, mask))
|
|
|
|
++ break;
|
|
|
|
++
|
|
|
|
++ buf = *buf0;
|
|
|
|
++ buflen = buf0len;
|
|
|
|
++ buf[0] = '\0';
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ return ret;
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
+--- a/libopkg/parse_util.h
|
|
|
|
++++ b/libopkg/parse_util.h
|
|
|
|
+@@ -22,4 +22,8 @@ int is_field(const char *type, const cha
|
|
|
|
+ char *parse_simple(const char *type, const char *line);
|
|
|
|
+ char **parse_list(const char *raw, unsigned int *count, const char sep, int skip_field);
|
|
|
|
+
|
|
|
|
++typedef int (*parse_line_t)(void *, const char *, uint);
|
|
|
|
++int parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
|
|
|
|
++ char **buf0, size_t buf0len);
|
|
|
|
++
|
|
|
|
+ #endif
|
|
|
|
+--- a/libopkg/pkg_hash.c
|
|
|
|
++++ b/libopkg/pkg_hash.c
|
|
|
|
+@@ -23,6 +23,7 @@
|
|
|
|
+ #include "opkg_message.h"
|
|
|
|
+ #include "pkg_vec.h"
|
|
|
|
+ #include "pkg_hash.h"
|
|
|
|
++#include "parse_util.h"
|
|
|
|
+ #include "pkg_parse.h"
|
|
|
|
+ #include "opkg_utils.h"
|
|
|
|
+ #include "sprintf_alloc.h"
|
|
|
|
+@@ -119,8 +120,14 @@ pkg_hash_add_from_file(const char *file_
|
|
|
|
+ pkg->src = src;
|
|
|
|
+ pkg->dest = dest;
|
|
|
|
+
|
|
|
|
+- ret = pkg_parse_from_stream_nomalloc(pkg, fp, 0,
|
|
|
|
++ ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, 0,
|
|
|
|
+ &buf, len);
|
|
|
|
++
|
|
|
|
++ if (pkg->name == NULL) {
|
|
|
|
++ /* probably just a blank line */
|
|
|
|
++ ret = 1;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
+ if (ret) {
|
|
|
|
+ pkg_deinit (pkg);
|
|
|
|
+ free(pkg);
|
|
|
|
+--- a/libopkg/pkg_parse.c
|
|
|
|
++++ b/libopkg/pkg_parse.c
|
|
|
|
+@@ -104,9 +104,11 @@ get_arch_priority(const char *arch)
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+-static int
|
|
|
|
+-pkg_parse_line(pkg_t *pkg, const char *line, uint mask)
|
|
|
|
++int
|
|
|
|
++pkg_parse_line(void *ptr, const char *line, uint mask)
|
|
|
|
+ {
|
|
|
|
++ pkg_t *pkg = (pkg_t *) ptr;
|
|
|
|
++
|
|
|
|
+ /* these flags are a bit hackish... */
|
|
|
|
+ static int reading_conffiles = 0, reading_description = 0;
|
|
|
|
+ int ret = 0;
|
|
|
|
+@@ -266,91 +268,6 @@ dont_reset_flags:
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int
|
|
|
|
+-pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask,
|
|
|
|
+- char **buf0, size_t buf0len)
|
|
|
|
+-{
|
|
|
|
+- int ret, lineno;
|
|
|
|
+- char *buf, *nl;
|
|
|
|
+- size_t buflen;
|
|
|
|
+-
|
|
|
|
+- lineno = 1;
|
|
|
|
+- ret = 0;
|
|
|
|
+-
|
|
|
|
+- buflen = buf0len;
|
|
|
|
+- buf = *buf0;
|
|
|
|
+- buf[0] = '\0';
|
|
|
|
+-
|
|
|
|
+- while (1) {
|
|
|
|
+- if (fgets(buf, (int)buflen, fp) == NULL) {
|
|
|
|
+- if (ferror(fp)) {
|
|
|
|
+- opkg_perror(ERROR, "fgets");
|
|
|
|
+- ret = -1;
|
|
|
|
+- } else if (strlen(*buf0) == buf0len-1) {
|
|
|
|
+- opkg_msg(ERROR, "Missing new line character"
|
|
|
|
+- " at end of file!\n");
|
|
|
|
+- pkg_parse_line(pkg, *buf0, mask);
|
|
|
|
+- }
|
|
|
|
+- break;
|
|
|
|
+- }
|
|
|
|
+-
|
|
|
|
+- nl = strchr(buf, '\n');
|
|
|
|
+- if (nl == NULL) {
|
|
|
|
+- if (strlen(buf) < buflen-1) {
|
|
|
|
+- /*
|
|
|
|
+- * Line could be exactly buflen-1 long and
|
|
|
|
+- * missing a newline, but we won't know until
|
|
|
|
+- * fgets fails to read more data.
|
|
|
|
+- */
|
|
|
|
+- opkg_msg(ERROR, "Missing new line character"
|
|
|
|
+- " at end of file!\n");
|
|
|
|
+- pkg_parse_line(pkg, *buf0, mask);
|
|
|
|
+- break;
|
|
|
|
+- }
|
|
|
|
+- if (buf0len >= EXCESSIVE_LINE_LEN) {
|
|
|
|
+- opkg_msg(ERROR, "Excessively long line at "
|
|
|
|
+- "%d. Corrupt file?\n",
|
|
|
|
+- lineno);
|
|
|
|
+- ret = -1;
|
|
|
|
+- break;
|
|
|
|
+- }
|
|
|
|
+-
|
|
|
|
+- /*
|
|
|
|
+- * Realloc and point buf past the data already read,
|
|
|
|
+- * at the NULL terminator inserted by fgets.
|
|
|
|
+- * |<--------------- buf0len ----------------->|
|
|
|
|
+- * | |<------- buflen ---->|
|
|
|
|
+- * |---------------------|---------------------|
|
|
|
|
+- * buf0 buf
|
|
|
|
+- */
|
|
|
|
+- buflen = buf0len +1;
|
|
|
|
+- buf0len *= 2;
|
|
|
|
+- *buf0 = xrealloc(*buf0, buf0len);
|
|
|
|
+- buf = *buf0 + buflen -2;
|
|
|
|
+-
|
|
|
|
+- continue;
|
|
|
|
+- }
|
|
|
|
+-
|
|
|
|
+- *nl = '\0';
|
|
|
|
+-
|
|
|
|
+- lineno++;
|
|
|
|
+-
|
|
|
|
+- if (pkg_parse_line(pkg, *buf0, mask))
|
|
|
|
+- break;
|
|
|
|
+-
|
|
|
|
+- buf = *buf0;
|
|
|
|
+- buflen = buf0len;
|
|
|
|
+- buf[0] = '\0';
|
|
|
|
+- }
|
|
|
|
+-
|
|
|
|
+- if (pkg->name == NULL) {
|
|
|
|
+- /* probably just a blank line */
|
|
|
|
+- ret = 1;
|
|
|
|
+- }
|
|
|
|
+-
|
|
|
|
+- return ret;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+-int
|
|
|
|
+ pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask)
|
|
|
|
+ {
|
|
|
|
+ int ret;
|
|
|
|
+@@ -358,8 +275,13 @@ pkg_parse_from_stream(pkg_t *pkg, FILE *
|
|
|
|
+ const size_t len = 4096;
|
|
|
|
+
|
|
|
|
+ buf = xmalloc(len);
|
|
|
|
+- ret = pkg_parse_from_stream_nomalloc(pkg, fp, mask, &buf, len);
|
|
|
|
++ ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, mask, &buf, len);
|
|
|
|
+ free(buf);
|
|
|
|
+
|
|
|
|
++ if (pkg->name == NULL) {
|
|
|
|
++ /* probably just a blank line */
|
|
|
|
++ ret = 1;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+--- a/libopkg/pkg_parse.h
|
|
|
|
++++ b/libopkg/pkg_parse.h
|
|
|
|
+@@ -18,10 +18,11 @@
|
|
|
|
+ #ifndef PKG_PARSE_H
|
|
|
|
+ #define PKG_PARSE_H
|
|
|
|
+
|
|
|
|
++#include "pkg.h"
|
|
|
|
++
|
|
|
|
+ int parse_version(pkg_t *pkg, const char *raw);
|
|
|
|
+ int pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask);
|
|
|
|
+-int pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask,
|
|
|
|
+- char **buf0, size_t buf0len);
|
|
|
|
++int pkg_parse_line(void *ptr, const char *line, uint mask);
|
|
|
|
+
|
|
|
|
+ #define EXCESSIVE_LINE_LEN (4096 << 8)
|
|
|
|
+
|
|
|
|
+--- a/libopkg/release_parse.c
|
|
|
|
++++ b/libopkg/release_parse.c
|
|
|
|
+@@ -23,8 +23,10 @@
|
|
|
|
+ #include "parse_util.h"
|
|
|
|
+
|
|
|
|
+ static int
|
|
|
|
+-release_parse_line(release_t *release, const char *line)
|
|
|
|
++release_parse_line(void *ptr, const char *line, uint mask)
|
|
|
|
+ {
|
|
|
|
++ release_t *release = (release_t *) ptr;
|
|
|
|
++
|
|
|
|
+ int ret = 0;
|
|
|
|
+ unsigned int count = 0;
|
|
|
|
+ char **list = 0;
|
|
|
|
+@@ -111,25 +113,14 @@ dont_reset_flags:
|
|
|
|
+ int
|
|
|
|
+ release_parse_from_stream(release_t *release, FILE *fp)
|
|
|
|
+ {
|
|
|
|
+- int ret = 0;
|
|
|
|
+- char *buf = NULL;
|
|
|
|
+- size_t buflen, nread;
|
|
|
|
+-
|
|
|
|
+- nread = getline(&buf, &buflen, fp);
|
|
|
|
+- while ( nread != -1 ) {
|
|
|
|
+- if (buf[nread-1] == '\n') buf[nread-1] = '\0';
|
|
|
|
+- if (release_parse_line(release, buf))
|
|
|
|
+- opkg_msg(DEBUG, "Failed to parse release line for %s:\n\t%s\n",
|
|
|
|
+- release->name, buf);
|
|
|
|
+- nread = getline(&buf, &buflen, fp);
|
|
|
|
+- }
|
|
|
|
+-
|
|
|
|
+- if (!feof(fp)) {
|
|
|
|
+- opkg_perror(ERROR, "Problems reading Release file for %sd\n", release->name);
|
|
|
|
+- ret = -1;
|
|
|
|
+- }
|
|
|
|
++ int ret;
|
|
|
|
++ char *buf;
|
|
|
|
++ const size_t len = 4096;
|
|
|
|
+
|
|
|
|
++ buf = xmalloc(len);
|
|
|
|
++ ret = parse_from_stream_nomalloc(release_parse_line, release, fp, 0, &buf, len);
|
|
|
|
+ free(buf);
|
|
|
|
++
|
|
|
|
+ return ret;
|
|
|
|
+ }
|
|
|
|
+
|