Ejemplo n.º 1
0
Archivo: hfs.c Proyecto: asvitkine/phxd
size_t
comment_len (const char *path)
{
   char infopath[MAXPATHLEN];
   int f, i, r, len = 0;
   struct stat sb;
   union {
      struct hfs_cap_info cap;
      struct hfs_dbl_hdr dbl;
   } hdr;

   if (!finderinfo_path(infopath, path, &sb)) {
      f = open(infopath, O_RDONLY);
      if (f >= 0) {
         switch (cfg.fork) {
            case HFS_FORK_CAP:
               if (read(f, &hdr.cap, SIZEOF_HFS_CAP_INFO) == SIZEOF_HFS_CAP_INFO)
                  len = hdr.cap.fi_comln > 200 ? 200 : hdr.cap.fi_comln;
               break;
            case HFS_FORK_NETATALK:
            case HFS_FORK_DOUBLE:
               r = read(f, &hdr.dbl, SIZEOF_HFS_DBL_HDR);
               if (r != SIZEOF_HFS_DBL_HDR)
                  break;
               if (ntohs(hdr.dbl.entries) > HFS_HDR_MAX)
                  hdr.dbl.entries = htons(HFS_HDR_MAX);
               r = read(f, &hdr.dbl.descrs, SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries));
               if (r != SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries))
                  break;
               for (i = 0; i < ntohs(hdr.dbl.entries); i++) {
                  struct hfs_hdr_descr *descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * i]);
                  if (ntohl(descr->id) == HFS_HDR_COMNT)
                     len = ntohl(descr->length) > 200 ? 200 : ntohl(descr->length);
               }
               break;
         }
         close(f);
      }
   }
   if (!stat(path, &sb) && !S_ISDIR(sb.st_mode)) {
      if (!len && cfg.comment) {
         len = strlen(cfg.comment);
         if (len > 200)
            len = 200;
      }
   } else {
      if (!len && cfg.dir_comment) {
         len = strlen(cfg.dir_comment);
         if (len > 200)
            len = 200;
      }
   }

   return len;
}
Ejemplo n.º 2
0
Archivo: hfs.c Proyecto: asvitkine/phxd
size_t
resource_len (const char *path)
{
   size_t len = 0;

   if (cfg.fork == HFS_FORK_CAP) {
      char rsrcpath[MAXPATHLEN];
      struct stat sb;

      if (!resource_path(rsrcpath, path, &sb))
         len = sb.st_size;
   } else { /* AppleDouble */
      char infopath[MAXPATHLEN];
      struct hfs_dbl_hdr dbl;
      struct stat sb;
      ssize_t r;
      u_int16_t i;
      int f;

      if (!finderinfo_path(infopath, path, &sb)) {
         f = open(infopath, O_RDONLY);
         if (f < 0)
            return 0;
         r = read(f, &dbl, SIZEOF_HFS_DBL_HDR);
         if (r != SIZEOF_HFS_DBL_HDR)
            goto funkdat;
         if (ntohs(dbl.entries) > HFS_HDR_MAX)
            dbl.entries = htons(HFS_HDR_MAX);
         r = read(f, &dbl.descrs, SIZEOF_HFS_HDR_DESCR * ntohs(dbl.entries));
         if (r != SIZEOF_HFS_HDR_DESCR * ntohs(dbl.entries))
            goto funkdat;
         for (i = 0; i < ntohs(dbl.entries); i++) {
            struct hfs_hdr_descr *descr = (struct hfs_hdr_descr *)(&dbl.descrs[SIZEOF_HFS_HDR_DESCR * i]);
            if (ntohl(descr->id) == HFS_HDR_RSRC) {
               len = ntohl(descr->length);
               break;
            }
         }
funkdat:
         close(f);
      }
   }

   return len;
}
Ejemplo n.º 3
0
Archivo: hfs.c Proyecto: asvitkine/phxd
int
resource_open (const char *path, int mode, int perm)
{
   if (cfg.fork == HFS_FORK_CAP) {
      char rsrcpath[MAXPATHLEN];

      if (resource_path(rsrcpath, path, 0))
         return -1;
      return open(rsrcpath, mode, perm);
   } else { /* AppleDouble */
      char infopath[MAXPATHLEN];
      struct hfs_dbl_hdr dbl;
      struct stat sb;
      ssize_t r;
      u_int16_t i;
      int f;

      if (!finderinfo_path(infopath, path, &sb)) {
         f = open(infopath, mode);
         if (f < 0)
            return 0;
         r = read(f, &dbl, SIZEOF_HFS_DBL_HDR);
         if (r != SIZEOF_HFS_DBL_HDR)
            goto funkdat;
         if (ntohs(dbl.entries) > HFS_HDR_MAX)
            dbl.entries = htons(HFS_HDR_MAX);
         r = read(f, &dbl.descrs, SIZEOF_HFS_HDR_DESCR * ntohs(dbl.entries));
         if (r != SIZEOF_HFS_HDR_DESCR * ntohs(dbl.entries))
            goto funkdat;
         for (i = 0; i < ntohs(dbl.entries); i++) {
            struct hfs_hdr_descr *descr = (struct hfs_hdr_descr *)(&dbl.descrs[SIZEOF_HFS_HDR_DESCR * i]);
            if (ntohl(descr->id) == HFS_HDR_RSRC) {
               if (lseek(f, ntohl(descr->offset), SEEK_SET) != (off_t)ntohl(descr->offset))
                  goto funkdat;
               return f;
            }
         }
funkdat:
         close(f);
         return -1;
      }
   }

   return -1;
}
Ejemplo n.º 4
0
Archivo: files.c Proyecto: Schala/mhxd
void
rcv_file_delete (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0;
	char dir[MAXPATHLEN], filename[NAME_MAX], oldbuf[MAXPATHLEN];
	char rsrcpath_old[MAXPATHLEN];
	struct stat sb, rsb;
	int err;

	dir[0] = 0;

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
		}
	dh_end()

	if (!fnlen && !dir[0]) {
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}

	if (dir[0]) {
		if (fnlen)
			snprintf(oldbuf, sizeof(oldbuf), "%s/%s", dir, filename);
		else
			strcpy(oldbuf, dir);
	} else {
		snprintf(oldbuf, sizeof(oldbuf), "%s/%s", ROOTDIR, filename);
	}
	if (check_dropbox(htlc, oldbuf)) {
		snd_strerror(htlc, EPERM);
		return;
	}

	if (log_delete)
		hxd_log("%s:%s:%u - delete %s", htlc->name, htlc->login, htlc->uid, oldbuf);

	if (SYS_lstat(oldbuf, &sb)) {
		snd_strerror(htlc, errno);
		return;
	}

#if defined(CONFIG_HFS)
	if (!hxd_cfg.operation.hfs)
		goto skiphfs;
	if (hxd_cfg.files.fork == HFS_FORK_CAP) {
		if (!S_ISDIR(sb.st_mode) && !resource_path(rsrcpath_old, oldbuf, &rsb)
		    && !S_ISDIR(rsb.st_mode)) {
			if (unlink(rsrcpath_old)) {
				snd_strerror(htlc, errno);
				return;
			}
		}
	}
	if (!finderinfo_path(rsrcpath_old, oldbuf, &rsb)) {
		if (unlink(rsrcpath_old)) {
			snd_strerror(htlc, errno);
			return;
		}
	}
skiphfs:
#endif /* CONFIG_HFS */

	if (S_ISDIR(sb.st_mode) && !S_ISLNK(sb.st_mode))
		err = recursive_rmdir(oldbuf);
	else
		err = unlink(oldbuf);

	if (err)
		snd_strerror(htlc, errno);
	else
		hlwrite(htlc, HTLS_HDR_TASK, 0, 0);
}
Ejemplo n.º 5
0
Archivo: files.c Proyecto: Schala/mhxd
void
rcv_file_symlink (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0, newfnlen = 0;
	char dir[MAXPATHLEN], newdir[MAXPATHLEN],
	     filename[NAME_MAX], newfilename[NAME_MAX], oldbuf[MAXPATHLEN], newbuf[MAXPATHLEN];
	char rsrcpath_old[MAXPATHLEN], rsrcpath_new[MAXPATHLEN];
	struct stat rsb;
	int err;

	dir[0] = newdir[0] = 0;

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_FILE_RENAME:
				newfnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(newfilename, dh_data, newfnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
			case HTLC_DATA_DIR_RENAME:
				if ((err = hldir_to_path(dh, ROOTDIR, newdir, newdir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
		}
	dh_end()

	if ((!dir[0] && !fnlen) || !newdir[0]) {
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}
	if (!dir[0])
		strcpy(dir, ROOTDIR);
	if (fnlen) {
		snprintf(oldbuf, sizeof(oldbuf), "%s/%s", dir, filename);
		snprintf(newbuf, sizeof(newbuf), "%s/%s", newdir, newfnlen ? newfilename : filename);
	} else {
		strcpy(oldbuf, dir);
		strcpy(newbuf, newdir);
	}
	if (check_dropbox(htlc, oldbuf)) {
		snd_strerror(htlc, EPERM);
		return;
	}

	if (log_symlink)
		hxd_log("%s:%s:%u - symlink %s to %s", htlc->name, htlc->login, htlc->uid, newbuf, oldbuf);

	if (sys_symlink(oldbuf, newbuf))
		snd_strerror(htlc, errno);
	else
		hlwrite(htlc, HTLS_HDR_TASK, 0, 0);
#if defined(CONFIG_HFS)
	if (!hxd_cfg.operation.hfs)
		return;

	if (hxd_cfg.files.fork == HFS_FORK_CAP) {
		if (!resource_path(rsrcpath_old, oldbuf, &rsb)) {
			if ((err = resource_path(rsrcpath_new, newbuf, 0))) {
				/* (void)unlink(newbuf); */
				snd_strerror(htlc, err);
				return;
			} else {
				if (sys_symlink(rsrcpath_old, rsrcpath_new)) {
					/* (void)unlink(newbuf); */
					snd_strerror(htlc, errno);
					return;
				}
			}
		}
	}
	if (!finderinfo_path(rsrcpath_old, oldbuf, &rsb)) {
		if ((err = finderinfo_path(rsrcpath_new, newbuf, 0))) {
			/* (void)unlink(newbuf); */
			snd_strerror(htlc, err);
			return;
		} else {
			if (sys_symlink(rsrcpath_old, rsrcpath_new)) {
				/* (void)unlink(newbuf); */
				snd_strerror(htlc, errno);
				return;
			}
		}
	}
#endif /* CONFIG_HFS */
}
Ejemplo n.º 6
0
Archivo: files.c Proyecto: Schala/mhxd
void
rcv_file_move (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0;
	char dir[MAXPATHLEN], newdir[MAXPATHLEN],
	     filename[NAME_MAX], oldbuf[MAXPATHLEN], newbuf[MAXPATHLEN];
	char rsrcpath_old[MAXPATHLEN], rsrcpath_new[MAXPATHLEN];
	struct stat sb, rsb;
	int err;
	dev_t diff_device;

	dir[0] = newdir[0] = 0;

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
			case HTLC_DATA_DIR_RENAME:
				if ((err = hldir_to_path(dh, ROOTDIR, newdir, newdir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
		}
	dh_end()

	if ((!dir[0] && !fnlen) || !newdir[0]) {
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}
	if (!dir[0])
		strcpy(dir, ROOTDIR);
	if (fnlen) {
		snprintf(oldbuf, sizeof(oldbuf), "%s/%s", dir, filename);
		snprintf(newbuf, sizeof(newbuf), "%s/%s", newdir, filename);
	} else {
		strcpy(oldbuf, dir);
		strcpy(newbuf, newdir);
	}

	if (check_dropbox(htlc, oldbuf) || check_dropbox(htlc, newbuf)) {
		snd_strerror(htlc, EPERM);
		return;
	}

	if (stat(oldbuf, &sb)) {
		snd_strerror(htlc, errno);
		return;
	}
	if (S_ISDIR(sb.st_mode)) {
		if (!htlc->access.move_folders) {
			snd_strerror(htlc, EPERM);
			return;
		}
	} else {
		if (!htlc->access.move_files) {
			snd_strerror(htlc, EPERM);
			return;
		}
	}

	if (log_move)
		hxd_log("%s:%s:%u - move %s to %s", htlc->name, htlc->login, htlc->uid, oldbuf, newbuf);

	diff_device = sb.st_dev;
	if (stat(newdir, &sb)) {
		snd_strerror(htlc, errno);
		return;
	}

#if 0 /* gcc on hpux does not like this */
	diff_device &= ~sb.st_dev;
#else
	diff_device = diff_device != sb.st_dev;
#endif

	if (diff_device ? copy_and_unlink(oldbuf, newbuf) : rename(oldbuf, newbuf)) {
		snd_strerror(htlc, errno);
		return;
	}

#if defined(CONFIG_HFS)
	if (!hxd_cfg.operation.hfs)
		goto ret;
	if (hxd_cfg.files.fork == HFS_FORK_CAP) {
		if (!resource_path(rsrcpath_old, oldbuf, &rsb)) {
			if ((err = resource_path(rsrcpath_new, newbuf, 0))) {
				/* (void)rename(newbuf, oldbuf); */
				snd_strerror(htlc, err);
				return;
			} else {
				if (diff_device ? copy_and_unlink(rsrcpath_old, rsrcpath_new) : rename(rsrcpath_old, rsrcpath_new)) {
					/* (void)rename(newbuf, oldbuf); */
					snd_strerror(htlc, errno);
					return;
				}
			}
		}
	}
	if (!finderinfo_path(rsrcpath_old, oldbuf, &rsb)) {
		if ((err = finderinfo_path(rsrcpath_new, newbuf, 0))) {
			/* (void)rename(newbuf, oldbuf); */
			snd_strerror(htlc, err);
			return;
		} else {
			if (diff_device ? copy_and_unlink(rsrcpath_old, rsrcpath_new) : rename(rsrcpath_old, rsrcpath_new)) {
				/* (void)rename(newbuf, oldbuf); */
				snd_strerror(htlc, errno);
				return;
			}
		}
	}
ret:
#endif /* CONFIG_HFS */

	hlwrite(htlc, HTLS_HDR_TASK, 0, 0);
}
Ejemplo n.º 7
0
Archivo: files.c Proyecto: Schala/mhxd
void
rcv_file_setinfo (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0, newfnlen = 0, comlen = 0;
	char dir[MAXPATHLEN], oldbuf[MAXPATHLEN], newbuf[MAXPATHLEN],
	     filename[NAME_MAX], newfilename[NAME_MAX];
	char rsrcpath_old[MAXPATHLEN], rsrcpath_new[MAXPATHLEN];
	u_int8_t comment[200];
	struct stat sb;
	int err;

	dir[0] = 0;

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_FILE_RENAME:
				newfnlen = dh_len >= NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(newfilename, dh_data, newfnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
			case HTLC_DATA_FILE_COMMENT:
				comlen = dh_len > 255 ? 255 : dh_len;
				memcpy(comment, dh_data, comlen);
				break;
		}
	dh_end()

	if (!fnlen || (!newfnlen && !comlen)) {
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}

	snprintf(oldbuf, sizeof(oldbuf), "%s/%s", dir[0] ? dir : ROOTDIR, filename);
	if (stat(oldbuf, &sb)) {
		snd_strerror(htlc, errno);
		return;
	}
	if (check_dropbox(htlc, oldbuf)) {
		snd_strerror(htlc, EPERM);
		return;
	}

#if defined(CONFIG_HFS) 
	if (hxd_cfg.operation.hfs && comlen) {
		if (S_ISDIR(sb.st_mode)) {
			if (!htlc->access.comment_folders) {
				snd_strerror(htlc, EPERM);
				return;
			}
		} else {
			if (!htlc->access.comment_files) {
				snd_strerror(htlc, EPERM);
				return;
			}
		}
		if (log_comment)
			hxd_log("%s:%s:%u - comment %s to %.*s", htlc->name, htlc->login, htlc->uid, oldbuf, comlen, comment);
		comment_write(oldbuf, comment, comlen);
	}
#endif

	if (!newfnlen)
		goto ret;

	if (dir[0])
		snprintf(newbuf, sizeof(newbuf), "%s/%s", dir, newfilename);
	else
		snprintf(newbuf, sizeof(newbuf), "%s/%s", ROOTDIR, newfilename);

	if (S_ISDIR(sb.st_mode)) {
		if (!htlc->access.rename_folders) {
			snd_strerror(htlc, EPERM);
			return;
		}
	} else {
		if (!htlc->access.rename_files) {
			snd_strerror(htlc, EPERM);
			return;
		}
	}

	if (log_rename)
		hxd_log("%s:%s:%u - rename %s to %s", htlc->name, htlc->login, htlc->uid, oldbuf, newbuf);

	if (rename(oldbuf, newbuf)) {
		snd_strerror(htlc, errno);
		return;
	}

#if defined(CONFIG_HFS)
	if (!hxd_cfg.operation.hfs)
		goto ret;
	if (hxd_cfg.files.fork == HFS_FORK_CAP) {
		if (!resource_path(rsrcpath_old, oldbuf, &sb)) {
			if ((err = resource_path(rsrcpath_new, newbuf, 0))) {
				/* (void)rename(newbuf, oldbuf); */
				snd_strerror(htlc, err);
				return;
			} else {
				if (rename(rsrcpath_old, rsrcpath_new)) {
					/* (void)rename(newbuf, oldbuf); */
					snd_strerror(htlc, errno);
					return;
				}
			}
		}
	}
	if (!finderinfo_path(rsrcpath_old, oldbuf, &sb)) {
		if ((err = finderinfo_path(rsrcpath_new, newbuf, 0))) {
			/* (void)rename(newbuf, oldbuf); */
			snd_strerror(htlc, err);
			return;
		} else {
			if (rename(rsrcpath_old, rsrcpath_new)) {
				/* (void)rename(newbuf, oldbuf); */
				snd_strerror(htlc, errno);
				return;
			}
		}
	}
#endif /* CONFIG_HFS */

ret:
	hlwrite(htlc, HTLS_HDR_TASK, 0, 0);
}
Ejemplo n.º 8
0
Archivo: hfs.c Proyecto: asvitkine/phxd
void
comment_write (const char *path, char *comment, int comlen)
{
   char infopath[MAXPATHLEN];
   int f;
#if 0
   int i, r;
#endif
   union {
      struct hfs_cap_info cap;
      struct hfs_dbl_hdr dbl;
   } hdr;
   if (!finderinfo_path(infopath, path, 0)) {
      f = open(infopath, O_RDWR|O_CREAT, cfg.file_perm);
      if (f >= 0) {
         if (comlen > 200)
            comlen = 200;
         switch (cfg.fork) {
            case HFS_FORK_CAP:
               if (read(f, &hdr.cap, SIZEOF_HFS_CAP_INFO) != SIZEOF_HFS_CAP_INFO) {
                  memset(&hdr.cap, 0, sizeof(struct hfs_cap_info));
                  hdr.cap.fi_magic1 = HFS_CAP_MAGIC1;
                  hdr.cap.fi_version = HFS_CAP_VERSION;
                  hdr.cap.fi_magic = HFS_CAP_MAGIC;
                  hdr.cap.fi_datemagic = HFS_CAP_DMAGIC;
                  suffix_type_creator(hdr.cap.fi_fndr, path);
               }
               hdr.cap.fi_comln = comlen;
               memcpy(hdr.cap.fi_comnt, comment, comlen);
               lseek(f, 0, SEEK_SET);
               write(f, &hdr.cap, SIZEOF_HFS_CAP_INFO);
               break;
#if 0
            case HFS_FORK_NETATALK:
            case HFS_FORK_DOUBLE:
               r = read(f, &hdr.dbl, SIZEOF_HFS_DBL_HDR);
               if (r != SIZEOF_HFS_DBL_HDR)
                  break;
               if (ntohs(hdr.dbl.entries) > HFS_HDR_MAX)
                  hdr.dbl.entries = htons(HFS_HDR_MAX);
               r = read(f, &hdr.dbl.descrs, SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries));
               if (r != SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries))
                  break;
               for (i = 0; i < ntohs(hdr.dbl.entries); i++) {
                  struct hfs_hdr_descr *descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * i]);
                  if (ntohl(descr->id) == HFS_HDR_COMNT) {
                     descr->length = htonl(comlen);
                     if (lseek(f, ntohl(descr->offset), SEEK_SET) != (off_t)ntohl(descr->offset))
                        continue;
                     write(f, comment, comlen);
                     if (lseek(f, SIZEOF_HFS_DBL_HDR + SIZEOF_HFS_HDR_DESCR * i, SEEK_SET)
                         != (off_t)(SIZEOF_HFS_DBL_HDR + SIZEOF_HFS_HDR_DESCR * i))
                        continue;
                     write(f, descr, SIZEOF_HFS_HDR_DESCR);
                  }
               }
               break;
#endif
         }
         fsync(f);
         close(f);
      }
   }
}
Ejemplo n.º 9
0
Archivo: hfs.c Proyecto: asvitkine/phxd
void
hfsinfo_write (const char *path, struct hfsinfo *fi)
{
   char infopath[MAXPATHLEN];
#ifdef HAVE_CORESERVICES
   char type[5], creator[5], rpath[MAXPATHLEN];
#endif
   int f, i, r;
   union {
      struct hfs_cap_info cap;
      struct hfs_dbl_hdr dbl;
   } hdr;

#ifdef HAVE_CORESERVICES
   if (!resolve_alias_path(path, rpath) || mac_errno)
      goto fark;

   memcpy(type, fi->type, 4); type[4] = 0;
   memcpy(creator, fi->creator, 4); creator[4] = 0;
   mac_set_type(rpath, type, creator);

fark:
#endif

   if (!finderinfo_path(infopath, path, 0)) {
      f = open(infopath, O_RDWR|O_CREAT, cfg.file_perm);
      if (f >= 0) {
         switch (cfg.fork) {
            case HFS_FORK_CAP:
               memset(&hdr.cap, 0, sizeof(struct hfs_cap_info));
               hdr.cap.fi_magic1 = HFS_CAP_MAGIC1;
               hdr.cap.fi_version = HFS_CAP_VERSION;
               hdr.cap.fi_magic = HFS_CAP_MAGIC;
               hdr.cap.fi_datemagic = HFS_CAP_DMAGIC;
               hdr.cap.fi_datevalid = HFS_CAP_MDATE|HFS_CAP_CDATE;
               memcpy(hdr.cap.fi_fndr, fi->type, 8);
               memcpy(hdr.cap.fi_ctime, &fi->create_time, 8);
               hdr.cap.fi_comln = fi->comlen > 200 ? 200 : fi->comlen;
               memcpy(hdr.cap.fi_comnt, fi->comment, hdr.cap.fi_comln);
               write(f, &hdr.cap, SIZEOF_HFS_CAP_INFO);
               break;
            case HFS_FORK_NETATALK:
            case HFS_FORK_DOUBLE:
               r = read(f, &hdr.dbl, SIZEOF_HFS_DBL_HDR);
               if (r != SIZEOF_HFS_DBL_HDR) {
                  struct hfs_hdr_descr *descr;

#define NENTRIES 4
                  hdr.dbl.entries = htons(NENTRIES);
                  descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * 0]);
                  descr->id = htonl(HFS_HDR_COMNT);
                  descr->offset = htonl(SIZEOF_HFS_DBL_HDR + SIZEOF_HFS_HDR_DESCR * NENTRIES);
                  descr->length = htonl(fi->comlen);
                  descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * 1]);
                  descr->id = htonl(HFS_HDR_DATES);
                  descr->offset = htonl(SIZEOF_HFS_DBL_HDR + SIZEOF_HFS_HDR_DESCR * NENTRIES + fi->comlen);
                  descr->length = htonl(8);
                  descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * 2]);
                  descr->id = htonl(HFS_HDR_FINFO);
                  descr->offset = htonl(SIZEOF_HFS_DBL_HDR + SIZEOF_HFS_HDR_DESCR * NENTRIES + fi->comlen + 8);
                  descr->length = htonl(8);
                  descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * 3]);
                  descr->id = htonl(HFS_HDR_RSRC);
                  descr->offset = htonl(SIZEOF_HFS_DBL_HDR + SIZEOF_HFS_HDR_DESCR * NENTRIES + fi->comlen + 8 + 8);
                  descr->length = htonl(0);
               } else {
                  if (ntohs(hdr.dbl.entries) > HFS_HDR_MAX)
                     hdr.dbl.entries = htons(HFS_HDR_MAX);
                  r = read(f, &hdr.dbl.descrs, SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries));
                  if (r != SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries))
                     break;
               }
               for (i = 0; i < ntohs(hdr.dbl.entries); i++) {
                  struct hfs_hdr_descr *descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * i]);
                  if (lseek(f, ntohl(descr->offset), SEEK_SET) != (off_t)ntohl(descr->offset))
                     continue;
                  switch (ntohl(descr->id)) {
                     case HFS_HDR_COMNT:
                        if (r == SIZEOF_HFS_DBL_HDR)
                           break;
                        descr->length = htonl(fi->comlen);
                        write(f, fi->comment, fi->comlen);
                        break;
                     case HFS_HDR_OLDI:
                     case HFS_HDR_DATES:
                        if (descr->length < 8)
                           descr->length = 8;
                        write(f, &fi->create_time, 8);
                        break;
                     case HFS_HDR_FINFO:
                        if (descr->length < 8)
                           descr->length = 8;
                        write(f, fi->type, 8);
                        break;
                     case HFS_HDR_RSRC:
                        descr->length = htonl(fi->rsrclen);
                        break;
                  }
               }
               hdr.dbl.magic = htonl(HFS_DBL_MAGIC);
               if (cfg.fork == HFS_FORK_NETATALK)
                  hdr.dbl.version = htonl(HFS_HDR_VERSION_1);
               else
                  hdr.dbl.version = htonl(HFS_HDR_VERSION_2);
               lseek(f, 0, SEEK_SET);
               write(f, &hdr.dbl, SIZEOF_HFS_DBL_HDR + SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries));
               break;
         }
         fsync(f);
         close(f);
      }
   }
}
Ejemplo n.º 10
0
Archivo: hfs.c Proyecto: asvitkine/phxd
void
hfsinfo_read (const char *path, struct hfsinfo *fi)
{
   char infopath[MAXPATHLEN];
#ifdef HAVE_CORESERVICES
   char type[5], creator[5];
   char rpath[MAXPATHLEN];
#endif
   int f, i, r;
   struct stat sb;
   union {
      struct hfs_cap_info cap;
      struct hfs_dbl_hdr dbl;
   } hdr;

   memset(fi, 0, sizeof(struct hfsinfo));
   if (!finderinfo_path(infopath, path, &sb)) {
      f = open(infopath, O_RDONLY);
      if (f >= 0) {
         switch (cfg.fork) {
            case HFS_FORK_CAP:
               r = read(f, &hdr.cap, SIZEOF_HFS_CAP_INFO);
               if (r != SIZEOF_HFS_CAP_INFO)
                  break;
               memcpy(fi->type, hdr.cap.fi_fndr, 8);
               if (hdr.cap.fi_datevalid & HFS_CAP_CDATE)
                  memcpy(&fi->create_time, hdr.cap.fi_ctime, 4);
               else
                  fi->create_time = 0;
               if (hdr.cap.fi_datevalid & HFS_CAP_MDATE)
                  memcpy(&fi->modify_time, hdr.cap.fi_mtime, 4);
               else
                  fi->modify_time = 0;
               fi->comlen = hdr.cap.fi_comln > 200 ? 200 : hdr.cap.fi_comln;
               memcpy(fi->comment, hdr.cap.fi_comnt, fi->comlen);
               break;
            case HFS_FORK_NETATALK:
            case HFS_FORK_DOUBLE:
               r = read(f, &hdr.dbl, SIZEOF_HFS_DBL_HDR);
               if (r != SIZEOF_HFS_DBL_HDR)
                  break;
               if (ntohs(hdr.dbl.entries) > HFS_HDR_MAX)
                  hdr.dbl.entries = htons(HFS_HDR_MAX);
               r = read(f, &hdr.dbl.descrs, SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries));
               if (r != SIZEOF_HFS_HDR_DESCR * ntohs(hdr.dbl.entries))
                  break;
               for (i = 0; i < ntohs(hdr.dbl.entries); i++) {
                  struct hfs_hdr_descr *descr = (struct hfs_hdr_descr *)(&hdr.dbl.descrs[SIZEOF_HFS_HDR_DESCR * i]);
                  if (lseek(f, ntohl(descr->offset), SEEK_SET) != (off_t)ntohl(descr->offset))
                     continue;
                  switch (ntohl(descr->id)) {
                     case HFS_HDR_COMNT:
                        fi->comlen = ntohl(descr->length) > 200 ? 200 : ntohl(descr->length);
                        r = read(f, fi->comment, fi->comlen);
                        if (r != (int)fi->comlen)
                           fi->comlen = 0;
                        break;
                     case HFS_HDR_OLDI:
                     case HFS_HDR_DATES:
                        r = read(f, &fi->create_time, 8);
                        if (r != 8)
                           fi->create_time = fi->modify_time = 0;
                        break;
                     case HFS_HDR_FINFO:
                        r = read(f, fi->type, 8);
                        if (r != 8)
                           memset(fi->type, 0, 8);
                        break;
                     case HFS_HDR_RSRC:
                        fi->rsrclen = ntohl(descr->length);
                        break;
                  }
               }
               break;
         }
         close(f);
      }
   }

   if (!(*(u_int32_t *)(&fi->type[0])) || !(*(u_int32_t *)(&fi->type[4])))
      suffix_type_creator(fi->type, path);

#ifdef HAVE_CORESERVICES
   if (!resolve_alias_path(path, rpath) || mac_errno)
      goto fark;

   if (mac_get_type(path, type, creator) || mac_errno)
      goto fark;

   if (strcmp(type, "????") || strcmp(creator, "????")) {
      memcpy(fi->type, type, 4);
      memcpy(fi->creator, creator, 4);
   }

fark:
#endif

   if (!fi->create_time || !fi->modify_time) {
      if (!stat(path, &sb)) {
         u_int32_t htime = hfs_u_to_htime(sb.st_mtime);
         if (!fi->create_time)
            fi->create_time = htime;
         if (!fi->modify_time)
            fi->modify_time = htime;
      }
   }
   if (!stat(path, &sb) && !S_ISDIR(sb.st_mode)) {
      if (!fi->comlen && cfg.comment) {
         fi->comlen = strlen(cfg.comment);
         if (fi->comlen > 200)
            fi->comlen = 200;
         memcpy(fi->comment, cfg.comment, fi->comlen);
      }
   } else {
      if (!fi->comlen && cfg.dir_comment) {
         fi->comlen = strlen(cfg.dir_comment);
         if (fi->comlen > 200)
            fi->comlen = 200;
         memcpy(fi->comment, cfg.dir_comment, fi->comlen);
      }
   }
}
Ejemplo n.º 11
0
Archivo: hfs.c Proyecto: asvitkine/phxd
void
type_creator (u_int8_t *buf, const char *path)
{
   char infopath[MAXPATHLEN];
   struct stat sb;
   u_int8_t is_link = 0;

#ifdef HAVE_CORESERVICES
   if (!resolve_alias_path(path, infopath) || mac_errno)
      return;

   if (is_alias(infopath, &is_link) || mac_errno)
      return;

   if (is_link)
      strcpy(buf, "alis");
   else {
      char type[5], creator[5];
      if (!mac_get_type(infopath, type, creator) && !mac_errno) {
         memcpy(buf, type, 4);
         memcpy(buf + 4, creator, 4);
      }
   }

   if (memcmp(buf, "????????", 8))
      return;
#endif
      

   if (!finderinfo_path(infopath, path, &sb)) {
      int r, f;

      f = open(infopath, O_RDONLY);
      if (f < 0)
         goto use_suffix;
      switch (cfg.fork) {
         default:
         case HFS_FORK_CAP:
            r = read(f, buf, 8);
            if (r != 8 || !(*(u_int32_t *)(&buf[0])) || !(*(u_int32_t *)(&buf[4])))
               r = 0;
            break;
         case HFS_FORK_NETATALK:
         case HFS_FORK_DOUBLE:
            {
               struct hfs_dbl_hdr dbl;
               int i;

               r = read(f, &dbl, SIZEOF_HFS_DBL_HDR);
               if (r != SIZEOF_HFS_DBL_HDR) {
                  r = -1;
                  break;
               }
               if (ntohs(dbl.entries) > HFS_HDR_MAX)
                  dbl.entries = htons(HFS_HDR_MAX);
               r = read(f, &dbl.descrs, SIZEOF_HFS_HDR_DESCR * ntohs(dbl.entries));
               if (r != SIZEOF_HFS_HDR_DESCR * ntohs(dbl.entries)) {
                  r = -1;
                  break;
               }
               for (i = 0; i < ntohs(dbl.entries); i++) {
                  struct hfs_hdr_descr *descr = (struct hfs_hdr_descr *)(&dbl.descrs[SIZEOF_HFS_HDR_DESCR * i]);
                  if (ntohl(descr->id) == HFS_HDR_FINFO) {
                     if (lseek(f, ntohl(descr->offset), SEEK_SET) != (off_t)ntohl(descr->offset))
                        continue;
                     r = 8;
                     r = read(f, buf, 8);
                     break;
                  }
               }
            }
            break;
      }
      close(f);
      if (r == 8)
         return;
   }

use_suffix:
   suffix_type_creator(buf, path);
}