398 lines
9.1 KiB
C
Executable File
398 lines
9.1 KiB
C
Executable File
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "upnpreplyparse.h"
|
|
#include "minixml.h"
|
|
|
|
static void
|
|
NameValueParserStartElt(void * d, const char * name, int l)
|
|
{
|
|
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
|
if(l>63)
|
|
l = 63;
|
|
memcpy(data->curelt, name, l);
|
|
data->curelt[l] = '\0';
|
|
}
|
|
|
|
static void
|
|
NameValueParserGetData(void * d, const char * datas, int l)
|
|
{
|
|
struct NameValueParserData * data = (struct NameValueParserData *)d;
|
|
struct NameValue * nv;
|
|
|
|
nv = malloc(sizeof(struct NameValue));
|
|
memset(nv, 0, sizeof(struct NameValue));
|
|
nv->value = (char *) malloc(l+1);
|
|
memset(nv->value, 0, l+1);
|
|
|
|
strncpy(nv->name, data->curelt, 64);
|
|
memcpy(nv->value, datas, l);
|
|
LIST_INSERT_HEAD( &(data->head), nv, entries);
|
|
}
|
|
|
|
void ParseNameValue(const char * buffer, int bufsize,
|
|
struct NameValueParserData * data)
|
|
{
|
|
struct xmlparser parser;
|
|
LIST_INIT(&(data->head));
|
|
/* init xmlparser object */
|
|
parser.xmlstart = buffer;
|
|
parser.xmlsize = bufsize;
|
|
parser.data = data;
|
|
parser.starteltfunc = NameValueParserStartElt;
|
|
parser.endeltfunc = 0;
|
|
parser.datafunc = NameValueParserGetData;
|
|
parser.attfunc = 0;
|
|
parsexml(&parser);
|
|
}
|
|
|
|
void ClearNameValueList(struct NameValueParserData * pdata)
|
|
{
|
|
struct NameValue * nv;
|
|
|
|
while((nv = pdata->head.lh_first) != NULL)
|
|
{
|
|
if (nv->value)
|
|
free(nv->value);
|
|
LIST_REMOVE(nv, entries);
|
|
free(nv);
|
|
}
|
|
}
|
|
|
|
char *
|
|
GetValueFromNameValueList(struct NameValueParserData * pdata,
|
|
const char * Name)
|
|
{
|
|
struct NameValue * nv;
|
|
char * p = NULL;
|
|
for(nv = pdata->head.lh_first;
|
|
(nv != NULL) && (p == NULL);
|
|
nv = nv->entries.le_next)
|
|
{
|
|
if(strcmp(nv->name, Name) == 0)
|
|
p = nv->value;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
char *
|
|
GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
|
|
const char * Name)
|
|
{
|
|
struct NameValue * nv;
|
|
char * p = NULL;
|
|
char * pname;
|
|
for(nv = pdata->head.lh_first;
|
|
(nv != NULL) && (p == NULL);
|
|
nv = nv->entries.le_next)
|
|
{
|
|
pname = strrchr(nv->name, ':');
|
|
if(pname)
|
|
pname++;
|
|
else
|
|
pname = nv->name;
|
|
if(strcmp(pname, Name)==0)
|
|
p = nv->value;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
/* debug all-in-one function
|
|
* do parsing then display to stdout */
|
|
void DisplayNameValueList(char * buffer, int bufsize)
|
|
{
|
|
struct NameValueParserData pdata;
|
|
struct NameValue * nv;
|
|
ParseNameValue(buffer, bufsize, &pdata);
|
|
for(nv = pdata.head.lh_first;
|
|
nv != NULL;
|
|
nv = nv->entries.le_next)
|
|
{
|
|
printf("%s = %s\n", nv->name, nv->value);
|
|
}
|
|
ClearNameValueList(&pdata);
|
|
}
|
|
|
|
/* MUST free the returned buffer after this call */
|
|
char *mini_UPnPGetFirstElement(char *file_start, unsigned int len, char *tag_name, unsigned int tag_name_len)
|
|
{
|
|
char * line;
|
|
unsigned long file_end;
|
|
unsigned long string_begin=0;
|
|
unsigned long string_end=0;
|
|
char *tag_name_first=NULL;
|
|
char *tag_name_second=NULL;
|
|
char *buf=NULL;
|
|
unsigned int string_len=0;
|
|
|
|
if (file_start == NULL || tag_name == NULL)
|
|
return NULL;
|
|
|
|
if (len <= 0 || tag_name_len <= 0)
|
|
return NULL;
|
|
|
|
tag_name_first = (char *)malloc(tag_name_len+3);
|
|
if (tag_name_first == NULL)
|
|
return NULL;
|
|
memcpy(tag_name_first+1, tag_name, tag_name_len);
|
|
tag_name_first[0] = '<';
|
|
tag_name_first[tag_name_len+1] = '>';
|
|
tag_name_first[tag_name_len+2] = 0;
|
|
|
|
tag_name_second = (char *)malloc(tag_name_len+4);
|
|
if (tag_name_second == NULL) {
|
|
free(tag_name_first);
|
|
return NULL;
|
|
}
|
|
memcpy(tag_name_second+2, tag_name, tag_name_len);
|
|
tag_name_second[0] = '<';
|
|
tag_name_second[1] = '/';
|
|
tag_name_second[tag_name_len+2] = '>';
|
|
tag_name_second[tag_name_len+3] = 0;
|
|
|
|
line = file_start;
|
|
file_end = (unsigned long)file_start + len;
|
|
while ((unsigned long)line < (file_end-tag_name_len-3))
|
|
{
|
|
if (strncasecmp(line, tag_name_first, tag_name_len+2) == 0) {
|
|
if (string_begin == 0) {
|
|
string_begin = (unsigned long)line + tag_name_len + 2;
|
|
}
|
|
else {
|
|
//DEBUG_ERR("Duplicated tag %s\n", tag_name_first);
|
|
free(tag_name_first);
|
|
free(tag_name_second);
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (strncasecmp(line, tag_name_second, tag_name_len+3) == 0) {
|
|
if (string_begin == 0) {
|
|
//DEBUG_ERR("Missing tag %s\n", tag_name_first);
|
|
free(tag_name_first);
|
|
free(tag_name_second);
|
|
return NULL;
|
|
}
|
|
else {
|
|
string_end = (unsigned long)line;
|
|
break;
|
|
}
|
|
}
|
|
|
|
line++;
|
|
}
|
|
|
|
free(tag_name_first);
|
|
free(tag_name_second);
|
|
if (string_begin < string_end) {
|
|
string_len = string_end - string_begin;
|
|
buf = (char *)malloc(string_len+1);
|
|
if (buf == NULL)
|
|
return NULL;
|
|
memcpy(buf, (char *)string_begin, string_len);
|
|
buf[string_len] = 0;
|
|
return buf;
|
|
}
|
|
else {
|
|
//DEBUG_ERR("XML parse erroe!\n");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
char *mini_UPnPGetFirstElementAndReturnAddr(char *file_start, unsigned int len, char *tag_name, unsigned int tag_name_len, char *buf)
|
|
{
|
|
char * line;
|
|
unsigned long file_end;
|
|
unsigned long string_begin=0;
|
|
unsigned long string_end=0;
|
|
char *tag_name_first=NULL;
|
|
char *tag_name_second=NULL;
|
|
unsigned int string_len=0;
|
|
char *end=NULL;
|
|
unsigned char found=0;
|
|
|
|
if (file_start == NULL || tag_name == NULL || buf == NULL)
|
|
return NULL;
|
|
|
|
if (len <= 0 || tag_name_len <= 0)
|
|
return NULL;
|
|
|
|
tag_name_first = (char *)malloc(tag_name_len+3);
|
|
if (tag_name_first == NULL)
|
|
return NULL;
|
|
memcpy(tag_name_first+1, tag_name, tag_name_len);
|
|
tag_name_first[0] = '<';
|
|
tag_name_first[tag_name_len+1] = '>';
|
|
tag_name_first[tag_name_len+2] = 0;
|
|
|
|
tag_name_second = (char *)malloc(tag_name_len+4);
|
|
if (tag_name_second == NULL) {
|
|
free(tag_name_first);
|
|
return NULL;
|
|
}
|
|
memcpy(tag_name_second+2, tag_name, tag_name_len);
|
|
tag_name_second[0] = '<';
|
|
tag_name_second[1] = '/';
|
|
tag_name_second[tag_name_len+2] = '>';
|
|
tag_name_second[tag_name_len+3] = 0;
|
|
|
|
line = file_start;
|
|
file_end = (unsigned long)file_start + len;
|
|
while ((unsigned long)line < (file_end-tag_name_len-3))
|
|
{
|
|
if (strncasecmp(line, tag_name_first, tag_name_len+2) == 0) {
|
|
if (string_begin == 0) {
|
|
string_begin = (unsigned long)line + tag_name_len + 2;
|
|
}
|
|
else {
|
|
//DEBUG_ERR("Duplicated tag %s\n", tag_name_first);
|
|
free(tag_name_first);
|
|
free(tag_name_second);
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (strncasecmp(line, tag_name_second, tag_name_len+3) == 0) {
|
|
if (string_begin == 0) {
|
|
//DEBUG_ERR("Missing tag %s\n", tag_name_first);
|
|
free(tag_name_first);
|
|
free(tag_name_second);
|
|
return NULL;
|
|
}
|
|
else {
|
|
string_end = (unsigned long)line;
|
|
end = (char *)(line + (tag_name_len+3));
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
line++;
|
|
}
|
|
|
|
free(tag_name_first);
|
|
free(tag_name_second);
|
|
if (string_begin < string_end) {
|
|
string_len = string_end - string_begin;
|
|
memcpy(buf, (char *)string_begin, string_len);
|
|
buf[string_len] = 0;
|
|
return end;
|
|
}
|
|
else {
|
|
if (found) {
|
|
buf[0] = 0;
|
|
return end;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
char *mini_UPnP_UploadXML(char *file_path)
|
|
{
|
|
FILE *fp = NULL;
|
|
int retVal = 0;
|
|
struct stat file_info;
|
|
char *buf=NULL;
|
|
unsigned int fileLen=0;
|
|
unsigned int num_read=0;
|
|
char *membuf=NULL;
|
|
|
|
buf = file_path;
|
|
retVal = stat(buf, &file_info );
|
|
if ( retVal == -1 ) {
|
|
//printf("Failed to get file info. EXITING\n");
|
|
return NULL;
|
|
}
|
|
|
|
fileLen = file_info.st_size;
|
|
if ( ( fp = fopen( buf, "rb" ) ) == NULL ) {
|
|
printf("Failed to open file [%s]. EXITING\n", buf);
|
|
return NULL;
|
|
}
|
|
|
|
if ( ( membuf = ( char * )malloc( fileLen + 1 ) ) == NULL ) {
|
|
fclose( fp );
|
|
printf("mini_UPnP_UploadXML Out of memory! EXITING\n");
|
|
return NULL;
|
|
}
|
|
|
|
num_read = fread( membuf, 1, fileLen, fp );
|
|
if ( num_read != fileLen ) {
|
|
fclose( fp );
|
|
free( membuf );
|
|
printf("mini_UPnP_UploadXML File length mismatched! EXITING\n");
|
|
return NULL;
|
|
}
|
|
|
|
membuf[fileLen] = 0;
|
|
fclose( fp );
|
|
|
|
return membuf;
|
|
}
|
|
|
|
char *get_token(char *data, char *token)
|
|
{
|
|
char *ptr=data;
|
|
int len=0, idx=0;
|
|
|
|
while (*ptr && *ptr != '\n' ) {
|
|
if (*ptr == '=') {
|
|
if (len <= 1)
|
|
return NULL;
|
|
memcpy(token, data, len);
|
|
|
|
/* delete ending space */
|
|
for (idx=len-1; idx>=0; idx--) {
|
|
if (token[idx] != ' ')
|
|
break;
|
|
}
|
|
token[idx+1] = '\0';
|
|
|
|
return ptr+1;
|
|
}
|
|
len++;
|
|
ptr++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int get_value(char *data, char *value)
|
|
{
|
|
char *ptr=data;
|
|
int len=0, idx, i;
|
|
|
|
while (*ptr && *ptr != '\n' && *ptr != '\r') {
|
|
len++;
|
|
ptr++;
|
|
}
|
|
|
|
/* delete leading space */
|
|
idx = 0;
|
|
while (len-idx > 0) {
|
|
if (data[idx] != ' ')
|
|
break;
|
|
idx++;
|
|
}
|
|
len -= idx;
|
|
|
|
/* delete bracing '"' */
|
|
if (data[idx] == '"') {
|
|
for (i=idx+len-1; i>idx; i--) {
|
|
if (data[i] == '"') {
|
|
idx++;
|
|
len = i - idx;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (len > 0) {
|
|
memcpy(value, &data[idx], len);
|
|
value[len] = '\0';
|
|
}
|
|
return len;
|
|
}
|
|
|