\n");
spliton = true;
}
void _F_button_row::drawendline(unsigned width)
{
endline_width = width;
endline = true;
}
void _F_button_row::drawleftarrow (PARAM_STRING href, bool visible)
{
arrow_left_visible = visible;
href_arrow_left = href.ptr;
}
void _F_button_row::drawrightarrow (PARAM_STRING href, bool visible)
{
arrow_right_visible = visible;
href_arrow_right = href.ptr;
}
static const char *tbtype[]={
"text/html", //FILE_UNKNOWN,
"text/html", //FILE_TEXT,
"audio/mp3", //FILE_SOUND_MP3,
"audio/ogg", //FILE_SOUND_OGG,
"image/jpeg", //FILE_IMAGE_JPG,
"image/png", //FILE_IMAGE_PNG,
"image/gig", //FILE_IMAGE_GIF,
"video/mpeg" //FILE_VIDEO,
};
static void util_sendfile_common(CONNECT_INFO &con, const READINFO_receive &info, const BOB_TYPE &content, bool more, const char *handle, const char *session)
{
glocal CONNECT_INFO *con = &con;
tlmpweb_setmodified(info.modified);
tlmpweb_setexpire(time(NULL)+365*24*60*60); // Expires in one year
tlmpweb_doctype (tbtype[info.file_type],info.size);
htmlwrite (content.getbuffer(),content.getsize());
glocal bool more = more;
while (glocal.more){
(*glocal.con,session,handle);
htmlwrite (content.getbuffer(),content.getsize());
glocal.more = more;
//tlmp_error ("readmore success=%d msg=%s\n",success,msg);
}
}
static int util_sendfile (const char *fname)
{
int ret = -1;
FILE *fin = fopen (fname,"r");
if (fin != NULL){
struct stat64 st;
time_t mod = 0;
unsigned size = 0;
if (fstat64(fileno(fin),&st)!=-1){
size = st.st_size;
mod = st.st_mtime;
}
tlmpweb_setmodified(mod);
tlmpweb_doctype ("image/jpeg",size);
char buf[64*1024];
int n;
while ((n=fread(buf,1,sizeof(buf),fin))>0){
htmlwrite(buf,n);
}
fclose (fin);
ret = 0;
}
return ret;
}
int util_sendfile (CONNECT_INFO &con, PARAM_STRING session, PARAM_STRING filename)
{
glocal int ret = -1;
glocal CONNECT_INFO *con = &con;
glocal const char *session = session.ptr;
glocal bool is_mini_photo = strstr(filename.ptr,"/public/mini-photo.jpg")!=nullptr;
glocal bool is_photo = strstr(filename.ptr,"/public/photo.jpg")!=nullptr;
(con,session,filename,"",false);
if (success){
glocal.ret = 0;
util_sendfile_common(*glocal.con,info,content,more,handle,glocal.session);
}else if (glocal.is_mini_photo){
glocal.ret = util_sendfile("/var/www/html/no-mini-photo.jpg");
}else if (glocal.is_photo){
glocal.ret = util_sendfile("/var/www/html/no-photo.jpg");
}else{
}
return glocal.ret;
}
/*
Send a file using the public api.
The file is /username/file. We accept also username/file.
So we extract the username
*/
int util_sendpublicfile (CONNECT_INFO &con, PARAM_STRING filename)
{
glocal int ret = -1;
glocal CONNECT_INFO *con = &con;
const char *pt = filename.ptr;
if (*pt == '/') pt++;
const char *start = pt;
pt = strchr(pt,'/');
if (pt != NULL){
glocal const char *filename = pt;
glocal string username = string(start,pt-start);
(con,glocal.username,pt,0);
if (!success){
if (strcmp(glocal.filename,"/project/photo.jpg")==0){
glocal.ret = util_sendfile ("/var/www/html/no-photo.jpg");
}else if (strcmp(glocal.filename,"/project/mini-photo.jpg")==0){
glocal.ret = util_sendfile ("/var/www/html/no-mini-photo.jpg");
}
if (glocal.ret != 0) tlmp_warning ("Can't read public file %s for user %s: %s\n",glocal.filename,glocal.username.c_str(),msg);
}else{
glocal.ret = 0;
util_sendfile_common(*glocal.con,info,content,more,handle,"public");
}
}
return glocal.ret;
}
string util_flipspaces(PARAM_STRING src)
{
string ret = src.ptr;
for (auto &c:ret){
if (c == ' ') c = '_';
}
return ret;
}
static bool util_is_url(const char *txt, const char *&end,string &url)
{
bool ret = false;
const char *pt;
if (is_start_any_ofnc(txt,pt,"http://","https://")){
pt = txt;
while (*pt > ' ' && is_not_in(*pt,'"','>')) pt++;
url = string(txt,pt-txt);
end = pt;
ret = true;
}
return ret;
}
/*
Format and print a
... with openitab()
*/
void util_print_span(PARAM_STRING url)
{
htmlprintf ("
%s\n",url.ptr,url.ptr);
}
/*
Format a
... with openitab()
*/
static string util_span(PARAM_STRING url)
{
return string("
" + url.ptr + "";
}
/*
Format an open
... with openitab()
(no closing
*/
static string util_open_span(PARAM_STRING url)
{
return string("
";
}
void util_clickable_img (PARAM_STRING url, const char *image_width, unsigned border)
{
htmlout ("");
htmlprintf ("
",image_width,border,url.ptr);
htmlout ("");
}
/*
Create the HTML for a clickable image (using javascript openintab())
*/
string util_clickable_img (PARAM_STRING url, unsigned image_width)
{
string ret;
ret.reserve(500);
ret = util_open_span(url);
ret += string_f("
";
return ret;
}
/*
Format a short message, remove the signature
Escapes < and >
Supports ? for URL
*/
string util_format_shortmsg (PARAM_STRING msg, unsigned nblines, size_t size, unsigned image_width)
{
const char *txt = msg.ptr;
string ret;
ret.reserve(nblines > 0 ? nblines*100 : 1000);
unsigned pos=0;
unsigned noline=0;
if (nblines == 0) nblines=(unsigned)-1;
while (*txt != '\0' && noline < nblines){
if (*txt == '\n'){
ret += "
\n";
pos=0;
noline++;
}else{
const char *pt;
string url;
if (util_is_url(txt,pt,url)){
ret += util_span (string(txt,pt-txt));
txt = pt-1;
}else if (*txt == '<'){
if (is_start_any_ofnc(txt,pt,"
","","","","","","","","","","")){
while (txt < pt) ret += *txt++;
txt--; // There is a txt++ at the end of the loop.
}else{
ret += "<";
}
}else if (*txt == '>'){
ret += ">";
}else if (*txt == '\t'){
unsigned nb = 4 - (pos%4);
for (unsigned i=0; i\n"
"\n"
"Your browser does not support the video tag.\n"
"\n"
,image_width,url.c_str());
ret += "";
}else{
ret += "_VIDEO=";
}
txt--;
}else if (is_start_any_of(txt,pt,"_IFRAME=")){
txt = pt;
if (util_is_url(txt,pt,url)){
txt = pt;
ret += util_open_span(url);
ret += "
\n";
ret += string_f ("\n"
,url.c_str());
ret += "
";
}else{
ret += "_IFRAME=";
}
txt--;
}else{
ret += *txt;
pos++;
}
}
txt++;
}
if (*txt != '\0' || (size != 0 && size != strlen(msg.ptr))){
if (ret.size() > 0 && ret[ret.size()-1] != '\n') ret += "
\n";
ret += "...";
}
return ret;
}
string util_format_shortmsg (PARAM_STRING txt, unsigned image_width)
{
return util_format_shortmsg (txt,0,0,image_width);
}
// Send an HTML document. Does some remaping of relative URLs. Prevent scripting as well.
void _F_public_page::sendhtml (const BOB_TYPE &content)
{
string tmp((const char*)content.getbuffer(),content.getsize());
const char *txt = tmp.c_str();
const char *tosend = txt;
while (*txt != '\0'){
if (*txt == '<'){
// Check if this is