save memory in ipkg while parsing package lists - there's no need to load the whole...
[openwrt/svn-archive/archive.git] / package / busybox / patches / 524-memory_usage.patch
1 Index: busybox-1.8.2/archival/libipkg/pkg.c
2 ===================================================================
3 --- busybox-1.8.2.orig/archival/libipkg/pkg.c 2008-01-06 03:14:12.003658206 +0100
4 +++ busybox-1.8.2/archival/libipkg/pkg.c 2008-01-06 03:24:18.187737063 +0100
5 @@ -224,8 +224,7 @@
6 if (err) { return err; }
7
8 rewind(control_file);
9 - raw = read_raw_pkgs_from_stream(control_file);
10 - pkg_parse_raw(pkg, &raw, NULL, NULL);
11 + pkg_parse_stream(pkg, control_file, NULL, NULL);
12
13 fclose(control_file);
14
15 Index: busybox-1.8.2/archival/libipkg/pkg_hash.c
16 ===================================================================
17 --- busybox-1.8.2.orig/archival/libipkg/pkg_hash.c 2008-01-06 03:14:12.231671203 +0100
18 +++ busybox-1.8.2/archival/libipkg/pkg_hash.c 2008-01-06 03:28:38.218555373 +0100
19 @@ -89,20 +89,20 @@
20 pkg_src_t *src, pkg_dest_t *dest, int is_status_file)
21 {
22 hash_table_t *hash = &conf->pkg_hash;
23 - char **raw;
24 - char **raw_start;
25 + FILE *fp;
26 pkg_t *pkg;
27
28 - raw = raw_start = read_raw_pkgs_from_file(file_name);
29 - if (!raw)
30 - return -ENOMEM;
31 + if(!(fp = fopen(file_name, "r"))){
32 + fprintf(stderr, "can't get %s open for read\n", file_name);
33 + return NULL;
34 + }
35
36 - while(*raw){ /* don't worry, we'll increment raw in the parsing function */
37 + while(!feof(fp)) { /* don't worry, we'll increment raw in the parsing function */
38 pkg = pkg_new();
39 if (!pkg)
40 return -ENOMEM;
41
42 - if (pkg_parse_raw(pkg, &raw, src, dest) == 0) {
43 + if (pkg_parse_stream(pkg, fp, src, dest) == 0) {
44 if (!pkg->architecture) {
45 char *version_str = pkg_version_str_alloc(pkg);
46 pkg->architecture = pkg_get_default_arch(conf);
47 @@ -116,13 +116,6 @@
48 }
49 }
50
51 - /* XXX: CLEANUP: I'd like a cleaner interface for cleaning up
52 - memory after read_raw_pkgs_from_file */
53 - raw = raw_start;
54 - while (*raw) {
55 - free(*raw++);
56 - }
57 - free(raw_start);
58 return 0;
59 }
60
61 Index: busybox-1.8.2/archival/libipkg/pkg_parse.c
62 ===================================================================
63 --- busybox-1.8.2.orig/archival/libipkg/pkg_parse.c 2008-01-06 03:14:12.283674167 +0100
64 +++ busybox-1.8.2/archival/libipkg/pkg_parse.c 2008-01-06 03:38:24.111943535 +0100
65 @@ -227,6 +227,161 @@
66 Enhances, perhaps we could generalize all of these and save some
67 code duplication.
68 */
69 +int pkg_parse_stream(pkg_t *pkg, FILE *stream, pkg_src_t *src, pkg_dest_t *dest)
70 +{
71 + int reading_conffiles, reading_description;
72 + int pkg_false_provides=1;
73 + char ** lines;
74 + char *provide=NULL;
75 + char *buf, *scout;
76 + int count = 0;
77 + size_t size = 512;
78 +
79 + buf = malloc (size);
80 +
81 + pkg->src = src;
82 + pkg->dest = dest;
83 +
84 + reading_conffiles = reading_description = 0;
85 +
86 + while (fgets(buf, size, stream)) {
87 + while (strlen (buf) == (size - 1)
88 + && buf[size-2] != '\n') {
89 + size_t o = size - 1;
90 + size *= 2;
91 + buf = realloc (buf, size);
92 + if (fgets (buf + o, size - o, stream) == NULL)
93 + break;
94 + }
95 +
96 + if((scout = strchr(buf, '\n')))
97 + *scout = '\0';
98 +
99 + lines = &buf;
100 + /* fprintf(stderr, "PARSING %s\n", *lines);*/
101 + if(isGenericFieldType("Package:", *lines))
102 + pkg->name = parseGenericFieldType("Package", *lines);
103 + else if(isGenericFieldType("Architecture:", *lines))
104 + pkg->architecture = parseGenericFieldType("Architecture", *lines);
105 + else if(isGenericFieldType("Filename:", *lines))
106 + pkg->filename = parseGenericFieldType("Filename", *lines);
107 + else if(isGenericFieldType("Section:", *lines))
108 + pkg->section = parseGenericFieldType("Section", *lines);
109 + else if(isGenericFieldType("MD5sum:", *lines))
110 + pkg->md5sum = parseGenericFieldType("MD5sum", *lines);
111 + /* The old ipkg wrote out status files with the wrong case for MD5sum,
112 + let's parse it either way */
113 + else if(isGenericFieldType("MD5Sum:", *lines))
114 + pkg->md5sum = parseGenericFieldType("MD5Sum", *lines);
115 + else if(isGenericFieldType("Size:", *lines))
116 + pkg->size = parseGenericFieldType("Size", *lines);
117 + else if(isGenericFieldType("Source:", *lines))
118 + pkg->source = parseGenericFieldType("Source", *lines);
119 + else if(isGenericFieldType("Installed-Size:", *lines))
120 + pkg->installed_size = parseGenericFieldType("Installed-Size", *lines);
121 + else if(isGenericFieldType("Installed-Time:", *lines)) {
122 + char *time_str = parseGenericFieldType("Installed-Time", *lines);
123 + pkg->installed_time = strtoul(time_str, NULL, 0);
124 + } else if(isGenericFieldType("Priority:", *lines))
125 + pkg->priority = parseGenericFieldType("Priority", *lines);
126 + else if(isGenericFieldType("Essential:", *lines)) {
127 + char *essential_value;
128 + essential_value = parseGenericFieldType("Essential", *lines);
129 + if (strcmp(essential_value, "yes") == 0) {
130 + pkg->essential = 1;
131 + }
132 + free(essential_value);
133 + }
134 + else if(isGenericFieldType("Status", *lines))
135 + parseStatus(pkg, *lines);
136 + else if(isGenericFieldType("Version", *lines))
137 + parseVersion(pkg, *lines);
138 + else if(isGenericFieldType("Maintainer", *lines))
139 + pkg->maintainer = parseGenericFieldType("Maintainer", *lines);
140 + else if(isGenericFieldType("Conffiles", *lines)){
141 + parseConffiles(pkg, *lines);
142 + reading_conffiles = 1;
143 + }
144 + else if(isGenericFieldType("Description", *lines)) {
145 + pkg->description = parseGenericFieldType("Description", *lines);
146 + reading_conffiles = 0;
147 + reading_description = 1;
148 + }
149 +
150 + else if(isGenericFieldType("Provides", *lines)){
151 +/* Here we add the internal_use to align the off by one problem between provides_str and provides */
152 + provide = (char * ) malloc(strlen(*lines)+ 35 ); /* Preparing the space for the new ipkg_internal_use_only */
153 + if ( alterProvidesLine(*lines,provide) ){
154 + return EINVAL;
155 + }
156 + pkg->provides_str = parseDependsString( provide, &pkg->provides_count);
157 +/* Let's try to hack a bit here.
158 + The idea is that if a package has no Provides, we would add one generic, to permit the check of dependencies
159 + in alot of other places. We will remove it before writing down the status database */
160 + pkg_false_provides=0;
161 + free(provide);
162 + }
163 +
164 + else if(isGenericFieldType("Depends", *lines))
165 + pkg->depends_str = parseDependsString(*lines, &pkg->depends_count);
166 + else if(isGenericFieldType("Pre-Depends", *lines))
167 + pkg->pre_depends_str = parseDependsString(*lines, &pkg->pre_depends_count);
168 + else if(isGenericFieldType("Recommends", *lines))
169 + pkg->recommends_str = parseDependsString(*lines, &pkg->recommends_count);
170 + else if(isGenericFieldType("Suggests", *lines))
171 + pkg->suggests_str = parseDependsString(*lines, &pkg->suggests_count);
172 + /* Abhaya: support for conflicts */
173 + else if(isGenericFieldType("Conflicts", *lines))
174 + pkg->conflicts_str = parseDependsString(*lines, &pkg->conflicts_count);
175 + else if(isGenericFieldType("Replaces", *lines))
176 + pkg->replaces_str = parseDependsString(*lines, &pkg->replaces_count);
177 + else if(line_is_blank(*lines)) {
178 + break;
179 + }
180 + else if(**lines == ' '){
181 + if(reading_description) {
182 + /* we already know it's not blank, so the rest of description */
183 + pkg->description = realloc(pkg->description,
184 + strlen(pkg->description)
185 + + 1 + strlen(*lines) + 1);
186 + strcat(pkg->description, "\n");
187 + strcat(pkg->description, (*lines));
188 + }
189 + else if(reading_conffiles)
190 + parseConffiles(pkg, *lines);
191 + }
192 + }
193 +/* If the ipk has not a Provides line, we insert our false line */
194 + if ( pkg_false_provides==1)
195 + pkg->provides_str = parseDependsString ((char *)"Provides: ipkg_internal_use_only ", &pkg->provides_count);
196 +
197 + free(buf);
198 + if (pkg->name) {
199 + return 0;
200 + } else {
201 + return EINVAL;
202 + }
203 +}
204 +
205 +#if 0
206 +
207 +/* Some random thoughts from Carl:
208 +
209 + This function could be considerably simplified if we just kept
210 + an array of all the generic string-valued field names, and looped
211 + through those looking for a match. Also, these fields could perhaps
212 + be stored in the package as an array as well, (or, probably better,
213 + as an nv_pair_list_t).
214 +
215 + Fields which require special parsing or storage, (such as Depends:
216 + and Status:) could be handled as they are now.
217 +*/
218 +/* XXX: FEATURE: The Suggests: field needs to be changed from a string
219 + to a dependency list. And, since we already have
220 + Depends/Pre-Depends and need to add Conflicts, Recommends, and
221 + Enhances, perhaps we could generalize all of these and save some
222 + code duplication.
223 +*/
224 int pkg_parse_raw(pkg_t *pkg, char ***raw, pkg_src_t *src, pkg_dest_t *dest)
225 {
226 int reading_conffiles, reading_description;
227 @@ -345,6 +500,7 @@
228 return EINVAL;
229 }
230 }
231 +#endif
232
233 int pkg_valorize_other_field(pkg_t *pkg, char ***raw)
234 {
235 Index: busybox-1.8.2/archival/libipkg/pkg_parse.h
236 ===================================================================
237 --- busybox-1.8.2.orig/archival/libipkg/pkg_parse.h 2008-01-06 03:14:12.303675307 +0100
238 +++ busybox-1.8.2/archival/libipkg/pkg_parse.h 2008-01-06 03:39:03.954214018 +0100
239 @@ -25,7 +25,10 @@
240 char ** parseDependsString(char * raw, int * depends_count);
241 int parseVersion(pkg_t *pkg, char *raw);
242 void parseConffiles(pkg_t * pkg, char * raw);
243 +#if 0
244 int pkg_parse_raw(pkg_t *pkg, char ***raw, pkg_src_t *src, pkg_dest_t *dest);
245 +#endif
246 +int pkg_parse_stream(pkg_t *pkg, FILE *stream, pkg_src_t *src, pkg_dest_t *dest);
247 int pkg_valorize_other_field(pkg_t *pkg, char ***raw);
248
249 #endif