Add GPL-2-or-later license headers to the DOS utility source files and document the purpose and local dependencies of each C, header and assembler file. Preserve the original Martin Stover copyright attribution for the historic MARS-NWE utility sources, including files that did not previously carry an explicit header but are part of the original tool set. Add Mario Fetka as the 2026 copyright holder for the current maintenance work, and use Mario-only headers for files without original Martin Stover ownership. Also add a root-level COPYING file containing the GPL-2 license text.
622 lines
16 KiB
C
622 lines
16 KiB
C
/*
|
|
* mars-nwe-dosutils - NetWare/DOS utility tools.
|
|
*
|
|
* Copyright (C) 2026 Mario Fetka
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* Purpose: CREATOR utility for showing and changing NetWare file creator/owner metadata.
|
|
* Depends on: net.h, c32ncp.h, netcall.c requester helpers, c32ncp.c namespace/NCP helpers, tools.c shared utility routines.
|
|
*/
|
|
/* creator.c - friendly creator/modifier/archiver metadata test tool
|
|
*
|
|
* Uses the same NCP 22/25 Set Directory/File Information path as Novell
|
|
* FILER for the special fileinfo/archive metadata fields. This is intended
|
|
* for testing mars_nwe xattr-backed metadata without using the FILER GUI.
|
|
*/
|
|
|
|
#include "net.h"
|
|
#include "c32ncp.h"
|
|
|
|
#define DM_CREATE_DATE 0x00000004UL
|
|
#define DM_CREATE_TIME 0x00000008UL
|
|
#define DM_CREATOR_ID 0x00000010UL
|
|
#define DM_ARCHIVE_DATE 0x00000020UL
|
|
#define DM_ARCHIVE_TIME 0x00000040UL
|
|
#define DM_ARCHIVER_ID 0x00000080UL
|
|
#define DM_MODIFY_DATE 0x00000100UL
|
|
#define DM_MODIFY_TIME 0x00000200UL
|
|
#define DM_MODIFIER_ID 0x00000400UL
|
|
|
|
#define BINDERY_USER 0x0001
|
|
#define BINDERY_GROUP 0x0002
|
|
|
|
#ifndef _A_RDONLY
|
|
#define _A_RDONLY 0x01
|
|
#endif
|
|
#ifndef _A_HIDDEN
|
|
#define _A_HIDDEN 0x02
|
|
#endif
|
|
#ifndef _A_SYSTEM
|
|
#define _A_SYSTEM 0x04
|
|
#endif
|
|
#ifndef _A_SUBDIR
|
|
#define _A_SUBDIR 0x10
|
|
#endif
|
|
#ifndef _A_ARCH
|
|
#define _A_ARCH 0x20
|
|
#endif
|
|
|
|
#define CREATOR_ATTR_RENAME_INHIBIT 0x00020000UL
|
|
#define CREATOR_ATTR_DELETE_INHIBIT 0x00040000UL
|
|
|
|
#define CREATOR_RIGHT_S 0x01
|
|
#define CREATOR_RIGHT_R 0x02
|
|
#define CREATOR_RIGHT_W 0x04
|
|
#define CREATOR_RIGHT_C 0x08
|
|
#define CREATOR_RIGHT_E 0x10
|
|
#define CREATOR_RIGHT_M 0x20
|
|
#define CREATOR_RIGHT_F 0x40
|
|
#define CREATOR_RIGHT_A 0x80
|
|
|
|
static void creator_usage(void)
|
|
{
|
|
fprintf(stdout, "Usage:\n");
|
|
fprintf(stdout, " CREATOR file /SHOW\n");
|
|
fprintf(stdout, " CREATOR file /CREATOR user-or-hexid\n");
|
|
fprintf(stdout, " CREATOR file /MODIFIER user-or-hexid\n");
|
|
fprintf(stdout, " CREATOR file /ARCHIVER user-or-hexid\n");
|
|
fprintf(stdout, " CREATOR file /CREATE user-or-hexid [yyyy-mm-dd [hh:mm:ss]]\n");
|
|
fprintf(stdout, " CREATOR file /MODIFY user-or-hexid [yyyy-mm-dd [hh:mm:ss]]\n");
|
|
fprintf(stdout, " CREATOR file /ARCHIVE user-or-hexid [yyyy-mm-dd [hh:mm:ss]]\n");
|
|
fprintf(stdout, " CREATOR file /ALL user-or-hexid [yyyy-mm-dd [hh:mm:ss]]\n");
|
|
fprintf(stdout, "\n");
|
|
fprintf(stdout, "Examples:\n");
|
|
fprintf(stdout, " CREATOR F:\\CIXTEST\\SUP\\S_SUP.TXT /SHOW\n");
|
|
fprintf(stdout, " CREATOR F:\\CIXTEST\\SUP\\S_SUP.TXT /CREATOR MARIO\n");
|
|
fprintf(stdout, " CREATOR F:\\CIXTEST\\SUP\\S_SUP.TXT /ARCHIVE MARIO\n");
|
|
}
|
|
|
|
static int creator_get_current_drive(void)
|
|
{
|
|
REGS regs;
|
|
|
|
regs.h.ah = 0x19;
|
|
int86(0x21, ®s, ®s);
|
|
return((int)regs.h.al);
|
|
}
|
|
|
|
static int creator_current_dhandle(uint8 *dhandle)
|
|
{
|
|
uint8 connid = 0;
|
|
uint8 flags = 0;
|
|
int drive;
|
|
|
|
drive = creator_get_current_drive();
|
|
if (get_drive_info((uint8)drive, &connid, dhandle, &flags))
|
|
return(-1);
|
|
if (!connid || (flags & 0x80))
|
|
return(-1);
|
|
return(0);
|
|
}
|
|
|
|
static int hex_value(int c)
|
|
{
|
|
if (c >= '0' && c <= '9') return(c - '0');
|
|
if (c >= 'a' && c <= 'f') return(c - 'a' + 10);
|
|
if (c >= 'A' && c <= 'F') return(c - 'A' + 10);
|
|
return(-1);
|
|
}
|
|
|
|
static int parse_hex32(char *s, uint32 *out)
|
|
{
|
|
uint32 value = 0;
|
|
int i;
|
|
int v;
|
|
|
|
if (!s || !*s || !out)
|
|
return(-1);
|
|
if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
|
|
s += 2;
|
|
if (!*s) return(-1);
|
|
}
|
|
for (i = 0; s[i]; i++) {
|
|
v = hex_value(s[i]);
|
|
if (v < 0) return(-1);
|
|
value = (value << 4) | (uint32)v;
|
|
}
|
|
*out = value;
|
|
return(0);
|
|
}
|
|
|
|
static uint32 lookup_object_id(char *name)
|
|
{
|
|
uint32 id;
|
|
uint8 namebuf[48];
|
|
|
|
if (!name || !*name)
|
|
return(0);
|
|
|
|
if (!parse_hex32(name, &id))
|
|
return(id);
|
|
|
|
strmaxcpy(namebuf, name, sizeof(namebuf) - 1);
|
|
upstr(namebuf);
|
|
id = ncp_17_35(namebuf, BINDERY_USER);
|
|
if (id)
|
|
return(id);
|
|
id = ncp_17_35(namebuf, BINDERY_GROUP);
|
|
return(id);
|
|
}
|
|
|
|
static int parse_uint(char *s, int *out)
|
|
{
|
|
int v = 0;
|
|
int i;
|
|
|
|
if (!s || !*s || !out)
|
|
return(-1);
|
|
for (i = 0; s[i]; i++) {
|
|
if (s[i] < '0' || s[i] > '9') return(-1);
|
|
v = v * 10 + (s[i] - '0');
|
|
}
|
|
*out = v;
|
|
return(0);
|
|
}
|
|
|
|
static uint16 make_dos_date(int year, int month, int day)
|
|
{
|
|
if (year < 80)
|
|
year += 2000;
|
|
if (year < 1980)
|
|
year = 1980;
|
|
return((uint16)(((year - 1980) << 9) | (month << 5) | day));
|
|
}
|
|
|
|
static uint16 make_dos_time(int hour, int min, int sec)
|
|
{
|
|
return((uint16)((hour << 11) | (min << 5) | (sec / 2)));
|
|
}
|
|
|
|
static void current_dos_datetime(uint16 *date_out, uint16 *time_out)
|
|
{
|
|
REGS regs;
|
|
int year;
|
|
int month;
|
|
int day;
|
|
int hour;
|
|
int min;
|
|
int sec;
|
|
|
|
regs.h.ah = 0x2a;
|
|
int86(0x21, ®s, ®s);
|
|
year = regs.x.cx;
|
|
month = regs.h.dh;
|
|
day = regs.h.dl;
|
|
|
|
regs.h.ah = 0x2c;
|
|
int86(0x21, ®s, ®s);
|
|
hour = regs.h.ch;
|
|
min = regs.h.cl;
|
|
sec = regs.h.dh;
|
|
|
|
if (date_out) *date_out = make_dos_date(year, month, day);
|
|
if (time_out) *time_out = make_dos_time(hour, min, sec);
|
|
}
|
|
|
|
static int parse_date_arg(char *s, uint16 *date_out)
|
|
{
|
|
char buf[32];
|
|
char *p1;
|
|
char *p2;
|
|
int y;
|
|
int m;
|
|
int d;
|
|
uint32 hex;
|
|
|
|
if (!s || !date_out)
|
|
return(-1);
|
|
if (!parse_hex32(s, &hex) && (s[0] == '0' || strlen(s) <= 4)) {
|
|
*date_out = (uint16)hex;
|
|
return(0);
|
|
}
|
|
|
|
strmaxcpy(buf, s, sizeof(buf)-1);
|
|
p1 = strchr(buf, '-');
|
|
if (!p1) p1 = strchr(buf, '.');
|
|
if (!p1) return(-1);
|
|
*p1++ = '\0';
|
|
p2 = strchr(p1, '-');
|
|
if (!p2) p2 = strchr(p1, '.');
|
|
if (!p2) return(-1);
|
|
*p2++ = '\0';
|
|
|
|
if (parse_uint(buf, &y) || parse_uint(p1, &m) || parse_uint(p2, &d))
|
|
return(-1);
|
|
|
|
/* Support both yyyy-mm-dd and dd.mm.yy. */
|
|
if (y < 100 && d > 100) {
|
|
int tmp = y;
|
|
y = d;
|
|
d = tmp;
|
|
}
|
|
if (y < 100) y += 2000;
|
|
if (m < 1 || m > 12 || d < 1 || d > 31)
|
|
return(-1);
|
|
|
|
*date_out = make_dos_date(y, m, d);
|
|
return(0);
|
|
}
|
|
|
|
static int parse_time_arg(char *s, uint16 *time_out)
|
|
{
|
|
char buf[32];
|
|
char *p1;
|
|
char *p2;
|
|
int h;
|
|
int m;
|
|
int sec = 0;
|
|
uint32 hex;
|
|
|
|
if (!s || !time_out)
|
|
return(-1);
|
|
if (!parse_hex32(s, &hex) && (s[0] == '0' || strlen(s) <= 4)) {
|
|
*time_out = (uint16)hex;
|
|
return(0);
|
|
}
|
|
|
|
strmaxcpy(buf, s, sizeof(buf)-1);
|
|
p1 = strchr(buf, ':');
|
|
if (!p1) return(-1);
|
|
*p1++ = '\0';
|
|
p2 = strchr(p1, ':');
|
|
if (p2) *p2++ = '\0';
|
|
|
|
if (parse_uint(buf, &h) || parse_uint(p1, &m))
|
|
return(-1);
|
|
if (p2 && parse_uint(p2, &sec))
|
|
return(-1);
|
|
if (h < 0 || h > 23 || m < 0 || m > 59 || sec < 0 || sec > 59)
|
|
return(-1);
|
|
|
|
*time_out = make_dos_time(h, m, sec);
|
|
return(0);
|
|
}
|
|
|
|
static void print_dos_date(uint16 date)
|
|
{
|
|
int year = ((date >> 9) & 0x7f) + 1980;
|
|
int month = (date >> 5) & 0x0f;
|
|
int day = date & 0x1f;
|
|
fprintf(stdout, "%04d-%02d-%02d", year, month, day);
|
|
}
|
|
|
|
static void print_dos_time(uint16 time)
|
|
{
|
|
int hour = (time >> 11) & 0x1f;
|
|
int min = (time >> 5) & 0x3f;
|
|
int sec = (time & 0x1f) * 2;
|
|
fprintf(stdout, "%02d:%02d:%02d", hour, min, sec);
|
|
}
|
|
|
|
static int copy_ncp22_name(uint8 *dst, char *src, uint8 *len_out)
|
|
{
|
|
char tmp[260];
|
|
int len;
|
|
|
|
if (!dst || !len_out) return(-1);
|
|
if (!src) src = "";
|
|
tool_upcopy(tmp, src, sizeof(tmp));
|
|
if (strchr(tmp, '\\') || strchr(tmp, '/') || strchr(tmp, ':'))
|
|
return(-1);
|
|
len = strlen(tmp);
|
|
if (len < 1 || len > 12)
|
|
return(-1);
|
|
memcpy(dst, tmp, len);
|
|
*len_out = (uint8)len;
|
|
return(0);
|
|
}
|
|
|
|
static int split_path(char *path, char *parent, int parent_size, char *name, int name_size)
|
|
{
|
|
char tmp[260];
|
|
char *p;
|
|
|
|
if (!path || !*path || !parent || !name)
|
|
return(-1);
|
|
|
|
strmaxcpy(tmp, path, sizeof(tmp)-1);
|
|
korrpath(tmp);
|
|
p = strrchr(tmp, '\\');
|
|
if (!p) p = strrchr(tmp, '/');
|
|
|
|
if (p) {
|
|
*p++ = '\0';
|
|
strmaxcpy(parent, tmp, parent_size-1);
|
|
strmaxcpy(name, p, name_size-1);
|
|
} else {
|
|
parent[0] = '\0';
|
|
strmaxcpy(name, tmp, name_size-1);
|
|
}
|
|
|
|
if (!name[0]) return(-1);
|
|
return(0);
|
|
}
|
|
|
|
static int set_info(uint8 dhandle, char *name, uint32 bits,
|
|
uint16 cdate, uint16 ctime, uint32 cid,
|
|
uint16 adate, uint16 atime, uint32 aid,
|
|
uint16 mdate, uint16 mtime, uint32 mid)
|
|
{
|
|
struct {
|
|
uint16 len;
|
|
uint8 func;
|
|
uint8 dirhandle;
|
|
uint8 search_attributes;
|
|
uint8 searchsequence[4];
|
|
uint8 change_bits[4];
|
|
uint8 subdir[4];
|
|
uint8 attributes[4];
|
|
uint8 uniqueid;
|
|
uint8 flags;
|
|
uint8 namespace;
|
|
uint8 namlen;
|
|
uint8 name[12];
|
|
uint8 created_time[2];
|
|
uint8 created_date[2];
|
|
uint8 created_id[4];
|
|
uint8 archived_time[2];
|
|
uint8 archived_date[2];
|
|
uint8 archived_id[4];
|
|
uint8 updated_time[2];
|
|
uint8 updated_date[2];
|
|
uint8 updated_id[4];
|
|
uint8 rest[80];
|
|
} req;
|
|
struct { uint16 len; } repl;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
memset(&repl, 0, sizeof(repl));
|
|
|
|
req.func = 0x25;
|
|
req.dirhandle = dhandle;
|
|
req.search_attributes = 0x06;
|
|
U32_TO_BE32(0xffffffffUL, req.searchsequence);
|
|
U32_TO_32(bits, req.change_bits);
|
|
|
|
U16_TO_16(ctime, req.created_time);
|
|
U16_TO_16(cdate, req.created_date);
|
|
U32_TO_BE32(cid, req.created_id);
|
|
U16_TO_16(atime, req.archived_time);
|
|
U16_TO_16(adate, req.archived_date);
|
|
U32_TO_BE32(aid, req.archived_id);
|
|
U16_TO_16(mtime, req.updated_time);
|
|
U16_TO_16(mdate, req.updated_date);
|
|
U32_TO_BE32(mid, req.updated_id);
|
|
|
|
if (copy_ncp22_name(req.name, name, &req.namlen))
|
|
return(-1);
|
|
|
|
req.len = sizeof(req) - sizeof(req.len);
|
|
neterrno = Net_Call(0xE200, &req, &repl);
|
|
if (neterrno)
|
|
return(-neterrno);
|
|
return(0);
|
|
}
|
|
|
|
|
|
static void creator_attr_string(uint32 attr, char *out)
|
|
{
|
|
out[0] = '[';
|
|
out[1] = 'R';
|
|
out[2] = (attr & _A_RDONLY) ? 'o' : 'w';
|
|
out[3] = '-';
|
|
out[4] = (attr & _A_ARCH) ? 'A' : '-';
|
|
out[5] = '-';
|
|
out[6] = (attr & _A_HIDDEN) ? 'H' : '-';
|
|
if (attr & _A_SYSTEM) {
|
|
out[7] = 'S';
|
|
out[8] = 'y';
|
|
} else {
|
|
out[7] = '-';
|
|
out[8] = '-';
|
|
}
|
|
memset(out + 9, '-', 8);
|
|
out[17] = (attr & CREATOR_ATTR_DELETE_INHIBIT) ? 'D' : '-';
|
|
out[18] = (attr & CREATOR_ATTR_RENAME_INHIBIT) ? 'R' : '-';
|
|
out[19] = ']';
|
|
out[20] = '\0';
|
|
}
|
|
|
|
static void creator_rights_string(uint16 rights, char *out)
|
|
{
|
|
uint8 old = (uint8)rights;
|
|
|
|
out[0] = '[';
|
|
out[1] = (old & CREATOR_RIGHT_S) ? 'S' : '-';
|
|
out[2] = (old & CREATOR_RIGHT_R) ? 'R' : '-';
|
|
out[3] = (old & CREATOR_RIGHT_W) ? 'W' : '-';
|
|
out[4] = (old & CREATOR_RIGHT_C) ? 'C' : '-';
|
|
out[5] = (old & CREATOR_RIGHT_E) ? 'E' : '-';
|
|
out[6] = (old & CREATOR_RIGHT_M) ? 'M' : '-';
|
|
out[7] = (old & CREATOR_RIGHT_F) ? 'F' : '-';
|
|
out[8] = (old & CREATOR_RIGHT_A) ? 'A' : '-';
|
|
out[9] = ']';
|
|
out[10] = '\0';
|
|
}
|
|
|
|
static int show_info(char *name, uint8 dhandle)
|
|
{
|
|
C32_NDIR_INFO info;
|
|
int rc;
|
|
char attr_text[24];
|
|
char rights_text[12];
|
|
|
|
memset(&info, 0, sizeof(info));
|
|
rc = c32_ncp87_obtain_ndir_info(tool_is_current_path(name) ? "" : name,
|
|
(uint16)dhandle,
|
|
&info,
|
|
NULL, NULL, NULL);
|
|
if (rc) {
|
|
fprintf(stdout, "CREATOR: obtain info failed for %s, rc=%d\n", name, rc);
|
|
return(rc);
|
|
}
|
|
|
|
creator_attr_string(info.attributes, attr_text);
|
|
creator_rights_string(info.inherited_rights, rights_text);
|
|
|
|
fprintf(stdout, "File: %s\n", name);
|
|
fprintf(stdout, "Attributes: %s (0x%08lX)\n", attr_text, (unsigned long)info.attributes);
|
|
fprintf(stdout, "Create: "); print_dos_date(info.creation_date);
|
|
fprintf(stdout, " "); print_dos_time(info.creation_time);
|
|
fprintf(stdout, " creator=0x%08lX\n", (unsigned long)info.creator_id);
|
|
fprintf(stdout, "Modify: "); print_dos_date(info.modify_date);
|
|
fprintf(stdout, " "); print_dos_time(info.modify_time);
|
|
fprintf(stdout, " modifier=0x%08lX\n", (unsigned long)info.modifier_id);
|
|
fprintf(stdout, "Archive: "); print_dos_date(info.archive_date);
|
|
fprintf(stdout, " "); print_dos_time(info.archive_time);
|
|
fprintf(stdout, " archiver=0x%08lX\n", (unsigned long)info.archiver_id);
|
|
fprintf(stdout, "Access date: "); print_dos_date(info.last_access_date);
|
|
fprintf(stdout, "\nRights mask: %s (0x%04X)\n", rights_text, (unsigned)info.inherited_rights);
|
|
return(0);
|
|
}
|
|
|
|
int func_creator(int argc, char *argv[], int mode)
|
|
{
|
|
char oldcwd[260];
|
|
char parent[260];
|
|
char name[64];
|
|
char *path;
|
|
char *cmd;
|
|
char *id_arg;
|
|
uint8 dhandle = 0;
|
|
uint32 id = 0;
|
|
uint16 date;
|
|
uint16 time;
|
|
uint32 bits = 0;
|
|
int rc = 0;
|
|
int need_id = 0;
|
|
|
|
(void)mode;
|
|
|
|
if (argc < 3) {
|
|
creator_usage();
|
|
return(1);
|
|
}
|
|
|
|
path = argv[1];
|
|
cmd = argv[2];
|
|
upstr(cmd);
|
|
|
|
if (split_path(path, parent, sizeof(parent), name, sizeof(name))) {
|
|
fprintf(stdout, "CREATOR: bad path %s\n", path);
|
|
return(1);
|
|
}
|
|
|
|
if (!getcwd(oldcwd, sizeof(oldcwd)))
|
|
oldcwd[0] = '\0';
|
|
|
|
if (parent[0] && chdir(parent)) {
|
|
fprintf(stdout, "CREATOR: cannot change to parent %s\n", parent);
|
|
return(1);
|
|
}
|
|
|
|
if (creator_current_dhandle(&dhandle)) {
|
|
fprintf(stdout, "CREATOR: current drive is not a network drive\n");
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(1);
|
|
}
|
|
|
|
if (!strcmp(cmd, "/SHOW") || !strcmp(cmd, "SHOW")) {
|
|
rc = show_info(name, dhandle);
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(rc);
|
|
}
|
|
|
|
need_id = 1;
|
|
if (argc < 4) {
|
|
creator_usage();
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(1);
|
|
}
|
|
id_arg = argv[3];
|
|
id = lookup_object_id(id_arg);
|
|
if (!id) {
|
|
fprintf(stdout, "CREATOR: object not found: %s\n", id_arg);
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(1);
|
|
}
|
|
|
|
current_dos_datetime(&date, &time);
|
|
if (argc >= 5 && parse_date_arg(argv[4], &date)) {
|
|
fprintf(stdout, "CREATOR: bad date '%s'\n", argv[4]);
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(1);
|
|
}
|
|
if (argc >= 6 && parse_time_arg(argv[5], &time)) {
|
|
fprintf(stdout, "CREATOR: bad time '%s'\n", argv[5]);
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(1);
|
|
}
|
|
|
|
if (!strcmp(cmd, "/CREATOR") || !strcmp(cmd, "CREATOR")) {
|
|
bits = DM_CREATOR_ID;
|
|
rc = set_info(dhandle, name, bits, 0, 0, id, 0, 0, 0, 0, 0, 0);
|
|
} else if (!strcmp(cmd, "/MODIFIER") || !strcmp(cmd, "MODIFIER")) {
|
|
bits = DM_MODIFIER_ID;
|
|
rc = set_info(dhandle, name, bits, 0, 0, 0, 0, 0, 0, 0, 0, id);
|
|
} else if (!strcmp(cmd, "/ARCHIVER") || !strcmp(cmd, "ARCHIVER")) {
|
|
bits = DM_ARCHIVER_ID;
|
|
rc = set_info(dhandle, name, bits, 0, 0, 0, 0, 0, id, 0, 0, 0);
|
|
} else if (!strcmp(cmd, "/CREATE") || !strcmp(cmd, "CREATE")) {
|
|
bits = DM_CREATE_DATE | DM_CREATE_TIME | DM_CREATOR_ID;
|
|
rc = set_info(dhandle, name, bits, date, time, id, 0, 0, 0, 0, 0, 0);
|
|
} else if (!strcmp(cmd, "/MODIFY") || !strcmp(cmd, "MODIFY")) {
|
|
bits = DM_MODIFY_DATE | DM_MODIFY_TIME | DM_MODIFIER_ID;
|
|
rc = set_info(dhandle, name, bits, 0, 0, 0, 0, 0, 0, date, time, id);
|
|
} else if (!strcmp(cmd, "/ARCHIVE") || !strcmp(cmd, "ARCHIVE")) {
|
|
bits = DM_ARCHIVE_DATE | DM_ARCHIVE_TIME | DM_ARCHIVER_ID;
|
|
rc = set_info(dhandle, name, bits, 0, 0, 0, date, time, id, 0, 0, 0);
|
|
} else if (!strcmp(cmd, "/ALL") || !strcmp(cmd, "ALL")) {
|
|
bits = DM_CREATE_DATE | DM_CREATE_TIME | DM_CREATOR_ID |
|
|
DM_ARCHIVE_DATE | DM_ARCHIVE_TIME | DM_ARCHIVER_ID |
|
|
DM_MODIFY_DATE | DM_MODIFY_TIME | DM_MODIFIER_ID;
|
|
rc = set_info(dhandle, name, bits, date, time, id, date, time, id, date, time, id);
|
|
} else {
|
|
creator_usage();
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(1);
|
|
}
|
|
|
|
if (rc) {
|
|
fprintf(stdout, "CREATOR: NCP22/25 set info failed for %s, rc=%d neterrno=0x%02X\n",
|
|
path, rc, (unsigned)(rc < 0 ? -rc : 0));
|
|
} else {
|
|
fprintf(stdout, "CREATOR: set %s on %s to 0x%08lX OK\n",
|
|
cmd, path, (unsigned long)id);
|
|
if (bits & (DM_CREATE_DATE | DM_MODIFY_DATE | DM_ARCHIVE_DATE)) {
|
|
fprintf(stdout, "CREATOR: date/time "); print_dos_date(date);
|
|
fprintf(stdout, " "); print_dos_time(time); fprintf(stdout, "\n");
|
|
}
|
|
}
|
|
|
|
if (!rc)
|
|
show_info(name, dhandle);
|
|
|
|
if (oldcwd[0]) chdir(oldcwd);
|
|
return(rc ? rc : 0);
|
|
}
|