- struct stat st;
- u_int16_t attr;
- char *buf;
- int fd, off;
- int ret = -1;
- /* use resource fork offset from file */
- int shiftdata;
- int toV2;
- int toV1;
-
- if (!path) {
- return 0;
- }
-
- if (!(ad->ad_md->adf_flags & ( O_RDWR))) {
- /* we were unable to open the file read write the last time */
- return 0;
- }
-
- /* check to see if we should convert this header. */
- toV2 = ad->ad_version == AD_VERSION1 && ad->ad_flags == AD_VERSION2;
- toV1 = ad->ad_version == AD_VERSION2 && ad->ad_flags == AD_VERSION1;
-
- if (!toV2 && !toV1)
- return 0;
-
- /* convert from v1 to v2. what does this mean?
- * 1) change FILEI into FILEDATESI
- * 2) create space for SHORTNAME, AFPFILEI, DID, and PRODOSI
- * 3) move FILEI attributes into AFPFILEI
- * 4) initialize ACCESS field of FILEDATESI.
- * 5) move the resource fork
- */
-
- /* bail if we can't get a lock */
- if (ad_tmplock(ad, ADEID_RFORK, ADLOCK_WR, 0, 0, 0) < 0)
- goto bail_err;
-
- /* we reuse fd from the resource fork */
- fd = ad->ad_md->adf_fd;
-
- if (ad->ad_eid[ADEID_RFORK].ade_off) {
- shiftdata = ADEDOFF_RFORK_V2 -ad->ad_eid[ADEID_RFORK].ade_off;
- }
- else {
- shiftdata = ADEDOFF_RFORK_V2 -ADEDOFF_RFORK_V1; /* 136 */
- }
-
- if (fstat(fd, &st)) {
- goto bail_lock;
- }
-
- if (st.st_size > 0x7fffffff -shiftdata) {
- LOG(log_debug, logtype_default, "ad_v1tov2: file too big.");
- errno = EIO;
- goto bail_lock;
- }
-
- off = ad->ad_eid[ADEID_RFORK].ade_off;
-
- if (off > st.st_size) {
- LOG(log_error, logtype_default, "ad_v1tov2: invalid resource fork offset. (off: %u)", off);
- errno = EIO;
- goto bail_lock;
- }
-
- if (ad->ad_eid[ADEID_RFORK].ade_len > st.st_size - off) {
- LOG(log_error, logtype_default, "ad_v1tov2: invalid resource fork length. (rfork len: %u)", ad->ad_eid[ADEID_RFORK].ade_len);
- errno = EIO;
- goto bail_lock;
- }
-
- if ((void *) (buf = (char *)
- mmap(NULL, st.st_size + shiftdata,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) ==
- MAP_FAILED) {
- goto bail_lock;
- }
-
- /* last place for failure. */
-
- if (sys_ftruncate(fd, st.st_size + shiftdata) < 0) {
- goto bail_lock;
- }
-
- /* move the RFORK. this assumes that the RFORK is at the end */
- if (off) {
- memmove(buf + ADEDOFF_RFORK_V2, buf + off, ad->ad_eid[ADEID_RFORK].ade_len);
- }
-
- munmap(buf, st.st_size + shiftdata);
-
- /* now, fix up our copy of the header */
- memset(ad->ad_filler, 0, sizeof(ad->ad_filler));
-
- /* replace FILEI with FILEDATESI */
- ad_getattr(ad, &attr);
- ad->ad_eid[ADEID_FILEDATESI].ade_off = ADEDOFF_FILEDATESI;
- ad->ad_eid[ADEID_FILEDATESI].ade_len = ADEDLEN_FILEDATESI;
- ad->ad_eid[ADEID_FILEI].ade_off = 0;
- ad->ad_eid[ADEID_FILEI].ade_len = 0;
-
- /* add in the new entries */
- ad->ad_eid[ADEID_DID].ade_off = ADEDOFF_DID;
- ad->ad_eid[ADEID_DID].ade_len = ADEDLEN_DID;
- ad->ad_eid[ADEID_AFPFILEI].ade_off = ADEDOFF_AFPFILEI;
- ad->ad_eid[ADEID_AFPFILEI].ade_len = ADEDLEN_AFPFILEI;
- ad->ad_eid[ADEID_SHORTNAME].ade_off = ADEDOFF_SHORTNAME;
- ad->ad_eid[ADEID_SHORTNAME].ade_len = ADEDLEN_INIT;
- ad->ad_eid[ADEID_PRODOSFILEI].ade_off = ADEDOFF_PRODOSFILEI;
- ad->ad_eid[ADEID_PRODOSFILEI].ade_len = ADEDLEN_PRODOSFILEI;
-
- ad->ad_eid[ADEID_PRIVDEV].ade_off = ADEDOFF_PRIVDEV;
- ad->ad_eid[ADEID_PRIVDEV].ade_len = ADEDLEN_INIT;
- ad->ad_eid[ADEID_PRIVINO].ade_off = ADEDOFF_PRIVINO;
- ad->ad_eid[ADEID_PRIVINO].ade_len = ADEDLEN_INIT;
- ad->ad_eid[ADEID_PRIVSYN].ade_off = ADEDOFF_PRIVSYN;
- ad->ad_eid[ADEID_PRIVSYN].ade_len = ADEDLEN_INIT;
- ad->ad_eid[ADEID_PRIVID].ade_off = ADEDOFF_PRIVID;
- ad->ad_eid[ADEID_PRIVID].ade_len = ADEDLEN_INIT;
-
- /* shift the old entries (NAME, COMMENT, FINDERI, RFORK) */
- ad->ad_eid[ADEID_NAME].ade_off = ADEDOFF_NAME_V2;
- ad->ad_eid[ADEID_COMMENT].ade_off = ADEDOFF_COMMENT_V2;
- ad->ad_eid[ADEID_FINDERI].ade_off = ADEDOFF_FINDERI_V2;
- ad->ad_eid[ADEID_RFORK].ade_off = ADEDOFF_RFORK_V2;
-
- /* switch to dest version */
- ad->ad_version = (toV2)?AD_VERSION2:AD_VERSION1;
-
- /* move our data buffer to make space for the new entries. */
- memmove(ad->ad_data + ADEDOFF_NAME_V2, ad->ad_data + ADEDOFF_NAME_V1,
- ADEDOFF_RFORK_V1 - ADEDOFF_NAME_V1);
-
- /* now, fill in the space with appropriate stuff. we're
- operating as a v2 file now. */
- ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
- memset(ad_entry(ad, ADEID_DID), 0, ADEDLEN_DID);
- memset(ad_entry(ad, ADEID_AFPFILEI), 0, ADEDLEN_AFPFILEI);
- ad_setattr(ad, attr);
- memset(ad_entry(ad, ADEID_SHORTNAME), 0, ADEDLEN_SHORTNAME);
- memset(ad_entry(ad, ADEID_PRODOSFILEI), 0, ADEDLEN_PRODOSFILEI);
-
- /* rebuild the header and cleanup */
- ad_flush(ad );
- ret = 0;
-
+ struct stat st;
+ u_int16_t attr;
+ char *buf;
+ int fd, off;
+ int ret = -1;
+ /* use resource fork offset from file */
+ int shiftdata;
+ int toV2;
+ int toV1;
+
+ if (!path) {
+ return 0;
+ }
+
+ if (!(ad->ad_md->adf_flags & ( O_RDWR))) {
+ /* we were unable to open the file read write the last time */
+ return 0;
+ }
+
+ /* check to see if we should convert this header. */
+ toV2 = ad->ad_version == AD_VERSION1 && ad->ad_flags == AD_VERSION2;
+ toV1 = ad->ad_version == AD_VERSION2 && ad->ad_flags == AD_VERSION1;
+
+ if (!toV2 && !toV1)
+ return 0;
+
+ /* convert from v1 to v2. what does this mean?
+ * 1) change FILEI into FILEDATESI
+ * 2) create space for SHORTNAME, AFPFILEI, DID, and PRODOSI
+ * 3) move FILEI attributes into AFPFILEI
+ * 4) initialize ACCESS field of FILEDATESI.
+ * 5) move the resource fork
+ */
+
+ /* bail if we can't get a lock */
+ if (ad_tmplock(ad, ADEID_RFORK, ADLOCK_WR, 0, 0, 0) < 0)
+ goto bail_err;
+
+ /* we reuse fd from the resource fork */
+ fd = ad->ad_md->adf_fd;
+
+ if (ad->ad_eid[ADEID_RFORK].ade_off) {
+ shiftdata = ADEDOFF_RFORK_V2 -ad->ad_eid[ADEID_RFORK].ade_off;
+ }
+ else {
+ shiftdata = ADEDOFF_RFORK_V2 -ADEDOFF_RFORK_V1; /* 136 */
+ }
+
+ if (fstat(fd, &st)) {
+ goto bail_lock;
+ }
+
+ if (st.st_size > 0x7fffffff -shiftdata) {
+ LOG(log_debug, logtype_default, "ad_v1tov2: file too big.");
+ errno = EIO;
+ goto bail_lock;
+ }
+
+ off = ad->ad_eid[ADEID_RFORK].ade_off;
+
+ if (off > st.st_size) {
+ LOG(log_error, logtype_default, "ad_v1tov2: invalid resource fork offset. (off: %u)", off);
+ errno = EIO;
+ goto bail_lock;
+ }
+
+ if (ad->ad_eid[ADEID_RFORK].ade_len > st.st_size - off) {
+ LOG(log_error, logtype_default, "ad_v1tov2: invalid resource fork length. (rfork len: %u)", ad->ad_eid[ADEID_RFORK].ade_len);
+ errno = EIO;
+ goto bail_lock;
+ }
+
+ if ((void *) (buf = (char *)
+ mmap(NULL, st.st_size + shiftdata,
+ PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) ==
+ MAP_FAILED) {
+ goto bail_lock;
+ }
+
+ /* last place for failure. */
+
+ if (sys_ftruncate(fd, st.st_size + shiftdata) < 0) {
+ goto bail_lock;
+ }
+
+ /* move the RFORK. this assumes that the RFORK is at the end */
+ if (off) {
+ memmove(buf + ADEDOFF_RFORK_V2, buf + off, ad->ad_eid[ADEID_RFORK].ade_len);
+ }
+
+ munmap(buf, st.st_size + shiftdata);
+
+ /* now, fix up our copy of the header */
+ memset(ad->ad_filler, 0, sizeof(ad->ad_filler));
+
+ /* replace FILEI with FILEDATESI */
+ ad_getattr(ad, &attr);
+ ad->ad_eid[ADEID_FILEDATESI].ade_off = ADEDOFF_FILEDATESI;
+ ad->ad_eid[ADEID_FILEDATESI].ade_len = ADEDLEN_FILEDATESI;
+ ad->ad_eid[ADEID_FILEI].ade_off = 0;
+ ad->ad_eid[ADEID_FILEI].ade_len = 0;
+
+ /* add in the new entries */
+ ad->ad_eid[ADEID_DID].ade_off = ADEDOFF_DID;
+ ad->ad_eid[ADEID_DID].ade_len = ADEDLEN_DID;
+ ad->ad_eid[ADEID_AFPFILEI].ade_off = ADEDOFF_AFPFILEI;
+ ad->ad_eid[ADEID_AFPFILEI].ade_len = ADEDLEN_AFPFILEI;
+ ad->ad_eid[ADEID_SHORTNAME].ade_off = ADEDOFF_SHORTNAME;
+ ad->ad_eid[ADEID_SHORTNAME].ade_len = ADEDLEN_INIT;
+ ad->ad_eid[ADEID_PRODOSFILEI].ade_off = ADEDOFF_PRODOSFILEI;
+ ad->ad_eid[ADEID_PRODOSFILEI].ade_len = ADEDLEN_PRODOSFILEI;
+
+ ad->ad_eid[ADEID_PRIVDEV].ade_off = ADEDOFF_PRIVDEV;
+ ad->ad_eid[ADEID_PRIVDEV].ade_len = ADEDLEN_INIT;
+ ad->ad_eid[ADEID_PRIVINO].ade_off = ADEDOFF_PRIVINO;
+ ad->ad_eid[ADEID_PRIVINO].ade_len = ADEDLEN_INIT;
+ ad->ad_eid[ADEID_PRIVSYN].ade_off = ADEDOFF_PRIVSYN;
+ ad->ad_eid[ADEID_PRIVSYN].ade_len = ADEDLEN_INIT;
+ ad->ad_eid[ADEID_PRIVID].ade_off = ADEDOFF_PRIVID;
+ ad->ad_eid[ADEID_PRIVID].ade_len = ADEDLEN_INIT;
+
+ /* shift the old entries (NAME, COMMENT, FINDERI, RFORK) */
+ ad->ad_eid[ADEID_NAME].ade_off = ADEDOFF_NAME_V2;
+ ad->ad_eid[ADEID_COMMENT].ade_off = ADEDOFF_COMMENT_V2;
+ ad->ad_eid[ADEID_FINDERI].ade_off = ADEDOFF_FINDERI_V2;
+ ad->ad_eid[ADEID_RFORK].ade_off = ADEDOFF_RFORK_V2;
+
+ /* switch to dest version */
+ ad->ad_version = (toV2)?AD_VERSION2:AD_VERSION1;
+
+ /* move our data buffer to make space for the new entries. */
+ memmove(ad->ad_data + ADEDOFF_NAME_V2, ad->ad_data + ADEDOFF_NAME_V1,
+ ADEDOFF_RFORK_V1 - ADEDOFF_NAME_V1);
+
+ /* now, fill in the space with appropriate stuff. we're
+ operating as a v2 file now. */
+ ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
+ memset(ad_entry(ad, ADEID_DID), 0, ADEDLEN_DID);
+ memset(ad_entry(ad, ADEID_AFPFILEI), 0, ADEDLEN_AFPFILEI);
+ ad_setattr(ad, attr);
+ memset(ad_entry(ad, ADEID_SHORTNAME), 0, ADEDLEN_SHORTNAME);
+ memset(ad_entry(ad, ADEID_PRODOSFILEI), 0, ADEDLEN_PRODOSFILEI);
+
+ /* rebuild the header and cleanup */
+ ad_flush(ad );
+ ret = 0;
+