/* remove.c - Novell REMOVE-like DOS utility */ #include "net.h" #include "c32ncp.h" #include "trustee.h" #include #include #ifndef _A_NORMAL #define _A_NORMAL 0x00 #endif static int remove_last_rc = 0; static void remove_usage_error(void) { fprintf(stdout, "Command line arguments violate grammar defined for REMOVE.\n\n"); } static void remove_usage(void) { fprintf(stdout, "Usage: REMOVE [USER | GROUP] name [FROM path] [option]\n"); fprintf(stdout, "Options: /Subdirs | /Files\n"); } static int remove_one(char *path, uint16 dhandle, uint32 object_id, uint16 objtype, char *objname, int forced_is_file) { uint16 old_rights = 0; int is_dir; int rc; is_dir = forced_is_file ? 0 : trustee_path_is_dir(path); rc = c32_ncp87_find_trustee_rights(path, dhandle, object_id, &old_rights, NULL, NULL, NULL); remove_last_rc = rc; if (rc) { if (rc == 0xff) fprintf(stdout, "No trustee for the specified %s.\n", is_dir ? "directory" : "file"); else fprintf(stdout, "Error scanning trustee list.\n"); return(1); } rc = c32_ncp87_delete_trustee_rights(path, dhandle, object_id, NULL, NULL, NULL); remove_last_rc = rc; if (rc) { fprintf(stdout, "Error deleting trustee.\n"); return(1); } { char header[300]; trustee_header_path(header, path, sizeof(header)); fprintf(stdout, "%s\n\n", header); } if (objtype == TRUSTEE_BINDERY_GROUP) fprintf(stdout, "Group \"%s\" no longer a trustee to the specified %s.\n", objname, is_dir ? "directory" : "file"); else fprintf(stdout, "User \"%s\" no longer a trustee to the specified %s.\n", objname, is_dir ? "directory" : "file"); return(0); } static int remove_subdirs(char *path, uint16 dhandle, uint32 object_id, uint16 objtype, char *objname, int *count) { struct find_t ff; char pattern[260]; char child[260]; int rc = 0; if (remove_one(path, dhandle, object_id, objtype, objname, 0) == 0) (*count)++; else rc = 1; trustee_join_path(pattern, path, "*.*", sizeof(pattern)); if (_dos_findfirst(pattern, _A_SUBDIR, &ff) == 0) { do { if ((ff.attrib & _A_SUBDIR) && !trustee_is_dot_dir(ff.name)) { trustee_join_path(child, path, ff.name, sizeof(child)); if (remove_subdirs(child, dhandle, object_id, objtype, objname, count)) rc = 1; } } while (_dos_findnext(&ff) == 0); } return(rc); } static int remove_files(char *path, uint16 dhandle, uint32 object_id, uint16 objtype, char *objname, int *count) { struct find_t ff; char dir[260]; char pat[80]; char spec[260]; char target[260]; int rc = 0; if (trustee_path_is_dir(path)) { strmaxcpy(dir, path, sizeof(dir) - 1); strmaxcpy(pat, "*.*", sizeof(pat) - 1); } else if (trustee_path_has_wildcards(path)) { trustee_parent_pattern(dir, pat, path, sizeof(dir), sizeof(pat)); } else { if (remove_one(path, dhandle, object_id, objtype, objname, 1) == 0) (*count)++; else rc = 1; return(rc); } trustee_join_path(spec, dir, pat, sizeof(spec)); if (_dos_findfirst(spec, _A_NORMAL | _A_HIDDEN | _A_SYSTEM | _A_ARCH, &ff) == 0) { do { if (!(ff.attrib & _A_SUBDIR)) { trustee_join_path(target, dir, ff.name, sizeof(target)); if (remove_one(target, dhandle, object_id, objtype, objname, 1) == 0) (*count)++; else rc = 1; } } while (_dos_findnext(&ff) == 0); } return(rc); } int func_remove(int argc, char *argv[], int mode) { char *path = "."; char *objname = NULL; char objprint[48]; uint16 objtype = TRUSTEE_BINDERY_USER; int objtype_given = 0; uint8 connid = 0; uint8 dhandle = 0; uint32 object_id; int use_subdirs = 0; int use_files = 0; int count = 0; int i = 1; int rc; (void)mode; if (argc < 2 || trustee_is_help(argv[1])) { if (argc < 2) remove_usage_error(); remove_usage(); return(argc < 2 ? 1 : 0); } if (i < argc && trustee_same(argv[i], "USER")) { objtype = TRUSTEE_BINDERY_USER; objtype_given = 1; i++; } else if (i < argc && trustee_same(argv[i], "GROUP")) { objtype = TRUSTEE_BINDERY_GROUP; objtype_given = 1; i++; } if (i >= argc) { remove_usage_error(); remove_usage(); return(1); } objname = argv[i++]; if (i < argc && trustee_same(argv[i], "FROM")) { i++; if (i >= argc) { remove_usage_error(); remove_usage(); return(1); } path = argv[i++]; } while (i < argc) { if (!trustee_is_option(argv[i])) { remove_usage_error(); remove_usage(); return(1); } if (trustee_is_files_option(argv[i])) { use_files = 1; i++; continue; } if (trustee_is_subdirs_option(argv[i])) { use_subdirs = 1; i++; continue; } remove_usage_error(); remove_usage(); return(1); } if (use_files && use_subdirs) { fprintf(stdout, "Remove cannot do both directories and files in a single pass.\n"); return(1); } if (trustee_current_dhandle(&connid, &dhandle)) { fprintf(stdout, "Error: Drive not mapped to network.\n"); return(1); } object_id = trustee_lookup_object(objname, &objtype, objtype_given); if (!object_id) { if (objtype_given && objtype == TRUSTEE_BINDERY_GROUP) fprintf(stdout, "Group \"%s\" not found.\n", objname); else if (objtype_given) fprintf(stdout, "User \"%s\" not found.\n", objname); else fprintf(stdout, "User or group \"%s\" not found.\n", objname); return(1); } trustee_upcopy(objprint, objname, sizeof(objprint)); if (use_subdirs) rc = remove_subdirs(path, (uint16)dhandle, object_id, objtype, objprint, &count); else if (use_files) rc = remove_files(path, (uint16)dhandle, object_id, objtype, objprint, &count); else { rc = remove_one(path, (uint16)dhandle, object_id, objtype, objprint, 0); if (!rc) count = 1; } if (use_subdirs || (!use_files && !rc)) fprintf(stdout, "Trustee \"%s\" removed from %d directories.\n", objprint, count); else if (use_files) fprintf(stdout, "Trustee \"%s\" removed from %d files.\n", objprint, count); return(rc ? (remove_last_rc ? remove_last_rc : 1) : 0); }