butc-xbsa-20040713
[openafs.git] / src / butc / butc_xbsa.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #ifdef xbsa
11
12 #include <afsconfig.h>
13 #include <afs/param.h>
14
15 RCSID
16     ("$Header$");
17
18 #include <sys/types.h>
19 #include <afs/stds.h>
20 #include <stdio.h>
21 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
22 #include <dlfcn.h>
23 #endif
24 #include <errno.h>
25 #include "butc_xbsa.h"
26 #include <afs/butx.h>
27 #include <afs/bubasics.h>
28
29 #include "error_macros.h"
30
31 extern int debugLevel;
32
33
34 char resourceType[20] = "LFS FILE SYSTEM";
35 #define GOODSTR(s) ((s)?(s):"<NULL>")
36
37 BSA_Int16(*XBSAInit) (BSA_UInt32 *, SecurityToken *, ObjectOwner *, char **);
38 BSA_Int16(*XBSABeginTxn) (BSA_UInt32);
39 BSA_Int16(*XBSAEndTxn) (BSA_UInt32, Vote);
40 BSA_Int16(*XBSATerminate) (BSA_UInt32);
41 BSA_Int16(*XBSAQueryObject) (BSA_UInt32, QueryDescriptor *,
42                              ObjectDescriptor *);
43 BSA_Int16(*XBSAGetObject) (BSA_UInt32, ObjectDescriptor *, DataBlock *);
44 BSA_Int16(*XBSAEndData) (BSA_UInt32);
45 BSA_Int16(*XBSACreateObject) (BSA_UInt32, ObjectDescriptor *, DataBlock *);
46 BSA_Int16(*XBSADeleteObject) (BSA_UInt32, CopyType, ObjectName *, CopyId *);
47 BSA_Int16(*XBSAMarkObjectInactive) (BSA_UInt32, ObjectName *);
48 BSA_Int16(*XBSASendData) (BSA_UInt32, DataBlock *);
49 BSA_Int16(*XBSAGetData) (BSA_UInt32, DataBlock *);
50 BSA_Int16(*XBSAQueryApiVersion) (ApiVersion *);
51 BSA_Int16(*XBSAGetEnvironment) (BSA_UInt32, ObjectOwner *, char **);
52
53
54 xbsa_error(int rc, struct butx_transactionInfo *info)
55 {
56     switch (rc) {
57     case BSA_RC_AUTHENTICATION_FAILURE:
58         ELog(0, "     XBSA: Authentication failure\n");
59         break;
60     case BSA_RC_INVALID_KEYWORD:
61         ELog(0, "     XBSA: A specified keyword is invalid\n");
62         break;
63     case BSA_RC_TOKEN_EXPIRED:
64         ELog(0, "     XBSA: The security token has expired\n");
65         break;
66     case ADSM_RC_PSWD_GEN:
67         if (XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM) {
68             ELog(0, "     XBSA: Password generation is not supported\n");
69         }
70         break;
71     case BSA_RC_BAD_HANDLE:
72         ELog(0, "     XBSA: The handle is invalid, %d\n", info->bsaHandle);
73         break;
74     case BSA_RC_NO_MATCH:
75         ELog(0,
76              "     XBSA: There were no matches found for the specified object\n");
77         break;
78     case BSA_RC_MORE_DATA:
79         ELog(0, "     XBSA: There were more matches found than expected\n");
80         break;
81     case BSA_RC_NULL_OBJNAME:
82         ELog(0, "     XBSA: The object name is null\n");
83         break;
84     case BSA_RC_OBJNAME_TOO_LONG:
85         ELog(0, "     XBSA: The object name was longer than expected\n");
86         break;
87     case BSA_RC_DESC_TOO_LONG:
88         ELog(0,
89              "     XBSA: The description string was longer than expected\n");
90         break;
91     case BSA_RC_OBJINFO_TOO_LONG:
92         ELog(0,
93              "     XBSA: The object info string was longer than expected\n");
94         break;
95     case BSA_RC_ABORT_ACTIVE_NOT_FOUND:
96         ELog(0, "     XBSA: The specified object was not found\n");
97         break;
98     case BSA_RC_NULL_DATABLKPTR:
99         ELog(0, "     XBSA: The dataBlockPtr is null\n");
100         break;
101     case BSA_RC_INVALID_VOTE:
102         ELog(0, "     XBSA: The vote variable is invalid\n");
103         break;
104     }
105 }
106
107 /*
108  * Hook into the correct XBSA shared library.
109  * Set up the function pointers.
110  * Get the library version.
111  * XBSAQueryApiVersion
112  */
113 afs_int32
114 xbsa_MountLibrary(struct butx_transactionInfo *info, afs_int32 serverType)
115 {
116     void *dynlib;
117     int rc;
118
119     if (debugLevel > 98) {
120         printf("\nxbsa_MountLibraray\n");
121     }
122
123     switch (serverType) {
124     case XBSA_SERVER_TYPE_ADSM:
125 #if defined(AFS_AIX_ENV)
126         dynlib =
127             dlopen("/usr/lib/libXApi.a(bsashr10.o)",
128                    RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
129         if (dynlib == NULL) {
130             dynlib =
131                 dlopen("/usr/lib/libXApi.a(xbsa.o)",
132                        RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
133         }
134 #elif defined(AFS_SUN5_ENV)
135         dynlib = dlopen("/usr/lib/libXApi.so", RTLD_NOW | RTLD_LOCAL);
136 #else
137         dynlib = NULL;
138 #endif
139         break;
140     default:
141         ELog(0, "xbsa_MountLibrary: The serverType %d is not recognized\n",
142              serverType);
143         return (BUTX_INVALIDSERVERTYPE);
144         break;
145     }
146
147     if (dynlib == NULL) {
148         ELog(0,
149              "xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
150         return (BUTX_NOLIBRARY);
151     }
152
153     memset(info, 0, sizeof(struct butx_transactionInfo));
154     XBSA_SET_SERVER_TYPE(info->serverType, serverType);
155
156 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV)
157     XBSAInit = (BSA_Int16(*)
158                 (BSA_UInt32 *, SecurityToken *, ObjectOwner *,
159                  char **))dlsym((void *)dynlib, "BSAInit");
160     XBSABeginTxn =
161         (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSABeginTxn");
162     XBSAEndTxn =
163         (BSA_Int16(*)(BSA_UInt32, Vote)) dlsym((void *)dynlib, "BSAEndTxn");
164     XBSATerminate =
165         (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSATerminate");
166     XBSAQueryObject =
167         (BSA_Int16(*)(BSA_UInt32, QueryDescriptor *, ObjectDescriptor *))
168         dlsym((void *)dynlib, "BSAQueryObject");
169     XBSAGetObject =
170         (BSA_Int16(*)(BSA_UInt32, ObjectDescriptor *, DataBlock *))
171         dlsym((void *)dynlib, "BSAGetObject");
172     XBSAEndData =
173         (BSA_Int16(*)(BSA_UInt32)) dlsym((void *)dynlib, "BSAEndData");
174     XBSACreateObject =
175         (BSA_Int16(*)(BSA_UInt32, ObjectDescriptor *, DataBlock *))
176         dlsym((void *)dynlib, "BSACreateObject");
177     XBSAMarkObjectInactive =
178         (BSA_Int16(*)(BSA_UInt32, ObjectName *)) dlsym((void *)dynlib,
179                                                        "BSAMarkObjectInactive");
180     XBSADeleteObject =
181         (BSA_Int16(*)(BSA_UInt32, CopyType, ObjectName *, CopyId *))
182         dlsym((void *)dynlib, "BSADeleteObject");
183     XBSASendData =
184         (BSA_Int16(*)(BSA_UInt32, DataBlock *)) dlsym((void *)dynlib,
185                                                       "BSASendData");
186     XBSAGetData =
187         (BSA_Int16(*)(BSA_UInt32, DataBlock *)) dlsym((void *)dynlib,
188                                                       "BSAGetData");
189     XBSAQueryApiVersion =
190         (BSA_Int16(*)(ApiVersion *)) dlsym((void *)dynlib,
191                                            "BSAQueryApiVersion");
192     XBSAGetEnvironment =
193         (BSA_Int16(*)(BSA_UInt32, ObjectOwner *, char **))dlsym((void *)
194                                                                 dynlib,
195                                                                 "BSAGetEnvironment");
196
197     if (!XBSAInit || !XBSABeginTxn || !XBSAEndTxn || !XBSATerminate
198         || !XBSAQueryObject || !XBSAGetObject || !XBSAEndData
199         || !XBSACreateObject || !XBSADeleteObject || !XBSAMarkObjectInactive
200         || !XBSASendData || !XBSAGetData || !XBSAQueryApiVersion
201         || !XBSAGetEnvironment) {
202         ELog(0,
203              "xbsa_MountLibrary: The dlopen call to load the XBSA shared library failed\n");
204         return (BUTX_NOLIBRARY);
205     }
206
207     XBSAQueryApiVersion(&(info->apiVersion));
208 #endif
209
210     /*
211      * Verify the API version
212      */
213     if ((info->apiVersion.version == XBSA_TS_VERSION)
214         && (info->apiVersion.release == XBSA_TS_RELEASE)) {
215         /* XOPEN Techincal Standard Level! 
216          * We are coded to the Preliminary Spec!  Time to go boom!
217          */
218         ELog(0,
219              "xbsa_MountLibrary: The XBSAQueryApiVersion call returned an incompatible version, %d %d %d\n",
220              info->apiVersion.version, info->apiVersion.release,
221              info->apiVersion.level);
222         return (BUTX_INVALIDVERSION);
223     }
224
225     switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
226     case XBSA_SERVER_TYPE_ADSM:
227         if ((info->apiVersion.version > XBSA_ADSM_NO_MULT_SERVER_VERSION)
228             || (info->apiVersion.version == XBSA_ADSM_NO_MULT_SERVER_VERSION
229                 && info->apiVersion.release >
230                 XBSA_ADSM_NO_MULT_SERVER_RELEASE)
231             || (info->apiVersion.version == XBSA_ADSM_NO_MULT_SERVER_VERSION
232                 && info->apiVersion.release ==
233                 XBSA_ADSM_NO_MULT_SERVER_RELEASE
234                 && info->apiVersion.level > XBSA_ADSM_NO_MULT_SERVER_LEVEL)) {
235
236             /* This version contains the fixes to allow multiple servers */
237             info->serverType |= XBSA_SERVER_FLAG_MULTIPLE;
238         } else {
239             /* This is an older version of ADSM prior to the fix to
240              * allow multiple servers.
241              */
242             info->serverType |= XBSA_SERVER_FLAG_NONE;
243         }
244         break;
245     }
246
247     return (XBSA_SUCCESS);
248
249 }
250
251 /*
252  * Set up the connection to the XBSA Server.
253  * BSAInit
254  * BSAGetEnvironment
255  */
256 afs_int32
257 xbsa_Initialize(struct butx_transactionInfo * info, char *bsaObjectOwner,
258                 char *appObjectOwner, char *secToken, char *serverName)
259 {
260     char envStrs[XBSA_NUM_ENV_STRS][BSA_MAX_DESC];
261     char *envP[XBSA_NUM_ENV_STRS + 1];
262     char *ADSMMaxObject = "MAXOBJ=";
263     char *ADSMServer = "DSMSRVR=";
264     char *tempStrPtr;
265     int i;
266     int rc;
267
268     if (debugLevel > 98) {
269         printf("\nxbsa_Initialize bsaObjectOwner='%s' appObjectOwner='%s' "
270                "secToken=xxxxxx servername='%s'\n", GOODSTR(bsaObjectOwner),
271                GOODSTR(appObjectOwner), GOODSTR(serverName));
272     }
273
274     if (info->bsaHandle != 0) {
275         /* We already have a handle */
276         ELog(0,
277              "xbsa_Initialize: The dlopen call to load the XBSA shared library failed\n");
278         return (BUTX_ILLEGALINIT);
279     }
280
281     /*
282      * The XBSAGetEnvironment function is supposed to return the
283      * the serverName to use.  However, it is returning the tcpserveraddress
284      * instead.  So, we can't count on this function to properly fill it
285      * in.  So, until that get fixed.  The serverName will have to be filled
286      * in by the callers of this function (butc).
287      */
288
289     /* Initialize the environment strings */
290     for (i = 0; i < XBSA_NUM_ENV_STRS; i++)
291         envP[i] = envStrs[i];
292     envP[XBSA_NUM_ENV_STRS] = NULL;
293
294     /* The environment variables are specific to the server type */
295     switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
296     case XBSA_SERVER_TYPE_ADSM:
297         if (serverName) {
298             if (strlen(serverName) >= BSA_MAX_DESC) {
299                 ELog(0,
300                      "xbsa_Initialize: The serverName was not specified\n");
301                 return (BUTX_INVALIDSERVERNAME);
302             }
303             strcpy(info->serverName, serverName);
304             strcpy(envP[0], ADSMServer);
305             tempStrPtr = envP[0];
306             tempStrPtr = tempStrPtr + strlen(ADSMServer);
307             strcat(tempStrPtr, serverName);
308             envP[1] = NULL;
309         } else {
310             envP[0] = NULL;
311             ELog(0, "xbsa_Initialize: The serverName was not specified\n");
312             return (BUTX_INVALIDSERVERNAME);
313         }
314         break;
315     default:
316         ELog(0, "xbsa_Initialize: The serverType %d is not recognized\n",
317              XBSA_GET_SERVER_TYPE(info->serverType));
318         return (BUTX_INVALIDSERVERTYPE);
319         break;
320     }
321
322     if (bsaObjectOwner) {
323         if (strlen(bsaObjectOwner) >= BSA_MAX_BSAOBJECT_OWNER) {
324             ELog(0,
325                  "xbsa_Initialize: The bsaObjectOwner is too long; size = %d; name = %s\n",
326                  strlen(bsaObjectOwner), bsaObjectOwner);
327             return (BUTX_INVALIDBSANAME);
328         }
329         strcpy(info->objOwner.bsaObjectOwner, bsaObjectOwner);
330     } else {
331         info->objOwner.bsaObjectOwner[0] = NULL;
332     }
333
334     if (appObjectOwner) {
335         if (strlen(appObjectOwner) >= BSA_MAX_APPOBJECT_OWNER) {
336             ELog(0,
337                  "xbsa_Initialize: The appObjectOwner is too long; size = %d; name = %s\n",
338                  strlen(appObjectOwner), appObjectOwner);
339             return (BUTX_INVALIDAPPNAME);
340         }
341         strcpy(info->objOwner.appObjectOwner, appObjectOwner);
342     } else {
343         info->objOwner.appObjectOwner[0] = NULL;
344     }
345
346     if (secToken) {
347         if (strlen(secToken) >= BSA_MAX_TOKEN_SIZE) {
348             ELog(0,
349                  "xbsa_Initialize: The secToken is too long; size = %d; name = %s\n",
350                  strlen(secToken), secToken);
351             return (BUTX_INVALIDSECTOKEN);
352         }
353         strcpy(info->secToken, secToken);
354     } else {
355         info->secToken[0] = NULL;
356     }
357
358     rc = (int)XBSAInit(&(info->bsaHandle), &(info->secToken),
359                        &(info->objOwner), envP);
360     if (rc != BSA_RC_SUCCESS) {
361         ELog(0, "xbsa_Initialize: The XBSAInit call failed with %d\n", rc);
362         xbsa_error(rc, info);
363         return (BUTX_INITFAIL);
364     }
365
366     /* Initialize the environment strings */
367     for (i = 0; i < XBSA_NUM_ENV_STRS; i++)
368         envP[i] = envStrs[i];
369     envP[XBSA_NUM_ENV_STRS] = NULL;
370
371     rc = (int)XBSAGetEnvironment(info->bsaHandle, &info->objOwner, envP);
372     if (rc != BSA_RC_SUCCESS) {
373         ELog(0,
374              "xbsa_Initialize: The XBSAGetEnvironment call failed with %d\n",
375              rc);
376         xbsa_error(rc, info);
377         return (BUTX_GETENVFAIL);
378     }
379
380     switch (XBSA_GET_SERVER_TYPE(info->serverType)) {
381     case XBSA_SERVER_TYPE_ADSM:
382         for (i = 0; i < XBSA_NUM_ENV_STRS; i++) {
383             if (strncmp(envP[i], ADSMMaxObject, sizeof(ADSMMaxObject)) == 0) {
384                 tempStrPtr = envP[i];
385                 tempStrPtr = tempStrPtr + strlen(ADSMMaxObject);
386                 info->maxObjects = strtol(tempStrPtr, NULL, 10);
387                 if (info->maxObjects <= 0) {
388                     ELog(0,
389                          "xbsa_Initialize: The XBSAGetEnvironment call returned an invalid value for MAXOBJ %d\n",
390                          info->maxObjects);
391                     return (BUTX_GETENVFAIL);
392                 }
393             }
394         }
395         if (info->maxObjects == 0) {
396             ELog(0,
397                  "xbsa_Initialize: The XBSAGetEnvironment call failed to return the MAXOBJ string\n");
398             return (BUTX_GETENVFAIL);
399         }
400         break;
401     }
402
403     return (XBSA_SUCCESS);
404 }
405
406 /*
407  * Create a transaction
408  * BSABeginTxn
409  */
410 afs_int32
411 xbsa_BeginTrans(struct butx_transactionInfo * info)
412 {
413     int rc;
414
415     if (debugLevel > 98) {
416         printf("\nxbsa_BeginTrans\n");
417         printf
418             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
419              GOODSTR(info->serverName),
420              GOODSTR(info->objOwner.bsaObjectOwner),
421              GOODSTR(info->objOwner.appObjectOwner));
422     }
423
424     if (info->bsaHandle == 0) {
425         /* We haven't initialized yet! */
426         ELog(0, "xbsa_BeginTrans: No current handle, butx not initialized\n");
427         return (BUTX_NOHANDLE);
428     }
429
430     rc = (int)XBSABeginTxn(info->bsaHandle);
431     if (rc != BSA_RC_SUCCESS) {
432         ELog(0, "xbsa_BeginTrans: The XBSABeginTxn call failed with %d\n",
433              rc);
434         xbsa_error(rc, info);
435         return (BUTX_BEGINTXNFAIL);
436     }
437
438     info->numObjects = 0;
439     return (XBSA_SUCCESS);
440 }
441
442 /*
443  * End the current transaction
444  * BSAEndTxn
445  */
446 afs_int32
447 xbsa_EndTrans(struct butx_transactionInfo * info)
448 {
449     int rc;
450
451     if (debugLevel > 98) {
452         printf("\nxbsa_EndTrans\n");
453         printf
454             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
455              GOODSTR(info->serverName),
456              GOODSTR(info->objOwner.bsaObjectOwner),
457              GOODSTR(info->objOwner.appObjectOwner));
458     }
459
460     if (info->bsaHandle == 0) {
461         /* We haven't initialized yet! */
462         ELog(0, "xbsa_EndTrans: No current handle, butx not initialized\n");
463         return (BUTX_NOHANDLE);
464     }
465
466     /* terminate the transaction */
467     rc = (int)XBSAEndTxn(info->bsaHandle, BSAVote_COMMIT);
468     if (rc != BSA_RC_SUCCESS) {
469         ELog(0, "xbsa_EndTrans: The XBSAEndTxn call failed with %d\n", rc);
470         xbsa_error(rc, info);
471         return (BUTX_ENDTXNFAIL);
472     }
473     return (XBSA_SUCCESS);
474 }
475
476 /*
477  * Terminate the connection to the XBSA Server.
478  * End the transaction.
479  * BSATerminate
480  */
481 afs_int32
482 xbsa_Finalize(struct butx_transactionInfo * info)
483 {
484     int rc;
485
486     if (debugLevel > 98) {
487         printf("\nxbsa_Finalize\n");
488         printf
489             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
490              GOODSTR(info->serverName),
491              GOODSTR(info->objOwner.bsaObjectOwner),
492              GOODSTR(info->objOwner.appObjectOwner));
493     }
494
495     if (info->bsaHandle == 0) {
496         /* We haven't initialized yet! */
497         ELog(0, "xbsa_Finalize: No current handle, butx not initialized\n");
498         return (BUTX_NOHANDLE);
499     }
500
501     /* terminate the session */
502     rc = (int)XBSATerminate(info->bsaHandle);
503     if (rc != BSA_RC_SUCCESS) {
504         ELog(0, "The XBSATerminate call failed with %d\n", rc);
505         xbsa_error(rc, info);
506         return (BUTX_TERMFAIL);
507     }
508
509     info->bsaHandle = 0;
510     return (XBSA_SUCCESS);
511 }
512
513 /*
514  * Query for the object we are looking for.
515  * BSAQueryObject
516  */
517 afs_int32
518 xbsa_QueryObject(struct butx_transactionInfo * info, char *objectSpaceName,
519                  char *pathName)
520 {
521     int rc;
522     QueryDescriptor queryDescriptor;
523
524     if (debugLevel > 98) {
525         printf("\nxbsa_QueryObject objectSpaceName='%s' pathnName='%s'\n",
526                GOODSTR(objectSpaceName), GOODSTR(pathName));
527         printf
528             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
529              GOODSTR(info->serverName),
530              GOODSTR(info->objOwner.bsaObjectOwner),
531              GOODSTR(info->objOwner.appObjectOwner));
532     }
533
534     if (info->bsaHandle == 0) {
535         /* We haven't initialized yet! */
536         ELog(0,
537              "xbsa_QueryObject: No current handle, butx not initialized\n");
538         return (BUTX_NOHANDLE);
539     }
540
541     /* Initialize the query for our dump name */
542
543     if (objectSpaceName) {
544         if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
545             ELog(0,
546                  "xbsa_QueryObject: The objectSpaceName is too long; size = %d; name = %s\n",
547                  strlen(objectSpaceName), objectSpaceName);
548             return (BUTX_INVALIDOBJECTSPNAME);
549         }
550         strcpy(queryDescriptor.objName.objectSpaceName, objectSpaceName);
551     } else {
552         queryDescriptor.objName.objectSpaceName[0] = NULL;
553     }
554
555     if (pathName) {
556         if (strlen(pathName) >= BSA_MAX_PATHNAME) {
557             ELog(0,
558                  "xbsa_QueryObject: The pathName is too long; size = %d; name = %s\n",
559                  strlen(pathName), pathName);
560             return (BUTX_INVALIDPATHNAME);
561         }
562         strcpy(queryDescriptor.objName.pathName, pathName);
563     } else {
564         queryDescriptor.objName.pathName[0] = NULL;
565     }
566
567     queryDescriptor.owner = info->objOwner;
568     queryDescriptor.copyType = BSACopyType_BACKUP;
569     strcpy(queryDescriptor.lGName, "");
570     strcpy(queryDescriptor.cGName, "");
571     strcpy(queryDescriptor.resourceType, "");
572     queryDescriptor.objectType = BSAObjectType_FILE;
573     queryDescriptor.status = BSAObjectStatus_ACTIVE;
574     strcpy(queryDescriptor.desc, "");
575
576     rc = (int)XBSAQueryObject(info->bsaHandle, &queryDescriptor,
577                               &info->curObject);
578     if (rc == BSA_RC_NO_MORE_DATA)
579         rc = BSA_RC_SUCCESS;    /* This is actually a success! */
580     if (rc != BSA_RC_SUCCESS) {
581         ELog(0, "xbsa_QueryObject: The xBSAQueryObject call failed with %d\n",
582              rc);
583         xbsa_error(rc, info);
584         return (BUTX_QUERYFAIL);
585     }
586     return (XBSA_SUCCESS);
587 }
588
589 /*
590  * Locate the correct object on the server and then make the call to
591  * get the object descriptor so we can begin the transfer of data.
592  * BSAGetObject
593  */
594 afs_int32
595 xbsa_ReadObjectBegin(struct butx_transactionInfo * info, char *dataBuffer,
596                      afs_int32 bufferSize, afs_int32 * count,
597                      afs_int32 * endOfData)
598 {
599     int rc;
600     DataBlock dataBlock;
601
602     if (debugLevel > 98) {
603         printf("\nxbsa_ReadObjectBegin %d Bytes\n", bufferSize);
604         printf
605             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
606              GOODSTR(info->serverName),
607              GOODSTR(info->objOwner.bsaObjectOwner),
608              GOODSTR(info->objOwner.appObjectOwner));
609     }
610
611     if (info->bsaHandle == 0) {
612         /* We haven't initialized yet! */
613         ELog(0,
614              "xbsa_ReadObjectBegin: No current handle, butx not initialized\n");
615         return (BUTX_NOHANDLE);
616     }
617
618     if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
619         ELog(0, "xbsa_ReadObjectBegin: The bufferSize %d is invalid\n",
620              bufferSize);
621         return (BUTX_INVALIDBUFFERSIZE);
622     }
623
624     if (dataBuffer == NULL) {
625         ELog(0, "xbsa_ReadObjectBegin: The dataBuffer is NULL\n");
626         return (BUTX_INVALIDDATABUFFER);
627     }
628
629     dataBlock.bufferLen = (BSA_UInt16) bufferSize;
630     dataBlock.numBytes = (BSA_UInt16) 0;
631     dataBlock.bufferPtr = dataBuffer;
632     *endOfData = 0;
633
634     rc = (int)XBSAGetObject(info->bsaHandle, &info->curObject, &dataBlock);
635     if ((rc != BSA_RC_MORE_DATA) && (rc != BSA_RC_NO_MORE_DATA)) {
636         ELog(0,
637              "xbsa_ReadObjectBegin: The XBSAGetObject call failed with %d\n",
638              rc);
639         xbsa_error(rc, info);
640         return (BUTX_GETOBJFAIL);
641     }
642     *count = dataBlock.numBytes;
643     if (rc == BSA_RC_NO_MORE_DATA)
644         *endOfData = 1;
645     return (XBSA_SUCCESS);
646 }
647
648
649 /*
650  * Tell the XBSA Server that this is the end of Data for this object.
651  * BSAEndData()
652  */
653 afs_int32
654 xbsa_ReadObjectEnd(struct butx_transactionInfo * info)
655 {
656     int rc;
657
658     if (debugLevel > 98) {
659         printf("\nxbsa_ReadObjectEnd\n");
660         printf
661             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
662              GOODSTR(info->serverName),
663              GOODSTR(info->objOwner.bsaObjectOwner),
664              GOODSTR(info->objOwner.appObjectOwner));
665     }
666
667     if (info->bsaHandle == 0) {
668         /* We haven't initialized yet! */
669         ELog(0,
670              "xbsa_ReadObjectEnd: No current handle, butx not initialized\n");
671         return (BUTX_NOHANDLE);
672     }
673     rc = (int)XBSAEndData(info->bsaHandle);
674     if (rc != BSA_RC_SUCCESS) {
675         ELog(0, "xbsa_ReadObjectEnd: XBSAEndData call failed with %d\n", rc);
676         xbsa_error(rc, info);
677         return (BUTX_ENDDATAFAIL);
678     }
679     return (XBSA_SUCCESS);
680 }
681
682
683 /*
684  * Create the XBSA Backup Copy Object.
685  * BSACreateObject
686  */
687 afs_int32
688 xbsa_WriteObjectBegin(struct butx_transactionInfo * info,
689                       char *objectSpaceName, char *pathName, char *lGName,
690                       afs_hyper_t estimatedSize, char *objectDescription,
691                       char *objectInfo)
692 {
693     int rc;
694     int length;
695     DataBlock dataBlock;
696
697     if (debugLevel > 98) {
698         printf
699             ("\nxbsa_WriteObjectBegin objectSpacename='%s' pathName='%s' lGName='%s' "
700              "estimatesSize='0x%x%08x objectDescription='%s' objectInfo='%s'\n",
701              GOODSTR(objectSpaceName), GOODSTR(pathName), GOODSTR(lGName),
702              hgethi(estimatedSize), hgetlo(estimatedSize),
703              GOODSTR(objectDescription), GOODSTR(objectInfo));
704         printf
705             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
706              GOODSTR(info->serverName),
707              GOODSTR(info->objOwner.bsaObjectOwner),
708              GOODSTR(info->objOwner.appObjectOwner));
709     }
710
711     if (info->bsaHandle == 0) {
712         /* We haven't initialized yet! */
713         ELog(0,
714              "xbsa_WriteObjectBegin: No current handle, butx not initialized\n");
715         return (BUTX_NOHANDLE);
716     }
717
718     if (objectSpaceName) {
719         if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
720             ELog(0,
721                  "xbsa_WriteObjectBegin: The objectSpaceName is too long; size = %d; name = %s\n",
722                  strlen(objectSpaceName), objectSpaceName);
723             return (BUTX_INVALIDOBJECTSPNAME);
724         }
725         strcpy(info->curObject.objName.objectSpaceName, objectSpaceName);
726     } else {
727         info->curObject.objName.objectSpaceName[0] = NULL;
728     }
729
730     if (pathName) {
731         if (strlen(pathName) >= BSA_MAX_PATHNAME) {
732             ELog(0,
733                  "xbsa_WriteObjectBegin: The pathName is too long; size = %d; name = %s\n",
734                  strlen(pathName), pathName);
735             return (BUTX_INVALIDPATHNAME);
736         }
737         strcpy(info->curObject.objName.pathName, pathName);
738     } else {
739         info->curObject.objName.pathName[0] = NULL;
740     }
741
742     if (lGName) {
743         if (strlen(lGName) >= BSA_MAX_LG_NAME) {
744             ELog(0,
745                  "xbsa_WriteObjectBegin: The lGName is too long; size = %d; name = %s\n",
746                  strlen(lGName), lGName);
747             return (BUTX_INVALIDLGNAME);
748         }
749         strcpy(info->curObject.lGName, lGName);
750     } else {
751         info->curObject.lGName[0] = NULL;
752     }
753
754     if (objectDescription) {
755         if (((XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM)
756              && (strlen(objectDescription) >= ADSM_MAX_DESC))
757             ||
758             ((XBSA_GET_SERVER_TYPE(info->serverType) != XBSA_SERVER_TYPE_ADSM)
759              && (strlen(objectDescription) >= BSA_MAX_DESC))) {
760             ELog(0,
761                  "xbsa_WriteObjectBegin: The objectDescription is too long; size = %d; name = %s\n",
762                  strlen(objectDescription), objectDescription);
763             return (BUTX_INVALIDOBJDESC);
764         }
765         strcpy(info->curObject.desc, objectDescription);
766     } else {
767         info->curObject.desc[0] = NULL;
768     }
769
770     if (objectInfo) {
771         if (((XBSA_GET_SERVER_TYPE(info->serverType) == XBSA_SERVER_TYPE_ADSM)
772              && (strlen(objectInfo) >= ADSM_MAX_OBJINFO))
773             ||
774             ((XBSA_GET_SERVER_TYPE(info->serverType) != XBSA_SERVER_TYPE_ADSM)
775              && (strlen(objectInfo) >= BSA_MAX_OBJINFO))) {
776             ELog(0,
777                  "xbsa_WriteObjectBegin: The objectInfo is too long; size = %d; name = %s\n",
778                  strlen(objectInfo), objectInfo);
779             return (BUTX_INVALIDOBJINFO);
780         }
781         strcpy(info->curObject.objectInfo, objectInfo);
782     } else {
783         info->curObject.objectInfo[0] = NULL;
784     }
785
786     if (info->numObjects == info->maxObjects) {
787         /* If we've used up Max Objects we must start a new transaction. */
788         rc = (int)xbsa_EndTrans(info);
789         if (rc != XBSA_SUCCESS) {
790             return (rc);
791         }
792         rc = (int)xbsa_BeginTrans(info);
793         if (rc != XBSA_SUCCESS) {
794             return (rc);
795         }
796     }
797
798     dataBlock.bufferLen = (BSA_UInt16) 0;
799     dataBlock.numBytes = (BSA_UInt16) 0;
800     dataBlock.bufferPtr = 0;
801
802     info->curObject.Owner = info->objOwner;
803     info->curObject.copyType = BSACopyType_BACKUP;
804     info->curObject.size.left = hgethi(estimatedSize);
805     info->curObject.size.right = hgetlo(estimatedSize);
806     info->curObject.objectType = BSAObjectType_FILE;
807     strcpy(info->curObject.resourceType, resourceType);
808
809     rc = (int)XBSACreateObject(info->bsaHandle, &info->curObject, &dataBlock);
810     if (rc != BSA_RC_SUCCESS) {
811         ELog(0,
812              "xbsa_WriteObjectBegin: The XBSACreateObject call failed with %d\n",
813              rc);
814         xbsa_error(rc, info);
815         return (BUTX_CREATEOBJFAIL);
816     }
817
818     info->numObjects++;
819
820     return (XBSA_SUCCESS);
821 }
822
823 /*
824  * Delete a backup object from the server
825  * BSAMarkObjectInactive()
826  * BSADeleteObject()
827  */
828 afs_int32
829 xbsa_DeleteObject(struct butx_transactionInfo * info, char *objectSpaceName,
830                   char *pathName)
831 {
832     int rc;
833     ObjectName objectName;
834
835     if (debugLevel > 98) {
836         printf("\nxbsa_DeleteObject objectSpacename='%s' pathName='%s'\n",
837                GOODSTR(objectSpaceName), GOODSTR(pathName));
838         printf
839             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
840              GOODSTR(info->serverName),
841              GOODSTR(info->objOwner.bsaObjectOwner),
842              GOODSTR(info->objOwner.appObjectOwner));
843     }
844
845     if (info->bsaHandle == 0) {
846         /* We haven't initialized yet! */
847         ELog(0,
848              "xbsa_DeleteObject: No current handle, butx not initialized\n");
849         return (BUTX_NOHANDLE);
850     }
851
852     if (objectSpaceName) {
853         if (strlen(objectSpaceName) >= BSA_MAX_OSNAME) {
854             ELog(0,
855                  "xbsa_DeleteObject: The objectSpaceName is too long; size = %d; name = %s\n",
856                  strlen(objectSpaceName), objectSpaceName);
857             return (BUTX_INVALIDOBJECTSPNAME);
858         }
859         strcpy(objectName.objectSpaceName, objectSpaceName);
860     } else {
861         objectName.objectSpaceName[0] = NULL;
862     }
863
864     if (pathName) {
865         if (strlen(pathName) >= BSA_MAX_PATHNAME) {
866             ELog(0, "xbsa_DeleteObject: strlen(pathName), pathName\n",
867                  strlen(pathName), pathName);
868             return (BUTX_INVALIDPATHNAME);
869         }
870         strcpy(objectName.pathName, pathName);
871     } else {
872         objectName.pathName[0] = NULL;
873     }
874
875     rc = (int)XBSAMarkObjectInactive(info->bsaHandle, &objectName);
876     if (rc != BSA_RC_SUCCESS) {
877         ELog(0,
878              "xbsa_DeleteObject: XBSAMarkObjectInactive call failed with %d\n",
879              rc);
880         xbsa_error(rc, info);
881         return ((rc ==
882                  BSA_RC_ABORT_ACTIVE_NOT_FOUND) ? BUTX_DELETENOVOL :
883                 BUTX_DELETEOBJFAIL);
884     }
885
886     return (XBSA_SUCCESS);
887 }
888
889 /*
890  * Tell the XBSA Server that this is the end of Data for this object.
891  * BSAEndData()
892  */
893 afs_int32
894 xbsa_WriteObjectEnd(struct butx_transactionInfo * info)
895 {
896     int rc;
897
898     if (debugLevel > 98) {
899         printf("\nxbsa_WriteObjectEnd\n");
900         printf
901             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
902              GOODSTR(info->serverName),
903              GOODSTR(info->objOwner.bsaObjectOwner),
904              GOODSTR(info->objOwner.appObjectOwner));
905     }
906
907     if (info->bsaHandle == 0) {
908         /* We haven't initialized yet! */
909         ELog(0,
910              "xbsa_WriteObjectEnd: No current handle, butx not initialized\n");
911         return (BUTX_NOHANDLE);
912     }
913     rc = (int)XBSAEndData(info->bsaHandle);
914     if (rc != BSA_RC_SUCCESS) {
915         ELog(0, "xbsa_WriteObjectEnd: XBSAEndData call failed with %d\n", rc);
916         xbsa_error(rc, info);
917         return (BUTX_ENDDATAFAIL);
918     }
919
920     return (XBSA_SUCCESS);
921 }
922
923
924 /*
925  * Write the fileset data to the XBSA server
926  * BSASendData
927  */
928 afs_int32
929 xbsa_WriteObjectData(struct butx_transactionInfo * info, char *dataBuffer,
930                      afs_int32 bufferSize, afs_int32 * count)
931 {
932     int rc;
933     DataBlock dataBlock;
934
935     if (debugLevel > 98) {
936         printf("\nxbsa_WriteObjectData %d Bytes\n", bufferSize);
937         printf
938             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
939              GOODSTR(info->serverName),
940              GOODSTR(info->objOwner.bsaObjectOwner),
941              GOODSTR(info->objOwner.appObjectOwner));
942     }
943
944     if (info->bsaHandle == 0) {
945         /* We haven't initialized yet! */
946         ELog(0,
947              "xbsa_WriteObjectData: No current handle, butx not initialized\n");
948         return (BUTX_NOHANDLE);
949     }
950
951     if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
952         ELog(0, "xbsa_WriteObjectData: The bufferSize %d is invalid\n",
953              bufferSize);
954         return (BUTX_INVALIDBUFFERSIZE);
955     }
956
957     if (dataBuffer == NULL) {
958         ELog(0, "xbsa_WriteObjectData: The dataBuffer is NULL\n");
959         return (BUTX_INVALIDDATABUFFER);
960     }
961
962     dataBlock.bufferPtr = dataBuffer;
963     dataBlock.bufferLen = (BSA_UInt16) bufferSize;
964     dataBlock.numBytes = (BSA_UInt16) 0;
965
966     rc = (int)XBSASendData(info->bsaHandle, &dataBlock);
967     if (rc != BSA_RC_SUCCESS) {
968         ELog(0, "xbsa_WriteObjectData: XBSAEndData call failed with %d\n",
969              rc);
970         xbsa_error(rc, info);
971         return (BUTX_SENDDATAFAIL);
972     }
973     *count = dataBlock.numBytes;
974     return (XBSA_SUCCESS);
975 }
976
977
978 /*
979  * Read the fileset data from the XBSA server
980  * BSAGetData
981  */
982 afs_int32
983 xbsa_ReadObjectData(struct butx_transactionInfo * info, char *dataBuffer,
984                     afs_int32 bufferSize, afs_int32 * count,
985                     afs_int32 * endOfData)
986 {
987     int rc;
988     DataBlock dataBlock;
989
990     if (debugLevel > 98) {
991         printf("\nxbsa_ReadObjectData %d Bytes\n", bufferSize);
992         printf
993             ("serverName='%s' ; bsaObjectOwner='%s' ; appObjectOwner='%s' ; sectoken=xxxxxx\n",
994              GOODSTR(info->serverName),
995              GOODSTR(info->objOwner.bsaObjectOwner),
996              GOODSTR(info->objOwner.appObjectOwner));
997     }
998
999     if (info->bsaHandle == 0) {
1000         /* We haven't initialized yet! */
1001         ELog(0,
1002              "xbsa_ReadObjectData: No current handle, butx not initialized\n");
1003         return (BUTX_NOHANDLE);
1004     }
1005
1006     if ((bufferSize < 0) || (bufferSize > XBSAMAXBUFFER)) {
1007         ELog(0, "xbsa_ReadObjectData: The bufferSize %d is invalid\n",
1008              bufferSize);
1009         return (BUTX_INVALIDBUFFERSIZE);
1010     }
1011
1012     if (dataBuffer == NULL) {
1013         ELog(0, "xbsa_ReadObjectData: The dataBuffer is NULL\n");
1014         return (BUTX_INVALIDDATABUFFER);
1015     }
1016
1017     dataBlock.bufferLen = (BSA_UInt16) bufferSize;
1018     dataBlock.numBytes = (BSA_UInt16) 0;
1019     dataBlock.bufferPtr = dataBuffer;
1020     *endOfData = 0;
1021
1022     rc = (int)XBSAGetData(info->bsaHandle, &dataBlock);
1023     if ((rc != BSA_RC_MORE_DATA) && (rc != BSA_RC_NO_MORE_DATA)) {
1024         ELog(0, "xbsa_ReadObjectData: XBSAGetData call failed with %d\n", rc);
1025         xbsa_error(rc, info);
1026         return (BUTX_GETDATAFAIL);
1027     }
1028     *count = dataBlock.numBytes;
1029     if (rc == BSA_RC_NO_MORE_DATA)
1030         *endOfData = 1;
1031     return (XBSA_SUCCESS);
1032 }
1033 #endif /*xbsa */