Added archived echoes support

This commit is contained in:
Alexander S. Aganichev 2001-12-17 15:44:55 +00:00
parent f8a2159f0a
commit 4d4f620053
23 changed files with 265 additions and 17 deletions

View File

@ -12,6 +12,27 @@ ______________________________________________________________________
Notes for GoldED+ 1.1.5, /snapshot/
______________________________________________________________________
+ Added ability to READ packed messagebases. You need to add PKD
attribute to such echo definition and specify UNPACKER for the
extension defined. You should pack all files from the single
messagebase to the archive with the same name. For *.msg areas you
should add the directory as well. When entering to the archived area
UNPACKER will be executed to unpack files to TEMPPATH. On exit, all
files will be deleted.
New UNPACKER keyword have the following syntax:
UNPACKER <extension> <"commandline">
The commandline should provide the ability to extract all files from
@file.<extension> to the current directory. F.e.:
UNPACKER zip "unzip @file"
Note that all changes to the messagebase will be discarded.
This feature is not supported for Hudson and GoldBase messagebases.
! AREAPATH now used as default path for all SEMAPHOREs rather than
occasionally.

View File

@ -611,6 +611,7 @@ CfgGed::CfgGed() {
// tpl.clear();
// twitname.clear();
// twitsubj.clear();
// unpacker.clear();
// username.clear();
// wtpl.clear();
// xlatcharset.clear();

View File

@ -359,6 +359,7 @@ const word CRC_TWITMODE = 0x9DC8;
const word CRC_TWITNAME = 0x2055;
const word CRC_TWITSUBJ = 0x08C0;
const word CRC_TWITTO = 0x9DFE;
const word CRC_UNPACKER = 0x5691;
const word CRC_URLHANDLER = 0x688E;
const word CRC_USEAREA = 0x2FD4;
const word CRC_USECHARSET = 0xE1B9;

View File

@ -555,6 +555,7 @@ SwitchT:
SwitchU:
switch(crc) {
case CRC_UNPACKER : CfgUnpacker (); break;
case CRC_URLHANDLER : CfgUrlhandler (); break;
case CRC_USEAREA : CfgUsearea (); break;
case CRC_USECHARSET : CfgUsecharset (); break;

View File

@ -274,6 +274,20 @@ void CfgTwitsubj() {
// ------------------------------------------------------------------
void CfgUnpacker() {
char* key;
std::pair<std::string, std::string> unpackerentry;
getkeyval(&key, &val);
unpackerentry.first = key;
unpackerentry.second = StripQuotes(val);
CFG->unpacker.push_back(unpackerentry);
}
// ------------------------------------------------------------------
void CfgUrlhandler() {
// Get util number

View File

@ -341,6 +341,7 @@ void CfgTwitmode ();
void CfgTwitname ();
void CfgTwitsubj ();
void CfgTwitto ();
void CfgUnpacker ();
void CfgUrlhandler ();
void CfgUsearea ();
void CfgUsecharset ();

View File

@ -337,6 +337,7 @@ public:
int twitmode; // showtwits;
std::vector<Node> twitname;
gstrarray twitsubj;
std::vector< std::pair<std::string, std::string> > unpacker;
ExtUtil urlhandler;
bool usearea;
bool usecharset;

View File

@ -26,6 +26,7 @@
#include <golded.h>
#include <gdirposx.h>
#include <gutlos.h>
#include <gmoprot.h>
#ifdef __UNIX__
@ -122,6 +123,7 @@ void Cleanup(void) {
CFG->xlatescset.clear();
CFG->cmdkey.clear();
CFG->macro.clear();
CFG->unpacker.clear();
// Free misc data
throw_xrelease(CharTable);
@ -465,6 +467,87 @@ int ShellToDos(char* command, char* message, int cls, int cursor, int pause) {
}
// ------------------------------------------------------------------
const char* Unpack(const char* archive) {
static Path newname;
const char *filename = CleanFilename(archive);
std::vector< std::pair<std::string, std::string> >::iterator i;
for(i = CFG->unpacker.begin(); i != CFG->unpacker.end(); i++) {
int dots;
const char *ext, *myext;
for(dots = 0, ext = i->first.c_str() - 1; ext != NULL; dots++)
ext = strchr(ext+1, '.');
for(myext = filename + strlen(filename); (myext != filename) and (dots != 0); dots--) {
do
--myext;
while((myext != filename) and (myext[0] != '.'));
}
if(dots or not strieql(myext+1, i->first.c_str()))
continue;
Path newdir;
mktemp(strxcpy(newdir, AddPath(CFG->temppath, "GDXXXXXX"), sizeof(Path)));
mkdir(newdir, S_IWUSR);
char cmdline[1024];
strxcpy(cmdline, i->second.c_str(), sizeof(cmdline));
strxcpy(newname, archive, sizeof(Path));
strchg(newname, GOLD_WRONG_SLASH_CHR, GOLD_SLASH_CHR);
strischg(cmdline, "@file", newname);
// Store current drive/dir and change it to the temporary
Path orgdir;
getcwd(orgdir, sizeof(Path));
gchdir(newdir);
// Now unpack it
ShellToDos(cmdline, "", LGREY|_BLACK, 0, -1);
// Restore current directory
gchdir(orgdir);
strxcpy(newname, AddPath(AddBackslash(newdir), filename), sizeof(Path));
newname[strlen(newname) - (i->first.length() + 1)] = NUL;
return newname;
}
return NULL;
}
// ------------------------------------------------------------------
void CleanUnpacked(const char* unpacked) {
gposixdir d(unpacked);
const gdirentry *de;
std::string removeme;
if(is_dir(unpacked)) {
while((de = d.nextentry("*", true)) != NULL) {
removeme = de->dirname;
removeme += GOLD_SLASH_CHR;
removeme += de->name;
if(is_dir(removeme.c_str()))
rmdir(removeme.c_str());
else
remove(removeme.c_str());
}
}
Path tmpdir, tmpdir2;
strxcpy(tmpdir2, unpacked, sizeof(Path));
StripBackslash(tmpdir2);
extractdirname(tmpdir, tmpdir2);
d.cd(tmpdir);
while((de = d.nextentry("*", true)) != NULL) {
removeme = de->dirname;
removeme += GOLD_SLASH_CHR;
removeme += de->name;
if(is_dir(removeme.c_str()))
rmdir(removeme.c_str());
else
remove(removeme.c_str());
}
rmdir(tmpdir);
}
// ------------------------------------------------------------------
// Error exit function

View File

@ -115,14 +115,15 @@ const gdirentry *gposixdir::nextentry(const char *mask, bool nameonly)
}
ret.name = entries[last_entry];
ret.dirname = dirname.c_str();
if(!nameonly) {
std::string pn = ret.dirname;
pn += "/";
pn += ret.name;
size_t skipfrom;
while((skipfrom=pn.find("//")) != pn.npos)
pn.erase(skipfrom, 1);
if(!nameonly)
stat(pn.c_str(), &ret.stat_info);
}
++last_entry;
return &ret;
}

View File

@ -81,6 +81,8 @@ void ftn_attr::add(const ftn_attr& b) {
if(b.nok()) nok1();
if(b.fax()) fax1();
if(b.prn()) prn1();
if(b.pkd()) pkd1();
}
@ -188,6 +190,7 @@ void ftn_attr::get(const std::string& __s) {
if(striinc("NOK", s)) nok1();
if(striinc("FAX", s)) fax1();
if(striinc("PRN", s)) prn1();
if(striinc("PKD", s)) pkd1();
}

View File

@ -114,6 +114,8 @@ const ulong GATTR_FWD = 0x02000000UL; // forwarded (wildcat)
const ulong GATTR_EFL = 0x04000000UL; // echoflag (wildcat)
const ulong GATTR_HRP = 0x08000000UL; // has replies (wildcat)
const ulong GATTR_PKD = 0x10000000UL; // Archived
class ftn_attr {
protected:
@ -219,6 +221,8 @@ public:
int efl() const { return (attr2 & GATTR_EFL) != 0; }
int hrp() const { return (attr2 & GATTR_HRP) != 0; }
int pkd() const { return (attr2 & GATTR_PKD) != 0; }
// ----------------------------------------------------------------
void pvt(ulong x) { if(x) attr1 |= GATTR_PVT; else attr1 &= ~GATTR_PVT; }
@ -296,6 +300,8 @@ public:
void efl(ulong x) { if(x) attr2 |= GATTR_EFL; else attr2 &= ~GATTR_EFL; }
void hrp(ulong x) { if(x) attr2 |= GATTR_HRP; else attr2 &= ~GATTR_HRP; }
void pkd(ulong x) { if(x) attr2 |= GATTR_PKD; else attr2 &= ~GATTR_PKD; }
// -------------------------------------------------------------
void pvt0() { attr1 &= ~GATTR_PVT; }
@ -414,6 +420,8 @@ public:
void prn1() { attr2 |= GATTR_PRN; }
void pkd1() { attr2 |= GATTR_PKD; }
// ----------------------------------------------------------------
void pvtX() { attr1 ^= GATTR_PVT; }

View File

@ -86,6 +86,7 @@ public:
const ftn_addr& aka() const { return cfg.aka; }
int originno() const { return cfg.originno; }
Attr& attr() { return cfg.attr; }
bool ispacked() const { return cfg.attr.pkd(); }
bool ascan() { return (bool)cfg.scan; }
bool ascanexcl() { return (bool)cfg.scanexcl; }
@ -185,6 +186,11 @@ public:
virtual void set_highwater_mark() { }
virtual void reset_highwater_mark() { }
protected:
Path realpath;
const char* real_path() const { return ispacked() ? realpath : path(); }
void set_real_path(const char* newpath) { strxcpy(realpath, newpath, sizeof(Path)); }
};
@ -281,6 +287,8 @@ extern int WidePersonalmail;
// ------------------------------------------------------------------
int PopupLocked(long __tries, int __isopen, const char* __file);
const char* Unpack(const char* archive);
void CleanUnpacked(const char* unpacked);
// ------------------------------------------------------------------

View File

@ -338,6 +338,12 @@ void EzycomArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
data_open();
test_raw_open(__LINE__);
scan();
@ -390,6 +396,9 @@ void EzycomArea::close() {
raw_close();
Msgn->Reset();
data_close();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -170,6 +170,12 @@ void FidoArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
data_open();
scan();
}
@ -207,6 +213,9 @@ void FidoArea::close() {
save_lastread();
Msgn->Reset();
data_close();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -93,6 +93,12 @@ void JamArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
data_open();
open_area();
scan();
@ -161,6 +167,9 @@ void JamArea::close() {
raw_close();
Msgn->Reset();
data_close();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -181,6 +181,12 @@ void PcbArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
PcbWideOpen();
data_open();
raw_open();
@ -237,6 +243,9 @@ void PcbArea::close() {
Msgn->Reset();
data_close();
PcbWideClose();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -93,6 +93,12 @@ void SMBArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
data_open();
int _tries = 0;
@ -150,6 +156,9 @@ void SMBArea::close()
if(isopen == 1) {
smb_close(data);
data_close();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -162,8 +162,8 @@ void SquishArea::raw_open() {
GFTRK("SquishRawOpen");
data->fhsqd = test_open(AddPath(path(), ".sqd"));
data->fhsqi = test_open(AddPath(path(), ".sqi"));
data->fhsqd = test_open(AddPath(real_path(), ".sqd"));
data->fhsqi = test_open(AddPath(real_path(), ".sqi"));
GFTRK(NULL);
}
@ -186,6 +186,12 @@ void SquishArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
data_open();
raw_open();
refresh();
@ -202,7 +208,7 @@ void SquishArea::save_lastread() {
GFTRK("SquishSaveLastread");
int _fh = ::sopen(AddPath(path(), ".sql"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW);
int _fh = ::sopen(AddPath(real_path(), ".sql"), O_RDWR|O_CREAT|O_BINARY, WideSharemode, S_STDRW);
if(_fh != -1) {
lseekset(_fh, wide->userno, sizeof(dword));
dword _lastread = Msgn->CvtReln(lastread);
@ -227,6 +233,9 @@ void SquishArea::close() {
Msgn->Reset();
throw_xrelease(data->idx);
data_close();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -45,7 +45,7 @@ void SquishArea::refresh() {
SqshBase& _base = data->base;
memset(&_base, 0, sizeof(SqshBase));
_base.size = sizeof(SqshBase);
strxcpy(_base.name, path(), sizeof(_base.name));
strxcpy(_base.name, real_path(), sizeof(_base.name));
_base.endframe = _base.size;
_base.framesize = sizeof(SqshFrm);
_base.nextmsgno = 2;
@ -85,7 +85,7 @@ void SquishArea::raw_scan(int __keep_index, int __scanpm) {
// Load the lastread
dword _lastread = 0;
int _fh = ::sopen(AddPath(path(), ".sql"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
int _fh = ::sopen(AddPath(real_path(), ".sql"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
if(_fh != -1) {
lseekset(_fh, wide->userno, sizeof(dword));
read(_fh, &_lastread, sizeof(dword));
@ -99,7 +99,7 @@ void SquishArea::raw_scan(int __keep_index, int __scanpm) {
data->base.totalmsgs = 0;
// Open index file
data->fhsqi = ::sopen(AddPath(path(), ".sqi"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
data->fhsqi = ::sopen(AddPath(real_path(), ".sqi"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
if(data->fhsqi != -1) {
// Get the number of index records
@ -111,7 +111,7 @@ void SquishArea::raw_scan(int __keep_index, int __scanpm) {
if((data->base.totalmsgs == 1) or (wide->squishscan == SQS_API)) {
// Open, read and close data file
data->fhsqd = ::sopen(AddPath(path(), ".sqd"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
data->fhsqd = ::sopen(AddPath(real_path(), ".sqd"), O_RDONLY|O_BINARY, WideSharemode, S_STDRD);
if(data->fhsqd != -1) {
read(data->fhsqd, &data->base, sizeof(SqshBase));
::close(data->fhsqd);

View File

@ -46,11 +46,11 @@ void SquishArea::lock() {
if(WideCanLock) {
long _tries = 0;
while(::lock(data->fhsqd, 0, 1) == -1) {
if(PopupLocked(++_tries, true, path()) == false) {
if(PopupLocked(++_tries, true, real_path()) == false) {
WideLog->ErrLock();
raw_close();
WideLog->printf("! A Squish msgbase file could not be locked.");
WideLog->printf(": %s.SQD.", path());
WideLog->printf(": %s.sqd.", real_path());
WideLog->ErrOSInfo();
LockErrorExit();
}

View File

@ -154,6 +154,12 @@ void WCatArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
data_open();
raw_open();
refresh();
@ -195,6 +201,9 @@ void WCatArea::close() {
Msgn->Reset();
throw_release(data->idx);
data_close();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -198,6 +198,12 @@ void XbbsArea::open() {
TestErrorExit();
}
if(isopen == 1) {
if(ispacked()) {
isopen--;
const char* newpath = Unpack(path());
set_real_path(newpath ? newpath : path());
isopen++;
}
data_open();
raw_open();
refresh();
@ -239,6 +245,9 @@ void XbbsArea::close() {
Msgn->Reset();
throw_release(data->idx);
data_close();
if(ispacked()) {
CleanUnpacked(real_path());
}
}
isopen--;
}

View File

@ -2782,7 +2782,12 @@ AREA:&lt;OriginalEchoID&gt;</eg>
the optional default origin makes it simpler to create a common
<ref target=INCLUDE><kw/INCLUDE/</ref>'able area configuration
for several setups with different addresses, for example two people
sharing the same msgbase.
sharing the same msgbase.<lb>
If you wish to read packed area (f.e. from CD archive) <name/GoldED+/
allows you that. You need to specify pathname <b/with/ extension
in the <ident>path/board</ident> field, set <gi/PKD/ attribute and
define packer with <ref target=UNPACKER><kw/UNPACKER/</ref> keyword.
This feature is not supported for Hudson and GoldBase messagebases.
</item>
<label>
Processed by:
@ -9648,6 +9653,33 @@ AREASEP &excl;C "Group C" C Local]]></eg>
random system group.
</p>
</div2>
<div2 id=UNPACKER>
<head>
UNPACKER
</head>
<p>
Added ability to READ packed messagebases. You need to add PKD
attribute to such echo definition and specify UNPACKER for the
extension defined. You should pack all files from the single
messagebase to the archive with the same name. For *.msg areas you
should add the directory as well. When entering to the archived area
UNPACKER will be executed to unpack files to TEMPPATH. On exit, all
files will be deleted.
New UNPACKER keyword have the following syntax:
UNPACKER &gt;extension&lt; &gt;<q/commandline/&lt;
The commandline should provide the ability to extract all files from
@file.<extension> to the current directory. F.e.:
UNPACKER zip <q/unzip @file/
Note that all changes to the messagebase will be discarded.
This feature is not supported for Hudson and GoldBase messagebases.
</p>
</div2>
<div2>
<head>
USECHARSET &lt;yes/no&gt;
@ -10308,6 +10340,7 @@ LET Fax letterhead.
LOC Local. Message was written on your system.
LOK Lock. Prevents send/delete/purge/editing.
ORP Orphan. Could not be sent because destination node is unknown.
PKD Packed. Used in area definitions to unpack before using.
PRN Msg has been printed. Specific for Squish (bitvalue 00040000h).
PVT Private. Message may only be read by the addressee and author.
R/O Read only. Used in area definitions to prevent writing.