/* nwsalvage.c - Utility for salvaging deleted files from NetWare volumes Copyright (c) 2005 Scott Bentley 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Revision history: 0.00 2005 Scott Bentley Initial revision. */ #include #include #include #include #include "private/libintl.h" #define _(X) gettext(X) static void usage(void) { printf(_( "usage: nwsalvage [options] directory file_id\n" "\n" "-h Print this help text.\n" "-s Silent mode.\n" "-n Namespace for accessing files.\n" " DOS\n" " LONG - Default\n" " MAC\n" " FTAM\n" " NFS\n" "-r Rename the salvaged file. 255 chars max." "\n" "directory Directory in which salvageable file resides.\n" " Default is current directory.\n" "\n" "file_id The file identified by file_id will be salvaged.\n" " Numeric file_id is obtained from nwlistsalvage.\n" "\n" )); } static int g_silent = 0; static int g_rename = 0; static char* g_newname; static int g_nwns = NW_NS_LONG; static void process_salvage(struct ncp_conn* conn, int volume, u_int32_t directory_id, int file_id) { struct ncp_deleted_file info; int found; char filename[256]; NWCCODE err; found = 0; info.seq = -1; while (!ncp_ns_scan_salvageable_file(conn, g_nwns, 1, volume, directory_id, NULL, 0, &info, filename, sizeof(filename))) { if (info.seq == file_id) { found++; if (g_rename) { strcpy(filename, g_newname); } if ((err = ncp_ns_salvage_file(conn, g_nwns, &info, filename)) != 0) { if (!g_silent) { if (err == 0x89FE) { printf(_("%8s%d -- failed (File already exists, or path inaccessible)\n"), "", info.seq); } else { printf(_("%8s%d %s -- failed (%s)\n"), "", info.seq, filename, strnwerror(err)); } } } else { if (!g_silent) { printf(_("%8s%d %s -- salvaged \n"), "", info.seq, filename); } } break; } } if (!found) { printf(_("%8sFile with scan ID '%d' was not found."), "", file_id); } printf("\n"); } int main(int argc, char* argv[]) { struct NWCCRootEntry root; const char* mount_path; int file_id; struct ncp_conn* conn; int err; int c; char* opt_n; char* opt_r; setlocale(LC_ALL, ""); bindtextdomain(NCPFS_PACKAGE, LOCALEDIR); textdomain(NCPFS_PACKAGE); while ((c = getopt(argc, argv, "hsnr")) != -1) { switch (c) { case '?': case ':':break; case 'h':usage(); exit(2); case 's':g_silent = 1; break; case 'n': opt_n = argv[optind++]; if (strcasecmp(opt_n, "DOS") == 0) { g_nwns = NW_NS_DOS; } else if (strcasecmp(opt_n, "MAC") == 0) { g_nwns = NW_NS_MAC; } else if (strcasecmp(opt_n, "NFS") == 0) { g_nwns = NW_NS_NFS; } else if (strcasecmp(opt_n, "FTAM") == 0) { g_nwns = NW_NS_FTAM; } else if (strcasecmp(opt_n, "LONG") == 0) { g_nwns = NW_NS_LONG; } else { fprintf(stderr, _("Unrecognized namespace for option '-%c'\n"), c); exit(1); } break; case 'r': opt_r = argv[optind++]; if (strlen(opt_r) > 255 || strlen(opt_r) < 1) { fprintf(stderr, _("Filename for option '-%c' has invalid length."), c); exit(1); } g_rename = 1; g_newname = opt_r; break; default: fprintf(stderr, _("Unexpected option `-%c'\n"), c); break; } } if (optind < argc) { mount_path = argv[optind++]; file_id = atoi(argv[optind++]); } else { usage(); exit(2); } err = ncp_open_mount(mount_path, &conn); if (err) { com_err("nwsalvage", err, _("in ncp_open_mount")); exit(1); } err = NWCCGetConnInfo(conn, NWCC_INFO_ROOT_ENTRY, sizeof(root), &root); if (err) { com_err("nwsalvage", err, _("when retrieving root entry")); ncp_close(conn); return 0; } process_salvage(conn, root.volume, root.dirEnt, file_id); ncp_close(conn); return 0; }