373064f98aba9423eebf27f1092ea925fb43bce4
[xfstests-dev.git] / dmapi / src / common / lib / print.c
1 /*
2  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 #include <sys/types.h>
20 #include <sys/param.h>
21 #include <sys/stat.h>
22
23 #include <ctype.h>
24
25 #include <lib/hsm.h>
26
27 #include <string.h>
28 #ifdef linux
29 #define MAXNAMELEN 256
30 #endif
31
32   /*
33    * Define some standard formats for the printf statements below.
34    */
35
36 #define HDR  "type=%s token=%d sequence=%d\n"
37 #define VALS "\t%s=%s\n"
38 #define VALD "\t%s=%d\n"
39 #define VALLLD "\t%s=%lld\n"
40
41
42 /*
43         Convert a mode_t field into a printable string.
44
45         Returns non-zero if the mode_t is invalid.  The string is
46         returned in *ptr, whether there is an error or not.
47 */
48
49 int
50 format_mode(
51         mode_t  mode,
52         char    **ptr)
53 {
54 static  char    modestr[100];
55         char    *typestr;
56         int     error = 0;
57
58         if     (S_ISFIFO(mode)) typestr = "FIFO";
59         else if(S_ISCHR (mode)) typestr = "Character Device";
60         else if(S_ISBLK (mode)) typestr = "Block Device";
61         else if(S_ISDIR (mode)) typestr = "Directory";
62         else if(S_ISREG (mode)) typestr = "Regular File";
63         else if(S_ISLNK (mode)) typestr = "Symbolic Link";
64         else if(S_ISSOCK(mode)) typestr = "Socket";
65         else {
66                 typestr = "<unknown type>"; 
67                 error++;
68         }
69
70         sprintf(modestr, "mode %06o: perm %c%c%c %c%c%c %c%c%c %c%c%c, type %s",
71                 mode,
72                 mode & S_ISUID ? 's':' ',
73                 mode & S_ISGID ? 'g':' ',
74                 mode & S_ISVTX ? 't':' ',
75                 mode & S_IRUSR ? 'r':'-',
76                 mode & S_IWUSR ? 'w':'-',
77                 mode & S_IXUSR ? 'x':'-',
78                 mode & S_IRGRP ? 'r':'-',
79                 mode & S_IWGRP ? 'w':'-',
80                 mode & S_IXGRP ? 'x':'-',
81                 mode & S_IROTH ? 'r':'-',
82                 mode & S_IWOTH ? 'w':'-',
83                 mode & S_IXOTH ? 'x':'-',
84                 typestr);
85         *ptr = modestr;
86         return(error);
87 }
88
89
90 void
91 print_one_mount_event(
92         void            *msg)
93 {
94         void            *hanp1, *hanp2, *hanp3;
95         size_t          hlen1, hlen2, hlen3;
96         char            hans1[HANDLE_STR], hans2[HANDLE_STR], hans3[HANDLE_STR];
97         void            *namp1, *namp2;
98         size_t          nlen1, nlen2;
99         char            nams1[MAXNAMELEN], nams2[MAXNAMELEN];
100         mode_t          mode;
101
102 #if     VERITAS_21
103         dm_namesp_event_t  *msg_ne = (dm_namesp_event_t *)msg;
104
105 /*
106         msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
107 */
108         hanp1  = DM_GET_VALUE(msg_ne, ne_handle1, void *);
109         hlen1  = DM_GET_LEN  (msg_ne, ne_handle1);
110         hanp2  = DM_GET_VALUE(msg_ne, ne_handle2, void *);
111         hlen2  = DM_GET_LEN  (msg_ne, ne_handle2);
112         namp1  = DM_GET_VALUE(msg_ne, ne_name1, void *);
113         nlen1  = DM_GET_LEN  (msg_ne, ne_name1);
114         namp2  = DM_GET_VALUE(msg_ne, ne_name2, void *);
115         nlen2  = DM_GET_LEN  (msg_ne, ne_name2);
116         hanp3  = NULL;
117         hlen3  = 0;
118         mode   = msg_ne->ne_mode;
119 #else
120         dm_mount_event_t  *msg_me = (dm_mount_event_t *)msg;
121
122         hanp1 = DM_GET_VALUE(msg_me, me_handle1, void *);
123         hlen1 = DM_GET_LEN(msg_me, me_handle1);
124         hanp2 = DM_GET_VALUE(msg_me, me_handle2, void *);
125         hlen2 = DM_GET_LEN(msg_me, me_handle2);
126         namp1  = DM_GET_VALUE(msg_me, me_name1, void *);
127         nlen1 = DM_GET_LEN(msg_me, me_name1);
128         namp2 = DM_GET_VALUE(msg_me, me_name2, void *);
129         nlen2 = DM_GET_LEN(msg_me, me_name2);
130         hanp3 = DM_GET_VALUE(msg_me, me_roothandle, void *);
131         hlen3 = DM_GET_LEN(msg_me, me_roothandle);
132         mode  = msg_me->me_mode;
133 #endif  /* VERITAS_21 */
134
135         if (hanp1 && hlen1) {
136                 hantoa(hanp1, hlen1, hans1);
137         } else {
138                 sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
139         }
140         if (hanp2 && hlen2) {
141                 hantoa(hanp2, hlen2, hans2);
142         } else {
143                 sprintf(hans2, "<BAD HANDLE, hlen %d>", hlen2);
144         }
145         if (hanp3 && hlen3) {
146                 hantoa(hanp3, hlen3, hans3);
147         } else {
148                 sprintf(hans3, "<BAD HANDLE, hlen %d>", hlen3);
149         }
150         if (namp1 && nlen1) {
151                 strncpy(nams1, namp1, nlen1);
152                 if (nlen1 != sizeof(nams1))
153                         nams1[nlen1] = '\0';
154         } else {
155                 sprintf(nams1, "<BAD STRING, nlen %d>", nlen1);
156         }
157         if (namp2 && nlen2) {
158                 strncpy(nams2, namp2, nlen2);
159                 if (nlen2 != sizeof(nams2))
160                         nams2[nlen2] = '\0';
161         } else {
162                 sprintf(nams2, "<BAD STRING, nlen %d>", nlen2);
163         }
164
165         printf(VALS VALS VALS VALS VALS VALD,
166              "fs handle",       hans1,
167              "mtpt handle",     hans2,
168              "mtpt path",       nams1,
169              "media desig",     nams2,
170              "root handle",     hans3,
171              "mode",            mode);
172 }
173
174
175 static int
176 print_one_data_event(
177         dm_data_event_t *msg_de)
178 {
179         char            handle[HANDLE_STR];
180         void            *hanp;
181         size_t          hlen;
182
183         hanp  = DM_GET_VALUE(msg_de, de_handle, void *);
184         hlen  = DM_GET_LEN  (msg_de, de_handle);
185
186         if (hanp && hlen) {
187                 hantoa(hanp, hlen, handle);
188         } else {
189                 sprintf(handle, "<BAD HANDLE, hlen %d>", hlen);
190         }
191
192         printf(VALS VALLLD VALLLD,
193                 "file_handle",  handle,
194                 "offset", msg_de->de_offset,
195                 "length", msg_de->de_length);
196
197         return(0);
198 }
199
200
201 int
202 print_one_message(
203         dm_eventmsg_t   *msg)
204 {
205         int             pkt_error = 0;
206         dm_namesp_event_t  *msg_ne;
207         void            *hanp1, *hanp2, *namp1, *namp2;
208         u_int           hlen1, hlen2, nlen1, nlen2;
209         char            hans1[HANDLE_STR], hans2[HANDLE_STR];
210         char            nams1[MAXNAMELEN], nams2[MAXNAMELEN];
211
212         /***** USER EVENTS *****/
213
214         if (msg->ev_type == DM_EVENT_USER) {
215     char        *privp;
216     u_int       plen, i;
217
218     printf(HDR,
219                 "user", msg->ev_token, msg->ev_sequence);
220
221     /* print private data as ascii or hex if it exists DM_CONFIG_MAX_MESSAGE_DATA */
222
223     privp = DM_GET_VALUE(msg, ev_data, char *);
224     plen  = DM_GET_LEN  (msg, ev_data);
225     if (plen) {
226         for (i = 0; i < plen; i++) {
227                 if (!isprint(privp[i]) && !isspace(privp[i]))
228                         break;
229         }
230         if (i == plen - 1 && privp[i] == '\0') {
231           printf(VALS,
232                         "privdata", privp);
233         } else {
234           printf("\t%-15s ", "privdata");
235           for (i = 0; i < plen; i++) {
236             printf("%.2x", privp[i]);
237           }
238           printf("\n");
239         }
240     } else {
241         printf(VALS,
242                 "privdata", "<NONE>");
243     }
244
245         /***** CANCEL EVENT *****/
246
247 /* Not implemented on SGI or Veritas */
248
249         } else if (msg->ev_type == DM_EVENT_CANCEL) {
250                 dm_cancel_event_t       *msg_ce;
251
252                 msg_ce = DM_GET_VALUE(msg, ev_data, dm_cancel_event_t *);
253                 printf(HDR VALD VALD,
254                         "cancel", msg->ev_token, msg->ev_sequence,
255                         "sequence", msg_ce->ce_sequence,
256                         "token", msg_ce->ce_token);
257
258         /***** DATA EVENTS *****/
259
260         } else if (msg->ev_type == DM_EVENT_READ ||
261                    msg->ev_type == DM_EVENT_WRITE ||
262                    msg->ev_type == DM_EVENT_TRUNCATE) {
263                 dm_data_event_t *msg_de;
264
265                 msg_de = DM_GET_VALUE(msg, ev_data, dm_data_event_t *);
266
267                 switch (msg->ev_type) {
268                 case DM_EVENT_READ:
269                         printf(HDR, "read", msg->ev_token, msg->ev_sequence);
270                         break;
271
272                 case DM_EVENT_WRITE:
273                         printf(HDR, "write", msg->ev_token, msg->ev_sequence);
274                         break;
275
276                 case DM_EVENT_TRUNCATE:
277                         printf(HDR, "truncate", msg->ev_token,
278                                 msg->ev_sequence);
279                         break;
280                 default: break;
281                 }
282                 print_one_data_event(msg_de);
283
284   /***** DESTROY EVENT *****/
285
286         } else if (msg->ev_type == DM_EVENT_DESTROY) {
287     dm_destroy_event_t  *msg_ds;
288     char                attrname[DM_ATTR_NAME_SIZE + 1];
289     u_char              *copy;
290     u_int               clen;
291     u_int               i;
292
293     msg_ds= DM_GET_VALUE(msg, ev_data, dm_destroy_event_t *);
294     hanp1  = DM_GET_VALUE(msg_ds, ds_handle, void *);
295     hlen1  = DM_GET_LEN  (msg_ds, ds_handle);
296     if (hanp1 && hlen1) {
297       hantoa(hanp1, hlen1, hans1);
298     } else {
299       sprintf(hans1, "<BAD HANDLE, hlen %d>", hlen1);
300     }
301     if (msg_ds->ds_attrname.an_chars[0] != '\0') {
302       strncpy(attrname, (char *)msg_ds->ds_attrname.an_chars, sizeof(attrname));
303     } else {
304       strcpy(attrname, "<NONE>");
305     }
306     printf(HDR VALS VALS,
307              "destroy", msg->ev_token, msg->ev_sequence,
308              "handle",          hans1,
309              "attrname",        attrname);
310     copy  = DM_GET_VALUE(msg_ds, ds_attrcopy, u_char *);
311     clen  = DM_GET_LEN  (msg_ds, ds_attrcopy);
312     if (copy && clen) {
313       printf("\t%-15s ", "attrcopy");
314       for (i = 0; i < clen; i++) {
315         printf("%.2x", copy[i]);
316       }
317       printf("\n");
318     } else {
319       printf(VALS, "attrcopy", "<NONE>");
320     }
321
322   /***** MOUNT EVENT *****/
323
324         } else if (msg->ev_type == DM_EVENT_MOUNT) {
325                 void    *msg_body;
326
327                 printf(HDR, "mount", msg->ev_token, msg->ev_sequence);
328 #if     !VERITAS_21
329                 msg_body = DM_GET_VALUE(msg, ev_data, dm_mount_event_t *);
330 #else   /* VERITAS_21 */
331                 msg_body = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
332 #endif  /* VERITAS_21 */
333                 print_one_mount_event(msg_body);
334
335   /***** NAMESPACE EVENTS *****/
336
337         } else {
338     char        *type;
339
340     msg_ne = DM_GET_VALUE(msg, ev_data, dm_namesp_event_t *);
341     hanp1  = DM_GET_VALUE(msg_ne, ne_handle1, void *);
342     hlen1  = DM_GET_LEN  (msg_ne, ne_handle1);
343     hanp2  = DM_GET_VALUE(msg_ne, ne_handle2, void *);
344     hlen2  = DM_GET_LEN  (msg_ne, ne_handle2);
345     namp1  = DM_GET_VALUE(msg_ne, ne_name1, void *);
346     nlen1  = DM_GET_LEN  (msg_ne, ne_name1);
347     namp2  = DM_GET_VALUE(msg_ne, ne_name2, void *);
348     nlen2  = DM_GET_LEN  (msg_ne, ne_name2);
349
350     if (hanp1 && hlen1) {
351       hantoa(hanp1, hlen1, hans1);
352     }
353     if (hanp2 && hlen2) {
354       hantoa(hanp2, hlen2, hans2);
355     }
356     if (namp1 && nlen1) {
357       strncpy(nams1, namp1, nlen1);
358       if (nlen1 != sizeof(nams1))
359         nams1[nlen1] = '\0';
360     }
361     if (namp2 && nlen2) {
362       strncpy(nams2, namp2, nlen2);
363       if (nlen2 != sizeof(nams2))
364         nams2[nlen2] = '\0';
365     }
366
367     if (msg->ev_type == DM_EVENT_PREUNMOUNT ||
368         msg->ev_type == DM_EVENT_UNMOUNT) {
369       if (msg_ne->ne_mode == 0) {
370         type = "NOFORCE";
371 #if     !VERITAS_21
372       } else if (msg_ne->ne_mode == DM_UNMOUNT_FORCE) {
373 #else
374       } else if (msg_ne->ne_mode > 0) {
375 #endif
376         type = "FORCE";
377       } else {
378         type = "UNKNOWN";
379         pkt_error++;
380       }
381     } else if (msg->ev_type == DM_EVENT_CREATE ||
382                msg->ev_type == DM_EVENT_POSTCREATE ||
383                msg->ev_type == DM_EVENT_REMOVE ||
384                msg->ev_type == DM_EVENT_POSTREMOVE) {
385         if (format_mode(msg_ne->ne_mode, &type)) {
386           pkt_error++;
387         }
388     }
389
390     switch(msg->ev_type) {
391
392     case DM_EVENT_PREUNMOUNT:
393       printf(HDR VALS VALS VALS,
394              "preunmount", msg->ev_token, msg->ev_sequence,
395              "fs handle",       hans1,
396              "root dir",        hans2,
397              "unmount mode",    type);
398       break;
399
400     case DM_EVENT_UNMOUNT:
401       printf(HDR VALS VALS VALD,
402              "unmount", msg->ev_token, msg->ev_sequence,
403              "fs handle",       hans1,
404              "unmount mode",    type,
405              "retcode",         msg_ne->ne_retcode);
406       break;
407
408     case DM_EVENT_NOSPACE:
409       printf(HDR VALS,
410              "nospace", msg->ev_token, msg->ev_sequence,
411              "fs handle",       hans1);
412       break;
413
414     case DM_EVENT_DEBUT:                /* not supported on SGI */
415       printf(HDR VALS,
416              "debut", msg->ev_token, msg->ev_sequence,
417              "object",          hans1);
418       break;
419
420     case DM_EVENT_CREATE:
421       printf(HDR VALS VALS VALS,
422              "create", msg->ev_token, msg->ev_sequence,
423              "parent dir",      hans1,
424              "name",            nams1,
425              "mode bits",       type);
426       break;
427
428     case DM_EVENT_POSTCREATE:
429       printf(HDR VALS VALS VALS VALS VALD,
430              "postcreate", msg->ev_token, msg->ev_sequence,
431              "parent dir",      hans1,
432              "new object",      hans2,
433              "name",            nams1,
434              "mode bits",       type,
435              "retcode",         msg_ne->ne_retcode);
436       break;
437
438     case DM_EVENT_REMOVE:
439       printf(HDR VALS VALS VALS,
440              "remove", msg->ev_token, msg->ev_sequence,
441              "parent dir",      hans1,
442              "name",            nams1,
443              "mode bits",       type);
444       break;
445
446     case DM_EVENT_POSTREMOVE:
447       printf(HDR VALS VALS VALS VALD,
448              "postremove", msg->ev_token, msg->ev_sequence,
449              "parent dir",      hans1,
450              "name",            nams1,
451              "mode bits",       type,
452              "retcode",         msg_ne->ne_retcode);
453       break;
454
455     case DM_EVENT_RENAME:
456       printf(HDR VALS VALS VALS VALS,
457              "rename", msg->ev_token, msg->ev_sequence,
458              "old parent",      hans1,
459              "new parent",      hans2,
460              "old name",        nams1,
461              "new name",        nams2);
462       break;
463
464     case DM_EVENT_POSTRENAME:
465       printf(HDR VALS VALS VALS VALS VALD,
466              "postrename", msg->ev_token, msg->ev_sequence,
467              "old parent",      hans1,
468              "new parent",      hans2,
469              "old name",        nams1,
470              "new name",        nams2,
471              "retcode",         msg_ne->ne_retcode);
472       break;
473
474     case DM_EVENT_SYMLINK:
475       printf(HDR VALS VALS VALS,
476              "symlink", msg->ev_token, msg->ev_sequence,
477              "parent dir",      hans1,
478              "name",            nams1,
479              "contents",        nams2);
480       break;
481
482     case DM_EVENT_POSTSYMLINK:
483       printf(HDR VALS VALS VALS VALS VALD,
484              "postsymlink", msg->ev_token, msg->ev_sequence,
485              "parent dir",      hans1,
486              "new object",      hans2,
487              "name",            nams1,
488              "contents",        nams2,
489              "retcode",         msg_ne->ne_retcode);
490       break;
491
492     case DM_EVENT_LINK:
493       printf(HDR VALS VALS VALS,
494              "link", msg->ev_token, msg->ev_sequence,
495              "parent dir",      hans1,
496              "source",          hans2,
497              "name",            nams1);
498       break;
499
500     case DM_EVENT_POSTLINK:
501       printf(HDR VALS VALS VALS VALD,
502              "postlink", msg->ev_token, msg->ev_sequence,
503              "parent dir",      hans1,
504              "source",          hans2,
505              "name",            nams1,
506              "retcode",         msg_ne->ne_retcode);
507       break;
508
509     case DM_EVENT_ATTRIBUTE:
510       printf(HDR VALS,
511              "attribute", msg->ev_token, msg->ev_sequence,
512              "object",          hans1);
513       break;
514
515     case DM_EVENT_CLOSE:        /* not supported on SGI */
516       printf(HDR VALS,
517              "close", msg->ev_token, msg->ev_sequence,
518              "object",          hans1);
519       break;
520
521     default:
522       pkt_error++;
523       printf(HDR VALD,
524              "<UNKNOWN>", msg->ev_token, msg->ev_sequence,
525              "ev_type",         msg->ev_type);
526       break;
527     }
528         }
529         return(pkt_error);
530 }
531
532
533 int
534 handle_message(
535         dm_sessid_t     sid,
536         dm_eventmsg_t   *msg)
537 {
538         dm_response_t   response;
539         int             respond, respcode;
540         int             error = 0;
541
542         if (print_one_message(msg))
543                 error++;
544
545         /* Set the defaults for responding to events. */
546
547         respond = 1;
548         response = DM_RESP_CONTINUE;
549         respcode = 0;
550
551         /***** USER EVENTS *****/
552
553         switch (msg->ev_type) {
554         case DM_EVENT_USER:
555                 if (msg->ev_token == DM_INVALID_TOKEN)
556                         respond = 0;
557                 break;
558
559         case DM_EVENT_CANCEL:
560         case DM_EVENT_DESTROY:
561         case DM_EVENT_POSTCREATE:
562         case DM_EVENT_POSTREMOVE:
563         case DM_EVENT_POSTRENAME:
564         case DM_EVENT_POSTSYMLINK:
565         case DM_EVENT_POSTLINK:
566         case DM_EVENT_ATTRIBUTE:
567         case DM_EVENT_CLOSE:
568                 respond = 0;
569                 break;
570
571         case DM_EVENT_MOUNT:
572         case DM_EVENT_READ:
573         case DM_EVENT_WRITE:
574         case DM_EVENT_TRUNCATE:
575         case DM_EVENT_PREUNMOUNT:
576         case DM_EVENT_UNMOUNT:
577         case DM_EVENT_DEBUT:
578         case DM_EVENT_CREATE:
579         case DM_EVENT_REMOVE:
580         case DM_EVENT_RENAME:
581         case DM_EVENT_SYMLINK:
582         case DM_EVENT_LINK:
583                 break;
584
585         case DM_EVENT_NOSPACE:
586                 response = DM_RESP_ABORT;
587                 respcode = ENOSPC;
588                 break;
589
590         default:
591                 if (msg->ev_token == DM_INVALID_TOKEN)
592                         respond = 0;
593                 break;
594         }
595
596         /* Respond to those messages which require a response. */
597
598         if (respond) {
599                 if (dm_respond_event(sid, msg->ev_token, response, respcode, 0, 0)) {
600                         errno_msg("Can't respond to event");
601                 }
602         }
603         return(error);
604 }