From b3334a2401e66b3add938d12239510599843aa98 Mon Sep 17 00:00:00 2001 From: Deon George Date: Thu, 7 Nov 2013 15:10:18 +1100 Subject: [PATCH] Enabled Archive Date Query, enabled query with time, some minor internal work --- lib/dsmlist.c | 4 +- lib/dsmobjects.c | 48 +++++++-- lib/dsmsendrecv.c | 17 +-- lib/dsmsession.c | 7 +- tsmpipe.c | 267 +++++++++++++++++++++++----------------------- tsmpipe.h | 23 ++-- 6 files changed, 207 insertions(+), 159 deletions(-) diff --git a/lib/dsmlist.c b/lib/dsmlist.c index 870a0bc..6f3d6e5 100644 --- a/lib/dsmlist.c +++ b/lib/dsmlist.c @@ -130,10 +130,10 @@ int tsm_listfile_cb(dsmQueryType qType, DataBlk *qResp, void *userdata) { /* * List objects that are in TSM */ -int tsm_listfile(dsUint32_t sesshandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData, int verbose) { +int tsm_listfile(dsUint32_t sesshandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData) { dsInt16_t rc=0; - rc = tsm_queryfile(sesshandle,qType,tsm_listfile_cb,NULL,qaData,qbData,verbose); + rc = tsm_queryfile(sesshandle,qType,tsm_listfile_cb,NULL,qaData,qbData); if (rc != DSM_RC_OK && rc != DSM_RC_ABORT_NO_MATCH) return 0; diff --git a/lib/dsmobjects.c b/lib/dsmobjects.c index fb94379..b08c3fa 100644 --- a/lib/dsmobjects.c +++ b/lib/dsmobjects.c @@ -14,11 +14,15 @@ * * The date is passed to this function in the format mmddYYYY */ -dsmDate dsmStrToDate(char *s,int verbose) { +dsmDate dsmStrToDate(char *s) { + extern int verbose; dsmDate *date; - dsUint32_t x; + dsUint32_t d,t; + char *x=NULL, *y=NULL; date = (dsmDate*)malloc(sizeof(dsmDate)); + x = (char *)malloc(sizeof(s)); + y = (char *)malloc(sizeof(s)); if (date==NULL) { perror("Arg, out of memory?"); @@ -30,18 +34,31 @@ dsmDate dsmStrToDate(char *s,int verbose) { if (verbose) printf("dsmStrToDate: Date String: %s\n", s); + /* if user key in some inputs */ if (s[0] != '\0') { - x = atol(s); - date->month = x / 1000000; + strncpy(x,s,sizeof(strchr(s,':'))); - x %= 1000000; - date->day = x / 10000; - date->year = x % 10000; + d = atol(x); + date->month = d / 1000000; + + d %= 1000000; + date->day = d / 10000; + date->year = d % 10000; + + if (strlen(x) != strlen(s)) { + y = strchr(s,':')+1; + t = atol(y); + date->hour = t / 10000; + + t %= 10000; + date->minute = t / 100; + date->second = t % 100; + } } if (verbose) - printf("dsmStrToDate: date = %d, month = %d, year = %d\n", date->day, date->month, date->year); + printf("dsmStrToDate: date = %d, month = %d, year = %d, hour = %d, minute = %d, second = %d\n", date->day, date->month, date->year, date->hour, date->minute, date->second); return *date; } @@ -70,7 +87,8 @@ char *dsmDateToStr(dsmDate date) { return s; } -dsmObjName dsmNameToObjname(char *fsname, char *filename, int verbose) { +dsmObjName dsmNameToObjname(char *fsname, char *filename) { + extern int verbose; dsmObjName *objname; char *p; @@ -141,3 +159,15 @@ double dsmSizeToNum(dsStruct64_t dsStruct64) { // Return number in MB return (float)filesize/1024/1024; } + +void debugLog(int level, _IO_FILE *output, char *message, int die) { + extern int verbose; + + if (level > verbose) + return; + + fprintf(output,"%s\n",message); + + if (die) + exit(die); +} diff --git a/lib/dsmsendrecv.c b/lib/dsmsendrecv.c index 82d0660..1b47b0f 100644 --- a/lib/dsmsendrecv.c +++ b/lib/dsmsendrecv.c @@ -118,7 +118,8 @@ int tsm_regfs(dsUint32_t dsmHandle, char *fsname) { } /* Send data to TSM for storage */ -int tsm_sendfile(dsUint32_t dsmHandle, char *fsname, char *filename, long long length, char *description, dsmSendType sendtype, int verbose) { +int tsm_sendfile(dsUint32_t dsmHandle, char *fsname, char *filename, long long length, char *description, dsmSendType sendtype) { + extern int verbose; char *buffer; dsInt16_t rc=0; dsmObjName objName; @@ -153,7 +154,7 @@ int tsm_sendfile(dsUint32_t dsmHandle, char *fsname, char *filename, long long l } memset(&objName,0x00,sizeof(objName)); - objName = dsmNameToObjname(fsname,filename,verbose); + objName = dsmNameToObjname(fsname,filename); if (verbose) fprintf(stderr,"tsm_sendfile: Starting to send stdin as %s\n",dsmObjnameToStr(objName)); @@ -277,7 +278,8 @@ int tsm_sendfile(dsUint32_t dsmHandle, char *fsname, char *filename, long long l } /* Get data from TSM for restore */ -int tsm_restorefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData, int verbose) { +int tsm_restorefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData) { + extern int verbose; dsInt16_t rc=0; struct matchone_cb_data cbdata; dsmGetList getList; @@ -292,14 +294,14 @@ int tsm_restorefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaD fprintf(stderr,"tsm_restorefile: Starting to receive %s via stdin\n",dsmObjnameToStr(*qaData.objName)); gType = gtArchive; - rc = tsm_queryfile(dsmHandle,qType,tsm_matchone_cb,&cbdata,qaData,qbData,verbose); + rc = tsm_queryfile(dsmHandle,qType,tsm_matchone_cb,&cbdata,qaData,qbData); } else if (qType == qtBackup) { if (verbose) fprintf(stderr,"tsm_restorefile: Starting to receive %s via stdin\n",dsmObjnameToStr(*qbData.objName)); gType = gtBackup; - rc = tsm_queryfile(dsmHandle,qType,tsm_matchone_cb,&cbdata,qaData,qbData,verbose); + rc = tsm_queryfile(dsmHandle,qType,tsm_matchone_cb,&cbdata,qaData,qbData); } else { fprintf(stderr,"tsm_restorefile: Internal error: Unknown qType %d\n",qType); @@ -375,7 +377,8 @@ int tsm_restorefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaD } /* Delete data in TSM */ -int tsm_deletefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData, int verbose) { +int tsm_deletefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData) { + extern int verbose; dsInt16_t rc=0; dsUint16_t reason=0; dsmDelInfo *dInfoP; @@ -384,7 +387,7 @@ int tsm_deletefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaDa cbdata.numfound = 0; - rc = tsm_queryfile(dsmHandle,qType,tsm_matchone_cb,&cbdata,qaData,qbData,verbose); + rc = tsm_queryfile(dsmHandle,qType,tsm_matchone_cb,&cbdata,qaData,qbData); if (rc != DSM_RC_OK) { return 0; } diff --git a/lib/dsmsession.c b/lib/dsmsession.c index 5066d5d..e146141 100644 --- a/lib/dsmsession.c +++ b/lib/dsmsession.c @@ -149,7 +149,7 @@ dsUint32_t tsm_initsess(char *options) { } /* List objects that are in TSM */ -void tsm_sessioninfo(dsUint32_t dsmHandle) { +int tsm_sessioninfo(dsUint32_t dsmHandle) { dsInt16_t rc=0; optStruct dsmOpt; ApiSessInfo dsmSessInfo; @@ -269,6 +269,8 @@ void tsm_sessioninfo(dsUint32_t dsmHandle) { printf(" ARCHIVE retention grace: %u days\n",dsmSessInfo.gpArchRetn); printf("\n"); } + + return 1; } /* @@ -279,7 +281,8 @@ void tsm_sessioninfo(dsUint32_t dsmHandle) { * 0 if tsm_queryfile() should skip processing the remaining matches. * 1 otherwise. */ -dsInt16_t tsm_queryfile(dsUint32_t dsmHandle, dsmQueryType qType, tsm_query_callback usercb, void *userdata, qryArchiveData qaData, qryBackupData qbData, int verbose) { +dsInt16_t tsm_queryfile(dsUint32_t dsmHandle, dsmQueryType qType, tsm_query_callback usercb, void *userdata, qryArchiveData qaData, qryBackupData qbData) { + extern int verbose; dsInt16_t rc=0; dsmQueryBuff *qDataP; diff --git a/tsmpipe.c b/tsmpipe.c index 504c6cf..7346e65 100644 --- a/tsmpipe.c +++ b/tsmpipe.c @@ -38,6 +38,8 @@ SOFTWARE. #include "dsmapifp.h" #include "tsmpipe.h" +int verbose=0; + int copy_env(const char *from, const char *to) { char *e; char n[PATH_MAX+1]; @@ -79,7 +81,11 @@ void usage(void) { " -l length Length of object to store. If guesstimating too large\n" " is better than too small\n" " -D desc Description of archive object\n" - " -P pitdate PITDate (mmddYYYY) (BACKUP Objects)\n" + " -P pitdate PITDate (mmddYYYY[:HHMMSS]) (BACKUP Objects)\n" + " -n insdate Insert Date lower bound (mmddYYYY[:HHMMSS]) (ARCHIVE Objects)\n" + " -N insdate Insert Date upper bound (mmddYYYY[:HHMMSS]) (ARCHIVE Objects)\n" + " -e expdate Expire Date lower bound (mmddYYYY[:HHMMSS]) (ARCHIVE Objects)\n" + " -E expdate Expire Date upper bound (mmddYYYY[:HHMMSS]) (ARCHIVE Objects)\n" " -O options Extra options to pass to dsmInitEx\n" " -v Verbose. More -v's gives more verbosity\n" ,_TSMPIPE_VERSION); @@ -87,34 +93,51 @@ void usage(void) { exit(1); } +void usage_action(void) { + fprintf(stderr, "tsmpipe: ERROR: Must give one of -i, -c, -x, -d, -t\n"); + exit(1); +} + + int main(int argc, char *argv[]) { int c; extern int optopt; extern char *optarg; - char archive=0, backup=0, create=0, xtract=0, delete=0, info=0, list=0; - int verbose=0; - char *space=NULL, *filename=NULL, *lenstr=NULL, *desc=NULL, *pitdate=NULL, *options=NULL; + int action=0; + char *space=NULL, *filename=NULL, *lenstr=NULL, *desc=NULL, *pitdate=NULL, *options=NULL, *expdate_low=NULL, *expdate_high=NULL, *insdate_low=NULL, *insdate_high=NULL; off_t length; dsUint32_t dsmHandle; - dsmQueryType qType; + dsmQueryType qType=0xff; // We set this to an unlikely value, it should be set correctly via our getopt + qryArchiveData qaData; + qryBackupData qbData; + dsmObjName objName; + int rc=0; - while ((c = getopt(argc, argv, "hiABcxdtvs:f:l:D:O:P:")) != -1) { + while ((c = getopt(argc, argv, "hiABcxdtve:E:f:l:n:N:s:D:O:P:")) != -1) { switch(c) { case 'h': usage(); break; - case 'i': info = 1; break; - case 'A': archive = 1; break; - case 'B': backup = 1; break; - case 'c': create = 1; break; - case 'x': xtract = 1; break; - case 'd': delete = 1; break; - case 't': list = 1; break; + case 'A': qType = qtArchive; break; + case 'B': qType = qtBackup; break; + + case 'i': if (action != 0) usage_action(); action = ACTION_INFO; break; + case 'c': if (action != 0) usage_action(); action = ACTION_CREATE; break; + case 'x': if (action != 0) usage_action(); action = ACTION_EXTRACT; break; + case 'd': if (action != 0) usage_action(); action = ACTION_DELETE; break; + case 't': if (action != 0) usage_action(); action = ACTION_LIST; break; + case 'v': verbose++; break; case 's': space = optarg; break; case 'f': filename = optarg; break; case 'l': lenstr = optarg; break; case 'D': desc = optarg; break; + case 'O': options = optarg; break; + case 'P': pitdate = optarg; break; + case 'e': expdate_low = optarg; break; + case 'E': expdate_high = optarg; break; + case 'n': insdate_low = optarg; break; + case 'N': insdate_high = optarg; break; case ':': fprintf(stderr, "tsmpipe: Option -%c requires an operand\n", optopt); @@ -125,23 +148,23 @@ int main(int argc, char *argv[]) { } } - if (archive+backup+info != 1) { - fprintf(stderr, "tsmpipe: ERROR: Must give one of -i, -A or -B\n"); + // Arguement Validation + if (action == 0) { + fprintf(stderr, "tsmpipe: ERROR: Must give one of -i, -c, -x, -d, -t\n"); exit(1); } - // @todo To change. - if (pitdate && ! backup) { - fprintf(stderr, "tsmpipe: ERROR: -P can only be used with -A\n"); + if (pitdate && qType != qtBackup) { + fprintf(stderr, "tsmpipe: ERROR: -P can only be used with -B\n"); exit(1); } - if (! info) { - if (create+xtract+delete+list != 1) { - fprintf(stderr, "tsmpipe: ERROR: Must give one of -c, -x, -d or -t\n"); - exit(1); - } + if ((insdate_low|| insdate_high || expdate_low || expdate_high) && qType != qtArchive) { + fprintf(stderr, "tsmpipe: ERROR: -e, -E, -n, -N can only be used with -A\n"); + exit(1); + } + if (action != ACTION_INFO) { if (! space) { fprintf(stderr, "tsmpipe: ERROR: Must give -s filespacename\n"); exit(1); @@ -152,163 +175,145 @@ int main(int argc, char *argv[]) { exit(1); } - if(create && ! lenstr) { + if (action == ACTION_CREATE && ! lenstr) { fprintf(stderr, "tsmpipe: ERROR: Must give -l length with -c\n"); exit(1); } - if(! create && lenstr) { + if (action != ACTION_CREATE && lenstr) { fprintf(stderr, "tsmpipe: ERROR: -l length useless without -c\n"); exit(1); } - if(! archive && desc) { + if (desc && qType != qtArchive) { fprintf(stderr, "tsmpipe: ERROR: -D desc useless without -A\n"); exit(1); } } - qType = backup ? qtBackup : qtArchive; - /* Let the TSM api get the signals */ signal(SIGPIPE, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGUSR1, SIG_IGN); - if (getenv("DSM_DIR") && ((! copy_env("DSM_DIR", "DSMI_DIR")) || (! copy_env("DSM_CONFIG", "DSMI_CONFIG")))) { + if (getenv("DSM_DIR") && ((! copy_env("DSM_DIR", "DSMI_DIR")) || (! copy_env("DSM_CONFIG", "DSMI_CONFIG")))) exit(1); - } // OK, we are ready to talk to TSM - if (verbose > 0) - fprintf(stderr,"tsmpipe: Create TSM session\n"); + debugLog(1,stderr,"tsmpipe: Create TSM session",0); + dsmHandle = tsm_initsess(options); - if (! dsmHandle) { - fprintf(stderr,"tsmpipe: Unable to create TSM session?\n"); + if (! dsmHandle) + debugLog(0,stderr,"tsmpipe: Unable to create TSM session?",2); - exit(2); - } + debugLog(2,stderr,"tsmpipe: Session Initiated",0); - if (verbose > 1) - fprintf(stderr, "tsmpipe: Session initiated\n"); + switch (action) { + // Show our session information + case ACTION_INFO: + debugLog(2,stderr,"tsmpipe: INFO Operation",0); - // Show our session information - if (info) { - if (verbose > 0) - fprintf(stderr,"tsmpipe: INFO operation\n"); + rc = tsm_sessioninfo(dsmHandle); + break; - tsm_sessioninfo(dsmHandle); - } + // If we are backing up or archiving + case ACTION_CREATE: + debugLog(2,stderr,"tsmpipe: CREATE Operation",0); - // If we are backing up - if (create) { - if (verbose > 0) - fprintf(stderr,"tsmpipe: BACKUP operation\n"); + length = atof(lenstr); + if (length <= 0) + debugLog(0,stderr,"tsmpipe: ERROR: Provide positive length, overestimate if guessing",1); - length = atof(lenstr); - if (length <= 0) { - fprintf(stderr,"tsmpipe: ERROR: Provide positive length, overestimate if guessing\n"); - exit(1); - } + rc = tsm_sendfile(dsmHandle,space,filename,length,desc,((qType == qtArchive) ? stArchiveMountWait : stBackupMountWait)); + break; - if (! tsm_sendfile(dsmHandle,space,filename,length,desc,(archive ? stArchiveMountWait : stBackupMountWait),verbose)){ - dsmTerminate(dsmHandle); - exit(3); - } - exit(0); - } + case ACTION_DELETE: + case ACTION_LIST: + case ACTION_EXTRACT: + memset(&qaData,0x00,sizeof(qryArchiveData)); + memset(&qbData,0x00,sizeof(qryBackupData)); + objName = dsmNameToObjname(space,filename); - if (! info && ! create) { - qryArchiveData qaData; - qryBackupData qbData; - dsmObjName objName; - memset(&qaData,0x00,sizeof(qryArchiveData)); - memset(&qbData,0x00,sizeof(qryBackupData)); - objName = dsmNameToObjname(space,filename,verbose); + // Setup our Query Object + switch (qType) { + case qtBackup: + qbData.stVersion = qryBackupDataVersion; + qbData.objName = &objName; + qbData.owner = ""; + qbData.objState = (action == ACTION_DELETE) ? DSM_ACTIVE : DSM_ANY_MATCH; - // Setup our Query Object - if (backup) { - qbData.stVersion = qryBackupDataVersion; - qbData.objName = &objName; - qbData.owner = ""; - qbData.objState = delete ? DSM_ACTIVE : DSM_ANY_MATCH; + if (action == ACTION_DELETE || ! pitdate) { + qbData.pitDate.year = DATE_MINUS_INFINITE; + } else { + qbData.pitDate = dsmStrToDate(pitdate); + } - if (delete || ! pitdate) { - qbData.pitDate.year = DATE_MINUS_INFINITE; - } else { - // @todo Need to include time - qbData.pitDate = dsmStrToDate(pitdate,verbose); - } + break; - // We must be archive then - } else { - if (archive) { - qaData.stVersion = qryArchiveDataVersion; - qaData.objName = &objName; - qaData.owner = ""; + case qtArchive: + qaData.stVersion = qryArchiveDataVersion; + qaData.objName = &objName; + qaData.owner = ""; + qaData.descr = desc ? desc : "*"; - if (pitdate) { - fprintf(stderr,"tsmpipe: Archive Date Range Query not yet setup\n"); - exit(1); - - } else { qaData.insDateLowerBound.year = DATE_MINUS_INFINITE; qaData.insDateUpperBound.year = DATE_PLUS_INFINITE; qaData.expDateLowerBound.year = DATE_MINUS_INFINITE; qaData.expDateUpperBound.year = DATE_PLUS_INFINITE; - } - qaData.descr = desc ? desc : "*"; + if (insdate_low) + qaData.insDateLowerBound = dsmStrToDate(insdate_low); - } else { - fprintf(stderr,"tsmpipe: ERROR: How can we not be a backup or archive?\n"); - exit(1); + if (insdate_high) + qaData.insDateUpperBound = dsmStrToDate(insdate_high); + + if (expdate_low) + qaData.expDateLowerBound = dsmStrToDate(expdate_low); + + if (expdate_high) + qaData.expDateUpperBound = dsmStrToDate(expdate_high); + break; + + default: + fprintf(stderr,"tsmpipe: UNKNOWN Type %d",qType); + exit(2); } - } - // Delete an object from TSM - if (delete) { - if (verbose > 0) - fprintf(stderr,"tsmpipe: DELETE operation\n"); + switch (action) { + case ACTION_DELETE: + debugLog(2,stderr,"tsmpipe: DELETE Operation",0); + rc = tsm_deletefile(dsmHandle,qType,qaData,qbData); + break; - // @todo Delete Archives by date range. - if (! tsm_deletefile(dsmHandle,qType,qaData,qbData,verbose)) { - dsmTerminate(dsmHandle); - exit(3); + case ACTION_EXTRACT: + debugLog(2,stderr,"tsmpipe: EXTRACT Operation",0); + rc = tsm_restorefile(dsmHandle,qType,qaData,qbData); + break; + + case ACTION_LIST: + debugLog(2,stderr,"tsmpipe: LIST Operation",0); + rc = tsm_listfile(dsmHandle,qType,qaData,qbData); + break; + + default: + fprintf(stderr,"tsmpipe: Action not yet programmed for%d",action); + exit(2); } - } + break; - // Restore from TSM - if(xtract) { - if (verbose > 0) - fprintf(stderr,"tsmpipe: RESTORE operation\n"); - - // @todo Query Archives by date range. - if (! tsm_restorefile(dsmHandle,qType,qaData,qbData,verbose)) { - dsmTerminate(dsmHandle); - exit(3); - } - } - - // List objects in TSM - if (list) { - if (verbose > 0) - fprintf(stderr,"tsmpipe: LIST operation\n"); - - // @todo Query Archives by date range. - if (! tsm_listfile(dsmHandle,qType,qaData,qbData,verbose)) { - dsmTerminate(dsmHandle); - exit(3); - } - } + default: + fprintf(stderr,"tsmpipe: UNKNOWN Operation %d",action); + exit(2); } - if (verbose > 0) - fprintf(stderr,"tsmpipe: Terminate TSM session\n"); + debugLog(1,stderr,"tsmpipe: Terminate TSM session",0); + dsmTerminate(dsmHandle); - if (verbose > 0) - fprintf(stderr, "tsmpipe: Success\n"); + if (! rc) + debugLog(0,stderr,"tsmpipe: Operation Failed",3); + else + debugLog(1,stderr,"tsmpipe: Operation Success",0); return 0; } diff --git a/tsmpipe.h b/tsmpipe.h index 1fc5e6f..d160e8f 100644 --- a/tsmpipe.h +++ b/tsmpipe.h @@ -1,22 +1,29 @@ #define _TSMPIPE_VERSION "1.5.1" +#define ACTION_INFO 1 +#define ACTION_CREATE 2 +#define ACTION_EXTRACT 3 +#define ACTION_DELETE 4 +#define ACTION_LIST 5 + typedef int (*tsm_query_callback)(dsmQueryType, DataBlk *, void *); struct matchone_cb_data { int numfound; dsStruct64_t objId; dsUint32_t copyGroup; }; extern void tsm_printerr (dsUint32_t dsmHandle, dsInt16_t rc, char *str); -extern void tsm_sessioninfo(dsUint32_t dsmHandle); +extern void debugLog(int level, _IO_FILE *output, char *message, int die); -extern dsmDate dsmStrToDate(char *s,int verbose); -extern dsmObjName dsmNameToObjname(char *fsname, char *filename, int verbose); -extern dsInt16_t tsm_queryfile(dsUint32_t sesshandle, dsmQueryType qType, tsm_query_callback usercb, void *userdata, qryArchiveData qaData, qryBackupData qbData, int verbose); +extern dsmDate dsmStrToDate(char *s); +extern dsmObjName dsmNameToObjname(char *fsname, char *filename); +extern dsInt16_t tsm_queryfile(dsUint32_t sesshandle, dsmQueryType qType, tsm_query_callback usercb, void *userdata, qryArchiveData qaData, qryBackupData qbData); extern dsUint32_t tsm_initsess(char *options); extern dsBool_t compressEnabled; -extern int tsm_deletefile (dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData, int verbose); -extern int tsm_listfile (dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData, int verbose); -extern int tsm_restorefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData, int verbose); -extern int tsm_sendfile (dsUint32_t dsmHandle, char *fsname, char *filename, long long length, char *description, dsmSendType sendtype, int verbose); +extern int tsm_deletefile (dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData); +extern int tsm_listfile (dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData); +extern int tsm_restorefile(dsUint32_t dsmHandle, dsmQueryType qType, qryArchiveData qaData, qryBackupData qbData); +extern int tsm_sendfile (dsUint32_t dsmHandle, char *fsname, char *filename, long long length, char *description, dsmSendType sendtype); +extern int tsm_sessioninfo(dsUint32_t dsmHandle); extern char *dsmDateToStr(dsmDate date); extern char *dsmObjnameToStr(dsmObjName objName);