int autostart_prg_with_virtual_fs(const char *file_name, fileio_info_t *fh) { char *directory; char *file; /* Extract the directory path to allow FS-based drive emulation to work. */ util_fname_split(file_name, &directory, &file); if (archdep_path_is_relative(directory)) { char *tmp; archdep_expand_path(&tmp, directory); lib_free(directory); directory = tmp; /* FIXME: We should actually eat `.'s and `..'s from `directory' instead. */ } /* Setup FS-based drive emulation. */ fsdevice_set_directory(directory ? directory : ".", 8); resources_set_int("DriveTrueEmulation", 0); resources_set_int("VirtualDevices", 1); resources_set_int("FSDevice8ConvertP00", 1); file_system_detach_disk(8); resources_set_int("FileSystemDevice8", ATTACH_DEVICE_FS); lib_free(directory); lib_free(file); return 0; }
static int set_system_path(const char *val, void *param) { char *tmp_path, *tmp_path_save, *p, *s, *current_dir; util_string_set(&system_path, val); lib_free(expanded_system_path); expanded_system_path = NULL; /* will subsequently be replaced */ tmp_path_save = util_subst(system_path, "$$", default_path); /* malloc'd */ current_dir = ioutil_current_dir(); tmp_path = tmp_path_save; /* tmp_path points into tmp_path_save */ do { p = strstr(tmp_path, ARCHDEP_FINDPATH_SEPARATOR_STRING); if (p != NULL) { *p = 0; } if (!archdep_path_is_relative(tmp_path)) { /* absolute path */ if (expanded_system_path == NULL) { s = util_concat(tmp_path, NULL); /* concat allocs a new str. */ } else { s = util_concat(expanded_system_path, ARCHDEP_FINDPATH_SEPARATOR_STRING, tmp_path, NULL ); } } else { /* relative path */ if (expanded_system_path == NULL) { s = util_concat(current_dir, FSDEV_DIR_SEP_STR, tmp_path, NULL ); } else { s = util_concat(expanded_system_path, ARCHDEP_FINDPATH_SEPARATOR_STRING, current_dir, FSDEV_DIR_SEP_STR, tmp_path, NULL ); } } lib_free(expanded_system_path); expanded_system_path = s; tmp_path = p + strlen(ARCHDEP_FINDPATH_SEPARATOR_STRING); } while (p != NULL); lib_free(current_dir); lib_free(tmp_path_save); DBG(("set_system_path -> expanded_system_path:'%s'\n", expanded_system_path)); return 0; }
/* Autostart PRG file `file_name'. The PRG file can either be a raw CBM file or a P00 file, and the FS-based drive emulation is set up so that its directory becomes the current one on unit #8. */ int autostart_prg(const char *file_name, unsigned int runmode) { char *directory; char *file; fileio_info_t *finfo; if (network_connected()) return -1; finfo = fileio_open(file_name, NULL, FILEIO_FORMAT_RAW | FILEIO_FORMAT_P00, FILEIO_COMMAND_READ | FILEIO_COMMAND_FSNAME, FILEIO_TYPE_PRG); if (finfo == NULL) { log_error(autostart_log, "Cannot open `%s'.", file_name); return -1; } /* Extract the directory path to allow FS-based drive emulation to work. */ util_fname_split(file_name, &directory, &file); if (archdep_path_is_relative(directory)) { char *tmp; archdep_expand_path(&tmp, directory); lib_free(directory); directory = tmp; /* FIXME: We should actually eat `.'s and `..'s from `directory' instead. */ } /* Setup FS-based drive emulation. */ fsdevice_set_directory(directory ? directory : ".", 8); set_true_drive_emulation_mode(0); orig_drive_true_emulation_state =0; resources_set_int("VirtualDevices", 1); resources_set_int("FSDevice8ConvertP00", 1); file_system_detach_disk(8); ui_update_menus(); /* Now it's the same as autostarting a disk image. */ reboot_for_autostart((char *)(finfo->name), AUTOSTART_HASDISK, runmode); lib_free(directory); lib_free(file); fileio_close(finfo); log_message(autostart_log, "Preparing to load PRG file `%s'.", file_name); return 0; }
/** \brief Fall back: try to get absolute path to exec via argv[0] * * This is unreliable and should only be used as a last resort. * * \return bool (if this fails, we have to give up) */ static int argv_fallback(void) { char cwd_buf[4096]; char *result; size_t res_len; if (argv0_ref == NULL) { log_error(LOG_ERR, "argv[0] is NULL, giving up."); return 0; } if (*argv0_ref == '\0') { log_error(LOG_ERR, "argv[0] is empty, giving up."); return 0; } /* do we have an absolute path in argv[0]? */ if (!archdep_path_is_relative(argv0_ref)) { strcpy(buffer, argv0_ref); return 1; } /* * Relative path in argv[0], try to get cwd and join it with argv[0] */ memset(cwd_buf, 0, 4096); #if defined(ARCHDEP_OS_UNIX) || defined(ARCHDEP_OS_BEOS) if (getcwd(cwd_buf, 4096 - 1) == NULL) { log_error(LOG_ERR, "failed to get cwd, giving up."); return 0; } #elif defined(ARCHDEP_OS_WINDOWS) if (_getcwd(cwd_buf, 4096 -1) == NULL) { log_error(LOG_ERR, "failed to get cwd, giving up."); return 0; } #else log_error(LOG_ERR,"no getcwd() support for current OS, giving up."); return 0; #endif result = archdep_join_paths(cwd_buf, argv0_ref, NULL); res_len = strlen(result); if (res_len >= 4096) { /* insufficient space */ log_error(LOG_ERR, "insufficient space for path, giving up."); lib_free(result); return 0; } memcpy(buffer, result, res_len + 1); lib_free(result); return 1; }
int archdep_expand_path(char **return_path, const char *orig_name) { char tmp[FILENAME_MAX]; int len; if (archdep_path_is_relative(orig_name)) { getcwd(tmp, FILENAME_MAX); len = strlen(tmp); if (tmp[len - 1] == FSDEV_DIR_SEP_CHR) { *return_path = util_concat(tmp, orig_name, NULL); } else { *return_path = util_concat(tmp, FSDEV_DIR_SEP_STR, orig_name, NULL); } } else { *return_path = lib_stralloc(orig_name); } return 0; }
/* attach cartridge image type == -1 NONE type == 0 CRT format returns -1 on error, 0 on success */ int cartridge_attach_image(int type, const char *filename) { BYTE *rawcart; char *abs_filename; int carttype = CARTRIDGE_NONE; int cartid = CARTRIDGE_NONE; int oldmain = CARTRIDGE_NONE; int slotmain = 0; if (filename == NULL) { return -1; } /* Attaching no cartridge always works. */ if (type == CARTRIDGE_NONE || *filename == '\0') { return 0; } if (archdep_path_is_relative(filename)) { archdep_expand_path(&abs_filename, filename); } else { abs_filename = lib_stralloc(filename); } if (type == CARTRIDGE_CRT) { carttype = crt_getid(abs_filename); if (carttype == -1) { log_message(LOG_DEFAULT, "CART: '%s' is not a valid CRT file.", abs_filename); lib_free(abs_filename); return -1; } } else { carttype = type; } DBG(("CART: cartridge_attach_image type: %d ID: %d\n", type, carttype)); /* allocate temporary array */ rawcart = lib_malloc(C64CART_IMAGE_LIMIT); /* cart should always be detached. there is no reason for doing fancy checks here, and it will cause problems incase a cart MUST be detached before attaching another, or even itself. (eg for initialization reasons) most obvious reason: attaching a different ROM (software) for the same cartridge (hardware) */ slotmain = cart_is_slotmain(carttype); if (slotmain) { /* if the cart to be attached is in the "Main Slot", detach whatever cart currently is in the "Main Slot" */ oldmain = cart_getid_slotmain(); if (oldmain != CARTRIDGE_NONE) { DBG(("CART: detach slot main ID: %d\n", oldmain)); cartridge_detach_image(oldmain); } } if (oldmain != carttype) { DBG(("CART: detach %s ID: %d\n", slotmain ? "slot main" : "other slot", carttype)); cartridge_detach_image(carttype); } if (type == CARTRIDGE_CRT) { DBG(("CART: attach CRT ID: %d '%s'\n", carttype, filename)); cartid = crt_attach(abs_filename, rawcart); if (cartid == CARTRIDGE_NONE) { goto exiterror; } if (type < 0) { DBG(("CART: attach generic CRT ID: %d\n", type)); } } else { DBG(("CART: attach BIN ID: %d '%s'\n", carttype, filename)); cartid = carttype; if (cart_bin_attach(carttype, abs_filename, rawcart) < 0) { goto exiterror; } } if (cart_is_slotmain(cartid)) { DBG(("cartridge_attach MAIN ID: %d\n", cartid)); mem_cartridge_type = cartid; cart_romhbank_set_slotmain(0); cart_romlbank_set_slotmain(0); } else { DBG(("cartridge_attach (other) ID: %d\n", cartid)); } DBG(("CART: attach RAW ID: %d\n", cartid)); cart_attach(cartid, rawcart); cart_power_off(); if (cart_is_slotmain(cartid)) { /* "Main Slot" */ DBG(("CART: set main slot ID: %d type: %d\n", carttype, type)); c64cart_type = type; if (type == CARTRIDGE_CRT) { crttype = carttype; } util_string_set(&cartfile, abs_filename); } DBG(("CART: cartridge_attach_image type: %d ID: %d done.\n", type, carttype)); lib_free(rawcart); log_message(LOG_DEFAULT, "CART: attached '%s' as ID %d.", abs_filename, carttype); lib_free(abs_filename); return 0; exiterror: DBG(("CART: error\n")); lib_free(rawcart); log_message(LOG_DEFAULT, "CART: could not attach '%s'.", abs_filename); lib_free(abs_filename); return -1; }
char *findpath(const char *cmd, const char *syspath, int mode) { char *pd = NULL; char *c, *buf; size_t maxpathlen; maxpathlen = (size_t)ioutil_maxpathlen(); buf = lib_malloc(maxpathlen); buf[0] = '\0'; /* this will (and needs to) stay '\0' */ if (strchr(cmd, FSDEV_DIR_SEP_CHR)) { size_t l; int state; const char *ps; if (archdep_path_is_relative(cmd)) { if (ioutil_getcwd(buf + 1, (int)maxpathlen - 128) == NULL) goto fail; l = strlen(buf + 1); } else { l = 0; } if (l + strlen(cmd) >= maxpathlen - 5) goto fail; ps = cmd; pd = buf + l; /* buf + 1 + l - 1 */ #if !defined (__MSDOS__) && !defined (WIN32) && !defined (__OS2__) if (*pd++ != '/') *pd++ = '/'; #else pd++; #endif state = 1; /* delete extra `/./', '/../' and '//':s from the path */ while (*ps) { switch (state) { case 0: if (*ps == '/') state = 1; else state = 0; break; case 1: if (*ps == '.') { state = 2; break; } if (*ps == '/') pd--; else state = 0; break; case 2: if (*ps == '/') { state = 1; pd -= 2; break; } if (*ps == '.') state = 3; else state = 0; break; case 3: if (*ps != '/') { state = 0; break; } state = 1; pd -= 4; while (*pd != '/' && *pd != '\0') pd--; if (*pd == '\0') pd++; state = 1; break; } *pd++ = *ps++; } *pd = '\0'; pd = buf + 1; } else { const char *path = syspath; const char *s; size_t cl = strlen(cmd) + 1; for (s = path; s; path = s + 1) { char * p; int l; s = strchr(path, ARCHDEP_FINDPATH_SEPARATOR_CHAR); l = s ? (int)(s - path) : (int)strlen(path); if (l + cl > maxpathlen - 5) continue; memcpy(buf + 1, path, l); p = buf + l; /* buf + 1 + l - 1 */ if (*p++ != '/') *p++ = '/'; memcpy(p, cmd, cl); for (c = buf + 1; *c != '\0'; c++) #if defined (__MSDOS__) || defined (WIN32) || defined (__OS2__) if (*c == '/') *c = '\\'; #else if (*c == '\\') *c ='/'; #endif if (ioutil_access(buf + 1, mode) == 0) { pd = p /* + cl*/ ; break; } } } if (pd) { char *tmpbuf; #if 0 do pd--; while (*pd != '/'); /* there is at least one '/' */ if (*(pd - 1) == '\0') pd++; *pd = '\0'; #endif tmpbuf = lib_stralloc(buf + 1); lib_free(buf); return tmpbuf; } fail: lib_free(buf); return NULL; }