5 #include "assman_impl.h"
7 static int add_fop(const char *prefix, int type, struct ass_fileops *fop);
8 static const char *match_prefix(const char *str, const char *prefix);
10 #define DEF_FLAGS (1 << ASS_OPEN_FALLTHROUGH)
12 static unsigned int assflags = DEF_FLAGS;
13 static struct mount *mlist;
15 void ass_set_option(int opt, int val)
20 assflags &= ~(1 << opt);
24 int ass_get_option(int opt)
26 return assflags & (1 << opt);
29 int ass_add_path(const char *prefix, const char *path)
31 return add_fop(prefix, MOD_PATH, ass_alloc_path(path));
34 int ass_add_archive(const char *prefix, const char *arfile)
36 return add_fop(prefix, MOD_ARCHIVE, ass_alloc_archive(arfile));
39 int ass_add_url(const char *prefix, const char *url)
41 return add_fop(prefix, MOD_URL, ass_alloc_url(url));
44 int ass_add_user(const char *prefix, struct ass_fileops *fop)
46 return add_fop(prefix, MOD_USER, fop);
49 static int add_fop(const char *prefix, int type, struct ass_fileops *fop)
54 fprintf(stderr, "assman: failed to allocate asset source\n");
58 if(!(m = malloc(sizeof *m))) {
59 perror("assman: failed to allocate mount node");
63 if(!(m->prefix = malloc(strlen(prefix) + 1))) {
67 strcpy(m->prefix, prefix);
82 struct mount *m = mlist;
87 ass_free_path(m->fop);
90 ass_free_archive(m->fop);
104 ass_file *ass_fopen(const char *fname, const char *mode)
110 const char *after_prefix;
114 if((after_prefix = match_prefix(fname, m->prefix))) {
115 if((mfile = m->fop->open(after_prefix, m->fop->udata))) {
116 if(!(file = malloc(sizeof *file))) {
117 perror("assman: ass_fopen failed to allocate file structure");
118 m->fop->close(mfile, m->fop->udata);
125 if(!(assflags & (1 << ASS_OPEN_FALLTHROUGH))) {
133 /* nothing matched, or failed to open, try the filesystem */
134 if((fp = fopen(fname, mode))) {
135 if(!(file = malloc(sizeof *file))) {
137 perror("assman: ass_fopen failed to allocate file structure");
149 static const char *match_prefix(const char *str, const char *prefix)
151 if(!prefix || !*prefix) return str; /* match on null or empty prefix */
154 if(*prefix++ != *str++) {
161 void ass_fclose(ass_file *fp)
164 fp->fop->close(fp->file, fp->fop->udata);
171 long ass_fseek(ass_file *fp, long offs, int whence)
174 return fp->fop->seek(fp->file, offs, whence, fp->fop->udata);
177 if(fseek(fp->file, offs, whence) == -1) {
180 return ftell(fp->file);
183 long ass_ftell(ass_file *fp)
185 return ass_fseek(fp, 0, SEEK_CUR);
188 size_t ass_fread(void *buf, size_t size, size_t count, ass_file *fp)
191 long res = fp->fop->read(fp->file, buf, size * count, fp->fop->udata);
192 if(res <= 0) return 0;
196 return fread(buf, size, count, fp->file);
200 /* --- convenience functions --- */
202 int ass_fgetc(ass_file *fp)
206 if(ass_fread(&c, 1, 1, fp) < 1) {
212 char *ass_fgets(char *s, int size, ass_file *fp)
219 for(i=0; i<size - 1; i++) {
220 if((c = ass_fgetc(fp)) == -1) {
228 return ptr == s ? 0 : s;