int io68_init(int * argc, char ** argv) { int i,err; for ( err = i = 0; i < max; ++i ) { if (func[i].init) { err = func[i].init(argc, argv); if (err) { msg68_error("io68: failed to initialize *%s* IO plugin\n",func[i].name); break; } } } return err; }
istream68_t * istream68_file_create(context68_t * context, const char * fname, int mode) { msg68_error("file68: create -- *NOT SUPPORTED*"); return 0; }
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; }