00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "cstream.h"
00022 #include "htcfg.h"
00023 #include "htctrl.h"
00024 #include "htdebug.h"
00025 #include "htendian.h"
00026 #include "htreg.h"
00027 #include "htstring.h"
00028 #include "stream.h"
00029 #include "store.h"
00030 #include "htsys.h"
00031 #include "tools.h"
00032
00033 #include <errno.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036
00037
00038
00039
00040
00041
00042 #define object_stream_bin 0
00043 #define object_stream_txt 1
00044 #define object_stream_bin_compressed 2
00045
00046 ht_object_stream *create_object_stream(ht_stream *f, int object_stream_type)
00047 {
00048 ht_object_stream *s;
00049 switch (object_stream_type) {
00050 case object_stream_bin: {
00051 s=new ht_object_stream_bin();
00052 ((ht_object_stream_bin*)s)->init(f);
00053 break;
00054 }
00055 case object_stream_txt: {
00056 s=new ht_object_stream_txt();
00057 ((ht_object_stream_txt*)s)->init(f);
00058 break;
00059 }
00060 case object_stream_bin_compressed: {
00061 ht_compressed_stream *cs=new ht_compressed_stream();
00062 cs->init(f, false);
00063 s=new ht_object_stream_bin();
00064 ((ht_object_stream_bin*)s)->init(cs);
00065 s->set_stream_ownership(true);
00066 break;
00067 }
00068 default: {
00069 return NULL;
00070 }
00071 }
00072 return s;
00073 }
00074
00075 struct config_header {
00076 char magic[4] HTPACKED;
00077 char version[4] HTPACKED;
00078 char stream_type[2] HTPACKED;
00079 };
00080
00081
00082
00083
00084
00085 char *systemconfig_file;
00086
00087
00088
00089 loadstore_result save_systemconfig()
00090 {
00091 ht_file *f = new ht_file();
00092 f->init(systemconfig_file, FAM_WRITE, FOM_CREATE);
00093 if (f->get_error()) {
00094 f->done();
00095 delete f;
00096 return LS_ERROR_WRITE;
00097 }
00098
00099
00100 config_header h;
00101
00102 memmove(h.magic, ht_systemconfig_magic, sizeof h.magic);
00103
00104 char q[16];
00105
00106 int system_ostream_type = get_config_dword("misc/config format");
00107
00108 sprintf(q, "%04x", ht_systemconfig_fileversion);
00109 memmove(h.version, q, sizeof h.version);
00110
00111 sprintf(q, "%02x", system_ostream_type);
00112 memmove(h.stream_type, q, sizeof h.stream_type);
00113
00114 f->write(&h, sizeof h);
00115
00116
00117 ht_object_stream *d = create_object_stream(f, system_ostream_type);
00118
00119 switch (system_ostream_type) {
00120 case object_stream_bin:
00121 break;
00122 case object_stream_txt:
00123 f->write((void*)"\n#\n#\tThis is a generated file!\n#\n", 33);
00124 break;
00125 }
00126
00127 app->store(d);
00128 if (d->get_error()) return LS_ERROR_WRITE;
00129
00130 d->done();
00131 delete d;
00132
00133 f->done();
00134 delete f;
00135
00136 return LS_OK;
00137 }
00138
00139 bool load_systemconfig(loadstore_result *result, int *error_info)
00140 {
00141 ht_file *f = new ht_file();
00142 f->init(systemconfig_file, FAM_READ, FOM_EXISTS);
00143 switch (f->get_error()) {
00144 case 0:break;
00145 case STERR_SYSTEM | ENOENT:
00146 f->done();
00147 delete f;
00148 *result = LS_ERROR_NOT_FOUND;
00149 return false;
00150 default:
00151 f->done();
00152 delete f;
00153 *result = LS_ERROR_READ;
00154 return false;
00155 }
00156
00157 config_header h;
00158
00159 if (f->read(&h, sizeof h)!=sizeof h) {
00160 *result = LS_ERROR_MAGIC;
00161 f->done();
00162 delete f;
00163 return false;
00164 }
00165
00166 if (memcmp(h.magic, ht_systemconfig_magic, sizeof h.magic)!=0) {
00167 *result = LS_ERROR_MAGIC;
00168 f->done();
00169 delete f;
00170 return false;
00171 }
00172
00173 uint16 readver;
00174 if (!hexw_ex(readver, (char*)h.version) || (readver != ht_systemconfig_fileversion)) {
00175 *result = LS_ERROR_VERSION;
00176 *error_info = readver;
00177 f->done();
00178 delete f;
00179 return false;
00180 }
00181
00182
00183 uint8 object_stream_type;
00184 if (!hexb_ex(object_stream_type, (char*)h.stream_type)) {
00185 *result = LS_ERROR_FORMAT;
00186 f->done();
00187 delete f;
00188 return false;
00189 }
00190
00191 ht_object_stream *d = create_object_stream(f, object_stream_type);
00192 if (!d) {
00193 *result = LS_ERROR_FORMAT;
00194 f->done();
00195 delete f;
00196 return false;
00197 }
00198
00199
00200 if (app->load(d)!=0) {
00201 *result = LS_ERROR_CORRUPTED;
00202 *error_info = 0;
00203 if (d->get_error()) {
00204 if (object_stream_type==object_stream_txt)
00205 *error_info = ((ht_object_stream_txt*)d)->getErrorLine();
00206 }
00207 f->done();
00208 delete f;
00209 return false;
00210 }
00211
00212 d->done();
00213 delete d;
00214
00215 f->done();
00216 delete f;
00217
00218 *result = LS_OK;
00219 return true;
00220 }
00221
00222
00223
00224 loadstore_result save_fileconfig(char *fileconfig_file, const char *magic, UINT version, store_fcfg_func store_func, void *context)
00225 {
00226 ht_file *f=new ht_file();
00227 f->init(fileconfig_file, FAM_WRITE, FOM_CREATE);
00228 if (f->get_error()) {
00229 f->done();
00230 delete f;
00231 return LS_ERROR_WRITE;
00232 }
00233
00234
00235 config_header h;
00236
00237 memmove(h.magic, magic, sizeof h.magic);
00238
00239 char q[16];
00240
00241 int file_ostream_type = get_config_dword("misc/config format");
00242
00243 sprintf(q, "%04x", version);
00244 memmove(h.version, q, sizeof h.version);
00245
00246 sprintf(q, "%02x", file_ostream_type);
00247 memmove(h.stream_type, q, sizeof h.stream_type);
00248
00249 f->write(&h, sizeof h);
00250
00251
00252 ht_object_stream *d = create_object_stream(f, file_ostream_type);
00253
00254 switch (file_ostream_type) {
00255 case object_stream_bin:
00256 break;
00257 case object_stream_txt:
00258 f->write((void*)"\n#\n#\tThis is a generated file!\n#\n", 33);
00259 break;
00260 }
00261
00262 store_func(d, context);
00263
00264 d->done();
00265 delete d;
00266
00267 f->done();
00268 delete f;
00269
00270 return LS_OK;
00271 }
00272
00273 loadstore_result load_fileconfig(char *fileconfig_file, const char *magic, UINT version, load_fcfg_func load_func, void *context, int *error_info)
00274 {
00275 ht_file *f=new ht_file();
00276 f->init(fileconfig_file, FAM_READ, FOM_EXISTS);
00277 switch (f->get_error()) {
00278 case 0:break;
00279 case STERR_SYSTEM | ENOENT:
00280 f->done();
00281 delete f;
00282 return LS_ERROR_NOT_FOUND;
00283 default:
00284 f->done();
00285 delete f;
00286 return LS_ERROR_READ;
00287 }
00288
00289 config_header h;
00290
00291 if (f->read(&h, sizeof h)!=sizeof h) {
00292 f->done();
00293 delete f;
00294 return LS_ERROR_MAGIC;
00295 }
00296
00297 if (memcmp(h.magic, magic, sizeof h.magic)!=0) return LS_ERROR_MAGIC;
00298
00299 uint16 readver;
00300 if (!hexw_ex(readver, (char*)h.version) || (readver != version)) {
00301 f->done();
00302 delete f;
00303 *error_info = readver;
00304 return LS_ERROR_VERSION;
00305 }
00306
00307 uint8 object_stream_type;
00308 if (!hexb_ex(object_stream_type, (char*)h.stream_type)) {
00309 f->done();
00310 delete f;
00311 return LS_ERROR_FORMAT;
00312 }
00313
00314
00315 ht_object_stream *d = create_object_stream(f, object_stream_type);
00316 if (!d) {
00317 f->done();
00318 delete f;
00319 return LS_ERROR_FORMAT;
00320 }
00321
00322
00323 if (load_func(d, context)) {
00324 *error_info = 0;
00325 if (d->get_error()) {
00326 if (object_stream_type==object_stream_txt)
00327 *error_info = ((ht_object_stream_txt*)d)->getErrorLine();
00328 }
00329 f->done();
00330 delete f;
00331 return LS_ERROR_CORRUPTED;
00332 }
00333
00334 d->done();
00335 delete d;
00336
00337 f->done();
00338 delete f;
00339
00340 return LS_OK;
00341 }
00342
00343
00344
00345
00346
00347 bool init_cfg()
00348 {
00349 #if defined(MSDOS) || defined(DJGPP) || defined(WIN32) || defined(__WIN32__)
00350 char d[1024];
00351 sys_dirname(d, appname);
00352 char *b = "\\"SYSTEM_CONFIG_FILE_NAME;
00353 systemconfig_file = (char*)malloc(strlen(d)+strlen(b)+1);
00354 strcpy(systemconfig_file, d);
00355 strcat(systemconfig_file, b);
00356 #else
00357 char *home = getenv("HOME");
00358 char *b = "/"SYSTEM_CONFIG_FILE_NAME;
00359 if (!home) home = "";
00360 systemconfig_file = (char*)malloc(strlen(home)+strlen(b)+1);
00361 strcpy(systemconfig_file, home);
00362 strcat(systemconfig_file, b);
00363 #endif
00364 return true;
00365 }
00366
00367
00368
00369
00370
00371 void done_cfg()
00372 {
00373 free(systemconfig_file);
00374 }