]>
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@pld.ORG.PL>
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
,
102 _("namei: unable to get current directory - %s\n"),
108 for(; optind
< argc
; optind
++){
109 (void)printf("f: %s\n", argv
[optind
]);
111 namei(argv
[optind
], 0);
113 if(chdir(curdir
) == -1){
114 (void)fprintf(stderr
,
115 _("namei: unable to chdir to %s - %s (%d)\n"),
125 (void)fprintf(stderr
,_("usage: namei [-mx] pathname [pathname ...]\n"));
130 #define NODEV (dev_t)(-1)
134 namei(char *file
, int lev
) {
136 char buf
[BUFSIZ
], sym
[BUFSIZ
];
139 dev_t lastdev
= NODEV
;
142 * See if the file has a leading /, and if so cd to root
149 if(chdir("/") == -1){
150 (void)fprintf(stderr
,_("namei: could not chdir to root!\n"));
153 for(i
= 0; i
< lev
; i
++)
156 if(stat("/", &stb
) == -1){
157 (void)fprintf(stderr
, _("namei: could not stat root!\n"));
160 lastdev
= stb
.st_dev
;
163 (void)printf(" d%s /\n", pperm(stb
.st_mode
));
165 (void)printf(" d /\n");
170 if (strlen(file
) >= BUFSIZ
) {
171 fprintf(stderr
,_("namei: buf overflow\n"));
176 * Copy up to the next / (or nil) into buf
179 for(cp
= buf
; *file
!= '\0' && *file
!= '/'; cp
++, file
++)
182 while(*file
== '/') /* eat extra /'s */
190 * Buf is empty, so therefore we are done
191 * with this level of file
197 for(i
= 0; i
< lev
; i
++)
201 * See what type of critter this file is
204 if(lstat(buf
, &stb
) == -1){
205 (void)printf(" ? %s - %s (%d)\n", buf
, ERR
);
209 switch(stb
.st_mode
& S_IFMT
){
213 * File is a directory, chdir to it
216 if(chdir(buf
) == -1){
217 (void)printf(_(" ? could not chdir into %s - %s (%d)\n"), buf
, ERR
);
220 if(xflag
&& lastdev
!= stb
.st_dev
&& lastdev
!= NODEV
){
221 /* Across mnt point */
223 (void)printf(" D%s %s\n", pperm(stb
.st_mode
), buf
);
225 (void)printf(" D %s\n", buf
);
229 (void)printf(" d%s %s\n", pperm(stb
.st_mode
), buf
);
231 (void)printf(" d %s\n", buf
);
233 lastdev
= stb
.st_dev
;
235 (void)fflush(stdout
);
240 * Sigh, another symlink. Read its contents and
245 if(readlink(buf
, sym
, BUFSIZ
) == -1){
246 (void)printf(_(" ? problems reading symlink %s - %s (%d)\n"), buf
, ERR
);
251 (void)printf(" l%s %s -> %s", pperm(stb
.st_mode
), buf
, sym
);
253 (void)printf(" l %s -> %s", buf
, sym
);
255 if(symcount
> 0 && symcount
++ > MAXSYMLINKS
){
256 (void)printf(_(" *** EXCEEDED UNIX LIMIT OF SYMLINKS ***\n"));
266 (void)printf(" c%s %s\n", pperm(stb
.st_mode
), buf
);
268 (void)printf(" c %s\n", buf
);
273 (void)printf(" b%s %s\n", pperm(stb
.st_mode
), buf
);
275 (void)printf(" b %s\n", buf
);
280 (void)printf(" s%s %s\n", pperm(stb
.st_mode
), buf
);
282 (void)printf(" s %s\n", buf
);
287 (void)printf(" -%s %s\n", pperm(stb
.st_mode
), buf
);
289 (void)printf(" - %s\n", buf
);
293 (void)fprintf(stderr
,_("namei: unknown file type 0%06o on file %s\n"), stb
.st_mode
, buf
);
301 * Mode word, as from a struct stat, and return
302 * a pointer to a static string containing a printable version like ls.
303 * For example 0755 produces "rwxr-xr-x"
306 pperm(unsigned short mode
) {
310 char *lschars
= "xwrxwrxwr"; /* the complete string backwards */
314 for(i
= 0, cp
= lschars
, m
= mode
, bp
= &buf
[8];
316 i
++, cp
++, m
>>= 1, bp
--) {