Lines Matching refs:fts

28  * fts implementation unwound from the kpv ftwalk() of 1988-10-30
95 #include <fts.h>
177 node(FTS* fts, FTSENT* parent, register char* name, register size_t namelen)
182 if (fts->free && namelen < MINNAME)
184 f = fts->free;
185 fts->free = f->fts_link;
192 fts->fts_errno = errno;
193 fts->state = FTS_error;
196 f->fts = fts;
460 popdirs(FTS* fts)
471 if (!(f = fts->curdir) || f->fts_level < 0)
477 while (fts->nd > 0)
479 for (s = buf; s < e && fts->nd > 0; fts->nd--)
481 if (fts->pwd)
484 verify |= fts->pwd->symlink;
486 fts->pwd = fts->pwd->pwd;
504 info(FTS* fts, register FTSENT* f, const char* path, struct stat* sp, int flags)
524 if ((flags & FTS_NOSTAT) && !fts->fs3d)
578 * to give caller a chance to set fts->handle
582 toplist(FTS* fts, register char* const* pathnames)
593 if (fts->flags & FTS_NOSEEDOTDIR)
594 fts->flags &= ~FTS_SEEDOTDIR;
595 physical = (fts->flags & FTS_PHYSICAL);
596 metaphysical = (fts->flags & (FTS_META|FTS_PHYSICAL)) == (FTS_META|FTS_PHYSICAL);
604 if (!(f = node(fts, fts->parent, path, strlen(path))))
608 f->fts_namelen = (fts->flags & FTS_SEEDOTDIR) ? strlen(path) : (pathcanon(path, strlen(path) + 1, 0) - path);
612 fts->flags |= FTS_SEEDOTDIR;
616 if (fts->flags & FTS_NOSEEDOTDIR)
618 fts->flags &= ~FTS_SEEDOTDIR;
632 fts->flags |= FTS_SEEDOTDIR;
646 info(fts, f, path, f->fts_statp, fts->flags);
657 info(fts, f, NiL, f->fts_statp, 0);
672 * order fts->todo if fts->comparf != 0
676 order(FTS* fts)
684 for (f = fts->todo; f; f = f->fts_link)
685 root = search(f, root, fts->comparf, 1);
687 fts->todo = top;
692 * note that free() is not used because we may need to chdir(fts->home)
697 resize(register FTS* fts, size_t inc)
707 n_old = fts->homesize;
708 fts->homesize = ((fts->homesize + inc + 4) / PATH_MAX + 1) * PATH_MAX;
709 if (!(newp = newof(0, char, fts->homesize, 0)))
711 fts->fts_errno = errno;
712 fts->state = FTS_error;
715 old = fts->home;
716 fts->home = newp;
718 if (fts->endbuf)
719 fts->endbuf = newp + fts->homesize - 4;
720 if (fts->path)
721 fts->path = newp + (fts->path - old);
722 if (fts->base)
723 fts->base = newp + (fts->base - old);
729 * open a new fts stream on pathnames
735 register FTS* fts;
737 if (!(fts = newof(0, FTS, 1, sizeof(FTSENT))))
739 fts->flags = flags;
740 fts->cd = (flags & FTS_NOCHDIR) ? 1 : -1;
741 fts->comparf = comparf;
742 fts->fs3d = fs3d(FS3D_TEST);
748 fts->homesize = 2 * PATH_MAX;
751 if (!(fts->home = newof(fts->home, char, fts->homesize, 0)))
753 free(fts);
756 if (fts->cd > 0 || getcwd(fts->home, fts->homesize))
759 fts->homesize += PATH_MAX;
761 fts->cd = 1;
763 fts->endbuf = fts->home + fts->homesize - 4;
769 fts->parent = (FTSENT*)(fts + 1);
770 fts->parent->fts_info = FTS_D;
771 memcpy(fts->parent->fts_accpath = fts->parent->fts_path = fts->parent->fts_name = fts->parent->name, ".", 2);
772 fts->parent->fts_level = -1;
774 fts->parent->_fts_level = (short)fts->parent->fts_level;
776 fts->parent->fts_statp = &fts->parent->statb;
777 fts->parent->must = 2;
778 fts->parent->type = DT_UNKNOWN;
779 fts->path = fts->home + strlen(fts->home) + 1;
791 fts->todo = toplist(fts, v);
794 fts->todo = toplist(fts, pathnames);
796 if (!fts->todo || fts->todo->fts_info == FTS_NS && !fts->todo->fts_link)
798 if (!fts->todo)
801 fts_close(fts);
804 return fts;
812 fts_read(register FTS* fts)
826 switch (fts->state)
831 f = fts->todo;
839 drop(fts, f);
844 fts->todo = f->fts_link;
845 drop(fts, f);
846 f = fts->todo;
858 if (!fts->state && fts->comparf)
859 order(fts);
860 if (!(f = fts->todo))
870 fts->root = fts->top = fts->bot = 0;
878 fts->parent->fts_number = f->fts_number;
879 fts->parent->fts_pointer = f->fts_pointer;
880 fts->parent->fts_statp = f->fts_statp;
881 fts->parent->statb = *f->fts_statp;
882 f->fts_parent = fts->parent;
883 fts->diroot = 0;
884 if (fts->cd == 0)
885 pathcd(fts->home, NiL);
886 else if (fts->cd < 0)
887 fts->cd = 0;
888 fts->pwd = f->fts_parent;
889 fts->curdir = fts->cd ? 0 : f->fts_parent;
890 *(fts->base = fts->path) = 0;
897 if (fts->cd < 0)
899 fts->cd = setdir(fts->home, fts->path);
900 fts->pwd = f->fts_parent;
901 fts->curdir = fts->cd ? 0 : f->fts_parent;
908 if ((fts->baselen = f->fts_namelen) >= (fts->endbuf - fts->base) && resize(fts, fts->baselen))
910 memcpy(fts->base, f->name, fts->baselen + 1);
911 fts->name = fts->cd ? fts->path : fts->base;
922 if ((fts->diroot = search(f, fts->diroot, statcmp, 0)) != f || f->fts_level > 0 && (t = f) && statcmp(&t, &f->fts_parent) == 0)
925 f->fts_cycle = fts->diroot;
927 else if (!(fts->flags & FTS_TOP) && (!(fts->flags & FTS_XDEV) || f->statb.st_dev == f->fts_parent->statb.st_dev))
933 if (fts->base[fts->baselen - 1] != '/')
934 memcpy(fts->base + fts->baselen, "/.", 3);
935 if (!(fts->dir = opendir(fts->name)))
937 fts->base[fts->baselen] = 0;
938 if (!fts->dir && !(fts->dir = opendir(fts->name)))
943 if (f->nd || !(fts->flags & FTS_NOPREORDER))
945 fts->current = f;
946 fts->link = f->fts_link;
948 f->fts_path = PATH(fts, fts->path, f->fts_level);
949 f->fts_pathlen = (fts->base - f->fts_path) + fts->baselen;
950 f->fts_accpath = ACCESS(fts, f);
951 fts->state = FTS_preorder_return;
962 if (!fts->dir || f->nd || f->status == FTS_SKIP)
964 if (fts->dir)
966 closedir(fts->dir);
967 fts->dir = 0;
969 fts->state = FTS_popstack;
977 if (fts->cd == 0)
979 if ((fts->cd = chdir(fts->name)) < 0)
980 pathcd(fts->home, NiL);
981 else if (fts->pwd != f)
983 f->pwd = fts->pwd;
984 fts->pwd = f;
986 fts->curdir = fts->cd < 0 ? 0 : f;
988 fts->nostat = fts->children > 1 || f->fts_info == FTS_DNX;
989 fts->cpname = fts->cd && !fts->nostat || !fts->children && !fts->comparf;
990 fts->dotdot = 0;
991 fts->endbase = fts->base + fts->baselen;
992 if (fts->endbase[-1] != '/')
993 *fts->endbase++ = '/';
994 fts->current = f;
999 while (d = readdir(fts->dir))
1006 fts->current->nlink--;
1007 if (!(fts->flags & FTS_SEEDOT))
1013 fts->current->nlink--;
1014 if (fts->current->must == 1)
1015 fts->current->must = 0;
1016 if (!(fts->flags & FTS_SEEDOT))
1031 if (!(f = node(fts, fts->current, s, i)))
1039 if (i >= fts->endbuf - fts->endbase)
1041 if (resize(fts, i))
1043 fts->endbase = fts->base + fts->baselen;
1044 if (fts->endbase[-1] != '/')
1045 fts->endbase++;
1047 if (fts->cpname)
1049 memcpy(fts->endbase, s, i + 1);
1050 if (fts->cd)
1051 s = fts->path;
1060 f->fts_statp = fts->current->fts_statp;
1064 fts->dotdot = f;
1065 if (fts->current->fts_parent->fts_level < 0)
1067 f->fts_statp = &fts->current->fts_parent->statb;
1068 info(fts, f, s, f->fts_statp, 0);
1071 f->fts_statp = fts->current->fts_parent->fts_statp;
1075 else if ((fts->nostat || SKIP(fts, f)) && (f->fts_info = FTS_NSOK) || info(fts, f, s, &f->statb, fts->flags))
1077 if (fts->comparf)
1078 fts->root = search(f, fts->root, fts->comparf, 1);
1079 else if (fts->children || f->fts_info == FTS_D || f->fts_info == FTS_SL)
1081 if (fts->top)
1082 fts->bot = fts->bot->fts_link = f;
1084 fts->top = fts->bot = f;
1092 f->fts_path = PATH(fts, fts->path, 1);
1093 f->fts_pathlen = fts->endbase - f->fts_path + f->fts_namelen;
1094 f->fts_accpath = ACCESS(fts, f);
1095 fts->previous = fts->current;
1096 fts->current = f;
1097 fts->state = FTS_terminal;
1106 closedir(fts->dir);
1107 fts->dir = 0;
1108 if (fts->root)
1109 getlist(&fts->top, &fts->bot, fts->root);
1110 if (fts->children)
1116 fts->base[fts->baselen] = 0;
1117 if (fts->cd <= 0)
1119 f = fts->current->fts_parent;
1120 if (fts->cd < 0
1121 || f != fts->curdir
1122 || !fts->dotdot
1123 || !SAME(f->fts_statp, fts->dotdot->fts_statp)
1124 || fts->pwd && fts->pwd->symlink
1125 || (fts->cd = chdir("..")) < 0
1128 || !SAME(&sb, fts->dotdot->fts_statp)
1131 fts->cd = setpdir(fts->home, fts->path, fts->base);
1132 if (fts->pwd)
1133 fts->pwd = fts->pwd->pwd;
1134 fts->curdir = fts->cd ? 0 : f;
1136 f = fts->current;
1137 fts->link = f->fts_link;
1138 f->fts_link = fts->top;
1139 f->fts_path = PATH(fts, fts->path, f->fts_level);
1140 f->fts_pathlen = (fts->base - f->fts_path) + f->fts_namelen;
1141 f->fts_accpath = ACCESS(fts, f);
1142 fts->state = FTS_children_return;
1149 fts->base[fts->baselen] = 0;
1150 if (fts->top)
1152 fts->bot->fts_link = fts->todo;
1153 fts->todo = fts->top;
1154 fts->top = 0;
1164 fts->nd = 0;
1165 f = fts->current;
1170 while (fts->todo && f == fts->todo)
1179 if (f != fts->diroot)
1180 fts->diroot = search(f, fts->diroot, statcmp, 0);
1181 fts->diroot = deleteroot(fts->diroot);
1182 if (f == fts->curdir)
1184 fts->nd++;
1185 fts->curdir = t;
1192 if (!(fts->flags & FTS_NOPOSTORDER) &&
1200 if (fts->nd > 0)
1201 fts->cd = popdirs(fts);
1202 if (fts->cd < 0)
1203 fts->cd = setpdir(fts->home, fts->path, fts->base);
1204 fts->curdir = fts->cd ? 0 : t;
1206 f->fts_path = PATH(fts, fts->path, f->fts_level);
1207 f->fts_pathlen = (fts->base - f->fts_path) + f->fts_namelen;
1208 f->fts_accpath = ACCESS(fts, f);
1215 fts->link = f->fts_link;
1217 fts->state = FTS_popstack_return;
1226 if (fts->base > fts->path + t->fts_namelen)
1227 fts->base--;
1228 *fts->base = 0;
1229 fts->base -= t->fts_namelen;
1242 fts->todo = fts->todo->fts_link;
1243 drop(fts, f);
1252 if (fts->nd > 0 && popdirs(fts) < 0)
1254 pathcd(fts->home, NiL);
1255 fts->curdir = 0;
1256 fts->cd = -1;
1258 if (fts->todo)
1260 if (*fts->base)
1261 fts->base += f->fts_namelen;
1262 if (*(fts->base - 1) != '/')
1263 *fts->base++ = '/';
1264 *fts->base = 0;
1265 f = fts->todo;
1266 fts->state = FTS_todo;
1273 f = fts->current;
1274 f->fts_link = fts->link;
1282 if (!n && fts->cd == 0)
1284 if ((fts->cd = chdir(fts->base)) < 0)
1285 pathcd(fts->home, NiL);
1286 else if (fts->pwd != f)
1288 f->pwd = fts->pwd;
1289 fts->pwd = f;
1291 fts->curdir = fts->cd ? 0 : f;
1298 if (fts->base[fts->baselen - 1] != '/')
1299 fts->base[fts->baselen] = '/';
1300 for (fts->bot = 0, f = fts->top; f; )
1303 if (fts->bot)
1304 fts->bot->fts_link = f->fts_link;
1306 fts->top = f->fts_link;
1307 drop(fts, f);
1308 f = fts->bot ? fts->bot->fts_link : fts->top;
1312 if (fts->children > 1 && i)
1315 info(fts, f, NiL, f->fts_statp, 0);
1316 else if (f->fts_info == FTS_NSOK && !SKIP(fts, f))
1319 if (fts->cd)
1321 memcpy(fts->endbase, s, f->fts_namelen + 1);
1322 s = fts->path;
1324 info(fts, f, s, f->fts_statp, fts->flags);
1327 fts->bot = f;
1330 fts->children = 0;
1331 fts->state = FTS_children_resume;
1336 f = fts->todo;
1337 f->fts_link = fts->link;
1339 fts->state = FTS_popstack_resume;
1344 f = fts->current;
1345 f->fts_link = fts->link;
1356 info(fts, f, f->fts_accpath, f->fts_statp, 0);
1359 fts->state = FTS_preorder;
1369 if (fts->cd == 0 && f->fts_level == 0 && f->nd)
1370 fts->cd = -1;
1371 fts->state = FTS_preorder_resume;
1376 f = fts->current;
1382 info(fts, f, f->fts_accpath, f->fts_statp, 0);
1385 if (!(f->fts_link = fts->top))
1386 fts->bot = f;
1387 fts->top = f;
1388 fts->current = fts->previous;
1389 fts->state = FTS_readdir;
1395 drop(fts, fts->current);
1396 fts->current = f;
1397 fts->state = FTS_readdir;
1406 fts->fts_errno = EINVAL;
1407 fts->state = FTS_error;
1416 if ((n = (*p->notifyf)(fts, f, p->context)) > 0)
1420 fts->fts_errno = EINVAL;
1421 fts->state = FTS_error;
1432 fts_set(register FTS* fts, register FTSENT* f, int status)
1434 if (fts || !f || f->fts->current != f)
1462 fts_children(register FTS* fts, int flags)
1466 switch (fts->state)
1471 if (fts->comparf)
1472 order(fts);
1473 fts->state = FTS_top_return;
1474 return fts->todo;
1478 fts->children = ((flags | fts->flags) & FTS_NOSTAT) ? 2 : 1;
1479 if (f = fts_read(fts))
1522 * close an open fts stream
1526 fts_close(register FTS* fts)
1531 if (fts->dir)
1532 closedir(fts->dir);
1533 if (fts->cd == 0)
1534 pathcd(fts->home, NiL);
1535 free(fts->home);
1536 if (fts->state == FTS_children_return)
1537 fts->current->fts_link = fts->link;
1538 if (fts->top)
1540 fts->bot->fts_link = fts->todo;
1541 fts->todo = fts->top;
1543 for (f = fts->todo; f; f = x)
1548 for (f = fts->free; f; f = x)
1553 free(fts);