File: [Development] / xfs-cmds / xfstests / dmapi / src / common / lib / print.c (download)
Revision 1.8, Wed Nov 9 02:50:19 2005 UTC (11 years, 11 months ago) by nathans.longdrop.melbourne.sgi.com
Branch: MAIN
CVS Tags: HEAD Changes since 1.7: +14 -28
lines
Update copyright annotations and license boilerplates to correspond with SGI Legals preferences.
Merge of master-melb:xfs-cmds:24329a by kenmcd.
|
/*
* Copyright (c) 2000-2001 Silicon Graphics, Inc.
* All Rights Reserved.
*
* 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.
*
* This program is distributed in the hope that it would 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 the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <ctype.h>
#include <lib/hsm.h>
#include <string.h>
#ifdef linux
#define MAXNAMELEN 256
#endif
/*
* Define some standard formats for the printf statements below.
*/
#define HDR "type=%s token=%d sequence=%d\n"
#define VALS "\t%s=%s\n"
#define VALD "\t%s=%d\n"
#define VALLLD "\t%s=%lld\n"
/*
Convert a mode_t field into a printable string.
Returns non-zero if the mode_t is invalid. The string is
returned in *ptr, whether there is an error or not.
*/
int
format_mode(
mode_t mode,
char **ptr)
{
static char modestr[100];
char *typestr;
int error = 0;
if (S_ISFIFO(mode)) typestr = "FIFO";
else if(S_ISCHR (mode)) typestr = "Character Device";
else if(S_ISBLK (mode)) typestr = "Block Device";
else if(S_ISDIR (mode)) typestr = "Directory";
else if(S_ISREG (mode)) typestr = "Regular File";
else if(S_ISLNK (mode)) typestr = "Symbolic Link";
else if(S_ISSOCK(mode)) typestr = "Socket";
else {
typestr = "<unknown type>";
error++;
}
sprintf(modestr, "mode %06o: perm %c%c%c %c%c%c %c%c%c %c%c%c, type %s",
mode,
mode & S_ISUID ? 's':' ',
mode & S_ISGID ? 'g':' ',
mode & S_ISVTX ? 't':' ',
mode & S_IRUSR ? 'r':'-',
mode & S_IWUSR ? 'w':'-',
mode & S_IXUSR ? 'x':'-',
mode & S_IRGRP ? 'r':'-',
mode & S_IWGRP ? 'w':'-',
mode & S_IXGRP ? 'x':'-',
mode & S_IROTH ? 'r':'-',
mode & S_IWOTH ? 'w':'-',
mode & S_IXOTH ? 'x':'-',
typestr);
*ptr = modestr;
return(error);
}
void
print_one_mount_event(
void *msg)
{
void *hanp1, *hanp2, *hanp3;
size_t hlen1, hlen2, hlen3;
char hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR];
void *namp1, *namp2;
size_t nlen1, nlen2;
char nams1[MAXNAMELEN], nams2[MAXNAMELEN];
mode_t mode;
#if VERITAS_21
dm_namesp_event_t *msg_ne = (dm_namesp_event_t *)msg;
/*
msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
*/
hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *);
hlen1 = DM_GET_LEN (msg_ne, ne_handle1);
hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *);
hlen2 = DM_GET_LEN (msg_ne, ne_handle2);
namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *);
nlen1 = DM_GET_LEN (msg_ne, ne_name1);
namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *);
nlen2 = DM_GET_LEN (msg_ne, ne_name2);
hanp3 = NULL;
hlen3 = 0;
mode = msg_ne->ne_mode;
#else
dm_mount_event_t *msg_me = (dm_mount_event_t *)msg;
hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *);
hlen1 = DM_GET_LEN(msg_me, me_handle1);
hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *);
hlen2 = DM_GET_LEN(msg_me, me_handle2);
namp1 = DM_GET_VALUE(msg_me, me_name1, void *);
nlen1 = DM_GET_LEN(msg_me, me_name1);
namp2 = DM_GET_VALUE(msg_me, me_name2, void *);
nlen2 = DM_GET_LEN(msg_me, me_name2);
hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *);
hlen3 = DM_GET_LEN(msg_me, me_roothandle);
mode = msg_me->me_mode;
#endif /* VERITAS_21 */
if (hanp1 && hlen1) {
hantoa(hanp1, hlen1, hans1);
} else {
sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
}
if (hanp2 && hlen2) {
hantoa(hanp2, hlen2, hans2);
} else {
sprintf(hans2, "<BAD HANDLE, hlen %d>", hlen2);
}
if (hanp3 && hlen3) {
hantoa(hanp3, hlen3, hans3);
} else {
sprintf(hans3, "<BAD HANDLE, hlen %d>", hlen3);
}
if (namp1 && nlen1) {
strncpy(nams1, namp1, nlen1);
if (nlen1 != sizeof(nams1))
nams1[nlen1] = '\0';
} else {
sprintf(nams1, "<BAD STRING, nlen %d>", nlen1);
}
if (namp2 && nlen2) {
strncpy(nams2, namp2, nlen2);
if (nlen2 != sizeof(nams2))
nams2[nlen2] = '\0';
} else {
sprintf(nams2, "<BAD STRING, nlen %d>", nlen2);
}
printf(VALS VALS VALS VALS VALS VALD,
"fs handle", hans1,
"mtpt handle", hans2,
"mtpt path", nams1,
"media desig", nams2,
"root handle", hans3,
"mode", mode);
}
static int
print_one_data_event(
dm_data_event_t *msg_de)
{
char handle[HANDLE_STR];
void *hanp;
size_t hlen;
hanp = DM_GET_VALUE(msg_de, de_handle, void *);
hlen = DM_GET_LEN (msg_de, de_handle);
if (hanp && hlen) {
hantoa(hanp, hlen, handle);
} else {
sprintf(handle, "<BAD HANDLE, hlen %d>", hlen);
}
printf(VALS VALLLD VALLLD,
"file_handle", handle,
"offset", msg_de->de_offset,
"length", msg_de->de_length);
return(0);
}
int
print_one_message(
dm_eventmsg_t *msg)
{
int pkt_error = 0;
dm_namesp_event_t *msg_ne;
void *hanp1, *hanp2, *namp1, *namp2;
u_int hlen1, hlen2, nlen1, nlen2;
char hans1[HANDLE_STR], hans2[HANDLE_STR];
char nams1[MAXNAMELEN], nams2[MAXNAMELEN];
/***** USER EVENTS *****/
if (msg->ev_type == DM_EVENT_USER) {
char *privp;
u_int plen, i;
printf(HDR,
"user", msg->ev_token, msg->ev_sequence);
/* print private data as ascii or hex if it exists DM_CONFIG_MAX_MESSAGE_DATA */
privp = DM_GET_VALUE(msg, ev_data, char *);
plen = DM_GET_LEN (msg, ev_data);
if (plen) {
for (i = 0; i < plen; i++) {
if (!isprint(privp[i]) && !isspace(privp[i]))
break;
}
if (i == plen - 1 && privp[i] == '\0') {
printf(VALS,
"privdata", privp);
} else {
printf("\t%-15s ", "privdata");
for (i = 0; i < plen; i++) {
printf("%.2x", privp[i]);
}
printf("\n");
}
} else {
printf(VALS,
"privdata", "<NONE>");
}
/***** CANCEL EVENT *****/
/* Not implemented on SGI or Veritas */
} else if (msg->ev_type == DM_EVENT_CANCEL) {
dm_cancel_event_t *msg_ce;
msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *);
printf(HDR VALD VALD,
"cancel", msg->ev_token, msg->ev_sequence,
"sequence", msg_ce->ce_sequence,
"token", msg_ce->ce_token);
/***** DATA EVENTS *****/
} else if (msg->ev_type == DM_EVENT_READ ||
msg->ev_type == DM_EVENT_WRITE ||
msg->ev_type == DM_EVENT_TRUNCATE) {
dm_data_event_t *msg_de;
msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
switch (msg->ev_type) {
case DM_EVENT_READ:
printf(HDR, "read", msg->ev_token, msg->ev_sequence);
break;
case DM_EVENT_WRITE:
printf(HDR, "write", msg->ev_token, msg->ev_sequence);
break;
case DM_EVENT_TRUNCATE:
printf(HDR, "truncate", msg->ev_token,
msg->ev_sequence);
break;
default: break;
}
print_one_data_event(msg_de);
/***** DESTROY EVENT *****/
} else if (msg->ev_type == DM_EVENT_DESTROY) {
dm_destroy_event_t *msg_ds;
char attrname[DM_ATTR_NAME_SIZE + 1];
u_char *copy;
u_int clen;
u_int i;
msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *);
hanp1 = DM_GET_VALUE(msg_ds, ds_handle, void *);
hlen1 = DM_GET_LEN (msg_ds, ds_handle);
if (hanp1 && hlen1) {
hantoa(hanp1, hlen1, hans1);
} else {
sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
}
if (msg_ds->ds_attrname.an_chars[0] != '\0') {
strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname));
} else {
strcpy(attrname, "<NONE>");
}
printf(HDR VALS VALS,
"destroy", msg->ev_token, msg->ev_sequence,
"handle", hans1,
"attrname", attrname);
copy = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *);
clen = DM_GET_LEN (msg_ds, ds_attrcopy);
if (copy && clen) {
printf("\t%-15s ", "attrcopy");
for (i = 0; i < clen; i++) {
printf("%.2x", copy[i]);
}
printf("\n");
} else {
printf(VALS, "attrcopy", "<NONE>");
}
/***** MOUNT EVENT *****/
} else if (msg->ev_type == DM_EVENT_MOUNT) {
void *msg_body;
printf(HDR, "mount", msg->ev_token, msg->ev_sequence);
#if !VERITAS_21
msg_body = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *);
#else /* VERITAS_21 */
msg_body = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
#endif /* VERITAS_21 */
print_one_mount_event(msg_body);
/***** NAMESPACE EVENTS *****/
} else {
char *type;
msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
hanp1 = DM_GET_VALUE(msg_ne, ne_handle1, void *);
hlen1 = DM_GET_LEN (msg_ne, ne_handle1);
hanp2 = DM_GET_VALUE(msg_ne, ne_handle2, void *);
hlen2 = DM_GET_LEN (msg_ne, ne_handle2);
namp1 = DM_GET_VALUE(msg_ne, ne_name1, void *);
nlen1 = DM_GET_LEN (msg_ne, ne_name1);
namp2 = DM_GET_VALUE(msg_ne, ne_name2, void *);
nlen2 = DM_GET_LEN (msg_ne, ne_name2);
if (hanp1 && hlen1) {
hantoa(hanp1, hlen1, hans1);
}
if (hanp2 && hlen2) {
hantoa(hanp2, hlen2, hans2);
}
if (namp1 && nlen1) {
strncpy(nams1, namp1, nlen1);
if (nlen1 != sizeof(nams1))
nams1[nlen1] = '\0';
}
if (namp2 && nlen2) {
strncpy(nams2, namp2, nlen2);
if (nlen2 != sizeof(nams2))
nams2[nlen2] = '\0';
}
if (msg->ev_type == DM_EVENT_PREUNMOUNT ||
msg->ev_type == DM_EVENT_UNMOUNT) {
if (msg_ne->ne_mode == 0) {
type = "NOFORCE";
#if !VERITAS_21
} else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) {
#else
} else if (msg_ne->ne_mode > 0) {
#endif
type = "FORCE";
} else {
type = "UNKNOWN";
pkt_error++;
}
} else if (msg->ev_type == DM_EVENT_CREATE ||
msg->ev_type == DM_EVENT_POSTCREATE ||
msg->ev_type == DM_EVENT_REMOVE ||
msg->ev_type == DM_EVENT_POSTREMOVE) {
if (format_mode(msg_ne->ne_mode, &type)) {
pkt_error++;
}
}
switch(msg->ev_type) {
case DM_EVENT_PREUNMOUNT:
printf(HDR VALS VALS VALS,
"preunmount", msg->ev_token, msg->ev_sequence,
"fs handle", hans1,
"root dir", hans2,
"unmount mode", type);
break;
case DM_EVENT_UNMOUNT:
printf(HDR VALS VALS VALD,
"unmount", msg->ev_token, msg->ev_sequence,
"fs handle", hans1,
"unmount mode", type,
"retcode", msg_ne->ne_retcode);
break;
case DM_EVENT_NOSPACE:
printf(HDR VALS,
"nospace", msg->ev_token, msg->ev_sequence,
"fs handle", hans1);
break;
case DM_EVENT_DEBUT: /* not supported on SGI */
printf(HDR VALS,
"debut", msg->ev_token, msg->ev_sequence,
"object", hans1);
break;
case DM_EVENT_CREATE:
printf(HDR VALS VALS VALS,
"create", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"name", nams1,
"mode bits", type);
break;
case DM_EVENT_POSTCREATE:
printf(HDR VALS VALS VALS VALS VALD,
"postcreate", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"new object", hans2,
"name", nams1,
"mode bits", type,
"retcode", msg_ne->ne_retcode);
break;
case DM_EVENT_REMOVE:
printf(HDR VALS VALS VALS,
"remove", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"name", nams1,
"mode bits", type);
break;
case DM_EVENT_POSTREMOVE:
printf(HDR VALS VALS VALS VALD,
"postremove", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"name", nams1,
"mode bits", type,
"retcode", msg_ne->ne_retcode);
break;
case DM_EVENT_RENAME:
printf(HDR VALS VALS VALS VALS,
"rename", msg->ev_token, msg->ev_sequence,
"old parent", hans1,
"new parent", hans2,
"old name", nams1,
"new name", nams2);
break;
case DM_EVENT_POSTRENAME:
printf(HDR VALS VALS VALS VALS VALD,
"postrename", msg->ev_token, msg->ev_sequence,
"old parent", hans1,
"new parent", hans2,
"old name", nams1,
"new name", nams2,
"retcode", msg_ne->ne_retcode);
break;
case DM_EVENT_SYMLINK:
printf(HDR VALS VALS VALS,
"symlink", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"name", nams1,
"contents", nams2);
break;
case DM_EVENT_POSTSYMLINK:
printf(HDR VALS VALS VALS VALS VALD,
"postsymlink", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"new object", hans2,
"name", nams1,
"contents", nams2,
"retcode", msg_ne->ne_retcode);
break;
case DM_EVENT_LINK:
printf(HDR VALS VALS VALS,
"link", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"source", hans2,
"name", nams1);
break;
case DM_EVENT_POSTLINK:
printf(HDR VALS VALS VALS VALD,
"postlink", msg->ev_token, msg->ev_sequence,
"parent dir", hans1,
"source", hans2,
"name", nams1,
"retcode", msg_ne->ne_retcode);
break;
case DM_EVENT_ATTRIBUTE:
printf(HDR VALS,
"attribute", msg->ev_token, msg->ev_sequence,
"object", hans1);
break;
case DM_EVENT_CLOSE: /* not supported on SGI */
printf(HDR VALS,
"close", msg->ev_token, msg->ev_sequence,
"object", hans1);
break;
default:
pkt_error++;
printf(HDR VALD,
"<UNKNOWN>", msg->ev_token, msg->ev_sequence,
"ev_type", msg->ev_type);
break;
}
}
return(pkt_error);
}
int
handle_message(
dm_sessid_t sid,
dm_eventmsg_t *msg)
{
dm_response_t response;
int respond, respcode;
int error = 0;
if (print_one_message(msg))
error++;
/* Set the defaults for responding to events. */
respond = 1;
response = DM_RESP_CONTINUE;
respcode = 0;
/***** USER EVENTS *****/
switch (msg->ev_type) {
case DM_EVENT_USER:
if (msg->ev_token == DM_INVALID_TOKEN)
respond = 0;
break;
case DM_EVENT_CANCEL:
case DM_EVENT_DESTROY:
case DM_EVENT_POSTCREATE:
case DM_EVENT_POSTREMOVE:
case DM_EVENT_POSTRENAME:
case DM_EVENT_POSTSYMLINK:
case DM_EVENT_POSTLINK:
case DM_EVENT_ATTRIBUTE:
case DM_EVENT_CLOSE:
respond = 0;
break;
case DM_EVENT_MOUNT:
case DM_EVENT_READ:
case DM_EVENT_WRITE:
case DM_EVENT_TRUNCATE:
case DM_EVENT_PREUNMOUNT:
case DM_EVENT_UNMOUNT:
case DM_EVENT_DEBUT:
case DM_EVENT_CREATE:
case DM_EVENT_REMOVE:
case DM_EVENT_RENAME:
case DM_EVENT_SYMLINK:
case DM_EVENT_LINK:
break;
case DM_EVENT_NOSPACE:
response = DM_RESP_ABORT;
respcode = ENOSPC;
break;
default:
if (msg->ev_token == DM_INVALID_TOKEN)
respond = 0;
break;
}
/* Respond to those messages which require a response. */
if (respond) {
if (dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0)) {
errno_msg("Can't respond to event");
}
}
return(error);
}