OPENAFS-SA-2018-001 Add auditing to butc server RPC implementations
[openafs.git] / src / butc / afsxbsa.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 #include <afs/stds.h>
15
16 #include <roken.h>
17
18 #include <ctype.h>
19
20 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
21 #include <dlfcn.h>
22 #endif
23
24 #include <afs/tcdata.h>
25 #include "butc_xbsa.h"
26 #include <afs/butx.h>
27 #include "butc_internal.h"
28
29 /* Global Definations */
30 #define APPLTYPE "afs-butc"
31 #define TDP_LIBNAME "libApiDS.a"
32 #define FIRST_HANDLE 1
33 #define NOHANDLE 0
34 #define XAPI_FSINFO "FS for XOpen API"
35 #define DIR_DELIMITER '/'
36 #define STR_DIR_DELIMITER "/"
37
38 xGlobal xopenGbl;
39 char traceStr[DSM_MAX_RC_MSG_LENGTH+1];
40 char traceStr2[(DSM_MAX_RC_MSG_LENGTH+1) - 30];
41 char ourMsg[DSM_MAX_RC_MSG_LENGTH + 1];
42 static int dsm_init = 0 ;
43
44 /* >>>  TSM function pointers. */
45 dsInt16_t (* AFSdsmBeginQuery)( dsUint32_t dsmHandle, dsmQueryType queryType, dsmQueryBuff *queryBuffer);
46 dsInt16_t (* AFSdsmGetNextQObj)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr) ;
47 dsInt16_t (* AFSdsmEndQuery)( dsUint32_t dsmHandle);
48 dsInt16_t (* AFSdsmRCMsg)( dsUint32_t dsmHandle, dsInt16_t dsmRC, char *msg);
49 dsInt16_t (* AFSdsmLogEventEx)( dsUint32_t dsmHandle, dsmLogExIn_t *dsmLogExInP, dsmLogExOut_t *dsmLogExOutP);
50 dsInt16_t (* AFSdsmTrace)( dsUint32_t dsmHandle, char * string );
51 dsInt16_t (* AFSdsmTerminate)( dsUint32_t dsmHandle);
52 dsInt16_t (* AFSdsmSendData)( dsUint32_t dsmHandle, DataBlk *dataBlkPtri);
53 dsInt16_t (* AFSdsmBeginTxn)( dsUint32_t dsmHandle);
54 dsInt16_t (* AFSdsmDeleteObj)( dsUint32_t dsmHandle, dsmDelType delType, dsmDelInfo delInfo);
55 dsInt16_t (* AFSdsmEndTxn)( dsUint32_t dsmHandle, dsUint8_t vote, dsUint16_t *reason);
56 void (* AFSdsmQueryApiVersion)( dsmApiVersion *apiVersionP);
57 dsInt16_t (* AFSdsmInit)( dsUint32_t *dsmHandle, dsmApiVersion *dsmApiVersionP, char *clientNodeNameP, char *clientOwnerNameP, char *clientPasswordP, char *applicationType, char *configfile, char *options);
58 dsInt16_t (* AFSdsmQuerySessInfo)( dsUint32_t dsmHandle, ApiSessInfo *SessInfoP);
59 dsInt16_t (* AFSdsmBeginGetData)(dsUint32_t dsmHandle, dsBool_t mountWait, dsmGetType getType, dsmGetList *dsmGetObjListP);
60 dsInt16_t (* AFSdsmGetObj)( dsUint32_t dsmHandle, ObjID *objIdP, DataBlk *dataBlkPtr);
61 dsInt16_t (* AFSdsmEndGetObj)( dsUint32_t dsmHandle);
62 dsInt16_t (* AFSdsmEndGetData)( dsUint32_t dsmHandle);
63 dsInt16_t (* AFSdsmGetData)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr);
64 dsInt16_t (* AFSdsmEndSendObj)( dsUint32_t dsmHandle);
65 dsInt16_t (* AFSdsmRegisterFS)( dsUint32_t dsmHandle, regFSData *regFilespaceP);
66 dsInt16_t (* AFSdsmBindMC)( dsUint32_t dsmHandle, dsmObjName *objNameP, dsmSendType sendType, mcBindKey *mcBindKeyP);
67 dsInt16_t (* AFSdsmSendObj)( dsUint32_t dsmHandle, dsmSendType sendType, void *sendBuff, dsmObjName *objNameP, ObjAttr *objAttrPtr, DataBlk *dataBlkPtr);
68 dsInt16_t (* AFSdsmChangePW)( dsUint32_t dsmHandle, char *oldPW, char *newPW);
69 #if 0
70 dsInt16_t (* AFSdsmCleanUp)( dsBool_t mtFlag);
71 dsInt16_t (* AFSdsmDeleteAccess)( dsUint32_t dsmHandle, dsUint32_t ruleNum);
72 dsInt16_t (* AFSdsmDeleteFS)( dsUint32_t dsmHandle, char *fsName, dsUint8_t repository);
73 dsInt16_t (* AFSdsmEndGetDataEx)( dsmEndGetDataExIn_t *dsmEndGetDataExInP, dsmEndGetDataExOut_t *dsmEndGetDataExOutP);
74 dsInt16_t (* AFSdsmEndSendObjEx)( dsmEndSendObjExIn_t *dsmEndSendObjExInP, dsmEndSendObjExOut_t *dsmEndSendObjExOutP);
75 dsInt16_t (* AFSdsmEndTxnEx)( dsmEndTxnExIn_t *dsmEndTxnExInP, dsmEndTxnExOut_t *dsmEndTxnExOutP);
76 dsInt16_t (* AFSdsmGroupHandler)( dsmGroupHandlerIn_t *dsmGroupHandlerInP, dsmGroupHandlerOut_t  *dsmGroupHandlerOutP);
77 dsInt16_t (* AFSdsmInitEx)( dsUint32_t *dsmHandleP, dsmInitExIn_t *dsmInitExInP, dsmInitExOut_t *dsmInitExOutP);
78 dsInt16_t (* AFSdsmLogEvent)( dsUint32_t dsmHandle, logInfo *lopInfoP);
79 dsInt16_t (* AFSdsmQueryAccess)( dsUint32_t dsmHandle, qryRespAccessData **accessListP, dsUint16_t *numberOfRules);
80 void      (* AFSdsmQueryApiVersionEx)( dsmApiVersionEx *apiVersionP);
81 dsInt16_t (* AFSdsmQueryCliOptions)( optStruct *optstructP);
82 dsInt16_t (* AFSdsmQuerySessOptions)( dsUint32_t dsmHandle, optStruct *optstructP);
83 dsInt16_t (* AFSdsmRenameObj)( dsmRenameIn_t *dsmRenameInP, dsmRenameOut_t *dsmRenameOutP);
84 dsInt16_t (* AFSdsmSetAccess)( dsUint32_t dsmHandle, dsmAccessType accessType, dsmObjName *objNameP, char *node, char *owner);
85 dsInt16_t (* AFSdsmSetUp)( dsBool_t mtFlag, envSetUp *envSetUpPi);
86 dsInt16_t (* AFSdsmUpdateFS)( dsUint32_t dsmHandle, char *fs, dsmFSUpd *fsUpdP, dsUint32_t fsUpdAct);
87 dsInt16_t (* AFSdsmUpdateObj)( dsUint32_t dsmHandle, dsmSendType sendType, void *sendBuff, dsmObjName *objNameP, ObjAttr *objAttrPtr, dsUint32_t objUpdAct);
88 #endif
89 /* <<< TSM function pointers. */
90
91 typedef struct s_delList {
92   struct s_delList *next;
93   ObjID           objId;
94 } delList;
95
96 static dsInt16_t buildList(
97     dsUint32_t     dsmHandle,
98     dsmObjName     *objNameP,
99     delList        **llHeadPP,
100     delList        **llTailPP)
101 {
102    dsInt16_t            rc;
103    qryArchiveData       queryBuffer;       /* for query Archive*/
104    qryRespArchiveData   qaDataArea;
105    DataBlk              qDataBlkArea;
106    char                 descrStar[] = "*";
107    delList              *lnew = NULL, *ll = NULL;
108
109    queryBuffer.stVersion = qryArchiveDataVersion ;
110    queryBuffer.objName = objNameP;
111    queryBuffer.owner = xopenGbl.dsmSessInfo.owner;
112    queryBuffer.insDateLowerBound.year = DATE_MINUS_INFINITE;
113    queryBuffer.insDateUpperBound.year = DATE_PLUS_INFINITE;
114    queryBuffer.expDateLowerBound.year = DATE_MINUS_INFINITE;
115    queryBuffer.expDateUpperBound.year = DATE_PLUS_INFINITE;
116    queryBuffer.descr = descrStar;
117
118    if ((rc=AFSdsmBeginQuery(dsmHandle, qtArchive,
119                         (void *)&queryBuffer )) != DSM_RC_OK)
120    {
121       XOPENRETURN(dsmHandle,"buildList(AFSdsmBeginQuery)",rc,__FILE__,__LINE__);
122    }
123    qaDataArea.stVersion = qryRespArchiveDataVersion;
124    qDataBlkArea.stVersion = DataBlkVersion ;
125    qDataBlkArea.bufferPtr = (char *)&qaDataArea;
126    qDataBlkArea.bufferLen = sizeof(qryRespArchiveData);
127    while ((rc = AFSdsmGetNextQObj(dsmHandle, &qDataBlkArea)) == DSM_RC_MORE_DATA)
128    {
129      if (!(lnew = (delList *)dsMalloc(sizeof(delList))))
130         XOPENRETURN(dsmHandle,"buildList(AFSdsmGetNextQObj)",
131                     DSM_RC_NO_MEMORY,__FILE__,__LINE__);
132
133      if (!*llHeadPP)
134      {
135         *llHeadPP = lnew;
136         *llTailPP = lnew;
137      }
138      else
139      {
140         ll = *llTailPP;
141         ll->next = lnew;
142         *llTailPP = lnew;
143      }
144
145      lnew->next = NULL;
146      lnew->objId.hi = qaDataArea.objId.hi;
147      lnew->objId.lo = qaDataArea.objId.lo;
148    }
149
150    if (rc != DSM_RC_FINISHED)
151    {
152       AFSdsmEndQuery(dsmHandle);
153       XOPENRETURN(dsmHandle,"buildList(AFSdsmGetNextQObj)",
154                   rc,__FILE__,__LINE__);
155    }
156
157    if ((rc = AFSdsmEndQuery(dsmHandle)) != DSM_RC_OK)
158    {
159       sprintf(traceStr2, "buildList: AFSdsmEndQuery rc = %d", rc);
160       ourTrace(dsmHandle,TrFL,traceStr2);
161    }
162    XOPENRETURN(dsmHandle,"buildList",rc,__FILE__,__LINE__);
163 }
164
165 static dsInt16_t  freeList(
166     delList    **llHeadPP,
167     delList    **llTailPP)
168 {
169
170    delList *ll;
171    ll = *llHeadPP;
172    while (ll)
173    {
174       *llHeadPP = ll->next;
175       dsFree(ll);
176       ll = *llHeadPP;
177    }
178    *llHeadPP = NULL;
179    *llTailPP = NULL;
180    XOPENRETURN(0,"freeList",0,__FILE__,__LINE__);
181 }
182
183 void ourTrace(long           BSAHandle,
184               char          *fileName,
185               int            lineNumber,
186               char          *traceStr2)
187 {
188
189    sprintf(traceStr,"%s (%d) ",fileName, lineNumber);
190
191    if (traceStr2 != NULL && *traceStr2 != '\0')
192       strcat(traceStr, traceStr2);
193
194    AFSdsmTrace(BSAHandle, traceStr);
195    return;
196 }
197
198 void ourLogEvent_Ex(dsUint32_t dsmHandle, dsmLogType type, char *message,
199                     char *appMsg, dsmLogSeverity severity)
200 {
201    dsmLogExIn_t dsmLogIn;
202    dsmLogExOut_t dsmLogOut;
203    memset(&dsmLogOut, '\0', sizeof(dsmLogExOut_t));
204
205    if (dsmHandle)
206    {
207       dsmLogIn.stVersion = dsmLogExInVersion;
208       dsmLogIn.severity = severity;
209       dsmLogIn.logType = type;
210
211       strcpy(dsmLogIn.appMsgID, appMsg);
212       dsmLogIn.message = message;
213       AFSdsmLogEventEx(dsmHandle, &dsmLogIn, &dsmLogOut);
214    }
215 }
216
217 char* ourRCMsg(dsInt16_t ourRC, char *msgPrefix)
218 {
219    char         appStr[BSA_MAX_DESC];
220    char         *chP;
221    int          bytesToCp;
222
223    memset(&ourMsg, 0x00, DSM_MAX_RC_MSG_LENGTH + 1);
224    if(msgPrefix != NULL)
225    {
226        /*================================================================
227         call stdXOpenMsgMap if return code values are within the TSM
228         return code range (96 - 104). Reformat the message prefix
229         (ANS0660 - ANS0668).
230         ================================================================*/
231         if ((ourRC >= custMin_retcode) && (ourRC <= custMax_retcode))
232         {
233              stdXOpenMsgMap(ourRC, ourMsg);
234              /* set standard XOpen message prefix range: 660 - 668 */
235              ourRC = ((ourRC * 10) / 16) + (ourRC % 16) + 600;
236              sprintf(msgPrefix, "ANSO%d", ourRC);
237         }
238         else
239           /*===============================================================
240            call dsmRCMsg if return code values other then the above ranges.
241            Get message prefix from the return message of dsmRCMsg.
242            ===============================================================*/
243         {
244               AFSdsmRCMsg(NOHANDLE, ourRC, ourMsg);
245              /*=========================================================
246               search for the first ' ' and copy from beginning of string
247               until before the two charecter before ' '.
248               e.g. To get the code value from the messages of
249                    "ANS1038S Invalid option specified", we only want to
250                    get strings "ANS1038".
251               ========================================================*/
252               chP = (char *) strchr(ourMsg, ' ');
253               bytesToCp = strlen(ourMsg) - (strlen(chP) + 1);
254               strncpy(appStr, ourMsg, bytesToCp);
255               sprintf(msgPrefix, "%s", appStr);
256         }
257    }
258 return ourMsg;
259 } /* ourRCMsg() */
260
261 void StrUpper(char *s)
262 {
263    while (*s != '\0')
264    {
265       if (isalpha((int)(unsigned char)*s))
266          *s = (char)toupper((int)(unsigned char)*s);
267       s++;
268
269    } /* end while */
270 } /* StrUpper() */
271
272 BSA_Int16 xparsePath(
273     long           BSAHandle,
274     char          *pathname,
275     char          *hl,
276     char          *ll)
277 {
278    /*=== code taken from dscparse.c ParseDestOperand function ===*/
279
280    dsInt16_t    opLen;
281    dsInt16_t    x;
282
283    *hl = *ll = '\0';
284
285    strcpy(hl, pathname);   /* use hl as working area */
286    if ((opLen = strlen(hl)) > 0)
287    {
288       /*=== Find the ll portion of the name ===*/
289       #ifdef MBCS
290       {
291          char *llstart;
292          llstart = strrchr(hl,DIR_DELIMITER);
293          if (llstart == NULL)
294             x = 0;
295          else
296             x = llstart - hl;
297       }
298       #else
299          for (x = opLen-1; x>0 && hl[x]!=DIR_DELIMITER; x--);
300       #endif
301
302          /*=== If there is no leading delimiter then add one ===*/
303          if (hl[x] != DIR_DELIMITER)
304             strcpy(ll, STR_DIR_DELIMITER);
305
306          strncat(ll, hl+x, opLen-x);
307
308          hl[x] = '\0';          /* Shorten hl by length of ll */
309    }
310    return 0;
311 }
312
313 BSA_Int16 xlateRC(
314     long           BSAHandle,
315     BSA_Int16      dsmRC,
316     BSA_Int16      *bsaRCP)
317
318 {
319    switch (dsmRC)
320    {
321       case DSM_RC_OK:
322          *bsaRCP=BSA_RC_OK;                              break;
323
324       case DSM_RC_ABORT_ACTIVE_NOT_FOUND:
325          *bsaRCP=BSA_RC_ABORT_ACTIVE_NOT_FOUND;          break;
326
327       case DSM_RC_ABORT_SYSTEM_ERROR:
328          *bsaRCP=BSA_RC_ABORT_SYSTEM_ERROR;              break;
329
330       case DSM_RC_ABORT_BAD_VERIFIER:
331       case DSM_RC_AUTH_FAILURE:
332       case DSM_RC_REJECT_ID_UNKNOWN:
333       case DSM_RC_REJECT_DUPLICATE_ID:
334          *bsaRCP=BSA_RC_AUTHENTICATION_FAILURE;          break;
335
336       case DSM_RC_BAD_CALL_SEQUENCE:
337          *bsaRCP=BSA_RC_BAD_CALL_SEQUENCE;               break;
338
339       case DSM_RC_INVALID_DS_HANDLE:
340          *bsaRCP=BSA_RC_BAD_HANDLE;                      break;
341
342       case DSM_RC_BUFF_TOO_SMALL:
343          *bsaRCP=BSA_RC_BUFFER_TOO_SMALL;                break;
344
345       case DSM_RC_DESC_TOOLONG:
346          *bsaRCP=BSA_RC_DESC_TOO_LONG;                   break;
347
348       case DSM_RC_FILESPACE_TOOLONG:
349          *bsaRCP=BSA_RC_OBJECTSPACE_TOO_LONG;            break;
350
351       /* some other condition here ? */
352       case DSM_RC_PASSWD_TOOLONG:
353          *bsaRCP=BSA_RC_INVALID_TOKEN;                   break;
354
355       case DSM_RC_INVALID_VOTE:
356          *bsaRCP=BSA_RC_INVALID_VOTE;                    break;
357
358       case DSM_RC_INVALID_OPT:
359          *bsaRCP=BSA_RC_INVALID_KEYWORD;                 break;
360
361       /*  ? what conditions cause this - object already exists ?
362       case DSM_RC_?:
363          *bsaRCP=BSA_RC_MATCH_EXISTS;                    break;
364       */
365
366       case DSM_RC_MORE_DATA:
367          *bsaRCP=BSA_RC_MORE_DATA;                       break;
368
369       /* not supported - for QueryAccessRule
370       case :
371          *bsaRCP=BSA_RC_MORE_RULES;                      break;
372       */
373
374       case DSM_RC_NEWPW_REQD:
375          *bsaRCP=BSA_RC_NEWTOKEN_REQD;                   break;
376
377       case DSM_RC_ABORT_NO_MATCH:
378       case DSM_RC_FILE_SPACE_NOT_FOUND:
379       /*=== rc for query ===*/
380          *bsaRCP=BSA_RC_NO_MATCH;                        break;
381       /*=== if this return code comes on Delete, use OBJECT_NOT_FOUND
382             - see xopndel.c ===*/
383
384       case DSM_RC_FINISHED:
385          *bsaRCP=BSA_RC_NO_MORE_DATA;                    break;
386
387       case DSM_RC_ABORT_NO_LOG_SPACE:
388       case DSM_RC_ABORT_NO_DB_SPACE:
389       case DSM_RC_ABORT_NO_MEMORY:
390       case DSM_RC_ABORT_NO_REPOSIT_SPACE:
391       case DSM_RC_REJECT_NO_RESOURCES:
392       case DSM_RC_REJECT_NO_MEMORY:
393       case DSM_RC_REJECT_NO_DB_SPACE:
394       case DSM_RC_REJECT_NO_LOG_SPACE:
395          *bsaRCP=BSA_RC_NO_RESOURCES;                    break;
396
397       case DSM_RC_NULL_DATABLKPTR:
398          *bsaRCP=BSA_RC_NULL_DATABLKPTR;                 break;
399
400       case DSM_RC_NULL_OBJNAME:
401          *bsaRCP=BSA_RC_NULL_OBJNAME;                    break;
402
403       case DSM_RC_NULL_BUFPTR:
404          *bsaRCP=BSA_RC_NULL_POINTER;                    break;
405
406       /* not supported - for DeleteAccessRule
407       case :
408          *bsaRCP=BSA_RC_NULL_RULEID;                     break;
409       */
410
411       case DSM_RC_HL_TOOLONG:
412       case DSM_RC_LL_TOOLONG:
413          *bsaRCP=BSA_RC_OBJECT_NAME_TOO_LONG;            break;
414
415       /* not supported - for DeletePolicyDomain
416       case :
417          *bsaRCP=BSA_RC_OBJECT_NOT_EMPTY;                break;
418       */
419
420       /* same as NO_MATCH for DeleteObject
421       case :
422          *bsaRCP=BSA_RC_OBJECT_NOT_FOUND;                break;
423       */
424
425       case DSM_RC_OBJINFO_TOOLONG:
426          *bsaRCP=BSA_RC_OBJINFO_TOO_LONG;                break;
427
428       /* same as BSA_RC_OBJECT_NAME_TOO_LONG
429       case :
430          *bsaRCP=BSA_RC_OBJNAME_TOO_LONG;                break;
431       */
432
433       /* not supported - for CreatePolicySet, etc
434       case :
435          *bsaRCP=BSA_RC_OPERATION_NOT_AUTHORIZED;        break;
436       */
437
438       case DSM_RC_OLDPW_REQD:
439          *bsaRCP=BSA_RC_OLDTOKEN_REQD;                   break;
440
441       case DSM_RC_REJECT_VERIFIER_EXPIRED:
442          *bsaRCP=BSA_RC_TOKEN_EXPIRED;                   break;
443
444       case DSM_RC_WILL_ABORT:
445       case DSM_RC_CHECK_REASON_CODE:
446          *bsaRCP=BSA_RC_TXN_ABORTED;                     break;
447
448       case DSM_RC_UNMATCHED_QUOTE:
449          *bsaRCP=BSA_RC_UNMATCHED_QUOTE;                 break;
450
451       /* not supported - for DeleteUser
452       case :
453          *bsaRCP=BSA_RC_USER_OWNS_OBJECT;                break;
454       */
455
456       default:
457       {
458          /*=========================================================
459           No suitable match, so print message in log, if we still
460           have a handle.  AFSdsmInit calls ApiCleanUp in certain error
461           situations.  We lose the handle in those cases so check
462           for it.
463           =========================================================*/
464
465          char         rcMsg[DSM_MAX_RC_MSG_LENGTH] ;
466          char         errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
467          char         ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
468          dsUint32_t   dsmHandle;
469
470          memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
471          memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
472
473          if (BSAHandle)
474          {
475             dsmHandle = BSAHandle;
476             AFSdsmRCMsg(dsmHandle,dsmRC,rcMsg) ;
477             strcat(rcMsg, "\n");
478             sprintf(traceStr2,
479                    "xlateRC - %s", rcMsg);
480             ourTrace(BSAHandle,TrFL, traceStr2);
481             strcpy(ourMessage, ourRCMsg(dsmRC, errPrefix));
482             ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
483          }
484
485          *bsaRCP = ADSM_RC_ERROR;
486       }
487    }
488
489    /*=== trace only if we have a valid handle ===*/
490    if (dsmRC && BSAHandle)
491    {
492       sprintf(traceStr2, "xlateRC: TSM rc >%d< , BSA rc >%d<", dsmRC, *bsaRCP);
493       ourTrace(BSAHandle, TrFL, traceStr2);
494    }
495    return DSM_RC_OK ;
496 }
497
498 void stdXOpenMsgMap(dsInt16_t  rc,  char *msg)
499 {
500    switch(rc)
501    {
502       case ADSM_RC_ERROR:
503            strcpy(msg, "TSM rc error, see ADSM error log.");
504       case ADSM_RC_INVALID_NODE:
505            strcpy(msg, "BSAObjectOwner doesn't match value session Init.");
506            break;
507
508       case ADSM_RC_INVALID_COPYTYPE:
509            strcpy(msg, "Invalid copy type.");
510            break;
511
512       case ADSM_RC_INVALID_OBJTYPE:
513            strcpy(msg, "Invalid object type.");
514            break;
515
516       case ADSM_RC_INVALID_STATUS:
517            strcpy(msg, "Invalid Object Status.");
518            break;
519
520       case ADSM_RC_INVALID_ST_VER:
521            strcpy(msg, "Invalid object descriptor structure version.");
522            break;
523
524       case ADSM_RC_OWNER_TOO_LONG:
525            strcpy(msg, "Object owner name too long.");
526            break;
527
528       case ADSM_RC_PSWD_TOO_LONG:
529            strcpy(msg, "Client password too long.");
530            break;
531
532      case ADSM_RC_PSWD_GEN:
533           strcpy(msg, "Password input required .");
534           break;
535
536      default:
537            strcpy(msg, "No message available");
538            break;
539    }
540 }
541
542 BSA_Int16 fillArchiveResp(
543 long                BSAHandle,
544 ObjectDescriptor   *BSAobjDescP,
545 qryRespArchiveData *respArchiveP
546 )
547 {
548    XAPIObjInfo   *xapiObjInfoP;
549
550    strcpy(BSAobjDescP->Owner.appObjectOwner, respArchiveP->owner);
551    strcpy(BSAobjDescP->objName.objectSpaceName, respArchiveP->objName.fs);
552
553    /*=== concatenate hl and ll for pathName ===*/
554    strcpy(BSAobjDescP->objName.pathName, respArchiveP->objName.hl);
555    strcat(BSAobjDescP->objName.pathName, respArchiveP->objName.ll);
556
557    BSAobjDescP->createTime.tm_year = respArchiveP->insDate.year-1900;
558    BSAobjDescP->createTime.tm_mon  = respArchiveP->insDate.month-1;
559    BSAobjDescP->createTime.tm_mday = respArchiveP->insDate.day  ;
560    BSAobjDescP->createTime.tm_hour = respArchiveP->insDate.hour ;
561    BSAobjDescP->createTime.tm_min  = respArchiveP->insDate.minute ;
562    BSAobjDescP->createTime.tm_sec  = respArchiveP->insDate.second ;
563
564    BSAobjDescP->copyId.left  = respArchiveP->objId.hi;
565    BSAobjDescP->copyId.right = respArchiveP->objId.lo;
566
567    BSAobjDescP->restoreOrder.left  = respArchiveP->restoreOrderExt.lo_hi;
568    BSAobjDescP->restoreOrder.right = respArchiveP->restoreOrderExt.lo_lo;
569
570    strcpy(BSAobjDescP->lGName, respArchiveP->mcName) ;
571
572    xapiObjInfoP = (XAPIObjInfo *)&(respArchiveP->objInfo);
573    BSAobjDescP->size.left = xapiObjInfoP->size.left;
574    BSAobjDescP->size.right= xapiObjInfoP->size.right;
575    strcpy(BSAobjDescP->resourceType, xapiObjInfoP->resourceType);
576    strcpy(BSAobjDescP->desc, xapiObjInfoP->partDesc);
577    strcpy(BSAobjDescP->objectInfo, xapiObjInfoP->partObjInfo);
578
579    if (respArchiveP->objName.objType == DSM_OBJ_DIRECTORY)
580       BSAobjDescP->objectType = BSAObjectType_DIRECTORY;
581    else
582       BSAobjDescP->objectType = BSAObjectType_FILE;
583       /*=== future - type DATABASE ?? ===*/
584
585       BSAobjDescP->status = BSAObjectStatus_ACTIVE;
586       XOPENRETURN(BSAHandle, "fillArchiveResp",
587                   BSA_RC_SUCCESS,__FILE__,__LINE__);
588 }
589
590 BSA_Int16 fillBackupResp(
591 long               BSAHandle,
592 ObjectDescriptor  *BSAobjDescP,
593 qryRespBackupData *respBackupP
594 )
595 {
596    XAPIObjInfo   *xapiObjInfoP;
597
598    strcpy(BSAobjDescP->Owner.appObjectOwner, respBackupP->owner);
599    strcpy(BSAobjDescP->objName.objectSpaceName, respBackupP->objName.fs);
600
601    /*=== concatenate hl and ll for pathName ===*/
602    strcpy(BSAobjDescP->objName.pathName, respBackupP->objName.hl);
603    strcat(BSAobjDescP->objName.pathName, respBackupP->objName.ll);
604
605    BSAobjDescP->createTime.tm_year = respBackupP->insDate.year-1900;
606    BSAobjDescP->createTime.tm_mon  = respBackupP->insDate.month-1;
607    BSAobjDescP->createTime.tm_mday = respBackupP->insDate.day  ;
608    BSAobjDescP->createTime.tm_hour = respBackupP->insDate.hour ;
609    BSAobjDescP->createTime.tm_min  = respBackupP->insDate.minute ;
610    BSAobjDescP->createTime.tm_sec  = respBackupP->insDate.second ;
611
612    BSAobjDescP->copyId.left  = respBackupP->objId.hi;
613    BSAobjDescP->copyId.right = respBackupP->objId.lo;
614
615    BSAobjDescP->restoreOrder.left  = respBackupP->restoreOrderExt.lo_hi;
616    BSAobjDescP->restoreOrder.right = respBackupP->restoreOrderExt.lo_lo;
617
618    strcpy(BSAobjDescP->lGName, respBackupP->mcName) ;
619
620    xapiObjInfoP = (XAPIObjInfo *)&(respBackupP->objInfo);
621    BSAobjDescP->size.left = xapiObjInfoP->size.left;
622    BSAobjDescP->size.right= xapiObjInfoP->size.right;
623    strcpy(BSAobjDescP->resourceType, xapiObjInfoP->resourceType);
624    strcpy(BSAobjDescP->desc, xapiObjInfoP->partDesc);
625    strcpy(BSAobjDescP->objectInfo, xapiObjInfoP->partObjInfo);
626
627    if (respBackupP->objName.objType == DSM_OBJ_DIRECTORY)
628       BSAobjDescP->objectType = BSAObjectType_DIRECTORY;
629    else
630       BSAobjDescP->objectType = BSAObjectType_FILE;
631       /*=== future - type DATABASE ?? ===*/
632
633    if (respBackupP->objState == DSM_ACTIVE)
634       BSAobjDescP->status = BSAObjectStatus_ACTIVE;
635    else
636       BSAobjDescP->status = BSAObjectStatus_INACTIVE;
637       /*=== ?? check for any other ===*/
638
639    XOPENRETURN(BSAHandle, "fillRBackupResp",
640                BSA_RC_SUCCESS,__FILE__,__LINE__);
641 }
642
643
644 afs_int32 dsm_MountLibrary(void)
645 {
646 void * dynlib = NULL ;
647
648 #ifdef DEBUG_BUTC
649     printf("dsm_MountLibrary : inside function.  \n");
650 #endif
651 #if defined(AFS_AIX_ENV)
652         dynlib = dlopen("/usr/lib/libApiDS.a(dsmapish.o)", RTLD_NOW | RTLD_LOCAL | RTLD_MEMBER);
653 #elif defined (AFS_AMD64_LINUX26_ENV)
654         dynlib = dlopen("/usr/lib64/libApiTSM64.so", RTLD_NOW | RTLD_LOCAL);
655 #elif defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
656         dynlib = dlopen("/usr/lib/libApiDS.so", RTLD_NOW | RTLD_LOCAL);
657 #else
658         dynlib = NULL;
659 #endif
660
661         if (dynlib == NULL) {
662                 ELog(0,"dsm_MountLibrary: The dlopen call to load the libApiDS shared library failed\n");
663                 return(BUTX_NOLIBRARY);
664         }
665
666 #ifdef DEBUG_BUTC
667         printf("dsm_MountLibrary : SUCCESS to Open the libApiDS shared library. \n");
668 #endif
669 #if defined(AFS_AIX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX26_ENV)
670         AFSdsmBeginQuery = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmQueryType queryType, dsmQueryBuff *queryBuffer)) dlsym((void *)dynlib, "dsmBeginQuery");
671         AFSdsmGetNextQObj = (dsInt16_t (*)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmGetNextQObj") ;
672         AFSdsmEndQuery = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndQuery");
673         AFSdsmRCMsg = (dsInt16_t (*)( dsUint32_t dsmHandle, dsInt16_t dsmRC, char *msg))dlsym((void *)dynlib, "dsmRCMsg");
674         AFSdsmLogEventEx = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmLogExIn_t *dsmLogExInP, dsmLogExOut_t *dsmLogExOutP))dlsym((void *)dynlib, "dsmLogEventEx");
675         AFSdsmTrace = (dsInt16_t (*)( dsUint32_t dsmHandle, char * string ))dlsym((void *)dynlib, "dsmTrace");
676         AFSdsmTerminate = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmTerminate");
677         AFSdsmSendData = (dsInt16_t (*)( dsUint32_t dsmHandle, DataBlk *dataBlkPtri))dlsym((void *)dynlib, "dsmSendData");
678         AFSdsmBeginTxn = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmBeginTxn");
679         AFSdsmDeleteObj = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmDelType delType, dsmDelInfo delInfo))dlsym((void *)dynlib, "dsmDeleteObj");
680         AFSdsmEndTxn = (dsInt16_t (*)( dsUint32_t dsmHandle, dsUint8_t vote, dsUint16_t *reason))dlsym((void *)dynlib, "dsmEndTxn");
681         AFSdsmQueryApiVersion = (void (*)( dsmApiVersion *apiVersionP))dlsym((void *)dynlib, "dsmQueryApiVersion");
682         AFSdsmInit = (dsInt16_t (*)( dsUint32_t *dsmHandle, dsmApiVersion *dsmApiVersionP, char *clientNodeNameP, char *clientOwnerNameP, char *clientPasswordP, char *applicationType, char *configfile, char *options))dlsym((void *)dynlib, "dsmInit");
683         AFSdsmQuerySessInfo = (dsInt16_t (*)( dsUint32_t dsmHandle, ApiSessInfo *SessInfoP))dlsym((void *)dynlib, "dsmQuerySessInfo");
684         AFSdsmBeginGetData = (dsInt16_t (*)(dsUint32_t dsmHandle, dsBool_t mountWait, dsmGetType getType, dsmGetList *dsmGetObjListP))dlsym((void *)dynlib, "dsmBeginGetData");
685         AFSdsmGetObj = (dsInt16_t (*)( dsUint32_t dsmHandle, ObjID *objIdP, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmGetObj");
686         AFSdsmEndGetObj = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndGetObj");
687         AFSdsmEndGetData = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndGetData");
688         AFSdsmGetData = (dsInt16_t (*)( dsUint32_t dsmHandle, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmGetData");
689         AFSdsmEndSendObj = (dsInt16_t (*)( dsUint32_t dsmHandle))dlsym((void *)dynlib, "dsmEndSendObj");
690         AFSdsmRegisterFS = (dsInt16_t (*)( dsUint32_t dsmHandle, regFSData *regFilespaceP))dlsym((void *)dynlib, "dsmRegisterFS");
691         AFSdsmBindMC = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmObjName *objNameP, dsmSendType sendType, mcBindKey *mcBindKeyP))dlsym((void *)dynlib, "dsmBindMC");
692         AFSdsmSendObj = (dsInt16_t (*)( dsUint32_t dsmHandle, dsmSendType sendType, void *sendBuff, dsmObjName *objNameP, ObjAttr *objAttrPtr, DataBlk *dataBlkPtr))dlsym((void *)dynlib, "dsmSendObj");
693         AFSdsmChangePW = (dsInt16_t (*)( dsUint32_t dsmHandle, char *oldPW, char *newPW))dlsym((void *)dynlib, "dsmChangePW");
694
695
696         if (    !AFSdsmBeginQuery || !AFSdsmGetNextQObj || !AFSdsmEndQuery ||
697                 !AFSdsmRCMsg || !AFSdsmLogEventEx || !AFSdsmTrace ||
698                 !AFSdsmTerminate || !AFSdsmEndGetObj || !AFSdsmSendData ||
699                 !AFSdsmBeginTxn || !AFSdsmDeleteObj || !AFSdsmEndGetData ||
700                 !AFSdsmEndTxn || !AFSdsmQueryApiVersion || !AFSdsmInit ||
701                 !AFSdsmGetData || !AFSdsmQuerySessInfo || !AFSdsmBeginGetData ||
702                 !AFSdsmGetObj || !AFSdsmEndSendObj || !AFSdsmRegisterFS ||
703                 !AFSdsmBindMC || !AFSdsmSendObj || !AFSdsmChangePW )
704         {
705                 ELog(0,"dsm_MountLibrary: The dlopen call to load the TSM shared library failed\n");
706                 return(BUTX_NOLIBRARY);
707         }
708 #ifdef DEBUG_BUTC
709                 printf("dsm_MountLibrary : All TSM function pointers initialized. \n");
710 #endif
711
712 #endif
713         dsm_init = 1 ;
714 #ifdef DEBUG_BUTC
715     printf("dsm_MountLibrary : leaving function. \n");
716 #endif
717         return 0 ;
718
719 }
720
721 BSA_Int16 BSAInit( long     *BSAHandleP,
722                    SecurityToken  *clientPasswordP,
723                    ObjectOwner    *objectOwnerP,
724                    char          **envP )
725 {
726    dsInt16_t        rc = 0;
727    dsInt16_t        saverc = 0;
728    BSA_Int16        bsaRC = 0;
729    dsUint32_t       dsmHandle;   /* use diff field when talking to base
730                                    code in case either format changes */
731    dsmApiVersion    xapiHdrVer;  /* Xopen API build version           */
732    dsmApiVersion    apiLibVer;  /* Xopen API Libary version          */
733
734    dsUint32_t       xapiVersion, apiVersion;
735    envSetUp         dsmEnvSetUp;
736
737    /*==================================================================
738      Today the BSA constants have the same values as the DSM constants.
739      If this changes, use strncpy.
740      =================================================================*/
741
742    char            rcmsg[DSM_MAX_RC_MSG_LENGTH + 1];
743    char            dsmNode[DSM_MAX_NODE_LENGTH];
744    char            dsmOwner[DSM_MAX_OWNER_LENGTH];
745    char            dsmPswd[DSM_MAX_VERIFIER_LENGTH];
746    char           *dsmNodeP;
747    char           *dsmOwnerP;
748    char           *dsmPswdP;
749    char            options[DSM_MAX_RC_MSG_LENGTH];
750    char           *optionP = NULL;
751    char            TDPLibName[BSA_MAX_DESC];
752    char            TDPILibName[BSA_MAX_DESC];
753    int             i=0;
754    char            errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
755    char            ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
756    char            rcMsg[DSM_MAX_RC_MSG_LENGTH + 1];
757
758    dsmHandle = 0;
759   *BSAHandleP = 0;
760
761 #ifdef DEBUG_BUTC
762    printf("BSAInit : inside function. \n");
763 #endif
764    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
765    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
766    memset(rcMsg,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
767
768    if(!dsm_init)
769    {
770 #ifdef DEBUG_BUTC
771         printf("TSM library not mounted. \n");
772 #endif
773         if (dsm_MountLibrary())
774         {
775                 printf("TSM Library initialisation failed. \n");
776                 return 1 ;
777         }
778 #ifdef DEBUG_BUTC
779         printf("TSM Library initialisation SUCCESS. \n");
780 #endif
781    }
782
783    /*==================================================================
784     Trace won't work before AFSdsmInit, moved to after call to AFSdsmInit
785     The XOpen library is built by statically linking with the API and
786     client common modules.  So, the version checking is unnecessary.
787     We'll fill in the value anyway for consistency.
788     ==================================================================*/
789    memset(&xapiHdrVer,0x00,sizeof(dsmApiVersion));
790    memset(&apiLibVer,0x00,sizeof(dsmApiVersion));
791    memset(&dsmEnvSetUp,0x00,sizeof(envSetUp));
792
793    AFSdsmQueryApiVersion(&apiLibVer);
794
795    xapiHdrVer.version = DSM_API_VERSION;  /* Set the applications    */
796    xapiHdrVer.release = DSM_API_RELEASE;  /* compile time version.   */
797    xapiHdrVer.level   = DSM_API_LEVEL;    /* version                 */
798
799    xapiVersion = (1000 * DSM_API_VERSION) + (100 * DSM_API_RELEASE)
800                   + DSM_API_LEVEL;
801
802    apiVersion  = (1000 * apiLibVer.version) + (100 * apiLibVer.release)
803                   + apiLibVer.level;
804
805    /* check for compatibility problems */
806    if (apiVersion < xapiVersion)
807         return ADSM_RC_ERROR;
808
809    /*==== Init global area ===*/
810
811    memset(&xopenGbl,0x00, sizeof(xGlobal));  /* Zero out block.        */
812
813    memset(dsmNode,0x00,DSM_MAX_NODE_LENGTH);
814    memset(dsmOwner,0x00,DSM_MAX_OWNER_LENGTH);
815    memset(dsmPswd,0x00,DSM_MAX_VERIFIER_LENGTH);
816    memset(options,0x00,DSM_MAX_RC_MSG_LENGTH);
817    memset(TDPLibName,0x00,BSA_MAX_DESC);
818    memset(TDPILibName,0x00,BSA_MAX_DESC);
819
820    memset(rcmsg,         '\0', DSM_MAX_RC_MSG_LENGTH + 1);
821
822
823    /*=== Validate the inputs ===*/
824
825    if (objectOwnerP)
826    {
827       if (strlen(objectOwnerP->bsaObjectOwner) > BSA_MAX_BSAOBJECT_OWNER)
828       {
829          bsaRC = ADSM_RC_OWNER_TOO_LONG;
830          return(bsaRC);
831       }
832
833       if (strlen(objectOwnerP->appObjectOwner) > BSA_MAX_APPOBJECT_OWNER)
834       {
835          bsaRC = ADSM_RC_OWNER_TOO_LONG;
836          return(bsaRC);
837       }
838
839       if (objectOwnerP->bsaObjectOwner[0] == '\0') /* empty string */
840          dsmNodeP = NULL;
841       else
842       {
843          strcpy(dsmNode, objectOwnerP->bsaObjectOwner);
844          dsmNodeP = dsmNode;
845       }
846
847       if (objectOwnerP->appObjectOwner[0] == '\0') /* empty string  */
848          dsmOwnerP = NULL;
849       else
850       {
851          strcpy(dsmOwner, objectOwnerP->appObjectOwner);
852          dsmOwnerP = dsmOwner;
853       }
854    }
855    else
856    {
857       dsmNodeP = NULL;
858       dsmOwnerP = NULL;
859    }
860
861    if (clientPasswordP != NULL)
862    {
863       if (strlen((const char *)clientPasswordP) > BSA_MAX_TOKEN_SIZE)
864       {
865          bsaRC = ADSM_RC_PSWD_TOO_LONG;
866          return(bsaRC);
867       }
868
869       strcpy(dsmPswd, (const char *)clientPasswordP);
870       dsmPswdP = dsmPswd;
871    }
872    else
873       dsmPswdP = NULL;
874       {
875           while ((envP[i] != NULL) && (envP[i] != '\0'))
876           {
877              strcat(options, "-");
878              strcat(options, envP[i]);
879              if ((envP[i+1] != NULL) && (envP[i+1] != '\0'))
880                 strcat(options, " ");
881                 i++;
882           }
883
884           if (options[0] == '\0')   /* empty string */
885              optionP = NULL;
886           else
887              optionP = options;
888
889           rc = AFSdsmInit(&dsmHandle,   /* On return contains session handle.   */
890                        &xapiHdrVer,   /* Version of the API we are using.     */
891                        dsmNodeP,      /* node name                            */
892                        dsmOwnerP,     /* owner name                           */
893                        dsmPswdP,      /* password                             */
894                        APPLTYPE,      /* Name of our node type.               */
895                        NULL,          /* no API config file name              */
896                        optionP);      /* option string                        */
897      }
898
899      if (rc == DSM_RC_OK)
900      {
901         /*=== now that AFSdsmInit issued, we can trace ===*/
902         sprintf(traceStr2,
903                 "BSAInit: original bsaOwner=%s, appOwner=%s, token=%s, Appl Type=%s, options=%s.",
904                  dsmNode, dsmOwner, dsmPswd, APPLTYPE, options);
905         ourTrace(dsmHandle, TrFL, traceStr2);
906         {
907               strcpy(TDPLibName, TDP_LIBNAME);
908               sprintf(traceStr2,
909                      "BSAInit: Using TSM Native API library : %s", TDPLibName);
910               ourTrace(dsmHandle, TrFL, traceStr2);
911         }
912      }
913
914
915      /*=================================================================
916      If the password expired, continue initialization so the session
917      can continue.
918
919      Save the 'password expired' rc away, so we can return it to the
920      caller.
921
922      The application will be responsible for issuing a BSAChangeToken()
923      to update the password.
924      =================================================================*/
925      if (rc == DSM_RC_REJECT_VERIFIER_EXPIRED)
926      {
927         /*=== don't return yet - init global so session can continue ===*/
928
929          saverc = rc;
930          rc = DSM_RC_OK;
931      }
932      else
933         if ((rc == DSM_RC_NO_OWNER_REQD) ||
934             (rc == DSM_RC_NO_NODE_REQD))       /* pswd=generate */
935         {
936             AFSdsmTerminate(dsmHandle);
937             bsaRC = ADSM_RC_PSWD_GEN;
938             return (bsaRC);
939         }
940
941
942    /*==================================================================
943      If we ran into any problems so far, rc will be non-zero or 'true'.
944
945      This is not true for password expired, since we reset rc to zero
946      in that case.  We'll have to check for that later so we return
947      the 'password expired' indication to the caller.
948      ==================================================================*/
949
950    if (rc)
951    {
952       AFSdsmRCMsg(dsmHandle, rc, rcmsg);
953       sprintf(traceStr2, "BSAInit(AFSdsmInit): Messages - %s ", rcmsg);
954       ourTrace(dsmHandle, TrFL, traceStr2);
955       strcpy(ourMessage, ourRCMsg(rc, errPrefix));
956       ourLogEvent_Ex(dsmHandle, logLocal, ourMessage, errPrefix, logSevError);
957       xlateRC(*BSAHandleP, rc, &bsaRC); /* BSAHandle still 0, but not used */
958       AFSdsmTerminate(dsmHandle);          /* clean up memory blocks          */
959       return (bsaRC);
960    }
961
962
963    {
964       char msg[256];                    /* format string and watch for NULLs */
965
966       strcpy(msg, "BSAInit for node=");
967
968       if (objectOwnerP)
969       {
970          if (dsmNodeP)
971             strcat(msg, dsmNodeP);
972          else
973             strcat(msg, "<empty>");
974       }
975       else
976          strcat(msg, "<NULL>");
977
978       strcat(msg, ", owner=");
979
980       if (objectOwnerP)
981       {
982          if (dsmOwnerP)
983             strcat(msg, dsmOwnerP);
984          else
985             strcat(msg, "<empty>");
986       }
987       else
988          strcat(msg, "<NULL>");
989
990       strcat(msg, ".\n");
991
992       strcpy(traceStr, msg);
993    }
994
995    *BSAHandleP = (long)dsmHandle;
996
997
998    /*=================================================================
999     For password expired processing the application is responsible for
1000     issuing BSAChangeToken() to update the password, when they see the
1001     'expired password' return code.
1002
1003     The BSAChangeToken() command will issue the AFSdsmQuerySessInfo()
1004     call, so don't issue it here.
1005     =================================================================*/
1006
1007    if (!saverc)               /* don't call this if we got pswd expire */
1008    {
1009       /*=== now query session info to populate the global structure ===*/
1010
1011       xopenGbl.dsmSessInfo.stVersion = ApiSessInfoVersion;
1012       rc = AFSdsmQuerySessInfo(dsmHandle,                /* Session handle */
1013                             &xopenGbl.dsmSessInfo);   /* Output struct  */
1014
1015       if (rc)
1016       {
1017          sprintf(traceStr2, "BSAInit(AFSdsmQuerySessInfo): error rc = %d", rc);
1018          ourTrace(dsmHandle, TrFL, traceStr2);
1019          AFSdsmTerminate(dsmHandle);
1020          *BSAHandleP = 0;
1021       }
1022       else
1023       {
1024          sprintf(traceStr2, "BSAInit: Actual node=%s, actual DSM owner=%s, servername=%s.",
1025                  xopenGbl.dsmSessInfo.id, xopenGbl.dsmSessInfo.owner,
1026                  xopenGbl.dsmSessInfo.adsmServerName);
1027          ourTrace(dsmHandle, TrFL, traceStr2);
1028       }
1029    }
1030    else
1031    {
1032       /*============================================================
1033         Indicate in the session flags that we encountered a password
1034         expiration condition.  The application will know that this
1035         happened via the return code.
1036         ===========================================================*/
1037
1038       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_PSWD_EXPIRE);
1039    }
1040
1041    /*=== Save bsaObjectOwner (node name) value passed on Init ===*/
1042
1043    if (dsmNodeP)
1044       strcpy(xopenGbl.bsaObjectOwner, dsmNodeP);
1045
1046      /*================================================================
1047       Check to see if we saved away the 'expired password' return code.
1048       if so, return it to the caller.
1049       ================================================================*/
1050
1051    if (saverc)
1052       rc = saverc;
1053
1054    xlateRC(*BSAHandleP, rc, &bsaRC);
1055 #ifdef DEBUG_BUTC
1056         printf("BSAInit : Leaving Function. \n");
1057 #endif
1058    return (bsaRC);
1059 }
1060
1061 BSA_Int16 BSATerminate(
1062     long              BSAHandle
1063 )
1064 {
1065    dsInt16_t      rc = 0;
1066    BSA_Int16      bsaRC = 0;
1067    dsUint32_t     dsmHandle;
1068
1069    if(!dsm_init)
1070    {
1071 #ifdef DEBUG_BUTC
1072         printf("TSM library not mounted. \n");
1073 #endif
1074         if (dsm_MountLibrary())
1075         {
1076                 printf("TSM Library initialisation failed. \n");
1077                 return 1 ;
1078         }
1079 #ifdef DEBUG_BUTC
1080         printf("TSM Library initialisation SUCCESS. \n");
1081 #endif
1082    }
1083
1084    dsmHandle = BSAHandle;
1085    sprintf(traceStr2, "BSATerminate ENTRY: BSAHandle is %ld.",
1086                       BSAHandle);
1087    ourTrace(dsmHandle, TrFL, traceStr2);
1088
1089    rc = AFSdsmTerminate(dsmHandle);
1090    dsmHandle = 0;
1091    xlateRC(dsmHandle, rc, &bsaRC);
1092
1093    return (bsaRC);
1094
1095 }
1096
1097 BSA_Int16 BSAChangeToken(
1098    long           BSAHandle,
1099    SecurityToken *oldTokenP,
1100    SecurityToken *newTokenP
1101 )
1102 {
1103    dsInt16_t      rc = 0;
1104    BSA_Int16      bsaRC = 0;
1105    dsUint32_t     dsmHandle;
1106
1107    if(!dsm_init)
1108    {
1109 #ifdef DEBUG_BUTC
1110         printf("TSM library not mounted. \n");
1111 #endif
1112         if (dsm_MountLibrary())
1113         {
1114                 printf("TSM Library initialisation failed. \n");
1115                 return 1 ;
1116         }
1117 #ifdef DEBUG_BUTC
1118         printf("TSM Library initialisation SUCCESS. \n");
1119 #endif
1120    }
1121
1122    dsmHandle = BSAHandle;
1123
1124    sprintf(traceStr2, "BSAChangeToken ENTRY: BSAHandle:%ld old:>%s< new:>%s<",
1125            BSAHandle,*oldTokenP,*newTokenP);
1126    ourTrace(dsmHandle, TrFL, traceStr2);
1127
1128    rc = AFSdsmChangePW(dsmHandle, (char *)oldTokenP, (char *)newTokenP);
1129
1130    if (rc)
1131    {
1132       xlateRC(BSAHandle, rc, &bsaRC);
1133       XOPENRETURN(BSAHandle,"BSAChangeToken(AFSdsmChangePW)",
1134                   bsaRC,__FILE__,__LINE__);
1135    }
1136
1137    xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_PSWD_EXPIRE); /* set off */
1138
1139     /*=== now query session info to populate the global structure ===*/
1140
1141    xopenGbl.dsmSessInfo.stVersion = ApiSessInfoVersion;
1142    rc = AFSdsmQuerySessInfo(dsmHandle,                /* Our session handle  */
1143                          &xopenGbl.dsmSessInfo);   /* Output structure.   */
1144    if (rc)
1145    {
1146       /*=== appl should call Terminate ===*/
1147       sprintf(traceStr2, "BSAChangeToken(AFSdsmQuerySessInfo): error rc = %d", rc);
1148       ourTrace(BSAHandle, TrFL, traceStr2);
1149    }
1150    xlateRC(BSAHandle, rc, &bsaRC);
1151    XOPENRETURN(BSAHandle,"BSAChangeToken",
1152                bsaRC,__FILE__,__LINE__);
1153 }
1154
1155 BSA_Int16 BSASetEnvironment(
1156     long     BSAHandle,
1157     char           **envP
1158 )
1159 {
1160    if(!dsm_init)
1161    {
1162 #ifdef DEBUG_BUTC
1163         printf("TSM library not mounted. \n");
1164 #endif
1165         if (dsm_MountLibrary())
1166         {
1167                 printf("TSM Library initialisation failed. \n");
1168                 return 1 ;
1169         }
1170 #ifdef DEBUG_BUTC
1171         printf("TSM Library initialisation SUCCESS. \n");
1172 #endif
1173    }
1174
1175    sprintf(traceStr2, "BSASetEnvironment ENTRY: BSAHandle:%ld envP:>%p< ",
1176            BSAHandle,envP);
1177    ourTrace(BSAHandle, TrFL, traceStr2);
1178    XOPENRETURN(BSAHandle,"BSASetEnvironment",
1179                BSA_RC_BAD_CALL_SEQUENCE,__FILE__,__LINE__);
1180 }
1181
1182 BSA_Int16 BSAGetEnvironment(
1183    long           BSAHandle,
1184    ObjectOwner   *objOwnerP,
1185    char         **envP
1186 )
1187 {
1188    dsInt16_t   rc = 0;
1189    BSA_Int16   bsaRC = 0;
1190    dsUint32_t  dsmHandle;
1191    char        envString[ADSM_ENV_STRS][BSA_MAX_DESC];
1192    char        maxObjStr[6];  /* conversion field. value range is 16-256 */
1193    dsUint32_t  maxObjNum;
1194    dsInt16_t   i;
1195
1196    if(!dsm_init)
1197    {
1198 #ifdef DEBUG_BUTC
1199         printf("TSM library not mounted. \n");
1200 #endif
1201         if (dsm_MountLibrary())
1202         {
1203                 printf("TSM Library initialisation failed. \n");
1204                 return 1 ;
1205         }
1206 #ifdef DEBUG_BUTC
1207         printf("TSM Library initialisation SUCCESS. \n");
1208 #endif
1209    }
1210
1211    for (i=0; i<ADSM_ENV_STRS; i++)
1212    {
1213       memset(envString[i], 0x00, BSA_MAX_DESC);
1214    }
1215    sprintf(traceStr2, "BSAGetEnvironment ENTRY: BSAHandle:%ld ObjOwner:'%s' appOwner:'%s' envP:>%p<.",
1216            BSAHandle,
1217            objOwnerP->bsaObjectOwner,
1218            objOwnerP->appObjectOwner,
1219            envP);
1220    ourTrace(BSAHandle, TrFL, traceStr2);
1221
1222    dsmHandle = BSAHandle;
1223
1224    /*===============================================================
1225     check if BSAInit has been done for now we have only one possible
1226     handle value - change in future
1227     ==============================================================*/
1228    if ((dsmHandle != FIRST_HANDLE) ||
1229       (xopenGbl.dsmSessInfo.stVersion != ApiSessInfoVersion))
1230        XOPENRETURN(BSAHandle,"BSAGetEnvironment",
1231                    BSA_RC_BAD_CALL_SEQUENCE, __FILE__,__LINE__);
1232
1233    if (objOwnerP)
1234    {
1235       strcpy(objOwnerP->bsaObjectOwner, xopenGbl.dsmSessInfo.id);
1236       strcpy(objOwnerP->appObjectOwner, xopenGbl.dsmSessInfo.owner);
1237    }
1238    else
1239       XOPENRETURN(BSAHandle,"BSAGetEnvironment",
1240                   BSA_RC_NULL_POINTER, __FILE__,__LINE__);
1241
1242    rc = AFSdsmQuerySessInfo(dsmHandle,                   /* Session Handle */
1243                          &xopenGbl.dsmSessInfo);       /* Output struct  */
1244
1245    if (rc)
1246       {
1247          sprintf(traceStr2, "BSAGetEnvironment(AFSdsmQuerySessInfo): error rc = %d", rc);
1248          ourTrace(dsmHandle, TrFL, traceStr2);
1249          AFSdsmTerminate(dsmHandle);
1250         /* *BSAHandleP = 0; */
1251       }
1252       else
1253       {
1254          sprintf(traceStr2, "BSAGetEnvironment: Actual node=%s, actual DSM owner=%s, ServerName=%s.",
1255                  xopenGbl.dsmSessInfo.id, xopenGbl.dsmSessInfo.owner, xopenGbl.dsmSessInfo.adsmServerName);
1256          ourTrace(dsmHandle, TrFL, traceStr2);
1257       }
1258
1259    strcpy(envString[0],"TSMSRVR=");
1260    strcat(envString[0],xopenGbl.dsmSessInfo.serverHost);
1261
1262    strcpy(envString[1],"TSMMAXOBJ=");
1263    maxObjNum = xopenGbl.dsmSessInfo.maxObjPerTxn;  /* convert to 32 bit */
1264    sprintf(maxObjStr,"%u", maxObjNum );
1265    strcat(envString[1], maxObjStr);
1266
1267    strcpy(envString[2], "TSMSRVRSTANZA=");
1268    strcat(envString[2], xopenGbl.dsmSessInfo.adsmServerName);
1269
1270    sprintf(traceStr2, "BSAGetEnvironment Value : TSM Server '%s', TSM Max Object '%s',TSM Server STANZA '%s'",
1271          envString[0], envString[1], envString[2]);
1272    ourTrace(BSAHandle, TrFL, traceStr2);
1273
1274    for (i=0; i< ADSM_ENV_STRS; i++) {
1275      if ( *envP == NULL ) {  /* watch for NULL pointers */
1276        /* Allocating memory for *envP.*/
1277        *envP = malloc(sizeof(char) * BSA_MAX_DESC +1);
1278
1279        /* copy the content of envString[i] to *envP. */
1280         strcpy(*envP,envString[i]);
1281         envP++;
1282      }
1283    }
1284
1285    xlateRC(BSAHandle, rc, &bsaRC);
1286    XOPENRETURN(BSAHandle,"BSAGetEnvironment",
1287                bsaRC,__FILE__,__LINE__)
1288 }
1289
1290 BSA_Int16 BSABeginTxn(
1291     long             BSAHandle
1292 )
1293 {
1294    if(!dsm_init)
1295    {
1296 #ifdef DEBUG_BUTC
1297         printf("TSM library not mounted. \n");
1298 #endif
1299         if (dsm_MountLibrary())
1300         {
1301                 printf("TSM Library initialisation failed. \n");
1302                 return 1 ;
1303         }
1304 #ifdef DEBUG_BUTC
1305         printf("TSM Library initialisation SUCCESS. \n");
1306 #endif
1307    }
1308
1309    sprintf(traceStr2, "BSABeginTxn ENTRY: BSAHandle:%ld", BSAHandle);
1310    ourTrace(BSAHandle, TrFL, traceStr2);
1311   /*========================================================
1312    don't actually issue BeginTxn yet, because we will do our
1313    own for Get and Query
1314    ========================================================*/
1315
1316    xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_BSA_TXN); /* set on */
1317    XOPENRETURN(BSAHandle, "BSABeginTxn",
1318                BSA_RC_SUCCESS,__FILE__,__LINE__);
1319 }
1320
1321 BSA_Int16 BSAEndTxn(
1322     long           BSAHandle,
1323     Vote           vote
1324 )
1325 {
1326    dsInt16_t      rc = 0;
1327    BSA_Int16      bsaRC = 0;
1328    dsUint32_t     dsmHandle;
1329    dsUint8_t      dsmVote;
1330    dsUint16_t     reason ;
1331    char           rsMsg[DSM_MAX_RC_MSG_LENGTH + 1];
1332    char           errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
1333    char           ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
1334
1335    if(!dsm_init)
1336    {
1337 #ifdef DEBUG_BUTC
1338         printf("TSM library not mounted. \n");
1339 #endif
1340         if (dsm_MountLibrary())
1341         {
1342                 printf("TSM Library initialisation failed. \n");
1343                 return 1 ;
1344         }
1345 #ifdef DEBUG_BUTC
1346         printf("TSM Library initialisation SUCCESS. \n");
1347 #endif
1348    }
1349
1350    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1351    memset(rsMsg,        '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1352    memset(ourMessage,    '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1353
1354    sprintf(traceStr2, "BSAEndTxn ENTRY: BSAHandle:%ld Vote:>%d<", BSAHandle, vote);
1355    ourTrace(BSAHandle, TrFL, traceStr2);
1356
1357    dsmHandle = BSAHandle;
1358
1359    if (xopenGbl.sessFlags & FL_IN_DSM_TXN)
1360    {
1361       if (vote == BSAVote_COMMIT)
1362          dsmVote = DSM_VOTE_COMMIT;
1363       else
1364          if (vote == BSAVote_ABORT)
1365             dsmVote = DSM_VOTE_ABORT;
1366          else
1367          {
1368             sprintf(traceStr2, "BSAEndTxn: invalid vote (%d)", vote);
1369             ourTrace(BSAHandle,TrFL, traceStr2);
1370             bsaRC = BSA_RC_INVALID_VOTE;
1371             XOPENRETURN(BSAHandle, "BSAEndTxn",bsaRC,__FILE__,__LINE__);
1372          }
1373
1374
1375       sprintf(traceStr2, "BSAEndTxn: issue AFSdsmEndTxn, vote=%s",
1376                   dsmVote == DSM_VOTE_COMMIT ? "COMMIT" : "ABORT");
1377       ourTrace(BSAHandle,TrFL, traceStr2);
1378       /*===========================================================
1379         check if this EndTxn call was proceeded by a Send call which
1380         returned WILL_ABORT. If so, make sure the vote is COMMIT
1381         so we will get the server's reason code.
1382         ===========================================================*/
1383       if (xopenGbl.sessFlags & FL_RC_WILL_ABORT)
1384       {
1385          dsmVote = DSM_VOTE_COMMIT;
1386
1387          sprintf(traceStr2, "BSAEndTxn: sproceeded by RC_WILL_ABORT, so use vote=COMMIT");
1388          ourTrace(BSAHandle,TrFL, traceStr2);
1389          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_RC_WILL_ABORT); /* set off*/
1390       }
1391
1392       rc = AFSdsmEndTxn(dsmHandle, dsmVote, &reason);
1393       xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_DSM_TXN); /* set off */
1394
1395       /*====================================================
1396        if the caller wanted to Abort, then return rc=OK, not
1397        our usual 2302 and reason 3
1398        =====================================================*/
1399       if ((dsmVote ==  DSM_VOTE_ABORT)     &&
1400           (rc == DSM_RC_CHECK_REASON_CODE) &&
1401           (reason == DSM_RC_ABORT_BY_CLIENT))
1402
1403          rc = DSM_RC_OK;
1404
1405       if (rc)
1406       {
1407          sprintf(traceStr2, "BSAEndTxn(AFSdsmEndTxn) error rc = %d", rc);
1408          ourTrace(BSAHandle,TrFL, traceStr2);
1409
1410          AFSdsmRCMsg(BSAHandle, reason, rsMsg);
1411          sprintf(traceStr2, "BSAEndTxn: reason code = %d, Message='%s'", reason, rsMsg);
1412          ourTrace(BSAHandle,TrFL, traceStr2);
1413
1414          strcpy(ourMessage, ourRCMsg(reason, errPrefix));
1415          ourLogEvent_Ex(BSAHandle,logBoth, ourMessage, errPrefix, logSevError);
1416       }
1417       xlateRC(BSAHandle, rc, &bsaRC);
1418
1419       if (rc == DSM_RC_CHECK_REASON_CODE) /* return reason code instead */
1420       {
1421          xlateRC(BSAHandle, reason, &bsaRC);
1422       }
1423    }
1424
1425    /*=== check if Query was terminated ===*/
1426    if (xopenGbl.sessFlags & FL_IN_BSA_QRY)
1427    {
1428       AFSdsmEndQuery(dsmHandle);
1429       xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1430    }
1431
1432    xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_TXN); /* set off */
1433    XOPENRETURN(BSAHandle, "BSAEndTxn",
1434                bsaRC,__FILE__,__LINE__);
1435 }
1436
1437 void  BSAQueryApiVersion(
1438 ApiVersion       *BSAapiVerP
1439 )
1440
1441 {
1442    /*===============================================================
1443     Don't actually call the base QueryApiVersion call.
1444     Use the defines from custom.h since this is what the application
1445     sees in the header file. The constants should be the same,
1446     but may get out of sync occasionally.
1447     ===============================================================*/
1448    BSAapiVerP->version = BSA_API_VERSION;
1449    BSAapiVerP->release = BSA_API_RELEASE;
1450    BSAapiVerP->level   = BSA_API_LEVEL;
1451    return;
1452 }
1453
1454 BSA_Int16 BSAQueryObject(
1455 long              BSAHandle,
1456 QueryDescriptor  *BSAqryDescP,
1457 ObjectDescriptor *BSAobjDescP
1458 )
1459 {
1460    dsInt16_t      rc = 0;
1461    BSA_Int16      bsaRC = 0;
1462    dsUint32_t     dsmHandle;
1463    dsmObjName     objName;
1464    dsUint8_t      dsmObjType;
1465    dsmQueryType   query_type;
1466    dsmQueryBuff   *query_buff;
1467    DataBlk        qData;
1468    qryArchiveData archiveData;
1469    qryRespArchiveData respArchive;
1470    qryBackupData  backupData;
1471    qryRespBackupData  respBackup;
1472    BSAObjectOwner upperNode;  /* upper cased node name */
1473
1474    char           errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
1475    char           ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
1476
1477    if(!dsm_init)
1478    {
1479 #ifdef DEBUG_BUTC
1480         printf("TSM library not mounted. \n");
1481 #endif
1482         if (dsm_MountLibrary())
1483         {
1484                 printf("TSM Library initialisation failed. \n");
1485                 return 1 ;
1486         }
1487 #ifdef DEBUG_BUTC
1488         printf("TSM Library initialisation SUCCESS. \n");
1489 #endif
1490    }
1491
1492    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1493    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1494
1495    dsmHandle = BSAHandle;
1496
1497    memset(&backupData, 0x00, sizeof(qryBackupData));
1498
1499    sprintf(traceStr2, "BSAQueryObject ENTRY: BSAHandle:%ld ObjOwner(qryDesc):'%s' appOwner(qryDesc):'%s' \n ObjName(qryDesc):'%.*s%.*s' \n copyType:%d ObjectType:%d status:%d ",
1500           BSAHandle,
1501           BSAqryDescP->owner.bsaObjectOwner,
1502           BSAqryDescP->owner.appObjectOwner,
1503           100,BSAqryDescP->objName.objectSpaceName,
1504           100,BSAqryDescP->objName.pathName,
1505           BSAqryDescP->copyType,
1506           BSAqryDescP->objectType,
1507           BSAqryDescP->status);
1508    ourTrace(BSAHandle, TrFL, traceStr2);
1509
1510    /*=====================================================
1511     init objDesc area to 0's before we start to erase any
1512     garbage that might be there.
1513     =====================================================*/
1514    memset(BSAobjDescP, 0x00, sizeof(ObjectDescriptor));
1515
1516    /*=== init global look ahead pointer to NULL ===*/
1517    if (xopenGbl.nextQryP != NULL)
1518    {
1519       dsFree(xopenGbl.nextQryP);
1520       xopenGbl.nextQryP = NULL;
1521    }
1522
1523    /*=========================================================
1524     if the node name is different - we won't query it compare
1525     both the value passed on the BSAInit and the final value
1526     used for the session (which may be different for Generate).
1527     =========================================================*/
1528    strcpy(upperNode, BSAqryDescP->owner.bsaObjectOwner);
1529    StrUpper(upperNode);
1530    if ((strcmp(upperNode, xopenGbl.dsmSessInfo.id)) &&
1531       (strcmp(BSAqryDescP->owner.bsaObjectOwner, xopenGbl.bsaObjectOwner)))
1532    {
1533       sprintf(traceStr2,
1534       "BSAQueryObject: BSAObjectOwner(%s) doesn't match value for session(%s).", upperNode, xopenGbl.dsmSessInfo.id);
1535       ourTrace(BSAHandle,TrFL, traceStr2);
1536       bsaRC = ADSM_RC_INVALID_NODE;
1537       strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1538       ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1539       XOPENRETURN(BSAHandle, "BSAQueryObject",
1540                   bsaRC,__FILE__,__LINE__);
1541    }
1542
1543    /*=====================================================
1544      currently BSA_MAX_OSNAME = DSM_MAX_FSNAME_LENGTH
1545      if this changes, use strncpy
1546      ====================================================*/
1547    if (strlen(BSAqryDescP->objName.objectSpaceName) > BSA_MAX_OSNAME)
1548    {
1549       sprintf(traceStr2, "BSAQueryObject: objectSpaceName too long (%" AFS_SIZET_FMT ").",
1550               strlen(BSAqryDescP->objName.objectSpaceName));
1551       ourTrace(BSAHandle,TrFL, traceStr2);
1552       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
1553       XOPENRETURN(BSAHandle, "BSAQueryObject",
1554                   bsaRC,__FILE__,__LINE__);
1555    }
1556    /*=================================================================
1557      the entire pathname gets copied into hl during parsing, so check
1558      for that max len as well. For now these are the same value.
1559      ================================================================*/
1560    if (strlen(BSAqryDescP->objName.pathName) >
1561        min(DSM_MAX_HL_LENGTH, BSA_MAX_PATHNAME))
1562    {
1563       sprintf(traceStr2, "BSAQueryObject: pathName too long (%" AFS_SIZET_FMT ")",
1564               strlen(BSAqryDescP->objName.pathName));
1565       ourTrace(BSAHandle, TrFL, traceStr2);
1566       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
1567       XOPENRETURN(BSAHandle, "BSAQueryObject",
1568                   bsaRC,__FILE__,__LINE__);
1569    }
1570    if ((BSAqryDescP->objectType == BSAObjectType_FILE) ||
1571        (BSAqryDescP->objectType == BSAObjectType_DATABASE))
1572       dsmObjType = DSM_OBJ_FILE;
1573    else
1574       if (BSAqryDescP->objectType == BSAObjectType_DIRECTORY)
1575          dsmObjType = DSM_OBJ_DIRECTORY;
1576       else
1577          if (BSAqryDescP->objectType == BSAObjectType_ANY)
1578             dsmObjType = DSM_OBJ_ANY_TYPE;
1579          else
1580          {
1581              sprintf(traceStr2,
1582                      "BSAQueryObject: invalid objectType (%d)", BSAqryDescP->objectType);
1583              ourTrace(BSAHandle,TrFL, traceStr2);
1584              bsaRC = ADSM_RC_INVALID_OBJTYPE;
1585              strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1586              ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1587              XOPENRETURN(BSAHandle, "BSAQueryObject",
1588                          bsaRC,__FILE__,__LINE__);
1589          }
1590
1591    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
1592    {
1593       sprintf(traceStr2, "BSAQueryObject: issued without BSABeginTxn");
1594       ourTrace(BSAHandle,TrFL, traceStr2);
1595       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
1596       XOPENRETURN(BSAHandle, "BSAQueryObject",
1597                   bsaRC,__FILE__,__LINE__);
1598    }
1599
1600    /* store object name in ADSM structure */
1601    strcpy(objName.fs,BSAqryDescP->objName.objectSpaceName) ;
1602
1603    if (!strcmp(BSAqryDescP->objName.pathName, "/*")) /* if they use a wildcard */
1604    {  /* we need to use a wild card on both hl and ll since the path gets split */
1605       strcpy(objName.hl, "*");  /* don't include delimiter in case there is
1606                              no hl */
1607       strcpy(objName.ll, "/*");
1608    }
1609    else
1610       xparsePath(BSAHandle, BSAqryDescP->objName.pathName, objName.hl, objName.ll);
1611
1612       objName.objType = dsmObjType ;
1613
1614       /*=== save copy type for GetNextQuery call later ===*/
1615       xopenGbl.copyType = BSAqryDescP->copyType;
1616
1617       if (BSAqryDescP->copyType == BSACopyType_ARCHIVE)
1618       {
1619          if (strlen(BSAqryDescP->desc) > ADSM_MAX_DESC)
1620          {
1621
1622             sprintf(traceStr2, "BSAQueryObject: description longer than ADSM max (%" AFS_SIZET_FMT "). ", strlen(BSAqryDescP->desc));
1623             ourTrace(BSAHandle,TrFL, traceStr2);
1624             bsaRC = BSA_RC_DESC_TOO_LONG;
1625             XOPENRETURN(BSAHandle, "BSAQueryObject",
1626                         bsaRC,__FILE__,__LINE__);
1627          }
1628
1629          archiveData.stVersion = qryArchiveDataVersion;
1630          archiveData.objName   = &objName;
1631          archiveData.owner     = (char *)&BSAqryDescP->owner.appObjectOwner;
1632
1633          /*=================================================================
1634            in the tm structure the month count starts with 0 and year is
1635            the value since 1900.
1636            Adjust the year value only if it isn't one of the boundary values
1637            =================================================================*/
1638
1639          archiveData.insDateLowerBound.year   = BSAqryDescP->createTimeLB.tm_year;
1640          if (archiveData.insDateLowerBound.year != ADSM_LOWEST_BOUND)
1641             archiveData.insDateLowerBound.year  += 1900;
1642          archiveData.insDateLowerBound.month  = BSAqryDescP->createTimeLB.tm_mon+1;
1643          archiveData.insDateLowerBound.day    = BSAqryDescP->createTimeLB.tm_mday;
1644          archiveData.insDateLowerBound.hour   = BSAqryDescP->createTimeLB.tm_hour;
1645          archiveData.insDateLowerBound.minute = BSAqryDescP->createTimeLB.tm_min;
1646          archiveData.insDateLowerBound.second = BSAqryDescP->createTimeLB.tm_sec;
1647
1648          archiveData.insDateUpperBound.year   = BSAqryDescP->createTimeUB.tm_year;
1649          if (archiveData.insDateUpperBound.year != ADSM_HIGHEST_BOUND)
1650              archiveData.insDateUpperBound.year  += 1900;
1651          archiveData.insDateUpperBound.month  = BSAqryDescP->createTimeUB.tm_mon+1;
1652          archiveData.insDateUpperBound.day    = BSAqryDescP->createTimeUB.tm_mday;
1653          archiveData.insDateUpperBound.hour   = BSAqryDescP->createTimeUB.tm_hour;
1654          archiveData.insDateUpperBound.minute = BSAqryDescP->createTimeUB.tm_min;
1655          archiveData.insDateUpperBound.second = BSAqryDescP->createTimeUB.tm_sec;
1656
1657          archiveData.expDateLowerBound.year   = BSAqryDescP->expireTimeLB.tm_year;
1658          if (archiveData.expDateLowerBound.year != ADSM_LOWEST_BOUND)
1659              archiveData.expDateLowerBound.year  += 1900;
1660          archiveData.expDateLowerBound.month  = BSAqryDescP->expireTimeLB.tm_mon+1;
1661          archiveData.expDateLowerBound.day    = BSAqryDescP->expireTimeLB.tm_mday;
1662          archiveData.expDateLowerBound.hour   = BSAqryDescP->expireTimeLB.tm_hour;
1663          archiveData.expDateLowerBound.minute = BSAqryDescP->expireTimeLB.tm_min;
1664          archiveData.expDateLowerBound.second = BSAqryDescP->expireTimeLB.tm_sec;
1665
1666          archiveData.expDateUpperBound.year   = BSAqryDescP->expireTimeUB.tm_year;
1667          if (archiveData.expDateUpperBound.year != ADSM_HIGHEST_BOUND)
1668             archiveData.expDateUpperBound.year  += 1900;
1669          archiveData.expDateUpperBound.month  = BSAqryDescP->expireTimeUB.tm_mon+1;
1670          archiveData.expDateUpperBound.day    = BSAqryDescP->expireTimeUB.tm_mday;
1671          archiveData.expDateUpperBound.hour   = BSAqryDescP->expireTimeUB.tm_hour;
1672          archiveData.expDateUpperBound.minute = BSAqryDescP->expireTimeUB.tm_min;
1673          archiveData.expDateUpperBound.second = BSAqryDescP->expireTimeUB.tm_sec;
1674
1675          archiveData.descr = (char *)&BSAqryDescP->desc;
1676          query_type = qtArchive;
1677          query_buff = (dsmQueryBuff *)&archiveData;
1678
1679          qData.stVersion = DataBlkVersion;
1680          qData.bufferLen = sizeof(qryRespArchiveData);
1681          qData.bufferPtr = (char *)&respArchive;
1682          respArchive.stVersion = qryRespArchiveDataVersion;
1683    }
1684    else
1685       if (BSAqryDescP->copyType == BSACopyType_BACKUP)
1686       {
1687          if (BSAqryDescP->status == BSAObjectStatus_ACTIVE)
1688             backupData.objState  = DSM_ACTIVE;
1689          else
1690             if (BSAqryDescP->status == BSAObjectStatus_INACTIVE)
1691                backupData.objState  = DSM_INACTIVE;
1692             else
1693                if (BSAqryDescP->status == BSAObjectStatus_ANY)
1694                   backupData.objState  = DSM_ANY_MATCH;
1695                else
1696                {
1697                    sprintf(traceStr2,
1698                            "BSAQueryObject: invalid status (%d)",
1699                             BSAqryDescP->status);
1700                    ourTrace(BSAHandle,TrFL, traceStr2);
1701                    bsaRC = ADSM_RC_INVALID_STATUS;
1702                    strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1703                    ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1704                    XOPENRETURN(BSAHandle, "BSAQueryObject",
1705                                bsaRC,__FILE__,__LINE__);
1706                }
1707
1708             backupData.stVersion = qryBackupDataVersion;
1709             backupData.objName   = &objName;
1710             backupData.owner     = (char *)&BSAqryDescP->owner.appObjectOwner;
1711
1712             query_type = qtBackup;
1713             query_buff = (dsmQueryBuff *)&backupData;
1714
1715             qData.stVersion = DataBlkVersion;
1716             qData.bufferLen = sizeof(qryRespBackupData);
1717             qData.bufferPtr = (char *)&respBackup;
1718             respBackup.stVersion = qryRespBackupDataVersion;;
1719       }
1720       else
1721       {
1722          sprintf(traceStr2,
1723                            "BSAQueryObject: invalid copyType (%d)",
1724                             BSAqryDescP->copyType);
1725          ourTrace(BSAHandle,TrFL, traceStr2);
1726          bsaRC = ADSM_RC_INVALID_COPYTYPE;
1727          strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1728          ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1729          XOPENRETURN(BSAHandle, "BSAQueryObject",
1730                      bsaRC,__FILE__,__LINE__);
1731       }
1732
1733       /*=== now set flag for query ===*/
1734       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_BSA_QRY); /* set on */
1735
1736       if ((rc = AFSdsmBeginQuery(dsmHandle,query_type,query_buff)))
1737       {
1738
1739          sprintf(traceStr2, "BSAQueryObject(AFSdsmBeginQuery) error rc = %d", rc);
1740          ourTrace(BSAHandle,TrFL, traceStr2);
1741          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1742          xlateRC(BSAHandle, rc, &bsaRC);
1743          XOPENRETURN(BSAHandle, "BSAQueryObject(AFSdsmBeginQuery)",
1744                                  bsaRC,__FILE__,__LINE__);
1745       }
1746
1747       rc = AFSdsmGetNextQObj(dsmHandle,&qData);
1748       if (((rc == DSM_RC_OK) || (rc == DSM_RC_MORE_DATA)) && qData.numBytes)
1749       {
1750          BSAobjDescP->version = ObjectDescriptorVersion;
1751          strcpy(BSAobjDescP->Owner.bsaObjectOwner, xopenGbl.dsmSessInfo.id);
1752          BSAobjDescP->copyType = BSAqryDescP->copyType;
1753          strcpy(BSAobjDescP->cGName, "\0");   /* no copy group name returned */
1754
1755          if (BSAqryDescP->copyType == BSACopyType_ARCHIVE)
1756          {
1757             fillArchiveResp(dsmHandle, BSAobjDescP, &respArchive);
1758          }
1759          else /* backup */
1760          {
1761             fillBackupResp(dsmHandle, BSAobjDescP, &respBackup);
1762          }
1763          /*=== look ahead and see if there is more or if this is really done ===*/
1764          rc = AFSdsmGetNextQObj(dsmHandle,&qData);
1765          if (( (rc == DSM_RC_OK) || (rc == DSM_RC_MORE_DATA)) && qData.numBytes)
1766          { /*=== save the response we just got for later call ===*/
1767             if (BSAqryDescP->copyType == BSACopyType_ARCHIVE)
1768             {
1769                if (!(xopenGbl.nextQryP = (char *)dsMalloc(sizeof(qryRespArchiveData))))
1770                {
1771
1772                   sprintf(traceStr2, "BSAQueryObject: no memory for look ahead buffer");
1773                   ourTrace(BSAHandle,TrFL, traceStr2);
1774                   xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1775                   bsaRC = BSA_RC_NO_RESOURCES;
1776                   XOPENRETURN(BSAHandle, "BSAQueryObject(AFSdsmGetNextQObj)",
1777                               bsaRC,__FILE__,__LINE__);
1778                }
1779                memcpy(xopenGbl.nextQryP, &respArchive, sizeof(qryRespArchiveData));
1780             }
1781             else
1782             {
1783                if (!(xopenGbl.nextQryP = (char *)dsMalloc(sizeof(qryRespBackupData))))
1784                {
1785
1786                   sprintf(traceStr2, "BSAQueryObject: no memory for look ahead buffer");
1787                   ourTrace(BSAHandle,TrFL, traceStr2);
1788                   xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1789                   bsaRC = BSA_RC_NO_RESOURCES;
1790                   XOPENRETURN(BSAHandle, "BSAQueryObject(AFSdsmGetNextQObj)",
1791                               bsaRC,__FILE__,__LINE__);
1792
1793                }
1794                memcpy(xopenGbl.nextQryP, &respBackup, sizeof(qryRespBackupData));
1795             }
1796          }
1797       else
1798       {
1799
1800          sprintf(traceStr2, "BSAQueryObject(AFSdsmGetNextQObj) rc = %d", rc);
1801          ourTrace(BSAHandle,TrFL, traceStr2);
1802          AFSdsmEndQuery(dsmHandle);
1803          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1804       }
1805
1806    }
1807    else /* could be FINISHED or an error */
1808    {
1809
1810       sprintf(traceStr2, "BSAQueryObject(AFSdsmGetNextQObj) rc = %d", rc);
1811       ourTrace(BSAHandle,TrFL, traceStr2);
1812       AFSdsmEndQuery(dsmHandle);
1813       xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_BSA_QRY); /* set off */
1814    }
1815
1816    if (rc == DSM_RC_OK)
1817    {
1818       sprintf(traceStr2, "BSAQueryObject(AFSdsmGetNextQObj) rc = %d, ObjOwner(objDesc):'%s' appOwner(objDesc):'%s' \n ObjName(objDesc):'%.*s%.*s' \n copyType:%d copyId:'%lu %lu' cGName:'%s'",
1819        rc,
1820        BSAobjDescP->Owner.bsaObjectOwner,
1821        BSAobjDescP->Owner.appObjectOwner,
1822        100,BSAobjDescP->objName.objectSpaceName,
1823        100,BSAobjDescP->objName.pathName,
1824        BSAobjDescP->copyType,
1825        BSAobjDescP->copyId.left,
1826        BSAobjDescP->copyId.right,
1827        BSAobjDescP->cGName);
1828        ourTrace(BSAHandle,TrFL, traceStr2);
1829    }
1830
1831    xlateRC(BSAHandle, rc, &bsaRC);
1832    XOPENRETURN(BSAHandle, "BSAQueryObject",
1833                bsaRC, __FILE__,__LINE__);
1834 }
1835
1836 BSA_Int16 BSAGetObject(
1837     long              BSAHandle,
1838     ObjectDescriptor *BSAobjDescP,
1839     DataBlock        *BSAdataBlockP
1840 )
1841 {
1842    dsInt16_t      rc = 0;
1843    BSA_Int16      bsaRC = 0;
1844    dsUint32_t     dsmHandle;
1845    DataBlk        getBlk;
1846    dsmGetType     getType;
1847    dsmGetList     dsmObjList ;
1848    char           rcMsg[DSM_MAX_RC_MSG_LENGTH + 1];
1849    char           errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
1850    char           ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
1851
1852    if(!dsm_init)
1853    {
1854 #ifdef DEBUG_BUTC
1855         printf("TSM library not mounted. \n");
1856 #endif
1857         if (dsm_MountLibrary())
1858         {
1859                 printf("TSM Library initialisation failed. \n");
1860                 return 1 ;
1861         }
1862 #ifdef DEBUG_BUTC
1863         printf("TSM Library initialisation SUCCESS. \n");
1864 #endif
1865    }
1866
1867    dsmHandle = BSAHandle;
1868
1869    memset(rcMsg,         '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1870    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1871    memset(ourMessage,    '\0', DSM_MAX_RC_MSG_LENGTH + 1);
1872
1873    sprintf(traceStr2, "BSAGetObject ENTRY: BSAHandle:%ld version:%lu copyType:%d copyId:'%lu %lu' \n bufferLen:%d numBytes:%d ",
1874            BSAHandle,
1875            BSAobjDescP->version,
1876            BSAobjDescP->copyType,
1877            BSAobjDescP->copyId.left,
1878            BSAobjDescP->copyId.right,
1879            BSAdataBlockP->bufferLen,
1880            BSAdataBlockP->numBytes);
1881    ourTrace(BSAHandle, TrFL, traceStr2);
1882
1883    xopenGbl.oper = OPER_RECV_START;    /* save state for EndData later */
1884
1885    if (BSAobjDescP->version != ObjectDescriptorVersion)
1886    {
1887       sprintf(traceStr2,"Warning: BSAGetObject: objectDesc.version unexpected %lu.", BSAobjDescP->version);
1888       ourTrace(BSAHandle,TrFL, traceStr2);
1889       /*==================================================================
1890        don't treat this as an error now since it isn't defined in the spec
1891        bsaRC = ADSM_RC_INVALID_ST_VER;
1892        return(bsaRC);
1893        =================================================================*/
1894    }
1895
1896    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
1897    {
1898       sprintf(traceStr2, "BSAGetObject: issued without BSABeginTxn");
1899       ourTrace(BSAHandle,TrFL, traceStr2);
1900       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
1901       XOPENRETURN(BSAHandle, "BSAGetObject",
1902                   bsaRC,__FILE__,__LINE__);
1903    }
1904
1905    /*=== Get the data ===*/
1906    if (BSAobjDescP->copyType == BSACopyType_ARCHIVE)
1907       getType = gtArchive;
1908    else
1909       if (BSAobjDescP->copyType == BSACopyType_BACKUP)
1910          getType = gtBackup;
1911       else
1912       {
1913          sprintf(traceStr2,
1914                            "BSAGetObject: invalid copyType (%d)",
1915                             BSAobjDescP->copyType);
1916          ourTrace(BSAHandle,TrFL, traceStr2);
1917          bsaRC = ADSM_RC_INVALID_COPYTYPE;
1918          strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
1919          ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
1920          XOPENRETURN(BSAHandle, "BSAGetObject",
1921                      bsaRC,__FILE__,__LINE__);
1922       }
1923
1924    /*=== now update state since we'll issue a base API call ===*/
1925    xopenGbl.oper = OPER_RECV_ISSUED;    /* save state for EndData later */
1926    /*=== setup for a single object get ===*/
1927
1928    dsmObjList.stVersion = dsmGetListVersion ;
1929    dsmObjList.numObjId = 1 ;
1930    dsmObjList.objId = (ObjID *)dsMalloc(sizeof(ObjID) * dsmObjList.numObjId) ;
1931
1932    dsmObjList.objId[0].hi = BSAobjDescP->copyId.left ;
1933    dsmObjList.objId[0].lo = BSAobjDescP->copyId.right ;
1934
1935    if ((rc = AFSdsmBeginGetData(dsmHandle,bTrue,   /* always say MountWait */
1936                              getType,
1937                              &dsmObjList)) != DSM_RC_OK)
1938    {
1939       sprintf(traceStr2, "BSAGetObject: Call to AFSdsmBeginGetData error rc = %d", rc);
1940       ourTrace(BSAHandle,TrFL, traceStr2);
1941       xlateRC(BSAHandle, rc, &bsaRC);
1942       XOPENRETURN(BSAHandle, "BSAGetObject(AFSdsmBeginGetData)",
1943                   bsaRC,__FILE__,__LINE__);
1944    }
1945
1946    /*********************************************************************/
1947    getBlk.stVersion = DataBlkVersion ;
1948    getBlk.bufferPtr = BSAdataBlockP->bufferPtr ;
1949    getBlk.bufferLen = BSAdataBlockP->bufferLen;
1950    getBlk.numBytes  = 0;
1951
1952    rc = AFSdsmGetObj(dsmHandle, &(dsmObjList.objId[0]), &getBlk) ;
1953
1954    if ((rc == DSM_RC_FINISHED) &&
1955        (getBlk.numBytes != 0))    /* actually is data received */
1956       rc = DSM_RC_MORE_DATA;      /* use different rc for consistency */
1957                                   /* with Query. No data returned */
1958                                   /* if rc = FINISHED.     */
1959    if ((rc == DSM_RC_FINISHED) ||
1960        (rc == DSM_RC_MORE_DATA))
1961    {
1962       /*=== data is already in the buffer ===*/
1963       BSAdataBlockP->numBytes = (BSA_UInt16)getBlk.numBytes;
1964    }
1965    else
1966    {
1967       /*=== appl may call BSAEndData to clean up trxn but don't count on it... ===*/
1968       AFSdsmEndGetObj(dsmHandle);
1969       AFSdsmEndGetData(dsmHandle);
1970       xopenGbl.sessFlags =
1971                (xopenGbl.sessFlags | FL_END_DATA_DONE);  /* turn flag on */
1972     }
1973
1974    xlateRC(BSAHandle, rc, &bsaRC);
1975    XOPENRETURN(BSAHandle, "BSAGetObject",
1976                bsaRC,__FILE__,__LINE__);
1977 }
1978
1979 BSA_Int16 BSAGetData(
1980     long              BSAHandle,
1981     DataBlock        *BSAdataBlockP
1982 )
1983 {
1984    dsInt16_t      rc = 0;
1985    BSA_Int16      bsaRC = 0;
1986    dsUint32_t     dsmHandle;
1987    DataBlk        getBlk;
1988
1989    if(!dsm_init)
1990    {
1991 #ifdef DEBUG_BUTC
1992         printf("TSM library not mounted. \n");
1993 #endif
1994         if (dsm_MountLibrary())
1995         {
1996                 printf("TSM Library initialisation failed. \n");
1997                 return 1 ;
1998         }
1999 #ifdef DEBUG_BUTC
2000         printf("TSM Library initialisation SUCCESS. \n");
2001 #endif
2002    }
2003
2004    dsmHandle = BSAHandle;
2005
2006
2007    sprintf(traceStr2, "BSAGetData ENTRY: BSAHandle:%ld, bufferLen:%d, numBytes:%d",
2008            BSAHandle,
2009            BSAdataBlockP->bufferLen,
2010            BSAdataBlockP->numBytes);
2011    ourTrace(BSAHandle,TrFL, traceStr2);
2012
2013    getBlk.stVersion = DataBlkVersion ;
2014    getBlk.bufferPtr = BSAdataBlockP->bufferPtr ;
2015    getBlk.bufferLen = BSAdataBlockP->bufferLen;
2016    getBlk.numBytes  = 0;
2017
2018    rc = AFSdsmGetData(dsmHandle, &getBlk) ;
2019
2020    if ((rc == DSM_RC_FINISHED) &&
2021        (getBlk.numBytes != 0))      /* actually is data received */
2022       rc = DSM_RC_MORE_DATA;        /* use different rc for consistency */
2023                                     /* with Query. No data returned */
2024                                     /* if rc = FINISHED.     */
2025
2026    if ((rc == DSM_RC_FINISHED) ||
2027        (rc == DSM_RC_MORE_DATA))
2028    {
2029       /*=== data is already in the buffer ===*/
2030       BSAdataBlockP->numBytes = (BSA_UInt16)getBlk.numBytes;
2031    }
2032    else
2033    {
2034       sprintf(traceStr2, "BSAGetData: Call to AFSdsmGetData error rc = %d", rc);
2035       ourTrace(BSAHandle, TrFL,traceStr2);
2036
2037       /*=== appl may call BSAEndData to clean up trxn but don't count on it... ===*/
2038       AFSdsmEndGetObj(dsmHandle);
2039       AFSdsmEndGetData(dsmHandle);
2040       xopenGbl.sessFlags =
2041                (xopenGbl.sessFlags | FL_END_DATA_DONE);  /* turn flag on */
2042    }
2043    xlateRC(BSAHandle, rc, &bsaRC);
2044    XOPENRETURN(BSAHandle, "BSAGetData(AFSdsmGetData)",
2045                bsaRC,__FILE__,__LINE__);
2046 }
2047
2048 BSA_Int16 BSASendData(
2049     long           BSAHandle,
2050     DataBlock     *BSAdataBlockP
2051 )
2052 {
2053    dsInt16_t      rc = 0;
2054    BSA_Int16      bsaRC = 0;
2055    dsUint32_t     dsmHandle;
2056    DataBlk        dataBlkArea;
2057
2058    if(!dsm_init)
2059    {
2060 #ifdef DEBUG_BUTC
2061         printf("TSM library not mounted. \n");
2062 #endif
2063         if (dsm_MountLibrary())
2064         {
2065                 printf("TSM Library initialisation failed. \n");
2066                 return 1 ;
2067         }
2068 #ifdef DEBUG_BUTC
2069         printf("TSM Library initialisation SUCCESS. \n");
2070 #endif
2071    }
2072
2073    dsmHandle = BSAHandle;
2074
2075
2076    sprintf(traceStr2, "BSASendData ENTRY: BSAHandle:%ld bufferLen: %d numBytes: %d ",
2077            BSAHandle,
2078            BSAdataBlockP->bufferLen,
2079            BSAdataBlockP->numBytes);
2080    ourTrace(BSAHandle, TrFL, traceStr2);
2081
2082    /*=== check for NULL dataBlock pointer ===*/
2083    if (BSAdataBlockP == NULL)
2084       XOPENRETURN(BSAHandle, "BSASendData",
2085                   BSA_RC_NULL_POINTER,__FILE__,__LINE__);
2086       dataBlkArea.stVersion = DataBlkVersion ;
2087       dataBlkArea.bufferPtr = BSAdataBlockP->bufferPtr ;
2088       dataBlkArea.bufferLen = BSAdataBlockP->bufferLen;
2089
2090       rc = AFSdsmSendData(dsmHandle, &dataBlkArea);
2091
2092       if (rc)
2093       {
2094
2095          sprintf(traceStr2, "BSASendData(AFSdsmSendData) error rc = %d", rc);
2096          ourTrace(BSAHandle,TrFL, traceStr2);
2097
2098          if (rc == DSM_RC_WILL_ABORT)  /* save flag */
2099             xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_RC_WILL_ABORT);
2100       }
2101       BSAdataBlockP->numBytes = (BSA_UInt16)dataBlkArea.numBytes;
2102       sprintf(traceStr2, "BSASendData(AFSdsmSendData): BSAHandle:%ld bufferLen: %d numBytes sent: %d ",
2103            BSAHandle,
2104            BSAdataBlockP->bufferLen,
2105            BSAdataBlockP->numBytes);
2106       ourTrace(BSAHandle, TrFL, traceStr2);
2107
2108       xlateRC(BSAHandle, rc, &bsaRC);
2109       XOPENRETURN(BSAHandle, "BSASendData",
2110                   BSA_RC_SUCCESS,__FILE__,__LINE__);
2111 }
2112
2113 BSA_Int16 BSAEndData(
2114     long          BSAHandle
2115 )
2116 {
2117    dsInt16_t      rc = 0;
2118    BSA_Int16      bsaRC = 0;
2119    dsUint32_t     dsmHandle;
2120
2121    if(!dsm_init)
2122    {
2123 #ifdef DEBUG_BUTC
2124         printf("TSM library not mounted. \n");
2125 #endif
2126         if (dsm_MountLibrary())
2127         {
2128                 printf("TSM Library initialisation failed. \n");
2129                 return 1 ;
2130         }
2131 #ifdef DEBUG_BUTC
2132         printf("TSM Library initialisation SUCCESS. \n");
2133 #endif
2134    }
2135
2136    dsmHandle = BSAHandle;
2137
2138
2139    sprintf(traceStr2, "BSAEndData ENTRY: BSAHandle:%ld", BSAHandle);
2140    ourTrace(BSAHandle,TrFL, traceStr2);
2141
2142    /*=======================================================
2143      check the state - don't issue base API call unless one
2144      was called previously, or else we get a sequence error.
2145      ======================================================*/
2146
2147    if (xopenGbl.oper == OPER_SEND_ISSUED)
2148    {
2149       rc = AFSdsmEndSendObj(dsmHandle);
2150       if (rc)
2151       {
2152
2153          sprintf(traceStr2, "BSAEndData(AFSdsmEndSendObj) error rc = %d", rc);
2154          ourTrace(BSAHandle,TrFL, traceStr2);
2155          xlateRC(BSAHandle, rc, &bsaRC);
2156       }
2157    }
2158    else
2159       if (xopenGbl.oper == OPER_RECV_ISSUED)
2160       {
2161           if (xopenGbl.sessFlags & FL_END_DATA_DONE)   /* EndData processing */
2162              xopenGbl.sessFlags =                     /*  already done */
2163                    (xopenGbl.sessFlags ^ FL_END_DATA_DONE);  /* turn flag off */
2164          else
2165          {
2166             rc = AFSdsmEndGetObj(dsmHandle);
2167             if (rc)
2168             {
2169                sprintf(traceStr2, "BSAEndData(AFSdsmEndGetObj) error rc = %d", rc);
2170                ourTrace(BSAHandle, TrFL, traceStr2);
2171
2172                /*==============================================================
2173                 this may get 'Out of sequence error' if previous GetObject
2174                 had rc=2 (no match). Don't return this to caller - too confusing
2175                 ===============================================================*/
2176                if (rc != DSM_RC_BAD_CALL_SEQUENCE)
2177                xlateRC(BSAHandle, rc, &bsaRC);
2178             }
2179
2180             rc = AFSdsmEndGetData(dsmHandle);
2181             if (rc)
2182             {
2183                sprintf(traceStr2, "BSAEndData(AFSdsmEndGetData) error rc = %d", rc);
2184                ourTrace(BSAHandle, TrFL, traceStr2);
2185                xlateRC(BSAHandle, rc, &bsaRC);
2186             }
2187          }
2188       }
2189    else  /* invalid state */
2190       if ((xopenGbl.oper != OPER_RECV_START) &&
2191           (xopenGbl.oper != OPER_SEND_START))
2192       {
2193          sprintf(traceStr2, "BSAEndData: BSAEndData but not Send or Recv");
2194          ourTrace(BSAHandle,TrFL, traceStr2);
2195          bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2196       }
2197
2198    xopenGbl.oper = OPER_NONE;
2199    XOPENRETURN(BSAHandle, "BSAEndData",bsaRC,__FILE__,__LINE__);
2200 }
2201
2202 BSA_Int16 BSACreateObject(
2203     long              BSAHandle,
2204     ObjectDescriptor *BSAobjDescP,
2205     DataBlock        *BSAdataBlockP
2206 )
2207 {
2208    dsInt16_t          rc = 0;
2209    BSA_Int16          bsaRC = 0;
2210    dsUint32_t         dsmHandle;
2211    regFSData          regFilespace ;
2212    dsmObjName         objName ;
2213    ObjAttr            objAttrArea;
2214    sndArchiveData     archData;
2215    DataBlk            dataBlkArea;
2216    dsmSendType        sendType;
2217    dsUint8_t          dsmObjType;
2218    XAPIObjInfo        xapiObjInfo;
2219    mcBindKey          mcBindKey;
2220    BSAObjectOwner     upperNode;  /* upper cased node name */
2221    char               errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
2222    char               ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
2223
2224    if(!dsm_init)
2225    {
2226 #ifdef DEBUG_BUTC
2227         printf("TSM library not mounted. \n");
2228 #endif
2229         if (dsm_MountLibrary())
2230         {
2231                 printf("TSM Library initialisation failed. \n");
2232                 return 1 ;
2233         }
2234 #ifdef DEBUG_BUTC
2235         printf("TSM Library initialisation SUCCESS. \n");
2236 #endif
2237    }
2238
2239    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2240    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2241
2242    dsmHandle = BSAHandle;
2243
2244    if (BSAobjDescP != NULL && BSAdataBlockP != NULL)
2245    {
2246    sprintf(traceStr2, "BSACreateObject ENTRY: BSAHandle:%ld ObjOwner:'%s' appOwner:'%s' \n ObjName:'%.*s%.*s' \n objType:%d  size:'%lu %lu' resourceType:'%s'  \n bufferLen:%d numBytes:%d ",
2247
2248            BSAHandle,
2249            BSAobjDescP->Owner.bsaObjectOwner[0] != '\0' ? BSAobjDescP->Owner.bsaObjectOwner : "",
2250            BSAobjDescP->Owner.appObjectOwner[0] != '\0' ?  BSAobjDescP->Owner.appObjectOwner : "",
2251            100,BSAobjDescP->objName.objectSpaceName[0] != '\0' ? BSAobjDescP->objName.objectSpaceName
2252            : "",
2253            100,BSAobjDescP->objName.pathName[0] != '\0' ? BSAobjDescP->objName.pathName : "",
2254            BSAobjDescP->objectType,
2255            BSAobjDescP->size.left,
2256            BSAobjDescP->size.right,
2257            BSAobjDescP->resourceType[0] != '\0' ?  BSAobjDescP->resourceType : "" ,
2258            BSAdataBlockP->bufferLen,
2259            BSAdataBlockP->numBytes);
2260   }
2261   else
2262   {
2263     if (BSAobjDescP == NULL)
2264       {
2265          bsaRC = BSA_RC_NULL_POINTER;
2266          XOPENRETURN(BSAHandle, "BSACreateObject",
2267                   bsaRC,__FILE__,__LINE__);
2268       }
2269     sprintf(traceStr2, "BSACreateObject ENTRY: BSAHandle:%ld", BSAHandle);
2270   }
2271
2272   ourTrace(BSAHandle, TrFL, traceStr2);
2273
2274    xopenGbl.oper = OPER_SEND_START;    /* save state for EndData later */
2275    /*=================================================================
2276    if (BSAobjDescP->version != ObjectDescriptorVersion)
2277        BSA spec doesn't require this currently..
2278    =================================================================*/
2279
2280    /*===============================================================
2281     if the node name is different - we won't create it compare both
2282     the value passed on the BSAInit and the final value used for the
2283     session (which may be different for Generate)
2284     ===============================================================*/
2285    strcpy(upperNode, BSAobjDescP->Owner.bsaObjectOwner);
2286    StrUpper(upperNode);
2287    if ((strcmp(upperNode, xopenGbl.dsmSessInfo.id)) &&
2288       (strcmp(BSAobjDescP->Owner.bsaObjectOwner, xopenGbl.bsaObjectOwner)))
2289    {
2290       sprintf(traceStr2,
2291              "BSACreateObject: BSAObjectOwner(%s) doesn't match value for session(%s).",
2292               upperNode, xopenGbl.dsmSessInfo.id);
2293       ourTrace(BSAHandle,TrFL, traceStr2);
2294       bsaRC = ADSM_RC_INVALID_NODE;
2295       strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2296       ourLogEvent_Ex(BSAHandle,logLocal, ourMessage, errPrefix, logSevError);
2297       XOPENRETURN(BSAHandle, "BSACreateObject",
2298                   bsaRC,__FILE__,__LINE__);
2299    }
2300
2301    /*=== check string lengths - if this too long, it won't fit in our objInfo ===*/
2302    if (strlen(BSAobjDescP->desc) > ADSM_MAX_DESC)
2303    {
2304       sprintf(traceStr2,"BSACreateObject: description longer than TSM max (%" AFS_SIZET_FMT "). ",
2305               strlen(BSAobjDescP->desc));
2306       ourTrace(BSAHandle, TrFL, traceStr2);
2307       bsaRC = BSA_RC_DESC_TOO_LONG;
2308       XOPENRETURN(BSAHandle, "BSACreateObject",
2309                   bsaRC,__FILE__,__LINE__);
2310    }
2311    if (strlen(BSAobjDescP->objectInfo) > ADSM_MAX_OBJINFO)
2312    {
2313       sprintf(traceStr2,"BSACreateObject: objInfo longer than TSM max (%" AFS_SIZET_FMT ").",
2314       strlen(BSAobjDescP->objectInfo));
2315       ourTrace(BSAHandle,TrFL, traceStr2);
2316       bsaRC = BSA_RC_OBJINFO_TOO_LONG;
2317       XOPENRETURN(BSAHandle, "BSACreateObject",
2318                   bsaRC,__FILE__,__LINE__);
2319    }
2320
2321    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
2322    {
2323       sprintf(traceStr2, "BSACreateObject issued without BSABeginTxn");
2324       ourTrace(BSAHandle,TrFL, traceStr2);
2325       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2326       XOPENRETURN(BSAHandle, "BSACreateObject",
2327                   bsaRC,__FILE__,__LINE__);
2328    }
2329
2330    if (strlen(BSAobjDescP->objName.objectSpaceName) > BSA_MAX_OSNAME)
2331    {
2332       sprintf(traceStr2, "BSACreateObject: objectSpaceName too long (%" AFS_SIZET_FMT ")",
2333                        strlen(BSAobjDescP->objName.objectSpaceName));
2334       ourTrace(BSAHandle, TrFL, traceStr2);
2335       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2336       XOPENRETURN(BSAHandle, "BSACreateObject:",
2337                   bsaRC,__FILE__,__LINE__);
2338    }
2339
2340    if (!(xopenGbl.sessFlags & FL_IN_DSM_TXN))        /* first CreateObj */
2341    { /* can't issue RegisterFS if already in Txn */
2342       /*=== Register the file space ===*/
2343       regFilespace.stVersion = regFSDataVersion ;
2344       regFilespace.fsName = BSAobjDescP->objName.objectSpaceName ;
2345
2346       /*===  use resource type for fsType (as it was intended)  ===*/
2347
2348       regFilespace.fsType = BSAobjDescP->resourceType ;
2349       regFilespace.capacity.lo = 0;
2350       regFilespace.capacity.hi = 0;
2351       regFilespace.occupancy.lo = 0;
2352       regFilespace.occupancy.hi = 0;
2353       #if _OPSYS_TYPE == DS_AIX
2354          regFilespace.fsAttr.unixFSAttr.fsInfoLength = strlen(XAPI_FSINFO) ;
2355          strcpy(regFilespace.fsAttr.unixFSAttr.fsInfo, XAPI_FSINFO);
2356       #else
2357          regFilespace.fsAttr.dosFSAttr.fsInfoLength = strlen(XAPI_FSINFO) ;
2358          strcpy(regFilespace.fsAttr.dosFSAttr.fsInfo, XAPI_FSINFO);
2359          regFilespace.fsAttr.dosFSAttr.driveLetter = 'X';
2360       #endif
2361       rc = AFSdsmRegisterFS(dsmHandle, &regFilespace) ;
2362       if ((rc != 0) && (rc != DSM_RC_FS_ALREADY_REGED))
2363       {
2364          sprintf(traceStr2, "BSACreateObject(AFSdsmRegisterFS) error rc = %d",rc);
2365          ourTrace(BSAHandle,TrFL, traceStr2);
2366
2367          xlateRC(BSAHandle, rc, &bsaRC);
2368          XOPENRETURN(BSAHandle, "BSACreateObject(AFSdsmRegisterFS)",
2369                      bsaRC,__FILE__,__LINE__);
2370       }
2371    }
2372
2373    /*========================================================
2374     Check for invalid copyType before sending data. Log error
2375     to dsirror.log file.
2376     ========================================================*/
2377     if (BSAobjDescP->copyType == BSACopyType_ARCHIVE)
2378        sendType = stArchiveMountWait;
2379     else
2380        if (BSAobjDescP->copyType == BSACopyType_BACKUP)
2381           sendType = stBackupMountWait;
2382        else
2383        {
2384            sprintf(traceStr2,
2385                   "BSACreateObject: invalid copyType (%d)",
2386                    BSAobjDescP->copyType);
2387            ourTrace(BSAHandle,TrFL, traceStr2);
2388            bsaRC = ADSM_RC_INVALID_COPYTYPE;
2389            strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2390            ourLogEvent_Ex(BSAHandle,logLocal, ourMessage, errPrefix, logSevError);
2391            XOPENRETURN(BSAHandle, "BSACreateObject",
2392                        bsaRC,__FILE__,__LINE__);
2393        }
2394
2395    if ((BSAobjDescP->objectType == BSAObjectType_FILE) ||
2396       (BSAobjDescP->objectType == BSAObjectType_DATABASE) ||
2397       (BSAobjDescP->objectType == BSAObjectType_ANY))
2398
2399          dsmObjType = DSM_OBJ_FILE;
2400    else
2401       if (BSAobjDescP->objectType == BSAObjectType_DIRECTORY)
2402          dsmObjType = DSM_OBJ_DIRECTORY;
2403       else
2404       {
2405          sprintf(traceStr2,
2406                "BSACreateObject: invalid objectType (%d)",
2407                 BSAobjDescP->objectType);
2408          ourTrace(BSAHandle,TrFL, traceStr2);
2409          bsaRC = ADSM_RC_INVALID_OBJTYPE;
2410          strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2411          ourLogEvent_Ex(BSAHandle,logLocal, ourMessage, errPrefix, logSevError);
2412          XOPENRETURN(BSAHandle, "BSACreateObject",
2413                     bsaRC,__FILE__,__LINE__);
2414       }
2415
2416    /*==================================================================
2417     put in a check here - count the number of objects per txn
2418     and compare with xopenGbl.sessInfo.maxObjPerTxn
2419     If reach the limit, EndTxn and start a new one
2420     OK to do this without telling the BSA caller?
2421     Or should we exit with an error to tell them the limit is reached ?
2422     ==================================================================*/
2423
2424     if (!(xopenGbl.sessFlags & FL_IN_DSM_TXN))
2425     {
2426       rc = AFSdsmBeginTxn(dsmHandle);
2427
2428       if (rc)
2429       {
2430          sprintf(traceStr2, "BSACreateObject(AFSdsmBeginTxn) error rc = %d", rc);
2431          ourTrace(BSAHandle,TrFL, traceStr2);
2432          xlateRC(BSAHandle, rc, &bsaRC);
2433          XOPENRETURN(BSAHandle, "BSACreateObject(AFSdsmBeginTxn)",
2434                      bsaRC,__FILE__,__LINE__);
2435       }
2436       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_DSM_TXN); /* set on */
2437     }
2438
2439     /*=== Backup the data  ===*/
2440
2441    /*================================================================
2442      the entire pathname gets copied into hl during parsing, so
2443      check for that max len as well. For now these are the same value.
2444      =================================================================*/
2445    if (strlen(BSAobjDescP->objName.pathName) >
2446             min(DSM_MAX_HL_LENGTH, BSA_MAX_PATHNAME))
2447    {
2448       sprintf(traceStr2, "BSACreateObject: pathName too long (%" AFS_SIZET_FMT ")",
2449               strlen(BSAobjDescP->objName.pathName));
2450       ourTrace(BSAHandle,TrFL, traceStr2);
2451       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2452       XOPENRETURN(BSAHandle, "BSACreateObject",
2453                   bsaRC,__FILE__,__LINE__);
2454    }
2455
2456    strcpy(objName.fs,BSAobjDescP->objName.objectSpaceName) ;
2457    /*=== previous code to use only ll field ===*/
2458    /*objName.hl[0] = '\0';
2459      strcpy(objName.ll,BSAobjDescP->objName.pathName) ;
2460    */
2461    xparsePath(BSAHandle, BSAobjDescP->objName.pathName, objName.hl, objName.ll);
2462    objName.objType = dsmObjType ;
2463
2464    objAttrArea.stVersion = ObjAttrVersion ;
2465    strcpy(objAttrArea.owner,BSAobjDescP->Owner.appObjectOwner);
2466    objAttrArea.sizeEstimate.hi = BSAobjDescP->size.left;
2467    objAttrArea.sizeEstimate.lo = BSAobjDescP->size.right;
2468    objAttrArea.objCompressed = bFalse ;  /* let COMPRESSION option decide */
2469    /*=== whether there's actually compression ===*/
2470    objAttrArea.objInfoLength = sizeof(XAPIObjInfo);
2471    objAttrArea.objInfo = (char *)&xapiObjInfo ;
2472
2473    memset(&xapiObjInfo,0x00,sizeof(XAPIObjInfo));
2474    strcpy(xapiObjInfo.resourceType, BSAobjDescP->resourceType);
2475    xapiObjInfo.size.left = BSAobjDescP->size.left;
2476    xapiObjInfo.size.right = BSAobjDescP->size.right;
2477    strcpy(xapiObjInfo.partDesc, BSAobjDescP->desc);
2478    strcpy(xapiObjInfo.partObjInfo, BSAobjDescP->objectInfo);
2479
2480    /*=== check if a lifecycle group name was passed to us ===*/
2481    if (strlen(BSAobjDescP->lGName))
2482       objAttrArea.mcNameP = (char *)BSAobjDescP->lGName ;
2483    else
2484       objAttrArea.mcNameP = NULL;
2485
2486       dataBlkArea.stVersion = DataBlkVersion ;
2487       if (BSAdataBlockP == NULL)
2488       {
2489          dataBlkArea.bufferPtr = NULL;
2490          dataBlkArea.bufferLen = 0;
2491       }
2492       else
2493       {
2494          dataBlkArea.bufferPtr = BSAdataBlockP->bufferPtr ;
2495          dataBlkArea.bufferLen = BSAdataBlockP->bufferLen;
2496       }
2497
2498       /*=======================================================
2499        always issue BindMC because we don't expect applications
2500        to call ResolveLifecycleGroup since it isn't in the
2501        Data Movement subset
2502        =======================================================*/
2503        mcBindKey.stVersion = mcBindKeyVersion ;
2504        rc = AFSdsmBindMC(dsmHandle, &objName, sendType, &mcBindKey);
2505        if (rc)
2506        {
2507           sprintf(traceStr2, "BSACreateObject(AFSdsmBindMC): error rc = %d", rc);
2508           ourTrace(BSAHandle, TrFL, traceStr2);
2509           xlateRC(BSAHandle, rc, &bsaRC);
2510           XOPENRETURN(BSAHandle, "BSACreateObject(dsnBindMC)",
2511                       bsaRC,__FILE__,__LINE__);
2512        }
2513
2514        /*=== now update state since we'll issue the base Send call ===*/
2515
2516        xopenGbl.oper = OPER_SEND_ISSUED;    /* save state for EndData later */
2517
2518        switch (sendType)
2519        {
2520           case (stBackupMountWait) :
2521           rc = AFSdsmSendObj(dsmHandle,
2522                           sendType,
2523                           NULL,
2524                           &objName,
2525                           &objAttrArea,
2526                           &dataBlkArea);
2527           break;
2528
2529           case (stArchiveMountWait) :
2530           archData.stVersion = sndArchiveDataVersion;
2531           archData.descr = (char *)(BSAobjDescP->desc);
2532           rc = AFSdsmSendObj(dsmHandle,
2533                           sendType,
2534                           &archData,
2535                           &objName,
2536                           &objAttrArea,
2537                           &dataBlkArea);
2538           break;
2539           default : ;
2540        }
2541
2542        if (rc != DSM_RC_OK)
2543        {
2544           sprintf(traceStr2, "BSACreateObject(AFSdsmSendObj) error rc = %d", rc);
2545           ourTrace(BSAHandle,TrFL, traceStr2);
2546
2547           if (rc == DSM_RC_WILL_ABORT)  /* save flag */
2548              xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_RC_WILL_ABORT);
2549
2550           xlateRC(BSAHandle, rc, &bsaRC);
2551           XOPENRETURN(BSAHandle, "BSACreateObject(AFSdsmSendObj)",
2552                       bsaRC,__FILE__,__LINE__);
2553        }
2554    XOPENRETURN(BSAHandle, "BSACreateObject",
2555                BSA_RC_SUCCESS, __FILE__,__LINE__);
2556 }
2557
2558
2559 BSA_Int16 BSADeleteObject(
2560     long           BSAHandle,
2561     CopyType       copyType,
2562     ObjectName     *BSAobjNameP,
2563     CopyId         *copyidP
2564 )
2565 {
2566    dsInt16_t      rc = 0;
2567    BSA_Int16      bsaRC = 0;
2568    dsUint32_t     dsmHandle;
2569    dsUint16_t     reason ;                   /* for AFSdsmEndTxn */
2570    dsmObjName     dsmobjName;
2571
2572    dsmDelType delType;
2573    dsmDelInfo delInfo;
2574
2575    delList *llHeadP = NULL;
2576    delList *llTailP = NULL;
2577    delList *ll = NULL;
2578
2579    char errPrefix[DSM_MAX_RC_MSG_LENGTH + 1];
2580    char ourMessage[DSM_MAX_RC_MSG_LENGTH + 1];
2581
2582    if(!dsm_init)
2583    {
2584 #ifdef DEBUG_BUTC
2585         printf("TSM library not mounted. \n");
2586 #endif
2587         if (dsm_MountLibrary())
2588         {
2589                 printf("TSM Library initialisation failed. \n");
2590                 return 1 ;
2591         }
2592 #ifdef DEBUG_BUTC
2593         printf("TSM Library initialisation SUCCESS. \n");
2594 #endif
2595    }
2596
2597    memset(errPrefix,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2598    memset(ourMessage,     '\0', DSM_MAX_RC_MSG_LENGTH + 1);
2599
2600    dsmHandle = BSAHandle;
2601
2602    sprintf(traceStr2, "BSADeleteObject ENTRY: BSAHandle:%ld CopyType:%d \n ObjName:'%.*s%.*s' copyidP:'%lu %lu'.",
2603            BSAHandle,
2604            copyType,
2605            100,BSAobjNameP->objectSpaceName,
2606            100,BSAobjNameP->pathName,
2607            copyidP->left,
2608            copyidP->right);
2609    ourTrace(BSAHandle, TrFL, traceStr2);
2610    if (copyType != BSACopyType_ARCHIVE)
2611    {
2612       sprintf(traceStr2,
2613               "BSADeleteObject: invalid copyType %d",
2614                copyType);
2615       ourTrace(BSAHandle,TrFL, traceStr2);
2616       bsaRC = ADSM_RC_INVALID_COPYTYPE;
2617       strcpy(ourMessage, ourRCMsg(bsaRC, errPrefix));
2618       ourLogEvent_Ex(BSAHandle, logLocal, ourMessage, errPrefix, logSevError);
2619       XOPENRETURN(BSAHandle, "BSADeleteObject",
2620                   bsaRC,__FILE__,__LINE__);
2621    }
2622
2623    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
2624    {
2625       sprintf(traceStr2, "BSADeleteObject issued without BSABeginTxn");
2626       ourTrace(BSAHandle, TrFL, traceStr2);
2627
2628       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2629       XOPENRETURN(BSAHandle, "BSADeleteObject:",
2630                   bsaRC,__FILE__,__LINE__);
2631    }
2632
2633    strcpy(dsmobjName.fs, BSAobjNameP->objectSpaceName);
2634    xparsePath(BSAHandle, BSAobjNameP->pathName, dsmobjName.hl, dsmobjName.ll);
2635    dsmobjName.objType = DSM_OBJ_FILE;
2636
2637    if (!copyidP)    /* NULL, so query and delete all with same name */
2638    {
2639       if (xopenGbl.sessFlags & FL_IN_DSM_TXN)
2640       /*=== if a trxn had been started, end it before doing Query ===*/
2641       {
2642          rc = AFSdsmEndTxn(dsmHandle, DSM_VOTE_COMMIT, &reason);
2643          xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_DSM_TXN); /* set off */
2644       }
2645       rc = buildList(dsmHandle, &dsmobjName, &llHeadP, &llTailP);
2646       if (rc)
2647       {
2648          bsaRC = BSA_RC_OBJECT_NOT_FOUND;
2649          XOPENRETURN(BSAHandle, "BSADeleteObject(buildList)",
2650                      bsaRC,__FILE__,__LINE__);
2651       }
2652    }
2653
2654    if (!(xopenGbl.sessFlags & FL_IN_DSM_TXN))        /* first call */
2655    {
2656       rc = AFSdsmBeginTxn(dsmHandle);
2657       if (rc)
2658       {
2659          xlateRC(BSAHandle, rc, &bsaRC);
2660          XOPENRETURN(dsmHandle,"BSADeleteObject(AFSdsmBeginTxn)",
2661                      bsaRC,__FILE__,__LINE__);
2662       }
2663       xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_DSM_TXN); /* set on */
2664    }
2665
2666    delType = dtArchive;
2667    delInfo.archInfo.stVersion = delArchVersion;
2668
2669    if (copyidP)   /* single ID to delete */
2670    {
2671       delInfo.archInfo.objId.hi  = copyidP->left;
2672       delInfo.archInfo.objId.lo  = copyidP->right;
2673
2674       if ((rc = AFSdsmDeleteObj(dsmHandle,delType,delInfo)) != DSM_RC_OK)
2675       {
2676          sprintf(traceStr2, "BSADeleteObject: AFSdsmDeleteObj error rc = %d", rc);
2677          ourTrace(dsmHandle,TrFL, traceStr2);
2678       }
2679    }
2680    else   /* multiple IDs to delete */
2681    {
2682       ll = llHeadP;
2683       while (ll)
2684       {
2685          delInfo.archInfo.objId.hi  = ll->objId.hi;
2686          delInfo.archInfo.objId.lo  = ll->objId.lo;
2687          if ((rc = AFSdsmDeleteObj(dsmHandle, delType, delInfo)) != DSM_RC_OK)
2688          {
2689             sprintf(traceStr2, "BSADeleteObject: AFSdsmDeleteObj error rc = %d", rc);
2690             ourTrace(dsmHandle, TrFL, traceStr2);
2691             /*=== break and get out of loop, or keep going? ===*/
2692          }
2693          /*=== incr to next list entry ===*/
2694          ll = ll->next;
2695       }
2696       /*=== free list now that done ===*/
2697       rc =  freeList(&llHeadP, &llTailP);
2698    }
2699
2700    xlateRC(BSAHandle, rc, &bsaRC);
2701    XOPENRETURN(BSAHandle,"BSADeleteObject",
2702                bsaRC,__FILE__,__LINE__)
2703 }
2704
2705 BSA_Int16 BSAMarkObjectInactive(
2706     long            BSAHandle,
2707     ObjectName     *BSAobjNameP
2708 )
2709 {
2710    dsInt16_t      rc = 0;
2711    BSA_Int16      bsaRC = 0;
2712    dsUint32_t     dsmHandle;
2713
2714    dsmObjName           dsmobjName;
2715
2716    qryBackupData        queryBuffer;       /* for query Backup */
2717    qryRespBackupData    qbDataArea;
2718    DataBlk              qDataBlkArea;
2719
2720    dsmDelType           delType;
2721    dsmDelInfo           delInfo;
2722
2723    dsUint16_t           reason ;                   /* for AFSdsmEndTxn */
2724    /*=== build list of all objTypes we find for this name ===*/
2725    dsInt16_t            i;
2726    dsInt16_t            numTypes;
2727    dsUint8_t            listObjType[5];    /* only 2 objTypes defined today */
2728    dsUint32_t           listCopyGroup[5];
2729
2730    if(!dsm_init)
2731    {
2732 #ifdef DEBUG_BUTC
2733         printf("TSM library not mounted. \n");
2734 #endif
2735         if (dsm_MountLibrary())
2736         {
2737                 printf("TSM Library initialisation failed. \n");
2738                 return 1 ;
2739         }
2740 #ifdef DEBUG_BUTC
2741         printf("TSM Library initialisation SUCCESS. \n");
2742 #endif
2743    }
2744
2745    dsmHandle = BSAHandle;
2746    memset(&delInfo, 0x00, sizeof(dsmDelInfo));
2747    memset(&queryBuffer, 0x00, sizeof(qryBackupData));
2748
2749    sprintf(traceStr2, "BSAMarkObjectInactive ENTRY: BSAHandle:%ld \n ObjName:'%.*s%.*s'.",
2750            BSAHandle,
2751            100, BSAobjNameP->objectSpaceName,
2752            100, BSAobjNameP->pathName);
2753    ourTrace(dsmHandle, TrFL, traceStr2);
2754
2755    if (!(xopenGbl.sessFlags & FL_IN_BSA_TXN))
2756    {
2757       sprintf(traceStr2, "BSAMarkObjectInactive: issued without BSABeginTxn.");
2758       ourTrace(BSAHandle, TrFL, traceStr2);
2759       bsaRC = BSA_RC_BAD_CALL_SEQUENCE;
2760       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2761                   bsaRC,__FILE__,__LINE__);
2762    }
2763
2764    if (strlen(BSAobjNameP->objectSpaceName) > DSM_MAX_FSNAME_LENGTH)
2765    {
2766       sprintf(traceStr2, "BSAMarkObjectInactive: objectSpaceName too long (%" AFS_SIZET_FMT ")", strlen(BSAobjNameP->objectSpaceName));
2767       ourTrace(BSAHandle,TrFL, traceStr2);
2768
2769       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2770       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2771                   bsaRC,__FILE__,__LINE__);
2772    }
2773    /*===============================================================
2774     The entire pathname gets copied into hl during parsing, so
2775     check for that max len as well. For now these are the same value.
2776     =============================================================== */
2777    if (strlen(BSAobjNameP->pathName) >
2778        min(DSM_MAX_HL_LENGTH, BSA_MAX_PATHNAME))
2779    {
2780       sprintf(traceStr2, "BSAMarkObjectInactive: pathName too long (%" AFS_SIZET_FMT ")",
2781                          strlen(BSAobjNameP->pathName));
2782       ourTrace(BSAHandle,TrFL, traceStr2);
2783       bsaRC = BSA_RC_OBJNAME_TOO_LONG;
2784       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2785                   bsaRC,__FILE__,__LINE__);
2786    }
2787
2788    /*==============================================================
2789     we don't allow any wildcard in name because that could retrieve
2790     LOTS of objects and make list processing more complicated.
2791     XBSA spec implies a single object.
2792     ==============================================================*/
2793    if ( strchr(BSAobjNameP->objectSpaceName, '*') ||
2794         strchr(BSAobjNameP->objectSpaceName, '?') ||
2795         strchr(BSAobjNameP->pathName,        '*') ||
2796         strchr(BSAobjNameP->pathName,        '?'))
2797    {
2798
2799       sprintf(traceStr2, "BSAMarkObjectInactive: objName contains a wildcard.")
2800 ;
2801       ourTrace(BSAHandle, TrFL, traceStr2);
2802       /*=== could have a more specific rc, use this for now ===*/
2803       bsaRC = BSA_RC_ABORT_ACTIVE_NOT_FOUND;
2804       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive",
2805                   bsaRC,__FILE__,__LINE__);
2806    }
2807
2808    strcpy(dsmobjName.fs, BSAobjNameP->objectSpaceName);
2809    xparsePath(BSAHandle, BSAobjNameP->pathName, dsmobjName.hl, dsmobjName.ll);
2810    dsmobjName.objType = DSM_OBJ_ANY_TYPE;
2811
2812    /*============================================================
2813     A Backup Delete must include the copy Group and objType this
2814     wasn't passed in, so we have to do a query.
2815     ============================================================*/
2816
2817    queryBuffer.stVersion = qryBackupDataVersion ;
2818    queryBuffer.objName = &dsmobjName;
2819    queryBuffer.owner   = xopenGbl.dsmSessInfo.owner;
2820    queryBuffer.objState = DSM_ACTIVE;              /* only get active one */
2821
2822    if ((rc=AFSdsmBeginQuery(dsmHandle, qtBackup,
2823                         (void *)&queryBuffer )) != DSM_RC_OK)
2824    {
2825       sprintf(traceStr2, "BSAMarkObjectInactive: Call to AFSdsmBeginQuery for Backup error rc = %d", rc);
2826       ourTrace(BSAHandle,TrFL, traceStr2);
2827       xlateRC(BSAHandle, rc, &bsaRC);
2828       if ((rc == DSM_RC_ABORT_NO_MATCH) ||    /* special rc for MarkInact */
2829           (rc == DSM_RC_FILE_SPACE_NOT_FOUND))
2830          bsaRC = BSA_RC_ABORT_ACTIVE_NOT_FOUND;
2831
2832       rc = AFSdsmEndQuery(dsmHandle);
2833       XOPENRETURN(BSAHandle, "BSAMarkObjectInactive: AFSdsmBeginQuery",
2834                   bsaRC,__FILE__,__LINE__);
2835    }
2836
2837    qbDataArea.stVersion   = qryRespBackupDataVersion;
2838    qDataBlkArea.stVersion = DataBlkVersion ;
2839    qDataBlkArea.bufferPtr = (char *)&qbDataArea;
2840    qDataBlkArea.bufferLen = sizeof(qryRespBackupData);
2841
2842    numTypes = 0;
2843    rc = AFSdsmGetNextQObj(dsmHandle, &qDataBlkArea);
2844    while (((rc == DSM_RC_MORE_DATA) ||
2845          (rc == DSM_RC_FINISHED)) &&
2846           qDataBlkArea.numBytes)
2847    {  /* save copy Group we got */
2848       listCopyGroup[numTypes] = qbDataArea.copyGroup;
2849       listObjType[numTypes]   = qbDataArea.objName.objType;
2850       numTypes++;
2851       rc = AFSdsmGetNextQObj(dsmHandle, &qDataBlkArea);
2852    }
2853
2854    if (rc != DSM_RC_FINISHED)
2855    {
2856       xlateRC(BSAHandle, rc, &bsaRC);
2857       if ((rc == DSM_RC_ABORT_NO_MATCH) || /* special rc for MarkInact */
2858           (rc == DSM_RC_FILE_SPACE_NOT_FOUND))
2859          bsaRC = BSA_RC_ABORT_ACTIVE_NOT_FOUND;
2860       rc = AFSdsmEndQuery(dsmHandle);
2861       XOPENRETURN(BSAHandle,"BSAMarkObjectInactive: AFSdsmGetNextQObj",
2862                   bsaRC,__FILE__,__LINE__);
2863    }
2864    rc = AFSdsmEndQuery(dsmHandle);
2865
2866    /*=== now we can do the delete ===*/
2867    rc = AFSdsmBeginTxn(dsmHandle);
2868
2869    if (rc)
2870    {
2871      xlateRC(BSAHandle, rc, &bsaRC);
2872      XOPENRETURN(BSAHandle,"BSAMarkObjectInactive: AFSdsmBeginTxn",
2873                  bsaRC,__FILE__,__LINE__);
2874    }
2875    xopenGbl.sessFlags = (xopenGbl.sessFlags | FL_IN_DSM_TXN); /* set on */
2876
2877    delType = dtBackup;     /* this only applies to Backup */
2878
2879    delInfo.backInfo.stVersion = delBackVersion;
2880    delInfo.backInfo.objNameP = &dsmobjName;
2881
2882    for (i=0; i<numTypes; i++)
2883    {
2884       delInfo.backInfo.copyGroup = listCopyGroup[i];
2885       dsmobjName.objType         = listObjType[i];
2886
2887       if ((rc = AFSdsmDeleteObj(dsmHandle, delType, delInfo)) != DSM_RC_OK)
2888       {
2889
2890          sprintf(traceStr2, "BSAMarkObjectInactive: call to AFSdsmDeleteObj error rc = %d", rc);
2891          ourTrace(BSAHandle, TrFL, traceStr2);
2892       }
2893    }
2894
2895    /*=== issue EndTxn since these can't be nested because of Query sequence ===*/
2896    AFSdsmEndTxn(dsmHandle, DSM_VOTE_COMMIT, &reason);
2897    xopenGbl.sessFlags = (xopenGbl.sessFlags ^ FL_IN_DSM_TXN); /* set off */
2898
2899    xlateRC(BSAHandle, rc, &bsaRC);
2900    XOPENRETURN(BSAHandle,"BSAMarkObjectInactive",
2901                bsaRC,__FILE__,__LINE__);
2902 }
2903
2904 #endif /*xbsa*/