From 823a7c8699ab762c7948ffc73afa6e2d905c69b7 Mon Sep 17 00:00:00 2001 From: Ianos Gnatiuc Date: Mon, 20 Feb 2006 21:44:10 +0000 Subject: [PATCH] All buffers used with TokenXlat function now are of variable size --- docs/notework.txt | 8 + golded3/gectrl.cpp | 13 +- golded3/gedoss.cpp | 2 +- golded3/geedit2.cpp | 4 +- golded3/gefile.cpp | 15 +- golded3/gemsgs.cpp | 883 ++++++++++++++++++++++---------------- golded3/gepost.cpp | 5 +- golded3/geprot.h | 8 +- golded3/geread2.cpp | 13 +- golded3/getpls.cpp | 27 +- goldlib/gall/gfilutil.h | 9 + goldlib/gall/gstrall.h | 2 + goldlib/gall/gstrutil.cpp | 37 ++ 13 files changed, 610 insertions(+), 416 deletions(-) diff --git a/docs/notework.txt b/docs/notework.txt index 7ef855a..d9a5bcd 100644 --- a/docs/notework.txt +++ b/docs/notework.txt @@ -10,6 +10,14 @@ ______________________________________________________________________ Notes for GoldED+ 1.1.5, /snapshot/ ______________________________________________________________________ ++ Macro @pad is recursive now. + Example: @pad{=C79}{ @oname{I}{You} } + +! Changed macro @pipe{`command`} to @pipe{command} + +- All buffers used with TokenXlat function now are of variable size. + This may prevent some buffer overflow bugs. + = Snapshot for the February 18, 2006. + Added new macro: @pipe{`command`}, that inserts command's stdout in diff --git a/golded3/gectrl.cpp b/golded3/gectrl.cpp index 5c6d289..c425b58 100644 --- a/golded3/gectrl.cpp +++ b/golded3/gectrl.cpp @@ -720,14 +720,15 @@ void DoTearorig(int mode, GMsg* msg) { origin = AA->Origin(); - if(AA->Taglinesupport()) { + if (AA->Taglinesupport()) + { if(*msg->tagline == '@') GetRandomLine(msg->tagline, sizeof(msg->tagline), msg->tagline+1); - TokenXlat(mode, msg->tagline, msg, msg, CurrArea); + TokenXlat(mode, msg->tagline, sizeof(msg->tagline), msg, msg, CurrArea); strbtrim(msg->tagline); } - TokenXlat(mode, msg->tearline, msg, msg, CurrArea); + TokenXlat(mode, msg->tearline, sizeof(msg->tearline), msg, msg, CurrArea); ctrlinfo = AA->Ctrlinfo(); @@ -775,9 +776,9 @@ void DoTearorig(int mode, GMsg* msg) { } MakeOrigin(msg, origin.c_str()); - TokenXlat(mode, msg->tagline, msg, msg, CurrArea); - TokenXlat(mode, msg->tearline, msg, msg, CurrArea); - TokenXlat(mode, msg->origin, msg, msg, CurrArea); + TokenXlat(mode, msg->tagline, sizeof(msg->tagline), msg, msg, CurrArea); + TokenXlat(mode, msg->tearline, sizeof(msg->tearline), msg, msg, CurrArea); + TokenXlat(mode, msg->origin, sizeof(msg->origin), msg, msg, CurrArea); // Add the tagline, tearline and origin as defined if(AA->Taglinesupport() and *msg->tagline) { diff --git a/golded3/gedoss.cpp b/golded3/gedoss.cpp index aad2e46..399d525 100644 --- a/golded3/gedoss.cpp +++ b/golded3/gedoss.cpp @@ -217,7 +217,7 @@ void Cleanup(void) { // ------------------------------------------------------------------ // Multipurpose DOS shell function -int ShellToDos(char* command, char* message, vattr cls, int cursor, int pause) { +int ShellToDos(const char* command, char* message, vattr cls, int cursor, int pause) { int error = 0; diff --git a/golded3/geedit2.cpp b/golded3/geedit2.cpp index 541dabc..bbb58cf 100644 --- a/golded3/geedit2.cpp +++ b/golded3/geedit2.cpp @@ -1021,7 +1021,7 @@ void IEclass::editimport(Line* __line, char* __filename, bool imptxt) { { sprintf(_parabuf, "%s\n", CFG->importbegin); strischg(_parabuf, "@file", imp_filename); - TokenXlat(MODE_NEW, _parabuf, msgptr, msgptr, CurrArea); + TokenXlat(MODE_NEW, _parabuf, EDIT_PARABUFLEN, true, msgptr, msgptr, CurrArea); _parabuf[strlen(_parabuf)-1] = '\n'; _parabuf[margintext] = NUL; _parabuf[margintext-1] = '\n'; @@ -1198,7 +1198,7 @@ void IEclass::editimport(Line* __line, char* __filename, bool imptxt) { { sprintf(_parabuf, "%s\n", *CFG->importend ? CFG->importend : CFG->importbegin); strischg(_parabuf, "@file", imp_filename); - TokenXlat(MODE_NEW, _parabuf, msgptr, msgptr, CurrArea); + TokenXlat(MODE_NEW, _parabuf, EDIT_PARABUFLEN, true, msgptr, msgptr, CurrArea); _parabuf[strlen(_parabuf)-1] = '\n'; _parabuf[margintext] = NUL; _parabuf[margintext-1] = '\n'; diff --git a/golded3/gefile.cpp b/golded3/gefile.cpp index d47e024..ded613a 100644 --- a/golded3/gefile.cpp +++ b/golded3/gefile.cpp @@ -478,10 +478,11 @@ void FileSelect(GMsg* msg, char* title, FileSpec* fspec) { // ------------------------------------------------------------------ -void CreateFileAddr(GMsg* msg) { - +void CreateFileAddr(GMsg* msg) +{ // Create message - char* _txt; + std::string _txt; + if(msg->attr.att()) _txt = LNG->AutoAttachMsg; else if(msg->attr.frq()) @@ -490,9 +491,11 @@ void CreateFileAddr(GMsg* msg) { _txt = LNG->AutoUpdreqMsg; else _txt = LNG->EmptyMsg; - msg->txt = (char*)throw_realloc(msg->txt, strlen(_txt)+256); - strcpy(msg->txt, _txt); - TokenXlat(MODE_NEW, msg->txt, msg, msg, CurrArea); + + TokenXlat(MODE_NEW, _txt, msg, msg, CurrArea); + + msg->txt = (char*)throw_realloc(msg->txt, _txt.length()+1); + strcpy(msg->txt, _txt.c_str()); } diff --git a/golded3/gemsgs.cpp b/golded3/gemsgs.cpp index 00bc581..ff463b5 100644 --- a/golded3/gemsgs.cpp +++ b/golded3/gemsgs.cpp @@ -35,68 +35,74 @@ // ------------------------------------------------------------------ -static bool tokenxchg(char*& dst, char* tok, const char* src, int len = 0, int cnt = 0, ...) { +static bool tokenxchg(std::string &input, std::string::iterator &pos, + const char* tok, const char* src, + size_t len = 0, size_t cnt = 0, ...) +{ + size_t toklen = strlen(tok); - uint toklen = strlen(tok); - char buf[100]; + if (strnieql(pos, tok, toklen)) + { + std::string str = src; + std::string::iterator tokend = pos+toklen; - if(*dst != *tok) - return false; - if(not strnieql(dst, tok, toklen)) { - if(len and *dst and (*(dst+1) == '_') and *(dst+2)) { - if(not strnieql(dst+2, tok+1, toklen-1)) - return false; - else - toklen++; - } - else - return false; - } - else - len = 0; + if (cnt) + { + va_list a; + va_start(a, cnt); - va_list a; - va_start(a, cnt); - for(int i = 0; i < cnt; i ++) { - bool use = make_bool(va_arg(a, int)); - if(dst[toklen] == '{') { - char *p = strchr(dst+toklen, '}'); - if(p) { - uint dstlen = p-dst-toklen-1; - if(use and dstlen) { - strxcpy (buf, dst+toklen+1, dstlen+1); - src = buf; + for (int i = 0; i < cnt; i++) + { + std::string::iterator beg = tokend; + if (*beg++ != '{') break; + + std::string::iterator end; + for (end = beg; end != input.end(); end++) + { + if (*end == '}') + { + if (va_arg(a, int)) + str = input.substr(beg-input.begin(), end-beg); + + end++; + break; + } } - toklen = p-dst+1; - } - } - } - va_end(a); - uint sl = strlen(src); - uint srclen = (len == 0) ? sl : len; - memmove(dst+srclen, dst+toklen, strlen(dst+toklen)+1); - memset(dst, ' ', srclen); - memcpy(dst, src, ((len != 0) and (len < sl)) ? len : sl); - dst += srclen; - return true; + tokend = end; + } + + va_end(a); + } + + size_t strlen = str.length(); + if (!len || (len > strlen)) len = strlen; + + size_t idx = pos - input.begin(); + input.replace(pos, tokend, str.c_str(), len); + pos = input.begin() + idx; + + return true; + } + + return false; } // ------------------------------------------------------------------ -inline bool domain_requested(const char *str, size_t pos) { - - if(str[1] == '_') pos++; +inline bool domain_requested(std::string::iterator str, size_t pos) +{ + if (*(str+1) == '_') pos++; return strnieql(str+pos, "{domain}", 8); } // ------------------------------------------------------------------ -char* TokenXlat(int mode, char* input, GMsg* msg, GMsg* oldmsg, int __origarea) { - +void TokenXlat(int mode, std::string &input, GMsg* msg, GMsg* oldmsg, int __origarea) +{ static char revbuf[5] = ""; - if(revbuf[0] == NUL) + if (revbuf[0] == NUL) sprintf(revbuf, "%02d%02d", str2mon(__gver_date__), atoi(&__gver_date__[4])); char attr[80]; @@ -132,357 +138,396 @@ char* TokenXlat(int mode, char* input, GMsg* msg, GMsg* oldmsg, int __origarea) char msgs[16]; sprintf(msgs, "%u", AA->Msgn.Count() + (msg->attr.nwm() ? 1 : 0)); - if((mode == MODE_QUOTE) or (mode == MODE_REPLYCOMMENT) or (mode == MODE_REPLY)) { - if(AL.AreaIdToPtr(__origarea)->Areareplydirect() and oldmsg->areakludgeid) + if ((mode == MODE_QUOTE) or (mode == MODE_REPLYCOMMENT) or (mode == MODE_REPLY)) + { + if (AL.AreaIdToPtr(__origarea)->Areareplydirect() and oldmsg->areakludgeid) origareaid = oldmsg->areakludgeid; } - else if(mode != MODE_FORWARD) + else if (mode != MODE_FORWARD) modereptr = msg->re; char buf[100]; - char* dst = input; - while(*dst) { - while((*dst != '@') and (*dst != LF) and *dst) - dst++; - if(*dst == LF) - *dst++ = CR; - else if(*dst == '@') { - if(dst[1] == '@') { - memmove(dst, dst+1, strlen(dst+1)+1); - dst++; + std::string::iterator dst; + for (dst = input.begin(); dst != input.end(); ) + { + if (*dst == LF) *dst = CR; + else if (*dst != '@') ; + else if (*(dst+1) == '@') input.erase(dst); + else + { + if (tokenxchg(input, dst, "@cecho", AA->echoid())) + continue; + + if (tokenxchg(input, dst, "@cdesc", AA->desc())) + continue; + + if (tokenxchg(input, dst, "@oecho", origareaid)) + continue; + + if (tokenxchg(input, dst, "@odesc", AL.AreaEchoToPtr(origareaid)->desc())) + continue; + + if (tokenxchg(input, dst, "@oname", strbtrim(strtmp(oldmsg->By())), 34, 2, + (int)msg->by_me(), (int)msg->by_you())) + continue; + + if (tokenxchg(input, dst, "@ofname", strlword(oldmsg->By()), 0, 2, + (int)msg->by_me(), (int)msg->by_you())) + continue; + + if (tokenxchg(input, dst, "@olname", strrword(oldmsg->By()), 0, 2, + (int)msg->by_me(), (int)msg->by_you())) + continue; + + if (tokenxchg(input, dst, "@odate", odate)) + continue; + + if (tokenxchg(input, dst, "@otime", otime)) + continue; + + if (tokenxchg(input, dst, "@odtime", odtime)) + continue; + + if (tokenxchg(input, dst, "@otzoffset", (oldmsg->tzutc == -32767) ? "" : (sprintf(buf, " %+05d", oldmsg->tzutc), buf))) + continue; + + if (tokenxchg(input, dst, "@ofrom", oldmsg->ifrom)) + continue; + + if (tokenxchg(input, dst, "@oto", oldmsg->ito)) + continue; + + if (tokenxchg(input, dst, "@omessageid", oldmsg->messageid ? oldmsg->messageid : "")) + continue; + + if (tokenxchg(input, dst, "@omsgid", *msg->replys ? msg->replys : "")) + continue; + + if (tokenxchg(input, dst, "@dname", strbtrim(strtmp(oldmsg->To())), 34, 3, + (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all())) + continue; + + if (tokenxchg(input, dst, "@dpgp", *msg->iaddr ? msg->iaddr : msg->To())) + continue; + + if (tokenxchg(input, dst, "@dfname", strlword(oldmsg->To()), 0, 3, + (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all())) + continue; + + if (tokenxchg(input, dst, "@dlname", strrword(oldmsg->To()), 0, 3, + (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all())) + continue; + + if (origareaisinet) + { + if (tokenxchg(input, dst, "@oaddr", oldmsg->iorig, 19, 1, 0)) + continue; + + if (tokenxchg(input, dst, "@daddr", oldmsg->iaddr, 19, 1, 0)) + continue; } - else { - if(tokenxchg(dst, "@cecho", AA->echoid())) - continue; - if(tokenxchg(dst, "@cdesc", AA->desc())) - continue; - if(tokenxchg(dst, "@oecho", origareaid)) - continue; - if(tokenxchg(dst, "@odesc", AL.AreaEchoToPtr(origareaid)->desc())) - continue; - if(tokenxchg(dst, "@oname", strbtrim(strtmp(oldmsg->By())), 34, 2, - (int)msg->by_me(), (int)msg->by_you())) - continue; - if(tokenxchg(dst, "@ofname", strlword(oldmsg->By()), 0, 2, - (int)msg->by_me(), (int)msg->by_you())) - continue; - if(tokenxchg(dst, "@olname", strrword(oldmsg->By()), 0, 2, - (int)msg->by_me(), (int)msg->by_you())) - continue; - if(tokenxchg(dst, "@odate", odate)) - continue; - if(tokenxchg(dst, "@otime", otime)) - continue; - if(tokenxchg(dst, "@odtime", odtime)) - continue; - if(tokenxchg(dst, "@otzoffset", (oldmsg->tzutc == -32767) ? "" : (sprintf(buf, " %+05d", oldmsg->tzutc), buf))) - continue; - if(tokenxchg(dst, "@ofrom", oldmsg->ifrom)) - continue; - if(tokenxchg(dst, "@oto", oldmsg->ito)) - continue; - if(tokenxchg(dst, "@omessageid", oldmsg->messageid ? oldmsg->messageid : "")) - continue; - if(tokenxchg(dst, "@omsgid", *msg->replys ? msg->replys : "")) - continue; - if(tokenxchg(dst, "@dname", strbtrim(strtmp(oldmsg->To())), 34, 3, - (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all())) - continue; - if(tokenxchg(dst, "@dpgp", *msg->iaddr ? msg->iaddr : msg->To())) - continue; - if(tokenxchg(dst, "@dfname", strlword(oldmsg->To()), 0, 3, - (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all())) - continue; - if(tokenxchg(dst, "@dlname", strrword(oldmsg->To()), 0, 3, - (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all())) - continue; - if(origareaisinet) { - if(tokenxchg(dst, "@oaddr", oldmsg->iorig, 19, 1, 0)) - continue; - if(tokenxchg(dst, "@daddr", oldmsg->iaddr, 19, 1, 0)) - continue; - } - if(currareaisinet) { - if(tokenxchg(dst, "@caddr", AA->Internetaddress(), 19, 1, 0)) - continue; - if(tokenxchg(dst, "@faddr", msg->iorig, 19, 1, 0)) - continue; - if(tokenxchg(dst, "@taddr", msg->iaddr, 19, 1, 0)) - continue; - } - if((not origareaisinet or not currareaisinet) and (strlen(dst) >= 6)) { - bool dr = domain_requested(dst, 6); - if(not origareaisinet) { - if(tokenxchg(dst, "@oaddr", oldmsg->orig.make_string(buf, dr ? oldmsg->odom : NULL), 19, 1, 0)) - continue; - if(strnieql(dst, "@o3daddr", 8)) { - ftn_addr boss = oldmsg->orig; - boss.point = 0; - tokenxchg(dst, "@o3daddr", boss.make_string(buf, domain_requested(dst, 8) ? oldmsg->odom : NULL), 19, 1, 0); - continue; - } - if(tokenxchg(dst, "@daddr", oldmsg->dest.make_string(buf, dr ? oldmsg->ddom : NULL), 19, 1, 0)) - continue; - if(strnieql(dst, "@d3daddr", 8)) { - ftn_addr boss = oldmsg->dest; - boss.point = 0; - tokenxchg(dst, "@d3daddr", boss.make_string(buf, domain_requested(dst, 8) ? oldmsg->ddom : NULL), 19, 1, 0); - continue; - } - } - if(not currareaisinet) { - const gaka &caka=AA->Aka(); - if(tokenxchg(dst, "@caddr", caka.addr.make_string(buf, dr ? caka.domain : NULL), 19, 1, 0)) - continue; - if(strnieql(dst, "@c3daddr", 8)) { - ftn_addr boss = caka.addr; - boss.point = 0; - tokenxchg(dst, "@c3daddr", boss.make_string(buf, domain_requested(dst, 8) ? caka.domain : NULL), 19, 1, 0); - continue; - } - if(tokenxchg(dst, "@taddr", msg->dest.make_string(buf, dr ? msg->ddom : NULL), 19, 1, 0)) - continue; - if(strnieql(dst, "@t3daddr", 8)) { - ftn_addr boss = msg->dest; - boss.point = 0; - tokenxchg(dst, "@t3daddr", boss.make_string(buf, domain_requested(dst, 8) ? msg->ddom : NULL), 19, 1, 0); - continue; - } - if(tokenxchg(dst, "@faddr", msg->orig.make_string(buf, dr ? msg->odom : NULL), 19, 1, 0)) - continue; - if(strnieql(dst, "@f3daddr", 8)) { - ftn_addr boss = msg->orig; - boss.point = 0; - tokenxchg(dst, "@f3daddr", boss.make_string(buf, domain_requested(dst, 8) ? msg->odom : NULL), 19, 1, 0); - continue; - } - } - } - if(tokenxchg(dst, "@tname", strbtrim(strtmp(msg->To())), 34, 3, - (int)false, (int)false, (int)msg->to_all())) - continue; - if(tokenxchg(dst, "@tfname", strlword(msg->To()), 0, 3, - (int)false, (int)false, (int)msg->to_all())) - continue; - if(tokenxchg(dst, "@tlname", strrword(msg->To()), 0, 3, - (int)false, (int)false, (int)msg->to_all())) - continue; - if(tokenxchg(dst, "@cname", AA->Username().name, 34)) - continue; - if(tokenxchg(dst, "@cfname", strlword(strcpy(buf, AA->Username().name)))) - continue; - if(tokenxchg(dst, "@clname", strrword(strcpy(buf, AA->Username().name)))) - continue; - if(tokenxchg(dst, "@cfrom", msg->ifrom)) - continue; - if(tokenxchg(dst, "@cto", msg->ito)) - continue; - if(tokenxchg(dst, "@cdate", cdate)) - continue; - if(tokenxchg(dst, "@ctime", ctime)) - continue; - if(tokenxchg(dst, "@cdtime", cdtime)) - continue; - if(tokenxchg(dst, "@ctzoffset", AA->Usetzutc() ? (sprintf(buf, " %+05d", tzoffset()), buf) : "")) - continue; - if(tokenxchg(dst, "@fname", strbtrim(strtmp(msg->By())), 34)) - continue; - if(tokenxchg(dst, "@fpgp", *msg->iorig ? msg->iorig : msg->By())) - continue; - if(tokenxchg(dst, "@ffname", strlword(msg->By()))) - continue; - if(tokenxchg(dst, "@flname", strrword(msg->By()))) - continue; - if(strnieql(dst, "@dpseudo", 8)) { - if(*(oldmsg->pseudoto) == NUL) - build_pseudo(oldmsg); - tokenxchg(dst, "@dpseudo", oldmsg->pseudoto, 0, 3, (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all()); - continue; - } - if(strnieql(dst, "@opseudo", 8)) { - if(*(oldmsg->pseudofrom) == NUL) - build_pseudo(oldmsg, false); - tokenxchg(dst, "@opseudo", oldmsg->pseudofrom, 0, 2, (int)msg->by_me(), (int)msg->by_you()); - continue; - } - if(strnieql(dst, "@tpseudo", 8)) { - if(*(msg->pseudoto) == NUL) - build_pseudo(msg); - tokenxchg(dst, "@tpseudo", msg->pseudoto, 0, 3, (int)false, (int)false, (int)msg->to_all()); - continue; - } - // Same as above (just for backward compatibility) - if(strnieql(dst, "@pseudo", 7)) { - if(*(msg->pseudoto) == NUL) - build_pseudo(msg); - tokenxchg(dst, "@pseudo", msg->pseudoto, 0, 3, (int)false, (int)false, (int)msg->to_all()); - continue; - } - if(strnieql(dst, "@fpseudo", 8)) { - if(*(msg->pseudofrom) == NUL) - build_pseudo(msg, false); - tokenxchg(dst, "@fpseudo", msg->pseudofrom); - continue; - } - if(tokenxchg(dst, "@msgno", msgno)) - continue; - if(tokenxchg(dst, "@msgs", msgs)) - continue; - if(tokenxchg(dst, "@cpseudo", *AA->Nickname() ? AA->Nickname() : strlword(strcpy(buf, AA->Username().name), " @."))) - continue; - if(tokenxchg(dst, "@version", __gver_ver__)) - continue; - if(tokenxchg(dst, "@ver", __gver_shortver__)) - continue; - if(tokenxchg(dst, "@rev", revbuf)) - continue; - if(strnieql(dst, "@align{", 6)) { - char *ptr = strchr(dst, '}'); - if(ptr) { - int size = atoi(dst+7) - (dst-input); - if(size > 0) { - char filler = ' '; - if((ptr[1] == '{') and (ptr[3] == '}')) { - filler = ptr[2]; - ptr += 3; - } - memmove(dst+size, ptr+1, strlen(ptr+1)+1); - memset(dst, filler, size); - dst += size; - } - else { - if ((ptr[1] == '{') and (ptr[3] == '}')) - ptr += 3; - memmove(dst, ptr+1, strlen(ptr+1)+1); - } - } - else { - memmove(dst, dst+6, strlen(dst+6)+1); - } - continue; - } - if(tokenxchg(dst, "@pid", __gver_shortpid__)) - continue; - if(tokenxchg(dst, "@longpid", __gver_longpid__)) - continue; - if(tokenxchg(dst, "@widepid", xmailer)) - continue; - if(tokenxchg(dst, "@osver", osver)) - continue; - if(tokenxchg(dst, "@osslash", __gver_platform__)) - continue; - if(tokenxchg(dst, "@subject", modereptr)) - continue; - if(tokenxchg(dst, "@attr", attr)) - continue; - if(tokenxchg(dst, "@tagline", - HandleRandomLine(strxcpy(buf, AA->Tagline(), sizeof(buf)), sizeof(buf)))) - continue; - if(tokenxchg(dst, "@tearline", - HandleRandomLine(strxcpy(buf, AA->Tearline(), sizeof(buf)), sizeof(buf)))) - continue; - if(tokenxchg(dst, "@origin", - HandleRandomLine(strxcpy(buf, AA->Origin(), sizeof(buf)), sizeof(buf)))) + + if (currareaisinet) + { + if (tokenxchg(input, dst, "@caddr", AA->Internetaddress(), 19, 1, 0)) continue; - if (strnieql(dst, "@area", 5)) + if (tokenxchg(input, dst, "@faddr", msg->iorig, 19, 1, 0)) + continue; + + if (tokenxchg(input, dst, "@taddr", msg->iaddr, 19, 1, 0)) + continue; + } + + if ((not origareaisinet or not currareaisinet) and (strlen(dst) >= 6)) + { + bool dr = domain_requested(dst, 6); + if (not origareaisinet) { - if (tokenxchg(dst, "@areatype", AA->basetype())) + if (tokenxchg(input, dst, "@oaddr", oldmsg->orig.make_string(buf, dr ? oldmsg->odom : NULL), 19, 1, 0)) continue; - char areapath[GMAXPATH]; - char areaname[GMAXPATH]; - - strcpy(areapath, AA->path()); - areaname[0] = NUL; - - size_t slashpos; - size_t pathlen = strlen(areapath); - - for (slashpos = pathlen-1; slashpos < pathlen; slashpos--) - if (isslash(areapath[slashpos])) break; - - if (slashpos < pathlen) + if (strnieql(dst, "@o3daddr", 8)) { - strcpy(areaname, &areapath[slashpos+1]); - areapath[slashpos+1] = NUL; - } - else - { - strcpy(areaname, areapath); - areapath[0] = NUL; + ftn_addr boss = oldmsg->orig; + boss.point = 0; + tokenxchg(input, dst, "@o3daddr", boss.make_string(buf, domain_requested(dst, 8) ? oldmsg->odom : NULL), 19, 1, 0); + continue; } - if (tokenxchg(dst, "@areapath", areapath)) + if (tokenxchg(input, dst, "@daddr", oldmsg->dest.make_string(buf, dr ? oldmsg->ddom : NULL), 19, 1, 0)) continue; - if (tokenxchg(dst, "@areaname", areaname)) - continue; - } - char *ptr1, *ptr2; - if (strnieql(dst, "@pad{", 5) && - ((ptr1 = strstr(dst+5, "}{")) != NULL) && - ((ptr1-dst-5) > 2) && - ((ptr2 = strchr(ptr1+2, '}')) != NULL) - ) - { - char buff[1024]; - char token[1024]; - char fill = dst[5]; - char align = g_toupper(dst[6]); - int size = atoi(dst+7); - - if (strchr("CLR", align)) + if (strnieql(dst, "@d3daddr", 8)) { - memcpy(token, dst, ptr2-dst+1); - memcpy(buff, ptr1+2, ptr2-ptr1-2); - token[ptr2-dst+1] = buff[ptr2-ptr1-2] = 0; - - TokenXlat(mode, buff, msg, oldmsg, __origarea); - buff[size] = 0; - - size_t length = strlen(buff); - if (length != size) - { - size_t diff = size - length; - switch (align) - { - case 'C': - memmove(&buff[diff/2], buff, length); - memset(buff, fill, diff/2); - memset(&buff[diff/2+length], fill, diff-diff/2); - break; - case 'L': - memset(&buff[length], fill, diff); - break; - case 'R': - memmove(&buff[diff], buff, length); - memset(buff, fill, diff); - break; - } - } - - if (tokenxchg(dst, token, buff)) - continue; + ftn_addr boss = oldmsg->dest; + boss.point = 0; + tokenxchg(input, dst, "@d3daddr", boss.make_string(buf, domain_requested(dst, 8) ? oldmsg->ddom : NULL), 19, 1, 0); + continue; } } - if (strnieql(dst, "@pipe{`", 7)) + if (not currareaisinet) { - char *argbeg = dst+7; - char *argend = strstr(argbeg, "`}"); + const gaka &caka=AA->Aka(); + if (tokenxchg(input, dst, "@caddr", caka.addr.make_string(buf, dr ? caka.domain : NULL), 19, 1, 0)) + continue; - char token[1024]; - size_t tlen = argend-dst+2; + if (strnieql(dst, "@c3daddr", 8)) + { + ftn_addr boss = caka.addr; + boss.point = 0; + tokenxchg(input, dst, "@c3daddr", boss.make_string(buf, domain_requested(dst, 8) ? caka.domain : NULL), 19, 1, 0); + continue; + } - memcpy(token, dst, tlen); - *argend = token[tlen] = 0; + if (tokenxchg(input, dst, "@taddr", msg->dest.make_string(buf, dr ? msg->ddom : NULL), 19, 1, 0)) + continue; + + if (strnieql(dst, "@t3daddr", 8)) + { + ftn_addr boss = msg->dest; + boss.point = 0; + tokenxchg(input, dst, "@t3daddr", boss.make_string(buf, domain_requested(dst, 8) ? msg->ddom : NULL), 19, 1, 0); + continue; + } + + if (tokenxchg(input, dst, "@faddr", msg->orig.make_string(buf, dr ? msg->odom : NULL), 19, 1, 0)) + continue; + + if (strnieql(dst, "@f3daddr", 8)) + { + ftn_addr boss = msg->orig; + boss.point = 0; + tokenxchg(input, dst, "@f3daddr", boss.make_string(buf, domain_requested(dst, 8) ? msg->odom : NULL), 19, 1, 0); + continue; + } + } + } + + if (tokenxchg(input, dst, "@tname", strbtrim(strtmp(msg->To())), 34, 3, + (int)false, (int)false, (int)msg->to_all())) + continue; + + if (tokenxchg(input, dst, "@tfname", strlword(msg->To()), 0, 3, + (int)false, (int)false, (int)msg->to_all())) + continue; + + if (tokenxchg(input, dst, "@tlname", strrword(msg->To()), 0, 3, + (int)false, (int)false, (int)msg->to_all())) + continue; + + if (tokenxchg(input, dst, "@cname", AA->Username().name, 34)) + continue; + + if (tokenxchg(input, dst, "@cfname", strlword(strcpy(buf, AA->Username().name)))) + continue; + + if (tokenxchg(input, dst, "@clname", strrword(strcpy(buf, AA->Username().name)))) + continue; + + if (tokenxchg(input, dst, "@cfrom", msg->ifrom)) + continue; + + if (tokenxchg(input, dst, "@cto", msg->ito)) + continue; + + if (tokenxchg(input, dst, "@cdate", cdate)) + continue; + + if (tokenxchg(input, dst, "@ctime", ctime)) + continue; + + if (tokenxchg(input, dst, "@cdtime", cdtime)) + continue; + + if (tokenxchg(input, dst, "@ctzoffset", AA->Usetzutc() ? (sprintf(buf, " %+05d", tzoffset()), buf) : "")) + continue; + + if (tokenxchg(input, dst, "@fname", strbtrim(strtmp(msg->By())), 34)) + continue; + + if (tokenxchg(input, dst, "@fpgp", *msg->iorig ? msg->iorig : msg->By())) + continue; + + if (tokenxchg(input, dst, "@ffname", strlword(msg->By()))) + continue; + + if (tokenxchg(input, dst, "@flname", strrword(msg->By()))) + continue; + + if (strnieql(dst, "@dpseudo", 8)) + { + if (*(oldmsg->pseudoto) == NUL) + build_pseudo(oldmsg); + tokenxchg(input, dst, "@dpseudo", oldmsg->pseudoto, 0, 3, (int)msg->to_me(), (int)msg->to_you(), (int)oldmsg->to_all()); + continue; + } + + if (strnieql(dst, "@opseudo", 8)) + { + if (*(oldmsg->pseudofrom) == NUL) + build_pseudo(oldmsg, false); + tokenxchg(input, dst, "@opseudo", oldmsg->pseudofrom, 0, 2, (int)msg->by_me(), (int)msg->by_you()); + continue; + } + + if (strnieql(dst, "@tpseudo", 8)) + { + if (*(msg->pseudoto) == NUL) + build_pseudo(msg); + tokenxchg(input, dst, "@tpseudo", msg->pseudoto, 0, 3, (int)false, (int)false, (int)msg->to_all()); + continue; + } + + // Same as above (just for backward compatibility) + if (strnieql(dst, "@pseudo", 7)) + { + if (*(msg->pseudoto) == NUL) + build_pseudo(msg); + tokenxchg(input, dst, "@pseudo", msg->pseudoto, 0, 3, (int)false, (int)false, (int)msg->to_all()); + continue; + } + + if (strnieql(dst, "@fpseudo", 8)) + { + if (*(msg->pseudofrom) == NUL) + build_pseudo(msg, false); + tokenxchg(input, dst, "@fpseudo", msg->pseudofrom); + continue; + } + + if (tokenxchg(input, dst, "@msgno", msgno)) + continue; + + if (tokenxchg(input, dst, "@msgs", msgs)) + continue; + + if (tokenxchg(input, dst, "@cpseudo", *AA->Nickname() ? AA->Nickname() : strlword(strcpy(buf, AA->Username().name), " @."))) + continue; + + if (tokenxchg(input, dst, "@version", __gver_ver__)) + continue; + + if (tokenxchg(input, dst, "@ver", __gver_shortver__)) + continue; + + if (tokenxchg(input, dst, "@rev", revbuf)) + continue; + + if (tokenxchg(input, dst, "@pid", __gver_shortpid__)) + continue; + + if (tokenxchg(input, dst, "@longpid", __gver_longpid__)) + continue; + + if (tokenxchg(input, dst, "@widepid", xmailer)) + continue; + + if (tokenxchg(input, dst, "@osver", osver)) + continue; + + if (tokenxchg(input, dst, "@osslash", __gver_platform__)) + continue; + + if (tokenxchg(input, dst, "@subject", modereptr)) + continue; + + if (tokenxchg(input, dst, "@attr", attr)) + continue; + + if (tokenxchg(input, dst, "@tagline", + HandleRandomLine(strxcpy(buf, AA->Tagline(), sizeof(buf)), sizeof(buf)))) + continue; + + if (tokenxchg(input, dst, "@tearline", + HandleRandomLine(strxcpy(buf, AA->Tearline(), sizeof(buf)), sizeof(buf)))) + continue; + + if (tokenxchg(input, dst, "@origin", + HandleRandomLine(strxcpy(buf, AA->Origin(), sizeof(buf)), sizeof(buf)))) + continue; + + if (strnieql(dst, "@area", 5)) + { + if (tokenxchg(input, dst, "@areatype", AA->basetype())) + continue; + + char areapath[GMAXPATH]; + char areaname[GMAXPATH]; + + strcpy(areapath, AA->path()); + areaname[0] = NUL; + + size_t slashpos; + size_t pathlen = strlen(areapath); + + for (slashpos = pathlen-1; slashpos < pathlen; slashpos--) + if (isslash(areapath[slashpos])) break; + + if (slashpos < pathlen) + { + strcpy(areaname, &areapath[slashpos+1]); + areapath[slashpos+1] = NUL; + } + else + { + strcpy(areaname, areapath); + areapath[0] = NUL; + } + + if (tokenxchg(input, dst, "@areapath", areapath)) + continue; + + if (tokenxchg(input, dst, "@areaname", areaname)) + continue; + } + + if (strnieql(dst, "@align{", 7)) + { + std::string::iterator ptr = dst+7; + while ((*ptr != '}') && (ptr != input.end())) ptr++; + + if (*ptr != '}') + tokenxchg(input, dst, "@align", ""); + else + { + int size = atoi(dst+7) - (dst-input.begin()); + if (size < 0) size = 0; + + char filler = ' '; + if ((*(ptr+1) == '{') && (*(ptr+3) == '}')) + { + ptr += 2; + filler = *ptr; + } + + std::string fill(size, filler); + tokenxchg(input, dst, "@align", fill.c_str(), 0, 2, (int)false, (int)false); + dst += size; + } + + continue; + } + + if (strnieql(dst, "@pipe{", 6)) + { + std::string::iterator pbeg = dst+6; + std::string::iterator pend = pbeg; + while ((*pend != '}') && (pend != input.end())) + pend++; + + if (*pend != '}') + tokenxchg(input, dst, "@pipe", ""); + else + { + std::string param = input.substr(pbeg-input.begin(), pend-pbeg); FILE *pipe_in; std::string pipe_buff; - if ((pipe_in = popen(argbeg, "rt")) != NULL ) + if ((pipe_in = popen(param.c_str(), "rt")) != NULL ) { char buffer[1024]; while (!feof(pipe_in)) @@ -494,24 +539,114 @@ char* TokenXlat(int mode, char* input, GMsg* msg, GMsg* oldmsg, int __origarea) pclose(pipe_in); } - *argend = '`'; - for (size_t i = 0; i < pipe_buff.length(); i++) { if (pipe_buff[i] == LF) pipe_buff[i] = CR; } - if (tokenxchg(dst, token, pipe_buff.c_str())) + if (tokenxchg(input, dst, "@pipe", pipe_buff.c_str(), 0, 1, (int)false)) continue; } + } - dst++; + if (strnieql(dst, "@pad{", 5)) + { + std::string::iterator pbeg = dst+5; + std::string::iterator pend = pbeg; + while ((*pend != '}') && (pend != input.end())) + pend++; + + if ((*pend != '}') || ((pend-pbeg) < 3)) + tokenxchg(input, dst, "@pad", ""); + else + { + pend++; + + char fill = *pbeg; + char align = toupper(*(pbeg+1)); + int padsize = atoi(pbeg+2); + + if (padsize < 0) padsize = 0; + + std::string text; + if (*pend == '{') + { + std::string buff = input.substr(pend-input.begin()); + TokenXlat(mode, buff, msg, oldmsg, __origarea); + + size_t idx1 = dst - input.begin(); + size_t idx2 = pend - dst; + input.replace(pend, input.end(), buff); + dst = input.begin() + idx1; + pend = pbeg = dst + idx2 + 1; + + while ((*pend != '}') && (pend != input.end())) + pend++; + + text = input.substr(pbeg-input.begin(), pend-pbeg); + } + + size_t tlen = text.length(); + if (tlen != padsize) + { + int diff = padsize - tlen; + switch (align) + { + case 'L': + if (diff > 0) + text.insert(text.end(), diff, fill); + else + text.erase(padsize); + break; + case 'R': + if (diff > 0) + text.insert(text.begin(), diff, fill); + else + text = text.substr(-diff); + break; + default: + if (diff > 0) + { + text.insert(text.begin(), diff/2, fill); + text.insert(text.end(), diff-diff/2, fill); + } + else + { + text = text.substr((-diff)/2); + text.erase(padsize); + } + break; + } + } + + if (tokenxchg(input, dst, "@pad", text.c_str(), 0, 2, (int)false, (int)false)) + continue; + } } } + + dst++; + } +} + + +// ------------------------------------------------------------------ + +void TokenXlat(int mode, char *&input, size_t size, bool resize, GMsg* msg, GMsg* oldmsg, int origarea) +{ + std::string buff = input; + TokenXlat(mode, buff, msg, oldmsg, origarea); + + if (resize) + { + size_t newsize = buff.length() + 1; + if (size < newsize) + input = (char*)throw_realloc(input, size = newsize); } - return input; + strncpy(input, buff.c_str(), size); + input[size-1] = 0; } diff --git a/golded3/gepost.cpp b/golded3/gepost.cpp index 5926b49..9efe10e 100644 --- a/golded3/gepost.cpp +++ b/golded3/gepost.cpp @@ -1097,7 +1097,8 @@ void MakeMsg(int mode, GMsg* omsg, bool ignore_replyto) { forwstat = YES; } else { - if(confirm) { + if (confirm) + { throw_release(msg->txt); FILE* fp = fsopen(AddPath(CFG->goldpath, CFG->confirmfile), "rt", CFG->sharemode); if(fp) { @@ -1106,7 +1107,7 @@ void MakeMsg(int mode, GMsg* omsg, bool ignore_replyto) { } if(msg->txt == NULL) msg->txt = throw_strdup("\r\rConfirmation Receipt\r\r"); - TokenXlat(mode, msg->txt, msg, omsg, CurrArea); + TokenXlat(mode, msg->txt, strlen(msg->txt)+1, true, msg, omsg, CurrArea); } else CreateFileAddr(msg); diff --git a/golded3/geprot.h b/golded3/geprot.h index 45aca62..ef11cc3 100644 --- a/golded3/geprot.h +++ b/golded3/geprot.h @@ -118,7 +118,7 @@ void SaveLines(int mode, const char* savefile, GMsg* msg, int margin, bool clip= // GEDOSS prototypes void Cleanup(void); -int ShellToDos(char* command, char* message, vattr cls, int cursor, int pause=NO); +int ShellToDos(const char* command, char* message, vattr cls, int cursor, int pause=NO); // ------------------------------------------------------------------ @@ -221,7 +221,11 @@ int NextMarkedmsg(int direction, GMsg* msg); // ------------------------------------------------------------------ // GEMSGS prototypes -char* TokenXlat(int mode, char* input, GMsg* msg, GMsg* oldmsg, int origarea); +void TokenXlat(int mode, std::string &input, GMsg* msg, GMsg* oldmsg, int origarea); +void TokenXlat(int mode, char *&input, size_t size, bool resize, GMsg* msg, GMsg* oldmsg, int origarea); +inline void TokenXlat(int mode, char *input, size_t size, GMsg* msg, GMsg* oldmsg, int origarea) +{ TokenXlat(mode, input, size, false, msg, oldmsg, origarea); } + void Rot13(GMsg* msg); void ResetMsg(GMsg* msg); int DoCarboncopy(GMsg* msg, GMsg** carbon); diff --git a/golded3/geread2.cpp b/golded3/geread2.cpp index ef14a73..eb7b2de 100644 --- a/golded3/geread2.cpp +++ b/golded3/geread2.cpp @@ -538,15 +538,15 @@ int ExternUtil(GMsg *msg, ExtUtil *extutil) { Path editorfile, tmpfile, buf; strxcpy(editorfile, AddPath(CFG->goldpath, EDIT->File()), sizeof(Path)); - char cmdline[1024]; - strxcpy(cmdline, extutil->cmdline, sizeof(cmdline)); + std::string cmdline = extutil->cmdline; int mode = (extutil->options & EXTUTIL_KEEPCTRL) ? MODE_SAVE : MODE_SAVENOCTRL; SaveLines(mode, editorfile, msg, 79); strcpy(buf, editorfile); strchg(buf, GOLD_WRONG_SLASH_CHR, GOLD_SLASH_CHR); strischg(cmdline, "@file", buf); - if(striinc("@tmpfile", cmdline)) { + if(striinc("@tmpfile", cmdline) != cmdline.end()) + { mktemp(strcpy(tmpfile, AddPath(CFG->temppath, "GDXXXXXX"))); SaveLines(mode, tmpfile, msg, 79); strcpy(buf, tmpfile); @@ -566,7 +566,7 @@ int ExternUtil(GMsg *msg, ExtUtil *extutil) { if(extutil->options & EXTUTIL_PAUSE) pauseval = 1; - ShellToDos(cmdline, "", + ShellToDos(cmdline.c_str(), "", extutil->options & EXTUTIL_CLS ? LGREY_|_BLACK : BLACK_|_BLACK, extutil->options & EXTUTIL_CURSOR, pauseval @@ -761,8 +761,7 @@ void ReadPeekURLs(GMsg* msg) { whelpop(); if(n != -1) { - char cmdline[1024]; - strxcpy(cmdline, CFG->urlhandler.cmdline, sizeof(cmdline)); + std::string cmdline = CFG->urlhandler.cmdline; strxmerge(buf, sizeof(buf), "\"", strtrim(strltrim(Listi[n])), "\"", NULL); strischg(cmdline, "@url", buf); strxcpy(buf, CFG->goldpath, sizeof(buf)); @@ -776,7 +775,7 @@ void ReadPeekURLs(GMsg* msg) { if(CFG->urlhandler.options & EXTUTIL_PAUSE) pauseval = 1; - ShellToDos(cmdline, "", + ShellToDos(cmdline.c_str(), "", CFG->urlhandler.options & EXTUTIL_CLS ? LGREY_|_BLACK : BLACK_|_BLACK, CFG->urlhandler.options & EXTUTIL_CURSOR, pauseval diff --git a/golded3/getpls.cpp b/golded3/getpls.cpp index 11fdae4..8e2c301 100644 --- a/golded3/getpls.cpp +++ b/golded3/getpls.cpp @@ -87,12 +87,8 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa uint ctrlinfo; char textfile[GMAXPATH]; char indexfile[GMAXPATH]; -#if defined(__USE_ALLOCA__) size_t sizeofbuf = CFG->quotemargin + 256; - char *buf = (char*)alloca(sizeofbuf); -#else - __extension__ char buf[CFG->quotemargin + 256]; -#endif + char *buf = (char*)throw_malloc(sizeofbuf); char initials[10]; char quotestr[100]; char qbuf[100]; @@ -193,7 +189,8 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa EDIT->HardLines(false); msg->txt = (char*)throw_realloc(msg->txt, 256); strcpy(msg->txt, LNG->RobotMsg); - TokenXlat(mode, msg->txt, msg, oldmsg, origarea); + TokenXlat(mode, msg->txt, strlen(msg->txt)+1, true, msg, oldmsg, origarea); + throw_free(buf); return 0; } } @@ -339,11 +336,8 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa size_t oldmsg_size = oldmsg->txt ? strlen(oldmsg->txt) : REALLOC_CACHE_SIZE; size_t msg_txt_realloc_cache = 0; -#if defined(__MINGW32__) || defined(_MSC_VER) - while(fgets(buf, sizeofbuf, fp)) { -#else - while(fgets(buf, sizeof(buf), fp)) { -#endif + while(fgets(buf, sizeofbuf, fp)) + { ptr = strskip_wht(buf); if(*ptr != ';') { bool chg = false; @@ -487,7 +481,7 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa } while(*ptr and (token>=end_token)); if(token < end_token) { - TokenXlat(mode, buf, msg, oldmsg, origarea); + TokenXlat(mode, buf, sizeofbuf, true, msg, oldmsg, origarea); switch(token) { @@ -616,7 +610,7 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa if(*buf) { if(*buf == '+' and buf[1] == NUL) *buf = ' '; - TokenXlat(mode, buf, msg, oldmsg, origarea); + TokenXlat(mode, buf, sizeofbuf, true, msg, oldmsg, origarea); strtrim(buf); strcat(buf, "\r"); len = strlen(buf); @@ -650,7 +644,7 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa tfp = fsopen(textfile, "rt", CFG->sharemode); if(tfp) { while(fgets(buf, 255, tfp)) { - TokenXlat(mode, buf, msg, oldmsg, origarea); + TokenXlat(mode, buf, sizeofbuf, true, msg, oldmsg, origarea); strtrim(buf); strcat(buf, "\r"); len = strlen(buf); @@ -867,7 +861,7 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa continue; if((mode == MODE_QUOTEBUF) and not quotebufline) continue; - TokenXlat(mode, buf, msg, oldmsg, origarea); + TokenXlat(mode, buf, sizeofbuf, true, msg, oldmsg, origarea); len = strlen(buf); size += len; if(msg_txt_realloc_cache >= len) { @@ -918,7 +912,7 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa strtrim(buf); if(*buf) { strcat(buf, "\n"); - TokenXlat(mode, buf, msg, oldmsg, origarea); + TokenXlat(mode, buf, sizeofbuf, true, msg, oldmsg, origarea); len = strlen(buf); size += len; if(msg_txt_realloc_cache >= len) { @@ -939,6 +933,7 @@ int TemplateToText(int mode, GMsg* msg, GMsg* oldmsg, const char* tpl, int origa if(tmptpl) remove(tplfile); + throw_free(buf); return disphdr; } diff --git a/goldlib/gall/gfilutil.h b/goldlib/gall/gfilutil.h index ca9cc98..396acb4 100644 --- a/goldlib/gall/gfilutil.h +++ b/goldlib/gall/gfilutil.h @@ -83,6 +83,15 @@ #define R_OK 0 #endif + +// ------------------------------------------------------------------ + +#if defined(_MSC_VER) +#define popen(f,m) _popen(f,m) +#define pclose(fh) _pclose(fh) +#endif + + // ------------------------------------------------------------------ #define GMAXPATH (FILENAME_MAX+1) /* ANSI C */ diff --git a/goldlib/gall/gstrall.h b/goldlib/gall/gstrall.h index cd7ecf0..731da27 100644 --- a/goldlib/gall/gstrall.h +++ b/goldlib/gall/gstrall.h @@ -62,9 +62,11 @@ int strchg(char* str, char oldch, char newch); char* stridela(const char* substr, char* str); int strnicmpw(const char* str1, const char* str2, int len); const char* striinc(const char* str1, const char* str2); +std::string::iterator striinc(const char* str1, std::string &str2); char* strins(const char* instr, char* str, int st_pos); char* strisrep(char* str, const char* search, const char* replace); char* strischg(char* str, const char* find, const char* replace); +void strischg(std::string &str, const char* find, const char* replace); char* strrjust(char* str); char* strschg(char* str, const char* find, const char* replace); char* strsetsz(char* str, int newsize); diff --git a/goldlib/gall/gstrutil.cpp b/goldlib/gall/gstrutil.cpp index 3f88679..6c2a489 100644 --- a/goldlib/gall/gstrutil.cpp +++ b/goldlib/gall/gstrutil.cpp @@ -150,6 +150,22 @@ const char* striinc(const char* str1, const char* str2) { } +// ------------------------------------------------------------------ +// Determines if string1 is included in string2 + +std::string::iterator striinc(const char* str1, std::string &str2) +{ + int max = strlen(str1); + + std::string::iterator it; + for (it = str2.begin(); it != str2.end(); it++) + if (!strnicmp(str1, it, max)) + return it; + + return str2.end(); // string1 not found in string2 +} + + // ------------------------------------------------------------------ // Inserts one string into another @@ -211,6 +227,27 @@ char* strischg(char* str, const char* find, const char* replace) { } +// ------------------------------------------------------------------ +// Changes all occurrences of one string to another + +void strischg(std::string &str, const char* find, const char* replace) +{ + int lenf = strlen(find); + int lenr = strlen(replace); + + std::string::iterator it; + for (it = str.begin(); it != str.end(); it++) + { + if (strnieql(find, it, lenf)) + { + size_t idx = it - str.begin(); + str.replace(it, it+lenf, replace, lenr); + it = str.begin() + idx + lenr - 1; + } + } +} + + // ------------------------------------------------------------------ // Takes a long number and makes a string with the form x.xxx.xxx.xxx