]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - misc-utils/namei.c
1 /*-------------------------------------------------------------
10 Modifications by Steve Tell March 28, 1991
12 usage: namei pathname [pathname ... ]
14 This program reads it's arguments as pathnames to any type
15 of Unix file (symlinks, files, directories, and so forth).
16 The program then follows each pathname until a terminal
17 point is found (a file, directory, char device, etc).
18 If it finds a symbolic link, we show the link, and start
19 following it, indenting the output to show the context.
21 This program is useful for finding a "too many levels of
22 symbolic links" problems.
24 For each line output, the program puts a file type first:
26 f: = the pathname we are currently trying to resolve
28 D = directory that is a mount point
29 l = symbolic link (both the link and it's contents are output)
34 ? = an error of some kind
36 The program prints an informative messages when we exceed
37 the maximum number of symbolic links this system can have.
39 The program exits with a 1 status ONLY if it finds it cannot
40 chdir to /, or if it encounters an unknown file type.
42 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
43 - added Native Language Support
45 -------------------------------------------------------------*/
52 #include <sys/types.h>
54 #include <sys/param.h>
57 #define ERR strerror(errno),errno
64 #define MAXSYMLINKS 256
67 static char *pperm(unsigned short);
68 static void namei(char *, int);
69 static void usage(void);
72 main(int argc
, char **argv
) {
75 char curdir
[MAXPATHLEN
];
77 setlocale(LC_ALL
, "");
78 bindtextdomain(PACKAGE
, LOCALEDIR
);
84 while((c
= getopt(argc
, argv
, "mx")) != EOF
){
100 if(getcwd(curdir
, sizeof(curdir
)) == NULL
){
101 (void)fprintf(stderr
, _("namei: unable to get current directory - %s\n"), curdir
);
106 for(; optind
< argc
; optind
++){
107 (void)printf("f: %s\n", argv
[optind
]);
109 namei(argv
[optind
], 0);
111 if(chdir(curdir
) == -1){
112 (void)fprintf(stderr
, _("namei: unable to chdir to %s - %s (%d)\n"), curdir
, ERR
);
121 (void)fprintf(stderr
,_("usage: namei [-mx] pathname [pathname ...]\n"));
126 #define NODEV (dev_t)(-1)
130 namei(char *file
, int lev
) {
132 char buf
[BUFSIZ
], sym
[BUFSIZ
];
135 dev_t lastdev
= NODEV
;
138 * See if the file has a leading /, and if so cd to root
145 if(chdir("/") == -1){
146 (void)fprintf(stderr
,_("namei: could not chdir to root!\n"));
149 for(i
= 0; i
< lev
; i
++)
152 if(stat("/", &stb
) == -1){
153 (void)fprintf(stderr
, _("namei: could not stat root!\n"));
156 lastdev
= stb
.st_dev
;
159 (void)printf(" d%s /\n", pperm(stb
.st_mode
));
161 (void)printf(" d /\n");
167 * Copy up to the next / (or nil) into buf
170 for(cp
= buf
; *file
!= '\0' && *file
!= '/'; cp
++, file
++)
173 while(*file
== '/') /* eat extra /'s */
181 * Buf is empty, so therefore we are done
182 * with this level of file
188 for(i
= 0; i
< lev
; i
++)
192 * See what type of critter this file is
195 if(lstat(buf
, &stb
) == -1){
196 (void)printf(" ? %s - %s (%d)\n", buf
, ERR
);
200 switch(stb
.st_mode
& S_IFMT
){
204 * File is a directory, chdir to it
207 if(chdir(buf
) == -1){
208 (void)printf(_(" ? could not chdir into %s - %s (%d)\n"), buf
, ERR
);
211 if(xflag
&& lastdev
!= stb
.st_dev
&& lastdev
!= NODEV
){
212 /* Across mnt point */
214 (void)printf(" D%s %s\n", pperm(stb
.st_mode
), buf
);
216 (void)printf(" D %s\n", buf
);
220 (void)printf(" d%s %s\n", pperm(stb
.st_mode
), buf
);
222 (void)printf(" d %s\n", buf
);
224 lastdev
= stb
.st_dev
;
226 (void)fflush(stdout
);
231 * Sigh, another symlink. Read it's contents and
236 if(readlink(buf
, sym
, BUFSIZ
) == -1){
237 (void)printf(_(" ? problems reading symlink %s - %s (%d)\n"), buf
, ERR
);
242 (void)printf(" l%s %s -> %s", pperm(stb
.st_mode
), buf
, sym
);
244 (void)printf(" l %s -> %s", buf
, sym
);
246 if(symcount
> 0 && symcount
++ > MAXSYMLINKS
){
247 (void)printf(_(" *** EXCEEDED UNIX LIMIT OF SYMLINKS ***\n"));
257 (void)printf(" c%s %s\n", pperm(stb
.st_mode
), buf
);
259 (void)printf(" c %s\n", buf
);
264 (void)printf(" b%s %s\n", pperm(stb
.st_mode
), buf
);
266 (void)printf(" b %s\n", buf
);
271 (void)printf(" s%s %s\n", pperm(stb
.st_mode
), buf
);
273 (void)printf(" s %s\n", buf
);
278 (void)printf(" -%s %s\n", pperm(stb
.st_mode
), buf
);
280 (void)printf(" - %s\n", buf
);
284 (void)fprintf(stderr
,_("namei: unknown file type 0%06o on file %s\n"), stb
.st_mode
, buf
);
292 * Mode word, as from a struct stat, and return
293 * a pointer to a static string containing a printable version like ls.
294 * For example 0755 produces "rwxr-xr-x"
297 pperm(unsigned short mode
) {
301 char *lschars
= "xwrxwrxwr"; /* the complete string backwards */
305 for(i
= 0, cp
= lschars
, m
= mode
, bp
= &buf
[8];
307 i
++, cp
++, m
>>= 1, bp
--) {