This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-goldedplus/golded3/gehdre.cpp
2001-11-22 12:32:49 +00:00

609 lines
18 KiB
C++

// ------------------------------------------------------------------
// GoldED+
// Copyright (C) 1990-1999 Odinn Sorensen
// Copyright (C) 1999-2000 Alexander S. Aganichev
// ------------------------------------------------------------------
// This program 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 2 of the
// License, or (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston,
// MA 02111-1307 USA
// ------------------------------------------------------------------
// $Id$
// ------------------------------------------------------------------
// Header edit.
// ------------------------------------------------------------------
#include <golded.h>
#include <gwinput.h>
// ------------------------------------------------------------------
class GMsgHeaderEdit : public gwinput2 {
public:
enum {
id_from_name,
id_from_addr,
id_to_name,
id_to_addr,
id_subject
};
GMsgHeaderView &view;
GMsgHeaderEdit(GMsgHeaderView &v) : gwinput2(v.window), view(v) { msg = view.msg; }
GMsg* msg;
bool lookup;
bool handle_other_keys(gkey& key);
bool validate();
};
// ------------------------------------------------------------------
bool GMsgHeaderEdit::handle_other_keys(gkey& key) {
gkey kk;
if(key < KK_Commands) {
kk = SearchKey(key_tolower(key), HeaderKey, HeaderKeys);
if(kk)
key = kk;
}
if(ProcessAttrs(key) == true)
return true;
switch(key) {
case KK_HeaderAddressbook:
vcurhide();
lookup_addressbook(msg, get_field(id_to_name)->buf, get_field(id_to_addr)->buf, true);
get_field(id_to_name)->draw();
get_field(id_to_addr)->draw();
current->update();
vcurshow();
return true;
case KK_HeaderLookup:
{
Addr addr,addr2;
INam buf;
field* p;
addr.set_all(65535u);
addr2.set_all(65535u);
addr.set(get_field(id_to_addr)->buf);
strcpy(buf, strtrim(get_field(id_to_name)->buf));
if(addr != addr2)
addr.make_string(buf);
addr2 = addr;
Lookup(msg, &addr, buf, -6, LNG->SelectDestNode);
vcurshow();
if(addr != addr2 and addr.valid()) {
p = get_field(id_to_addr);
addr.make_string(p->buf);
p->buf_end_pos = strlen(buf);
p->buf_pos = p->buf_end_pos;
if(current->id == id_to_addr)
p->update();
else
p->draw();
p = get_field(id_to_name);
strcpy(p->buf, buf);
if(current->id == id_to_name)
p->update();
else
p->draw();
}
}
return true;
default:
if(PlayMacro(key, 0))
return true;
}
return false;
}
// ------------------------------------------------------------------
bool set_to_address(GMsg* msg, gsetaddr* toname, gsetaddr* toaddr, gsetaddr* fromaddr, gsetaddr* subj, int pos, char* lng_lookup, bool lookup) {
INam buf, buf1, buf2;
char* ptr = toname->buf;
strcpy(buf, ptr);
if(not CFG->addressmacro.empty()) {
std::vector<AddrMacro>::iterator n;
for(n=CFG->addressmacro.begin(); n != CFG->addressmacro.end(); n++) {
if(strieql(buf, n->macro)) {
ptr = strcpy(buf1, n->name);
if(*buf1 == '@') {
// UUCP/INTERNET addressing
ptr = strchr(buf1, '/');
if(ptr) {
*ptr++ = NUL;
ParseInternetAddr(ptr, buf2, buf);
}
else {
ParseInternetAddr(buf1+1, buf2, buf);
}
strcpy(msg->realto, buf2);
strcpy(msg->idest, buf);
strcpy(msg->iaddr, buf);
if(AA->isinternet())
ptr = strcpy(buf1, *buf2 ? buf2 : buf);
else {
if(ptr)
strcpy(buf2, buf1+1);
ptr = strcpy(buf1, ptr and *buf2 ? buf2 : *buf ? buf : buf2);
}
}
else if(AA->isinternet()) {
ParseInternetAddr(buf1, buf2, buf);
strcpy(msg->realto, buf2);
strcpy(msg->idest, buf);
strcpy(msg->iaddr, buf);
ptr = strcpy(buf1, *buf2 ? buf2 : buf);
}
else {
*msg->iaddr = NUL;
*msg->realto = NUL;
}
strcpy(toname->buf, ptr);
toname->update = true;
strcpy(msg->to, buf1);
if(AA->isinternet()) {
strcpy(toaddr->buf, msg->idest);
if(n->addr.net)
msg->dest = msg->odest = n->addr;
else
msg->dest = msg->odest = AA->Internetgate().addr;
}
else {
n->addr.make_string(toaddr->buf);
}
toaddr->update = true;
if(*n->subj and subj) {
strcpy(subj->buf, n->subj);
subj->update = true;
}
AttrAdd(&msg->attr, &n->attr);
if(lookup or AA->isnet())
return false;
return true;
}
}
}
if(lookup_addressbook(msg, toname->buf, toaddr->buf, false)) {
if(lookup or AA->isnet())
return false;
return true;
}
// Internet gating
if(not AA->isinternet()) {
if(strchr(toname->buf, '@') and AA->Internetgate().addr.valid()) {
if(*AA->Internetgate().name) {
strcpy(msg->iaddr, toname->buf);
strcpy(msg->to, AA->Internetgate().name);
strcpy(toname->buf, msg->to);
toname->update = true;
}
AA->Internetgate().addr.make_string(toaddr->buf);
toaddr->update = true;
if(lookup or AA->isnet())
return false;
return true;
}
if(lookup) {
strcpy(buf1, toname->buf);
strcpy(buf2, msg->to);
if(strblank(toaddr->buf) or strblank(buf1) or strcmp(buf1, buf2)) {
if(strblank(toname->buf))
strcpy(buf, toaddr->buf);
else
strcpy(buf, toname->buf);
strtrim(buf);
if(*buf == NUL)
strcpy(buf, " ");
*msg->iaddr = NUL;
*msg->realto = NUL;
if(*buf) {
Addr addr;
addr.reset(fromaddr->buf); // Get the orig address to base lookup on
Lookup(msg, &addr, buf, pos, lng_lookup);
if(striinc("Sysop", buf) or strieql(AA->Whoto(), buf)) {
if(addr.net == 0) {
if(not AA->isnet())
return false;
return true;
}
}
int robotchk = false;
for(gstrarray::iterator n = CFG->robotname.begin(); n != CFG->robotname.end(); n++)
if(striinc(n->c_str(), buf)) {
robotchk = true;
break;
}
if(robotchk) {
EDIT->HardLines(false);
if(addr.net == 0)
return true;
}
if(addr.net) {
addr.make_string(toaddr->buf);
toaddr->update = true;
strcpy(msg->to, buf);
strcpy(toname->buf, buf);
toname->update = true;
return false;
}
else {
HandleGEvent(EVTT_SEARCHFAILED);
return true;
}
}
}
}
else {
if(strpbrk(buf, "*?")) {
if(CFG->switches.get(lookupuserbase)) {
if(AA->UserLookup(buf)) {
strcpy(msg->to, buf);
*msg->iaddr = NUL;
*msg->realto = NUL;
toname->update = true;
return true;
}
}
}
}
}
return true;
}
// ------------------------------------------------------------------
bool GMsgHeaderEdit::validate() {
if(current->id == id_to_name) {
field* ffromaddr = get_field(id_from_addr);
field* ftoaddr = get_field(id_to_addr);
field* fsubj = get_field(id_subject);
gsetaddr toname, toaddr, fromaddr, subj;
std::string orig_toname;
orig_toname = msg->to;
toname.buf = current->buf; toname.update = false;
toaddr.buf = ftoaddr->buf; toaddr.update = false;
fromaddr.buf = ffromaddr->buf; fromaddr.update = false;
subj.buf = fsubj->buf; subj.update = false;
std::string iaddr(msg->iaddr), realto(msg->realto);
bool res = set_to_address(msg, &toname, &toaddr, &fromaddr, &subj, 0, LNG->SelectDestNode, lookup);
vcurshow();
__extension__ char bot2[EDIT->HdrNodeLen()+1];
MakeAttrStr(bot2, sizeof(bot2), &msg->attr);
strsetsz(bot2, EDIT->HdrNodeLen());
window.prints(1, EDIT->HdrNodePos(), C_HEADW, bot2);
if(toname.update) current->update();
if(toaddr.update) ftoaddr->update();
if(fromaddr.update) ffromaddr->update();
if(subj.update) fsubj->update();
if(res)
return true;
else
go_next_field();
}
else if(current->id == id_subject) {
CheckSubject(msg, current->buf);
current->update();
}
return true;
}
// ------------------------------------------------------------------
int EditHeaderinfo(int mode, GMsgHeaderView &view, bool doedithdr) {
GMsgHeaderEdit hedit(view);
GMsg *msg = view.msg;
std::string from_name, to_name, subject;
std::string from_addr, to_addr, orig_from_addr;
from_name = msg->By();
if(AA->isinternet()) {
from_addr = msg->iorig;
}
else {
if(msg->orig.net)
msg->orig.make_string(from_addr, msg->odom);
}
orig_from_addr = from_addr;
if(AA->isinternet()) {
to_name = msg->To();
to_addr = msg->idest;
}
else {
to_name = (*msg->iaddr and not *msg->igate) ? msg->iaddr : msg->to;
if(msg->dest.net)
msg->dest.make_string(to_addr, msg->ddom);
}
subject = msg->re;
if(doedithdr) {
if(AA->isnet())
hedit.lookup = CFG->switches.get(lookupnet);
else if(AA->isecho())
hedit.lookup = CFG->switches.get(lookupecho);
else
hedit.lookup = CFG->switches.get(lookuplocal);
int from_name_pos = EDIT->HdrNamePos();
int from_name_len = EDIT->HdrNameLen();
int from_addr_pos = EDIT->HdrNodePos();
int from_addr_len = EDIT->HdrNodeLen();
int to_name_pos = from_name_pos;
int to_name_len = from_name_len;
int to_addr_pos = from_addr_pos;
int to_addr_len = hedit.lookup or AA->isnet() ? from_addr_len : 0;
int subject_pos = 8;
int subject_len = MAXCOL - subject_pos;
int name_cvt = AA->Editmixcase() ? GMsgHeaderEdit::cvt_mixedcase : GMsgHeaderEdit::cvt_none;
int addr_cvt = GMsgHeaderEdit::cvt_none;
int subj_cvt = GMsgHeaderEdit::cvt_none;
hedit.setup(C_HEADW, C_HEADW, C_HEADE, _box_table(W_BHEAD,13), true);
hedit.add_field(GMsgHeaderEdit::id_from_name, 2, from_name_pos, from_name_len, from_name, sizeof(INam), name_cvt);
hedit.add_field(GMsgHeaderEdit::id_from_addr, 2, from_addr_pos, from_addr_len, from_addr, sizeof(IAdr), addr_cvt);
hedit.add_field(GMsgHeaderEdit::id_to_name, 3, to_name_pos, to_name_len, to_name, sizeof(INam), name_cvt);
hedit.add_field(GMsgHeaderEdit::id_to_addr, 3, to_addr_pos, to_addr_len, to_addr, sizeof(IAdr), addr_cvt);
hedit.add_field(GMsgHeaderEdit::id_subject, 4, subject_pos, subject_len, subject, sizeof(ISub), subj_cvt);
hedit.start_id = GMsgHeaderEdit::id_to_name;
switch(mode) {
case MODE_REPLYCOMMENT:
if(not (msg->dest.net or not AA->isnet()))
break;
// else drop through ...
case MODE_REPLY:
case MODE_QUOTE:
case MODE_CHANGE:
hedit.start_id = GMsgHeaderEdit::id_subject;
break;
}
ChgAttrs(YES, msg);
vcurshow();
if(not (hedit.lookup or AA->isnet())) {
char date2[25] = "";
strsetsz(date2, view.width - CFG->disphdrdateset.pos);
view.window.prints(3, CFG->disphdrdateset.pos, view.to_color, date2);
}
view.window.prints(5, view.width-strlen(LNG->HeaderEditHelp1)-1, view.title_color, LNG->HeaderEditHelp1);
view.window.prints(5, view.width-strlen(LNG->HeaderEditHelp1)-strlen(LNG->HeaderEditHelp2)-3, view.title_color, LNG->HeaderEditHelp2);
hedit.run(H_Header);
vcurhide();
ChgAttrs(NO, msg);
}
else
hedit.dropped = false;
if(not hedit.dropped and not gkbd.quitall) {
strcpy(msg->by, from_name.c_str());
strcpy(msg->re, subject.c_str());
INam tmp_to_name;
strxcpy(tmp_to_name, *msg->igate ? to_name.c_str() : msg->iaddr, sizeof(INam));
if(lookup_addressbook(msg, tmp_to_name, NULL))
to_name = tmp_to_name;
if(AA->isinternet()) {
strcpy(msg->iorig, from_addr.c_str());
strcpy(msg->to, to_name.c_str());
if(to_addr.empty() and strchr(to_name.c_str(), '@'))
strcpy(msg->idest, to_name.c_str());
else
strcpy(msg->idest, to_addr.c_str());
strcpy(msg->iaddr, msg->idest);
strcpy(msg->realby, msg->by);
if(not *msg->realto and not strchr(msg->to, '@'))
strcpy(msg->realto, msg->to);
if(*AA->Internetgate().name)
strcpy(msg->to, AA->Internetgate().name);
else if(strlen(msg->idest) > 34)
strcpy(msg->to, "UUCP");
else
strcpy(msg->to, msg->idest);
if(*msg->realby and *msg->iorig) {
char quot[2] = "\"";
if((msg->realby[0] == '\"') or (strpbrk(msg->realby, " \t") == NULL))
quot[0] = NUL;
sprintf(msg->ifrom, "%s%s%s <%s>", quot, msg->realby, quot, msg->iorig);
}
else
strcpy(msg->ifrom, msg->iorig);
if(*msg->realto) {
char quot[2] = "\"";
if((msg->realto[0] == '\"') or (strpbrk(msg->realto, " \t") == NULL))
quot[0] = NUL;
sprintf(msg->ito, "%s%s%s <%s>", quot, msg->realto, quot, msg->idest);
}
else
strcpy(msg->ito, msg->idest);
if(msg->orig.net == 0)
msg->orig = msg->oorig = AA->Aka().addr;
if(msg->dest.net == 0)
msg->dest = msg->odest = AA->Internetgate().addr;
}
else {
if(strchr(to_name.c_str(), '@')) {
if(*AA->Internetgate().name) {
strcpy(msg->to, AA->Internetgate().name);
strcpy(msg->iaddr, to_name.c_str());
}
else {
if(to_name.length() > 34) {
strcpy(msg->to, "UUCP");
strcpy(msg->iaddr, to_name.c_str());
}
else
strcpy(msg->to, to_name.c_str());
}
if(AA->Internetgate().addr.valid())
msg->dest = AA->Internetgate().addr;
}
else
strcpy(msg->to, to_name.c_str());
if(*msg->iaddr) {
if(not (CFG->internetgateexp == RFCAddress) and *msg->To() and (strpbrk(msg->iaddr, "<>()\"") == NULL) and not isuucp(msg->To())) {
Name name;
strcpy(name, msg->To());
StripQuotes(name);
if(CFG->internetgateexp == ((RFCName << 2) | RFCAddress)) {
char quot[2] = "\"";
if((name[0] == '\"') or (strpbrk(name, " \t") == NULL))
quot[0] = NUL;
sprintf(msg->ito, "%s%s%s <%s>", quot, name, quot, msg->iaddr);
}
else
sprintf(msg->ito, "%s (%s)", msg->iaddr, name);
}
else
strcpy(msg->ito, msg->iaddr);
if(not *msg->idest)
strcpy(msg->idest, msg->iaddr);
}
if(not *msg->realto and isuucp(msg->to))
strcpy(msg->realto, strlword(msg->iaddr, "@"));
Addr address;
address = AA->Aka().addr;
if(from_addr.length()) {
address.set(from_addr.c_str(), msg->odom);
msg->orig.zone = address.zone;
msg->orig.net = address.net;
msg->orig.node = address.node;
msg->orig.point = address.point;
}
if(to_addr.empty()) {
// Set destination to yourself or the Boss node
address = msg->orig;
address.point = 0;
address.make_string(to_addr);
}
address = AA->Aka().addr;
const char* domain = address.set(to_addr);
msg->odest.zone = msg->dest.zone = address.zone;
msg->odest.net = msg->dest.net = address.net;
msg->odest.node = msg->dest.node = address.node;
msg->odest.point = msg->dest.point = address.point;
if(*domain) {
address.reset();
address.zone = msg->orig.zone;
address.set(domain);
if(address.net) {
msg->odest.zone = address.zone;
msg->odest.net = address.net;
msg->odest.node = address.node;
msg->odest.point = address.point;
}
else {
msg->odest.zone = msg->dest.zone;
msg->odest.net = msg->dest.net;
msg->odest.node = msg->dest.node;
msg->odest.point = msg->dest.point;
}
}
// Try to match akas with the dest address, but only if the orig address was NOT changed
std::vector<gaka>::iterator i;
for(i = CFG->aka.begin(); i != CFG->aka.end(); i++) {
if(memcmp(&msg->orig, &(*i), sizeof(Addr)) == 0)
break; // Found one of our own akas.
}
// Try to match akas with the dest address, but only if the orig address was NOT changed
if(i != CFG->aka.end()) {
// ... and only if the orig aka was already one of our own
if(strieql(orig_from_addr.c_str(), from_addr.c_str())) {
// ... and only if we did NOT change aka manually
if(AA->Aka().addr.equals(AA->aka())) {
// Do aka matching
if(AA->Akamatching()) {
strcpy(msg->odom, CFG->aka[AkaMatch(&msg->orig, &msg->dest)].domain);
}
}
}
}
}
}
else {
for(int n=0; n<fspecs; n++)
throw_release(fspec[n].fblk);
fspecs = specfiles = 0;
}
view.Paint();
return hedit.dropped ? W_ESCPRESS : W_NOERROR;
}
// ------------------------------------------------------------------