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