[BACK]Return to fsmagic.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / file

Annotation of src/usr.bin/file/fsmagic.c, Revision 1.1

1.1     ! deraadt     1: /*
        !             2:  * fsmagic - magic based on filesystem info - directory, special files, etc.
        !             3:  *
        !             4:  * Copyright (c) Ian F. Darwin, 1987.
        !             5:  * Written by Ian F. Darwin.
        !             6:  *
        !             7:  * This software is not subject to any license of the American Telephone
        !             8:  * and Telegraph Company or of the Regents of the University of California.
        !             9:  *
        !            10:  * Permission is granted to anyone to use this software for any purpose on
        !            11:  * any computer system, and to alter it and redistribute it freely, subject
        !            12:  * to the following restrictions:
        !            13:  *
        !            14:  * 1. The author is not responsible for the consequences of use of this
        !            15:  *    software, no matter how awful, even if they arise from flaws in it.
        !            16:  *
        !            17:  * 2. The origin of this software must not be misrepresented, either by
        !            18:  *    explicit claim or by omission.  Since few users ever read sources,
        !            19:  *    credits must appear in the documentation.
        !            20:  *
        !            21:  * 3. Altered versions must be plainly marked as such, and must not be
        !            22:  *    misrepresented as being the original software.  Since few users
        !            23:  *    ever read sources, credits must appear in the documentation.
        !            24:  *
        !            25:  * 4. This notice may not be removed or altered.
        !            26:  */
        !            27:
        !            28: #include <stdio.h>
        !            29: #include <string.h>
        !            30: #include <sys/types.h>
        !            31: #include <sys/stat.h>
        !            32: #include <unistd.h>
        !            33: #include <stdlib.h>
        !            34: #ifndef        major                   /* if `major' not defined in types.h, */
        !            35: #include <sys/sysmacros.h>     /* try this one. */
        !            36: #endif
        !            37: #ifndef        major   /* still not defined? give up, manual intervention needed */
        !            38:                /* If cc tries to compile this, read and act on it. */
        !            39:                /* On most systems cpp will discard it automatically */
        !            40:                Congratulations, you have found a portability bug.
        !            41:                Please grep /usr/include/sys and edit the above #include
        !            42:                to point at the file that defines the "major" macro.
        !            43: #endif /*major*/
        !            44:
        !            45: #include "file.h"
        !            46:
        !            47: #ifndef        lint
        !            48: static char *moduleid =
        !            49:        "@(#)$Id: fsmagic.c,v 1.7 1995/04/28 19:23:51 christos Exp $";
        !            50: #endif /* lint */
        !            51:
        !            52: int
        !            53: fsmagic(fn, sb)
        !            54: const char *fn;
        !            55: struct stat *sb;
        !            56: {
        !            57:        int ret = 0;
        !            58:
        !            59:        /*
        !            60:         * Fstat is cheaper but fails for files you don't have read perms on.
        !            61:         * On 4.2BSD and similar systems, use lstat() to identify symlinks.
        !            62:         */
        !            63: #ifdef S_IFLNK
        !            64:        if (!lflag)
        !            65:                ret = lstat(fn, sb);
        !            66:        else
        !            67: #endif
        !            68:        ret = stat(fn, sb);     /* don't merge into if; see "ret =" above */
        !            69:
        !            70:        if (ret) {
        !            71:                ckfprintf(stdout,
        !            72:                        /* Yes, I do mean stdout. */
        !            73:                        /* No \n, caller will provide. */
        !            74:                        "can't stat `%s' (%s).", fn, strerror(errno));
        !            75:                return 1;
        !            76:        }
        !            77:
        !            78:        if (sb->st_mode & S_ISUID) ckfputs("setuid ", stdout);
        !            79:        if (sb->st_mode & S_ISGID) ckfputs("setgid ", stdout);
        !            80:        if (sb->st_mode & S_ISVTX) ckfputs("sticky ", stdout);
        !            81:
        !            82:        switch (sb->st_mode & S_IFMT) {
        !            83:        case S_IFDIR:
        !            84:                ckfputs("directory", stdout);
        !            85:                return 1;
        !            86:        case S_IFCHR:
        !            87:                (void) printf("character special (%d/%d)",
        !            88:                        major(sb->st_rdev), minor(sb->st_rdev));
        !            89:                return 1;
        !            90:        case S_IFBLK:
        !            91:                (void) printf("block special (%d/%d)",
        !            92:                        major(sb->st_rdev), minor(sb->st_rdev));
        !            93:                return 1;
        !            94:        /* TODO add code to handle V7 MUX and Blit MUX files */
        !            95: #ifdef S_IFIFO
        !            96:        case S_IFIFO:
        !            97:                ckfputs("fifo (named pipe)", stdout);
        !            98:                return 1;
        !            99: #endif
        !           100: #ifdef S_IFLNK
        !           101:        case S_IFLNK:
        !           102:                {
        !           103:                        char buf[BUFSIZ+4];
        !           104:                        register int nch;
        !           105:                        struct stat tstatbuf;
        !           106:
        !           107:                        if ((nch = readlink(fn, buf, BUFSIZ-1)) <= 0) {
        !           108:                                ckfprintf(stdout, "unreadable symlink (%s).",
        !           109:                                      strerror(errno));
        !           110:                                return 1;
        !           111:                        }
        !           112:                        buf[nch] = '\0';        /* readlink(2) forgets this */
        !           113:
        !           114:                        /* If broken symlink, say so and quit early. */
        !           115:                        if (*buf == '/') {
        !           116:                            if (stat(buf, &tstatbuf) < 0) {
        !           117:                                ckfprintf(stdout,
        !           118:                                        "broken symbolic link to %s", buf);
        !           119:                                return 1;
        !           120:                            }
        !           121:                        }
        !           122:                        else {
        !           123:                            char *tmp;
        !           124:                            char buf2[BUFSIZ+BUFSIZ+4];
        !           125:
        !           126:                            if ((tmp = strrchr(fn,  '/')) == NULL) {
        !           127:                                tmp = buf; /* in current directory anyway */
        !           128:                            }
        !           129:                            else {
        !           130:                                strcpy (buf2, fn);  /* take directory part */
        !           131:                                buf2[tmp-fn+1] = '\0';
        !           132:                                strcat (buf2, buf); /* plus (relative) symlink */
        !           133:                                tmp = buf2;
        !           134:                            }
        !           135:                            if (stat(tmp, &tstatbuf) < 0) {
        !           136:                                ckfprintf(stdout,
        !           137:                                        "broken symbolic link to %s", buf);
        !           138:                                return 1;
        !           139:                            }
        !           140:                         }
        !           141:
        !           142:                        /* Otherwise, handle it. */
        !           143:                        if (lflag) {
        !           144:                                process(buf, strlen(buf));
        !           145:                                return 1;
        !           146:                        } else { /* just print what it points to */
        !           147:                                ckfputs("symbolic link to ", stdout);
        !           148:                                ckfputs(buf, stdout);
        !           149:                        }
        !           150:                }
        !           151:                return 1;
        !           152: #endif
        !           153: #ifdef S_IFSOCK
        !           154: #ifndef __COHERENT__
        !           155:        case S_IFSOCK:
        !           156:                ckfputs("socket", stdout);
        !           157:                return 1;
        !           158: #endif
        !           159: #endif
        !           160:        case S_IFREG:
        !           161:                break;
        !           162:        default:
        !           163:                error("invalid mode 0%o.\n", sb->st_mode);
        !           164:                /*NOTREACHED*/
        !           165:        }
        !           166:
        !           167:        /*
        !           168:         * regular file, check next possibility
        !           169:         */
        !           170:        if (sb->st_size == 0) {
        !           171:                ckfputs("empty", stdout);
        !           172:                return 1;
        !           173:        }
        !           174:        return 0;
        !           175: }
        !           176: