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