]>
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 -------------------------------------------------------------*/
53 #include <sys/types.h>
55 #include <sys/param.h>
58 #define ERR strerror(errno),errno
65 #define MAXSYMLINKS 256
68 static char *pperm(unsigned short);
69 static void namei(char *, int);
70 static void usage(void);
73 main(int argc
, char **argv
) {
76 char curdir
[MAXPATHLEN
];
78 setlocale(LC_ALL
, "");
79 bindtextdomain(PACKAGE
, LOCALEDIR
);
85 while((c
= getopt(argc
, argv
, "mx")) != -1){
101 if(getcwd(curdir
, sizeof(curdir
)) == NULL
){
102 (void)fprintf(stderr
,
103 _("namei: unable to get current directory - %s\n"),
109 for(; optind
< argc
; optind
++){
110 (void)printf("f: %s\n", argv
[optind
]);
112 namei(argv
[optind
], 0);
114 if(chdir(curdir
) == -1){
115 (void)fprintf(stderr
,
116 _("namei: unable to chdir to %s - %s (%d)\n"),
126 (void)fprintf(stderr
,_("usage: namei [-mx] pathname [pathname ...]\n"));
131 #define NODEV (dev_t)(-1)
135 namei(char *file
, int lev
) {
137 char buf
[BUFSIZ
], sym
[BUFSIZ
];
140 dev_t lastdev
= NODEV
;
143 * See if the file has a leading /, and if so cd to root
150 if(chdir("/") == -1){
151 (void)fprintf(stderr
,_("namei: could not chdir to root!\n"));
154 for(i
= 0; i
< lev
; i
++)
157 if(stat("/", &stb
) == -1){
158 (void)fprintf(stderr
, _("namei: could not stat root!\n"));
161 lastdev
= stb
.st_dev
;
164 (void)printf(" d%s /\n", pperm(stb
.st_mode
));
166 (void)printf(" d /\n");
171 if (strlen(file
) >= BUFSIZ
) {
172 fprintf(stderr
,_("namei: buf overflow\n"));
177 * Copy up to the next / (or nil) into buf
180 for(cp
= buf
; *file
!= '\0' && *file
!= '/'; cp
++, file
++)
183 while(*file
== '/') /* eat extra /'s */
191 * Buf is empty, so therefore we are done
192 * with this level of file
198 for(i
= 0; i
< lev
; i
++)
202 * See what type of critter this file is
205 if(lstat(buf
, &stb
) == -1){
206 (void)printf(" ? %s - %s (%d)\n", buf
, ERR
);
210 switch(stb
.st_mode
& S_IFMT
){
214 * File is a directory, chdir to it
217 if(chdir(buf
) == -1){
218 (void)printf(_(" ? could not chdir into %s - %s (%d)\n"), buf
, ERR
);
221 if(xflag
&& lastdev
!= stb
.st_dev
&& lastdev
!= NODEV
){
222 /* Across mnt point */
224 (void)printf(" D%s %s\n", pperm(stb
.st_mode
), buf
);
226 (void)printf(" D %s\n", buf
);
230 (void)printf(" d%s %s\n", pperm(stb
.st_mode
), buf
);
232 (void)printf(" d %s\n", buf
);
234 lastdev
= stb
.st_dev
;
236 (void)fflush(stdout
);
241 * Sigh, another symlink. Read its contents and
246 if(readlink(buf
, sym
, BUFSIZ
) == -1){
247 (void)printf(_(" ? problems reading symlink %s - %s (%d)\n"), buf
, ERR
);
252 (void)printf(" l%s %s -> %s", pperm(stb
.st_mode
), buf
, sym
);
254 (void)printf(" l %s -> %s", buf
, sym
);
256 if(symcount
> 0 && symcount
++ > MAXSYMLINKS
){
257 (void)printf(_(" *** EXCEEDED UNIX LIMIT OF SYMLINKS ***\n"));
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"
307 pperm(unsigned short mode
) {
311 char *lschars
= "xwrxwrxwr"; /* the complete string backwards */
315 for(i
= 0, cp
= lschars
, m
= mode
, bp
= &buf
[8];
317 i
++, cp
++, m
>>= 1, bp
--) {