int config68_save(const char * confname) { return 0; int err = 0; char tmp[128]; option68_t * opt; confname = confname ? confname : config68_def_name; if (!config68_use_registry) { /* Save into file */ vfs68_t * os=0; const int sizeof_config_hd = sizeof(config_header)-1; strncpy(tmp, "sc68://config/", sizeof(tmp)); strncat(tmp, confname, sizeof(tmp)); os = uri68_vfs(tmp, 2, 0); err = vfs68_open(os); if (!err) { TRACE68(config68_cat,"conf68: save into \"%s\"\n", vfs68_filename(os)); err = - (vfs68_write(os, config_header, sizeof_config_hd) != sizeof_config_hd); for (opt = option68_enum(0); opt; opt=opt->next) err |= save_config_entry(os, opt); } vfs68_close(os); vfs68_destroy(os); } else { /* Save into registry */ int l = snprintf(tmp, sizeof(tmp), cuk_fmt, confname); char * s = tmp + l; l = sizeof(tmp) - l; for (opt = option68_enum(0); opt; opt=opt->next) { if (opt->org == opt68_UDF || !opt->save) continue; strncpy(s,opt->name,l); switch (opt->type) { case opt68_INT: case opt68_BOL: err |= registry68_puti(0, tmp, opt->val.num); break; case opt68_ENU: err |= registry68_puts(0, tmp, opt->val.num[(char**)opt->set]); break; case opt68_STR: err |= registry68_puts(0, tmp, opt->val.str); break; } } } return err; }
int vfs68_putc(vfs68_t *vfs, const int c) { unsigned char byte = c; return -(vfs68_write(vfs,&byte,1) != 1); }
static vfs68_t * default_open(rsc68_t type, const char *name, int mode, rsc68_info_t * info) { vfs68_t * is = 0; int err = -1; const char *subdir = 0, *ext = 0; char tmp[1024], * apath = 0; char tmpname[512]; int alen = 0; char_cv_t cv_path=0, cv_extra=0; struct { const char * path, * sdir, * ext; int curl; } pathes[4]; int ipath, npath = 0; const char * share_path = default_share_path(); const char * rmusic_path = default_rmusic_path(); /* default to invalid type. */ if (info) { info->type = rsc68_last; } if ( (int) type < 0 || (int)type >= rsc68_last) { return 0; } memset(pathes,0,sizeof(pathes)); if (type == rsc68_music && lmusic_path) { /* local music path is prior to user share */ pathes[npath].path = lmusic_path; pathes[npath].sdir = "/"; ++npath; } /* Build default pathes list */ if (user_path) { pathes[npath++].path = user_path; } switch (mode &= 3) { case 1: case 2: break; default: assert(!"invalid mode"); return 0; } if (mode == 1 && share_path) { pathes[npath++].path = share_path; } subdir = rsc68_table[type].path; ext = rsc68_table[type].ext; /* Set a default name for config file if none is given. */ if (type == rsc68_config && (!name || !name[0])) { name = "sc68"; } TRACE68(rsc68_cat,"rsc68: open %c 'sc68://%s/%s%s'\n", (mode==1)?'R':'W',rsc68_table[type].name, name, ext?ext:""); /* Any specific stuff. */ switch (type) { case rsc68_replay: #if defined (USE_REPLAY68) && 0 /* Method using vfs to inflate data. Notice that unfortunatly * we can't use a proper Z stream because the replay loader needs * to know the length and vfs68_z::length() method does not * have this information before it has inflated the all data. This * is a limitation that could probably be dealt with, at least * with gziped stream as the information is available at the end * of the stream. Also in this particular case the inflate size is * available via the replay68_get() function. */ if (mode == 1) { const void * cdata; int csize, dsize; vfs68_t * is_in; TRACE68(rsc68_cat,"rsc68: trying built-in replay -- %s\n", name); if (!replay68_get(name, &cdata, &csize, &dsize)) { TRACE68(rsc68_cat,"rsc68: found built-in replay -- %s %d %d\n", name, csize, dsize); is_in = vfs68_z_create( vfs68_mem_create(cdata, csize, mode), mode|VFS68_SLAVE, vfs68_z_default_option); if (is_in) { is = vfs68_mem_create(0, dsize, 3); if (!vfs68_open(is_in) && !vfs68_open(is)) { int n; while (n = vfs68_read(is_in, tmpname, sizeof(tmpname)), n > 0) if (vfs68_write(is, tmpname, n) != n) { n = -1; break; } err = -!!n; } vfs68_destroy(is_in); vfs68_seek_to(is,0); } } } #elif defined (USE_REPLAY68) /* Method using gzip68_buffer() is probably faster (less memory * copy) than the previous Z stream one. It still need to allocate * a temporary buffer to store deflated data whereas a proper * vfs could have deflated on the fly into the 68k memory * buffer. See previous method comment on that matter. */ if (mode == 1) { const void * cdata; void * ddata; int csize, dsize; TRACE68(rsc68_cat,"rsc68: trying built-in replay -- %s\n", name); if (!replay68_get(name, &cdata, &csize, &dsize)) { TRACE68(rsc68_cat,"rsc68: found built-in replay -- %s %d %d\n", name, csize, dsize); ddata = malloc(dsize); if (ddata) { int inflate = gzip68_buffer(ddata, dsize, cdata, csize); if (inflate != dsize) { msg68_error("rsc68: inflated size of built-in replay differs" " -- %s %d %d\n",name, inflate, dsize); err = -1; } else { is = vfs68_mem_create(ddata, dsize, mode|VFS68_SLAVE); if ( (err = -!is) != 0) { free(ddata); } } } } } #endif cv_extra = cv_lower; /* $$$ transform replay name to lower case. */ break; case rsc68_music: if (mode == 1 && rmusic_path) { pathes[npath].path = rmusic_path; pathes[npath].sdir = "/"; pathes[npath].curl = 1; ++npath; } name = convert_music_path(tmpname, sizeof(tmpname), name, info); break; default: break; } for (ipath=0; !is && name && ipath < npath; ++ipath) { const char *cpath, * cdir, * cext; char *p, *pe, *path; int len, l; cpath = pathes[ipath].path; cdir = pathes[ipath].sdir ? pathes[ipath].sdir : subdir; cext = pathes[ipath].ext ? pathes[ipath].ext : ext; len = 1 + strlen(cpath) + strlen(cdir) + strlen(name) + (cext ? strlen(cext) : 0); if (len <= alen) { path = apath; } else if (len <= sizeof(tmp)) { path = tmp; } else { free(apath); apath = malloc(len); alen = apath ? len : 0; path = apath; } if (!path) { continue; } p = path; pe = path + len; cv_path = pathes[ipath].curl ? cv_path_remote : cv_path_local; /* Build path. */ l = copy_path(p, pe-p, cpath, cv_path, 0 , 0); p += l; l = copy_path(p, pe-p, cdir, cv_path, 0, 0); p += l; l = copy_path(p, pe-p, name, cv_path, cv_extra, 0); p += l; if (cext) { l = copy_path(p, pe-p, cext, 0, 0 ,0); p += l; } is = uri68_vfs(path, mode, 0); err = vfs68_open(is); TRACE68(rsc68_cat, "rsc68: try [%s]\n", strok68(err)); if (!err) break; vfs68_destroy(is); is = 0; } if (apath != tmp) free(apath); if (err) { vfs68_destroy(is); is = 0; } if (is && info) info->type = type; TRACE68(rsc68_cat, "rsc68: open '%s' -- *%s*\n", vfs68_filename(is), strok68(!is)); return is; }