Files
Aldo Vargas 7e9e43606e webMAN MOD 1.47.45
- Added support for persistent custom popup notification using /popup.ps3$text (issue #895)
- Fixed warning in ps3mapi.h on lite edition
- Changed source for covers in ps2 config database
2023-06-24 18:40:43 -04:00

498 lines
14 KiB
C

#define HTML_RECV_SIZE 2048
#define HTML_RECV_LAST 2047
#define ORANGE 0xf90
#define MAGENTA 0xf0f
#define CYAN 0x0ff
static char html_base_path[HTML_RECV_SIZE]; // used as temporary buffer
#define custom_popup_msg (html_base_path + 1845)
#define ITEM_CHECKED " checked=\"checked\""
#define ITEM_SELECTED " selected=\"selected\""
#define IS_MARKED(key) (strstr(param, key) != NULL)
#define IS_UNMARKED(key) (!strstr(param, key))
#define HTML_REFRESH "<meta http-equiv=\"refresh\" content=\""
#define HTML_URL "<a href=\"%s\">%s</a>"
#define HTML_URL2 "<a href=\"%s%s\">%s</a>"
#define HTML_URL_STYLE "color:#ccc;text-decoration:none;"
#define HTML_DIR "&lt;dir>"
#define HTML_BUTTON_FMT "%s%s\" %s'%s';\">"
#define HTML_BUTTON_FMT2 "%s%s\" %s'%s%s';\">"
#define HTML_BUTTON " <input type=\"button\" value=\""
#define HTML_ONCLICK "onclick=\"location.href="
#define HTML_ONCLICK2 "onclick=\"var req=new XMLHttpRequest();req.open('GET',"
#define HTML_SEND_CMD "',true);req.send();return'"
#define HTML_INPUT(n, v, m, s) "<input name=\"" n "\" type=\"text\" value=\"" v "\" maxlength=\"" m "\" size=\"" s "\">"
#define HTML_PASSW(n, v, m, s) "<input name=\"" n "\" type=\"password\" value=\"" v "\" maxlength=\"" m "\" size=\"" s "\">"
#define HTML_NUMBER(n, v, min, max) "<input name=\"" n "\" type=\"number\" value=\"" v "\" min=\"" min "\" max=\"" max "\" style=\"width:45px;\">"
#define HTML_PORT(n, v) "<input name=\"" n "\" type=\"number\" value=\"" v "\" min=\"1\" max=\"65535\" style=\"width:60px;\">"
#define HTML_DISABLED_CHECKBOX "disabled"
#define HTML_FORM_METHOD_FMT(a) "<form action=\"" a "%s"
#define HTML_FORM_METHOD ".ps3mapi\" method=\"get\" enctype=\"application/x-www-form-urlencoded\" target=\"_self\">"
#define HTML_ENTRY_DATE " &nbsp; " \
"<td>11-Nov-2006 11:11"
#define _BR_ NULL
#define HTML_RESPONSE_FMT "HTTP/1.1 %i OK\r\n" \
"X-PS3-Info: [%s]\r\n" \
"Content-Type: text/html;charset=UTF-8\r\n" \
"Cache-Control: no-cache\r\n" \
"\r\n" \
"%s%s%s"
#define HTML_HEADER " <!DOCTYPE html>" \
"<html xmlns=\"http://www.w3.org/1999/xhtml\">" \
"<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">" \
"<meta http-equiv=\"Cache-Control\" content=\"no-cache\">" \
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=0.6,maximum-scale=1.0\">" /* size: 264 */
#define HTML_RESPONSE_TITLE WM_APP_VERSION EDITION "<hr><h2>"
#define HTML_BODY "<body bgcolor=\"#101010\" text=\"#c0c0c0\">" \
"<font face=\"Courier New\">" /* size: 64 */
#define HTML_BODY_END "</font></body></html>" /* size: 21 */
#define HTML_BLU_SEPARATOR "<hr color=\"blue\"/>"
#define HTML_RED_SEPARATOR "<hr color=\"red\"/>"
#define SCRIPT_SRC_FMT "<script src=\"%s\"></script>"
#define HTML_REDIRECT_TO_URL "<script>setTimeout(function(){self.location=\"%s\"},%i);</script>"
#define HTML_REDIRECT_TO_BACK "<script>history.back();</script>"
#define HTML_CLOSE_BROWSER "<script>window.close(this);</script>"
#define HTML_REDIRECT_WAIT 3000
#define HTML_TOGGLER HTML_BLU_SEPARATOR "<b><a class=\"tg\" href=\"javascript:tgl("
#define HTML_SHOW_LAST_GAME "<span style=\"position:absolute;right:8px\"><font size=2>"
#define HTML_SHOW_LAST_GAME_END "</font></span>"
static void open_browser(const char *url, int mode)
{
int is_ingame = View_Find("game_plugin");
if(is_ingame)
{
game_interface = (game_plugin_interface *)plugin_GetInterface(is_ingame, 1);
game_interface->wakeupWithGameExit((char*)url, 1);
}
else
{
vshmain_AE35CF2D((char*)url, mode); // xmb_plugin->Function 23
}
}
static void urldec(char *url, char *original)
{
if(!url) return;
if(strchr(url, '+') || strchr(url, '%'))
{
if(original) strcpy(original, url); // return original url
u16 pos = 0;
for(u16 i = 0; url[i] >= ' '; i++, pos++)
{
if(url[i] == '+')
url[pos] = ' ';
else if(url[i] != '%')
url[pos] = url[i];
else
{
url[pos] = 0; u8 n = 2; if(url[i+1]=='u') {i++, n+=2;}
while(n--)
{
url[pos] <<= 4, url[pos] += h2b(url[++i]);
}
}
}
url[pos] = '\0';
}
}
static bool urlenc_ex(char *dst, const char *src, bool gurl)
{
if(!src || !dst) return false;
u16 i, j = 0, pos = 0, max_len = gurl ? HTML_RECV_LAST : MAX_PATH_LEN;
if(islike(src, "http") && (src[4] == ':' || src[5] == ':') && (src[6] == '/') && src[7]) { for(i = 8; src[i]; i++) if(src[i] == '/') {pos = i; break;} }
#ifdef USE_NTFS
if(islike(src + pos, "/dev_nt")) pos += 11;
#endif
for(i = 0; src[i]; i++, j++)
{
if(j >= max_len) {j = max_len; break;}
if((unsigned char)src[i] & 0x80)
{
dst[j++] = '%';
dst[j++] = h2a((unsigned char)src[i]>>4);
dst[j] = h2a(src[i] & 0xf);
}
else if((src[i]=='?' || ((src[i]==':') && (i >= pos))) && gurl)
{
dst[j++] = '%';
dst[j++] = '3';
dst[j] = h2a(src[i] & 0xf);
}
else if(src[i]==' ')
dst[j] = '+';
else if(src[i]=='\'' || src[i]=='"' || src[i]=='%' || src[i]=='&' || src[i]=='+' || src[i]=='#')
{
dst[j++] = '%';
dst[j++] = '2';
dst[j] = h2a(src[i] & 0xf);
}
else
dst[j] = src[i];
}
dst[j] = '\0';
return (j > i); // true if dst != src
}
static bool urlenc(char *dst, const char *src)
{
return urlenc_ex(dst, src, true);
}
static size_t htmlenc(char *dst, char *src, u8 cpy2src)
{
if(!src || !dst) return 0;
size_t j = 0;
char tmp[10]; u8 t, c;
for(size_t i = 0; src[i]; i++)
{
if((unsigned char)src[i] >= 0x7F || (unsigned char)src[i] < 0x20)
{
t = sprintf(tmp, "&#x%X;", (unsigned char)src[i]); c = 0;
while(t--) {dst[j++] = tmp[c++];}
}
else dst[j++] = src[i];
}
j = MIN(j, MAX_LINE_LEN);
dst[j] = '\0';
if(cpy2src) strcpy(src, dst);
return j;
}
static size_t utf8enc(char *dst, char *src, u8 cpy2src)
{
if(!src || !dst) return 0;
size_t j = 0; unsigned int c;
for(size_t i = 0; src[i]; i++)
{
c = (unsigned char)src[i];
if(c <= 0x7F)
dst[j++] = c;
else { if(c <= 0x07FF) {
dst[j++] = 0xC0 | (c>>06);
} else { if(c <= 0xFFFF) {
dst[j++] = 0xE0 | (0x0F & (c>>12));
} else { if(c <= 0x1FFFFF) {
dst[j++] = 0xF0 | (0x0F & (c>>18));
} else { if(c <= 0x3FFFFFF) {
dst[j++] = 0xF8 | (0x0F & (c>>24));
} else { if(c <= 0x7FFFFFFF) {
dst[j++] = 0xFC | (0x0F & (c>>30));
dst[j++] = 0x80 | (0x3F & (c>>24)); }
} dst[j++] = 0x80 | (0x3F & (c>>18)); }
dst[j++] = 0x80 | (0x3F & (c>>12)); }
dst[j++] = 0x80 | (0x3F & (c>>06)); }
dst[j++] = 0x80 | (0x3F & c); }
}
j = MIN(j, MAX_LINE_LEN);
dst[j] = '\0';
if(cpy2src) strcpy(src, dst);
return j;
}
/*
static size_t utf8dec(char *dst, char *src, u8 cpy2src)
{
size_t j = 0;
unsigned char c;
for(size_t i = 0; src[i]; i++, j++)
{
c = (unsigned char)src[i];
if( (c & 0x80) == 0 )
{
dst[j] = c;
}
else if( (c & 0xE0) == 0xC0 )
{
dst[j] = ((c & 0x1F)<<6) |
(src[i+1] & 0x3F);
i+=1;
}
else if( (c & 0xF0) == 0xE0 )
{
dst[j] = ((c & 0xF)<<12);
dst[j] |= ((src[i+1] & 0x3F)<<6);
dst[j] |= ((src[i+2] & 0x3F));
i+=2;
}
else if ( (c & 0xF8) == 0xF0 )
{
dst[j] = ((c & 0x7)<<18);
dst[j] |= ((src[i+1] & 0x3F)<<12);
dst[j] |= ((src[i+2] & 0x3F)<<06);
dst[j] |= ((src[i+3] & 0x3F));
i+=3;
}
else if ( (c & 0xFC) == 0xF8 )
{
dst[j] = ((c & 0x3)<<24);
dst[j] |= ((src[i+1] & 0x3F)<<18);
dst[j] |= ((src[i+2] & 0x3F)<<12);
dst[j] |= ((src[i+3] & 0x3F)<<06);
dst[j] |= ((src[i+4] & 0x3F));
i+=4;
}
else if ( (c & 0xFE) == 0xFC )
{
dst[j] = ((c & 0x1)<<30);
dst[j] |= ((src[i+1] & 0x3F)<<24);
dst[j] |= ((src[i+2] & 0x3F)<<18);
dst[j] |= ((src[i+3] & 0x3F)<<12);
dst[j] |= ((src[i+4] & 0x3F)<<06);
dst[j] |= ((src[i+5] & 0x3F));
i+=5;
}
}
j = MIN(j, MAX_LINE_LEN);
dst[j] = '\0';
if(cpy2src) strcpy(src, dst);
return j;
}
*/
static void add_url(char *body, const char *prefix, const char *url, const char *sufix)
{
if(!body) return;
if(prefix) concat(body, prefix);
if(url) concat(body, url);
if(sufix) concat(body, sufix);
}
static void add_html(u8 id, int value, char *buffer, char *templn)
{
if(!buffer || !templn) return;
char res_file[40];
sprintf(res_file, "%s/setup/setup%c.dat", WM_RES_PATH, id);
read_file(res_file, templn, 1023, 0);
char *pos = strstr(templn, " ");
if(pos)
{
if((id == 'a') || (id == 'v'))
sprintf(res_file, "%04x", value);
else
sprintf(res_file, "%04i", value);
memcpy(pos, res_file, 4);
}
concat(buffer, templn);
}
static size_t add_radio_button(const char *name, int value, const char *id, const char *label, const char *sufix, bool checked, char *buffer)
{
if(!buffer || !label) return 0;
char templn[MAX_LINE_LEN];
sprintf(templn, "<label><input type=\"radio\" name=\"%s\" value=\"%i\" id=\"%s\"%s/> %s%s</label>", name, value, id, checked ? ITEM_CHECKED : "", label, (sufix) ? sufix : "<br>");
return concat(buffer, templn);
}
static size_t add_check_box(const char *name, bool disabled, const char *label, const char *sufix, bool checked, char *buffer)
{
if(!buffer || !label) return 0;
char templn[MAX_LINE_LEN];
const char *pos = strstr(label, AUTOBOOT_PATH), *clabel = label;
if(pos)
{
char *autob = templn + 100; clabel = autob;
int n = (pos - label); strcpy(autob, label); // prefix
const char *on_startup = pos + strlen(AUTOBOOT_PATH); // sufix
sprintf(autob + n, HTML_INPUT("autop", "%s", "255", "40") "%s", webman_config->autoboot_path, on_startup);
}
sprintf(templn, "<label><input type=\"checkbox\" name=\"%s\" value=\"1\" %s%s/> %s</label>%s", name, disabled ? HTML_DISABLED_CHECKBOX : "", checked ? ITEM_CHECKED : "", clabel, (!sufix) ? "<br>" : sufix);
return concat(buffer, templn);
}
static size_t add_checkbox(const char *name, const char *label, const char *sufix, bool checked, char *buffer)
{
return add_check_box(name, false, label, sufix, checked, buffer);
}
static size_t add_checkbox_line(const char *name, const char *label, bool checked, char *buffer)
{
return add_checkbox(name, label, _BR_, checked, buffer);
}
static size_t add_option_item(int value, const char *label, bool selected, char *buffer)
{
char templn[MAX_LINE_LEN], svalue[20];
if(value >= 0x1000) sprintf(svalue, "0x%x", value); else sprintf(svalue, "%i", value);
sprintf(templn, "<option value=\"%s\"%s/>%s", svalue, selected ? ITEM_SELECTED : "", label);
return concat(buffer, templn);
}
#if defined(VIDEO_REC) || defined(USE_UACCOUNT)
//static size_t add_string_item(const char *value, const char *label, bool selected, char *buffer)
//{
// char templn[MAX_LINE_LEN];
// sprintf(templn, "<option value=\"%s\"%s/>%s", value, selected ? ITEM_SELECTED : "", label);
// return concat(buffer, templn);
//}
#endif
static size_t prepare_header(char *buffer, const char *param, u8 is_binary)
{
if(!buffer || !param) return 0;
bool set_base_path = false;
size_t slen = sprintf(buffer, "HTTP/1.1 200 OK\r\n"
"%s"
"Content-Type: ",
webman_config->bind ? "" : // disallow CORS if bind (remote access to FTP/WWW services) is disabled
"Access-Control-Allow-Origin: *\r\n"); // default: allow CORS (Cross-Origin Resource Sharing)
t_string header; _set(&header, buffer, slen);
// get mime type
if(is_binary == BINARY_FILE)
{
const char *ext = get_ext(param);
if(_IS(ext, ".png"))
_concat2(&header, "image/", "png");
else
if(_IS(ext, ".jpg") || _IS(ext, ".jpeg") || IS(ext, ".STH"))
_concat2(&header, "image/", "jpeg");
else
if(_IS(ext, ".htm") || _IS(ext, ".html") || _IS(ext, ".shtm"))
{_concat2(&header, "text/", "html;charset=UTF-8"); set_base_path = true;}
else
if(_IS(ext + 1, ".js"))
_concat2(&header, "text/", "javascript");
else
if(_IS(ext, ".css"))
_concat2(&header, "text/", "css");
else
if(_IS(ext, ".txt") || _IS(ext, ".log") || _IS(ext, ".ini") || _IS(ext, ".cfg") || IS(ext, ".HIP") || IS(ext, ".HIS") || IS(ext, ".HIP") || IS(ext, ".CNF"))
_concat2(&header, "text/", "plain;charset=UTF-8");
else
if(_IS(ext, ".svg"))
_concat2(&header, "image/", "svg+xml");
#ifndef LITE_EDITION
else
if(_IS(ext, ".gif"))
_concat2(&header, "image/", "gif");
else
if(_IS(ext, ".bmp"))
_concat2(&header, "image/", "bmp");
else
if(_IS(ext, ".tif"))
_concat2(&header, "image/", "tiff");
else
if(_IS(ext, ".avi"))
_concat2(&header, "video/", "x-msvideo");
else
if(_IS(ext, ".mp4") || IS(ext, ".MTH"))
_concat2(&header, "video/", "mp4");
else
if(_IS(ext, ".mkv"))
_concat2(&header, "video/", "x-matroska");
else
if(_IS(ext, ".mpg") || _IS(ext, ".mp2") || strcasestr(ext, ".mpe"))
_concat2(&header, "video/", "mpeg");
else
if(_IS(ext, ".vob"))
_concat2(&header, "video/", "vob");
else
if(_IS(ext, ".wmv"))
_concat2(&header, "video/", "x-ms-wmv");
else
if(_IS(ext, ".flv"))
_concat2(&header, "video/", "x-flv");
else
if(_IS(ext, ".mov"))
_concat2(&header, "video/", "quicktime");
else
if(_IS(ext, ".webm"))
_concat2(&header, "video/", "webm");
else
if(_IS(ext, ".mp3"))
_concat2(&header, "audio/", "mpeg");
else
if(_IS(ext, ".wav"))
_concat2(&header, "audio/", "x-wav");
else
if(_IS(ext, ".wma"))
_concat2(&header, "audio/", "x-ms-wma");
else
if(_IS(ext, ".mid") || _IS(ext, ".kar"))
_concat2(&header, "audio/", "midi");
else
if(_IS(ext, ".mod"))
_concat2(&header, "audio/", "mod");
else
if(_IS(ext, ".zip"))
_concat2(&header, "application/", "zip");
else
if(_IS(ext, ".pdf"))
_concat2(&header, "application/", "pdf");
else
if(_IS(ext, ".doc"))
_concat2(&header, "application/", "msword");
else
if(_IS(ext, ".docx"))
_concat2(&header, "application/", "vnd.openxmlformats-officedocument.wordprocessingml.document");
else
if(_IS(ext, ".xls"))
_concat2(&header, "application/", "vnd.ms-excel");
else
if(_IS(ext, ".xlsx"))
_concat2(&header, "application/", "vnd.openxmlformats-officedocument.spreadsheetml.sheet");
else
if(_IS(ext, ".ppt") || _IS(ext, ".pps"))
_concat2(&header, "application/", "vnd.ms-powerpoint");
else
if(_IS(ext, ".swf"))
_concat2(&header, "application/", "x-shockwave-flash");
#endif
else
_concat2(&header, "application/", "octet-stream");
}
else
{_concat2(&header, "text/", "html;charset=UTF-8"); set_base_path = true;}
if(set_base_path && (is_binary != WEB_COMMAND) && param[0] == '/') {strcpy(html_base_path, param); if(!isDir(param)) remove_filename(html_base_path);}
_concat(&header, "\r\n");
return header.size;
}