static int follow_symlinks(struct namei *nm) { int symcount = 0; for (; nm; nm = nm->next) { struct namei *next, *last; if (nm->noent) continue; if (!S_ISLNK(nm->st.st_mode)) continue; if (++symcount > MAXSYMLINKS) { /* drop the rest of the list */ free_namei(nm->next); nm->next = NULL; return -1; } next = nm->next; nm->next = add_namei(nm, nm->abslink, nm->relstart, &last); if (last) last->next = next; else nm->next = next; } return 0; }
int main(int argc, char **argv) { int c; int rc = EXIT_SUCCESS; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); atexit(close_stdout); while ((c = getopt_long(argc, argv, "hVlmnovx", longopts, NULL)) != -1) { switch(c) { case 'h': usage(EXIT_SUCCESS); break; case 'V': printf(UTIL_LINUX_VERSION); return EXIT_SUCCESS; case 'l': flags |= (NAMEI_OWNERS | NAMEI_MODES | NAMEI_VERTICAL); break; case 'm': flags |= NAMEI_MODES; break; case 'n': flags |= NAMEI_NOLINKS; break; case 'o': flags |= NAMEI_OWNERS; break; case 'x': flags |= NAMEI_MNTS; break; case 'v': flags |= NAMEI_VERTICAL; break; default: usage(EXIT_FAILURE); } } if (optind == argc) { warnx(_("pathname argument is missing")); usage(EXIT_FAILURE); } for(; optind < argc; optind++) { char *path = argv[optind]; struct namei *nm = NULL; struct stat st; if (stat(path, &st) != 0) rc = EXIT_FAILURE; nm = add_namei(NULL, path, 0, NULL); if (nm) { int sml = 0; if (!(flags & NAMEI_NOLINKS)) sml = follow_symlinks(nm); if (print_namei(nm, path)) { rc = EXIT_FAILURE; continue; } free_namei(nm); if (sml == -1) { rc = EXIT_FAILURE; warnx(_("%s: exceeded limit of symlinks"), path); continue; } } } free_idcache(ucache); free_idcache(gcache); return rc; }
int main(int argc, char **argv) { extern int optind; int c; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); if (argc < 2) usage(EXIT_FAILURE); while ((c = getopt_long(argc, argv, "+h?lmnovx", longopts, NULL)) != -1) { switch(c) { case 'h': case '?': usage(EXIT_SUCCESS); break; case 'l': flags |= (NAMEI_OWNERS | NAMEI_MODES | NAMEI_VERTICAL); break; case 'm': flags |= NAMEI_MODES; break; case 'n': flags |= NAMEI_NOLINKS; break; case 'o': flags |= NAMEI_OWNERS; break; case 'x': flags |= NAMEI_MNTS; break; case 'v': flags |= NAMEI_VERTICAL; } } for(; optind < argc; optind++) { char *path = argv[optind]; struct namei *nm = NULL; struct stat st; if (stat(path, &st) != 0) err(EXIT_FAILURE, _("failed to stat: %s"), path); nm = add_namei(NULL, path, 0, NULL); if (nm) { int sml = 0; if (!(flags & NAMEI_NOLINKS)) sml = follow_symlinks(nm); print_namei(nm, path); free_namei(nm); if (sml == -1) errx(EXIT_FAILURE, _("%s: exceeded limit of symlinks"), path); } } free_idcache(ucache); free_idcache(gcache); return EXIT_SUCCESS; }