mem leak fix
This commit is contained in:
parent
1eb8f06cb6
commit
58ebfcc0fd
|
@ -1,3 +1,5 @@
|
||||||
|
2011-10-11 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
|
* Fixed mem leaks in mmsc uaprof module
|
||||||
2011-10-03 P. A. Bagyenda <bagyenda@dsmagic.com>
|
2011-10-03 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
* Fixed: compilation issue
|
* Fixed: compilation issue
|
||||||
2011-09-23 P. A. Bagyenda <bagyenda@dsmagic.com>
|
2011-09-23 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
|
|
|
@ -57,7 +57,7 @@ static void destroy_uaprof(MmsUaProfile *prof)
|
||||||
{
|
{
|
||||||
if (prof->versions)
|
if (prof->versions)
|
||||||
gwlist_destroy(prof->versions,
|
gwlist_destroy(prof->versions,
|
||||||
(gwlist_item_destructor_t *)octstr_destroy);
|
(gwlist_item_destructor_t *)octstr_destroy);
|
||||||
|
|
||||||
if (prof->ccppaccept.content) {
|
if (prof->ccppaccept.content) {
|
||||||
gwlist_destroy(prof->ccppaccept.content, (gwlist_item_destructor_t *)octstr_destroy);
|
gwlist_destroy(prof->ccppaccept.content, (gwlist_item_destructor_t *)octstr_destroy);
|
||||||
|
@ -68,7 +68,7 @@ static void destroy_uaprof(MmsUaProfile *prof)
|
||||||
gwlist_destroy(prof->ccppaccept.charset, (gwlist_item_destructor_t *)octstr_destroy);
|
gwlist_destroy(prof->ccppaccept.charset, (gwlist_item_destructor_t *)octstr_destroy);
|
||||||
gwlist_destroy(prof->ccppaccept._chash, NULL);
|
gwlist_destroy(prof->ccppaccept._chash, NULL);
|
||||||
} if (prof->ccppaccept.lang)
|
} if (prof->ccppaccept.lang)
|
||||||
gwlist_destroy(prof->ccppaccept.lang, (gwlist_item_destructor_t *)octstr_destroy);
|
gwlist_destroy(prof->ccppaccept.lang, (gwlist_item_destructor_t *)octstr_destroy);
|
||||||
if (prof->ccppaccept.enc)
|
if (prof->ccppaccept.enc)
|
||||||
gwlist_destroy(prof->ccppaccept.enc, (gwlist_item_destructor_t *)octstr_destroy);
|
gwlist_destroy(prof->ccppaccept.enc, (gwlist_item_destructor_t *)octstr_destroy);
|
||||||
|
|
||||||
|
@ -247,10 +247,10 @@ MmsUaProfile *mms_make_ua_profile(List *req_headers)
|
||||||
/* Put it in with the UA string as the key. */
|
/* Put it in with the UA string as the key. */
|
||||||
if (dict_put_once(profile_dict, ua, prof) != 1)
|
if (dict_put_once(profile_dict, ua, prof) != 1)
|
||||||
mms_warning(0, "mms_uaprof", NULL, "Duplicate cache entry(%s)?\n",
|
mms_warning(0, "mms_uaprof", NULL, "Duplicate cache entry(%s)?\n",
|
||||||
octstr_get_cstr(ua));
|
octstr_get_cstr(ua));
|
||||||
|
|
||||||
/* Done. Dump it while debugging. */
|
/* Done. Dump it while debugging. */
|
||||||
done:
|
done:
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
dump_profile(prof, ua ? ua : octstr_imm("<from http headers>"));
|
dump_profile(prof, ua ? ua : octstr_imm("<from http headers>"));
|
||||||
|
@ -300,34 +300,38 @@ static MmsUaProfile *parse_uaprofile(Octstr *xml)
|
||||||
if (xmlStrcasecmp(lnode->name, (const xmlChar *)"li") == 0) {
|
if (xmlStrcasecmp(lnode->name, (const xmlChar *)"li") == 0) {
|
||||||
unsigned char *t = xmlNodeListGetString(doc, lnode->xmlChildrenNode,1);
|
unsigned char *t = xmlNodeListGetString(doc, lnode->xmlChildrenNode,1);
|
||||||
if (t) {
|
if (t) {
|
||||||
gwlist_append(l, octstr_create((char *)t));
|
gwlist_append(l, octstr_create((char *)t));
|
||||||
xmlFree(t);
|
xmlFree(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
l = NULL;
|
l = NULL;
|
||||||
|
|
||||||
if (xmlStrcasecmp(xname, (const xmlChar *)"MmsMaxMessageSize") == 0)
|
if (xmlStrcasecmp(xname, (const xmlChar *)"MmsMaxMessageSize") == 0)
|
||||||
sscanf((char *)childtext, "%ld", &prof->maxmsgsize);
|
sscanf((char *)childtext, "%ld", &prof->maxmsgsize);
|
||||||
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsMaxImageResolution") == 0)
|
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsMaxImageResolution") == 0)
|
||||||
sscanf((char *)childtext, "%ldx%ld", &prof->maxres.x, &prof->maxres.y);
|
sscanf((char *)childtext, "%ldx%ld", &prof->maxres.x, &prof->maxres.y);
|
||||||
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptCharSet") == 0 ||
|
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptCharSet") == 0 ||
|
||||||
xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept-CharSet") == 0) {/* Cranky old ones! */
|
xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept-CharSet") == 0) {/* Cranky old ones! */
|
||||||
int i, n;
|
int i, n;
|
||||||
prof->ccppaccept.charset = l;
|
prof->ccppaccept.charset = l;
|
||||||
|
l = NULL; /* Avoid deletion below */
|
||||||
prof->ccppaccept._chash = gwlist_create();
|
prof->ccppaccept._chash = gwlist_create();
|
||||||
for (i = 0, n = gwlist_len(l); i<n; i++)
|
for (i = 0, n = gwlist_len(l); i<n; i++)
|
||||||
gwlist_append(prof->ccppaccept._chash, (void *)hash_key(gwlist_get(l, i)));
|
gwlist_append(prof->ccppaccept._chash, (void *)hash_key(gwlist_get(l, i)));
|
||||||
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptLanguage") == 0)
|
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptLanguage") == 0) {
|
||||||
prof->ccppaccept.lang = l;
|
prof->ccppaccept.lang = l;
|
||||||
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptEncoding") == 0)
|
l = NULL; /* Avoid deletion below */
|
||||||
|
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAcceptEncoding") == 0) {
|
||||||
prof->ccppaccept.enc = l;
|
prof->ccppaccept.enc = l;
|
||||||
else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsVersion") == 0) {
|
l = NULL; /* Avoid deletion below */
|
||||||
if (!l && childtext) { /* SonyEriccson uses old format! */
|
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsVersion") == 0) {
|
||||||
|
if (l == NULL && childtext) { /* SonyEriccson uses old format! */
|
||||||
l = gwlist_create();
|
l = gwlist_create();
|
||||||
gwlist_append(l, octstr_create((char *)childtext));
|
gwlist_append(l, octstr_create((char *)childtext));
|
||||||
}
|
}
|
||||||
prof->versions = l;
|
prof->versions = l;
|
||||||
|
l = NULL; /* Avoid deletion below */
|
||||||
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept") == 0) {
|
} else if (xmlStrcasecmp(xname, (const xmlChar *)"MmsCcppAccept") == 0) {
|
||||||
int i, n;
|
int i, n;
|
||||||
prof->ccppaccept.content = l;
|
prof->ccppaccept.content = l;
|
||||||
|
@ -342,11 +346,13 @@ static MmsUaProfile *parse_uaprofile(Octstr *xml)
|
||||||
|
|
||||||
gwlist_append(prof->ccppaccept._hash, (void *)hash_key(x));
|
gwlist_append(prof->ccppaccept._hash, (void *)hash_key(x));
|
||||||
}
|
}
|
||||||
|
l = NULL; /* Avoid deletion below */
|
||||||
}
|
}
|
||||||
if (childtext) xmlFree(childtext);
|
if (childtext) xmlFree(childtext);
|
||||||
|
gwlist_destroy(l, (void *)octstr_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (doc) xmlFreeDoc(doc);
|
if (doc) xmlFreeDoc(doc);
|
||||||
return prof;
|
return prof;
|
||||||
}
|
}
|
||||||
|
@ -371,7 +377,7 @@ static int mms_load_ua_profile_cache(char *dir)
|
||||||
|
|
||||||
if (!dirp) {
|
if (!dirp) {
|
||||||
mms_error(0, "mms_uaprof", NULL, "Failed to open UA prof cache directory %s",
|
mms_error(0, "mms_uaprof", NULL, "Failed to open UA prof cache directory %s",
|
||||||
dir);
|
dir);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +398,7 @@ static int mms_load_ua_profile_cache(char *dir)
|
||||||
octstr_destroy(fname);
|
octstr_destroy(fname);
|
||||||
if (!xml) {
|
if (!xml) {
|
||||||
mms_error(0, "mms_uaprof", NULL, "Failed to read UA prof doc %s in %s (%s)\n",
|
mms_error(0, "mms_uaprof", NULL, "Failed to read UA prof doc %s in %s (%s)\n",
|
||||||
dp->d_name, dir, strerror(errno));
|
dp->d_name, dir, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,7 +413,7 @@ static int mms_load_ua_profile_cache(char *dir)
|
||||||
|
|
||||||
if (dict_put_once(profile_dict, key, prof) != 1)
|
if (dict_put_once(profile_dict, key, prof) != 1)
|
||||||
mms_warning(0, "mms_uaprof", NULL, "Duplicate cache entry(%s)?\n",
|
mms_warning(0, "mms_uaprof", NULL, "Duplicate cache entry(%s)?\n",
|
||||||
octstr_get_cstr(key));
|
octstr_get_cstr(key));
|
||||||
#if 1
|
#if 1
|
||||||
dump_profile(prof, key);
|
dump_profile(prof, key);
|
||||||
#endif
|
#endif
|
||||||
|
@ -446,7 +452,7 @@ static MmsUaProfile *profile_fetch(Octstr *profile_url)
|
||||||
if (prof) {
|
if (prof) {
|
||||||
if (dict_put_once(profile_dict, profile_url, prof) != 1)
|
if (dict_put_once(profile_dict, profile_url, prof) != 1)
|
||||||
mms_warning(0, "mms_uaprof", NULL, "Duplicate ua profile fetched? (%s)?\n",
|
mms_warning(0, "mms_uaprof", NULL, "Duplicate ua profile fetched? (%s)?\n",
|
||||||
octstr_get_cstr(profile_url));
|
octstr_get_cstr(profile_url));
|
||||||
else {
|
else {
|
||||||
Octstr *fname;
|
Octstr *fname;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
@ -461,12 +467,12 @@ static MmsUaProfile *profile_fetch(Octstr *profile_url)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
} else
|
} else
|
||||||
mms_error(0, "mms_uaprof", NULL, "Failed to save profile data to cache file %s->%s\n",
|
mms_error(0, "mms_uaprof", NULL, "Failed to save profile data to cache file %s->%s\n",
|
||||||
octstr_get_cstr(fname), strerror(errno));
|
octstr_get_cstr(fname), strerror(errno));
|
||||||
octstr_destroy(fname);
|
octstr_destroy(fname);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
mms_error(0, "mms_uaprof", NULL, "Failed to parse UA prof url=%s\n",
|
mms_error(0, "mms_uaprof", NULL, "Failed to parse UA prof url=%s\n",
|
||||||
octstr_get_cstr(profile_url));
|
octstr_get_cstr(profile_url));
|
||||||
} else
|
} else
|
||||||
prof = NULL;
|
prof = NULL;
|
||||||
|
|
||||||
|
@ -487,7 +493,7 @@ int mms_start_profile_engine(char *cache_dir)
|
||||||
|
|
||||||
profile_dir = octstr_create(cache_dir);
|
profile_dir = octstr_create(cache_dir);
|
||||||
|
|
||||||
if (!profile_dict)
|
if (!profile_dict)
|
||||||
profile_dict = dict_create(UACOUNT_PROFILE,
|
profile_dict = dict_create(UACOUNT_PROFILE,
|
||||||
(void (*)(void *))destroy_uaprof);
|
(void (*)(void *))destroy_uaprof);
|
||||||
init_format_table();
|
init_format_table();
|
||||||
|
@ -539,10 +545,10 @@ struct {
|
||||||
int multi_image; /* whether this format allows for multiple images in one file. */
|
int multi_image; /* whether this format allows for multiple images in one file. */
|
||||||
enum {TIMAGE=1,TAUDIO,TTEXT,TPRES,TOTHER} t;
|
enum {TIMAGE=1,TAUDIO,TTEXT,TPRES,TOTHER} t;
|
||||||
} cformats[] = {
|
} cformats[] = {
|
||||||
/* Note: Order of listing matters:
|
/* Note: Order of listing matters:
|
||||||
* For images, we prefer jpeg (smaller, better support),
|
* For images, we prefer jpeg (smaller, better support),
|
||||||
* For audio we prefer MP3 (smaller, well supported).
|
* For audio we prefer MP3 (smaller, well supported).
|
||||||
*/
|
*/
|
||||||
{"image/jpeg", 0, "jpegtopnm", "pnmtojpeg", "jpg", 0, TIMAGE},
|
{"image/jpeg", 0, "jpegtopnm", "pnmtojpeg", "jpg", 0, TIMAGE},
|
||||||
{"image/png", 0, "pngtopnm ", "pnmtopng ", "png", 0, TIMAGE},
|
{"image/png", 0, "pngtopnm ", "pnmtopng ", "png", 0, TIMAGE},
|
||||||
{"image/jpg", 0, "jpegtopnm", "pnmtojpeg", "jpg", 0, TIMAGE},
|
{"image/jpg", 0, "jpegtopnm", "pnmtojpeg", "jpg", 0, TIMAGE},
|
||||||
|
@ -825,7 +831,7 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
|
||||||
goto done; /* No further processing for text/plain. */
|
goto done; /* No further processing for text/plain. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find out if it is supported by the user agent. */
|
/* find out if it is supported by the user agent. */
|
||||||
chash = hash_key(content_type);
|
chash = hash_key(content_type);
|
||||||
if (prof->ccppaccept.all) /* Check if it accepts all content types. */
|
if (prof->ccppaccept.all) /* Check if it accepts all content types. */
|
||||||
supported = 1;
|
supported = 1;
|
||||||
|
@ -904,7 +910,7 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
|
||||||
|
|
||||||
/* Get the image dimensions, see if we need to modify it. */
|
/* Get the image dimensions, see if we need to modify it. */
|
||||||
icmd = octstr_format(IMGRESCMD,
|
icmd = octstr_format(IMGRESCMD,
|
||||||
cformats[iindex].file_ext, tmpf2);
|
cformats[iindex].file_ext, tmpf2);
|
||||||
|
|
||||||
pf = popen(octstr_get_cstr(icmd), "r");
|
pf = popen(octstr_get_cstr(icmd), "r");
|
||||||
octstr_destroy(icmd);
|
octstr_destroy(icmd);
|
||||||
|
@ -918,9 +924,9 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
|
||||||
if (x > prof->maxres.x ||
|
if (x > prof->maxres.x ||
|
||||||
y > prof->maxres.y)
|
y > prof->maxres.y)
|
||||||
icmd = octstr_format(IMGSCALECMD, prof->maxres.x, prof->maxres.y,
|
icmd = octstr_format(IMGSCALECMD, prof->maxres.x, prof->maxres.y,
|
||||||
cformats[iindex].file_ext,
|
cformats[iindex].file_ext,
|
||||||
tmpf2,
|
tmpf2,
|
||||||
cformats[iindex].file_ext);
|
cformats[iindex].file_ext);
|
||||||
else if (supported) /* A supported image format and no need to scale, so go away. */
|
else if (supported) /* A supported image format and no need to scale, so go away. */
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -946,9 +952,9 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
|
||||||
|
|
||||||
send_data = 0;
|
send_data = 0;
|
||||||
} else {/* Type is audio. */
|
} else {/* Type is audio. */
|
||||||
cmd = octstr_format("%s | %s > %s",
|
cmd = octstr_format("%s | %s > %s",
|
||||||
cformats[iindex].tostandard_cmd,
|
cformats[iindex].tostandard_cmd,
|
||||||
cformats[oindex].fromstandard_cmd, tmpf);
|
cformats[oindex].fromstandard_cmd, tmpf);
|
||||||
send_data = 1;
|
send_data = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,10 +983,10 @@ static int modify_msg(MIMEEntity *msg, MmsUaProfile *prof)
|
||||||
} else /* failed to convert, hence unsupported. */
|
} else /* failed to convert, hence unsupported. */
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (h)
|
if (h)
|
||||||
mime_replace_headers(msg,h);
|
mime_replace_headers(msg,h);
|
||||||
done2:
|
done2:
|
||||||
if (!supported)
|
if (!supported)
|
||||||
remove_object(msg, content_type);
|
remove_object(msg, content_type);
|
||||||
|
|
||||||
|
@ -1163,7 +1169,7 @@ static int format_special(MIMEEntity *m,
|
||||||
else if (octstr_case_search(ctype, octstr_imm("audio/"), 0) == 0)
|
else if (octstr_case_search(ctype, octstr_imm("audio/"), 0) == 0)
|
||||||
octstr_format_append(btxt,
|
octstr_format_append(btxt,
|
||||||
"<embed src=\"cid:%S\" >%S</embed><br><br>\n",
|
"<embed src=\"cid:%S\" >%S</embed><br><br>\n",
|
||||||
cidurl, ctype, pname);
|
cidurl, ctype, pname);
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
octstr_format_append(btxt,
|
octstr_format_append(btxt,
|
||||||
|
@ -1231,7 +1237,7 @@ static int format_special(MIMEEntity *m,
|
||||||
h2 = http_create_empty_headers();
|
h2 = http_create_empty_headers();
|
||||||
http_header_add(h2, "Content-Type", "text/html");
|
http_header_add(h2, "Content-Type", "text/html");
|
||||||
tmp = octstr_format("<html><body><center>%s<hr><br>%S<hr></center></body></html>\n",
|
tmp = octstr_format("<html><body><center>%s<hr><br>%S<hr></center></body></html>\n",
|
||||||
htmlmsg ? htmlmsg : "", btxt);
|
htmlmsg ? htmlmsg : "", btxt);
|
||||||
|
|
||||||
mime_replace_headers(x, h2);
|
mime_replace_headers(x, h2);
|
||||||
mime_entity_set_body(x,tmp);
|
mime_entity_set_body(x,tmp);
|
||||||
|
@ -1322,7 +1328,7 @@ static int format_special(MIMEEntity *m,
|
||||||
Octstr *s;
|
Octstr *s;
|
||||||
if (charset == NULL ||
|
if (charset == NULL ||
|
||||||
octstr_case_compare(charset, octstr_imm("unknown")) == 0 ||
|
octstr_case_compare(charset, octstr_imm("unknown")) == 0 ||
|
||||||
octstr_case_compare(charset, octstr_imm(DEFAULT_CHARSET)) == 0) {
|
octstr_case_compare(charset, octstr_imm(DEFAULT_CHARSET)) == 0) {
|
||||||
if (charset) octstr_destroy(charset);
|
if (charset) octstr_destroy(charset);
|
||||||
goto done; /* Nothing more to do here. */
|
goto done; /* Nothing more to do here. */
|
||||||
}
|
}
|
||||||
|
@ -1346,7 +1352,7 @@ static int format_special(MIMEEntity *m,
|
||||||
octstr_destroy(s);
|
octstr_destroy(s);
|
||||||
} /* Else do nothing. */
|
} /* Else do nothing. */
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
if (headers) {
|
if (headers) {
|
||||||
mime_replace_headers(m, headers);
|
mime_replace_headers(m, headers);
|
||||||
|
@ -1366,9 +1372,9 @@ static int format_special(MIMEEntity *m,
|
||||||
}
|
}
|
||||||
|
|
||||||
int mms_format_special(MmsMsg *inmsg,
|
int mms_format_special(MmsMsg *inmsg,
|
||||||
int trans_smil,
|
int trans_smil,
|
||||||
char *txtmsg,
|
char *txtmsg,
|
||||||
char *htmlmsg, MIMEEntity **outmsg)
|
char *htmlmsg, MIMEEntity **outmsg)
|
||||||
{
|
{
|
||||||
MIMEEntity *m = mms_tomime(inmsg,0);
|
MIMEEntity *m = mms_tomime(inmsg,0);
|
||||||
int ct = 0;
|
int ct = 0;
|
||||||
|
|
|
@ -2907,13 +2907,14 @@ void get_content_from_sendmms_request(Octstr *body, List *headers, List *cgivars
|
||||||
{
|
{
|
||||||
Octstr *s;
|
Octstr *s;
|
||||||
/* Now get the data. */
|
/* Now get the data. */
|
||||||
if ((*data = http_cgi_variable(cgivars, "text")) != NULL) { /* text. */
|
if ((s = http_cgi_variable(cgivars, "text")) != NULL) { /* text. */
|
||||||
Octstr *charset = http_cgi_variable(cgivars, "charset");
|
Octstr *charset = http_cgi_variable(cgivars, "charset");
|
||||||
|
|
||||||
*ctype = octstr_format("text/plain");
|
*ctype = octstr_format("text/plain");
|
||||||
if (charset)
|
if (charset)
|
||||||
octstr_format_append(*ctype, "; charset=%S", charset);
|
octstr_format_append(*ctype, "; charset=%S", charset);
|
||||||
} else if ((s = http_cgi_variable(cgivars, "smil")) != NULL) { /* smil. */
|
*data = octstr_duplicate(s);
|
||||||
|
} else if ((s = http_cgi_variable(cgivars, "smil")) != NULL) { /* smil. */
|
||||||
*ctype = octstr_create("application/smil");
|
*ctype = octstr_create("application/smil");
|
||||||
*data = octstr_duplicate(s);
|
*data = octstr_duplicate(s);
|
||||||
} else if ((s = http_cgi_variable(cgivars, "content-url")) != NULL) { /* arbitrary content. */
|
} else if ((s = http_cgi_variable(cgivars, "content-url")) != NULL) { /* arbitrary content. */
|
||||||
|
|
Loading…
Reference in New Issue