1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <shared.h>
5
6#ifdef RTCONFIG_USB
7#include <disk_io_tools.h>
8
9#include "apps.h"
10
11char *alloc_string(const char *string){
12	char *buf;
13	int len;
14
15	len = strlen(string);
16	if((buf = (char *)malloc(len+1)) == NULL)
17		return NULL;
18
19	strcpy(buf, string);
20	buf[len] = 0;
21
22	return buf;
23}
24
25char *get_status_field(const char *target, const char *field){
26	char *buf;
27	char *ptr_head, *ptr_tail, backup;
28
29	if((ptr_head = strstr(target, field)) == NULL)
30		return NULL;
31
32	ptr_head += strlen(field);
33
34	if((ptr_tail = strchr(ptr_head, '\n')) == NULL)
35		ptr_tail = ptr_head+strlen(ptr_head);
36
37	backup = ptr_tail[0];
38	ptr_tail[0] = '\0';
39	buf = alloc_string(ptr_head);
40	ptr_tail[0] = backup;
41
42	return buf;
43}
44
45apps_info_t *initial_apps_data(){
46	apps_info_t *new_apps_info;
47
48	new_apps_info = (apps_info_t *)malloc(sizeof(apps_info_t));
49	if(new_apps_info == NULL)
50		return NULL;
51
52	new_apps_info->name = NULL;
53	new_apps_info->version = NULL;
54	new_apps_info->new_version = NULL;
55	new_apps_info->installed = NULL;
56	new_apps_info->enabled = NULL;
57	new_apps_info->source = NULL;
58	new_apps_info->url = NULL;
59	new_apps_info->description = NULL;
60	new_apps_info->depends = NULL;
61	new_apps_info->optional_utility = NULL;
62	new_apps_info->new_optional_utility = NULL;
63	new_apps_info->help_path = NULL;
64	new_apps_info->new_file_name = NULL;
65	new_apps_info->from_owner = NULL;
66
67	new_apps_info->next = NULL;
68
69	return new_apps_info;
70}
71
72void free_apps_list(apps_info_t **apps_info_list){
73	apps_info_t *apps_info, *old_apps_info;
74
75	if(apps_info_list == NULL)
76		return;
77
78	apps_info = *apps_info_list;
79	while(apps_info != NULL){
80		if(apps_info->name != NULL)
81			free(apps_info->name);
82		if(apps_info->version != NULL)
83			free(apps_info->version);
84		if(apps_info->new_version != NULL)
85			free(apps_info->new_version);
86		if(apps_info->installed != NULL)
87			free(apps_info->installed);
88		if(apps_info->enabled != NULL)
89			free(apps_info->enabled);
90		if(apps_info->source != NULL)
91			free(apps_info->source);
92		if(apps_info->url != NULL)
93			free(apps_info->url);
94		if(apps_info->description != NULL)
95			free(apps_info->description);
96		if(apps_info->depends != NULL)
97			free(apps_info->depends);
98		if(apps_info->optional_utility != NULL)
99			free(apps_info->optional_utility);
100		if(apps_info->new_optional_utility != NULL)
101			free(apps_info->new_optional_utility);
102		if(apps_info->help_path != NULL)
103			free(apps_info->help_path);
104		if(apps_info->new_file_name != NULL)
105			free(apps_info->new_file_name);
106		if(apps_info->from_owner != NULL)
107			free(apps_info->from_owner);
108
109		old_apps_info = apps_info;
110		apps_info = apps_info->next;
111		free(old_apps_info);
112	}
113}
114
115apps_info_t *get_apps_list(char *argv){
116	apps_info_t *apps_info_list = NULL, **follow_apps_info_list = NULL, *follow_apps_info;
117	char *apps_info;
118	char *pkg_head, *pkg_tail;
119	char info_name[128];
120	FILE *fp;
121	unsigned long file_size = 0;
122	int pid;
123	char *cmd[] = {"app_update.sh", NULL};
124	char line[128], buf[4096];
125	char *tmp_apps_name;
126	int got_apps;
127	char *STATUS;
128
129	if(!argv || strcmp(argv, APP_OWNER_OTHERS)){
130		// Get the newest version of the installed packages,
131		// and information of the non-installed packages from APPS_LIST_ASUS.
132		if((fp = fopen(APPS_LIST_ASUS, "r")) == NULL)
133			return apps_info_list;
134
135		fseek(fp, 0, SEEK_END);
136		file_size = ftell(fp);
137		fseek(fp, 0, SEEK_SET);
138		if(file_size <= 0){
139_dprintf("httpd: get the Zero size of the ASUS APP list.\n");
140			fclose(fp);
141			_eval(cmd, NULL, 0, &pid);
142			return apps_info_list;
143		}
144
145		memset(line, 0, sizeof(line));
146		while(fgets(line, 128, fp) != NULL){
147			if((tmp_apps_name = get_status_field(line, FIELD_PACKAGE)) == NULL)
148				continue;
149
150			memset(buf, 0, sizeof(buf));
151			pkg_tail = pkg_head = buf;
152			do{
153				sprintf(pkg_tail, "%s", line);
154				pkg_tail += strlen(line);
155
156				memset(line, 0, sizeof(line));
157			}while(fgets(line, 128, fp) != NULL && strlen(line) > 1);
158
159			follow_apps_info = apps_info_list;
160			got_apps = 0;
161			while(follow_apps_info != NULL){
162				if(!strcmp(follow_apps_info->name, tmp_apps_name)){
163					got_apps = 1;
164					break;
165				}
166
167				follow_apps_info = follow_apps_info->next;
168			}
169			free(tmp_apps_name);
170
171			// Installed package.
172			if(got_apps){
173				follow_apps_info->new_version = get_status_field(pkg_head, FIELD_VERSION);
174				follow_apps_info->new_optional_utility = get_status_field(pkg_head, FIELD_OPTIONALUTILITY);
175				follow_apps_info->new_file_name = get_status_field(pkg_head, FIELD_FILENAME);
176				if(follow_apps_info->from_owner != NULL)
177					free(follow_apps_info->from_owner);
178				follow_apps_info->from_owner = alloc_string(APP_OWNER_ASUS);
179			}
180			// Non-installed package.
181			else{
182				follow_apps_info_list = &apps_info_list;
183				while(*follow_apps_info_list != NULL)
184					follow_apps_info_list = &((*follow_apps_info_list)->next);
185
186				*follow_apps_info_list = initial_apps_data();
187
188				(*follow_apps_info_list)->name = get_status_field(pkg_head, FIELD_PACKAGE);
189				(*follow_apps_info_list)->new_version = get_status_field(pkg_head, FIELD_VERSION);
190				(*follow_apps_info_list)->installed = alloc_string(FIELD_NO);
191				(*follow_apps_info_list)->enabled = alloc_string(FIELD_NO);
192				(*follow_apps_info_list)->source = get_status_field(pkg_head, FIELD_SOURCE);
193				(*follow_apps_info_list)->url = get_status_field(pkg_head, FIELD_URL);
194				(*follow_apps_info_list)->description = get_status_field(pkg_head, FIELD_DESCRIPTION);
195				(*follow_apps_info_list)->depends = get_status_field(pkg_head, FIELD_DEPENDS);
196				(*follow_apps_info_list)->new_optional_utility = get_status_field(pkg_head, FIELD_OPTIONALUTILITY);
197				(*follow_apps_info_list)->help_path = get_status_field(pkg_head, FIELD_HELPPATH);
198				(*follow_apps_info_list)->new_file_name = get_status_field(pkg_head, FIELD_FILENAME);
199				(*follow_apps_info_list)->from_owner = alloc_string(APP_OWNER_ASUS);
200			}
201
202			memset(line, 0, sizeof(line));
203		}
204		fclose(fp);
205	}
206
207	if(!argv || strcmp(argv, APP_OWNER_ASUS)){
208		// Get the newest version of the installed packages,
209		// and information of the non-installed packages from APPS_LIST_OLEG.
210		if((fp = fopen(APPS_LIST_OLEG, "r")) == NULL)
211			return apps_info_list;
212
213		fseek(fp, 0, SEEK_END);
214		file_size = ftell(fp);
215		fseek(fp, 0, SEEK_SET);
216		if(file_size <= 0){
217_dprintf("httpd: get the Zero size of the third-party APP list.\n");
218			fclose(fp);
219			_eval(cmd, NULL, 0, &pid);
220			return apps_info_list;
221		}
222
223		memset(line, 0, sizeof(line));
224		while(fgets(line, 128, fp) != NULL){
225			if((tmp_apps_name = get_status_field(line, FIELD_PACKAGE)) == NULL)
226				continue;
227
228			memset(buf, 0, sizeof(buf));
229			pkg_tail = pkg_head = buf;
230			do{
231				sprintf(pkg_tail, "%s", line);
232				pkg_tail += strlen(line);
233
234				memset(line, 0, sizeof(line));
235			}while(fgets(line, 128, fp) != NULL && strlen(line) > 1);
236
237			follow_apps_info = apps_info_list;
238			got_apps = 0;
239			while(follow_apps_info != NULL){
240				if(!strcmp(follow_apps_info->name, tmp_apps_name)){
241					got_apps = 1;
242					break;
243				}
244
245				follow_apps_info = follow_apps_info->next;
246			}
247			free(tmp_apps_name);
248
249			// Installed package.
250			if(got_apps){
251				follow_apps_info->new_version = get_status_field(pkg_head, FIELD_VERSION);
252				follow_apps_info->new_optional_utility = get_status_field(pkg_head, FIELD_OPTIONALUTILITY);
253				if(follow_apps_info->from_owner != NULL)
254					free(follow_apps_info->from_owner);
255				follow_apps_info->from_owner = alloc_string(APP_OWNER_OLEG);
256			}
257			// Non-installed package.
258			else{
259				follow_apps_info_list = &apps_info_list;
260				while(*follow_apps_info_list != NULL)
261					follow_apps_info_list = &((*follow_apps_info_list)->next);
262
263				*follow_apps_info_list = initial_apps_data();
264
265				(*follow_apps_info_list)->name = get_status_field(pkg_head, FIELD_PACKAGE);
266				(*follow_apps_info_list)->new_version = get_status_field(pkg_head, FIELD_VERSION);
267				(*follow_apps_info_list)->installed = alloc_string(FIELD_NO);
268				(*follow_apps_info_list)->enabled = alloc_string(FIELD_NO);
269				(*follow_apps_info_list)->source = get_status_field(pkg_head, FIELD_SOURCE);
270				(*follow_apps_info_list)->url = get_status_field(pkg_head, FIELD_URL);
271				(*follow_apps_info_list)->description = get_status_field(pkg_head, FIELD_DESCRIPTION);
272				(*follow_apps_info_list)->depends = get_status_field(pkg_head, FIELD_DEPENDS);
273				(*follow_apps_info_list)->new_optional_utility = get_status_field(pkg_head, FIELD_OPTIONALUTILITY);
274				(*follow_apps_info_list)->help_path = get_status_field(pkg_head, FIELD_HELPPATH);
275				(*follow_apps_info_list)->new_file_name = get_status_field(pkg_head, FIELD_FILENAME);
276				(*follow_apps_info_list)->from_owner = alloc_string(APP_OWNER_OLEG);
277			}
278
279			memset(line, 0, sizeof(line));
280		}
281		fclose(fp);
282	}
283
284	// Get the name and version of the installed packages from APPS_STATUS.
285	if((fp = fopen(APPS_STATUS, "r")) == NULL)
286		return apps_info_list;
287
288	memset(line, 0, sizeof(line));
289	while(fgets(line, 128, fp) != NULL){
290		if((tmp_apps_name = get_status_field(line, FIELD_PACKAGE)) == NULL)
291			continue;
292
293		memset(buf, 0, sizeof(buf));
294		pkg_tail = pkg_head = buf;
295		do{
296			sprintf(pkg_tail, "%s", line);
297			pkg_tail += strlen(line);
298
299			memset(line, 0, sizeof(line));
300		}while(fgets(line, 128, fp) != NULL && strlen(line) > 1);
301
302		if((STATUS = get_status_field(pkg_head, FIELD_STATUS)) == NULL)
303			continue;
304		if(strstr(STATUS, "not-installed")){
305			free(STATUS);
306			continue;
307		}
308		free(STATUS);
309
310		follow_apps_info = apps_info_list;
311		got_apps = 0;
312		while(follow_apps_info != NULL){
313			if(!strcmp(follow_apps_info->name, tmp_apps_name)){
314				got_apps = 1;
315				break;
316			}
317
318			follow_apps_info = follow_apps_info->next;
319		}
320		free(tmp_apps_name);
321
322		// Installed package.
323		if(got_apps){
324			follow_apps_info->version = get_status_field(pkg_head, FIELD_VERSION);
325			if(follow_apps_info->installed != NULL)
326				free(follow_apps_info->installed);
327			follow_apps_info->installed = alloc_string(FIELD_YES);
328		}
329		// Non-installed package.
330		else if(!argv || !strcmp(argv, APP_OWNER_ALL)){
331			follow_apps_info_list = &apps_info_list;
332			while(*follow_apps_info_list != NULL)
333				follow_apps_info_list = &((*follow_apps_info_list)->next);
334
335			*follow_apps_info_list = initial_apps_data();
336
337			(*follow_apps_info_list)->name = get_status_field(pkg_head, FIELD_PACKAGE);
338			(*follow_apps_info_list)->version = get_status_field(pkg_head, FIELD_VERSION);
339			(*follow_apps_info_list)->installed = alloc_string(FIELD_YES);
340			(*follow_apps_info_list)->from_owner = alloc_string(APP_OWNER_OTHERS);
341		}
342
343		memset(line, 0, sizeof(line));
344	}
345	fclose(fp);
346
347	follow_apps_info = apps_info_list;
348	while(follow_apps_info != NULL){
349		// Get the source, description and depends of the installed packages from the control in APPS_INFO.
350		memset(info_name, 0, sizeof(info_name));
351		sprintf(info_name, "%s/%s.control", APPS_INFO, follow_apps_info->name);
352		apps_info = read_whole_file(info_name);
353		if(apps_info != NULL){
354			if((tmp_apps_name = get_status_field(apps_info, FIELD_ENABLED)) != NULL){
355				if(follow_apps_info->enabled != NULL)
356					free(follow_apps_info->enabled);
357				follow_apps_info->enabled = get_status_field(apps_info, FIELD_ENABLED);
358				free(tmp_apps_name);
359			}
360			follow_apps_info->optional_utility = get_status_field(apps_info, FIELD_OPTIONALUTILITY);
361
362			free(apps_info);
363		}
364
365		follow_apps_info = follow_apps_info->next;
366	}
367
368	return apps_info_list;
369}
370
371int printf_apps_info(const apps_info_t *follow_apps_info){
372	while(follow_apps_info != NULL){
373		apps_dbg("            name: %s.\n", follow_apps_info->name);
374		apps_dbg("         version: %s.\n", follow_apps_info->version);
375		apps_dbg("     new version: %s.\n", follow_apps_info->new_version);
376		apps_dbg("       installed: %s.\n", follow_apps_info->installed);
377		apps_dbg("         enabled: %s.\n", follow_apps_info->enabled);
378		apps_dbg("          source: %s.\n", follow_apps_info->source);
379		apps_dbg("             url: %s.\n", follow_apps_info->url);
380		apps_dbg("     description: %s.\n", follow_apps_info->description);
381		apps_dbg("         depends: %s.\n", follow_apps_info->depends);
382		apps_dbg("optional_utility: %s.\n", follow_apps_info->optional_utility);
383		apps_dbg("new_optional_utility: %s.\n", follow_apps_info->new_optional_utility);
384		apps_dbg("       help_path: %s.\n", follow_apps_info->help_path);
385		apps_dbg("   new_file_name: %s.\n", follow_apps_info->new_file_name);
386		apps_dbg("      from_owner: %s.\n\n", follow_apps_info->from_owner);
387
388		follow_apps_info = follow_apps_info->next;
389	}
390
391	return 0;
392}
393
394#ifdef APPS
395int main(int argc, char *argv[]){
396	apps_info_t *apps_info_list = get_apps_list(argv[1]);
397
398	printf_apps_info(apps_info_list);
399
400	free_apps_list(&apps_info_list);
401
402	return 0;
403}
404#endif
405#endif
406