Files
Arquivotheca.Solaris-2.5/cmd/backup/database/utils/mdbmaint.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

632 lines
13 KiB
C
Executable File

#ident "@(#)mdbmaint.c 1.30 93/06/23"
/*
* Copyright (c) 1990,1991,1992 by Sun Microsystems, Inc.
*/
#include "defs.h"
#include <ctype.h>
#include <rpc/rpc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef USG
#include <rpc/clnt_soc.h>
#endif
#include <config.h>
int nmapblocks = 100;
static char thishost[BCHOSTNAMELEN+1];
static char *myname;
#ifdef __STDC__
static void usage(void);
static bool_t xdr_strresults(XDR *, int);
static void dodbinfo(char *);
static void listem(const char *, int, const char *);
static void dodelete(char *, char *);
#else
static void usage();
static bool_t xdr_strresults();
static void dodbinfo();
static void listem();
static void dodelete();
#endif
main(argc, argv)
int argc;
char *argv[];
{
extern char *optarg;
extern int optind;
int c;
int listverb;
int rebuildall = 0;
int tpbsize;
int nblks;
char *dbserv, *dumpdev, *dbroot, *host, *tapelabel, *tempdir;
char cmd[BUFSIZ];
FILE *in;
struct labelstruct *labeltype = NULL;
extern struct labelstruct labeltypes[];
(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
myname = strrchr(argv[0], '/');
if (myname == (char *)0)
myname = argv[0];
else
myname++;
if (argc < 2) {
usage();
}
if (geteuid() != 0) {
(void) fprintf(stderr,
gettext("%s: must be run by root\n"), myname);
exit(1);
}
if (gethostname(thishost, BCHOSTNAMELEN)) {
perror("gethostname");
exit(1);
}
dbserv = dumpdev = dbroot = host = tapelabel = tempdir = NULL;
listverb = tpbsize = 0;
while ((c = getopt(argc, argv, "ab:d:f:h:l:m:r:s:t:vV")) != -1) {
switch (c) {
case 'a':
++rebuildall;
break;
case 'b':
tpbsize = atoi(optarg);
if (tpbsize <= 0 || tpbsize > 512 || (tpbsize & 1)) {
tpbsize = 0;
(void) fprintf(stderr, gettext(
"Bad tape block size, default used\n"));
} else {
tpbsize /= 2;
}
break;
case 'd':
dumpdev = optarg;
break;
case 'f':
tempdir = optarg;
break;
case 'h':
host = optarg;
break;
case 'l':
for (labeltype = labeltypes;
labeltype->name; labeltype++)
if (strcmp(labeltype->name, optarg) == 0)
break;
if (labeltype->name == NULL)
usage();
break;
case 'm':
nblks = atoi(optarg);
if (nblks <= 0 || nblks > 500) {
(void) fprintf(stderr, gettext(
"bad map block specification\n"));
(void) fprintf(stderr, gettext(
"using %d megabyte blocks\n"),
nmapblocks);
} else {
nmapblocks = nblks;
}
break;
case 'r':
dbroot = optarg;
break;
case 's':
dbserv = optarg;
break;
case 't':
tapelabel = optarg;
break;
case 'v':
listverb = 1;
break;
case 'V':
listverb = 2;
break;
}
}
if (optind >= argc)
usage();
switch (argv[optind][0]) {
case 'd':
if (strcmp(argv[optind], "dumpadd") == 0) {
dumpadd(dbserv, dumpdev, tempdir, tpbsize);
} else if (strcmp(argv[optind], "dir_rebuild") == 0) {
rebuilddir(dbroot, host, rebuildall);
} else if (strcmp(argv[optind], "delete") == 0) {
dodelete(dbserv, tapelabel);
} else if (strcmp(argv[optind], "dbinfo") == 0) {
while (dbserv == NULL) {
char buf[256];
(void) fprintf(stderr,
gettext(
"What database server do you wish information about (hostname)? "));
if (gets(buf) == NULL)
exit(1);
if (buf[0])
dbserv = buf;
}
dodbinfo(dbserv);
} else {
usage();
}
break;
case 'p':
if (strcmp(argv[optind], "pslabel"))
usage();
while (dbserv == NULL) {
char buf[256];
(void) fprintf(stderr, gettext(
"What database server do you wish to list tapes from (hostname)? "));
if (gets(buf) == NULL)
exit(1);
if (buf[0])
dbserv = buf;
}
sprintf(cmd, "%s -s %s -V tapelist", argv[0], dbserv);
while (++optind < argc) {
strcat(cmd, " ");
strcat(cmd, argv[optind]);
}
if ((in = popen(cmd, "r")) == NULL) {
fprintf(stderr, gettext("can't invoke '%s':"), cmd);
perror("");
exit(1);
}
pslabel(in, labeltype);
break;
case 'r':
if (strcmp(argv[optind], "reclaim"))
usage();
reclaim(dbroot, host);
break;
case 's':
if (strcmp(argv[optind], "stop") == 0) {
pokeserver(QUIESCE_OPERATION, dbserv);
} else if (strcmp(argv[optind], "start") == 0) {
pokeserver(RESUME_OPERATION, dbserv);
} else {
usage();
}
break;
case 't':
if (strcmp(argv[optind], "tapefile_rebuild") == 0) {
rebuildtape(dbroot);
} else if (strcmp(argv[optind], "tapeadd") == 0) {
tapeadd(dbserv, dumpdev, tempdir, tpbsize);
} else if (strcmp(argv[optind], "tapelist") == 0) {
if (dbserv == NULL)
dbserv = thishost;
if (++optind < argc) {
for (; optind < argc; optind++)
listem(argv[optind], listverb, dbserv);
} else {
listem((char *)NULL, listverb, dbserv);
}
} else {
usage();
}
break;
default:
usage();
}
exit(0);
#ifdef lint
return (0);
#endif
/*NOTREACHED*/
}
static void
#ifdef __STDC__
usage(void)
#else
usage()
#endif
{
extern struct labelstruct labeltypes[];
struct labelstruct *lt;
(void) fprintf(stderr, gettext("usage: %s arg\n\n"), myname);
(void) fprintf(stderr, gettext("where `arg' is one of:\n\n"));
(void) fprintf(stderr,
gettext("\t[%s tapelabel] %s\n"), "-t", "delete");
(void) fprintf(stderr,
gettext("\t[%s database_root] [%s | %s host] [%s mapsize] %s\n"),
"-r", "-a", "-h", "-m", "dir_rebuild");
(void) fprintf(stderr,
gettext("\t[%s database_server] [%s dumpdevice] "), "-s", "-d");
(void) fprintf(stderr, gettext("[%s tempdir] [%s blksize] %s\n"),
"-f", "-b", "dumpadd");
(void) fprintf(stderr,
gettext("\t[%s database_root] [%s host] [%s mapsize] %s\n"),
"-r", "-h", "-m", "reclaim");
(void) fprintf(stderr, "\tstart\n");
(void) fprintf(stderr, "\tstop\n");
(void) fprintf(stderr, gettext(
"\t[%s database_server] [%s dumpdevice] [%s tempdir] [%s blksize] %s\n"),
"-s", "-d", "-f", "-b", "tapeadd");
(void) fprintf(stderr,
gettext("\t[%s database_root] [%s mapsize] %s\n"),
"-r", "-m", "tapefile_rebuild");
(void) fprintf(stderr,
gettext("\t[%s database_server] [%s] [%s] %s [tapelabel...]\n"),
"-s", "-v", "-V", "tapelist");
(void) fprintf(stderr,
gettext("\t[%s database server] [%s %s"), "-s", "-l",
labeltypes[0].name);
for (lt = labeltypes + 1; lt->name; lt++)
(void) fprintf(stderr, "|%s", lt->name);
(void) fprintf(stderr,
gettext("] %s [tapelabel...]\n"), "pslabel");
(void) fprintf(stderr,
gettext("\t[%s database_server] %s\n"), "-s", "dbinfo");
exit(1);
}
static struct timeval TIMEOUT = {120, 0};
/*ARGSUSED*/
static bool_t
xdr_strresults(xdrs, notused)
XDR *xdrs;
int notused;
{
char line[256], *lp;
int size;
register char *p;
lp = line;
while (xdr_bytes(xdrs, &lp, (u_int *)&size, 256) == TRUE) {
for (p = line; *p; p++)
if (isprint((u_char)*p) || *p == '\n')
(void) putchar(*p);
else
(void) putchar('?');
}
return (TRUE);
}
static void
dodbinfo(dbserv)
char *dbserv;
{
CLIENT *cl;
#ifdef USG
struct hostent *h = gethostbyname(dbserv);
struct sockaddr_in addr;
int socket = RPC_ANYSOCK;
if (h == (struct hostent *)0) {
(void) fprintf(stderr, gettext("unknown host `%s'\n"), dbserv);
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port = 0;
/*LINTED [alignment ok]*/
addr.sin_addr.s_addr = *(u_long *)(h->h_addr);
cl = clnttcp_create(&addr, DBSERV, DBVERS, &socket, 0, 0);
#else
cl = clnt_create(dbserv, DBSERV, DBVERS, "tcp");
#endif
if (cl == NULL) {
clnt_pcreateerror("clnttcp_create");
(void) fprintf(stderr, gettext(
"database server not running at host `%s'\n"), dbserv);
exit(1);
}
cl->cl_auth = authunix_create_default();
if (clnt_call(cl, DB_DBINFO, xdr_void, NULL,
xdr_strresults, NULL, TIMEOUT) != RPC_SUCCESS) {
clnt_perror(cl, dbserv);
exit(1);
}
}
static void
#ifdef __STDC__
listem(const char *name,
int verbose,
const char *dbserv)
#else
listem(name, verbose, dbserv)
char *name;
int verbose;
char *dbserv;
#endif
{
CLIENT *cl;
struct tapelistargs a;
#ifdef USG
struct hostent *h = gethostbyname(dbserv);
struct sockaddr_in addr;
int socket = RPC_ANYSOCK;
if (h == (struct hostent *)0) {
(void) fprintf(stderr, gettext("unknown host `%s'\n"), dbserv);
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port = 0;
/*LINTED [alignment ok]*/
addr.sin_addr.s_addr = *(u_long *)(h->h_addr);
cl = clnttcp_create(&addr, DBSERV, DBVERS, &socket, 0, 0);
#else
cl = clnt_create(dbserv, DBSERV, DBVERS, "tcp");
#endif
if (cl == NULL) {
(void) fprintf(stderr, gettext(
"database server not running at host `%s'\n"), dbserv);
exit(1);
}
cl->cl_auth = authunix_create_default();
a.label = name ? (char *)name : "";
a.verbose = verbose;
if (clnt_call(cl, DB_TAPELIST, xdr_tapelistargs, (caddr_t)&a,
xdr_strresults, (caddr_t)0, TIMEOUT) != RPC_SUCCESS) {
clnt_perror(cl, (char *)dbserv);
exit(1);
}
}
void
pokeserver(cmd, dbserv)
u_long cmd;
char *dbserv;
{
CLIENT *cl;
if (dbserv) {
if (strcmp(dbserv, thishost)) {
if (cmd == QUIESCE_OPERATION)
(void) fprintf(stderr, gettext(
"You cannot stop a remote server\n"));
else
(void) fprintf(stderr, gettext(
"You cannot start a remote server\n"));
exit(1);
}
} else {
dbserv = thishost;
}
for (;;) {
#ifdef USG
struct sockaddr_in addr;
int socket = RPC_ANYSOCK;
struct hostent *h = gethostbyname(dbserv);
if (h == (struct hostent *)0) {
(void) fprintf(stderr,
gettext("unknown host `%s'\n"), dbserv);
exit(1);
}
addr.sin_family = AF_INET;
addr.sin_port = 0;
/*LINTED [alignment ok]*/
addr.sin_addr.s_addr = *(u_long *)(h->h_addr);
cl = clnttcp_create(&addr, DBSERV, DBVERS, &socket, 0, 0);
#else
cl = clnt_create(dbserv, DBSERV, DBVERS, "tcp");
#endif
if (cl == NULL) {
(void) fprintf(stderr, gettext(
"database server not running at host `%s'\n"),
dbserv);
return;
}
cl->cl_auth = authunix_create_default();
if (clnt_call(cl, cmd, xdr_void, NULL,
xdr_void, NULL, TIMEOUT) == RPC_SUCCESS) {
return;
} else {
clnt_perror(cl, dbserv);
}
clnt_destroy(cl);
TIMEOUT.tv_sec += 60;
if (cmd == QUIESCE_OPERATION)
(void) fprintf(stderr, gettext(
"Re-trying database stop operation at server `%s'\n"),
dbserv);
else
(void) fprintf(stderr, gettext(
"Re-trying database start operation at server `%s'\n"),
dbserv);
}
}
static void
dodelete(dbserv, tapelabel)
char *dbserv;
char *tapelabel;
{
#define LABELSIZE 16
char label[LABELSIZE];
int rc;
if (dbserv) {
if (strcmp(dbserv, thishost)) {
(void) fprintf(stderr, gettext(
"You cannot delete from a remote server\n"));
exit(1);
}
} else {
dbserv = thishost;
}
(void) bzero(label, LABELSIZE);
if (tapelabel == NULL) {
(void) fprintf(stderr,
gettext("Enter tape label to be deleted: "));
if (gets(label) == NULL)
exit(1);
} else {
(void) strcpy(label, tapelabel);
}
if ((rc = delete_bytape(dbserv, label)) != 0) {
if (rc == -1)
(void) fprintf(stderr,
gettext("%s: %s: no such tape\n"),
myname, label);
exit(1);
}
}
char *
getdbhost(name)
char *name;
{
static char hostdir[MAXPATHLEN];
struct hostent *h;
struct in_addr inaddr;
char *dot, *newline;
if (name == NULL) {
(void) fprintf(stderr, gettext(
"Enter name of host to be operated on: "));
if (fgets(hostdir, sizeof (hostdir), stdin) == NULL)
exit(1);
if ((newline = strrchr(hostdir, '\n')) != NULL)
*newline = '\0';
name = hostdir;
} else {
(void) strcpy(hostdir, name);
name = hostdir;
}
/* if it has a dot and it's followed by a digit, just return it */
if ((dot = strchr(name, '.')) != NULL) {
if (isdigit(*(dot + 1)))
return (hostdir);
}
h = gethostbyname(name);
if (h == NULL) {
(void) fprintf(stderr, gettext(
"Cannot get host entry for `%s'\n"), name);
return (NULL);
}
/*LINTED [alignment ok]*/
inaddr.s_addr = *((u_long *)h->h_addr);
if (dot != NULL)
*dot = '\0';
(void) strcat(name, ".");
(void) strcat(name, inet_ntoa(inaddr));
return (hostdir);
}
static int lockfd;
#if defined(USG) && !defined(FLOCK)
#include <sys/file.h>
/*
* Trump up a version of flock based on fcntl.
* You don't need this if your implementation
* has flock -- just compile with -DFLOCK.
*/
#define LOCK_SH 1 /* shared lock */
#define LOCK_EX 2 /* exclusive lock */
#define LOCK_NB 4 /* don't block when locking */
#define LOCK_UN 8 /* unlock */
static int
flock(fd, operation)
int fd;
int operation;
{
struct flock fl;
int block = 0;
int status;
if (operation & LOCK_SH)
fl.l_type = F_RDLCK;
else if (operation & LOCK_EX)
fl.l_type = F_WRLCK;
else if (operation & LOCK_UN)
fl.l_type = F_UNLCK;
if ((operation & LOCK_NB) == 0)
block = 1;
fl.l_whence = SEEK_SET; /* XXX ? */
fl.l_start = (off_t)0;
fl.l_len = (off_t)0; /* till EOF */
while ((status = fcntl(fd, F_SETLK, (char *)&fl)) < 0 &&
(errno == EACCES || errno == EAGAIN) && block) {
(void) sleep(1);
}
return (status);
}
#endif
void
#ifdef __STDC__
maint_lock(void)
#else
maint_lock()
#endif
{
if ((lockfd = open(UTIL_LOCKFILE, O_RDWR|O_CREAT, 0600)) == -1) {
perror("lockdb/open");
exit(1);
}
if (flock(lockfd, LOCK_EX) == -1) {
perror("lockdb/flock");
exit(1);
}
}
void
#ifdef __STDC__
maint_unlock(void)
#else
maint_unlock()
#endif
{
if (flock(lockfd, LOCK_UN) == -1) {
perror("unlockdb/flock");
exit(1);
}
(void) close(lockfd);
}
char *
lctime(timep)
time_t *timep;
{
static char buf[256];
struct tm *tm;
tm = localtime(timep);
(void) strftime(buf, sizeof (buf), "%c\n", tm);
return (buf);
}