* fsmagic - magic based on filesystem info - directory, special files, etc.
* Copyright (c) Ian F. Darwin, 1987.
* Written by Ian F. Darwin.
* This software is not subject to any license of the American Telephone
* and Telegraph Company or of the Regents of the University of California.
* Permission is granted to anyone to use this software for any purpose on
* any computer system, and to alter it and redistribute it freely, subject
* to the following restrictions:
* 1. The author is not responsible for the consequences of use of this
* software, no matter how awful, even if they arise from flaws in it.
* 2. The origin of this software must not be misrepresented, either by
* explicit claim or by omission. Since few users ever read sources,
* credits must appear in the documentation.
* 3. Altered versions must be plainly marked as such, and must not be
* misrepresented as being the original software. Since few users
* ever read sources, credits must appear in the documentation.
* 4. This notice may not be removed or altered.
#ifndef major /* if `major' not defined in types.h, */
#include <sys/sysmacros.h> /* try this one. */
#ifndef major /* still not defined? give up, manual intervention needed */
/* If cc tries to compile this, read and act on it. */
/* On most systems cpp will discard it automatically */
Congratulations
, you have found a portability bug
.
Please grep
/usr
/include
/sys
and edit the above
#include
to point at the file that defines the
"major" macro
.
"@(#)fsmagic.c,v 1.3 1993/06/10 00:38:10 jtc Exp";
* Fstat is cheaper but fails for files you don't have read perms on.
* On 4.2BSD and similar systems, use lstat() to identify symlinks.
ret
= stat(fn
, sb
); /* don't merge into if; see "ret =" above */
/* Yes, I do mean stdout. */
/* No \n, caller will provide. */
"can't stat `%s' (%s).", fn
, strerror(errno
));
if (sb
->st_mode
& S_ISUID
) ckfputs("setuid ", stdout
);
if (sb
->st_mode
& S_ISGID
) ckfputs("setgid ", stdout
);
if (sb
->st_mode
& S_ISVTX
) ckfputs("sticky ", stdout
);
switch (sb
->st_mode
& S_IFMT
) {
ckfputs("directory", stdout
);
(void) printf("character special (%d/%d)",
major(sb
->st_rdev
), minor(sb
->st_rdev
));
(void) printf("block special (%d/%d)",
major(sb
->st_rdev
), minor(sb
->st_rdev
));
/* TODO add code to handle V7 MUX and Blit MUX files */
ckfputs("fifo (named pipe)", stdout
);
if ((nch
= readlink(fn
, buf
, BUFSIZ
-1)) <= 0) {
ckfprintf(stdout
, "unreadable symlink (%s).",
buf
[nch
] = '\0'; /* readlink(2) forgets this */
/* If broken symlink, say so and quit early. */
if (stat(buf
, &tstatbuf
) < 0) {
"broken symbolic link to %s", buf
);
char buf2
[BUFSIZ
+BUFSIZ
+4];
if ((tmp
= strrchr(fn
, '/')) == NULL
) {
tmp
= buf
; /* in current directory anyway */
strcpy (buf2
, fn
); /* take directory part */
strcat (buf2
, buf
); /* plus (relative) symlink */
if (stat(tmp
, &tstatbuf
) < 0) {
"broken symbolic link to %s", buf
);
/* Otherwise, handle it. */
process(buf
, strlen(buf
));
} else { /* just print what it points to */
ckfputs("symbolic link to ", stdout
);
ckfputs("socket", stdout
);
error("invalid mode 0%o.\n", sb
->st_mode
);
* regular file, check next possibility
ckfputs("empty", stdout
);