コード例 #1
0
ファイル: resload.cpp プロジェクト: BPaden/garglk
/*
 *   Open a resource file given the resource path.
 */
osfildef *CResLoader::open_res_file(const char *respath,
                                    const char *deflib,
                                    const char *exerestype)
{
    char filepath[OSFNMAX];
    osfildef *fp;
    
    /* 
     *   Look for the resource as an external file.  If we have a root
     *   directory, look for the file under that directory; otherwise,
     *   look for it in the current directory.  
     */
    if (root_dir_ != 0)
    {
        char fname[OSFNMAX];
        
        /* get the resource name as a file path */
        os_cvt_url_dir(fname, sizeof(fname), respath, FALSE);

        /* build a full path from the root directory and the resource path */
        os_build_full_path(filepath, sizeof(filepath), root_dir_, fname);
    }
    else
    {
        /* get the resource name as a file path */
        os_cvt_url_dir(filepath, sizeof(filepath), respath, FALSE);
    }

    /* try opening the file */
    fp = osfoprb(filepath, OSFTBIN);

    /* if we didn't find it, try looking in the default library */
    if (fp == 0 && deflib != 0)
    {
        char fname[OSFNMAX];

        /* convert from URL notation to local path conventions */
        os_cvt_url_dir(fname, sizeof(fname), deflib, FALSE);

        /* build the full path, starting in the root resource directory */
        os_build_full_path(filepath, sizeof(filepath), root_dir_, fname);

        /* add the default resource library extension */
        os_defext(filepath, "t3r");

        /* try opening the file */
        fp = open_lib_res(filepath, respath);
    }

    /* if we still didn't find it, try looking in the executable */
    if (fp == 0 && exerestype != 0)
        fp = open_exe_res(respath, exerestype);

    /* return the result */
    return fp;
}
コード例 #2
0
ファイル: vmnetfillcl.cpp プロジェクト: HieuLsw/iphonefrotz
/*
 *   Empty a local directory 
 */
static void empty_dir(VMG_ const char *dir)
{
    /* open the directory search */
    osdirhdl_t dirhdl;
    if (os_open_dir(dir, &dirhdl))
    {
        err_try
        {
            /* keep going until we're out of files */
            char fname[OSFNMAX];
            while (os_read_dir(dirhdl, fname, sizeof(fname)))
            {
                /* get the full path */
                char path[OSFNMAX];
                os_build_full_path(path, sizeof(path), dir, fname);

                /* get the mode */
                unsigned long fmode;
                unsigned long fattr;
                if (osfmode(path, FALSE, &fmode, &fattr))
                {
                    /* check whether it's a directory or an ordinary file */
                    if ((fmode & OSFMODE_DIR) != 0)
                    {
                        /* 
                         *   directory - skip the special '.' and '..' links,
                         *   since they'd get us stuck in a loop 
                         */
                        os_specfile_t st = os_is_special_file(fname);
                        if (st != OS_SPECFILE_SELF && st != OS_SPECFILE_PARENT)
                        {
                            /* recursively empty the directory */
                            empty_dir(vmg_ path);
                            
                            /* remove this directory */
                            if (!os_rmdir(path))
                                err_throw(VMERR_DELETE_FILE);
                        }
                    }
                    else
                    {
                        /* ordinary file - delete it */
                        if (osfdel(path))
                            err_throw(VMERR_DELETE_FILE);
                    }
                }
            }
        }
        err_finally
        {
            /* close the directory search handle */
            os_close_dir(dirhdl);
        }
        err_end;
    }
コード例 #3
0
/*
 *   Scan a resource filename.  We build the full filename by combining the
 *   enclosing library path and the given filename, then we call
 *   scan_full_resource().  
 */
void CTcLibParser::scan_resource(const char *val)
{
    char rel_path[OSFNMAX];
    char full_name[OSFNMAX];

    /* convert the value from a URL-style path to a local path */
    os_cvt_url_dir(rel_path, sizeof(rel_path), val, FALSE);

    /* build the full name */
    os_build_full_path(full_name, sizeof(full_name), lib_path_, rel_path);

    /* call the full resource filename scanner */
    scan_full_resource(val, full_name);
}
コード例 #4
0
ファイル: vmnetfillcl.cpp プロジェクト: tags07/gpm-maze
/*
 *   Open a network file 
 */
CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc,
                             int mode, os_filetype_t typ,
                             const char *mime_type)
{
    vm_val_t filespec;
    
    /* check for a TadsObject implementing getFilename */
    if (G_predef->filespec_getFilename != VM_INVALID_PROP
        && val->typ == VM_OBJ
        && CVmObjTads::is_tadsobj_obj(vmg_ val->val.obj))
    {
        /* call getFilename - the return value is the file spec */
        G_interpreter->get_prop(
            vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc);

        /* the result is the real file spec */
        filespec = *G_interpreter->get_r0();
    }
    else
    {
        /* it's not a TadsObject, so it must directly have the file name */
        filespec = *val;
    }

    /* check the argument type */
    CVmNetFile *nf = 0;
    if (filespec.typ == VM_OBJ
        && CVmObjTemporaryFile::is_tmpfil_obj(vmg_ filespec.val.obj))
    {
        /* temporary file object - get the object, properly cast */
        CVmObjTemporaryFile *tmp = (CVmObjTemporaryFile *)vm_objp(
            vmg_ filespec.val.obj);

        /* if the temporary file object is invalid, it's an error */
        if (tmp->get_fname() == 0)
            err_throw(VMERR_CREATE_FILE);

        /* create the local file descriptor for the temp file path */
        nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ);

        /* mark it as a temp file */
        nf->is_temp = TRUE;
    }
    else
    {
        /* anything else has to be a string */
        char fname[OSFNMAX];
        CVmBif::get_str_val_fname(vmg_ fname, sizeof(fname),
                                  CVmBif::get_str_val(vmg_ &filespec));

        /* 
         *   if it's a local file, and it has a relative path, explicitly
         *   apply the image file path as the default working directory 
         */
        if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_))
        {
            /* build the full, absolute name based on the image file path */
            char fname_abs[OSFNMAX];
            os_build_full_path(fname_abs, sizeof(fname_abs),
                               G_image_loader->get_path(), fname);

            /* replace the relative path with the new absolute path */
            lib_strcpy(fname, sizeof(fname), fname_abs);
        }

        /* create the regular network file descriptor */
        nf = open(vmg_ fname, 0, mode, typ, mime_type);
    }

    /* if they gave us an object as our file spec, remember it */
    if (nf != 0 && val->typ == VM_OBJ)
        nf->filespec = val->val.obj;

    /* return the network file descriptor */
    return nf;
}
コード例 #5
0
ファイル: vmnetfillcl.cpp プロジェクト: HieuLsw/iphonefrotz
/*
 *   Open a network file 
 */
CVmNetFile *CVmNetFile::open(VMG_ const vm_val_t *val, const vm_rcdesc *rc,
                             int mode, os_filetype_t typ,
                             const char *mime_type)
{
    vm_val_t filespec;
    
    /* check for a TadsObject implementing getFilename */
    if (G_predef->filespec_getFilename != VM_INVALID_PROP
        && vm_val_cast_ok(CVmObjTads, val))
    {
        /* call getFilename - the return value is the file spec */
        G_interpreter->get_prop(
            vmg_ 0, val, G_predef->filespec_getFilename, val, 0, rc);

        /* the result is the real file spec */
        filespec = *G_interpreter->get_r0();
    }
    else
    {
        /* it's not a TadsObject, so it must directly have the file name */
        filespec = *val;
    }

    /* check the file spec argument type */
    CVmNetFile *nf = 0;
    CVmObjTemporaryFile *tmp = 0;
    CVmObjFileName *ofn = 0;
    if ((tmp = vm_val_cast(CVmObjTemporaryFile, &filespec)) != 0)
    {
        /* if the temporary file object is invalid, it's an error */
        if (tmp->get_fname() == 0)
            err_throw(VMERR_CREATE_FILE);

        /* create the local file descriptor for the temp file path */
        nf = open_local(vmg_ tmp->get_fname(), 0, mode, typ);

        /* mark it as a temp file */
        nf->is_temp = TRUE;
    }
    else if (filespec.is_numeric(vmg0_)
             || ((ofn = vm_val_cast(CVmObjFileName, &filespec)) != 0
                 && ofn->is_special_file()))
    {
        /* 
         *   It's a special file ID, either as an integer or as a FileName
         *   wrapping a special file int.  Get the value. 
         */
        int32_t sfid = (ofn != 0 ? ofn->get_sfid()
                                 : filespec.num_to_int(vmg0_));

        /* resolve the file system path for the given special file ID */
        char fname[OSFNMAX] = { '\0' };
        if (!CVmObjFile::sfid_to_path(vmg_ fname, sizeof(fname), sfid))
            err_throw(VMERR_BAD_VAL_BIF);

        /* create the special file descriptor */
        nf = open(vmg_ fname, sfid, mode, typ, mime_type);
    }
    else
    {
        /* anything else has to be a string */
        char fname[OSFNMAX];
        CVmBif::get_fname_val(vmg_ fname, sizeof(fname), &filespec);

        /* 
         *   if it's a local file, and it has a relative path, explicitly
         *   apply the image file path as the default working directory 
         */
        if (!os_is_file_absolute(fname) && !is_net_mode(vmg0_))
        {
            /* build the full, absolute name based on the file base path */
            char fnabs[OSFNMAX];
            os_build_full_path(fnabs, sizeof(fnabs), G_file_path, fname);

            /* replace the relative path with the new absolute path */
            lib_strcpy(fname, sizeof(fname), fnabs);
        }

        /* create the regular network file descriptor */
        nf = open(vmg_ fname, 0, mode, typ, mime_type);
    }

    /* if they gave us an object as our file spec, remember it */
    if (nf != 0 && val->typ == VM_OBJ)
        nf->filespec = val->val.obj;

    /* return the network file descriptor */
    return nf;
}
コード例 #6
0
ファイル: ostzposix.c プロジェクト: HieuLsw/iphonefrotz
/* Get the local time zone name, as a zoneinfo database key.  Many
 * modern Unix systems use zoneinfo keys as they native timezone
 * setting, but there are several different ways of storing this on a
 * per-process and system-wide basis.  We'll try looking for the common
 * mechanisms.
 */
int
os_get_zoneinfo_key( char *buf, size_t buflen )
{
    /* First, try the TZ environment variable.  This is used on nearly
     * all Unix-alikes for a per-process timezone setting, although
     * it will only contain a zoneinfo key in newer versions.  There
     * are several possible formats for specifying a zoneinfo key:
     *
     *  TZ=/usr/share/zoneinfo/America/Los_Angeles
     *    - A full absolute path name to a tzinfo file.  We'll sense
     *      this by looking for "/zoneinfo/" in the string, and if we
     *      find it, we'll return the portion after /zoneinfo/.
     *
     *  TZ=America/Los_Angeles
     *    - Just the zoneinfo key, without a path.  If we find a string
     *      that contains all alphabetics, undersores, and slashes, and
     *      has at least one internal slash but doesn't start with a
     *      slash, we probably have a zoneinfo key.  We'll see if we
     *      can find a matching file in the usual zoneinfo database
     *      locations: /etc/zoneinfo, /usr/share/zoneinfo; if we can,
     *      we'll return the key name, otherwise we'll assume this
     *      isn't actually a zoneinfo key but just happens to look like
     *      one in terms of format.
     *
     *  TZ=:America/Los_Angeles
     *  TZ=:/etc/zoneinfo/America/Los_Angeles
     *    - POSIX systems generally use the ":" prefix to signify that
     *      this is a zoneinfo path rather than the old-style "EST5EDT"
     *      type of self-contained zone description.  If we see a colon
     *      prefix with a relative path (properly formed in terms of
     *      its character content), we'll simply assume this is a
     *      zoneinfo key without even checking for an existing file,
     *      since there's not much else it could be.  If we see an
     *      absolute path, we'll search it for /zoneinfo/ and return
     *      the portion after this, again without checking for an
     *      existing file.
     */
    const char *tz = getenv("TZ");
    if (tz != 0 && tz[0] != '\0')
    {
        /* check that the string is formatted like a zoneinfo key */
#define tzcharok(c) (isalpha(c) != 0 || (c) == '/' || (c) == '_')
        int fmt_ok = TRUE;
        const char *p;
        fmt_ok &= (tz[0] == ':' || tzcharok(tz[0]));
        for (p = tz + 1 ; *p != '\0' ; ++p)
            fmt_ok &= tzcharok(*p);

        /* proceed only if it has the right format */
        if (fmt_ok)
        {
            /* check for a leading ':', per POSIX */
            if (tz[0] == ':')
            {
                /* yes, we have a leading ':', so it's almost certainly
                 * a zoneinfo key; if it's an absolute path, find the
                 * part after /zoneinfo/
                 */
                if (tz[1] == '/')
                {
                    /* absolute form - look for /zoneinfo/ */
                    const char *z = strstr(tz, "/zoneinfo/");
                    if (z != 0)
                    {
                        /* found it - return the part after /zoneinfo/ */
                        safe_strcpy(buf, buflen, z + 10);
                        return TRUE;
                    }
                }
                else
                {
                    /* relative path - return as-is minus the colon */
                    safe_strcpy(buf, buflen, tz + 1);
                    return TRUE;
                }
            }
            else
            {
                /* There's no colon, so it *might* be a zoneinfo key.
                 * If it's an absolute path containing /zoneinfo/, it's
                 * a solid bet.  If it's a relative path, look to see
                 * if we can find a file in one of the usual zoneinfo
                 * database locations.
                 */
                if (tz[0] == '/')
                {
                    /* absolute path - check for /zoneinfo/ */
                    const char *z = strstr(tz, "/zoneinfo/");
                    if (z != 0)
                    {
                        /* found it - return the part after /zoneinfo/ */
                        safe_strcpy(buf, buflen, z + 10);
                        return TRUE;
                    }
                }
                else
                {
                    /* relative path - look for a tzinfo file in the
                     * usual locations
                     */
                    static const char *dirs[] = {
                        "/etc/zoneinfo",
                        "/usr/share/zoneinfo",
                        0
                    };
                    const char **dir;
                    for (dir = dirs ; *dir != 0 ; ++dir)
                    {
                        /* build this full path */
                        char fbuf[OSFNMAX];
                        os_build_full_path(fbuf, sizeof(fbuf), *dir, tz);

                        /* check for a file at this location */
                        if (!osfacc(fbuf))
                        {
                            /* got it - looks like a good zoneinfo key */
                            safe_strcpy(buf, buflen, tz);
                            return TRUE;
                        }
                    }
                }
            }
        }
    }

    /* No luck with TZ, so try the system-wide settings next.
     *
     * If a file called /etc/timezone exists, it's usually a one-line
     * text file containing the zoneinfo key.  Read and return its
     * contents.
     */
    FILE *fp;
    if ((fp = fopen("/etc/timezone", "r")) != 0)
    {
        /* read the one-liner */
        char lbuf[256];
        int ok = FALSE;
        if (fgets(lbuf, sizeof(lbuf), fp) != 0)
        {
            /* strip any trailing newline */
            size_t l = strlen(lbuf);
            if (l != 0 && lbuf[l-1] == '\n')
                lbuf[l-1] = '\0';

            /* if it's in absolute format, return the part after
             * /zoneinfo/; otherwise just return the string
             */
            if (lbuf[0] == '/')
            {
                /* absoltue path - find /zoneinfo/ */
                const char *z = strstr(lbuf, "/zoneinfo/");
                if (z != 0)
                {
                    safe_strcpy(buf, buflen, z + 10);
                    ok = TRUE;
                }
            }
            else
            {
                /* relative notation - return it as-is */
                safe_strcpy(buf, buflen, lbuf);
                ok = TRUE;
            }
        }

        /* we're done with the file */
        fclose(fp);

        /* if we got our result, return success */
        if (ok)
            return TRUE;
    }

    /* If /etc/sysconfig/clock exists, read it and look for a line
     * starting with ZONE=.  This contains the zoneinfo key.
     */
    if ((fp = fopen("/etc/sysconfig/clock", "r")) != 0)
    {
        /* scan the file for ZONE=... */
        int ok = FALSE;
        for (;;)
        {
            /* read the next line */
            char lbuf[256];
            if (fgets(lbuf, sizeof(lbuf), fp) == 0)
                break;

            /* skip leading spaces */
            const char *p;
            for (p = lbuf ; isspace(*p) ; ++p) ;

            /* check for ZONE */
            if (memicmp(p, "zone", 4) != 0)
                continue;

            /* skip spaces after ZONE */
            for (p += 4 ; isspace(*p) ; ++p) ;

            /* check for '=' */
            if (*p != '=')
                continue;

            /* skip spaces after the '=' */
            for (++p ; isspace(*p) ; ++p) ;

            /* if it's in absolute form, look for /zoneinfo/ */
            if (*p == '/')
            {
                const char *z = strstr(p, "/zoneinfo/");
                if (z != 0)
                {
                    safe_strcpy(buf, buflen, z + 10);
                    ok = TRUE;
                }
            }
            else
            {
                /* relative notation - it's the zoneinfo key */
                safe_strcpy(buf, buflen, p);
                ok = TRUE;
            }

            /* that's our ZONE line, so we're done scanning the file */
            break;
        }

        /* done with the file */
        fclose(fp);

        /* if we got our result, return success */
        if (ok)
            return TRUE;
    }

    /* If /etc/localtime is a symbolic link, the linked file is the
     * actual zoneinfo file.  Resolve the link and return the portion
     * of the path after "/zoneinfo/".
     */
#if 0
    static const char *elt = "/etc/localtime";
    unsigned long mode;
    char linkbuf[OSFNMAX];
    const char *zi;
    if (osfmode(elt, FALSE, &mode, NULL)
        && (mode & OSFMODE_LINK) != 0
        && os_resolve_symlink(elt, linkbuf, sizeof(linkbuf))
        && (zi = strstr(linkbuf, "/zoneinfo/")) != 0)
    {
        /* it's a link containing /zoneinfo/, so return the portion
         * after /zoneinfo/
         */
        safe_strcpy(buf, buflen, zi + 10);
        return TRUE;
    }
#endif
    /* well, we're out of ideas - return failure */
    return FALSE;
}
コード例 #7
0
ファイル: vminit.cpp プロジェクト: tags07/gpm-maze
/*
 *   Perform base initialization.  This is an internal routine called only
 *   by higher-level initialization routines; we perform all of the
 *   generic, configuration-independent initialization.
 */
void vm_init_base(vm_globals **vmg, const vm_init_options *opts)
{
    vm_globals *vmg__;
    char disp_mapname[32];
    char filename_mapname[32];
    char filecont_mapname[32];
    CResLoader *map_loader;
    int disp_map_err;
    const char *charset = opts->charset;
    
    /* 
     *   Allocate globals according to build-time configuration, then
     *   assign the global pointer to a local named vmg__.  This will
     *   ensure that the globals are accessible for all of the different
     *   build-time configurations.  
     */
    vmg__ = *vmg = vmglob_alloc();

    /* initialize the error stack */
    err_init(VM_ERR_STACK_BYTES);

    /* get the character map loader from the host interface */
    map_loader = opts->hostifc->get_cmap_res_loader();

    /* if an external message set hasn't been loaded, try loading one */
    if (!err_is_message_file_loaded() && map_loader != 0)
    {
        osfildef *fp;
        
        /* try finding a message file */
        fp = map_loader->open_res_file(VM_ERR_MSG_FNAME, 0,
                                       VM_ERR_MSG_RESTYPE);
        if (fp != 0)
        {
            /* 
             *   try loading it - if that fails, we'll just be left with
             *   the built-in messages, so we won't have lost anything for
             *   trying 
             */
            err_load_vm_message_file(fp);
            
            /* we're done with the file */
            osfcls(fp);
        }
    }

    /* remember the host interface */
    G_host_ifc = opts->hostifc;

    /* initialize the system debug log file name */
    char path[OSFNMAX];
    opts->hostifc->get_special_file_path(path, sizeof(path), OS_GSP_LOGFILE);
    os_build_full_path(G_syslogfile, sizeof(G_syslogfile),
                       path, "tadslog.txt");

    /* we don't have a resource loader for program resources yet */
    G_res_loader = 0;

    /* create the object table */
    VM_IF_ALLOC_PRE_GLOBAL(G_obj_table = new CVmObjTable());
    G_obj_table->init(vmg0_);

    /* 
     *   Create the memory manager.  Empirically, our hybrid heap allocator
     *   is faster than the standard C++ run-time library's allocator on many
     *   platforms, so use it instead of hte basic 'malloc' allocator. 
     */
    G_varheap = new CVmVarHeapHybrid(G_obj_table);
    // G_varheap = new CVmVarHeapMalloc(); to use the system 'malloc' instead
    G_mem = new CVmMemory(vmg_ G_varheap);

    /* create the undo manager */
    G_undo = new CVmUndo(VM_UNDO_MAX_RECORDS, VM_UNDO_MAX_SAVEPTS);

    /* create the metafile and function set tables */
    G_meta_table = new CVmMetaTable(5);
    G_bif_table = new CVmBifTable(5);

    /* initialize the metaclass registration tables */
    vm_register_metaclasses();

    /* initialize the TadsObject class */
    CVmObjTads::class_init(vmg0_);

    /* create the byte-code interpreter */
    VM_IFELSE_ALLOC_PRE_GLOBAL(
        G_interpreter = new CVmRun(VM_STACK_SIZE, vm_init_stack_reserve()),
        G_interpreter->init());

    /* presume we won't create debugger information */
    G_debugger = 0;
    G_srcf_table = 0;

    /* presume we don't have a network configuration */
    G_net_config = 0;

    /* initialize the debugger if present */
    vm_init_debugger(vmg0_);

    /* create the source file table */
    G_srcf_table = new CVmSrcfTable();

    /* create the pre-defined object mapper */
    VM_IFELSE_ALLOC_PRE_GLOBAL(G_predef = new CVmPredef, G_predef->reset());

    /* presume we're in normal execution mode (not preinit) */
    G_preinit_mode = FALSE;

    /* allocate the TADS intrinsic function set's globals */
    G_bif_tads_globals = new CVmBifTADSGlobals(vmg0_);

    /* allocate the BigNumber register cache */
    G_bignum_cache = new CVmBigNumCache(32);

    /* no image loader yet */
    G_image_loader = 0;

    /*
     *   If the caller explicitly specified a character set, use it.
     *   Otherwise, ask the OS layer for the default character set we
     *   should use. 
     */
    if (charset == 0)
    {
        /* the user did not specify a mapping - ask the OS for the default */
        os_get_charmap(disp_mapname, OS_CHARMAP_DISPLAY);

        /* use the name we got from the OS */
        charset = disp_mapname;

        /* there's no explicit global character set name setting to store */
        G_disp_cset_name = 0;
    }
    else
    {
        /* save the global character set name */
        G_disp_cset_name = lib_copy_str(charset);
    }

    /* create the display character maps */
    G_cmap_from_ui = CCharmapToUni::load(map_loader, charset);
    G_cmap_to_ui = CCharmapToLocal::load(map_loader, charset);

    /* create the filename character maps */
    os_get_charmap(filename_mapname, OS_CHARMAP_FILENAME);
    G_cmap_from_fname = CCharmapToUni::load(map_loader, filename_mapname);
    G_cmap_to_fname = CCharmapToLocal::load(map_loader, filename_mapname);

    /* create the file-contents character maps */
    os_get_charmap(filecont_mapname, OS_CHARMAP_FILECONTENTS);
    G_cmap_from_file = CCharmapToUni::load(map_loader, filecont_mapname);
    G_cmap_to_file = CCharmapToLocal::load(map_loader, filecont_mapname);

    /* 
     *   If the caller specified a separate log-file character set, create
     *   the mapping.  Otherwise, just use the to-file mapper for log files.
     */
    if (opts->log_charset != 0)
    {
        /* load the specified log file output mapping */
        G_cmap_to_log = CCharmapToLocal::load(map_loader, opts->log_charset);
    }
    else
    {
        /* no log file mapping is specified, so use the generic file map */
        if ((G_cmap_to_log = G_cmap_to_file) != 0)
            G_cmap_to_log->add_ref();
    }

    /* make a note of whether we had any problems loading the maps */
    disp_map_err = (G_cmap_from_ui == 0 || G_cmap_to_ui == 0);

    /* if we failed to create any of the maps, load defaults */
    if (G_cmap_from_ui == 0)
        G_cmap_from_ui = CCharmapToUni::load(map_loader, "us-ascii");
    if (G_cmap_to_ui == 0)
        G_cmap_to_ui = CCharmapToLocal::load(map_loader, "us-ascii");
    if (G_cmap_from_fname == 0)
        G_cmap_from_fname = CCharmapToUni::load(map_loader, "us-ascii");
    if (G_cmap_to_fname == 0)
        G_cmap_to_fname = CCharmapToLocal::load(map_loader, "us-ascii");
    if (G_cmap_from_file == 0)
        G_cmap_from_file = CCharmapToUni::load(map_loader, "us-ascii");
    if (G_cmap_to_file == 0)
        G_cmap_to_file = CCharmapToLocal::load(map_loader, "us-ascii");
    if (G_cmap_to_log == 0)
        G_cmap_to_log = CCharmapToLocal::load(map_loader, "us-ascii");

    /* create the primary console */
    G_console = opts->clientifc->create_console(VMGLOB_ADDR);

    /* 
     *   if we had any trouble opening the display character mapping file,
     *   make a note that we are using a default mapping 
     */
    if (disp_map_err)
    {
        const char *msg;
        char buf[256];

        /* get the message */
        msg = err_get_msg(vm_messages, vm_message_count,
                          VMERR_NO_CHARMAP_FILE, TRUE);

        /* format it */
        sprintf(buf, msg, charset);

        /* display it */
        opts->clientifc->display_error(VMGLOB_ADDR, 0, buf, TRUE);
    }
}