/* This file is part of Bolixo. Bolixo is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Bolixo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bolixo. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEFINE_USERINFO #include "util.h" #include "../bolixo.h" #include "../bolixo.m" #include #include "document.h" #include "../instrument.h" #include "webtabs.h" #include "w_var.h" #include extern void bolixo_doc (DOCUMENT_POINTER &, DOC_ID &jump, const char *username, bool display_full, bool index); extern void bolixo_doc_fr (DOCUMENT_POINTER &, DOC_ID &jump, const char *username, bool display_full, bool index); extern void bolixo_techdoc (DOCUMENT_POINTER &, DOC_ID &jump, const char *username, bool display_full, bool index); extern void profile(CONNECT_INFO &con, CONNECT_INFO &con_sess, vector &docpointers); extern void mail(CONNECT_INFO &con, vector &docpointers); extern void projects(CONNECT_INFO &con, CONNECT_INFO &con_sess, vector &docpointers); extern void projects_documents(CONNECT_INFO &con, CONNECT_INFO &con_sess, const char *formid, const char *id, unsigned tab_width, unsigned tab_height); static WEBID ID_MAIL("mail"); static WEBID ID_FOLLOW("follow"); static WEBID ID_ALLCONTACTS("allcontacts"); using namespace std; #include "../proto/bod_client.protoch" #define bo_sessiond_getsessioninfovars_NOTNEED #include "../proto/bo-sessiond_client.protoch" static const char *newscolor = "#DCDCDC"; struct COPY{ string name; // Suggested base name // used for short messages string path; string date; void clear(){ path.clear(); date.clear(); name.clear(); } }; static COPY fcopy; // Cut buffer, holding a file path static vector fulltext; // For interest_check and talk, list of messages with full text required // This list is shared by all message lists. It is simpler this way. static W_SSTRING w_fulltext("fullt"); static W_SSTRING w_topic("topic"); W_SSTRING w_lang("lang"); W_SSTRING w_public_dir("public_dir"); W_UNSIGNED w_public_view("public_view"); W_SSTRING w_dateformat("dateformat"); W_UNSIGNED w_anon_messages("anonmsgs"); W_SSTRING w_timezone("timezone"); W_SSTRING w_document("document"); W_SSTRING w_recipients("recipients"); W_SSTRING w_recipients2("recipients2"); // Allow override of w_recipients W_SSTRING w_upload("upload"); W_SSTRING w_accept("accept"); W_SSTRING w_user("user"); W_SSTRING w_list("list"); W_SSTRING w_group("group"); W_UNSIGNED w_add("add"); W_SSTRING w_desc("desc"); W_SSTRING w_group1("group1"); W_SSTRING w_group2("group2"); W_SSTRING w_group3("group3"); W_SSTRING w_group4("group4"); W_SSTRING w_access1("access1"); W_SSTRING w_access2("access2"); W_SSTRING w_access3("access3"); W_SSTRING w_access4("access4"); W_SSTRING w_name("name"); W_SSTRING w_image("image"); W_SSTRING w_action("action"); W_SSTRING w_gameid("gameid"); static W_UNSIGNED w_sequence("sequence"); extern W_SSTRING w_webtable; map offsets; map currents; W_UNSIGNED w_publish("publish"); W_UNSIGNED w_bosite("bosite"); W_UNSIGNED w_photo("photo"); W_UNSIGNED w_miniphoto("miniphoto"); W_SSTRING w_address1("address1"); W_SSTRING w_address2("address2"); W_SSTRING w_city("city"); W_SSTRING w_state("state"); W_SSTRING w_country("country"); W_SSTRING w_zipcode("zipcode"); W_SSTRING w_phone("phone"); W_SSTRING w_fax("fax"); W_SSTRING w_website("website"); W_SSTRING w_interest("interest"); W_UNSIGNED w_notify_ui("note_ui"); W_UNSIGNED w_notify_email("note_email"); W_UNSIGNED w_showhidden("showhidden"); static void index_field (_F_form *c, bool newline,unsigned colspan, const char *title, W_SSTRING &var, unsigned size) { if (newline) htmlout (""); htmlprintf ("%s\n",title,colspan); char tmp[100]; snprintf (tmp,sizeof(tmp),"size=%u",size); c->field_string (var,tmp); } static void index_field (_F_form *c, bool newline, const char *title, W_SSTRING &var) { index_field (c,newline,1,title,var,25); } map tabs; static void webtab_init (const vector &vals) { for (auto &s:vals){ // Split the name const char *pt = strchr(s.sname,':'); if (pt != NULL){ WEBTAB_CTRL &ctrl = tabs[string(s.sname,pt)]; if (strcmp(pt,":0")==0){ vector tb; int n = str_splitline(s.sval,',',tb); if (n == 4){ for (unsigned i=0; i<4; i++){ ctrl.offsets[i] = atoi(tb[i].c_str()); } } }else{ ctrl.tabs.push_back(WEBTAB(pt+1,s.sval)); } } } } /* Set the notify flag on each tabs based on userinfo.notifies */ static void webtab_notify() { for (auto &m:tabs){ const char *tname = m.first.c_str(); for (auto &t:m.second.tabs){ const char *name = t.tab.c_str(); if (isdigit(*name) && name[1] == ':') name += 2; string tmp = string_f("%s:%s",tname,name); if (userinfo.notifies.count(tmp) > 0) t.notify = true; t.id = tmp; // We record the notification id, it will be used // as the ID in javascript } } } W_UNSIGNED w_order ("order"); static unsigned order = 0; W_UNSIGNED w_test("test"); W_SSTRING w_email("email"); W_SSTRING w_password("password"); W_SSTRING new_nickname("nickname"); W_SSTRING new_email ("new_email"); W_SSTRING new_password1 ("new_password1"); W_SSTRING new_password2 ("new_password2"); W_SSTRING w_content("content"); W_SSTRING w_filename("filename"); W_SSTRING w_confirm("confirm"); #include "steps.h" static bool is_mobile = false; static bool private_site = false; static void show_buttons_right(_F_websteps *c) { int step = c->getcurstep(); /- /- unsigned fontsize = is_mobile ? 3 : 1; // size=+fontsize bool is_user = userinfo.name.size() > 0; if (step == step_doc && !is_user){ /-
  /- htmlprintf ("%s\n",tlmpweb_curpage(),step_login,fontsize,MSG_U(I_LOGIN,"Login")); if (0 && !private_site){ /-   /- htmlprintf ("%s",fontsize,MSG_U(I_OR,"or")); /-   /- htmlprintf ("%s\n",tlmpweb_curpage(),step_adduser,fontsize,MSG_U(I_CREATEACCT,"Create account")); } } #if 0 if (userinfo.is_admin){ /- string tmp = string_f ("href=%s/admin.hc",tlmpweb_curdir()); print_href("Admin menu",tmp); } #endif if (is_user){ if (!is_mobile){ /- htmlprintf ("\n",fontsize); htmlprintf (MSG_U(I_WELCOME,"Welcome %s"),userinfo.name.c_str()); /-    } } /-
} static unsigned subject = 0; const unsigned max_subject=7; static void print_button (const char *id_suffix, const char *title, int step, int curstep, bool notify) { if (step == curstep){ print_aref_selected (id_suffix,title,step,notify); }else{ print_aref (id_suffix,title,step,notify); } } struct CURRENTFORM{ string id; vector vars; }; static vector currentforms; struct SEENS{ string last; // last first line in the list we have seen string previous; // previous last SEENS(){} SEENS(const string &_last, const string &_previous) : last(_last), previous(_previous){} SEENS(const string &_last) : last(_last){} void pushlast(const char *newlast){ previous = last; last = newlast; } }; static map firstseens; static string org("Bolixo.org"); static void bolixo_title (const char *title, _F_websteps *c, bool doc_full_screen) { glocal int step = c->getcurstep(); string tmp = doc_full_screen ? title : string_f ("Bolixo: %s",title); tlmpweb_title (tmp.c_str()); util_meta(); util_google_code(); tlmpweb_body("white",NULL); util_defstyles(); DIV main; main.id("main").h(100).w(100).dispflex().flowcol().print(); DIV head; head.id("head").flexfixe().style("background-image","linear-gradient(to right, #03a9f4 , #ffffff)").print(); /- htmlprintf ("
} if (is_mobile && is_any_of(glocal.step,step_projects,step_talks)){ unsigned subtab = webtabs_get_subtab(); bool adding = webtabs_adding(); if (adding || subtab > 0){ if (!adding && subtab > 0) subtab--; htmlprintf ("\n",tlmpweb_curpage(),subtab); util_draw_dotmenu ("",false,false); htmlout ("\n"); } } if (!doc_full_screen){ /- /- } /-
\n"); //,newscolor); if (!doc_full_screen && !is_mobile){ /-
  htmlprintf ("%s   ",util_getdirserver(),org.c_str()); /- htmlprintf (MSG_U(I_NODENAME,"Node %s"),util_getnodename()); /- /- if (userinfo.name.empty()) htmlout (MSG_U(I_ABOUT,"A peer to peer open social media")); /-
/-
show_buttons_right (c); /-
if (w_robot == 0 && userinfo.name.size() > 0){ (0,newscolor,false); split(); print_button ("main",MSG_U(M_MAIN,"Main"),1,glocal.step,userinfo.main_notify); split(); print_button ("talks",MSG_U(M_TALK,"Talk"),step_talks,glocal.step,userinfo.talk_notify); #if 0 split(); print_button (MSG_U(M_MAIL,"Mail"),step_mails,glocal.step,userinfo.mail_notify); #endif split(); print_button ("Projects",MSG_U(M_PROJECTS,"Projects"),step_projects,glocal.step,false); split(); vector menu; menu.emplace_back(DOTMENU(MSG_U(M_PROFILE,"Profile"),step_profile)); menu.emplace_back(DOTMENU(MSG_U(M_DOCUM,"Documentation"),step_doc)); menu.emplace_back(DOTMENU(MSG_U(M_TECHDOCUM,"Technical doc."),step_techdoc)); menu.emplace_back(DOTMENU(MSG_U(I_LOGOUT,"Logout"),step_logout)); util_dotmenu(menu,is_any_of(glocal.step,step_profile,step_doc),glocal.step==step_profile ? false : userinfo.menu_notify); } /-
/- head.end(); DIV body; body.id("body").flexfixe().print(); body.donotend(); main.donotend(); }
static void bolixo_title (const char *title, _F_websteps *c) { bolixo_title (title,c,false); } static bool valid_context (CONNECT_INFO &con, _F_websteps *c, const char *subject, bool check_news, bool check_proof) { glocal bool ret = true; if (userinfo.name.empty()){ bolixo_title ("",c); /-

You must be logged to printf ("%s

\n",subject); /- You do not have an account, just create one (top right button). /-
/- It takes one minute. /-

/- See the printhref_raw ("/terms-of-use.html","terms of use",false); /-  for more details. glocal.ret = false; } return glocal.ret; } static void trli_initvar (VAR &var, PARAM_STRING name, PARAM_STRING val) { var.name = name.ptr; SNAMEVAL sval; sval.sval = val.ptr; var.vals.push_back(sval); } static unsigned subtab_talk=0; static unsigned subtab_projects=0; /* Update the session information if the subtab was changed (from a user action). */ static void index_set_subtab(CONNECT_INFO &con_sess, unsigned &subtab) { unsigned newval = webtabs_get_subtab(); if (newval != subtab){ subtab = newval; VAR var; var.name = "subtabs"; SNAMEVAL sval; sval.sname = "talk"; sval.sval = string_f("%u",subtab_talk); var.vals.push_back(sval); sval.sname = "projects"; sval.sval = string_f("%u",subtab_projects); var.vals.push_back(sval); add_to_instrument ("setvar subtabs"); (con_sess,w_session.c_str(),var); if (!success) tlmp_error ("Can't set variable subtabs: %s\n",msg); } } static void trli_getsessioninfo(CONNECT_INFO &con, CONNECT_INFO &con_sess, vector &docpointers) { glocal CONNECT_INFO *con = &con; glocal vector *docpointers = &docpointers; tlmpweb_reset_tablegeometry(); (con_sess,w_session.c_str(),true); if (success){ userinfo.lang = lang; if (lang[0] != '\0'){ translat_selectlang (lang); }else{ userinfo.lang = tlmpweb_getlang(); } userinfo.name = name; userinfo.dateformat = dateformat; userinfo.is_admin = admin; fcopy.clear(); fulltext.clear(); for (auto &var:vars){ if (strcmp(var.name,"subject")==0 && var.vals.size()==1) subject=atoi(var.vals[0].sval); if (strcmp(var.name,"order")==0 && var.vals.size()==1) order=atoi(var.vals[0].sval); if (strcmp(var.name,"offsets")==0){ for (auto &s:var.vals) offsets[s.sname] = atoi(s.sval); }else if (strcmp(var.name,"currents")==0){ for (auto &s:var.vals) currents[s.sname] = atoi(s.sval); }else if (strcmp(var.name,"webtabs")==0){ webtab_init (var.vals); }else if (strcmp(var.name,"document")==0){ // Several document pointers are stored in sequence, repeating the same variable names unsigned nodoc = 0; unsigned s1=0,s2=0,s3=0,s4=0,s5=0,s6=0; for (auto &v:var.vals){ if (strcmp(v.sname,"s1")==0){ s1 = atoi(v.sval); }else if (strcmp(v.sname,"s2")==0){ s2 = atoi(v.sval); }else if (strcmp(v.sname,"s3")==0){ s3 = atoi(v.sval); }else if (strcmp(v.sname,"s4")==0){ s4 = atoi(v.sval); }else if (strcmp(v.sname,"s5")==0){ s5 = atoi(v.sval); }else if (strcmp(v.sname,"s6")==0){ s6 = atoi(v.sval); while (nodoc >= glocal.docpointers->size()) glocal.docpointers->push_back(DOCUMENT_POINTER()); (*glocal.docpointers)[nodoc].set(s1,s2,s3,s4,s5,s6); (*glocal.docpointers)[nodoc].resetchanged(); nodoc++; } } }else if (strcmp(var.name,"currentform")==0){ CURRENTFORM form; for (auto &v:var.vals){ if (strcmp(v.sname,"id")==0){ if (form.id.size()>0){ currentforms.push_back(form); } form.id = v.sval; form.vars.clear(); }else if (strcmp(v.sname,"var")==0){ form.vars.push_back(v.sval); } } if (form.id.size()>0){ currentforms.push_back(form); } }else if (strcmp(var.name,"firstseen")==0){ firstseens.clear(); for (auto &v:var.vals){ vector tb; int nb = str_splitline(v.sval,' ',tb); if (nb > 0){ auto &f = firstseens[v.sname]; if (nb == 1){ f = SEENS(tb[0]); }else if (nb == 2){ f = SEENS(tb[0],tb[1]); } } } }else if (strcmp(var.name,"geometry")==0){ // We receive 4 values: id,height,width,scroll_top WEBID id; unsigned height=0,width=0,scroll_top=0; for (auto &v:var.vals){ if (strcmp(v.sname,"id")==0){ id.set(v.sval); }else if (strcmp(v.sname,"height")==0){ height = atoi(v.sval); }else if (strcmp(v.sname,"width")==0){ width = atoi(v.sval); }else if (strcmp(v.sname,"scroll_top")==0){ scroll_top = atoi(v.sval); }else if (strcmp(v.sname,"scroll_left")==0){ tlmpweb_settablegeometry(id,height,width,scroll_top,atoi(v.sval)); } } }else if (strcmp(var.name,"copy")==0){ for (auto &v:var.vals){ if (strcmp(v.sname,"path")==0){ fcopy.path = v.sval; }else if (strcmp(v.sname,"date")==0){ fcopy.date = v.sval; }else if (strcmp(v.sname,"name")==0){ fcopy.name = v.sval; } } }else if (strcmp(var.name,"notifies")==0){ for (auto &v:var.vals){ if (strncmp(v.sname,"talks:",6)==0){ userinfo.talk_notify=true; }else if (strncmp(v.sname,"mail:",5)==0){ userinfo.mail_notify=true; }else if (is_start_any_of(v.sname,NONEED,"profile:")){ userinfo.menu_notify=true; }else if (strcmp(v.sname,"main")==0){ userinfo.main_notify=true; }else if (strcmp(v.sname,"notify_sequence")==0){ userinfo.notify_sequence=atoi(v.sval); } userinfo.notifies.insert(v.sname); } }else if (strcmp(var.name,"fulltext")==0){ for (auto &v:var.vals) fulltext.push_back(v.sname); }else if (strcmp(var.name,"subtabs")==0){ for (auto &v:var.vals){ if (strcmp(v.sname,"talk")==0){ subtab_talk = atoi(v.sval); }else if (strcmp(v.sname,"projects")==0){ subtab_projects = atoi(v.sval); } } } } webtab_notify(); // Refresh the cookie so it is valid for 100 more days // A user may connect to Bolixo and after a while, do nothing, just watch a long long game // A chess game for example. // The cookie has to be available so a websocket may be established using that cookie. websession_setcookie("session",w_session.c_str(),time(NULL)+100*24*60*60); }else{ userinfo.reset(); (*glocal.con); w_session = sessionid; websession_setcookie("session",sessionid,time(NULL)+4*24*60*60); } } /* The fulltext values control the visibility of entries in the main screen. Normally, only a few lines are shown for each entries. Entries with their message id (UUID) in fulltext[] are shown in full. When we click on on entry, the variable w_fulltext is filled. It acts as a toggle. If it is in fulltext[], it is removed, if not it is added. */ static void index_check_fulltext(CONNECT_INFO &con_sess) { if (w_fulltext.is_filled()){ const char *new_fulltext = w_fulltext.c_str(); auto p = find(fulltext.begin(),fulltext.end(),new_fulltext); if (p == fulltext.end()){ fulltext.push_back(new_fulltext); }else{ fulltext.erase(p); } // Old fulltext may remain here because the user may expand an entry and move on. // To avoid a growing list of fulltext, we keep only 5 around. Since they // are added using push_back, the older is the first. // We do this here because we are about the save the fulltext back to the session manager. while (fulltext.size() > 5) fulltext.erase(fulltext.begin()); VAR var; var.name = "fulltext"; for (auto &v:fulltext){ SNAMEVAL val; val.sname = v; var.vals.push_back(val); } add_to_instrument ("setvar fulltext"); (con_sess,w_session.c_str(),var); if (!success) tlmp_error ("Can't set variable fulltext: %s\n",msg); } } /* Return the color (row style in fact) to tell if this ID has a notification or not */ static const char *index_talk_notify_color (const string &id) { const char *ret = "white"; string tmp = string("talks:")+id; if (userinfo.notifies.count(tmp) > 0){ ret = "orange"; } return ret; } void index_doc (DOCUMENT_POINTER &pt, DOC_ID &jump, bool index) { if (tlmpweb_ismobile()) index = false; if (userinfo.lang == "fr"){ bolixo_doc_fr(pt,jump,userinfo.name.c_str(),w_robot,index); }else{ bolixo_doc (pt,jump,userinfo.name.c_str(),w_robot,index); } } void index_doc (DOCUMENT_POINTER &pt, DOC_ID &jump) { index_doc (pt,jump,false); } static void button_validate(int step) { htmlprintf ("\n" ,tlmpweb_curpage(),step); } static void web_updateoffsets(CONNECT_INFO &con_sess) { VAR var; var.name = "offsets"; for (auto &v:offsets){ SNAMEVAL val; val.sname = v.first; val.sval = string_f ("%u",v.second); var.vals.push_back(val); } add_to_instrument ("setvar updateoffsets"); (con_sess,w_session.c_str(),var); if (!success) tlmp_error ("Can't set variable offset: %s\n",msg); } static void web_updatecurrents(CONNECT_INFO &con_sess) { VAR var; var.name = "currents"; for (auto &v:currents){ SNAMEVAL val; val.sname = v.first; val.sval = string_f ("%u",v.second); var.vals.push_back(val); } add_to_instrument ("setvar updatecurrents"); (con_sess,w_session.c_str(),var); if (!success) printf ("Can't set variable current: %s\n",msg); } static void web_update_firstseen(CONNECT_INFO &con_sess, const char *tablename, const char *key) { auto &val = firstseens[tablename]; if (val.last != key){ val.pushlast(key); VAR var; var.name = "firstseen"; for (auto &v:firstseens){ SNAMEVAL val; val.sname = v.first; val.sval = string_f("%s %s",v.second.last.c_str(),v.second.previous.c_str()); var.vals.push_back(val); } add_to_instrument ("setvar updatefirstseens"); (con_sess,w_session.c_str(),var); if (!success) tlmp_error ("Can't set variable firstseen: %s\n",msg); } } static int index_paste_copy (CONNECT_INFO &con, PARAM_STRING newfname) { glocal int ret = -1; // tlmp_error ("pasting %s %s -> %s\n",fcopy.path.c_str(),fcopy.date.c_str(),newfname.ptr); (con,w_session.c_str(),fcopy.path,fcopy.date,newfname); if (!success){ htmlprintf (MSG_U(E_CANTPASTEENTRY,"Can't paste: %s
\n"),msg); }else{ glocal.ret = 0; }
return glocal.ret; } void index_paste(CONNECT_INFO &con, PARAM_STRING path) { if (fcopy.path.size() == 0){ htmlout (MSG_U(E_NOTHINGTOPASTE,"Nothing to paste
\n")); }else{ glocal const char *path = path.ptr; glocal CONNECT_INFO *con = &con; glocal string newfname = string_f("%s/%s",path.ptr,fcopy.name.c_str()); ENTRY_TYPE type = util_entrytype(con,glocal.newfname); if (type != ENTRY_NONE){ ("pasterename"); Please select a new name. ?> /-

/- /-
htmlout (MSG_R(F_OLDNAME)); /- htmlout(fcopy.name); /-
htmlout (MSG_R(F_NEWNAME)); /- field_string (w_name,""); /-
bool ret = true; glocal.newfname = string_f("%s/%s",glocal.path,w_name.c_str()); if (util_entrytype(*glocal.con,glocal.newfname) != ENTRY_NONE){ htmlprintf (MSG_U(E_NAMEEXIST,"File or folder name %s already exist"),w_name.c_str()); ret = false; } return ret; if (index_paste_copy (*glocal.con,glocal.newfname)==-1){ fail = true; } }else{ index_paste_copy (con,glocal.newfname); } } } static void index_list_contacts(CONNECT_INFO &con, vector &contacts) { glocal contacts; (con,w_session.c_str(),""); for (auto m:members) glocal.contacts.push_back(m); } // Paste something into a message. // If the group is the inbox, we need a recipient. static void index_paste(CONNECT_INFO &con, PARAM_STRING path, PARAM_STRING groupowner, PARAM_STRING group) { glocal con; if (fcopy.path.size()==0){ htmlprintf (MSG_R(E_NOTHINGTOPASTE),fcopy.path.c_str()); }else{ glocal vector recipients; glocal function fun; glocal.fun = [&](bool &fail){ glocal fail; fail = false; (con,w_session.c_str(),"",glocal.recipients,group,groupowner,fcopy.path,fcopy.date); if (!success){ glocal.fail = true; htmlprintf (MSG_R(E_CANTPASTEENTRY),msg); } }; if (is_eq(group,"inbox")){ ("recipients"); vector contacts; index_list_contacts (glocal.con,contacts); /-#I_RECIPIENTNEEDED Please provide one or more recipients for this message. /-

/- /-
htmlout (MSG_R(F_RECIPIENTS)); /- field_string (w_name,"",contacts); /-
auto tb = str_splitline(w_name.c_str()); for (auto &t:tb) glocal.recipients.push_back(t); bool ret = true; // bod_client_sendtalk_file validates the recipients if (glocal.recipients.size() == 0){ htmlprintf ("%s
\n",MSG_R(E_NORECIPIENT)); ret = false; } return ret;
glocal.fun(fail); }else{ bool fail; glocal.fun(fail); } } } // Set the MENU_PASTE menu, make it gray out sens void index_setpastemenu (_F_webtable *c, PARAM_STRING path) { bool disable = false; string paste = MSG_U(M_PASTE,"Paste"); if (fcopy.path.size()==0){ disable = true; // Nothing to paste }else{ #if 0 if (fcopy.path == path.ptr){ disable = true; // Pasting on itself }else{ size_t size = strlen(path.ptr); if (strncmp(fcopy.path.c_str(),path.ptr,size)==0){ // Check if copypath come from the directory path const char *pt = fcopy.path.c_str()+size; if (pt[0] == '/'){ pt = strchr(pt+1,'/'); if (pt == NULL){ // copypath is a file or folder member of path disable = true; } } } } #endif paste = string_f("%s %s",MSG_R(M_PASTE),fcopy.name.c_str()); } c->adddrop_opt (MENU_PASTE,paste); if (disable) c->setdrop_disable(MENU_PASTE); } /* Record the document as the last copied item. It can be used later for a paste command. */ void index_setcopyitem(CONNECT_INFO &con_sess, PARAM_STRING path, PARAM_STRING modified, PARAM_STRING name) { VAR var; var.name = "copy"; SNAMEVAL val; val.sname = "path"; val.sval = path.ptr; var.vals.push_back(val); val.sname = "date"; val.sval = modified.ptr; var.vals.push_back(val); val.sname = "name"; val.sval = name.ptr; var.vals.push_back(val); add_to_instrument ("setvar setcopyitem"); (con_sess,w_session.c_str(),var); if (!success) tlmp_error ("Can't set variable copy: %s\n",msg); fcopy.path = path.ptr; fcopy.date = modified.ptr; fcopy.name = name.ptr; } /* Does like index_setcopyitem() above, but also fills the system clipboard with the text content. */ void index_setcopyitem(CONNECT_INFO &con, CONNECT_INFO &con_sess, PARAM_STRING path, PARAM_STRING modified, PARAM_STRING name) { index_setcopyitem(con_sess,path,modified,name); (con,w_session.c_str(),path,modified); if (info.file_type == FILE_TEXT){ index_set_clipboard (content); } } /* Define a meaningful filename for a short message */ static void index_msg_name (FILE_TYPE file_type, string &filename, string &extension) { // Message do not have a meaningful filename, so we invent something filename = MSG_U(I_BOLIXOMESSAGE,"bolixomessage"); extension = "txt"; if (file_is_sound(file_type)){ filename=MSG_U(I_BOLIXOAUDIO,"bolixoaudio"); if (file_type == FILE_SOUND_MP3){ extension = "mp3"; }else if (file_type == FILE_SOUND_OGG){ extension = "ogg"; } }else if (file_is_image(file_type)){ filename=MSG_U(I_BOLIXOIMAGE,"bolixoimage"); if (file_type == FILE_IMAGE_JPG){ extension = "jpg"; }else if (file_type == FILE_IMAGE_GIF){ extension = "gif"; }else if (file_type == FILE_IMAGE_PNG){ extension = "png"; }else if (file_type == FILE_IMAGE_TIFF){ extension = "tif"; } }else if (file_is_video(file_type)){ filename=MSG_U(I_BOLIXOVIDEO,"bolixovideo"); extension = file_type == FILE_WEBM ? "webm" : "mp4"; }else if (file_is_data(file_type)){ filename=MSG_U(I_BOLIXODATA,"bolixodata"); if (file_type == FILE_ZIP){ extension = "zip"; }else if (file_type == FILE_TGZ){ extension = "tgz"; }else if (file_type == FILE_PDF){ extension = "pdf"; } } } static void index_download (CONNECT_INFO &con, FILE_TYPE file_type, PARAM_STRING fname) { string filename,extension; index_msg_name(file_type,filename,extension); tlmpweb_header ("Content-Disposition"," attachment; filename=%s.%s",filename.c_str(),extension.c_str()); util_sendfile (con,w_session.c_str(),fname); } static void index_msgs_style(_F_webtable &c) { c.setrowstyle ("sep","bgcolor=ghostwhite valign=top\t\t\talign=right"); c.setrowstyle ("sep+current","bgcolor=lightblue valign=top\t\t\talign=right"); c.setrowstyle ("sep1","bgcolor=white valign=top\t\t\talign=right"); c.setrowstyle ("sep1+current","bgcolor=lightblue valign=top\t\t\talign=right"); c.setrowstyle ("septo","bgcolor=#F0F0F0 valign=top\t\t\talign=right"); c.setrowstyle ("septo+current","bgcolor=lightblue valign=top\t\tbgcolor=#F0F0F0\talign=right"); c.sethead (MSG_U(H_TALKMOBILE,"From\t\tSubmit")); } static void index_talk_delnotify (CONNECT_INFO &con_sess, PARAM_STRING prefix, PARAM_STRING id) { util_delnotify (con_sess,prefix,id); bool talks_found = false; for (auto &s:userinfo.notifies){ if (is_start_any_of (s,NONEED,"talks:")) talks_found = true; } userinfo.talk_notify = talks_found; if (!talks_found){ /- } } static void index_show_shortmsg( CONNECT_INFO &con, CONNECT_INFO &con_sess, const char *id, _F_webtabs &webtabs, PARAM_STRING groupname, PARAM_STRING groupowner, unsigned &offset, // First row displayed unsigned &nbhidden) // How many message are not shown { glocal id; glocal nbhidden; glocal webtabs; glocal con; glocal con_sess; glocal const char *groupname = groupname.ptr; glocal const char *groupowner = groupowner.ptr; glocal bool is_inbox = strcmp(glocal.groupname,"inbox")==0; glocal bool is_anonymous = strcmp(glocal.groupname,"anonymous")==0; glocal string path = string_f("/msgs/%s/short-inbox/%s",glocal.groupowner,glocal.groupname); WEBID ID_TALK("talk",string_f("%s:%s",groupowner.ptr,groupname.ptr)); glocal const char *table = ID_TALK.c_str(); if (offsets[glocal.table] == 0){ util_markview (con,glocal.path); } offset = offsets[glocal.table]; (ID_TALK,currents[glocal.table],offset,5); glocal unsigned dropmenu = dropmenu; if (dropmenu == MENU_UNDELETE){ (glocal.con,w_session.c_str(),glocal.path); if (!success) htmlprintf (MSG_R(E_CANTUNDELETEENTRY),msg); }else if (dropmenu == MENU_PASTE){ index_paste (glocal.con,glocal.path,glocal.groupowner,glocal.groupname); }else{ vector fullt; (glocal.con,w_session.c_str(),"",glocal.groupname,glocal.groupowner,fullt,noline,1,firstseens[glocal.table].last); if (messages.size()!=1){ htmlprintf ("Internal error: %s\n",msg); }else{ auto &m = messages[0]; glocal string fname = string_f("%s/%s",glocal.path.c_str(),m.uuid); glocal const char *eventdate = m.eventdate; glocal string suggested_name; string filename,extension; index_msg_name (m.file_type,filename,extension); glocal.suggested_name = filename + "." + extension; if (glocal.dropmenu == MENU_DELETE){ (glocal.con,w_session.c_str(),glocal.fname); if (!success){ htmlprintf (MSG_R(E_CANTDELETEENTRY),msg); }else{ index_setcopyitem(glocal.con,glocal.con_sess,glocal.fname,glocal.eventdate,glocal.suggested_name); } }else if (glocal.dropmenu == MENU_COPY){ index_setcopyitem(glocal.con,glocal.con_sess,glocal.fname,glocal.eventdate,glocal.suggested_name); }else if (glocal.dropmenu == MENU_DOWNLOAD){ index_download (glocal.con,m.file_type,glocal.fname); }else if (glocal.dropmenu == MENU_REPLY){ vector tb; str_splitline(m.recipients,' ',tb); string tmp; if (userinfo.name != m.from) tmp = m.from; for (auto &t:tb){ if (t != m.from && t != userinfo.name){ if (tmp.size() > 0) tmp += " "; tmp += t; } } if (!glocal.is_anonymous && tmp.size() > 0){ tlmpweb_forcevar(w_recipients2,tmp); if (!glocal.is_inbox) glocal.webtabs.addtab (string_f("1:%s:inbox",userinfo.name.c_str()),MSG_R(I_SHORTINBOX)); }else{ /-#E_REPLYTOYOU Can't reply to yourself } }else if (glocal.dropmenu == MENU_EDITITEM){ if (m.file_type != FILE_TEXT){ /-#E_CANTEDIT Can't edit this message }else{ tlmpweb_forcevar(w_recipients2,m.recipients); tlmpweb_forcevar(w_content,m.content); } }else if (glocal.dropmenu == MENU_OPENINTAB){ const char *tabname = MSG_U(I_TEXT,"Text"); if (file_is_image(m.file_type)){ tabname = MSG_R(I_IMAGE); }else if (file_is_video(m.file_type)){ tabname = MSG_U(I_VIDEO,"Video"); }else if (file_is_sound(m.file_type)){ tabname = MSG_U(I_AUDIO,"Audio"); } glocal.webtabs.addtab (string_f("2:%s",glocal.fname.c_str()),tabname); }else if (m.file_type == FILE_PDF){ util_sendfile (glocal.con,w_session.c_str(),glocal.fname); }else if (file_is_video(m.file_type) || file_is_sound(m.file_type)){ tlmpweb_flushheader(); util_popup (glocal.con,m.content,m.file_type,m.submit,m.from ,string_f("/msgs/%s/short-inbox/%s/%s" ,glocal.groupowner,glocal.groupname,m.uuid)); } } } glocal unsigned rownum = nbskip; // Defines all posible options for dropdown if (!glocal.is_anonymous){ adddrop_opt (MENU_REPLY,glocal.is_inbox ? MSG_U(M_REPLY,"Reply") : MSG_U(M_PRIVATEREPLY,"Private reply")); } adddrop_opt (MENU_COPY,MSG_R(M_COPY)); index_setpastemenu(this,glocal.path); adddrop_opt (MENU_DELETE,MSG_R(M_DELETE)); adddrop_opt (MENU_UNDELETE,MSG_R(M_UNDELETE)); adddrop_opt (MENU_EDITITEM,MSG_U(M_EDIT,"Edit")); adddrop_opt (MENU_DOWNLOAD,MSG_R(M_DOWNLOAD)); adddrop_opt (MENU_OPENINTAB,MSG_U(M_OPENINTAB,"Open in tab")); index_msgs_style(*this); auto &fseen = firstseens[glocal.table]; const char *last = fseen.last.c_str(); if (w_showhidden == 1){ last = ""; } (glocal.con,w_session.c_str(),"",glocal.groupname,glocal.groupowner ,fulltext,nbskip,nblines,last); glocal.webtable.setdrop_default({MENU_PASTE,MENU_UNDELETE}); if (!success){ //htmlprintf ("Error: %s %s
",internal_error?"Internal error":"",msg); // No way to access, this is probably an old group or we are no more a member index_talk_delnotify (glocal.con_sess,"talks",glocal.id); }else{ glocal.nbhidden = nbnew; glocal.webtable.settotal(total); glocal.webtable.sethiddens(nbnew); glocal.webtable.sethidden_title (tlmpweb_ismobile() ? MSG_U(I_NEWM,"new") : MSG_U(I_NEWMESSAGES,"new messages")); if (glocal.rownum == 0 && nbnew == 0 && messages.size() > 0){ web_update_firstseen(glocal.con_sess,glocal.table, messages[0].uuid); } if (nbnew == 0){ index_talk_delnotify (glocal.con_sess,"talks",glocal.id); } string day; static const char *line_styles[]={"sep","sep1"}; unsigned line_style = 0; if (!deletes) glocal.webtable.setdrop_disable(MENU_UNDELETE); glocal unsigned image_width = 200; unsigned mini_image_width = 40; unsigned video_size = 200; unsigned icon_height = 24; if (is_mobile){ glocal.image_width = 700; mini_image_width = 60; video_size = 700; icon_height=40; } auto &previous_last = firstseens[glocal.table].previous; for (auto &m:messages){ bool is_previous_last = previous_last == m.uuid; string now = string(m.submit,10); if (now != day){ day = now; glocal.webtable.setclickopt (true,"",""); glocal.webtable.setdrop_visibles({MENU_PASTE}); glocal.webtable.setrow(is_previous_last ? "yline" : "hline",-1,"

%s
\a\a\a",format_date(userinfo.dateformat,day).c_str()); glocal.webtable.resetdrop(); line_style=0; }else if (is_previous_last){ glocal.webtable.setclickopt (false,"",""); glocal.webtable.setrow("yline",-1,"
\a\a\a",is_mobile ? 15 : 5); } if (glocal.is_inbox){ if (userinfo.name == m.from){ glocal.webtable.setdrop_disable(MENU_REPLY); }else{ glocal.webtable.setdrop_enable(MENU_REPLY); } } if (m.file_type == FILE_TEXT){ glocal.webtable.setdrop_enable(MENU_EDITITEM); }else{ glocal.webtable.setdrop_disable(MENU_EDITITEM); } const char *style = line_styles[line_style]; line_style++; if (line_style == 2) line_style = 0; { // Print the first line of the message (from date) // The first line does not trigger the popup or display of the message. // It just makes the message current and flip its status to read. string email_icon; if (userinfo.name != m.from){ // Message not written by you so we put an icon showing if you have read it email_icon = string_f("",icon_height ,m.viewed == VIEWED_NEW ? "email-outline.svg" : "email-open-outline.svg"); } string time = string_f("
%s
%s",format_date(userinfo.dateformat,m.submit).c_str(),email_icon.c_str()); string img; if (strcmp(m.from,"admin")==0){ // admin is not in the contact list of everyone, but has a public page img = ""; }else{ string dir = string_f("/projects/%s/public",m.from); img = util_mini_img(step_image,mini_image_width,dir,"mini-photo.jpg",""); } glocal.webtable.setclickopt (true,"",""); glocal.webtable.setrow (style,glocal.rownum,"%s\t%s\t%s" ,img.c_str(),m.from,time.c_str()); } const char *func = "Popup"; string path = string_f("/msgs/%s/short-inbox/%s/%s",glocal.groupowner,glocal.groupname,m.uuid); if (glocal.webtabs.selected(path)) glocal.webtable.setcurrent(glocal.rownum); if (file_is_sound(m.file_type)){ glocal.webtable.setclickopt (true,func,"400,100"); }else if (file_is_video(m.file_type)){ glocal.webtable.setclickopt (true,func,"800,800"); }else if (file_is_image(m.file_type)){ glocal.webtable.setclickopt (true,"",string_f("webtab_add=2:%s~%s",path.c_str(),MSG_U(I_IMAGE,"Image"))); }else if (file_is_text(m.file_type)){ glocal.webtable.setclickopt (true,"",string_f("fullt=%s",m.uuid)); //glocal.webtable.setclickopt (true,"",string_f("webtab_add=2:%s~%s",path.c_str(),MSG_R(I_TEXT))); }else if (m.file_type == FILE_PDF){ glocal.webtable.setclickopt (true,"viewintab",""); } string content; if (m.content[0] != '\0'){ content = string_f("
%s
",util_format_shortmsg (m.content ,0,m.size,glocal.image_width).c_str()); }else if (file_is_sound(m.file_type)){ string tmp = util_flipspaces(m.submit); content = string_f("" ,tlmpweb_curpage(),step_image,path.c_str(),tmp.c_str(),tbftype[m.file_type]); }else if (file_is_image(m.file_type)){ content = util_img (step_image,glocal.image_width,"",path,m.submit); }else if (file_is_video(m.file_type)){ string tmp = util_flipspaces(m.submit); const char *extension = tbftype[m.file_type]; content = string_f( "" ,video_size,video_size ,tlmpweb_curpage(),step_image,path.c_str(),tmp.c_str(),extension); }else if (file_is_text(m.file_type)){ // Large text file (glocal.con,w_session.c_str(),path,"",true); if (!success){ htmlprintf (MSG_U(E_CANTREADFILE,"Can't read file: %s\n"),msg); }else{ string tmp = string((const char*)content.getbuffer(),content.getsize()); tmp = util_format_shortmsg (tmp.c_str(),0,info.size,glocal.image_width); glocal.webtable.setrow("image",glocal.rownum,"\t%s\a",tmp.c_str()); } }else if (file_is_data(m.file_type)){ const char *image = "zip.png"; if (m.file_type == FILE_PDF) image = "pdf.png"; content = string_f(" %s" ,mini_image_width,mini_image_width,image,MSG_U(I_DATAFILE,"data files")); } if (m.recipients[0] != '\0'){ vectortb; str_splitline (m.recipients,' ',tb); string tmp; for (auto &t:tb){ if (t != userinfo.name){ string add = string_f("webstep=%d&webtab_add=1:%s:inbox~%s&recipients2=%s" ,step_talks,userinfo.name.c_str(),MSG_R(I_SHORTINBOX),t.c_str()); tmp += " " + util_subformsubmit(add,t); } } if (tmp.size() > 0){ glocal.webtable.setrow ("septo",glocal.rownum,"%s\t%s\a",MSG_U(I_TO,"To:"),tmp.c_str()); } } glocal.webtable.setrow (style,glocal.rownum,"\t%s\a",content.c_str()); glocal.rownum++; } } }
// Create the link for the terms_of_use file, localised static void terms_of_use() { const char *lang = tlmpweb_getlang(); if (strcmp(lang,"fr")==0){ printhref_raw ("/conditions-d-utilisation.html",MSG_U(I_TERMSOFUSE,"terms of use"),false); }else{ printhref_raw ("/terms-of-use.html",MSG_R(I_TERMSOFUSE),false); } } // Present some info about a document in the right tab static void index_tab_title(const char *path, const FILEINFO &info) { DIV d("",TAB_FORM); d.print(); /- vector tb; int n=str_splitline(path,'/',tb); if (n == 6){ htmlprintf ("
%s%s%s\n",MSG_U(I_TALKGROUP,"Group") ,tb[2].c_str(),tb[4].c_str()); } htmlprintf ("
%s%s\n",MSG_U(I_TALKFROM,"From"),info.owner.c_str()); /-
} static string gameid; /* Record the gameid of the document currently displayed. This will be used while connecting with the bo-websocket service. */ void index_setgameid(PARAM_STRING id) { gameid = id.ptr; } void projects_show_docgeometry(bool); static string clipboard; void index_set_clipboard (PARAM_STRING txt) { clipboard = txt.ptr; } /* Escape quotes (' and `) and backslashes in a string. This is used to encode string as javascript statements. */ string javascript_escape(PARAM_STRING msg) { return copystring (msg,[](auto &c, auto pt){ if (is_any_of(*pt,'\'','\\','`')) c.insert ('\\'); }); } extern "C" void webmain_real() { glocal bool displayjs=false; // Display notification JS scripts in console glocal bool use_gamesequence = true; // Used for testing while we are moving from game notification by sessiond // to bo-websocket doing a waitevent with bod -> documentd glocal unsigned waitevent_delay=0; glocal bool account_confirmed = false; glocal CONNECT_INFO con; glocal CONNECT_INFO con_sess; glocal.con.port = "/dev/bod.sock"; glocal.con_sess.port = "/dev/sessiond.sock"; glocal vector docpointers; glocal.con.secret = util_readsecret(); glocal.con_sess.secret = glocal.con.secret; for (unsigned i=0; i("/etc/bolixonode.conf",true); const char *pt; if (is_start_any_of(line,pt,"node=")){ util_setnodeurl(pt); }else if (is_start_any_of(line,pt,"dirserver=")){ util_setdirserver(pt); }else if (is_start_any_of(line,pt,"org=")){ org = pt; }else if (is_start_any_of(line,pt,"waitevent_delay=")){ glocal.waitevent_delay=atoi(pt); }else if (strcmp(line,"private_site")==0){ private_site = true; }else if (strcmp(line,"mobile")==0){ tlmpweb_forcemobile(); }else if (strcmp(line,"nonstrict")==0){ util_setnonstrict(true); }else if (strcmp(line,"displayjs")==0){ glocal.displayjs=true; }else if (strcmp(line,"docgeometry")==0){ projects_show_docgeometry(true); }else if (strcmp(line,"nogamesequence")==0){ glocal.use_gamesequence=false; }else if (strcmp(line,"experimental")==0){ util_set_experimental(); }else if (is_start_any_of(line,pt,"mobilespecs")){ unsigned u1,u2,u3; if (splitline(pt,u1,u2,u3)){ util_setmobilespecs(u1,u2,u3); } }else if (strcmp(line,"debug-agent")==0){ tlmpweb_debug_agent(); }else{ tlmp_warning ("Invalid entry in /etc/bolixonode.conf: %s",line); } return 0; // debug is_mobile = tlmpweb_ismobile(); if (0){ ("/tmp/environ.log",false); extern char **environ; char **ptenv = environ; while (*ptenv != NULL){ fprintf (fout,"%s\n",*ptenv); ptenv++; } return 0; } { glocal const char *agent = getenv ("HTTP_USER_AGENT"); glocal bool mobile = is_mobile; if (glocal.agent == NULL || strcmp(glocal.agent,"bo-webtest")!=0){ ("/tmp/agent.log",true); string ip = tlmpweb_getip(); if (glocal.agent == NULL){ fprintf (fout,"%s: robot=%u mobile=%d HTTP_USER_AGENT null\n",ip.c_str(),w_robot.getval(),glocal.mobile); }else{ fprintf (fout,"%s: robot=%u mobile=%d HTTP_USER_AGENT %s\n",ip.c_str(),w_robot.getval(),glocal.mobile,glocal.agent); } return 0; } } const char *ptsession = tlmpweb_getcookie("session"); if (ptsession == NULL){ (glocal.con); w_session = sessionid; websession_setcookie("session",sessionid,time(NULL)+48*60*60); }else{ w_session=ptsession; trli_getsessioninfo(glocal.con,glocal.con_sess,glocal.docpointers); } if (w_session.empty()) return; (); VAR var; var.name = "geometry"; for (auto &v:tb){ SNAMEVAL val; val.sname = "id"; val.sval = v.id.c_str(); var.vals.push_back(move(val)); val.sname = "height"; val.sval = string_f("%u",v.height); var.vals.push_back(move(val)); val.sname = "width"; val.sval = string_f("%u",v.width); var.vals.push_back(move(val)); val.sname = "scroll_top"; val.sval = string_f("%u",v.scroll_top); var.vals.push_back(move(val)); val.sname = "scroll_left"; val.sval = string_f("%u",v.scroll_left); var.vals.push_back(move(val)); } add_to_instrument ("setvar savetablegeometry"); (glocal.con_sess,w_session.c_str(),var); if (!success) tlmp_error ("Can't set variable geometry: %s\n",msg); /* We avoid poluting the session manager with fake request. So we make sure the request is associated with a real or possible webtable We do the markview at the same time. */ glocal bool valid = false; if (strncmp(tableid,"project=",8)==0){ glocal string dir = string_f("/projects/%s",tableid+8); (glocal.con,w_session.c_str(),glocal.dir,"",false,current_row,1); if (files.size()==1){ glocal.valid = true; string fname = string_f("%s/%s",glocal.dir.c_str(),files[0].name); util_markview (glocal.con,fname); } }else if (strncmp(tableid,"inbox",5)==0){ const char *project = tableid+5; if (strcmp(project,"INBOX")==0) project = ""; (glocal.con,w_session.c_str(),"",project,false,current_row,1); if (messages.size()==1){ glocal.valid = true; string fname = index_format_mail_fname(messages[0],userinfo.name); util_markview (glocal.con,fname); } }else if (strncmp(tableid,"list:",5)==0){ const char *tab = tableid+5; if (is_any_of(tab,"projects","groups","interests","contacts")){ glocal.valid = true; } }else if (strncmp(tableid,"tab:",4)==0){ const char *tab = tableid+4; if (is_any_of(tab,"projects","mails","talk","profiles","search")){ glocal.valid = true; } }else if (is_any_of(tableid,"allcontacts","talkpublic","follow","group_contacts")){ // All contacts in main tab // Messages in preview // Messages in main tab glocal.valid = true; }else if (strncmp(tableid,"talk=",5)==0){ vector tb; int n = str_splitline (tableid+5,':',tb); if (n == 2){ glocal string dir = string_f("/msgs/%s/short-inbox/%s",tb[0].c_str(),tb[1].c_str()); vector fullt; (glocal.con,w_session.c_str(),"",tb[1],tb[0],fullt,current_row,1,""); if (messages.size()==1){ glocal.valid = true; string fname = string_f("%s/%s",glocal.dir.c_str(),messages[0].uuid); util_markview (glocal.con,fname); } } } if (glocal.valid){ unsigned &cur = currents[tableid]; unsigned &off = offsets[tableid]; //tlmp_error ("settablecoor tableid=%s set=%d cur=%u current_row=%u\n",tableid,current_row_set,cur,current_row); if (current_row_set && cur != current_row){ cur = current_row; web_updatecurrents(glocal.con_sess); } if (offset_set && off != offset){ off = offset; web_updateoffsets(glocal.con_sess); } }else{ tlmp_error ("settablerow unknown tableid %s %d\n",tableid,current_row); } bool update = false; if (userinfo.name.size() == 0) return; if (forms.size() != currentforms.size()){ update = true; }else{ // Forms have fixed field definition. So we compare only // to see if the same form IDs are in the list for (auto &v:forms){ bool found = false; for (auto &c:currentforms){ if (c.id == v.formid){ found = true; break; } } if (!found){ update = true; break; } } } if (update){ VAR var; var.name = "currentform"; for (auto &v:forms){ SNAMEVAL val; val.sname = "id"; val.sval = v.formid; var.vals.push_back(val); for (auto &vv:v.variables){ val.sname = "var"; val.sval = vv.getname(); var.vals.push_back(val); } } add_to_instrument ("setvar recordform"); (glocal.con_sess,w_session.c_str(),var); if (!success) tlmp_error (MSG_U(E_SAVECURFORM,"Can't save active form state: %s\n"),msg); } glocal int ret = -1; if (userinfo.name.size()==0){ glocal.ret = 0; }else{ // tlmp_error ("restore form %s\n",formid); glocal const char *formid = formid; (glocal.con,w_session.c_str(),formid); if (!success){ tlmp_error (MSG_U(E_RESTOREFORM,"Can't restore active form state %s: %s\n"),glocal.formid,msg); }else{ // tlmp_error ("restore form %s size=%lu\n",glocal.formid,vars.size()); if (vars.size() > 0){ glocal.ret = 0; for (auto &v:vars){ // tlmp_error ("restore form %s var %s val %s\n",glocal.formid,v.name,v.val); tlmpweb_setvar (v.name,v.val); } } } } return glocal.ret; if (userinfo.name.size() > 0){ // tlmp_error ("deleteform %s\n",formid); glocal const char *formid = formid; (glocal.con,w_session.c_str(),formid); if (!success) tlmp_error ("deleteform %s: %s\n",glocal.formid,msg); } (glocal.con,w_session.c_str()); if (!success) tlmp_error ("deleteallform: %s\n",msg); if (currentforms.size() > 0){ for (auto &form:currentforms){ FORMVARS f; glocal const char *id = form.id.c_str(); // tlmp_error ("saveform id=%s\n",glocal.id); f.id = form.id; for (auto &v:form.vars){ bool is_def; const char *val = t_varstr(v.c_str(),is_def); if (is_def){ FORMVAR var; var.name = v; var.val = val; f.vars.push_back(var); } } if (f.vars.size() > 0){ (glocal.con,w_session.c_str(),f); if (!success){ if (internal_error){ tlmp_error ("internal_error saveform currentform %s\n",glocal.id); }else{ tlmp_error (MSG_U(E_SAVEFORM,"saveform currentform %s: %s\n"),glocal.id,msg); } } } } } c.settableparms ("border=0"); c.setthparms ("align=left bgcolor=lightgray",""); c.setrowstyle ("sep","bgcolor=ghostwhite valign=top"); c.setrowstyle ("sep+current","bgcolor=lightblue valign=top"); c.setrowstyle ("sep1","bgcolor=white valign=top"); c.setrowstyle ("sep1+current","bgcolor=lightblue valign=top"); c.setrowstyle ("hline","bgcolor=gray valign=top"); c.setrowstyle ("yline","bgcolor=#fdfd96 valign=top"); c.setrowstyle ("white","bgcolor=white"); c.setrowstyle ("white+current","bgcolor=lightblue"); c.setrowstyle ("whitebold","bgcolor=white style='font-weight:bold;'"); c.setrowstyle ("whitebold+current","bgcolor=lightblue style='font-weight:bold;'"); c.setrowstyle ("orange","bgcolor=orange"); c.setrowstyle ("orange+current","bgcolor=orange"); // Normally the current line of a webtable // is shown using the lightblue color. // But when there is a notification, it stays orange. //c.setrowstyle ("whitebold","bgcolor=white>\b"); //c.setrowstyle ("whitebold+current","bgcolor=lightblue>\b"); c.setrowstyle ("image","bgcolor=white align=center"); // Save the webtabs state to the session manager VAR var; var.name = "webtabs"; for (auto &v:tabs){ { SNAMEVAL val; val.sname = string_f("%s:0",v.first.c_str()); val.sval = string_f("%u,%u,%u,%u" ,v.second.offsets[0] ,v.second.offsets[1] ,v.second.offsets[2] ,v.second.offsets[3]); var.vals.push_back(val); } for (auto &t:v.second.tabs){ SNAMEVAL val; val.sname = string_f("%s:%c:%s",v.first.c_str(),t.type+'1',t.tab.c_str()); val.sval = string_f("f=%u,s=%s,t=%s,l=%d",t.selorder,t.state.c_str() ,t.title.c_str(),t.locked); var.vals.push_back(val); } } add_to_instrument ("setvar savetabs"); (glocal.con_sess,w_session.c_str(),var); if (!success) htmlprintf ("Can't set variable webtabs: %s\n",msg); index_check_fulltext(glocal.con_sess); websteps_setdefaultstep(currents["websteps"]); (); if (tlmpweb_isrobot() || w_robot==1){ step = step_doc; }else if (w_session.empty() && step > 2){ step = 1; }else if (userinfo.name.empty() && !is_any_of(step,2,3,10,12)){ step = 2; }else if (getcurstep()==0 && step == 15){ // step 15 is full screen document // but getcurstep()==0 means the step was not received from the HTTP request // It means the end user is just opening a new browser tab and enter the URL of the server // without any parameter. It does not want to enter the last fullscreen document step = 1; } { unsigned step = getcurstep(); auto &cur_step = currents["websteps"]; if (step != cur_step){ cur_step = step; web_updatecurrents(glocal.con_sess); } } /- /- util_endscript(string_f("webstep=%u&subtab=%u%s",getcurstep(),webtabs_get_subtab(),getextraargs())); { // Save the position in the document bool one_changed = false; for (auto &d:glocal.docpointers){ if (d.ischanged()){ one_changed = true; } } if (one_changed){ VAR var; var.name = "document"; for (auto &d:glocal.docpointers){ unsigned nos = 1; for (auto s:d.tb){ SNAMEVAL val; val.sname = string_f("s%u",nos++); val.sval = string_f("%u",s); var.vals.push_back(val); } } add_to_instrument ("setvar document"); (glocal.con_sess,w_session.c_str(),var); if (!success) htmlprintf ("Can't set variable document: %s\n",msg); } } // Generate the javascript to retrieve the notification code if (!userinfo.name.empty()){ /- } if (clipboard.size() > 0){ /- } if (userinfo.name.size() == 0){ // Anonymous, present public news ? // /- So far no public content if (!is_mobile){ bolixo_title ("",this); DIV d; d.w(50).marginauto().vmargins(30,0).vpaddings(10,10).paddings(10,10).border(1,"black").borderradius(5).bg("white").print(); htmlout (MSG_R(I_BOLIXO)); /-

htmlprintf ("%s\n",tlmpweb_curpage(),MSG_R(I_COMPLETEDOC)); } }else{ glocal bool junk_output = false; // If the user hit "reply" in the drop down menu, we ditch everything // Also used for download vector output; tlmpweb_pushgrab(output); // We use DIV to split the main screen into 3 areas: contacts, messages and notifications // Based on the width of the screen, we drop some areas. On mobiles, we only show the messages DIV h; h.w(100).dispflex().flowrow().print(); DIV d("tabs"); unsigned center_w = 100; unsigned left_side_w = 0; unsigned right_side_w = 0; if (is_mobile){ tlmpweb_screenwidth(); d.w(100).print(); }else{ unsigned w = tlmpweb_screenwidth(); unsigned dw = 50; if (w > 0){ unsigned pixels = dw/100.0*1920; // dw% of an HD screen center_w = pixels*100/w; if (center_w > 90){ center_w = 95; }else if (center_w > 70){ right_side_w = 100-center_w; }else{ left_side_w = (100-center_w)/2; right_side_w = left_side_w; } } } if (center_w < 100){ if (left_side_w > 0){ DIV l("tabs"); l.flexfixe().w(left_side_w).border(1,"black").borderradius(5).margins(5,5).vmargins(5,5).paddings(5,5).print(); DIV f; f.id(TAB_FORM).print(); htmlprintf ("

%s
\n",MSG_U(I_CONTACTS,"Contacts")); f.end(); string table("allcontacts"); (ID_ALLCONTACTS,currents[table],offsets[table],5); (glocal.con,w_session.c_str(),""); unsigned rownum = 0; unsigned mini_image_width = is_mobile ? 60 : 40; string img = util_mini_img(step_public,mini_image_width,"admin","project/mini-photo.jpg",""); string add = string_f("webstep=%d&webtab_add=1:%s:inbox&recipients=admin",step_talks,userinfo.name.c_str()); glocal.webtable.setclickopt (true,"",add); glocal.webtable.setrow("white",rownum,"%s\tadmin",img.c_str()); rownum++; for (auto m:members){ string add = string_f("webstep=%d&webtab_add=1:%s:inbox~%s&recipients2=%s" ,step_talks,userinfo.name.c_str(),MSG_R(I_SHORTINBOX),m); glocal.webtable.setclickopt (true,"",add); string dir = string_f("/projects/%s/public",m); img = util_mini_img(step_image,mini_image_width,dir,"mini-photo.jpg",""); glocal.webtable.setrow("white",rownum,"%s\t%s",img.c_str(),m); rownum++; } l.end(); } d.w(center_w).textalign("center").border(1,"black").borderradius(5).vmargins(5,5).paddings(5,5); if (left_side_w == 0 && right_side_w == 0) d.marginauto(); d.print(); } glocal const char *table = ID_FOLLOW.c_str(); (ID_FOLLOW,currents[glocal.table],offsets[glocal.table],5); glocal unsigned dropmenu = dropmenu; glocal exit_webtable; vector empty; (glocal.con,w_session.c_str(),"",empty,noline,1,firstseens[glocal.table].last); if (messages.size()!=1){ htmlprintf ("Internal error: %s\n",msg); }else{ auto &m = messages[0]; string filename,extension; index_msg_name(m.file_type,filename,extension); string suggested_name = string_f("%s.%s",filename.c_str(),extension.c_str()); string fname; unsigned step = step_image; if (m.inbox){ fname = string_f("/msgs/%s/short-inbox/inbox/%s",userinfo.name.c_str(),m.uuid); }else{ fname = string_f("/%s/msg/%s",m.from,m.uuid); step = step_public; } if (glocal.dropmenu == MENU_DOWNLOAD){ tlmpweb_popgrab(); tlmpweb_header ("Content-Disposition"," attachment; filename=%s" ,suggested_name.c_str()); if (m.inbox){ util_sendfile (glocal.con,w_session.c_str(),fname); }else{ util_sendpublicfile (glocal.con,fname); } glocal.junk_output = true; }else if (glocal.dropmenu == MENU_COPY){ string msg_name; if (m.inbox){ msg_name = fname; }else{ msg_name = string_f("/msgs/%s/short-inbox/public/%s",m.from,m.uuid); } index_setcopyitem(glocal.con,glocal.con_sess,msg_name,"",suggested_name); }else if (glocal.dropmenu == MENU_REPLY){ if (userinfo.name != m.from){ tlmpweb_forcevar(w_recipients,m.from); webtabs_forcevar(string_f("1:%s:inbox~%s",userinfo.name.c_str(),MSG_R(I_SHORTINBOX))); glocal.websteps.gotostep(step_talks); glocal.exit_webtable = true; glocal.junk_output = true; }else{ htmlprintf (MSG_R(E_REPLYTOYOU)); } }else if (file_is_image(m.file_type) || file_is_video(m.file_type) || file_is_sound(m.file_type)){ tlmpweb_popgrab(); glocal.junk_output = true; util_popup (glocal.con,step,m.content,m.file_type,m.submit,m.from ,fname); } } sethelp(string_f("webstep=%d&topic=main",step_doctopic)); adddrop_opt (MENU_COPY,MSG_R(M_COPY)); adddrop_opt (MENU_DOWNLOAD,MSG_R(M_DOWNLOAD)); adddrop_opt (MENU_REPLY,MSG_R(M_REPLY)); index_msgs_style (*this); glocal unsigned rownum = nbskip; auto &fseen = firstseens[glocal.table]; const char *last = fseen.last.c_str(); if (w_showhidden == 1){ last = ""; userinfo.main_notify = false; } (glocal.con,w_session.c_str(),"",fulltext,nbskip,nblines,last); // success:b msg messages:U{MAINMSG}v static const char *func = "Popup"; string day; static const char *line_styles[]={"sep","sep1"}; unsigned line_style = 0; unsigned image_width = 200; unsigned mini_image_width = 30; unsigned video_size = 200; if (is_mobile){ image_width = 700; mini_image_width = 60; video_size = 700; } if (nbnew==0) util_delnotify(glocal.con_sess,"main"); glocal.webtable.settotal(total); glocal.webtable.sethiddens(nbnew); glocal.webtable.sethidden_title(tlmpweb_ismobile() ? MSG_R(I_NEWM) : MSG_R(I_NEWMESSAGES)); if (glocal.rownum == 0 && nbnew == 0 && messages.size() > 0){ web_update_firstseen(glocal.con_sess,glocal.table,messages[0].uuid); } auto &previous_last = firstseens[glocal.table].previous; for (auto &m:messages){ bool is_previous_last = previous_last == m.uuid; string now = string (m.submit,10); if (1){ if (m.inbox && userinfo.name != m.from){ glocal.webtable.setdrop_visible(MENU_REPLY); }else{ glocal.webtable.setdrop_hidden(MENU_REPLY); } } if (now != day){ day = now; glocal.webtable.setclickopt (true,"",""); glocal.webtable.setrow(is_previous_last ? "yline" : "hline",-1,"
%s
\a\a\a" ,format_date(userinfo.dateformat,day).c_str()); line_style=0; }else if (is_previous_last){ glocal.webtable.setclickopt (false,"",""); glocal.webtable.setrow("yline",-1,"
\a\a\a",is_mobile ? 15 : 5); } const char *style = line_styles[line_style]; line_style++; if (line_style == 2) line_style = 0; string time = string_f("
%s
",format_date(userinfo.dateformat,m.submit).c_str()); string img; // Mini-photo // Public message from interest list const char *pt = strchr(m.from,'@'); if (pt!=NULL){ string user(m.from,pt-m.from); img = string_f("\n" ,mini_image_width,pt+1,user.c_str()); }else{ img = util_mini_img(step_public,mini_image_width,m.from,"project/mini-photo.jpg",""); } string path; unsigned step = step_image; if (m.inbox){ // Private message string add = string_f("webstep=%d&webtab_add=1:%s:inbox&recipients=%s" ,step_talks,userinfo.name.c_str(),m.from); glocal.webtable.setclickopt (true,"",add); path = string_f("/msgs/%s/short-inbox/inbox/%s",userinfo.name.c_str(),m.uuid); }else{ glocal.webtable.setclickopt (true,"",""); // Public message in the interest list path = string_f("%s/msg/%s",m.from,m.uuid); step = step_public; } string content; if (m.content[0] != '\0'){ content = string_f("
%s
",util_format_shortmsg (m.content,0,m.size,image_width).c_str()); }else if (file_is_sound(m.file_type)){ string tmp = util_flipspaces(m.submit); content = string_f("" ,tlmpweb_curpage(),step,path.c_str(),tmp.c_str(),tbftype[m.file_type]); }else if (file_is_image(m.file_type)){ content = util_img (step,image_width,"",path,m.submit); }else if (file_is_video(m.file_type)){ string tmp = util_flipspaces(m.submit); const char *extension = tbftype[m.file_type]; content = string_f( "" ,video_size,video_size ,tlmpweb_curpage(),step,path.c_str(),tmp.c_str(),extension); } { const char *private_msg = ""; string from; if (m.inbox){ private_msg = MSG_U(I_PRIVATE,"(private)"); from = m.from; }else{ const char *pt = strchr(m.from,'@'); string link; if (pt == NULL){ link = string_f("/public/%s",m.from); }else{ link = string_f("https://%s/public/%s",pt+1,string(m.from,pt-m.from).c_str()); } from = string_f("%s",link.c_str(),m.from); } glocal.webtable.setrow (style,glocal.rownum,"%s\t%s %s\t%s",img.c_str(),private_msg,from.c_str() ,time.c_str()); if (file_is_sound(m.file_type)){ glocal.webtable.setclickopt (true,func,"400,100"); }else if (file_is_video(m.file_type)){ glocal.webtable.setclickopt (true,func,"800,800"); }else if (file_is_image(m.file_type)){ glocal.webtable.setclickopt (true,func,"800,800"); }else{ glocal.webtable.setclickopt (true,"",string_f("fullt=%s",m.uuid)); } glocal.webtable.setrow (style,glocal.rownum,"\t%s\a",content.c_str()); } glocal.rownum++; }
d.end(); if (right_side_w > 0){ DIV r("tabs"); r.flexfixe().w(right_side_w).border(1,"black").borderradius(5).margins(5,5).vmargins(5,5).paddings(5,5).autoscroll().print(); htmlprintf ("
%s

\n",MSG_U(I_NOTIFICATIONS,"Notifications")); for (auto n:userinfo.notifies){ if (n == "profile:Contacts"){ htmlprintf ("%s

\n" ,tlmpweb_curpage(),step_profile,MSG_R(T_CONTACTSTOYOU)); }else if (n == "profile:Contact-req"){ htmlprintf ("%s

\n" ,tlmpweb_curpage(),step_profile,MSG_R(T_REQUESTSBYYOU)); }else if (strncmp(n.c_str(),"talks:",6)==0){ const char *name = n.c_str()+6; const char *groupname = strchr(name,':'); if (groupname != NULL){ string owner = string(name,groupname-name); groupname++; htmlprintf ("",MSG_R(I_SHORTINBOX)); /-#I_MESSAGESINBOX Messages in your inbox }else if (strcmp(groupname,"anonymous")==0){ htmlprintf ("~%s')>",MSG_R(I_ANONINBOX)); /-#I_MESSAGESANONYMOUS Messages in your public inbox }else{ htmlout ("')>"); htmlprintf (MSG_U(I_MESSAGEINYOURGROUP,"Messages in your %s group"),groupname); } }else{ htmlout ("')>"); htmlprintf (MSG_U(I_MESSAGEINGROUP,"Messages in %s group of %s"),groupname,owner.c_str()); } htmlout ("

\n"); } } } } h.end(); tlmpweb_popgrab(); if (!glocal.junk_output){ tlmpweb_ctrloutput(true); bolixo_title ("",this); htmlout (output); } } // Login ("login"); tlmpweb_body ("white",NULL,"background=background.png"); bolixo_title (MSG_U(T_LOGIN,"Login"),&glocal.websteps); /-

DIV d; d.bg("white").w(is_mobile ? 80 : 50).marginauto().paddings(10,10).vpaddings(10,10).borderradius(5).border(1,"black").print(); d.donotend(); if (glocal.account_confirmed){ The account is now confirmed, you can log in ?> }else{ /-

htmlprintf (MSG_R(I_NODENAME),util_getnodename()); /-

if (!tlmpweb_ismobile()) htmlout (MSG_R(I_BOLIXO)); /-

/-#I_HAVEACCT Already have an account, please login. htmlprintf (" %s\n",tlmpweb_curpage(),MSG_U(I_NOACCT,"No account, just create one")); /-

} /- /- /-
/-#I_EMAIL Enter your email /- field_string (w_email,"style=width:100%"); /-
/-#I_PASSWORD Password /- field_password (w_password,""); /-
button_submit (MSG_U(B_LOGIN,"Login")); /-
DIV line; line.dispflex().flowrow().w(100).print(); DIV l; l.flex("1").align("flex-start").print(); terms_of_use(); l.end(); l.sfloat("right").print(); htmlprintf ("%s\n",tlmpweb_curpage(),step_doc,"Documentation");
bool ret = false; if (w_email.is_filled()){ if (w_password.empty()){ /-#I_PASSWDREQ You must supply a password }else{ ret = true; } }else{ /-#I_PROVIDEEMAIL Please provide an email } return ret; glocal bool fail = false; (glocal.con,w_session.c_str(),w_email.c_str(),w_password.c_str()); if (success){ trli_getsessioninfo(glocal.con,glocal.con_sess,glocal.docpointers); glocal.websteps.gotostep(1); ("/tmp/login.log",true); DATEASC buf; fdpass_asctime(time(NULL),buf); fprintf (fout,"%s %s %s\n",buf.buf,userinfo.name.c_str(),tlmpweb_getip().c_str()); return 0; }else if (incomplete){ glocal.websteps.gotostep(step_incomplete); }else{ /-#I_LOGINFAILED Login failed, invalid email or password glocal.fail = true; } fail = glocal.fail; // Account creation if (private_site) return; glocal bool account_created = false; ("createaccount"); bolixo_title (MSG_U(T_CREATEACC,"Account creation"),&glocal.websteps); /-

DIV d; d.border(1,"black").borderradius(5).paddings(10,10).vpaddings(10,10).marginauto().w(is_mobile ? 80 : 50).print(); d.donotend(); /-

htmlprintf (MSG_R(I_NODENAME),util_getnodename()); /-

htmlprintf (" (%s)

\n",tlmpweb_curpage(),MSG_R(I_HAVEACCT)); Your email will only be used for the following reasons.

  • Login.
  • Account confirmation.
  • Account modification confirmation.
The only information shown on the web site is the nickname. Your email won't appear on the site.

Cookies are used on this site to preserve the states of your session. The cookie allocated to your session is deleted at logout time. Cookies have no other uses and are not shared.

See the ?> terms_of_use(); /-#I_MOREDETAILS  for more details /-

/-#I_NAMEVALIDCHAR Nick name must not contain spaces, /, @, #, ; " and ' /-

/- /- htmlprintf ("
%s\n",MSG_U(I_NICKNAME,"Select a nickname")); field_string (new_nickname,"style=width:50%"); htmlprintf ("
%s\n",MSG_U(I_ENTERMAIL,"Enter your email")); field_string (new_email,"style=width:90%"); htmlprintf ("
%s\n",MSG_U(I_ENTERPWD,"Password")); field_password (new_password1,"style=width:50%"); htmlprintf ("
%s\n",MSG_U(I_CONFIRMPWD,"Confirm password")); field_password (new_password2,"style=width:50%"); /-
button_submit (MSG_U(B_ACCACCOUNT,"Add account")); /-
bool ret = true; if (new_nickname.empty()){ /-#E_NEEDNICKMAME Please provide a nickname ret = false; }else if (new_email.empty()){ /-#E_NEEDEMAIL Please provide an email ret = false; }else if (new_password1.empty()){ /-#E_NEEDPWD Please enter a password ret = false; }else if (strcmp(new_password1.c_str(),new_password2.c_str())!=0){ /-#E_PWDMISMATCH Passwords do not match ret = false; } return ret; glocal bool fail = false; (glocal.con,w_session.c_str(),new_nickname.c_str(),new_email.c_str(),new_password1.c_str(),tlmpweb_getlang()); if (confirmid[0] == '\0'){ glocal.fail = true; DIV d; d.w(50).marginauto().print(); /-#E_CREATACCT Account creation failure htmlout (msg); /-

}else{ glocal.account_created = true; } fail = glocal.fail; if (glocal.account_created){ bolixo_title (MSG_R(T_CREATEACC),&glocal.websteps); DIV d; d.marginauto().w(50).vmargins(20,5).vpaddings(5,5).paddings(5,5).border(1,"black").borderradius(5).print(); A confirmation email has been sent.

Once you received the email click on the link. This will complete the account creation process

Please note: the email is sometimes thrown into spam. If you have not received the message after few minutes, it probably sits there.

To get another copy of the confirmation message, just sign-in to the account. ?> /-

htmlprintf ("%s\n",MSG_U(I_BACKTOLOGIN,"Back to login page")); } // Logout tlmpweb_deleteallform(); (glocal.con,w_session.c_str()); userinfo.reset(); //trli_getsessioninfo(glocal.con,glocal.con_sess); glocal.websteps.gotostep(step_login); // Send a file if (util_sendfile (glocal.con,w_session.c_str(),w_image.c_str())==-1){ tlmpweb_httpnotfound(); } noend(); // Send a file from a user public directory if (util_sendpublicfile (glocal.con,w_image.c_str())==-1){ tlmpweb_httpnotfound(); } noend(); // TAB Projects webtabs_set_subtab (subtab_projects); bolixo_title (MSG_R(M_PROJECTS),this); projects (glocal.con,glocal.con_sess,glocal.docpointers); index_set_subtab (glocal.con_sess,subtab_projects); // TAB Mails bolixo_title (MSG_U(T_MAILS,"Mails"),this); mail (glocal.con,glocal.docpointers); // TAB Talks webtabs_set_subtab (subtab_talk); bolixo_title (MSG_U(T_TALKS,"Talks"),this); static unsigned size[5]={15,40,45,0,0}; static unsigned size_mobile[5]={25,60,15,0,0}; ("talks",tabs,is_mobile ? size_mobile : size); sethelp(); static WEBID id("tab:talk"); (id,currents[id.c_str()]); if (dropmenu == MENU_NOTIFICATIONS){ glocal vector keys; glocal.keys.push_back(string_f("talks:%s:inbox",userinfo.name.c_str())); (glocal.con,w_session.c_str(),"",false); for (auto &g:groups){ if (userinfo.name != g.owner || is_not_in(g.name,"inbox","anonymous")){ glocal.keys.push_back(string_f("talks:%s:%s",g.owner,g.name)); } } glocal.keys.push_back(string_f("talks:%s:anonymous",userinfo.name.c_str())); if (noline < glocal.keys.size()){ glocal const char *key = glocal.keys[noline].c_str(); ("notifications"); (glocal.con,w_session.c_str(),"",glocal.key); if (success){ w_notify_ui = ui; w_notify_email = email; } // active_ui and digest are not done, even if they are in the database // and the procotol set/get_notification supports it. glocal.webtable.set_errortitle(MSG_R(I_NOTIFICATIONS)); /- /-
/-#F_PASSIVENOTIFY Passive UI notifications /- field_checkbox (w_notify_ui,""); /-
/-#F_EMAILNOTIFY Email notification /- field_checkbox (w_notify_email,""); /-
button_submit(); /-
return true; (glocal.con,w_session.c_str(),"",glocal.key,w_notify_ui,false,w_notify_email,false);
} }
adddrop_opt(MENU_NOTIFICATIONS,MSG_U(M_NOTIFICATIONS,"Notifications")); sethead (MSG_U(H_TALKS,"Owner\tGroup")); (glocal.con,w_session.c_str(),"",false); // Make sure the inbox and public inbox (anonymous) appears at the // top unsigned rownum = 0; const char *username = userinfo.name.c_str(); string id = string_f("%s:inbox",username); string add = string_f("webtab_add=1:%s:inbox~%s",username,MSG_U(I_SHORTINBOX,"Inbox")); if (glocal.webtabs.selected(id)) glocal.webtable.setcurrent(rownum); glocal.webtable.setclickopt (true,"",add); glocal.webtable.setid(string_f("talktbl:%s:inbox",username)); glocal.webtable.setrow (index_talk_notify_color(id),rownum,"\t%s" ,MSG_R(I_SHORTINBOX)); rownum++; for (auto &g:groups){ if (userinfo.name != g.owner || is_not_in(g.name,"inbox","anonymous")){ id = string_f("%s:%s",g.owner,g.name); add = string_f("webtab_add=1:%s:%s",g.owner,g.name); if (glocal.webtabs.selected(id)) glocal.webtable.setcurrent(rownum); glocal.webtable.setclickopt (true,"",add); glocal.webtable.setid (string_f("talktbl:%s:%s",g.owner,g.name)); glocal.webtable.setrow (index_talk_notify_color(id),rownum,"%s\t%s" ,g.owner,g.name); rownum++; } } id = string_f("%s:anonymous",username); add = string_f("webtab_add=1:%s:anonymous~%s",username,MSG_U(I_ANONINBOX,"Public-inbox")); if (glocal.webtabs.selected(id)) glocal.webtable.setcurrent(rownum); glocal.webtable.setclickopt (true,"",add); glocal.webtable.setid(string_f("talktbl:%s:anonymous",username)); glocal.webtable.setrow (index_talk_notify_color(id),rownum,"\t%s" ,MSG_R(I_ANONINBOX));
vector tb; int n = str_splitline (id,':',tb); if (n != 2) return; glocal id; glocal string groupowner = tb[0]; glocal string groupname = tb[1]; glocal const char *formid = formid; glocal unsigned offset = 0; // First row displayed glocal unsigned nbhidden = 0; // Number of hidden message (not yet seen by the user) (); if (glocal.groupname != "anonymous"){ glocal bool private_inbox = glocal.groupname == "inbox"; DIV f; f.id(TAB_FORM).bg("#a0a0a0").paddings(5,5).vpaddings(5,5).vmargins(5,0).borderradius(5).print(); (glocal.formid); DIV d; d.dispflex().flowcol().print(); const unsigned vspace=tlmpweb_ismobile() ? 10: 3; const unsigned hspace=3; glocal vector contacts; index_list_contacts(glocal.con,glocal.contacts); if (w_recipients2.size() > 0){ if (w_recipients.size() > 0){ string tmp = string_f("%s %s",w_recipients.c_str(),w_recipients2.c_str()); tlmpweb_forcevar(w_recipients,tmp); }else{ tlmpweb_forcevar(w_recipients,w_recipients2.c_str()); } } if (glocal.private_inbox){ DIV dd; dd.w(100).flexfixe().vmargins(vspace,0).print(); DIV ddd; ddd.dispflex().flowrow().print(); DIV dddd; dddd.flexfixe().margins(0,hspace).print(); /-#F_RECIPIENTS Recipients dddd.end(); dddd.flexgrow().print(); field_string(w_recipients,"style=width:100%",glocal.contacts); } { DIV dd; d.w(100).flexfixe().vmargins(vspace,vspace).print(); // Limit message to 20000. The limit in the database is 64k. // But the limit for the paquet size used to communicate between // Bolixo components has been set to 64k. string place = string_f("placeholder='%s' maxlength=20000",MSG_U(I_WRITEMSG,"Write a message")); WEBID id ("talkedit",glocal.formid); field_textarea (w_content,id,5,-100,place.c_str()); } { DIV dd; dd.w(100).flexfixe().vmargins(5,0).print(); DIV ddd; ddd.dispflex().flowrow().print(); DIV dddd; dddd.flexfixe().print(); field_file_attach (w_upload); dddd.end(); dddd.flexfixe().marginleftauto().print(); button_send (); } if (!glocal.private_inbox){ DIV dd; dd.w(100).flexfixe().vmargins(vspace,0).print(); DIV ddd; ddd.dispflex().flowrow().print(); DIV dddd; dddd.flexfixe().margins(0,hspace).print(); /-#F_EXTRARECIPIENTS Recipients(opt) dddd.end(); dddd.flexgrow().print(); field_string(w_recipients,"style=width:100%",glocal.contacts); } bool ret = true; if (glocal.private_inbox && w_recipients.size()==0){ /-#E_ONERECIPIENT You must specify at least one recipient ret = false; }else{ string errmsg; util_format_shortmsg (w_content.c_str(),10,1000,100,true,glocal.con,errmsg); if (errmsg.size() > 0){ htmlout (errmsg); ret = false; } } return ret; glocal bool fail = false; glocal vector recipients; str_splitline(w_recipients.c_str(),' ',glocal.recipients); if (w_content.size() > 0){ BOB_TYPE bob; bob.setbuffer (w_content.c_str(),w_content.size(),false); (glocal.con,w_session.c_str(),"",glocal.recipients ,glocal.groupname,glocal.groupowner,bob,false,"","",""); if (!success){ htmlprintf (MSG_U(E_CANTSEND,"Can't send: %s
\n"),msg); glocal.fail = true; }
} if (strcmp(w_upload.c_str(),"")!=0){ const char *tempname = tlmpweb_getfilename(w_upload); struct stat64 st; if (stat64(tempname,&st)==-1 || st.st_size==0){ htmlprintf (MSG_U(E_EMPTYFILE,"Attached file is empty
")); glocal.fail = true; }else{ ("",tempname,glocal.fail); (glocal.con,w_session.c_str(),"",glocal.recipients ,glocal.groupname,glocal.groupowner ,content,more,"","",""); glocal.sendfile.sethandle (handle); glocal.sendfile.setresult (success,msg); (glocal.con,w_session.c_str(),handle,content,more); glocal.sendfile.setresult (success,msg); } } fail = glocal.fail; if (!fail){ w_recipients.setempty(); w_content.setempty(); w_upload.setempty(); if (glocal.nbhidden == 0 && glocal.offset == 0) w_showhidden = 1; glocal.webflip.reload_second(); } keepediting = true;
}
index_show_shortmsg (glocal.con,glocal.con_sess,glocal.id,glocal.webtabs,glocal.groupname,glocal.groupowner,glocal.offset,glocal.nbhidden);
FILEINFO info; util_entrytype(glocal.con,id,info); if (strcmp(id,"help")==0){ DIV d("webtable"); d.print(); index_doc(glocal.docpointers[SECTION_TALK],section_talk); }else if (strcmp(id,"helpmain")==0){ DIV d("webtable"); d.print(); index_doc(glocal.docpointers[SECTION_NONE],section_none); }else if (file_is_image(info.file_type)){ index_tab_title(id,info); DIV d("webtable"); d.print(); string img = util_img(step_image,"max-height:95%;",id,info.modified); /-
htmlout (img); }else if (file_is_video(info.file_type)){ index_tab_title(id,info); DIV d("webtable"); d.print(); const char *extension = tbftype[info.file_type]; string content = string_f( "" ,tlmpweb_curpage(),step_image,id,extension); htmlout (content); }else if (file_is_sound(info.file_type)){ index_tab_title(id,info); DIV d("webtable"); d.print(); string content = string_f("" ,tlmpweb_curpage(),step_image,id,tbftype[info.file_type]); htmlout (content); }else if (file_is_text(info.file_type)){ index_tab_title(id,info); DIV dd("webtable","text"); dd.autoscroll().w(100).bordertop(1,"black").print(); (glocal.con,w_session.c_str(),id,""); string tmp = util_format_shortmsg (content,700); htmlout (tmp); }
index_set_subtab (glocal.con_sess,subtab_talk);
// Confirm user if (w_confirm.empty()){ /-#E_REACHMISS You have reach this web page by mistake. Sorry! }else{ (glocal.con,w_confirm.c_str(),tlmpweb_getlang()); if (success){ glocal.account_confirmed = true; glocal.websteps.gotostep(step_login); }else{ bolixo_title ("",&glocal.websteps); DIV d; d.marginauto().w(50).vmargins(50,0).vpaddings(10,10) .paddings(10,10).border(1,"black").borderradius(5).bg("pink").print(); htmlprintf (MSG_U(E_CONFIRMFAILED,"Account confirmation failed: %s\n"),msg); } } // TAB Profile bolixo_title (MSG_U(T_PROFILE,"Profile"),this); profile(glocal.con,glocal.con_sess,glocal.docpointers); // Documentation bolixo_title (MSG_R(M_DOCUM),this); DIV d("tabs","tab"); d.w(100).print(); index_doc(glocal.docpointers[SECTION_NONE],section_none,true); // Valid password on incomplete account tlmpweb_body ("white",NULL,"background=background.png"); bolixo_title (MSG_R(T_LOGIN),this); /-

DIV d; d.bg("white").w(is_mobile ? 80 : 50).marginauto().paddings(10,10).vpaddings(10,10).borderradius(5).border(1,"black").print(); A confirmation email was sent with a link. Click on the link to enable this account.

We just sent another confirmation email (just in case the first was lost). ?> /-

htmlprintf ("%s\n",MSG_R(I_BACKTOLOGIN)); // This is used to jump to a specific area in the document by encoding a URL webstep=14&topic=some_name // This is used in the help for the main screen and to encode _HELP= tag in short message (greeting // for new account). bolixo_title (MSG_R(M_DOCUM),this); DIV d("tabs","tab"); d.w(100).print(); DOC_ID *ptdoc = nullptr; if (strcmp(w_topic.c_str(),"main")==0){ ptdoc = §ion_main; }else if (strcmp(w_topic.c_str(),"interests")==0){ ptdoc = §ion_interests; }else if (strcmp(w_topic.c_str(),"contactreq")==0){ ptdoc = §ion_contact_req; }else if (strcmp(w_topic.c_str(),"started")==0){ ptdoc = §ion_started; }else if (strcmp(w_topic.c_str(),"intro")==0){ ptdoc = §ion_intro; }else if (strcmp(w_topic.c_str(),"talk")==0){ ptdoc = §ion_talk; }else if (strcmp(w_topic.c_str(),"project")==0){ ptdoc = §ion_project; }else if (strcmp(w_topic.c_str(),"profile")==0){ ptdoc = §ion_profile; }else if (strcmp(w_topic.c_str(),"ui")==0){ ptdoc = §ion_ui; }else if (strcmp(w_topic.c_str(),"publish")==0){ ptdoc = §ion_publish; }else if (strcmp(w_topic.c_str(),"checkers")==0){ ptdoc = §ion_checker; }else if (strcmp(w_topic.c_str(),"chess")==0){ ptdoc = §ion_chess; }else if (strcmp(w_topic.c_str(),"sudoku")==0){ ptdoc = §ion_sudoku; } if (ptdoc != nullptr){ // When a topic is selected, we reset the document pointer // so the requested section is used. glocal.docpointers[SECTION_NONE].reset(); }else{ ptdoc = §ion_none; } index_doc(glocal.docpointers[SECTION_NONE],*ptdoc,true); // View a document in its own browser tab setextraargs(string_f("&document=%s",w_document.c_str())); const char *id = w_document.c_str(); const char *name = strrchr(id,'/'); if (name != nullptr){ name++; }else{ name = id; } bolixo_title (name,this,true); WEBID wid("browser"); unsigned content_width,content_height; tlmpweb_gettablegeometry(wid,content_height,content_width); DIV d("tabs","browser"); d.w(100).print(); FORM_HIDDEN h(w_document); projects_documents (glocal.con,glocal.con_sess,id,id,content_width,content_height); bolixo_title (MSG_R(M_TECHDOCUM),this); DIV d("tabs","tab"); d.w(100).print(); bool index = tlmpweb_ismobile() ? false : true; bolixo_techdoc (glocal.docpointers[SECTION_TECH],section_none,userinfo.name.c_str(),w_robot,index); } extern "C" void tlmp_initmod() { translat_load ("bolixo"); } extern "C" void webmain() { if (w_test == 1){ htmlout ("\n\nok\n\n\n"); return; } long long start = fdpass_getnow(); #ifdef INSTRUMENT fprintf (f_instrument,"%Ld --------\n",start); #endif { // The tlcc TLMP converter has a problem with a ("unix:","/tmp/stop.sock",1); webmain_real(); end=true; webmain_real(); } long long end = fdpass_getnow(); glocal long long diff = end - start; ("/tmp/duration",true); struct rusage u; if (getrusage(RUSAGE_SELF,&u)==-1){ fprintf (fout,"syscall getrusage failed: %s\n",strerror(errno)); } fprintf (fout,"%Ld.%06Ld [%lu.%06lu,%lu.%06lu] %s?%s\n" ,glocal.diff/1000000,glocal.diff%1000000 ,u.ru_utime.tv_sec,u.ru_utime.tv_usec ,u.ru_stime.tv_sec,u.ru_stime.tv_usec ,tlmpweb_curpage(),getenv ("QUERY_STRING")); return 0; }