void post(void) { messagerec m; postrec p; char s[121]; int i,dm,a,flag; time_t time1, time2; flag=0; m.storage_type=subboards[curlsub].storage_type; a=0; time1=time(NULL); // write_inst(INST_LOC_POST,curlsub,INST_FLAGS_NONE); // inmsg(&m,p.title,&a,1,(subboards[curlsub].filename),ALLOW_FULLSCREEN, // subboards[curlsub].name, (subboards[curlsub].anony&anony_no_tag)?1:0); savefile(buffer,length,&m,(subboards[curlsub].filename)); if (m.stored_as!=0xffffffff) { p.anony=a; p.msg=m; p.ownersys=0; p.owneruser=usernum; lock_status(); p.qscan=status.qscanptr++; save_status(); time((long *)(&p.daten)); p.status=0; open_sub(1); if ((xsubs[curlsub].num_nets) && (subboards[curlsub].anony & anony_val_net) && (!lcs() || irt[0])) { p.status |= status_pending_net; dm=1; for (i=nummsgs; (i>=1) && (i>(nummsgs-28)); i--) { if (get_post(i)->status & status_pending_net) { dm=0; break; } } if (dm) { sprintf(s,get_stringx(1,37),subboards[curlsub].name); ssm(1,0,s); } } if (nummsgs>=subboards[curlsub].maxmsgs) { i=1; dm=0; while ((dm==0) && (i<=nummsgs)) { if ((get_post(i)->status & status_no_delete)==0) dm=i; ++i; } if (dm==0) dm=1; delete(dm); } add_post(&p); lock_status(); ++status.msgposttoday; ++status.localposts; save_status(); close_sub(); if (xsubs[curlsub].num_nets) { if (!(p.status & status_pending_net)) send_net_post(&p, subboards[curlsub].filename, curlsub); } } }
void deletemsg(int mn) { postrec *p1, p; int close_file=0; unsigned int nb; char *buf; // char scratch[181]; long len, l, cp; /* open file, if needed */ if (sub_f <= 0) { open_sub(1); close_file=1; } /* see if anything changed */ read_status(); if (sub_f >= 0) { if ((mn>0) && (mn<=nummsgs)) { buf=(char *)malloca(BUFSIZE); if (buf) { p1=get_post(mn); remove_link(&(p1->msg),(subboards[curlsub].filename)); cp=((long)mn+1)*sizeof(postrec); len=((long)(nummsgs+1))*sizeof(postrec); do { l=len-cp; if (l<BUFSIZE) nb=(int)l; else nb=BUFSIZE; if (nb) { sh_lseek(sub_f, cp, SEEK_SET); sh_read(sub_f, buf, nb); sh_lseek(sub_f, cp-sizeof(postrec), SEEK_SET); sh_write(sub_f, buf, nb); cp += nb; } } while (nb==BUFSIZE); /* update # msgs */ sh_lseek(sub_f, 0L, SEEK_SET); sh_read(sub_f, &p, sizeof(postrec)); p.owneruser--; nummsgs=p.owneruser; sh_lseek(sub_f, 0L, SEEK_SET); sh_write(sub_f, &p, sizeof(postrec)); /* cache is now invalid */ believe_cache = 0; bbsfree(buf); } } } /* close file, if needed */ if (close_file) close_sub(); }
void valscan() { // Must be local cosysop or better if (!lcs()) { return; } int ac = 0; int os = GetSession()->GetCurrentMessageArea(); if (uconfsub[1].confnum != -1 && okconf(GetSession()->GetCurrentUser())) { ac = 1; tmp_disable_conf(true); } bool done = false; for (int sn = 0; sn < GetSession()->num_subs && !hangup && !done; sn++) { if (!iscan(sn)) { continue; } if (GetSession()->GetCurrentReadMessageArea() < 0) { return; } uint32_t sq = qsc_p[sn]; // Must be sub with validation "on" if (!(xsubs[GetSession()->GetCurrentReadMessageArea()].num_nets) || !(subboards[GetSession()->GetCurrentReadMessageArea()].anony & anony_val_net)) { continue; } GetSession()->bout.NewLine(); GetSession()->bout.Color(2); GetSession()->bout.ClearEOL(); GetSession()->bout << "{{ ValScanning " << subboards[GetSession()->GetCurrentReadMessageArea()].name << " }}\r\n"; lines_listed = 0; GetSession()->bout.ClearEOL(); if (okansi() && !newline) { GetSession()->bout << "\r\x1b[2A"; } for (int i = 1; i <= GetSession()->GetNumMessagesInCurrentMessageArea() && !hangup && !done; i++) { // was i = 0 if (get_post(i)->status & status_pending_net) { CheckForHangup(); GetSession()->localIO()->tleft(true); if (i > 0 && i <= GetSession()->GetNumMessagesInCurrentMessageArea()) { bool next; int val; read_message(i, &next, &val); GetSession()->bout << "|#4[|#4Subboard: " << subboards[GetSession()->GetCurrentReadMessageArea()].name << "|#1]\r\n"; GetSession()->bout << "|#1D|#9)elete, |#1R|#9)eread |#1V|#9)alidate, |#1M|#9)ark Validated, |#1Q|#9)uit: |#2"; char ch = onek("QDVMR"); switch (ch) { case 'Q': done = true; break; case 'R': i--; continue; case 'V': { open_sub(true); resynch(&i, nullptr); postrec *p1 = get_post(i); p1->status &= ~status_pending_net; write_post(i, p1); close_sub(); send_net_post(p1, subboards[GetSession()->GetCurrentReadMessageArea()].filename, GetSession()->GetCurrentReadMessageArea()); GetSession()->bout.NewLine(); GetSession()->bout << "|#7Message sent.\r\n\n"; } break; case 'M': if (lcs() && i > 0 && i <= GetSession()->GetNumMessagesInCurrentMessageArea() && subboards[GetSession()->GetCurrentReadMessageArea()].anony & anony_val_net && xsubs[GetSession()->GetCurrentReadMessageArea()].num_nets) { open_sub(true); resynch(&i, nullptr); postrec *p1 = get_post(i); p1->status &= ~status_pending_net; write_post(i, p1); close_sub(); GetSession()->bout.NewLine(); GetSession()->bout << "|#9Not set for net pending now.\r\n\n"; } break; case 'D': if (lcs()) { if (i > 0) { open_sub(true); resynch(&i, nullptr); postrec p2 = *get_post(i); delete_message(i); close_sub(); if (p2.ownersys == 0) { WUser tu; GetApplication()->GetUserManager()->ReadUser(&tu, p2.owneruser); if (!tu.IsUserDeleted()) { if (static_cast<unsigned long>(date_to_daten(tu.GetFirstOn())) < p2.daten) { GetSession()->bout.NewLine(); GetSession()->bout << "|#2Remove how many posts credit? "; char szNumCredits[ 11 ]; input(szNumCredits, 3, true); int nNumPostCredits = 1; if (szNumCredits[0]) { nNumPostCredits = atoi(szNumCredits); } nNumPostCredits = std::min<int>(tu.GetNumMessagesPosted(), nNumPostCredits); if (nNumPostCredits) { tu.SetNumMessagesPosted(tu.GetNumMessagesPosted() - static_cast<unsigned short>(nNumPostCredits)); } GetSession()->bout.NewLine(); GetSession()->bout << "|#3Post credit removed = " << nNumPostCredits << wwiv::endl; tu.SetNumDeletedPosts(tu.GetNumDeletedPosts() + 1); GetApplication()->GetUserManager()->WriteUser(&tu, p2.owneruser); GetApplication()->UpdateTopScreen(); } } } resynch(&i, &p2); } } break; } } } } qsc_p[sn] = sq; } if (ac) { tmp_disable_conf(false); } GetSession()->SetCurrentMessageArea(os); GetSession()->bout.NewLine(2); }
void handle_search_page(const crow::request &req, crow::response &res, std::string str, uint64_t page) { auto records = Index::search(URLEncoding::url_decode(str)); rj::StringBuffer result; rj::Writer<rj::StringBuffer> writer(result); writer.StartObject(); // Root writer.Key("results"); writer.StartArray(); // Results auto rec = records.begin(); uint32_t skipped = search_length * (page - 1); while(rec != records.end() && skipped) { --skipped; ++rec; } uint32_t i = 0; for(; rec != records.end() && i < search_length; ++rec) { Post p = get_post(rec->first); uint32_t lineEnd = 0, lineCount = 0; while(lineEnd < p.content.length() && p.content[lineEnd] != '\n') ++lineEnd; std::vector<uint32_t> lineHits(1); std::vector<uint32_t> lineEnds(1); lineEnds[0] = lineEnd; lineHits[0] = 0; bool inbody = false; writer.StartObject(); // Record writer.Key("post_id"); writer.Uint64(rec->first); writer.Key("hits"); writer.StartArray(); // Hits uint32_t offsetPtr = 0; uint32_t offsetUTF8 = 0; for(auto &hit : rec->second) { uint32_t offsetAscii = std::get<0>(hit); while(offsetPtr < offsetAscii) if((p.content[offsetPtr++] & 0xC0) != 0x80) ++offsetUTF8; uint32_t lengthAscii = std::get<1>(hit); uint32_t lengthPtr = 0; uint32_t lengthUTF8 = 0; while(lengthPtr < lengthAscii) if((p.content[offsetPtr + (lengthPtr++)] & 0xC0) != 0x80) ++lengthUTF8; writer.StartObject(); // Hit writer.Key("offset"); writer.Uint(offsetUTF8); writer.Key("length"); writer.Uint(lengthUTF8); writer.Key("topic"); writer.Bool(std::get<2>(hit)); writer.EndObject(); // Hit if(!std::get<2>(hit)){ inbody = true; while(std::get<0>(hit) > lineEnd) { ++lineCount; ++lineEnd; while(lineEnd < p.content.length() && p.content[lineEnd] != '\n') ++lineEnd; lineEnds.push_back(lineEnd); lineHits.push_back(0); } } ++lineHits[lineCount]; } writer.EndArray(); // Hits // Info writer.Key("topic"); writer.String(p.topic); writer.Key("tags"); writer.StartArray(); // Tags for(auto &tag : p.tags) writer.String(tag); writer.EndArray(); // Tags writer.Key("url"); writer.String(p.url); writer.Key("updated"); writer.Uint64(p.update_time); // Preview ++lineCount; if(inbody) { uint32_t maxStart = 0; if(search_preview < lineCount) { uint32_t maxSum; uint32_t sum = 0; for(uint32_t i = 0; i < search_preview ; ++i) { sum += lineHits[i]; } maxSum = sum; for(uint32_t start = 1; start + search_preview <= lineCount; ++start) { sum -= lineEnds[start - 1]; sum += lineEnds[start - 1 + search_preview]; if(sum > maxSum) { maxSum = sum; maxStart = start; } } } uint32_t maxEnd = maxStart + search_preview - 1; if(maxEnd >= lineCount) maxEnd = lineCount - 1; while(maxEnd > maxStart && lineHits[maxEnd] == 0) --maxEnd; while(maxStart < maxEnd && lineHits[maxStart] == 0) ++maxStart; const uint32_t startIndex = maxStart == 0 ? 0 : lineEnds[maxStart-1] +1; const uint32_t endIndex = lineEnds[maxEnd]; writer.Key("preview"); writer.String(p.content.substr(startIndex, endIndex - startIndex)); } else { // Only in title uint32_t currentLine = 0; uint32_t ptr = 0; while(ptr < p.content.size() && currentLine < search_preview) { while(ptr < p.content.size() && p.content[ptr] != '\n') ++ptr; ++currentLine; ++ptr; } writer.Key("preview"); writer.String(p.content.substr(0, ptr - 1)); } writer.EndObject(); // Record ++i; } writer.EndArray(); // Results writer.Key("pages"); writer.Uint64((records.size() + search_length - 1) / search_length); writer.EndObject(); // Root res.end(result.GetString()); }