summaryrefslogtreecommitdiffstats
path: root/fsmagic.c
diff options
context:
space:
mode:
Diffstat (limited to 'fsmagic.c')
-rw-r--r--fsmagic.c165
1 files changed, 100 insertions, 65 deletions
diff --git a/fsmagic.c b/fsmagic.c
index e04f598..f3b2372 100644
--- a/fsmagic.c
+++ b/fsmagic.c
@@ -57,9 +57,33 @@
#undef HAVE_MAJOR
#ifndef lint
-FILE_RCSID("@(#)$File: fsmagic.c,v 1.48 2007/10/17 19:33:31 christos Exp $")
+FILE_RCSID("@(#)$File: fsmagic.c,v 1.52 2008/07/25 23:59:01 rrt Exp $")
#endif /* lint */
+private int
+bad_link(struct magic_set *ms, int err, char *buf)
+{
+ const char *errfmt;
+ int mime = ms->flags & MAGIC_MIME;
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-symlink")
+ == -1)
+ return -1;
+ else if (!mime) {
+ if (err == ELOOP)
+ errfmt = "symbolic link in a loop";
+ else
+ errfmt = "broken symbolic link to `%s'";
+ if (ms->flags & MAGIC_ERROR) {
+ file_error(ms, err, errfmt, buf);
+ return -1;
+ }
+ if (file_printf(ms, errfmt, buf) == -1)
+ return -1;
+ }
+ return 1;
+}
+
protected int
file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
{
@@ -96,16 +120,7 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
return 1;
}
- if (mime) {
- if ((sb->st_mode & S_IFMT) != S_IFREG) {
- if ((mime & MAGIC_MIME_TYPE) &&
- file_printf(ms, "application/x-not-regular-file")
- == -1)
- return -1;
- return 1;
- }
- }
- else {
+ if (!mime) {
#ifdef S_ISUID
if (sb->st_mode & S_ISUID)
if (file_printf(ms, "setuid ") == -1)
@@ -125,7 +140,11 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
switch (sb->st_mode & S_IFMT) {
case S_IFDIR:
- if (file_printf(ms, "directory") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-directory")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "directory") == -1)
return -1;
return 1;
#ifdef S_IFCHR
@@ -137,21 +156,27 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
*/
if ((ms->flags & MAGIC_DEVICES) != 0)
break;
-#ifdef HAVE_ST_RDEV
-# ifdef dv_unit
- if (file_printf(ms, "character special (%d/%d/%d)",
- major(sb->st_rdev), dv_unit(sb->st_rdev),
- dv_subunit(sb->st_rdev)) == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-character-device")
+ == -1)
return -1;
+ if (!mime) {
+#ifdef HAVE_STAT_ST_RDEV
+# ifdef dv_unit
+ if (file_printf(ms, "character special (%d/%d/%d)",
+ major(sb->st_rdev), dv_unit(sb->st_rdev),
+ dv_subunit(sb->st_rdev)) == -1)
+ return -1;
# else
- if (file_printf(ms, "character special (%ld/%ld)",
- (long) major(sb->st_rdev), (long) minor(sb->st_rdev)) == -1)
- return -1;
+ if (file_printf(ms, "character special (%ld/%ld)",
+ (long) major(sb->st_rdev), (long) minor(sb->st_rdev)) == -1)
+ return -1;
# endif
#else
- if (file_printf(ms, "character special") == -1)
- return -1;
+ if (file_printf(ms, "character special") == -1)
+ return -1;
#endif
+ }
return 1;
#endif
#ifdef S_IFBLK
@@ -163,21 +188,27 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
*/
if ((ms->flags & MAGIC_DEVICES) != 0)
break;
-#ifdef HAVE_ST_RDEV
-# ifdef dv_unit
- if (file_printf(ms, "block special (%d/%d/%d)",
- major(sb->st_rdev), dv_unit(sb->st_rdev),
- dv_subunit(sb->st_rdev)) == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-block-device")
+ == -1)
return -1;
+ if (!mime) {
+#ifdef HAVE_STAT_ST_RDEV
+# ifdef dv_unit
+ if (file_printf(ms, "block special (%d/%d/%d)",
+ major(sb->st_rdev), dv_unit(sb->st_rdev),
+ dv_subunit(sb->st_rdev)) == -1)
+ return -1;
# else
- if (file_printf(ms, "block special (%ld/%ld)",
- (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1)
- return -1;
+ if (file_printf(ms, "block special (%ld/%ld)",
+ (long)major(sb->st_rdev), (long)minor(sb->st_rdev)) == -1)
+ return -1;
# endif
#else
- if (file_printf(ms, "block special") == -1)
- return -1;
+ if (file_printf(ms, "block special") == -1)
+ return -1;
#endif
+ }
return 1;
#endif
/* TODO add code to handle V7 MUX and Blit MUX files */
@@ -185,13 +216,21 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
case S_IFIFO:
if((ms->flags & MAGIC_DEVICES) != 0)
break;
- if (file_printf(ms, "fifo (named pipe)") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-fifo")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "fifo (named pipe)") == -1)
return -1;
return 1;
#endif
#ifdef S_IFDOOR
case S_IFDOOR:
- if (file_printf(ms, "door") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-door")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "door") == -1)
return -1;
return 1;
#endif
@@ -203,29 +242,23 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
fn);
return -1;
}
- if (file_printf(ms,
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-symlink")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms,
"unreadable symlink `%s' (%s)", fn,
strerror(errno)) == -1)
return -1;
return 1;
}
- buf[nch] = '\0'; /* readlink(2) forgets this */
+ buf[nch] = '\0'; /* readlink(2) does not do this */
/* If broken symlink, say so and quit early. */
if (*buf == '/') {
- if (stat(buf, &tstatbuf) < 0) {
- if (ms->flags & MAGIC_ERROR) {
- file_error(ms, errno,
- "broken symbolic link to `%s'", buf);
- return -1;
- }
- if (file_printf(ms, "broken symbolic link to `%s'",
- buf) == -1)
- return -1;
- return 1;
- }
- }
- else {
+ if (stat(buf, &tstatbuf) < 0)
+ return bad_link(ms, errno, buf);
+ } else {
char *tmp;
char buf2[BUFSIZ+BUFSIZ+4];
@@ -238,7 +271,11 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
"path too long: `%s'", buf);
return -1;
}
- if (file_printf(ms,
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-path-too-long")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms,
"path too long: `%s'", fn) == -1)
return -1;
return 1;
@@ -248,18 +285,8 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
(void)strcat(buf2, buf); /* plus (rel) link */
tmp = buf2;
}
- if (stat(tmp, &tstatbuf) < 0) {
- if (ms->flags & MAGIC_ERROR) {
- file_error(ms, errno,
- "broken symbolic link to `%s'",
- buf);
- return -1;
- }
- if (file_printf(ms,
- "broken symbolic link to `%s'", buf) == -1)
- return -1;
- return 1;
- }
+ if (stat(tmp, &tstatbuf) < 0)
+ return bad_link(ms, errno, buf);
}
/* Otherwise, handle it. */
@@ -270,16 +297,24 @@ file_fsmagic(struct magic_set *ms, const char *fn, struct stat *sb)
ms->flags |= MAGIC_SYMLINK;
return p != NULL ? 1 : -1;
} else { /* just print what it points to */
- if (file_printf(ms, "symbolic link to `%s'",
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-symlink")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "symbolic link to `%s'",
buf) == -1)
return -1;
}
- return 1;
+ return 1;
#endif
#ifdef S_IFSOCK
#ifndef __COHERENT__
case S_IFSOCK:
- if (file_printf(ms, "socket") == -1)
+ if ((mime & MAGIC_MIME_TYPE) &&
+ file_printf(ms, "application/x-socket")
+ == -1)
+ return -1;
+ if (!mime && file_printf(ms, "socket") == -1)
return -1;
return 1;
#endif
OpenPOWER on IntegriCloud