Added archived echoes support
This commit is contained in:
parent
f8a2159f0a
commit
4d4f620053
@ -12,6 +12,27 @@ ______________________________________________________________________
|
|||||||
Notes for GoldED+ 1.1.5, /snapshot/
|
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
|
! AREAPATH now used as default path for all SEMAPHOREs rather than
|
||||||
occasionally.
|
occasionally.
|
||||||
|
|
||||||
|
@ -611,6 +611,7 @@ CfgGed::CfgGed() {
|
|||||||
// tpl.clear();
|
// tpl.clear();
|
||||||
// twitname.clear();
|
// twitname.clear();
|
||||||
// twitsubj.clear();
|
// twitsubj.clear();
|
||||||
|
// unpacker.clear();
|
||||||
// username.clear();
|
// username.clear();
|
||||||
// wtpl.clear();
|
// wtpl.clear();
|
||||||
// xlatcharset.clear();
|
// xlatcharset.clear();
|
||||||
|
@ -359,6 +359,7 @@ const word CRC_TWITMODE = 0x9DC8;
|
|||||||
const word CRC_TWITNAME = 0x2055;
|
const word CRC_TWITNAME = 0x2055;
|
||||||
const word CRC_TWITSUBJ = 0x08C0;
|
const word CRC_TWITSUBJ = 0x08C0;
|
||||||
const word CRC_TWITTO = 0x9DFE;
|
const word CRC_TWITTO = 0x9DFE;
|
||||||
|
const word CRC_UNPACKER = 0x5691;
|
||||||
const word CRC_URLHANDLER = 0x688E;
|
const word CRC_URLHANDLER = 0x688E;
|
||||||
const word CRC_USEAREA = 0x2FD4;
|
const word CRC_USEAREA = 0x2FD4;
|
||||||
const word CRC_USECHARSET = 0xE1B9;
|
const word CRC_USECHARSET = 0xE1B9;
|
||||||
|
@ -555,6 +555,7 @@ SwitchT:
|
|||||||
|
|
||||||
SwitchU:
|
SwitchU:
|
||||||
switch(crc) {
|
switch(crc) {
|
||||||
|
case CRC_UNPACKER : CfgUnpacker (); break;
|
||||||
case CRC_URLHANDLER : CfgUrlhandler (); break;
|
case CRC_URLHANDLER : CfgUrlhandler (); break;
|
||||||
case CRC_USEAREA : CfgUsearea (); break;
|
case CRC_USEAREA : CfgUsearea (); break;
|
||||||
case CRC_USECHARSET : CfgUsecharset (); break;
|
case CRC_USECHARSET : CfgUsecharset (); break;
|
||||||
|
@ -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() {
|
void CfgUrlhandler() {
|
||||||
|
|
||||||
// Get util number
|
// Get util number
|
||||||
|
@ -341,6 +341,7 @@ void CfgTwitmode ();
|
|||||||
void CfgTwitname ();
|
void CfgTwitname ();
|
||||||
void CfgTwitsubj ();
|
void CfgTwitsubj ();
|
||||||
void CfgTwitto ();
|
void CfgTwitto ();
|
||||||
|
void CfgUnpacker ();
|
||||||
void CfgUrlhandler ();
|
void CfgUrlhandler ();
|
||||||
void CfgUsearea ();
|
void CfgUsearea ();
|
||||||
void CfgUsecharset ();
|
void CfgUsecharset ();
|
||||||
|
@ -337,6 +337,7 @@ public:
|
|||||||
int twitmode; // showtwits;
|
int twitmode; // showtwits;
|
||||||
std::vector<Node> twitname;
|
std::vector<Node> twitname;
|
||||||
gstrarray twitsubj;
|
gstrarray twitsubj;
|
||||||
|
std::vector< std::pair<std::string, std::string> > unpacker;
|
||||||
ExtUtil urlhandler;
|
ExtUtil urlhandler;
|
||||||
bool usearea;
|
bool usearea;
|
||||||
bool usecharset;
|
bool usecharset;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <golded.h>
|
#include <golded.h>
|
||||||
|
#include <gdirposx.h>
|
||||||
#include <gutlos.h>
|
#include <gutlos.h>
|
||||||
#include <gmoprot.h>
|
#include <gmoprot.h>
|
||||||
#ifdef __UNIX__
|
#ifdef __UNIX__
|
||||||
@ -122,6 +123,7 @@ void Cleanup(void) {
|
|||||||
CFG->xlatescset.clear();
|
CFG->xlatescset.clear();
|
||||||
CFG->cmdkey.clear();
|
CFG->cmdkey.clear();
|
||||||
CFG->macro.clear();
|
CFG->macro.clear();
|
||||||
|
CFG->unpacker.clear();
|
||||||
|
|
||||||
// Free misc data
|
// Free misc data
|
||||||
throw_xrelease(CharTable);
|
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
|
// Error exit function
|
||||||
|
|
||||||
|
@ -115,14 +115,15 @@ const gdirentry *gposixdir::nextentry(const char *mask, bool nameonly)
|
|||||||
}
|
}
|
||||||
ret.name = entries[last_entry];
|
ret.name = entries[last_entry];
|
||||||
ret.dirname = dirname.c_str();
|
ret.dirname = dirname.c_str();
|
||||||
std::string pn = ret.dirname;
|
if(!nameonly) {
|
||||||
pn += "/";
|
std::string pn = ret.dirname;
|
||||||
pn += ret.name;
|
pn += "/";
|
||||||
size_t skipfrom;
|
pn += ret.name;
|
||||||
while((skipfrom=pn.find("//")) != pn.npos)
|
size_t skipfrom;
|
||||||
pn.erase(skipfrom, 1);
|
while((skipfrom=pn.find("//")) != pn.npos)
|
||||||
if(!nameonly)
|
pn.erase(skipfrom, 1);
|
||||||
stat(pn.c_str(), &ret.stat_info);
|
stat(pn.c_str(), &ret.stat_info);
|
||||||
|
}
|
||||||
++last_entry;
|
++last_entry;
|
||||||
return &ret;
|
return &ret;
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,8 @@ void ftn_attr::add(const ftn_attr& b) {
|
|||||||
if(b.nok()) nok1();
|
if(b.nok()) nok1();
|
||||||
if(b.fax()) fax1();
|
if(b.fax()) fax1();
|
||||||
if(b.prn()) prn1();
|
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("NOK", s)) nok1();
|
||||||
if(striinc("FAX", s)) fax1();
|
if(striinc("FAX", s)) fax1();
|
||||||
if(striinc("PRN", s)) prn1();
|
if(striinc("PRN", s)) prn1();
|
||||||
|
if(striinc("PKD", s)) pkd1();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,6 +114,8 @@ const ulong GATTR_FWD = 0x02000000UL; // forwarded (wildcat)
|
|||||||
const ulong GATTR_EFL = 0x04000000UL; // echoflag (wildcat)
|
const ulong GATTR_EFL = 0x04000000UL; // echoflag (wildcat)
|
||||||
const ulong GATTR_HRP = 0x08000000UL; // has replies (wildcat)
|
const ulong GATTR_HRP = 0x08000000UL; // has replies (wildcat)
|
||||||
|
|
||||||
|
const ulong GATTR_PKD = 0x10000000UL; // Archived
|
||||||
|
|
||||||
class ftn_attr {
|
class ftn_attr {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -219,6 +221,8 @@ public:
|
|||||||
int efl() const { return (attr2 & GATTR_EFL) != 0; }
|
int efl() const { return (attr2 & GATTR_EFL) != 0; }
|
||||||
int hrp() const { return (attr2 & GATTR_HRP) != 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; }
|
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 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 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; }
|
void pvt0() { attr1 &= ~GATTR_PVT; }
|
||||||
@ -414,6 +420,8 @@ public:
|
|||||||
|
|
||||||
void prn1() { attr2 |= GATTR_PRN; }
|
void prn1() { attr2 |= GATTR_PRN; }
|
||||||
|
|
||||||
|
void pkd1() { attr2 |= GATTR_PKD; }
|
||||||
|
|
||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
void pvtX() { attr1 ^= GATTR_PVT; }
|
void pvtX() { attr1 ^= GATTR_PVT; }
|
||||||
|
@ -86,6 +86,7 @@ public:
|
|||||||
const ftn_addr& aka() const { return cfg.aka; }
|
const ftn_addr& aka() const { return cfg.aka; }
|
||||||
int originno() const { return cfg.originno; }
|
int originno() const { return cfg.originno; }
|
||||||
Attr& attr() { return cfg.attr; }
|
Attr& attr() { return cfg.attr; }
|
||||||
|
bool ispacked() const { return cfg.attr.pkd(); }
|
||||||
|
|
||||||
bool ascan() { return (bool)cfg.scan; }
|
bool ascan() { return (bool)cfg.scan; }
|
||||||
bool ascanexcl() { return (bool)cfg.scanexcl; }
|
bool ascanexcl() { return (bool)cfg.scanexcl; }
|
||||||
@ -185,6 +186,11 @@ public:
|
|||||||
|
|
||||||
virtual void set_highwater_mark() { }
|
virtual void set_highwater_mark() { }
|
||||||
virtual void reset_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);
|
int PopupLocked(long __tries, int __isopen, const char* __file);
|
||||||
|
const char* Unpack(const char* archive);
|
||||||
|
void CleanUnpacked(const char* unpacked);
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
@ -338,6 +338,12 @@ void EzycomArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
data_open();
|
data_open();
|
||||||
test_raw_open(__LINE__);
|
test_raw_open(__LINE__);
|
||||||
scan();
|
scan();
|
||||||
@ -390,6 +396,9 @@ void EzycomArea::close() {
|
|||||||
raw_close();
|
raw_close();
|
||||||
Msgn->Reset();
|
Msgn->Reset();
|
||||||
data_close();
|
data_close();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -170,6 +170,12 @@ void FidoArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
data_open();
|
data_open();
|
||||||
scan();
|
scan();
|
||||||
}
|
}
|
||||||
@ -207,6 +213,9 @@ void FidoArea::close() {
|
|||||||
save_lastread();
|
save_lastread();
|
||||||
Msgn->Reset();
|
Msgn->Reset();
|
||||||
data_close();
|
data_close();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,12 @@ void JamArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
data_open();
|
data_open();
|
||||||
open_area();
|
open_area();
|
||||||
scan();
|
scan();
|
||||||
@ -161,6 +167,9 @@ void JamArea::close() {
|
|||||||
raw_close();
|
raw_close();
|
||||||
Msgn->Reset();
|
Msgn->Reset();
|
||||||
data_close();
|
data_close();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,12 @@ void PcbArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
PcbWideOpen();
|
PcbWideOpen();
|
||||||
data_open();
|
data_open();
|
||||||
raw_open();
|
raw_open();
|
||||||
@ -237,6 +243,9 @@ void PcbArea::close() {
|
|||||||
Msgn->Reset();
|
Msgn->Reset();
|
||||||
data_close();
|
data_close();
|
||||||
PcbWideClose();
|
PcbWideClose();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,12 @@ void SMBArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
data_open();
|
data_open();
|
||||||
|
|
||||||
int _tries = 0;
|
int _tries = 0;
|
||||||
@ -150,6 +156,9 @@ void SMBArea::close()
|
|||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
smb_close(data);
|
smb_close(data);
|
||||||
data_close();
|
data_close();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -162,8 +162,8 @@ void SquishArea::raw_open() {
|
|||||||
|
|
||||||
GFTRK("SquishRawOpen");
|
GFTRK("SquishRawOpen");
|
||||||
|
|
||||||
data->fhsqd = test_open(AddPath(path(), ".sqd"));
|
data->fhsqd = test_open(AddPath(real_path(), ".sqd"));
|
||||||
data->fhsqi = test_open(AddPath(path(), ".sqi"));
|
data->fhsqi = test_open(AddPath(real_path(), ".sqi"));
|
||||||
|
|
||||||
GFTRK(NULL);
|
GFTRK(NULL);
|
||||||
}
|
}
|
||||||
@ -186,6 +186,12 @@ void SquishArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
data_open();
|
data_open();
|
||||||
raw_open();
|
raw_open();
|
||||||
refresh();
|
refresh();
|
||||||
@ -202,7 +208,7 @@ void SquishArea::save_lastread() {
|
|||||||
|
|
||||||
GFTRK("SquishSaveLastread");
|
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) {
|
if(_fh != -1) {
|
||||||
lseekset(_fh, wide->userno, sizeof(dword));
|
lseekset(_fh, wide->userno, sizeof(dword));
|
||||||
dword _lastread = Msgn->CvtReln(lastread);
|
dword _lastread = Msgn->CvtReln(lastread);
|
||||||
@ -227,6 +233,9 @@ void SquishArea::close() {
|
|||||||
Msgn->Reset();
|
Msgn->Reset();
|
||||||
throw_xrelease(data->idx);
|
throw_xrelease(data->idx);
|
||||||
data_close();
|
data_close();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ void SquishArea::refresh() {
|
|||||||
SqshBase& _base = data->base;
|
SqshBase& _base = data->base;
|
||||||
memset(&_base, 0, sizeof(SqshBase));
|
memset(&_base, 0, sizeof(SqshBase));
|
||||||
_base.size = 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.endframe = _base.size;
|
||||||
_base.framesize = sizeof(SqshFrm);
|
_base.framesize = sizeof(SqshFrm);
|
||||||
_base.nextmsgno = 2;
|
_base.nextmsgno = 2;
|
||||||
@ -85,7 +85,7 @@ void SquishArea::raw_scan(int __keep_index, int __scanpm) {
|
|||||||
|
|
||||||
// Load the lastread
|
// Load the lastread
|
||||||
dword _lastread = 0;
|
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) {
|
if(_fh != -1) {
|
||||||
lseekset(_fh, wide->userno, sizeof(dword));
|
lseekset(_fh, wide->userno, sizeof(dword));
|
||||||
read(_fh, &_lastread, sizeof(dword));
|
read(_fh, &_lastread, sizeof(dword));
|
||||||
@ -99,7 +99,7 @@ void SquishArea::raw_scan(int __keep_index, int __scanpm) {
|
|||||||
data->base.totalmsgs = 0;
|
data->base.totalmsgs = 0;
|
||||||
|
|
||||||
// Open index file
|
// 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) {
|
if(data->fhsqi != -1) {
|
||||||
|
|
||||||
// Get the number of index records
|
// 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)) {
|
if((data->base.totalmsgs == 1) or (wide->squishscan == SQS_API)) {
|
||||||
|
|
||||||
// Open, read and close data file
|
// 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) {
|
if(data->fhsqd != -1) {
|
||||||
read(data->fhsqd, &data->base, sizeof(SqshBase));
|
read(data->fhsqd, &data->base, sizeof(SqshBase));
|
||||||
::close(data->fhsqd);
|
::close(data->fhsqd);
|
||||||
|
@ -46,11 +46,11 @@ void SquishArea::lock() {
|
|||||||
if(WideCanLock) {
|
if(WideCanLock) {
|
||||||
long _tries = 0;
|
long _tries = 0;
|
||||||
while(::lock(data->fhsqd, 0, 1) == -1) {
|
while(::lock(data->fhsqd, 0, 1) == -1) {
|
||||||
if(PopupLocked(++_tries, true, path()) == false) {
|
if(PopupLocked(++_tries, true, real_path()) == false) {
|
||||||
WideLog->ErrLock();
|
WideLog->ErrLock();
|
||||||
raw_close();
|
raw_close();
|
||||||
WideLog->printf("! A Squish msgbase file could not be locked.");
|
WideLog->printf("! A Squish msgbase file could not be locked.");
|
||||||
WideLog->printf(": %s.SQD.", path());
|
WideLog->printf(": %s.sqd.", real_path());
|
||||||
WideLog->ErrOSInfo();
|
WideLog->ErrOSInfo();
|
||||||
LockErrorExit();
|
LockErrorExit();
|
||||||
}
|
}
|
||||||
|
@ -154,6 +154,12 @@ void WCatArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
data_open();
|
data_open();
|
||||||
raw_open();
|
raw_open();
|
||||||
refresh();
|
refresh();
|
||||||
@ -195,6 +201,9 @@ void WCatArea::close() {
|
|||||||
Msgn->Reset();
|
Msgn->Reset();
|
||||||
throw_release(data->idx);
|
throw_release(data->idx);
|
||||||
data_close();
|
data_close();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,12 @@ void XbbsArea::open() {
|
|||||||
TestErrorExit();
|
TestErrorExit();
|
||||||
}
|
}
|
||||||
if(isopen == 1) {
|
if(isopen == 1) {
|
||||||
|
if(ispacked()) {
|
||||||
|
isopen--;
|
||||||
|
const char* newpath = Unpack(path());
|
||||||
|
set_real_path(newpath ? newpath : path());
|
||||||
|
isopen++;
|
||||||
|
}
|
||||||
data_open();
|
data_open();
|
||||||
raw_open();
|
raw_open();
|
||||||
refresh();
|
refresh();
|
||||||
@ -239,6 +245,9 @@ void XbbsArea::close() {
|
|||||||
Msgn->Reset();
|
Msgn->Reset();
|
||||||
throw_release(data->idx);
|
throw_release(data->idx);
|
||||||
data_close();
|
data_close();
|
||||||
|
if(ispacked()) {
|
||||||
|
CleanUnpacked(real_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
isopen--;
|
isopen--;
|
||||||
}
|
}
|
||||||
|
@ -2782,7 +2782,12 @@ AREA:<OriginalEchoID></eg>
|
|||||||
the optional default origin makes it simpler to create a common
|
the optional default origin makes it simpler to create a common
|
||||||
<ref target=INCLUDE><kw/INCLUDE/</ref>'able area configuration
|
<ref target=INCLUDE><kw/INCLUDE/</ref>'able area configuration
|
||||||
for several setups with different addresses, for example two people
|
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>
|
</item>
|
||||||
<label>
|
<label>
|
||||||
Processed by:
|
Processed by:
|
||||||
@ -9648,6 +9653,33 @@ AREASEP !C "Group C" C Local]]></eg>
|
|||||||
random system group.
|
random system group.
|
||||||
</p>
|
</p>
|
||||||
</div2>
|
</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 >extension< ><q/commandline/<
|
||||||
|
|
||||||
|
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>
|
<div2>
|
||||||
<head>
|
<head>
|
||||||
USECHARSET <yes/no>
|
USECHARSET <yes/no>
|
||||||
@ -10308,6 +10340,7 @@ LET Fax letterhead.
|
|||||||
LOC Local. Message was written on your system.
|
LOC Local. Message was written on your system.
|
||||||
LOK Lock. Prevents send/delete/purge/editing.
|
LOK Lock. Prevents send/delete/purge/editing.
|
||||||
ORP Orphan. Could not be sent because destination node is unknown.
|
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).
|
PRN Msg has been printed. Specific for Squish (bitvalue 00040000h).
|
||||||
PVT Private. Message may only be read by the addressee and author.
|
PVT Private. Message may only be read by the addressee and author.
|
||||||
R/O Read only. Used in area definitions to prevent writing.
|
R/O Read only. Used in area definitions to prevent writing.
|
||||||
|
Reference in New Issue
Block a user