int disc_cache_bdrom_file(BD_DISC *p, const char *rel_path, const char *cache_path) { BD_FILE_H *fp_in; BD_FILE_H *fp_out; int64_t got; size_t size; if (!cache_path || !cache_path[0]) { return -1; } /* make sure cache directory exists */ if (file_mkdirs(cache_path) < 0) { return -1; } /* plain directory ? */ size = strlen(rel_path); if (rel_path[size - 1] == '/' || rel_path[size - 1] == '\\') { return 0; } /* input file from BD-ROM */ fp_in = p->pf_file_open_bdrom(p->fs_handle, rel_path); if (!fp_in) { BD_DEBUG(DBG_FILE | DBG_CRIT, "error caching file %s (does not exist ?)\n", rel_path); return -1; } /* output file in local filesystem */ fp_out = file_open(cache_path, "wb"); if (!fp_out) { BD_DEBUG(DBG_FILE | DBG_CRIT, "error creating cache file %s\n", cache_path); file_close(fp_in); return -1; } do { uint8_t buf[16*2048]; got = file_read(fp_in, buf, sizeof(buf)); /* we'll call write(fp, buf, 0) after EOF. It is used to check for errors. */ if (got < 0 || fp_out->write(fp_out, buf, got) != got) { BD_DEBUG(DBG_FILE | DBG_CRIT, "error caching file %s\n", rel_path); file_close(fp_out); file_close(fp_in); (void)file_unlink(cache_path); return -1; } } while (got > 0); BD_DEBUG(DBG_FILE, "cached %s to %s\n", rel_path, cache_path); file_close(fp_out); file_close(fp_in); return 0; }
int make_link_file (const char *linkpath, uuid_t uuid) { char *p; char uuidbuf[30]; struct stat st; char upbuf[12], lobuf[12]; uint64_t upper, lower; upper = arrow_bytes_to_long (uuid); lower = arrow_bytes_to_long (uuid + 8); b64_encode (upper, upbuf); b64_encode (lower, lobuf); snprintf (uuidbuf, sizeof (uuidbuf), "%02x/%s.%s", uuid[0], upbuf, lobuf); if (lstat (linkpath, &st) == 0) { if ((st.st_mode & S_IFLNK) == 0) { errno = EEXIST; return -1; } if (unlink (linkpath) != 0) return -1; } p = strrchr (linkpath, '/'); *p = '\0'; /* fprintf (stderr, "%s: file_mkdirs %s\n", __FUNCTION__, linkpath); */ int ret; if ((ret = file_mkdirs (linkpath, 0700)) != 0) { /* fprintf (stderr, "file_mkdirs: %s (returned %d)\n", strerror (errno), ret); */ return -1; } *p = '/'; /* fprintf (stderr, "%s: symlink %s -> %s\n", __FUNCTION__, uuidbuf, linkpath); */ if (symlink (uuidbuf, linkpath) != 0) return -1; return 0; }
int file_mkdirs (const char *path, int mode) { char dir[1024]; char *p; if (file_isdir (path)) return 0; if (file_isfile (path)) { errno = EEXIST; return -1; } file_dirname (path, dir, sizeof (dir)); if (strcmp (dir, ".") != 0) file_mkdirs (dir, mode); if (mkdir (path, mode) != 0) return -1; return 0; }