X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=libatalk%2Futil%2Fvolinfo.c;fp=libatalk%2Futil%2Fvolinfo.c;h=6dec61a0ccf4f817d91d9128be7629ea2469a6bf;hp=3e639f09ff28837bfcdc37d2d931315b27094658;hb=cc15ae44b2b11aa756c39b77ce995f8e52711343;hpb=b6817f5eaafb3f2859731c5434e4b4c4a12a980e diff --git a/libatalk/util/volinfo.c b/libatalk/util/volinfo.c index 3e639f09..6dec61a0 100644 --- a/libatalk/util/volinfo.c +++ b/libatalk/util/volinfo.c @@ -294,10 +294,9 @@ static int parseline ( char *buf, struct volinfo *vol) } break; case CNID_DBPATH: - if ((vol->v_dbpath = strdup(value)) == NULL) { - fprintf (stderr, "strdup: %s", strerror(errno)); - return -1; - } + if ((vol->v_dbpath = malloc(MAXPATHLEN+1)) == NULL) + return -1; + strcpy(vol->v_dbpath, value); break; case ADOUBLE_VER: if (strcasecmp(value, "v2") == 0) { @@ -340,7 +339,7 @@ int loadvolinfo (char *path, struct volinfo *vol) char volinfofile[MAXPATHLEN]; char buf[MAXPATHLEN]; struct flock lock; - int fd; + int fd, len; FILE *fp; if ( !path || !vol) @@ -354,9 +353,16 @@ int loadvolinfo (char *path, struct volinfo *vol) return -1; if ((vol->v_path = strdup(volinfofile)) == NULL ) { - fprintf (stderr, "strdup: %s", strerror(errno)); + fprintf (stderr, "strdup: %s", strerror(errno)); return (-1); } + /* Remove trailing slashes */ + len = strlen(vol->v_path); + while (len && (vol->v_path[len-1] == '/')) { + vol->v_path[len-1] = 0; + len--; + } + strlcat(volinfofile, ".AppleDesktop/", sizeof(volinfofile)); strlcat(volinfofile, VOLINFOFILE, sizeof(volinfofile)); @@ -399,10 +405,63 @@ int loadvolinfo (char *path, struct volinfo *vol) if ((vol->v_flags & AFPVOL_INV_DOTS)) vol->v_ad_options |= ADVOL_INVDOTS; + vol->retaincount = 1; + fclose(fp); return 0; } +/*! + * Allocate a struct volinfo object for refcounting usage with retain and close, and + * call loadvolinfo with it + */ +struct volinfo *allocvolinfo(char *path) +{ + struct volinfo *p = malloc(sizeof(struct volinfo)); + if (p == NULL) + return NULL; + + if (loadvolinfo(path, p) == -1) + return NULL; + + p->malloced = 1; + + return p; +} + +void retainvolinfo(struct volinfo *vol) +{ + vol->retaincount++; +} + +/*! + * Decrement retain count, free resources when retaincount reaches 0 + */ +int closevolinfo(struct volinfo *volinfo) +{ + if (volinfo->retaincount <= 0) + abort(); + + volinfo->retaincount--; + + if (volinfo->retaincount == 0) { + free(volinfo->v_name); volinfo->v_name = NULL; + free(volinfo->v_path); volinfo->v_path = NULL; + free(volinfo->v_cnidscheme); volinfo->v_cnidscheme = NULL; + free(volinfo->v_dbpath); volinfo->v_dbpath = NULL; + free(volinfo->v_volcodepage); volinfo->v_volcodepage = NULL; + free(volinfo->v_maccodepage); volinfo->v_maccodepage = NULL; + free(volinfo->v_dbd_host); volinfo->v_dbd_host = NULL; + free(volinfo->v_dbd_port); volinfo->v_dbd_port = NULL; + if (volinfo->malloced) { + volinfo->malloced = 0; + free(volinfo); + } + } + + return 0; +} + /* * Save the volume options to a file, used by shell utilities. Writing the file * everytime a volume is opened is unnecessary, but it shouldn't hurt much.