4ea3c057bf98100c0a8927c21941275e5e407db0
[xfstests-dev.git] / dmapi / src / common / cmd / read_invis.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6
7 #include <ctype.h>
8
9 #include <lib/hsm.h>
10
11 #include <string.h>
12 #include <malloc.h>
13 #include <unistd.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17
18 /*---------------------------------------------------------------------------
19
20 Test program used to test the DMAPI function dm_read_invis().  The
21 command line is:
22
23         read_invis [-o offset] [-l length] [-s sid] [-c char] \
24                 [-S storefile] {pathname|handle}
25
26 where:
27 'offset' is the offset of the start of the write (0 is the default),
28 'length' is the length of the write in bytes (1 is the default),
29 'sid' is the session ID whose events you you are interested in.
30 'pathname' is the name of the file to be written.
31 'char' is ignored--it just allows read_invis and write_invis to have
32     interchangeable commandlines without having to fuss with the params.
33
34 ----------------------------------------------------------------------------*/
35
36 #ifndef linux
37 extern  char    *sys_errlist[];
38 #endif
39 extern  int     optind;
40 extern  char    *optarg;
41
42
43 char    *Progname;
44
45
46 static void
47 usage(void)
48 {
49         fprintf(stderr, "usage:\t%s [-o offset] [-l length] "
50                 "[-s sid] [-c char] "
51                 "[-S storefile] {pathname|handle}\n", Progname);
52         exit(1);
53 }
54
55
56 int
57 main(
58         int     argc, 
59         char    **argv)
60 {
61         dm_sessid_t     sid = DM_NO_SESSION;
62         char            *object = NULL;
63         dm_off_t        offset = 0;
64         long long       lltemp;
65         dm_size_t       length = 1;
66         unsigned long long      ulltemp;
67         char            *bufp = NULL;
68         void            *hanp;
69         size_t          hlen;
70         dm_ssize_t      rc;
71         char            *name;
72         int             opt;
73         int             i;
74         char            *storefile = NULL;
75         int             storefd = 0;
76         int             exit_status = 0;
77
78         Progname = strrchr(argv[0], '/');
79         if (Progname) {
80                 Progname++;
81         } else {
82                 Progname = argv[0];
83         }
84
85         /* Crack and validate the command line options. */
86
87         while ((opt = getopt(argc, argv, "o:l:s:c:S:")) != EOF) {
88                 switch (opt) {
89                 case 'o':
90                         sscanf(optarg, "%lld", &lltemp);
91                         offset = (dm_off_t) lltemp;
92                         break;
93                 case 'l':
94                         sscanf(optarg, "%llu", &ulltemp);
95                         length = (dm_size_t) ulltemp;
96                         break;
97                 case 's':
98                         sid = atol(optarg);
99                         break;
100                 case 'c':
101                         /* This is a no-op, it just allows read_invis
102                          * and write_invis to have interchangeable
103                          * commandlines, without having to fuss with
104                          * the params.
105                          */
106                         break;
107                 case 'S':
108                         storefile = optarg;
109                         break;
110                 case '?':
111                         usage();
112                 }
113         }
114         if (optind + 1 != argc)
115                 usage();
116         object = argv[optind];
117
118         if (dm_init_service(&name) == -1)  {
119                 fprintf(stderr, "Can't initialize the DMAPI\n");
120                 exit(1);
121         }
122         if (sid == DM_NO_SESSION)
123                 find_test_session(&sid);
124
125         /* Get the file's handle. */
126
127         if (opaque_to_handle(object, &hanp, &hlen)) {
128                 fprintf(stderr, "can't get handle for %s\n", object);
129                 exit(1);
130         }
131
132         if (length > 0) {
133                 /* In case it is a realtime file, align the buffer on a
134                    sufficiently big boundary.
135                 */
136                 if ((bufp = memalign(4096, length)) == NULL) {
137                         fprintf(stderr, "malloc of %llu bytes failed\n",
138                                 (unsigned long long) length);
139                         exit(1);
140                 }
141                 memset(bufp, '\0', length);
142         }
143
144         if (storefile) {
145                 off_t   lret;
146
147                 if ((storefd = open(storefile, O_WRONLY|O_CREAT, 0777)) == -1) {
148                         fprintf(stderr, "unable to open store file for write (%s), errno = %d\n", storefile, errno);
149                         exit(1);
150                 }
151                 lret = lseek(storefd, offset, SEEK_SET);
152                 if (lret < 0) {
153                         fprintf(stderr, "unable to lseek(%s) to offset %lld, errno = %d\n",
154                                 storefile, (long long)lret, errno);
155                         exit(1);
156                 }
157         }
158
159         rc = dm_read_invis(sid, hanp, hlen, DM_NO_TOKEN, offset, length, bufp);
160
161         if (rc < 0) {
162                 fprintf(stderr, "dm_read_invis failed, %s\n", strerror(errno));
163                 exit_status++;
164         } else if (rc != length) {
165                 fprintf(stderr, "dm_read_invis expected to read %llu bytes, actually "
166                         "read %lld\n", (unsigned long long) length,
167                         (long long) rc);
168                 exit_status++;
169         }
170
171         if (storefile) {
172                 ssize_t sret;
173                 sret = write(storefd, bufp, rc);
174                 if (sret < 0) {
175                         fprintf(stderr, "unable to write to store file (%s), errno = %d\n", storefile, errno);
176                         exit_status++;
177                 }
178                 else if (sret != rc) {
179                         fprintf(stderr, "write(%s) returned %lld, expected %lld\n",
180                                 storefile, (long long)sret, (long long)rc);
181                         exit_status++;
182                 }
183                 close(storefd);
184         }
185         else {
186                 for (i = 0; i < rc; i++) {
187                         if (isprint(bufp[i])) {
188                                 fprintf(stdout, "%c", bufp[i]);
189                         } else {
190                                 fprintf(stdout, "\\%03d", bufp[i]);
191                         }
192                 }
193         }
194         dm_handle_free(hanp, hlen);
195         exit(exit_status);
196 }