jcs
/subtext
/amendments
/13
db: Store last-used db file as the resource, use it by default
This way we don't have to keep opening the file at startup.
Also pass around the file as a char * instead of an SFReply or
AppFile.
jcs made amendment 13 over 2 years ago
--- db.c Sun Dec 5 16:07:46 2021
+++ db.c Mon Dec 6 09:26:36 2021
@@ -19,14 +19,16 @@
#include <time.h>
#include "db.h"
+#include "subtext.h"
#include "user.h"
#include "util.h"
struct tmpl tmpls[10];
short ntmpls;
-struct db *db_init(SFReply reply, short is_new);
+struct db *db_init(char *path, short is_new);
short db_migrate(struct db *tdb, short is_new);
+void db_config_load(struct db *tdb);
void
load_db_tmpls(void)
@@ -47,24 +49,48 @@ load_db_tmpls(void)
}
struct db *
-db_open(AppFile *file)
+db_open(char *file)
{
+ struct stat sb;
Point pt = { 75, 100 };
- SFReply reply;
+ SFReply reply = { 0 };
SFTypeList types;
+ StringHandle lastfileh;
+ struct db *ret;
if (file) {
- reply.vRefNum = file->vRefNum;
- memcpy(&reply.fName, file->fName, sizeof(reply.fName));
- } else {
- types[0] = DB_TYPE;
+ if (stat((const char *)file, &sb) == 0)
+ return db_init(file, 0);
+
+ warn("Failed to open %s", file);
+ }
- SFGetFile(pt, NULL, NULL, 1, &types, NULL, &reply);
- if (!reply.good)
- return db_create();
+ if ((lastfileh = GetString(STR_LAST_DB))) {
+ HLock(lastfileh);
+ file = xmalloc(GetHandleSize(lastfileh));
+ memcpy(file, *lastfileh, *lastfileh[0] + 1);
+ HUnlock(lastfileh);
+ ReleaseResource(lastfileh);
+ PtoCstr(file);
+ if (stat(file, &sb) == 0) {
+ ret = db_init(file, 0);
+ free(file);
+ return ret;
+ }
+ free(file);
}
- return db_init(reply, 0);
+ /* no file passed, no last file, prompt */
+ types[0] = DB_TYPE;
+ SFGetFile(pt, NULL, NULL, 1, &types, NULL, &reply);
+ if (reply.good) {
+ getpath(reply.vRefNum, reply.fName, &file, 1);
+ ret = db_init(file, 0);
+ free(file);
+ return ret;
+ }
+
+ return db_create();
}
struct db *
@@ -72,71 +98,93 @@ db_create(void)
{
Point pt = { 75, 100 };
SFReply reply;
- char *newpath = NULL;
+ struct db *ret;
+ char *path;
short error, fh, tfh, i;
- SFPutFile(pt, "\pCreate new Subtext DB:", NULL, NULL, &reply);
+ SFPutFile(pt, "\pCreate new Subtext DB:", "\p", NULL, &reply);
if (!reply.good)
return NULL;
- getpath(reply.vRefNum, reply.fName, &newpath, 1);
- CtoPstr(newpath);
-
error = Create(reply.fName, reply.vRefNum, SUBTEXT_CREATOR, DB_TYPE);
if (error == dupFNErr) {
error = FSDelete(reply.fName, reply.vRefNum);
if (error)
err(1, "Failed to re-create file %s: %d", PtoCstr(reply.fName),
error);
- error = Create(reply.fName, reply.vRefNum, SUBTEXT_CREATOR, DB_TYPE);
+ error = Create(reply.fName, reply.vRefNum, SUBTEXT_CREATOR,
+ DB_TYPE);
}
if (error)
err(1, "Failed to create %s: %d", PtoCstr(reply.fName), error);
- CreateResFile(newpath);
+ getpath(reply.vRefNum, reply.fName, &path, 1);
+
+ CtoPstr(path);
+ CreateResFile(path);
if (ResError() != 0)
- err(1, "Failed to create DB %s: %d", PtoCstr(newpath), ResError());
-
- free(newpath);
+ err(1, "Failed to create DB %s: %d", PtoCstr(path), ResError());
+ PtoCstr(path);
- return db_init(reply, 1);
+ ret = db_init(path, 1);
+ free(path);
+ return ret;
}
struct db *
-db_init(SFReply reply, short is_new)
+db_init(char *path, short is_new)
{
Str255 buf;
struct db *tdb;
- char *newpath;
- Handle resh;
+ Handle resh, lastfileh;
short error, fh, i;
-
- getpath(reply.vRefNum, reply.fName, &newpath, 1);
- CtoPstr(newpath);
-
- fh = OpenResFile(newpath);
+ char *ppath;
+
+ ppath = xstrdup(path);
+ CtoPstr(ppath);
+ fh = OpenResFile(ppath);
if (fh == -1)
- err(1, "Failed to open %s: %d", PtoCstr(newpath), ResError());
-
+ err(1, "Failed to open %s: %d", path, ResError());
+
+ /* we got this far, store it as the last-accessed file */
+ UseResFile(mainResFile);
+ lastfileh = Get1Resource('STR ', STR_LAST_DB);
+ if (lastfileh)
+ xSetHandleSize(lastfileh, ppath[0] + 1);
+ else
+ lastfileh = xNewHandle(ppath[0] + 1);
+ HLock(lastfileh);
+ memcpy(*lastfileh, ppath, ppath[0] + 1);
+ HUnlock(lastfileh);
+ if (HomeResFile(lastfileh) == -1)
+ AddResource(lastfileh, 'STR ', STR_LAST_DB, "\pSTR_LAST_DB");
+ else
+ ChangedResource(lastfileh);
+ WriteResource(lastfileh);
+ DetachResource(lastfileh);
+ UseResFile(fh);
+
+ free(ppath);
+
tdb = xmalloczero(sizeof(struct db));
tdb->fh = fh;
- tdb->vrefnum = reply.vRefNum;
-
- memcpy(tdb->filename, reply.fName, reply.fName[0] + 1);
- PtoCstr(tdb->filename);
-
+ memcpy(tdb->filename, path, strlen(path) + 1);
+
if (db_migrate(tdb, is_new) != 0) {
free(tdb);
return NULL;
}
+ if (!is_new)
+ db_config_load(tdb);
+
return tdb;
}
void
db_close(struct db *tdb)
{
- CloseResFile(tdb->vrefnum);
+ CloseResFile(tdb->fh);
free(tdb);
}
@@ -157,7 +205,8 @@ db_migrate(struct db *tdb, short is_new)
sprintf(tdb->config.location, "Springfield");
sprintf(tdb->config.hostname, "bbs.example.com");
tdb->config.telnet_port = 23;
-
+ db_config_save(tdb);
+
/* create a default sysop user */
user = user_build(tdb, "sysop", &error);
if (!user)
@@ -209,4 +258,53 @@ db_migrate(struct db *tdb, short is_new)
UpdateResFile(tdb->fh);
return 0;
+}
+
+void
+db_config_save(struct db *tdb)
+{
+ Handle hconfig;
+ short is_new = 0;
+
+ hconfig = Get1Resource(DB_CONFIG_RTYPE, 1);
+ if (hconfig) {
+ if (sizeof(tdb->config) != GetHandleSize(hconfig))
+ err(1, "db_config_save: handle size %ld, struct size %ld",
+ GetHandleSize(hconfig), sizeof(tdb->config));
+ } else {
+ hconfig = xNewHandle(sizeof(tdb->config));
+ is_new = 1;
+ }
+
+ HLock(hconfig);
+ memcpy(*hconfig, &tdb->config, sizeof(tdb->config));
+ HUnlock(hconfig);
+
+ if (is_new) {
+ AddResource(hconfig, DB_CONFIG_RTYPE, 1, "\p");
+ if (ResError())
+ err(1, "db_config_save: failed to AddResource: %d",
+ ResError());
+ } else {
+ ChangedResource(hconfig);
+ }
+
+ WriteResource(hconfig);
+ if (ResError())
+ err(1, "db_config_save: failed to WriteResource: %d", ResError());
+ ReleaseResource(hconfig);
+}
+
+void
+db_config_load(struct db *tdb)
+{
+ Handle hconfig;
+
+ hconfig = Get1Resource(DB_CONFIG_RTYPE, 1);
+ if (!hconfig)
+ err(1, "db_config_load: no config in existing db!");
+
+ HLock(hconfig);
+ memcpy(&tdb->config, *hconfig, sizeof(tdb->config));
+ HUnlock(hconfig);
}
--- db.h Sun Dec 5 16:07:41 2021
+++ db.h Sun Dec 5 22:59:33 2021
@@ -57,7 +57,6 @@ struct user {
struct db {
char filename[256];
short fh;
- short vrefnum;
struct config config;
short nusers;
};
@@ -73,8 +72,9 @@ extern struct tmpl tmpls[10];
extern short ntmpls;
void load_db_tmpls(void);
-struct db *db_open(AppFile *file);
+struct db *db_open(char *file);
struct db *db_create(void);
void db_close(struct db *tdb);
+void db_config_save(struct db *tdb);
#endif