1/* $Id: testigddescparse.c,v 1.7 2014/11/17 19:28:20 nanard Exp $ */
2/* Project : miniupnp
3 * http://miniupnp.free.fr/
4 * Author : Thomas Bernard
5 * Copyright (c) 2008-2014 Thomas Bernard
6 * This software is subject to the conditions detailed in the
7 * LICENCE file provided in this distribution.
8 * */
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include "igd_desc_parse.h"
13#include "minixml.h"
14#include "miniupnpc.h"
15
16/* count number of differences */
17int compare_service(struct IGDdatas_service * s, FILE * f)
18{
19	int n = 0;
20	char line[1024];
21
22	while(fgets(line, sizeof(line), f)) {
23		char * value;
24		char * equal;
25		char * name;
26		char * parsedvalue;
27		int l;
28		l = strlen(line);
29		while((l > 0) && ((line[l-1] == '\r') || (line[l-1] == '\n') || (line[l-1] == ' ')))
30			line[--l] = '\0';
31		if(l == 0)
32			break;	/* end on blank line */
33		if(line[0] == '#')
34			continue;	/* skip comments */
35		equal = strchr(line, '=');
36		if(equal == NULL) {
37			fprintf(stderr, "Warning, line does not contain '=' : %s\n", line);
38			continue;
39		}
40		*equal = '\0';
41		name = line;
42		while(*name == ' ' || *name == '\t')
43			name++;
44		l = strlen(name);
45		while((l > 0) && (name[l-1] == ' ' || name[l-1] == '\t'))
46			name[--l] = '\0';
47		value = equal + 1;
48		while(*value == ' ' || *value == '\t')
49			value++;
50		if(strcmp(name, "controlurl") == 0)
51			parsedvalue = s->controlurl;
52		else if(strcmp(name, "eventsuburl") == 0)
53			parsedvalue = s->eventsuburl;
54		else if(strcmp(name, "scpdurl") == 0)
55			parsedvalue = s->scpdurl;
56		else if(strcmp(name, "servicetype") == 0)
57			parsedvalue = s->servicetype;
58		else {
59			fprintf(stderr, "unknown field '%s'\n", name);
60			continue;
61		}
62		if(0 != strcmp(parsedvalue, value)) {
63			fprintf(stderr, "difference : '%s' != '%s'\n", parsedvalue, value);
64			n++;
65		}
66	}
67	return n;
68}
69
70int compare_igd(struct IGDdatas * p, FILE * f)
71{
72	int n = 0;
73	char line[1024];
74	struct IGDdatas_service * s;
75
76	while(fgets(line, sizeof(line), f)) {
77		char * colon;
78		int l = (int)strlen(line);
79		while((l > 0) && (line[l-1] == '\r' || (line[l-1] == '\n')))
80			line[--l] = '\0';
81		if(l == 0 || line[0] == '#')
82			continue;	/* skip blank lines and comments */
83		colon = strchr(line, ':');
84		if(colon == NULL) {
85			fprintf(stderr, "Warning, no ':' : %s\n", line);
86			continue;
87		}
88		s = NULL;
89		*colon = '\0';
90		if(strcmp(line, "CIF") == 0)
91			s = &p->CIF;
92		else if(strcmp(line, "first") == 0)
93			s = &p->first;
94		else if(strcmp(line, "second") == 0)
95			s = &p->second;
96		else if(strcmp(line, "IPv6FC") == 0)
97			s = &p->IPv6FC;
98		else {
99			s = NULL;
100			fprintf(stderr, "*** unknown service '%s' ***\n", line);
101			n++;
102			continue;
103		}
104		n += compare_service(s, f);
105	}
106	if(n > 0)
107		fprintf(stderr, "*** %d difference%s ***\n", n, (n > 1) ? "s" : "");
108	return n;
109}
110
111int test_igd_desc_parse(char * buffer, int len, FILE * f)
112{
113	int n;
114	struct IGDdatas igd;
115	struct xmlparser parser;
116	struct UPNPUrls urls;
117
118	memset(&igd, 0, sizeof(struct IGDdatas));
119	memset(&parser, 0, sizeof(struct xmlparser));
120	parser.xmlstart = buffer;
121	parser.xmlsize = len;
122	parser.data = &igd;
123	parser.starteltfunc = IGDstartelt;
124	parser.endeltfunc = IGDendelt;
125	parser.datafunc = IGDdata;
126	parsexml(&parser);
127#ifdef DEBUG
128	printIGD(&igd);
129#endif /* DEBUG */
130	GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml", 0);
131	printf("ipcondescURL='%s'\n", urls.ipcondescURL);
132	printf("controlURL='%s'\n", urls.controlURL);
133	printf("controlURL_CIF='%s'\n", urls.controlURL_CIF);
134	n = f ? compare_igd(&igd, f) : 0;
135	FreeUPNPUrls(&urls);
136	return n;
137}
138
139int main(int argc, char * * argv)
140{
141	FILE * f;
142	char * buffer;
143	int len;
144	int r = 0;
145	if(argc<2) {
146		fprintf(stderr, "Usage: %s file.xml [file.values]\n", argv[0]);
147		return 1;
148	}
149	f = fopen(argv[1], "r");
150	if(!f) {
151		fprintf(stderr, "Cannot open %s for reading.\n", argv[1]);
152		return 1;
153	}
154	fseek(f, 0, SEEK_END);
155	len = ftell(f);
156	fseek(f, 0, SEEK_SET);
157	buffer = malloc(len);
158	fread(buffer, 1, len, f);
159	fclose(f);
160	f = NULL;
161	if(argc > 2) {
162		f = fopen(argv[2], "r");
163		if(!f) {
164			fprintf(stderr, "Cannot open %s for reading.\n", argv[2]);
165			return 1;
166		}
167	}
168	r = test_igd_desc_parse(buffer, len, f);
169	free(buffer);
170	if(f)
171		fclose(f);
172	return r;
173}
174
175