]> git.draconx.ca Git - upkg.git/blobdiff - src/libupkg.c
upkg: Add support for controlling which package is acted upon.
[upkg.git] / src / libupkg.c
index ae488209cf1142d350b69990899aed6e87359585..40b39136f4c3164f22732a73e33adba2b1fae65e 100644 (file)
@@ -45,6 +45,7 @@ struct upkg_import {
 
 struct upkg_private {
        const struct upkg_file_ops *fops;
+       int (*dtor)(void *handle);
        void *f;
 
        struct upkg_file *last_file;
@@ -60,22 +61,27 @@ struct upkg_private {
 /* Default I/O operations for ordinary files. */
 static size_t file_read(void *buf, size_t size, void *handle)
 {
-       return fread(buf, 1, size, handle);
+       return fread(buf, 1, size, (FILE *)handle);
 }
 
 static int file_seek(void *handle, long offset, int whence)
 {
-       return fseek(handle, offset, whence);
+       return fseek((FILE *)handle, offset, whence);
 }
 
 static long file_tell(void *handle)
 {
-       return ftell(handle);
+       return ftell((FILE *)handle);
 }
 
 static int file_eof(void *handle)
 {
-       return feof(handle);
+       return feof((FILE *)handle);
+}
+
+static int file_close(void *handle)
+{
+       return fclose((FILE *)handle);
 }
 
 const struct upkg_file_ops upkg_default_fops = {
@@ -351,12 +357,12 @@ static int pkg_init_imports(struct upkg *pkg)
 
                len = 0;
                rc = upkg_decode_index(&tmp, buf+len, nbuf-len);
-               if (rc == 0 || len < 0 || len >= pkg->name_count) goto err;
+               if (rc == 0 || len >= pkg->name_count) goto err;
                import->class_package = pkg->priv->names[tmp].name;
                len += rc;
 
                rc = upkg_decode_index(&tmp, buf+len, nbuf-len);
-               if (rc == 0 || len < 0 || len >= pkg->name_count) goto err;
+               if (rc == 0 || len >= pkg->name_count) goto err;
                import->class_name = pkg->priv->names[tmp].name;
                len += rc;
 
@@ -365,7 +371,7 @@ static int pkg_init_imports(struct upkg *pkg)
                len += 4;
 
                rc = upkg_decode_index(&tmp, buf+len, nbuf-len);
-               if (rc == 0 || len < 0 || len >= pkg->name_count) goto err;
+               if (rc == 0 || len >= pkg->name_count) goto err;
                import->object_name = pkg->priv->names[tmp].name;
                len += rc;
 
@@ -380,7 +386,8 @@ err:
        return -1;
 }
 
-struct upkg *upkg_open(void *f, const struct upkg_file_ops *fops)
+struct upkg *upkg_open(void *f, const struct upkg_file_ops *fops,
+                       int (*destructor)(void *handle))
 {
        unsigned char hdr_buf[UPKG_HDR_SIZE];
        struct upkg *pkg;
@@ -398,6 +405,7 @@ struct upkg *upkg_open(void *f, const struct upkg_file_ops *fops)
                return NULL;
        }
        pkg->priv->fops = fops;
+       pkg->priv->dtor = destructor;
        pkg->priv->f    = f;
 
        if (pkg_init_guid(pkg) != 0) {
@@ -438,7 +446,7 @@ struct upkg *upkg_fopen(const char *path)
                return NULL;
        }
 
-       pkg = upkg_open(f, &upkg_default_fops);
+       pkg = upkg_open(f, &upkg_default_fops, file_close);
        if (!pkg) {
                fclose(f);
        }
@@ -450,12 +458,12 @@ int upkg_close(struct upkg *pkg)
 {
        int rc = 0;
 
-       if (pkg->priv->f) {
-               rc = fclose(pkg->priv->f);
+       if (pkg->priv->dtor) {
+               rc = pkg->priv->dtor(pkg->priv->f);
+       }
 
-               for (unsigned i = 0; i < pkg->name_count; i++) {
-                       free(pkg->priv->names[i].name);
-               }
+       for (unsigned i = 0; i < pkg->name_count; i++) {
+               free(pkg->priv->names[i].name);
        }
 
        free(pkg->priv->imports);