dosutils: use NCP87 DOS info fields in NDIR
Add a Client32 NCP87 helper for obtaining DOS namespace file and subdirectory information and use it in NDIR. The new helper reads the classic NCP87 subfunction 6 RIM_ALL DOS info block, including timestamps, inherited rights, directory identifiers and size metadata. Use the NCP87 inherited rights mask for the inherited-rights column while keeping the existing Client32 effective-rights path for the effective rights column. Also use the NCP87 modify, archive, last-access and creation date fields for the /DATES display, falling back to DOS findfirst timestamps when the NCP87 info request is not available. Tighten the /DATES layout so the full Created/Copied timestamp remains within an 80-column DOS screen.
This commit is contained in:
102
ndir.c
102
ndir.c
@@ -48,6 +48,7 @@
|
||||
#define NDIR_NCP_RIGHT_SUPER 0x0100
|
||||
|
||||
static void ndir_dos_date(unsigned date, char *out);
|
||||
static void ndir_dos_datetime(unsigned date, unsigned time, char *out);
|
||||
|
||||
#define NDIR_OLD_RIGHT_S 0x01
|
||||
#define NDIR_OLD_RIGHT_R 0x02
|
||||
@@ -207,6 +208,27 @@ static void ndir_dos_date(unsigned date, char *out)
|
||||
sprintf(out, "%02d-%02d-%02d", month, day, year % 100);
|
||||
}
|
||||
|
||||
static void ndir_dos_datetime_or_blank(unsigned date, unsigned time, char *out)
|
||||
{
|
||||
if (!date) {
|
||||
strcpy(out, "0-00-00 0:00 A");
|
||||
return;
|
||||
}
|
||||
|
||||
ndir_dos_datetime(date, time, out);
|
||||
}
|
||||
|
||||
static void ndir_dos_date_or_blank(unsigned date, char *out)
|
||||
{
|
||||
if (!date) {
|
||||
strcpy(out, "0-00-00");
|
||||
return;
|
||||
}
|
||||
|
||||
ndir_dos_date(date, out);
|
||||
}
|
||||
|
||||
|
||||
static void ndir_dos_datetime(unsigned date, unsigned time, char *out)
|
||||
{
|
||||
int year;
|
||||
@@ -296,6 +318,35 @@ static void ndir_old_rights_string(uint8 old_rights, char *out)
|
||||
out[8] = '\0';
|
||||
}
|
||||
|
||||
static int ndir_get_ncp_info(char *path, C32_NDIR_INFO *info)
|
||||
{
|
||||
uint8 connid = 0;
|
||||
uint8 dhandle = 0;
|
||||
|
||||
if (!info)
|
||||
return(1);
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
if (tool_current_dhandle(&connid, &dhandle))
|
||||
return(1);
|
||||
|
||||
return(c32_ncp87_obtain_ndir_info(tool_is_current_path(path) ? "" : path,
|
||||
(uint16)dhandle,
|
||||
info,
|
||||
NULL, NULL, NULL));
|
||||
}
|
||||
|
||||
static void ndir_inherited_rights(char *path, char *out)
|
||||
{
|
||||
C32_NDIR_INFO info;
|
||||
|
||||
strcpy(out, "--------");
|
||||
|
||||
if (!ndir_get_ncp_info(path, &info))
|
||||
ndir_old_rights_string((uint8)info.inherited_rights, out);
|
||||
}
|
||||
|
||||
static void ndir_rights_string(uint16 ncp_rights, char *out)
|
||||
{
|
||||
out[0] = (ncp_rights & NDIR_NCP_RIGHT_SUPER) ? 'S' : '-';
|
||||
@@ -371,28 +422,45 @@ static void ndir_print_file(char *dir, struct find_t *ff, int options,
|
||||
char fl[20]; /* [RW-A------------] plus NUL */
|
||||
char path[260];
|
||||
char eff[10];
|
||||
char inh[10];
|
||||
char arch[24];
|
||||
char acc[12];
|
||||
char crea[24];
|
||||
C32_NDIR_INFO info;
|
||||
int have_info = 0;
|
||||
|
||||
tool_join_path(path, dir, ff->name, sizeof(path));
|
||||
have_info = !ndir_get_ncp_info(path, &info);
|
||||
|
||||
if (have_info)
|
||||
ndir_dos_datetime(info.modify_date, info.modify_time, dt);
|
||||
else
|
||||
ndir_dos_datetime(ff->wr_date, ff->wr_time, dt);
|
||||
|
||||
ndir_dos_datetime(ff->wr_date, ff->wr_time, dt);
|
||||
ndir_dos_date(ff->wr_date, d);
|
||||
ndir_flags(ff->attrib, fl);
|
||||
|
||||
if (options & NDIR_OPT_RIGHTS) {
|
||||
tool_join_path(path, dir, ff->name, sizeof(path));
|
||||
ndir_effective_rights(path, eff);
|
||||
/*
|
||||
* We do not have the inherited-rights mask yet. Use the effective
|
||||
* rights in both columns for this first /RIGHTS implementation.
|
||||
*/
|
||||
ndir_inherited_rights(path, inh);
|
||||
fprintf(stdout, "%-16.16s %-18.18s [%8.8s] [%8.8s]\n",
|
||||
ff->name, fl, eff, eff);
|
||||
ff->name, fl, inh, eff);
|
||||
} else if (options & NDIR_OPT_DATES) {
|
||||
/*
|
||||
* DOS findfirst gives us the update timestamp only. Keep the Novell
|
||||
* /DATES layout and use placeholders for archive/access data until
|
||||
* full NetWare namespace date fields are available.
|
||||
*/
|
||||
fprintf(stdout, "%-16.16s %-17.17s 0-00-00 0:00 A %-8.8s %-17.17s\n",
|
||||
ff->name, dt, d, dt);
|
||||
if (have_info) {
|
||||
ndir_dos_datetime_or_blank(info.archive_date, info.archive_time, arch);
|
||||
ndir_dos_date_or_blank(info.last_access_date, acc);
|
||||
ndir_dos_datetime_or_blank(info.creation_date, info.creation_time, crea);
|
||||
fprintf(stdout, "%-16.16s %-17.17s %-17.17s %-8.8s %-17.17s\n",
|
||||
ff->name, dt, arch, acc, crea);
|
||||
} else {
|
||||
fprintf(stdout, "%-16.16s %-17.17s 0-00-00 0:00 A %-8.8s %-17.17s\n",
|
||||
ff->name, dt, d, dt);
|
||||
}
|
||||
} else {
|
||||
fprintf(stdout, "%-16.16s %12lu %-17.17s %-18.18s\n",
|
||||
ff->name, (unsigned long)ff->size, dt, fl);
|
||||
@@ -407,14 +475,20 @@ static void ndir_print_dir(char *dir, struct find_t *ff, int options,
|
||||
char dt[24];
|
||||
char path[260];
|
||||
char eff[10];
|
||||
char inh[10];
|
||||
C32_NDIR_INFO info;
|
||||
|
||||
ndir_dos_datetime(ff->wr_date, ff->wr_time, dt);
|
||||
tool_join_path(path, dir, ff->name, sizeof(path));
|
||||
if (!ndir_get_ncp_info(path, &info))
|
||||
ndir_dos_datetime(info.creation_date, info.creation_time, dt);
|
||||
else
|
||||
ndir_dos_datetime(ff->wr_date, ff->wr_time, dt);
|
||||
|
||||
if (options & (NDIR_OPT_RIGHTS | NDIR_OPT_DIRS_ONLY)) {
|
||||
tool_join_path(path, dir, ff->name, sizeof(path));
|
||||
ndir_effective_rights(path, eff);
|
||||
ndir_inherited_rights(path, inh);
|
||||
fprintf(stdout, "%-16.16s [%8.8s] [%8.8s] %-17.17s\n",
|
||||
ff->name, eff, eff, dt);
|
||||
ff->name, inh, eff, dt);
|
||||
} else {
|
||||
fprintf(stdout, "%-16.16s <DIR> %-17.17s\n", ff->name, dt);
|
||||
}
|
||||
@@ -499,8 +573,8 @@ static int ndir_list_one(char *spec, int options, int *continuous)
|
||||
fprintf(stdout, "Files: Flags Rights Rights Owner\n");
|
||||
fprintf(stdout, "---------------- ------------------ ----------- ----------- --------\n");
|
||||
} else if (options & NDIR_OPT_DATES) {
|
||||
fprintf(stdout, "Files: Last Updated Last Archived * Accessed Created/Copied\n");
|
||||
fprintf(stdout, "---------------- ----------------- ------------- -- -------- -----------------\n");
|
||||
fprintf(stdout, "Files: Last Updated Last Archived Accessed Created/Copied\n");
|
||||
fprintf(stdout, "---------------- ----------------- ----------------- -------- -----------------\n");
|
||||
} else {
|
||||
fprintf(stdout, "Files: Size Last Updated Flags Owner\n");
|
||||
fprintf(stdout, "---------------- ---------------- ----------------- ------------------ --------\n");
|
||||
|
||||
Reference in New Issue
Block a user