static rc_t CC list_action (const KDirectory * dir, const char * path, void * _adata) { rc_t rc; list_adata * data; list_item * item; KPathType type; uint32_t access; uint64_t size; uint64_t loc; KTime_t mtime; size_t pathlen; size_t linklen; char link [2 * 4096]; /* we'll truncate? */ rc = 0; data = _adata; loc = size = 0; pathlen = strlen (path); type = KDirectoryPathType (dir, path); if (type & kptAlias) { rc = KDirectoryVResolveAlias (dir, false, link, sizeof (link), path, NULL); if (rc == 0) linklen = strlen (link); } else { linklen = 0; switch (type & ~kptAlias) { case kptNotFound: rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcNotFound); break; case kptBadPath: rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcInvalid); break; case kptZombieFile: if ( ! long_list ) return 0; data->has_zombies = true; case kptFile: rc = KDirectoryFileSize (dir, &size, path); if (rc == 0) { if (size > data->max_size) data->max_size = size; rc = KDirectoryFileLocator (dir, &loc, path); if ((rc == 0) && (loc > data->max_loc)) data->max_loc = loc; } break; case kptDir: break; case kptCharDev: case kptBlockDev: case kptFIFO: /* shouldn't get here */ return 0; } } if (rc == 0) { rc = KDirectoryAccess (dir, &access, "%s", path); if (rc == 0) { rc = KDirectoryDate (dir, &mtime, "%s", path); if (rc == 0) { item = malloc (sizeof (*item) + pathlen + linklen + 2); /* usually one too many */ if (item == NULL) { rc = RC (rcExe, rcNoTarg, rcAllocating, rcMemory, rcExhausted); } else { item->type = type; item->access = access; item->size = size; item->loc = loc; item->mtime = mtime; item->path = (char *)(item+1); strcpy (item->path, path); if (type & kptAlias) { item->link = item->path + pathlen + 1; strcpy (item->link, link); } else item->link = NULL; DLListPushHead (&data->list, &item->dad); if (type == kptDir) rc = step_through_dir (dir, path, data->filter, data->fdata, list_action, data); } } } } return rc; }
static int CC sort_pathpath_cmp (const void ** litem, const void ** ritem, void * data) { uint64_t lloc, rloc; { const VPath * lpath; size_t z; rc_t rc; char pbuff [8192]; lpath = *litem; rc = VPathReadPath (lpath, pbuff, sizeof pbuff, &z); if (rc == 0) { switch (KDirectoryPathType (options.base, "%s", pbuff)) { default: lloc = 0; break; case kptFile: rc = KDirectoryFileLocator (options.base, &lloc, "%s", pbuff); break; } if (rc == 0) { const VPath * rpath; rpath = *ritem; rc = VPathReadPath (rpath, pbuff, sizeof pbuff, &z); if (rc == 0) { switch (KDirectoryPathType (options.base, "%s", pbuff)) { default: rloc = 0; break; case kptFile: rc = KDirectoryFileLocator (options.base, &rloc, "%s", pbuff); break; } } } } if (rc) /* surrender */ lloc = rloc = 0; } { int cmp; if (lloc < rloc) cmp = -1; else if (lloc > rloc) cmp = 1; else { assert (lloc == rloc); cmp = 0; }; return cmp; } }
/* ---------------------------------------------------------------------- */ static rc_t walk_path_file (char * path, size_t z, uint64_t * offset, KPathType kpt) { uint64_t this_offset; char * pc; rc_t rc; assert (path); assert (offset); this_offset = 0; rc = 0; if (kpt == kptFile) { rc = KDirectoryFileLocator (options.base, &this_offset, "%s", path); if (rc) PLOGERR (klogErr, (klogErr, rc, "failure walking path '$(P)'", "P=%s", path)); } if (rc == 0) { pc = string_rchr (path, z, '/'); if (pc) { uint64_t that_offset; KPathType lkpt; *pc = '\0'; lkpt = KDirectoryPathType (options.base, "%s", path); switch (lkpt) { default: rc = RC (rcExe, rcPath, rcAccessing, rcPath, rcInvalid); break; case kptNotFound: case kptZombieFile: rc = RC (rcExe, rcPath, rcAccessing, rcPath, rcNotFound); break; case kptBadPath: rc = RC (rcExe, rcPath, rcAccessing, rcPath, rcInvalid); break; case kptFile: case kptDir: /* we should always hit here */ rc = walk_path_file (path, z, &that_offset, lkpt); if (rc == 0) { this_offset += that_offset; } break; case kptCharDev: case kptBlockDev: case kptFIFO: rc = RC (rcExe, rcPath, rcAccessing, rcPath, rcIncorrect); break; } *pc = '/'; } } *offset = this_offset; return rc; }
static rc_t list_action (const KDirectory * dir, const char * path, void * _adata) { rc_t rc = 0; list_adata * data = _adata; list_item * item = NULL; KPathType type = KDirectoryPathType (dir, "%s", path); size_t pathlen = strlen (path); size_t linklen = 0; char link [2 * 4096]; /* we'll truncate? */ if (type & kptAlias) { rc = KDirectoryVResolveAlias (dir, false, link, sizeof (link), path, NULL); if (rc == 0) linklen = strlen (link); } if (rc == 0) { item = calloc (sizeof (*item) + pathlen + linklen + 2, 1); /* usually one too many */ if (item == NULL) { rc = RC (rcExe, rcNoTarg, rcAllocating, rcMemory, rcExhausted); } else { do { item->path = (char *)(item+1); strcpy (item->path, path); item->type = type; rc = KDirectoryAccess (dir, &item->access, "%s", path); if (rc) break; rc = KDirectoryDate (dir, &item->mtime, "%s", path); if (rc) break; if (type & kptAlias) { item->link = item->path + pathlen + 1; strcpy (item->link, link); } else switch (type & ~kptAlias) { case kptNotFound: rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcNotFound); break; case kptBadPath: rc = RC (rcExe, rcDirectory, rcAccessing, rcPath, rcInvalid); break; case kptZombieFile: data->has_zombies = true; case kptFile: rc = KDirectoryFileSize (dir, &item->size, "%s", path); if (rc == 0) rc = KDirectoryFileLocator (dir, &item->loc, "%s", path); DBGMSG (DBG_APP, 1, ("%s: found file %s size %lu at %lu\n", __func__, item->path, item->size, item->loc)); break; case kptDir: DBGMSG (DBG_APP, 1, ("%s: found directory %s\n", __func__, item->path)); break; default: DBGMSG (DBG_APP, 1, ("%s: found unknown %s\n", __func__, item->path)); break; } } while (0); } } if (rc == 0) { VectorAppend (&data->list, NULL, item); VectorInsert (&data->sort, item, NULL, list_item_cmp); if (type == kptDir) rc = step_through_dir (dir, path, list_action, data); } return rc; }