Exemple #1
0
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;
}
Exemple #2
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;
}