]>
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 -------------------------------------------------------------*/
50 #include <sys/types.h>
52 #include <sys/param.h>
55 #ifndef __GNU_LIBRARY__
56 extern char *sys_errlist
[];
60 #define ERR sys_errlist[errno],errno
67 #define MAXSYMLINKS 256
77 void namei(), usage();
81 char curdir
[MAXPATHLEN
];
83 setlocale(LC_ALL
, "");
84 bindtextdomain(PACKAGE
, LOCALEDIR
);
90 while((c
= getopt(argc
, argv
, "mx")) != EOF
){
106 if(getcwd(curdir
, sizeof(curdir
)) == NULL
){
107 (void)fprintf(stderr
, _("namei: unable to get current directory - %s\n"), curdir
);
112 for(; optind
< argc
; optind
++){
113 (void)printf("f: %s\n", argv
[optind
]);
115 namei(argv
[optind
], 0);
117 if(chdir(curdir
) == -1){
118 (void)fprintf(stderr
, _("namei: unable to chdir to %s - %s (%d)\n"), curdir
, ERR
);
128 (void)fprintf(stderr
,_("usage: namei [-mx] pathname [pathname ...]\n"));
133 #define NODEV (dev_t)(-1)
143 char buf
[BUFSIZ
], sym
[BUFSIZ
];
146 dev_t lastdev
= NODEV
;
149 * See if the file has a leading /, and if so cd to root
156 if(chdir("/") == -1){
157 (void)fprintf(stderr
,_("namei: could not chdir to root!\n"));
160 for(i
= 0; i
< lev
; i
++)
163 if(stat("/", &stb
) == -1){
164 (void)fprintf(stderr
, _("namei: could not stat root!\n"));
167 lastdev
= stb
.st_dev
;
170 (void)printf(" d%s /\n", pperm(stb
.st_mode
));
172 (void)printf(" d /\n");
178 * Copy up to the next / (or nil) into buf
181 for(cp
= buf
; *file
!= '\0' && *file
!= '/'; cp
++, file
++)
184 while(*file
== '/') /* eat extra /'s */
192 * Buf is empty, so therefore we are done
193 * with this level of file
199 for(i
= 0; i
< lev
; i
++)
203 * See what type of critter this file is
206 if(lstat(buf
, &stb
) == -1){
207 (void)printf(" ? %s - %s (%d)\n", buf
, ERR
);
211 switch(stb
.st_mode
& S_IFMT
){
215 * File is a directory, chdir to it
218 if(chdir(buf
) == -1){
219 (void)printf(_(" ? could not chdir into %s - %s (%d)\n"), buf
, ERR
);
222 if(xflag
&& lastdev
!= stb
.st_dev
&& lastdev
!= NODEV
){
223 /* Across mnt point */
225 (void)printf(" D%s %s\n", pperm(stb
.st_mode
), buf
);
227 (void)printf(" D %s\n", buf
);
231 (void)printf(" d%s %s\n", pperm(stb
.st_mode
), buf
);
233 (void)printf(" d %s\n", buf
);
235 lastdev
= stb
.st_dev
;
237 (void)fflush(stdout
);
242 * Sigh, another symlink. Read it's contents and
247 if(readlink(buf
, sym
, BUFSIZ
) == -1){
248 (void)printf(_(" ? problems reading symlink %s - %s (%d)\n"), buf
, ERR
);
253 (void)printf(" l%s %s -> %s", pperm(stb
.st_mode
), buf
, sym
);
255 (void)printf(" l %s -> %s", buf
, sym
);
257 if(symcount
> 0 && symcount
++ > MAXSYMLINKS
){
258 (void)printf(_(" *** EXCEEDED UNIX LIMIT OF SYMLINKS ***"));
267 (void)printf(" c%s %s\n", pperm(stb
.st_mode
), buf
);
269 (void)printf(" c %s\n", buf
);
274 (void)printf(" b%s %s\n", pperm(stb
.st_mode
), buf
);
276 (void)printf(" b %s\n", buf
);
281 (void)printf(" s%s %s\n", pperm(stb
.st_mode
), buf
);
283 (void)printf(" s %s\n", buf
);
288 (void)printf(" -%s %s\n", pperm(stb
.st_mode
), buf
);
290 (void)printf(" - %s\n", buf
);
294 (void)fprintf(stderr
,_("namei: unknown file type 0%06o on file %s\n"), stb
.st_mode
, buf
);
302 * Mode word, as from a struct stat, and return
303 * a pointer to a static string containing a printable version like ls.
304 * For example 0755 produces "rwxr-xr-x"
313 char *lschars
= "xwrxwrxwr"; /* the complete string backwards */
317 for(i
= 0, cp
= lschars
, m
= mode
, bp
= &buf
[8];
319 i
++, cp
++, m
>>= 1, bp
--) {