Coding Sample
This program moves files from a Filenet Mezzanine Document Management Repository to aweb server, using Filenet's API to interface with the repository. It's another example of gaining,
an understanding of an environment through experimentation. The Filenet API documentation
was pretty good, but I had to play around with it for a few days to finally know what I
was doing. (Note that the free C++2HTML converter I used leaves some odd spacing at times.)
/*= WEBUPDATE PROGRAM * Allocate Search Request OAB * Build Where, Show, Order Structures * Find all Items where User is the Profile Originator * Print each OAB using OABInfo and Object information calls * * To make a new project for this program, using Dev Studio 97, just go to : * File, New, Console Application. Fill in the name and hit the Create button. * In the project, go to : Build, Settings, Link Tab. * Set Category to "General". Add srs_mapi.lib to the end of the entries * in the Object/library modules box. That's it. TESTING IN NYC Comment out the set of #defines for MIAMI and restore the vals for NYC. The values for some of the custom properties and the competer and repository names need to be changed. CHANGE LOG ====================== BB 9-25-1998 ADD CODE TO PUT THE EFFECTIVE DATE META TAG IN THE HTML FILE DURING THE COPY OUT PROCESS. *=========================================================================*/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stddef.h> #include <time.h> /* #if defined(WIN32) #ifdef _MSC_VER #pragma warning(disable:4514) // disable C4514 warning #pragma warning(disable:4214) // disable C4214 warning #pragma warning(disable:4201) // disable C4201 warning #pragma warning(disable:4115) // disable C4115 warning #endif // _MSC_VER #include <winbase.h> #ifdef _MSC_VER #pragma warning(default:4214) // enable 4214 warning #pragma warning(default:4201) // enable 4201 warning #pragma warning(default:4115) // enable 4115 warning #endif #endif /* WIN32 */ #include <windows.h> #define SPI_INCLUDE_OBJECTS #define SPI_INCLUDE_ATTRIBUTES extern "C" { #include <spi.h> #include <spi_sts.h> #include <spi_obj.h> #include <spi_attr.h> } // FUNCTION DECLARATIONS int copyItemToIIS ( SPI_SCTX_HNDL sctx, char * itemID, char * fileName, char * ansSub, char * keywords, char * effDate ); int deleteItemFromIIS ( SPI_SCTX_HNDL sctx, char * itemID, char * fileName ); int queryKeywordObject(SPI_SCTX_HNDL sctx, char * itemID, char * folderNum, char * parentKeyName ); int extractParent(char * keywordName, char * folderNum); int getFullPath ( SPI_SCTX_HNDL sctx, char * itemID,char * fileName, char * parentNum, char * retParentName, char * fullPath ); int expireTheFile(SPI_SCTX_HNDL sctx, char * itemID, char * parentKeyName, char * parentNum, char * parentName, char * fullPath ) ; int getSystemTime ( char * runTime, char * fileNameTime); int processMetaData( char * fullPath, char * metaTag, int numToSkip, char * propVal); int updateFile(FILE * htmlFile, char * fullPath, char * propName, int NumToSkip, char * oldVal, char * newVal); int insertMetaData(FILE * htmlFile, char * metaString, char * beforeString); int insertAnsSub( FILE * oFile, char * ansSubVal, char * inString); int changeDateFormat( char* filenetDate, char * date ); int editFullPath( char* fullPath, char * halfPath ); void killTime(); int getFolderNum ( SPI_SCTX_HNDL sctx, char * folderName, char * folderNum ); // CUSTOM PROPERTIES ARE PROP NUMBERS 282 - 301 IN THE ITEM OBJECT. IN FILESHARE, IF YOU LOOK AT THE CUSTOM PROPERTIES // LIST, THEY ARE NUMBERED FROM 1. SO, 1 = 282, 2 = 283, ETC. // PROP NYC VAL MIAMI VAL // =================== ======================= ======================= // EFFECTICE DATE SPI_ITEM_CUSTOM05 - 286 SPI_ITEM_CUSTOM04 - 285 // ANS SUB SPI_ITEM_CUSTOM01 - 282 SPI_ITEM_CUSTOM01 - 282 // KEYWORDS SPI_ITEM_CUSTOM13 - 294 SPI_ITEM_CUSTOM07 - 288 // EXPIRATION DATE SPI_ITEM_CUSTOM06 - 287 SPI_ITEM_CUSTOM05 - 286 // NYC VALUES //#define COMPUTER "server2" //#define REPOSITORY "password" //#define EFFECTIVE_DATE 286 //#define KEYWORDS 294 //#define EXPIRATION_DATE 287 // MIAMI VALUES #define COMPUTER "server1" #define REPOSITORY "password" #define EFFECTIVE_DATE 285 #define KEYWORDS 288 #define EXPIRATION_DATE 286 // open up the output files FILE *logFile; FILE *report; FILE *timeFile; FILE *bootUpLog; int main( void ) { SPI_SCTX_HNDL sctx; char username[SPI_MAXLEN_STRING+1] = "bob"; char password[SPI_MAXLEN_STRING+1] ="bobspw"; char catalog[SPI_MAXLEN_STRING+1] = REPOSITORY; char server[SPI_MAXLEN_STRING+1] = COMPUTER; SPI_STATUS status; SPI_QUERY_HNDL qhnd; unsigned long count; SPI_OAB_HNDL srOAB; SPI_OAB_HNDL rowOAB; unsigned long ii; SPI_ATTR_NO selectList[SPI_MAX_QRY_SHOW]; SPI_QUERY_SELECTION whereClause[SPI_MAX_QRY_SELECTIONS]; SPI_QUERY_SORT orderBy[SPI_MAX_QRY_SORT]; int isMoreRows; int firstRow; char keybuf[SPI_MAXLEN_ITEM + 1]; char itemID[SPI_MAXLEN_STRING + 1]; char ansSub[SPI_MAXLEN_ATTR + 1]; char effDate[SPI_MAXLEN_ATTR + 1]; char keywords[SPI_MAXLEN_ATTR + 1]; char itemName[SPI_MAXLEN_ATTR + 1]; char runTime[22]; char fileNameTime[22]; char timeLastRun[22]; char logName[100] = "C:\\Program Files\\Acme\\KBAT Web Update\\Logs\\WebUpdateLog"; char reportName[100] = "C:\\Program Files\\Acme\\KBAT Web Update\\Logs\\WebUpdateReport"; char dotTxt[5] = ".txt"; int numItemsUpdated = 0; int numItemsDeleted = 0; // open up the output files // The log and report file names include the system time. Until the time is obtained, use boot up log. bootUpLog = fopen("c:\\Program Files\\Acme\\KBAT Web Update\\Logs\\WebUpdateBootUpLog.txt","w"); // use boot up log till time is obtained timeFile = fopen("c:\\program files\\Acme\\WebUpdateTimeLastRun.txt","r+"); // read-write if (timeFile == NULL) { fprintf ( bootUpLog, "No c:\\program files\\Acme\\WebUpdateTimeLastRun.txt file. Going to EOJ.\n"); fflush( bootUpLog ); fclose ( bootUpLog ); return(1); } else { fprintf ( bootUpLog, "Good Time read. Continuing on. All further log messages written to the log file.\n"); fflush( bootUpLog ); } // Get the system time and save to write to the time last run file at EOJ status = getSystemTime( runTime, fileNameTime ); if ( status!= 0) { fprintf ( bootUpLog, "Failed to get system time. Going to EOJ.\n"); fflush( bootUpLog ); fclose ( bootUpLog ); return(1); } else { fprintf ( bootUpLog, "Got system time : %s\n", runTime ); fflush( bootUpLog ); fclose ( bootUpLog ); } strcat ( logName, fileNameTime ); strcat ( reportName, fileNameTime ); strcat ( logName, dotTxt ); strcat ( reportName, dotTxt ); logFile = fopen( logName,"w" ); report = fopen( reportName,"w" ); // Get the time that the program ran last from the file fgets( timeLastRun, 22, timeFile); // set file pointer back to start to overwrite previous date //WRITE THE SYSTEM TIME TO THE TIME LAST RUN FILE AND CLOSE THE FILE rewind(timeFile); fputs( runTime, timeFile); fclose(timeFile); fprintf ( logFile, "Got system time : %s\n", runTime ); fflush( logFile ); fprintf ( logFile, "Time last run was : %s\n", timeLastRun); fflush( logFile ); fprintf ( report, "Web Update \n" ); fprintf ( report, "================================\n" ); fprintf ( report, "System time : %s\n", runTime ); fprintf ( report, "Last run time : %s\n", timeLastRun ); fflush( report ); #if defined (WIN32) //================================================================ // Win32 console mode apps must tell the filesystem to use the // OEM codepage for file operations. //================================================================ SetFileApisToOEM(); #endif /* WIN32 */ //================================================================ //LOGIN TO MEZZANINE REPOSITORY //================================================================ status= spiSessionLogin( &sctx, username, password, catalog, server, ".", NULL, NULL, 0, 0 ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Failed to login. Going EOJ. Status = %d\n", status); fflush( logFile ); return(1); } fprintf(logFile,"Successfully logged in as %s\n", username ); fflush(logFile); fprintf ( report, "\n\nUpdated or Added These Files\n"); fprintf ( report, "===================================\n\n"); fflush( report ); //===================================================================== //SET UP TO SEARCH FOR THE ITEMS WITH AN EFFECTIVE DATE TODAY OR BEFORE //===================================================================== //OAB ALLOCATE FOR THE EFFECTIVE DATE SEARCH REQUEST OBJECT status= spiOABAlloc( sctx, SPI_OBJ_SEARCH_REQUEST, &srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Search OAB Alloc for effective date. Going EOJ. status = %d\n", status); fflush( logFile ); return(1); } //BUILD THE SELECT, WHERE AND ORDER CLAUSES FOR THE QUERY selectList[0] = SPI_ITEM_ID; //ITEM ID selectList[1] = SPI_ITEM_ICON_TITLE; //FILE NAME selectList[2] = SPI_ITEM_CUSTOM01; //ANSWER SUBJECT selectList[3] = EFFECTIVE_DATE; //EFFECTIVE DATE selectList[4] = KEYWORDS; //keywords selectList[5] = 0; status = spiOABAttrPut( sctx, srOAB, SPI_SR_SHOW, selectList ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrPut Failed-Select for effective date search, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } whereClause[0].andOrStop = SPI_ANDOR_START; whereClause[0].nestingLevel = 0; whereClause[0].attrNo = EFFECTIVE_DATE; //effective date whereClause[0].relOp = SPI_RELOP_GE; strcpy( whereClause[0].value, timeLastRun); whereClause[1].andOrStop = SPI_ANDOR_AND; whereClause[1].nestingLevel = 0; whereClause[1].attrNo = EFFECTIVE_DATE; //effective date whereClause[1].relOp = SPI_RELOP_LT; strcpy( whereClause[1].value, runTime); whereClause[2].andOrStop = SPI_ANDOR_STOP; whereClause[2].nestingLevel = 0; status = spiOABAttrPut( sctx, srOAB, SPI_SR_QUERY, whereClause ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrPut Failed-Where for effective date search, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } orderBy[0].attrNo = SPI_ITEM_ID; orderBy[0].ascDesc = SPI_QUERY_SORT_ASCENDING; orderBy[1].attrNo = 0; status = spiOABAttrPut( sctx, srOAB, SPI_SR_SORT, orderBy ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrBut Failed-Orderby for effective date search, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } //PARTIAL OAB ALLOCATE FOR THE SEARCH REQUEST OBJECT status= spiOABRowAlloc( sctx, srOAB, &rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Search OAB Row Alloc Failed-effective date search, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } //===================================================================== //ISSUE THE SEARCH - THIS DO-WHILE IS THE MAIN PROCESSING LOOP //===================================================================== //THE QUERY WILL PPROBABLY RETURN MULTIPLE ROWS. //WE GRAB UP TO 100 ROWS AT A TIME. PROCESS THEM AND THEN GRAB ANOTHER 100. //IN THE DO-WHILE LOOP. A FOR LOOP INSIDE THE DO-WHILE PROCESS THE ROWS //OF THE CURRENT RESULT SET. *keybuf = '\0'; firstRow = 0; do { //ISSUE THE SEARCH. IN THE DO-WHILE LOOP, GRAB UP TO 100 ROWS. //AT A TIME. A STATUS = 52 MEANS > 100 ROWS SATISFIED THE QUERY //AND ANOTHER SEARCH REQUEST CALL WILL BE NEEDED. //THE FOR LOOP INSIDE THE DO-WHILE PROCESSES EACH ROW OF THE SET. status= spiQuerySearchRequest( sctx, srOAB, SPI_QUERY_FORWARD, keybuf, (unsigned long)200, &count, &qhnd ); if ((status != SPI_STS_SUCCESS) && (status != SPI_STS_MORE_ROWS)) { fprintf ( logFile, "Query Search Request Failed-Effective date search, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } isMoreRows = (status == SPI_STS_MORE_ROWS); // fetch 100 rows at a time. After first time, don't show the first row. fprintf ( logFile, "Rows found-Effective Date search: %d%s\n", count, ((firstRow == 0)? "" : " (Note: Not displaying first row)") ); fflush(logFile); //FOR LOOP BEGIN. READ EACH ROW AND PROCESS TILL NO MORE ROWS IN THE RESULT SET for ( ii = firstRow; ii < count; ii++ ) { status= spiQueryRow( sctx, ii, rowOAB, qhnd ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "QueryRow Failed-Effective Date search, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } // Get the values of the SPI_ITEM_ID, item name and Answer Subject props of the item. status = spiOABAttrGet( sctx, rowOAB, SPI_ITEM_ID, itemID, SPI_MAXLEN_STRING + 1 ); status = spiOABAttrGet( sctx, rowOAB, SPI_ITEM_ICON_TITLE, itemName, SPI_MAXLEN_ATTR + 1 ); status = spiOABAttrGet( sctx, rowOAB, SPI_ITEM_CUSTOM01, ansSub, SPI_MAXLEN_ATTR + 1 ); status = spiOABAttrGet( sctx, rowOAB, EFFECTIVE_DATE, effDate, SPI_MAXLEN_ATTR + 1 ); status = spiOABAttrGet( sctx, rowOAB, KEYWORDS, keywords, SPI_MAXLEN_ATTR + 1 ); fprintf ( logFile, "Item : %s %s \n", itemID, itemName ); fprintf ( logFile, " Answer sub : %s\n", ansSub ); fprintf ( logFile, " Effective Date : %s\n", effDate); fflush(logFile); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Attr Get Failed-Effective Date search, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } //===================================================================== //COPY THE ITEM TO THE IIS FILE STRUCTURE //===================================================================== status = copyItemToIIS( sctx, itemID, itemName, ansSub, keywords, effDate ); //copy the item to IIS file system if (status > 0) { fprintf (logFile," Bad Copy - status : %d, moving on to next row\n", status); fflush(logFile); fprintf (report," *****Bad Copy - Check the log file - status : %d, moving on to next row\n", status); fflush(report); } else { numItemsUpdated++; } } //FOR LOOP END. THE LOOP PROCESSES EACH ROW OF THE RESULT SET //IF MORE ROWS, GET ANOTHER RESULT SET CONTAINING UP TO 100 ROWS. if (isMoreRows) { /* start next search from end of this one */ spiOABAttrGet(sctx, rowOAB, SPI_ITEM_ID, keybuf, SPI_MAXLEN_ITEM+1); firstRow = 1; } // CLOSE THE QUERY AND RELEASE RESOURCES status= spiQueryDone( sctx, qhnd ); } while (isMoreRows); // Write report total fprintf ( report, "\n\n\nTotal items updated : %d\n", numItemsUpdated); fflush( report ); //=================================================================================== //END OF THE BIG DO-WHILE LOOP * ALL NEWW EFFECTIVE DATE ITEMS PUPROCESSED //=================================================================================== //FREE THE OAB'S status= spiOABFree( sctx, srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OAB Free Failed, status = %d\n", status); fflush( logFile ); return(1); } status= spiOABFree( sctx, rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OAB Free Failed, status = %d\n", status); fflush( logFile ); return(1); } //======================================================================================== //NOW DO THE DELETES //=================================================================================== //=================================================================================== //=================================================================================== //=================================================================================== //=================================================================================== //=================================================================================== //=================================================================================== //=================================================================================== fprintf ( report, "\n\n\nDeleted These Files\n\n"); fprintf ( report, "==============================\n\n"); fflush( report ); //OAB ALLOCATE FOR THE EFFECTIVE DATE SEARCH REQUEST OBJECT status= spiOABAlloc( sctx, SPI_OBJ_SEARCH_REQUEST, &srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Search OAB Alloc for EXPIRATION date, status = %d\n", status); fflush( logFile ); return(1); } //BUILD THE SELECT, WHERE AND ORDER CLAUSES FOR THE QUERY selectList[0] = SPI_ITEM_ID; //ITEM ID selectList[1] = SPI_ITEM_ICON_TITLE; //FILE NAME selectList[2] = SPI_ITEM_CUSTOM01; //ANSWER SUBJECT selectList[3] = 0; spiOABAttrPut( sctx, srOAB, SPI_SR_SHOW, selectList ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrPut Failed-Select for effective date search, status = %d\n", status); fflush( logFile ); return(1); } whereClause[0].andOrStop = SPI_ANDOR_START; whereClause[0].nestingLevel = 0; whereClause[0].attrNo = EXPIRATION_DATE; whereClause[0].relOp = SPI_RELOP_GE; strcpy( whereClause[0].value, timeLastRun); whereClause[1].andOrStop = SPI_ANDOR_AND; whereClause[1].nestingLevel = 0; whereClause[1].attrNo = EXPIRATION_DATE; whereClause[1].relOp = SPI_RELOP_LT; strcpy( whereClause[1].value, runTime); whereClause[2].andOrStop = SPI_ANDOR_STOP; whereClause[2].nestingLevel = 0; spiOABAttrPut( sctx, srOAB, SPI_SR_QUERY, whereClause ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrPut Failed-Where for effective date search, status = %d\n", status); fflush( logFile ); return(1); } orderBy[0].attrNo = SPI_ITEM_ID; orderBy[0].ascDesc = SPI_QUERY_SORT_ASCENDING; orderBy[1].attrNo = 0; spiOABAttrPut( sctx, srOAB, SPI_SR_SORT, orderBy ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrBut Failed-Orderby for effective date search, status = %d\n", status); fflush( logFile ); return(1); } //PARTIAL OAB ALLOCATE FOR THE SEARCH REQUEST OBJECT status= spiOABRowAlloc( sctx, srOAB, &rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Search OAB Row Alloc Failed-effective date search, status = %d\n", status); fflush( logFile ); return(1); } //===================================================================== //ISSUE THE SEARCH - THIS DO-WHILE IS THE MAIN PROCESSING LOOP //===================================================================== //THE QUERY WILL PPROBABLY RETURN MULTIPLE ROWS. //WE GRAB UP TO 100 ROWS AT A TIME. PROCESS THEM AND THEN GRAB ANOTHER 100. //IN THE DO-WHILE LOOP. A FOR LOOP INSIDE THE DO-WHILE PROCESS THE ROWS //OF THE CURRENT RESULT SET. *keybuf = '\0'; firstRow = 0; do { //ISSUE THE SEARCH. IN THE DO-WHILE LOOP, GRAB UP TO 100 ROWS. //AT A TIME. A STATUS = 52 MEANS > 100 ROWS SATISFIED THE QUERY //AND ANOTHER SEARCH REQUEST CALL WILL BE NEEDED. //THE FOR LOOP INSIDE THE DO-WHILE PROCESSES EACH ROW OF THE SET. status= spiQuerySearchRequest( sctx, srOAB, SPI_QUERY_FORWARD, keybuf, (unsigned long)200, &count, &qhnd ); if ((status != SPI_STS_SUCCESS) && (status != SPI_STS_MORE_ROWS)) { fprintf ( logFile, "Query Search Request Failed-Effective date search, status = %d\n", status); fflush( logFile ); return(1); } isMoreRows = (status == SPI_STS_MORE_ROWS); // fetch 100 rows at a time. After first time, don't show the first row. fprintf ( logFile, "Rows found-EXPIRE Date search: %d%s\n", count, ((firstRow == 0)? "" : " (Note: Not displaying first row)") ); fflush(logFile); //FOR LOOP BEGIN. READ EACH ROW AND PROCESS TILL NO MORE ROWS IN THE RESULT SET for ( ii = firstRow; ii < count; ii++ ) { status= spiQueryRow( sctx, ii, rowOAB, qhnd ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "QueryRow Failed-EXPIRE Date search, status = %d\n", status); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); fflush( logFile ); return(1); } // Get the values of the SPI_ITEM_ID, item name and Answer Subject props of the item. spiOABAttrGet( sctx, rowOAB, SPI_ITEM_ID, itemID, SPI_MAXLEN_ATTR+1 ); spiOABAttrGet( sctx, rowOAB, SPI_ITEM_ICON_TITLE, itemName, SPI_MAXLEN_ATTR+1 ); fprintf ( logFile, "Item : %s %s \n", itemID, itemName ); fflush(logFile); //===================================================================== //DELETE THE ITEM FROM THE IIS FILE STRUCTURE //===================================================================== status = deleteItemFromIIS( sctx, itemID, itemName ); //copy the item to IIS file system if (status > 0) { fprintf (logFile," Bad Delete Item not expired - status : %d\n", status); fflush(logFile); } else numItemsDeleted++; } //FOR LOOP END. THE LOOP PROCESSES EACH ROW OF THE RESULT SET //IF MORE ROWS, GET ANOTHER RESULT SET CONTAINING UP TO 100 ROWS. if (isMoreRows) { /* start next search from end of this one */ spiOABAttrGet(sctx, rowOAB, SPI_ITEM_ID, keybuf, SPI_MAXLEN_ITEM+1); firstRow = 1; } // CLOSE THE QUERY AND RELEASE RESOURCES status= spiQueryDone( sctx, qhnd ); } while (isMoreRows); fprintf ( report, "\n\n\nTotal items deleted : %d\n", numItemsDeleted); fflush( report ); //=================================================================================== //END OF THE BIG DO-WHILE LOOP * ALL ITEMS PROCESSED //=================================================================================== //FREE THE OAB'S status= spiOABFree( sctx, srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OAB Free Failed, status = %d\n", status); fflush( logFile ); return(1); } status= spiOABFree( sctx, rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OAB Free Failed, status = %d\n", status); fflush( logFile ); return(1); } //LOGOUT FROM MEZZ AND GO TO END OF JOB spiSessionLogout( sctx ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Failed to logout, status = %d\n", status); fflush( logFile ); return(1); } fprintf ( logFile, "Successfully logged out as %s\n", username ); fflush( logFile ); flushall(); fclose( logFile); fclose ( report); return 0; } //=================================================================================== //=================================================================================== //=================================================================================== //==============F U N C T I O N S ========================== //=================================================================================== //=================================================================================== //=================================================================================== //*********************************************************************************** // F U N C T I O N // // copyItemToIIS // // Params: sctx - handle to the mezzanaine session // itemID - string holding the item's id number // ansSub - string holding the item's answer subject property // Function: // Copies the document to the local IIS file structure // // // We have the item number of the item to be copied out. We need the folder it is in so now we: // 1. look in the Keyword_Object table to first get the folder num of the folder that contains the item. // This folder will be referred to as the parent folder. // This is done in a call to another function:queryKeywordObject. The keyword object // contains just the parent folder number as shown in the table below. // // The structure of the Keyword object is: // // kw_e_name (file number) kw_name (folder number) // ----------------- ----------------------------- // 987120003 {MTISDM}11111111 // In this example, we have the item id. We query on the keyword object to get the // folder number of the folder where the item resides. // To get the parent folder NAME ( we have the folder number now ), a query on // the Custom Object is required. // // 2. Custom_object is shown below. co_key is the folder number and co_string2 is the folder // name. co-string1 is the folder number of the parent of the folder. // // The query exists in a loop and is executed for each folder in a file's // full path, i.e. till the Root folder is reached. // In this example // // The structure of the custom object is: // // co_key co_string1 co_string2 // -------- -------------------- ----------------------------- // 11111111 22222222 Health_Bennies_Folder // 22222222 33333333 Benefits_Folder // 33333333 SDMROOT CSR_Procedures_Folder // // In this example, we have the folder number, 11111111, and we query the custon object for // the folder name and the folder num where it in turn resides: 22222222. // // Then the custom object is selected based on co_key = 11111111 and the name, // Health_Bennies_Folder is added to the path and the next select is done // based on co_key = 22222222, and so on till SDMROOT is reached. // // 3. Now we have the full path and filename, so do the copy. // C:\CSR_Procedures_Folder\Benefits_Folder\Health_Bennies_Folder\file.html //*********************************************************************************** int copyItemToIIS ( SPI_SCTX_HNDL sctx, char * itemID, char * fileName, char * ansSub, char * keywords, char * effDate ) { SPI_STATUS status; SPI_OAB_HNDL checkoutOAB; char parentNum[SPI_MAXLEN_STRING+1]; char parentName[SPI_MAXLEN_STRING+1]={""}; char parentKeyName[SPI_MAXLEN_STRING+1]; char fullPath[300] = "C:\\srvapps\\Inetsrv\\WWWRoot\\Self_Serv\\"; char halfPath[300] = ""; char date[11] = ""; char retParentName[SPI_MAXLEN_STRING+1]={""}; //=================================================================================== //Keyword Object Query returns folder num and parent key name of file's parent folder // parentNum is a string with a number in it - "2345". key name is like - {MTISDM}2345" //=================================================================================== status = queryKeywordObject(sctx, itemID, parentNum, parentKeyName); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " queryKeywordObject failed, status = %d\n", status); fflush( logFile ); fprintf ( report, "PROBLEM PROCESSING ITEM NUMBER %s - see LOG file - %s\n", itemID, fileName ); fflush( report ); return(1); } fprintf ( logFile, " Back with parent num : %s\n", parentNum); fflush( logFile ); //=================================================================================== //Now get the full path of the item - fills in the fullPath string //=================================================================================== status = getFullPath( sctx, itemID, fileName, parentNum, retParentName, fullPath ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " getFullPath failed, status = %d\n", status); fflush( logFile ); fprintf ( report, "PROBLEM PROCESSING ITEM NUMBER %s - see LOG file - %s\n", itemID, fileName ); fflush( report ); return(1); } // Report the item status = editFullPath( fullPath, halfPath ); fprintf ( report, "%s - %s\n", halfPath, itemID); fflush( report ); // COPY THE ITEM OUT //Allocate the checkout OAB status = spiOABAlloc(sctx, SPI_OBJ_VERSION_CHECKOUT, &checkoutOAB); if(status != SPI_STS_SUCCESS) { fprintf ( logFile, " Failed to allocate Checkout OAB, error = %x\n",status); fflush( logFile ); return (1); } status = spiVersionCheckout ( sctx, itemID,"", checkoutOAB, fullPath, SPI_CHECKOUT_COPY|SPI_CHECKOUT_MAINLINE|SPI_CHECKOUT_OVERWRITE); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Copy out Failed, status = %d\n", status); fflush( logFile ); fprintf ( report, " ***** Copy out Failed, status = %d\n", status); fflush( report ); spiOABFree( sctx, checkoutOAB ); return(1); } //else //{ // fprintf ( report, "%s - %s\n", itemID, fullPath); // fflush( report ); //} //FREE THE OAB'S status= spiOABFree( sctx, checkoutOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Checkout OAB Free Failed, status = %d\n", status); fflush( logFile ); return(1); } // Insert props into the doc status = processMetaData( fullPath, "keywords", 19, keywords); if ( status > 0 ) { fprintf ( logFile, " process keywords Failed, status = %d\n", status); fflush( logFile ); return(7); } status = changeDateFormat( effDate, date ); status = processMetaData( fullPath, "EFFECTIVE-DATE", 25, date); if ( status > 0 ) { fprintf ( logFile, " process eff date Failed, status = %d\n", status); fflush( logFile ); return(7); } status = processMetaData( fullPath, "NAME=\"ANSWER-SUBJECT", 29, ansSub); if ( status > 0 ) { fprintf ( logFile, " process ans sub Failed, status = %d\n", status); fflush( logFile ); return(7); } return (0); } //Function end //*********************************************************************************** // F U N C T I O N // // deleteItemFromIIS // GET THE PATH, DELETE FROM IT'S MEZZ FOLDER, ADD IT TO DEAD FOLDER, DEL FROM NT // Params: sctx - handle to the mezzanaine session // itemID - string holding the item's id number // // Function: // 1) Deletes the document from it's Mezzanine folder (custom object) // 2) Adds the doc to the Expired Mezzanine folder // 3) Deletes the file from the local IIS file structure // //*********************************************************************************** int deleteItemFromIIS ( SPI_SCTX_HNDL sctx, char * itemID, char * fileName ) { SPI_STATUS status; BOOL deleteStatus; char parentNum[SPI_MAXLEN_STRING+1]; char parentNumSave[SPI_MAXLEN_STRING+1]; char parentName[SPI_MAXLEN_STRING+1]={""}; char retParentName[SPI_MAXLEN_STRING+1]={""}; char parentKeyName[SPI_MAXLEN_STRING+1]=""; char fullPath[300] = "C:\\srvapps\\Inetsrv\\WWWRoot\\Self_Serv\\"; char halfPath[300] = ""; //=================================================================================== //Keyword Object Query returns folder num of file's parent folder //=================================================================================== status = queryKeywordObject(sctx, itemID, parentNum, parentKeyName ); if ( status == 1) { fprintf ( logFile, " %s - %s - Skipping this file. It's in 2 places!!\n", fileName, itemID ); fflush( logFile ); fprintf ( report, "%s - %s - Skipping this file. It's in 2 places!!\n", fileName, itemID ); fprintf ( report, " This file not expired. Search in Mezz for 2 or more occurrences\n" ); fflush( report ); return(1); } fprintf ( logFile, " %s, Parent Key Name : %s\n", parentNum, parentKeyName); fflush( logFile ); strcpy ( parentNumSave, parentNum ); // save it for call to expireTheFile //=================================================================================== //Now get the full path of the item //=================================================================================== status = getFullPath( sctx, itemID, fileName, parentNum, retParentName, fullPath ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " getFullPath failed, status = %d\n", status); fflush( logFile ); return(1); } // Report the item status = editFullPath( fullPath, halfPath ); fprintf ( report, "%s - %s\n", halfPath, itemID); fflush( report ); // Add item to expired folder and delete it from it's parent folder status = expireTheFile(sctx, itemID, parentKeyName, parentNumSave, retParentName, fullPath ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " expireTheFile failed, status = %d\n", status); fflush( logFile ); fprintf ( report, " File not deleted from Mezz INFO. status = %d\n", status); fflush( report ); return(1); } // DELETE THE ITEM from the IIS Structure deleteStatus = DeleteFile(fullPath); if (deleteStatus) { fprintf ( logFile, " deleted %s\n", fullPath); fflush( logFile ); //status = editFullPath( fullPath, halfPath ); //fprintf ( report, "%s %s\n", halfPath, itemID); //fflush( report ); } else { fprintf ( logFile, " Delete from IIS structure failed !!! Must not have been there to delete. %s\n", fullPath); fflush( logFile ); fprintf ( report, " File not deleted from IIS INFO. Maybe it wasnt there in the first place.\n"); fflush( report ); } return (0); } //Function end //*********************************************************************************** // F U N C T I O N // // queryKeywordObject // // Params: sctx - handle to the mezzanine session // &parentNum, a string ptr containing the parent folder's number only // &parentKeyName - string hold whole folder key - "{MTISDM}12345" // itemID - the item id of the document to be copied out // // The table which corresponds to the keyword object, elem_kw, has a column // called kw_name, which contains the folder number. The data in the column, // however has 2 parts. The first is always the string "{MTISDM}". // The second part is the folder number. The data in the colimn therefore // would look like "{MTISDM}1234", for folder number 1234. // The data base col is called kw_name and the corresponding API name is // SPI_KWRD_NAME. // The query of the keyword object may return more that one row. // The row we're interested in is the one where the col SPI_KWRD_NAME // begins with the string '{MTISDM}'. // // Two data items are returned for the calling function's consumption: // The 1234 is extracteded and put into a string the pointer to which is // passed between the functions. The whole value is put in the string // parentKeyName. //*********************************************************************************** int queryKeywordObject(SPI_SCTX_HNDL sctx, char * itemID, char * parentNum, char * parentKeyName ) { SPI_STATUS status; SPI_QUERY_HNDL qhnd; unsigned long count; SPI_OAB_HNDL srOAB; SPI_OAB_HNDL rowOAB; SPI_ATTR_NO selectList[SPI_MAX_QRY_SHOW]; SPI_QUERY_SELECTION whereClause[SPI_MAX_QRY_SELECTIONS]; char keywordName[SPI_MAXLEN_ATTR+1]; char keybuf[SPI_MAXLEN_ITEM+1]; /* Allocate Search Request Object */ status= spiOABAlloc( sctx, SPI_OBJ_SEARCH_REQUEST, &srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Search OAB Alloc failed - Keyword Search, status = %d\n", status); fflush( logFile ); return(1); } //================================================================== // Build Select, Where, and Order and put in Search OAB // The SQL here is: // select kw_e_name kw_name from elem_kw where // kw_e_name = 'item id' and kw_name like '{MTISDM}' //================================================================== selectList[0] = SPI_KWRD_ITEM_ID; selectList[1] = SPI_KWRD_NAME; selectList[2] = 0; status = spiOABAttrPut( sctx, srOAB, SPI_SR_SHOW, selectList ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Select OABAttrPut Failed-Keyword, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } // If more than one file with the same name existed, more than 1 row // with {MTISDM} indicator would be returned, but fot the KBAT set of // files, there should be no duplicated filenames. whereClause[0].andOrStop = SPI_ANDOR_START; whereClause[0].nestingLevel = 0; whereClause[0].attrNo = SPI_KWRD_ITEM_ID; whereClause[0].relOp = SPI_RELOP_EQ; strcpy( whereClause[0].value, itemID); whereClause[1].andOrStop = SPI_ANDOR_AND; whereClause[1].nestingLevel = 0; whereClause[1].attrNo = SPI_KWRD_NAME; whereClause[1].relOp = SPI_RELOP_LK; strcpy( whereClause[1].value, "{MTISDM}*"); //whereClause[2].andOrStop = SPI_ANDOR_AND; //whereClause[2].nestingLevel = 0; //whereClause[2].attrNo = SPI_KWRD_NAME; //whereClause[2].relOp = SPI_RELOP_NL; //strcpy( whereClause[2].value, "{MTISDM}5*"); whereClause[2].andOrStop = SPI_ANDOR_STOP; whereClause[2].nestingLevel = 0; spiOABAttrPut( sctx, srOAB, SPI_SR_QUERY, whereClause ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Where OABAttrPut Failed-Keyword, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } /* Allocate Partial OAB to hold Search Request Results */ status= spiOABRowAlloc( sctx, srOAB, &rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " OAB Row Alloc Failed-Keyword, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } *keybuf = '\0'; // Issue Search - status will == 52 if the result set contains > 1 row. // Should just get 1 row status= spiQuerySearchRequest( sctx, srOAB, SPI_QUERY_FORWARD, keybuf, (unsigned long)1, &count, &qhnd ); if ((status == SPI_STS_MORE_ROWS)) { fprintf ( logFile, " Keyword Object Query Returned more than 1 row : Item is in more than 1 folder\n"); fflush( logFile ); //fprintf ( report, " ******Oops!! Item is in more than 1 folder - skip it. Count is %d\n", count); //fflush( report ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } if (status != SPI_STS_SUCCESS) { fprintf ( logFile, " spiQuerySearchRequest Failed-Keyword, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } status= spiQueryRow( sctx, (unsigned long)0, rowOAB, qhnd ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " spiQueryRow Failed-Keyword, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } // AttrGet return the value of the SPI_KWRD_NAME property of the object status = spiOABAttrGet( sctx, rowOAB, SPI_KWRD_NAME, keywordName, SPI_MAXLEN_ATTR+1 ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " attr get Failed-Keyword name, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } fprintf ( logFile, " Keyword Name : %s\n", keywordName); flushall(); strcpy ( parentKeyName, keywordName); extractParent( keywordName, parentNum); // isolate the folder number in parentNum fprintf ( logFile, " in keyword to get parent : %s\n", parentNum); fflush( logFile ); // FREE THE QUERY RESOURCES status= spiQueryDone( sctx, qhnd ); //FREE THE OAB'S status= spiOABFree( sctx, srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " OAB search Free Failed-Keyword, status = %d\n", status); fflush( logFile ); } status= spiOABFree( sctx, rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " OAB row Free Failed-Keyword, status = %d\n", status); fflush( logFile ); return(1); } return (0); } //end queryKeywordObject function //*********************************************************************************** // F U N C T I O N // // getFullPath // Get the full path of the item // Params: sctx - handle to the mezzanaine session // itemID - string holding the item's id number // &fullPath - pointer to the string of the full path // Function: // 1) // //*********************************************************************************** int getFullPath ( SPI_SCTX_HNDL sctx, char * itemID, char * fileName, char * parentNum, char * retParentName, char * fullPath ) { SPI_STATUS status; SPI_QUERY_HNDL qhnd; unsigned long count; SPI_OAB_HNDL srOAB; SPI_OAB_HNDL rowOAB; SPI_ATTR_NO selectList[SPI_MAX_QRY_SHOW]; SPI_QUERY_SELECTION whereClause[SPI_MAX_QRY_SELECTIONS]; int ptr; int i,j; char parentName[SPI_MAXLEN_STRING + 1]={""}; char parentNameLong[SPI_MAXLEN_ATTR + 1]={""}; char key[SPI_MAXLEN_STRING+1]; char path[50][300]; //array to hold the full path: 50, 300 char strings char whackwhack[3] = "\\"; char *pPtr; // ptr to short parent within long parent name int nameLen = 0; int firstTimeThru = 1; // null out the path array for ( i=0; i < 50; i++ ) { for ( j=0; j<300; j++ ) { path[i][j] = NULL; } } // put the filename in array position 0 strcpy(path[0],fileName); ptr=1; // Array pos 0 holds the filename. 1 and up will hold the folder names in the path. //=================================================================================== //Custom Object query. Build the full path, getting each successive parent folder. //=================================================================================== // while the parent num not = sdmroot while (strcmp(parentNum, "SDMROOT")) // returns 0 if the 2 strings are = { //Allocate Search Request Object status= spiOABAlloc( sctx, SPI_OBJ_SEARCH_REQUEST, &srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " CUSTOM OBJ SEARCH OAB Alloc failed, status = %d\n", status); fflush( logFile ); return(1); } //Build Select, Where, and Order and put in Search OAB selectList[0] = SPI_CO_ISV_ID; // Must include this in select on custom table!!!!! selectList[1] = SPI_CO_OBJECT_TYPE; selectList[2] = SPI_CO_KEY; // folder num selectList[3] = SPI_CO_STRING1; // key of the folder's parent selectList[4] = SPI_CO_STRING2; // folder name selectList[5] = SPI_CO_LONG_STRING1; // comment field in properties dialog box, holds long folder name selectList[6] = 0; // folder names in co-string1 & 2 limited to 32 chars spiOABAttrPut( sctx, srOAB, SPI_SR_SHOW, selectList ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Select OABAttrPut Failed-Custom, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } whereClause[0].andOrStop = SPI_ANDOR_START; whereClause[0].nestingLevel = 0; whereClause[0].attrNo = SPI_CO_KEY; whereClause[0].relOp = SPI_RELOP_EQ; strcpy( whereClause[0].value, parentNum); whereClause[1].andOrStop = SPI_ANDOR_STOP; whereClause[1].nestingLevel = 0; spiOABAttrPut( sctx, srOAB, SPI_SR_QUERY, whereClause ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Where OABAttrPut Failed-Custom, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } // Allocate Partial OAB to hold Search Request Result set status= spiOABRowAlloc( sctx, srOAB, &rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " ROW OAB Alloc Failed-Custom , status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } // Issue Search - status will == 52 if the result set contains > 1 row. // Should just get 1 row status= spiQuerySearchRequest( sctx, srOAB, SPI_QUERY_FORWARD, NULL, (unsigned long)100, &count, &qhnd ); if ((status == SPI_STS_MORE_ROWS)) { fprintf ( logFile, " Custom Object Query Returned more than 1 row, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } if (status != SPI_STS_SUCCESS) { fprintf ( logFile, " Custom Query Search Request Failed, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } // GOOD SELECT. NOW ACCESS THE DATA AND ADD IT TO THE PATH status= spiQueryRow( sctx, (unsigned long)0, rowOAB, qhnd ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " spiQueryRow Failed-Custom, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } // CALL AttrGet TO GET THE VALUES OF THE 4 SELECTED PROPERTIES OF THE CUSTOM OBJECT spiOABAttrGet( sctx, rowOAB, SPI_CO_KEY, key, SPI_MAXLEN_STRING + 1 ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " spiAttrGet Failed-SPI_CO_KEY, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } fprintf ( logFile, " Key : %s\n", key); flushall(); spiOABAttrGet( sctx, rowOAB, SPI_CO_STRING1, parentNum, SPI_MAXLEN_STRING + 1 ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " spiAttrGet Failed-SPI_CO_STRING1, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } fprintf ( logFile, " Parent # Str1 : %s\n", parentNum); flushall(); spiOABAttrGet( sctx, rowOAB, SPI_CO_STRING2, parentName, SPI_MAXLEN_STRING + 1 ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " spiAttrGet Failed-SPI_CO_STRING2, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } fprintf ( logFile, " Parent Name Str2 : %s\n", parentName); flushall(); // BB 5/25/1999 // first time thru the whiule loop, it gets the folder where the file resides, ie the end of the path // before the file name. Return this value to the calling function. if ( firstTimeThru ) { strcpy (retParentName , parentName ); firstTimeThru = 0; } spiOABAttrGet( sctx, rowOAB, SPI_CO_LONG_STRING1, parentNameLong, SPI_MAXLEN_ATTR + 1 ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " spiAttrGet Failed-SPI_CO_STRING2, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } fprintf ( logFile, " Parent Name long: %s\n", parentNameLong ); flushall(); // Put the folder name in the path array // If the folder has a name longer than 32 chars, the full name (not truncated at 32) is in the // co_long_string1 column of the custom table. This field is accessed by the users as the comment // field in ghe folder properties dialog box. // We do a strstr here to see if the short name is in the long name filed as a way to check // if there is anything in the long name field. That way, if someone types something in the // comment field as a comment , we wont mistake it for a long file name. // if there is a long file name, use it, instead of the truncated name, to build the path. pPtr = strstr(parentNameLong, parentName ); // pPtr points to short parent in the string if ( pPtr == NULL ) { strcpy(path[ptr], parentName); ptr++; } else { nameLen = strlen(parentNameLong); strcpy(path[ptr], parentNameLong); ptr++; } //CLOSE QUERY AND FREE RESOURCES status= spiQueryDone( sctx, qhnd ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " query done Failed-Custom, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } //FREE THE OAB RESOURCES status= spiOABFree( sctx, srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Search OAB Free Failed-Custom, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, rowOAB ); return(1); } status= spiOABFree( sctx, rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, " Row OAB Free Failed-Custom, status = %d\n", status); fflush( logFile ); return(1); } } // LOOP TO TOP IF NOT AT THE ROOT OF THE PATH YET //FREE THE OAB RESOURCES //status= spiOABFree( sctx, srOAB ); //if ( status!= SPI_STS_SUCCESS ) { // fprintf ( logFile, " Search OAB Free Failed-Custom, status = %d\n", status); // fflush( logFile ); // spiOABFree( sctx, rowOAB ); // return(1); //} // status= spiOABFree( sctx, rowOAB ); // if ( status!= SPI_STS_SUCCESS ) { // fprintf ( logFile, " Row OAB Free Failed-Custom, status = %d\n", status); // fflush( logFile ); // return(1); // } // BUILD THE FULL PATH FROM THE PATH ARRAY ptr--; for ( i=ptr; i>-1; i-- ) { strcat( fullPath, path[i] ); if ( i > 0 ) { strcat( fullPath, whackwhack ); } } fprintf ( logFile, " Full path : %s\n", fullPath); fflush( logFile ); return (0); } // getFullPath function end //*********************************************************************************** // F U N C T I O N // // extractParent // // extracts the folder number from the property SPI_KWRD_NAME // The string will have "{MTISDM}7", the 7 being the folder number, which // is extracted by this function. //*********************************************************************************** int extractParent(char * keywordName, char * parentNum) { int i; int j = 0; // string manipulation code to isolate the folder num from the {MTISDM} string // initialize the string for (i=0; i<10;i++) { parentNum[i] = 32; } i=0; // find the beginning of where the number is - I know this will always be 8 // but what the heck. Maybe it'll change someday. while ( keywordName[i] != '}' ) // count chars till } of {MTISDM} { i++; } i++; // move the value char by char to the folderNum string and return it while ( keywordName[i] != NULL ) //till a space is encountered { parentNum[j] = keywordName[i]; i++; j++; } parentNum[j] = '\0'; return (0); } // end of function //*********************************************************************************** // F U N C T I O N // // expireTheFile // // Params: sctx - handle to the mezzanine session // &parentKeyName, a string ptr containing the parent folder's key value // eg. {MTSIDM}567 // &parentNum - key of the parent eg 567 // &parentName - folder name of the parent folder // itemID - the item id of the document to be expired // // // Remove the file from it's parent directory and put it in It's corresponding // expired (DEAD) directory. // The whole INFO structure has a corresponding DEAD structure where expired // files go to rest in peace. // // //********************************************************************************** int expireTheFile(SPI_SCTX_HNDL sctx, char * itemID, char * parentKeyName, char * parentNum, char * parentName, char * fullPath ) { SPI_STATUS status; SPI_OAB_HNDL keywordOAB; char kwName[SPI_MAXLEN_KEY+1] = ""; char delKey[SPI_MAXLEN_KEY+1] = ""; char szKeyword[SPI_MAXLEN_ATTR+1] = ""; int x; char strParentNum[10] = ""; char folderName[32] = "DEAD"; //build the keyword for the DEAD folder strcpy(szKeyword, "{MTISDM}"); //keyword for a folder strarts with "MTISDM" // BB 6/1/99 comment out the next 3 lines //x = atoi(parentNum); //convert string to an int //x = x + 5000; //a folder's corresponding Dead folder has the same key + 5000 in Mezz //itoa( x, strParentNum, 10 ); // convert back to an int //replace above 3 lines with function call which gets the number of the folder. This way DEAD folders no longer will need // A little history about this change. When a file is expired by web update, it is added to the DEAD folder corresponding to its // live folder, and deleted from the live folder. I thought it would be nice to be able to locate the DEAD folder simply by // adding a number to the folder number of the live folder. // Web update has the live folder number already and a simple add would be easy and quick. // To accomplish this, all DEAD folders needed to be added to the system with // folder numbers = thier live counterparts + a Number (5000 I chose). All's well except the only way to add a folder to the system // and be able to dictate the number it is assigned is to use a c program using the mezz api. If you use the IDM desktop // to add a folder, the system assigns a number to it. When I did the big conversion I added all the folders using a program I wrote, // but any new folders KBAT wants to add, subsequent to the conversion, need to added using the folder add utility I wrote // using the c api. This is a pain and KBAT should have access to the folder add functionality in the IDM desktop. // So I'm fixing this flaw, and adding code here to go and get the DEAD folder number based on the live folder name. // The getFoldewrNum function is the new function. Notice folderNmae is initialized with "DEAD" and the live folder name is // concatenated to it. strcat ( folderName, parentName ); status = getFolderNum ( sctx, folderName, strParentNum ); strcat(szKeyword, strParentNum); // tack folder key onto the keyword // Allocate the keyword OAB status = spiOABAlloc(sctx, SPI_OBJ_KEYWORD, &keywordOAB); if ( status!= SPI_STS_SUCCESS ) { fprintf( logFile, " !!OAB alloc went wrong! status = %d \n", status ); flushall(); return(1); } //fill Keyword OAB with ItemID and Keyword before adding the object status = spiOABAttrPut(sctx, keywordOAB, SPI_KWRD_ITEM_ID, itemID); if ( status!= SPI_STS_SUCCESS ) { fprintf( logFile, " SPI_KWRD_ITEM_ID Put went wrong! status = %d \n", status); flushall(); spiOABFree( sctx, keywordOAB ); return(1); } status = spiOABAttrPut(sctx, keywordOAB, SPI_KWRD_NAME, szKeyword); if ( status!= SPI_STS_SUCCESS ) { fprintf( logFile, " SPI_KWRD_NAME Put went wrong! status = %d \n", status); flushall(); spiOABFree( sctx, keywordOAB ); return(1); } //Add the object - PUT THE FILE IN THE EXPIRED (DEAD) FOLDER status = spiObjectAdd(sctx, keywordOAB); if ( status!= SPI_STS_SUCCESS ) { fprintf( logFile, " OAB Add went wrong! status = %d \n", status); flushall(); spiOABFree( sctx, keywordOAB ); return(1); } else { fprintf( logFile, " File Added to DEAD folder. Status = %d \n", status); flushall(); } // Build the key for the Object delete call and do the delete from parent folder status = spiKeyBuild ( sctx, delKey, sizeof(delKey), (char SPI_DFAR *) itemID, (char SPI_DFAR *) parentKeyName, (char SPI_DFAR *) NULL); if ( status!= SPI_STS_SUCCESS ) { fprintf( logFile, " Key Build Failed B4 Delete-Keyword, status = %d\n", status); flushall(); spiOABFree( sctx, keywordOAB ); return(1); } status = spiObjectDelete(sctx, SPI_OBJ_KEYWORD, delKey); if ( status!= SPI_STS_SUCCESS ) { fprintf( logFile, " Object Delete Failed-Keyword, status = %d\n", status); flushall(); spiOABFree( sctx, keywordOAB ); return(1); } // FREE THE QUERY RESOURCES //FREE THE OAB status= spiOABFree( sctx, keywordOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf( logFile, " OAB search Free Failed-Keyword, status = %d\n", status); flushall(); return(1); } return(0); } //*********************************************************************************** // F U N C T I O N // // getSystemTime // // Params: runTime - pointer to the string which will hold the date in the // filenet format : 1997-02-01T13:05:09 // //********************************************************************************** int getSystemTime ( char * runTime, char * fileNameTime) { char yr[8]; char mon[8]; char day[8]; char min[8]; char hr[8]; char sec[8]; time_t timer; struct tm *sys_time; time(&timer); sys_time = localtime(&timer); // Convert the ints to strings itoa(sys_time->tm_year,yr,10); sys_time->tm_mon++; //month is 0 based, 0-11, so add 1 itoa(sys_time->tm_mon,mon,10); itoa(sys_time->tm_mday,day,10); itoa(sys_time->tm_hour,hr,10); itoa(sys_time->tm_min,min,10); itoa(sys_time->tm_sec,sec,10); // Year 2000 windowing if (sys_time->tm_year > 50) strcpy(runTime, "19"); else strcpy(runTime, "20"); // Build the date string in filenet format from the date pieces in the tm structure strcat(runTime, yr); strcat(runTime, "-"); if (sys_time->tm_mon < 10) { strcat(runTime, "0"); } strcat(runTime, mon); strcat(runTime, "-"); if (sys_time->tm_mday < 10) { strcat(runTime, "0"); } strcat(runTime, day); strcat(runTime, "T"); if (sys_time->tm_hour < 10) { strcat(runTime, "0"); } strcat(runTime, hr); strcat(runTime, ":"); if (sys_time->tm_min < 10) { strcat(runTime, "0"); } strcat(runTime, min); strcat(runTime, ":"); if (sys_time->tm_sec < 10) { strcat(runTime, "0"); } strcat(runTime, sec); // The time is appended to the output file names so during successive runs they arent // overwritten. // Same code Again for the fileNameTime colons are'nt legal chars for use in filenames. Use underscore. if (sys_time->tm_year > 50) strcpy(fileNameTime, "19"); else strcpy(fileNameTime, "20"); strcat(fileNameTime, yr); strcat(fileNameTime, "-"); if (sys_time->tm_mon < 10) { strcat(fileNameTime, "0"); } strcat(fileNameTime, mon); strcat(fileNameTime, "-"); if (sys_time->tm_mday < 10) { strcat(fileNameTime, "0"); } strcat(fileNameTime, day); strcat(fileNameTime, "T"); if (sys_time->tm_hour < 10) { strcat(fileNameTime, "0"); } strcat(fileNameTime, hr); strcat(fileNameTime, "_"); // underscore used for use in filename if (sys_time->tm_min < 10) { strcat(fileNameTime, "0"); } strcat(fileNameTime, min); strcat(fileNameTime, "_"); if (sys_time->tm_sec < 10) { strcat(fileNameTime, "0"); } strcat(fileNameTime, sec); return (0); } // End of getSystemDate Fucntion /************************************************************************************************** processMetaData : 2 properties in the Document Management system : Keywords and answer subject need to be in the text of the html file as meta data. 1. Reads the html file looking for the meta data tag name, ie answer-subject. 2. If it's not there, rewrite the file & insert it, with the value of the property. 3. if it is there - is it the same as the property value from the doc management system? (has it changed) - if the same, get out - nothing to do - if different, rewite the file with the new data. A problem here is that the answwr subject meta tag is different from the others. It is in a form as a hidden property. This difference is enough to require separate processing if the property being dealt with is the ans sub. Watch for this in the code. Rewriting the html file means write it to a temp file, delete the old and rename the temp to the name of the old. ***************************************************************************************************/ int processMetaData(char * fullPath, char * metaTag, int numToSkip, char * propVal) { char inChar; char inString[5000] = ""; // Hopefully there's not a string longer than 5000 chars out there char tstString[100] = ""; int ptr,i; int retVal = 0; char *cPtr; char metaVal[256]; int status = 0; int gotIt = 0; int updatedFlag = 0; char tempPath[200] = "c:\\temp\\webUpdateTemp.html"; char tempOld[200] = "c:\\temp\\theOldFile.html"; // Only have a meta tag string to add for keywords. Answer Subject tag is much longer and is // dealt with in a separate function. This is needed if the tag is not already in the file // and needs to be inserted. char keywordString[254] = "<META NAME=\"keywords\" CONTENT=\""; // keywords meta tag unsigned long dummy; ptr = 0; fprintf ( logFile, " Processing meta data for : %s\n", metaTag ); fflush( logFile ); FILE *htmlFile; htmlFile = fopen(fullPath,"r"); // I use fgetc instead of fgets so I can count the characters as they come in and be sure I know // if a string > 5000 chars exists. With fgets, you need to specify a string length and it won't // tell you the length of the string actully returned. while ( (inChar = fgetc(htmlFile) ) != EOF && gotIt == 0 && ptr < 5000)// Get chars one at a time { if (inChar == 10) // is it a line feed? ascii code for LF line feed { ptr = 0; cPtr = strstr(inString, metaTag); // cPtr points to meta tag in the string if !NULL if ( cPtr == NULL ) // meta tag not found in the string { for (i=0; i<5000; i++) // Null the string for next line inString[i] = NULL; } else { fprintf ( logFile, " Got the html line with the meta tag. Now get the value of the meta data.\n"); fflush( logFile ); gotIt = 1; for ( i = 0; i < 256; i++ ) // initailize to nulls metaVal[i] = NULL; cPtr = strstr(inString, metaTag); // now look for value of metaTag cPtr = cPtr + numToSkip; // skip from the tag to the value to isolate it ptr = 0; while ( cPtr[ptr] != 34 && ptr < 256) // 34 is a double quote { metaVal[ptr] = cPtr[ptr]; // copy the value to variable from the string ptr ++; } if (ptr > 254) { fprintf ( logFile, " BAD or too long meta data value from html file. Length limit = 254\n"); fflush( logFile ); } fprintf ( logFile, " **Doc meta val : %s **Mezz Val : %s\n", metaVal, propVal); fflush( logFile ); if ( (strcmp (metaVal, propVal)) && (ptr < 254)) // has value changed? { //replace old with new - need to rewrite the whole file status = updateFile( htmlFile, fullPath, metaTag, numToSkip, metaVal, propVal); if (status == 1) { retVal = 1; fprintf ( logFile, " ERROR Updating meta data \n"); fflush( logFile ); } else { fprintf ( logFile, " Changed %s to %s\n", metaVal, propVal); fflush( logFile ); } updatedFlag = 1; } // already there and current - do notihing Close and get out else { fprintf ( logFile, " No changes to be made for %s \n", metaTag); fflush( logFile ); } // end of has value changed if statement } // end of the code dealing with fact that the meta string was found in the current string } // not a line feed. else // add the character to the string and bump the pointer to get the next character { inString[ptr] = inChar; ptr ++; } } // end of big while loop which loops thru the html doc, char by char looking for the meta tag if (ptr > 4999) { fprintf ( logFile, " *** 5000 HTML file str limit reached!! Bad chars in it probably. File not processed. \n"); fflush( logFile ); retVal = 9; } if (gotIt == 0) { // If control is here it means the meta data tag was not found in the document and needs to be // added. KBAT uses a template for all their files which includes all // meta data tags but keywords and answer subject. // So, only code for these 2 properties. // The answer sub mata tag is really more than a tag: it's a hidden form. // Since the html code for a form spans several lines and each need a line feed, // I used a separate string variable for each line, and stuck them in the insertAnsSub // function. The function call for the ans sub insertion contains the property value // instead of the meta tag. The property value is contacenated to the appropriate html // line in the insertMetaData function. if (strstr(metaTag, "ANSWER") ) { fprintf ( logFile, " Inserting Answer Sub Tag. Value : %s\n", propVal); fflush( logFile ); status = insertMetaData( htmlFile, propVal, "/BODY"); } else if (strstr(metaTag, "EFFECTIVE") ) { char keywordString[254] = "<META NAME=\"EFFECTIVE-DATE\" CONTENT=\""; strcat( keywordString, propVal); strcat( keywordString, "\""); // tack on a dbl quote strcat( keywordString, ">"); // tack on a > tag delimiter // rewrite the html file and insert keyword string before the line // that contains the letters /HEAD fprintf ( logFile, " Inserting EFFECTIVE DATE Tag. Value : %s\n", propVal); fflush( logFile ); status = insertMetaData( htmlFile, keywordString, "/HEAD"); } else if (strstr(metaTag, "keywords") ) { strcat( keywordString, propVal); strcat( keywordString, "\""); // tack on a dbl quote strcat( keywordString, ">"); // tack on a > tag delimiter // rewrite the html file and insert keyword string before the line // that contains the letters /HEAD fprintf ( logFile, " Inserting keywords Tag. Value : %s \n", propVal); fflush( logFile ); status = insertMetaData(htmlFile, keywordString, "/HEAD"); } if (status == 0) { updatedFlag = 1; } else { retVal = status; // flow will fall to the end of the function - return bad code fprintf ( logFile, " ERROR Updating meta data \n"); fflush( logFile ); } } // end of if got it id stmt - where inserting of meta tags is called fclose(htmlFile); // Now whether the mata data was inserted new or updated, we need to delete the html file with out the change, // and rename the temp html file , that contains the change, to the original file name. //printf(" stop here for test - rename %s to something and hit enter to continue \n", tempPath ); //getchar(); if (updatedFlag == 1) { retVal = 0; //i = remove (fullPath); i = rename ( fullPath, tempOld ); // backup the orig file if the following rename goes bad if (i == 0) { fprintf ( logFile, " Old file renamed to theOldFile.html. Now rename %s to %s\n", tempPath, fullPath); fflush( logFile ); for ( dummy=0; dummy < 65000; dummy++ ) // execute a for loop here to waste some time. Timing issue with rename. { killTime(); } i = rename( tempPath, fullPath ); if (i == 0) { fprintf ( logFile, " Temp html file renamed.\n"); fflush( logFile ); i = remove (tempOld); // Successful temp to full rename so get rid of the backup original file } else { fprintf ( logFile, " ERROR : Temp html file NOT renamed. Ret Code : %d. TRY AGAIN\n", i ); fflush( logFile ); i = rename( tempPath, fullPath); // try again if ( i != 0 ) { fprintf ( logFile, " Second try at renaming was also unsuccessful.\n"); fflush( logFile ); i = rename ( tempOld, fullPath ); // Restore the old file back retVal = 9; } else { fprintf ( logFile, " Second try at renaming was successful.\n"); fflush( logFile ); i = remove (tempOld); retVal = 0; } } } else { fprintf ( logFile, " ERROR : Old html file NOT removed. Skipping this file.\n"); fflush( logFile ); retVal = 9; } } return (retVal); } //end insert metaTag function /******************************************************************************* update file function copy contents of the file to a new file replacing the value of the metaTag with the new value. A new file is created with the new prop value. *********************************************************************************/ int updateFile(FILE * htmlFile, char * fullPath, char * propName, int numToSkip, char * oldVal, char * newVal) { int i; char inChar; char newName[200]= ""; int ptr = 0; char inString[5000] = ""; char *cPtr; int quoteCnt = 0; int newLen = 0; int numQuotes = 3; // initialize for keywords property FILE * oFile; oFile = fopen("c:\\temp\\webUpdateTemp.html","w"); if ( oFile == NULL ) { fprintf ( logFile, " Error opening temp file in updateFile function.\n" ); fflush( logFile ); fprintf ( report, " ERROR opening temp file. Skipping this file!!!!!\n" ); fflush( report ); return (1); } fprintf ( logFile, " Updating %s. Old : %s New : %s\n", propName, oldVal, newVal); fflush( logFile ); rewind ( htmlFile ); // back to the top of the file while ( (inChar = fgetc(htmlFile) ) != EOF )// Get chars one at a time { if (inChar == 10) // is it a line feed? ascii code for LF line feed { ptr = 0; cPtr = strstr(inString,propName); // is the meta data in this string? if ( cPtr == NULL ) // meta data not found in the string { fputs ( inString, oFile); // write the string to output file fputc( 10, oFile); // write a line feed for (i=0; i<5000; i++) // Null the input string for next line inString[i] = NULL; } else { cPtr = strstr(inString, propName); // now look for value of property cPtr = cPtr + numToSkip; // cPtr points to 1st char of meta data value // Now write inString to out file char by char till the prop value i=0; quoteCnt = 0; if ( strstr ( propName, "ANSWER") ) { numQuotes = 5; // I know this stinks - count 5 quotes for ans sub insertion } while (quoteCnt < numQuotes) { fputc( inString[i], oFile ); if (inString[i] == 34) quoteCnt++; i++; } // Then write the meta value followed by dbl quote and > sign & LF newLen = strlen( newVal); i = 0; while (i < newLen) { fputc( newVal[i], oFile ); i++; } fputc( 34 , oFile); // dbl quote fputc( 62 , oFile); // > sign fputc( 10 , oFile); // line feed fflush(oFile); for (i=0; i<5000; i++) // Null the string for next line inString[i] = NULL; } // end of else - meta data not in this string } // not a line feed else // add the character to the input string and bump the pointer { inString[ptr] = inChar; ptr ++; } } // end of fgetc while loop fclose( oFile); return (0); } // end of function /******************************************************************************* insert Meta Data args: ptr to html file copy contents of the file to a new file and insert the meta data string after the string containing the search string is found A new file is created with the new meta data tag inserted in its place *********************************************************************************/ int insertMetaData(FILE * htmlFile, char * metaString, char * beforeString) { int i; char inChar; char newName[200]= ""; int ptr = 0; char inString[5000] = ""; char *cPtr; int quoteCnt = 0; int newLen = 0; int gotIt = 0; FILE * oFile; oFile = fopen("c:\\temp\\webUpdateTemp.html","w"); if ( oFile == NULL ) { fprintf ( logFile, " Error opening temp file in insertMetaData\n" ); fflush( logFile ); fprintf ( report, " ERROR opening temp file. Skipping this file!!!!!\n" ); fflush( report ); return (1); } fprintf ( logFile, " Inserting %s\n", metaString); fflush( logFile ); rewind ( htmlFile ); // back to the top while ( (inChar = fgetc(htmlFile) ) != EOF )// Get chars one at a time { if (inChar == 10) // is it a line feed? ascii code for LF line feed { ptr = 0; cPtr = strstr( inString, beforeString ); // is this the before string ? if ( cPtr != NULL ) // yes. Insert meta tag b4 copying string to output { gotIt = 1; cPtr = strstr( beforeString, "BODY" ); // Do diff for ans sub if ( cPtr == NULL ) cPtr = strstr( beforeString, "body" ); // could be lower case if ( cPtr != NULL ) { insertAnsSub( oFile, metaString, inString ); // special ans sub routine } else // not ans sub meta tag { // normal style meta tag - like keywords fputs( metaString, oFile); // write the meta tag to output file fputc( 10, oFile); // write a line feed fputs ( inString, oFile); // ok the meta tag is in, now write the before string fputc( 10, oFile); // write a line feed } } // not the before string, so just write it else { fputs ( inString, oFile); // ok the meta tag is in, now write the before string fputc( 10, oFile); } for (i=0; i<5000; i++) // Null the input string for next line inString[i] = NULL; } else // not a line feed - add the character to the string and bump the pointer { inString[ptr] = inChar; ptr ++; } } // end of fgetc while loop fclose( oFile); if (gotIt == 0) { fprintf ( logFile, " Insertion failed. Before string : %s, not in html file.\n", beforeString); fflush( logFile ); } return (0); } // end of function /********************************************************************************************************************* Answer Sub is a special case of insert meta data, because it needs to be inserted in the middle of an existing line, not before a whole line. Also, it's not a 1 line html tag but a form requiring several lines of code to be inserted. */ int insertAnsSub( FILE * oFile, char * ansSubVal, char * inString) { int i; int pos; int sLen; char ansSub1[7] = "<FORM>"; char ansSub2[4] = "<P>"; char ansSub3[100] = "<INPUT TYPE=\"HIDDEN\" NAME=\"BEGIN HIDDEN FORM\" VALUE=\"BAHR AUTHORING PROPERTIES\">"; char ansSub4[150] = "<INPUT TYPE=\"HIDDEN\" NAME=\"ANSWER-SUBJECT\" VALUE=\""; char ansSub5[12] = "</P></FORM>"; fflush ( oFile); strcat ( ansSub4, ansSubVal); // complete line 4 with the ans sub value strcat ( ansSub4, "\">"); // find position in string where the </BODY> tag is sLen = strlen(inString); for ( i=2; i<sLen; i++ ) { if ( (inString[i] == 'O' || inString[i] == '0') && (inString[i-1] == 'B' || inString[i-1] == 'b') && (inString[i-2] == '/') ) pos = i; } pos = pos - 3; // back up 3 to the beginning of <BODY> for (i=0; i<pos; i++) // write up to the </BODY> tag { putc(inString[i], oFile); } // then write the answer sub form fputc( 10, oFile); // line feed fputs( ansSub1, oFile); // write the meta tag to output file fputc( 10, oFile); fputs( ansSub2, oFile); // write the meta tag to output file fputc( 10, oFile); fputs( ansSub3, oFile); // write the meta tag to output file fputc( 10, oFile); fputs( ansSub4, oFile); // write the meta tag to output file fputc( 10, oFile); fputs( ansSub5, oFile); // write the meta tag to output file for (i=pos; i<sLen; i++) // finish up the end of the inString { putc(inString[i], oFile); } fputc( 10, oFile); // lay a line feed at the end return (0); // later } // end of function insertAnsSub //*********************************************************************************** // F U N C T I O N // // convert date from filenet to mm/dd/yyyy format // // Params: 0123456789 // filenet format : 1997-02-01T13:05:09 - date // yyyy mm dd // mm dd yyyy // format : 01/02/1998 - date // 0123456789 //********************************************************************************** int changeDateFormat( char* filenetDate, char * date ) { date[0] = filenetDate[5]; date[1] = filenetDate[6]; date[2] = '/'; date[3] = filenetDate[8]; date[4] = filenetDate[9]; date[5] = '/'; date[6] = filenetDate[0]; date[7] = filenetDate[1]; date[8] = filenetDate[2]; date[9] = filenetDate[3]; return (0); } /*************************************************************************************************** editFullPath In the IIS structure, the INFO folder sits under the path : C:\\srvapps\\Inetsrv\\WWWRoot\\Self_Serv\\ In IDM, (MEZZ), INFO is the root, ie there is no C:\\srvapps\\Inetsrv\\WWWRoot\\Self_Serv\\. To compare the location (path), of a file between the 2 enviroments, this string ( path piece ), needs to be stripped off the IIS path. ***************************************************************************************************/ int editFullPath( char* fullPath, char * halfPath ) { int i; int j; // initialize the half path value for ( i=0; i < 300; i++) halfPath[i] = NULL; j = 37; // skip to the INFO folder in the path i = 0; while ( fullPath[j] !=NULL ) { halfPath[i] = fullPath[j]; j++; i++; } return (0); } void killTime() { int status; char runTime[22]; char fileNameTime[22]; status = getSystemTime( runTime, fileNameTime ); } //////////////////////////////////////////////////////////////////////////////////////////// // getFolderNum // When a user adds a folder using IDM desktop, Mezzanine assigns it a number. // The folder is recorded in the data base in the custom table, and the folder number // is in the co_key column. // This function finds the folder number of a folder for which the name is known. // Calling func sends in a folder name and this function returns the folder's number. // // /////////////////////////////////////////////////////////////////////////////////////////// int getFolderNum ( SPI_SCTX_HNDL sctx, char * folderName, char * folderNum ) { //SPI_SCTX_HNDL sctx; SPI_STATUS status; SPI_QUERY_HNDL qhnd; unsigned long count; SPI_OAB_HNDL srOAB; SPI_OAB_HNDL rowOAB; unsigned long ii; SPI_ATTR_NO selectList[SPI_MAX_QRY_SHOW]; SPI_QUERY_SELECTION whereClause[SPI_MAX_QRY_SELECTIONS]; int isMoreRows; int firstRow; char keybuf[SPI_MAXLEN_ITEM + 1]; char coKey[SPI_MAXLEN_STRING + 1]; int i = 0; char name[32] = ""; //make sure folder name is 32 chars or less, as that is the upper limit for folder names imposed // by mezzanine software. strncpy ( name, folderName, 32 ); //OAB ALLOCATE FOR SEARCH REQUEST OBJECT status= spiOABAlloc( sctx, SPI_OBJ_SEARCH_REQUEST, &srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Search OAB Alloc . Going EOJ. status = %d\n", status); fflush( logFile ); return(1); } //BUILD THE SELECT, WHERE AND ORDER CLAUSES FOR THE QUERY selectList[0] = SPI_CO_ISV_ID; selectList[1] = SPI_CO_OBJECT_TYPE; selectList[2] = SPI_CO_KEY; selectList[3] = SPI_CO_STRING2; selectList[4] = 0; status = spiOABAttrPut( sctx, srOAB, SPI_SR_SHOW, selectList ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrPut Failed-Select , status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } whereClause[0].andOrStop = SPI_ANDOR_START; whereClause[0].nestingLevel = 0; whereClause[0].attrNo = SPI_CO_STRING2; whereClause[0].relOp = SPI_RELOP_EQ ; strcpy(whereClause[0].value, name); whereClause[1].andOrStop = SPI_ANDOR_STOP; whereClause[1].nestingLevel = 0; status = spiOABAttrPut( sctx, srOAB, SPI_SR_QUERY, whereClause ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OABAttrPut Failed-Where , status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } //PARTIAL OAB ALLOCATE FOR THE SEARCH REQUEST OBJECT status= spiOABRowAlloc( sctx, srOAB, &rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Search OAB Row Alloc Failed, status = %d\n", status); fflush( logFile ); spiOABFree( sctx, srOAB ); return(1); } //===================================================================== //ISSUE THE SEARCH - *keybuf = '\0'; firstRow = 0; //ISSUE THE SEARCH. status= spiQuerySearchRequest( sctx, srOAB, SPI_QUERY_FORWARD, keybuf, (unsigned long)200, &count, &qhnd ); if ((status != SPI_STS_SUCCESS) && (status != SPI_STS_MORE_ROWS)) { fprintf ( logFile, "Query Search Request Failed-Folder Number search, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } isMoreRows = (status == SPI_STS_MORE_ROWS); fprintf ( logFile, "Rows found-folder num search: %d%s\n", count, ((firstRow == 0)? "" : " (Note: Not displaying first row)") ); fflush( logFile ); // Get the row status= spiQueryRow( sctx, ii, rowOAB, qhnd ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "QueryRow Failed-Effective Date search, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } // Get the values of the folder number (CO_KEY) prop of the item. status = spiOABAttrGet( sctx, rowOAB, SPI_CO_KEY, coKey, SPI_MAXLEN_STRING + 1 ); strcpy ( folderNum, coKey ); fprintf ( logFile, "folderNumber is : %s \n", coKey ); fflush( logFile ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "Attr Get Failed-Effective Date search, status = %d\n", status); fflush( logFile ); spiQueryDone( sctx, qhnd ); spiOABFree( sctx, srOAB ); spiOABFree( sctx, rowOAB ); return(1); } //IF MORE ROWS, GET ANOTHER RESULT SET CONTAINING UP TO 100 ROWS. if (isMoreRows) { /* start next search from end of this one */ spiOABAttrGet(sctx, rowOAB, SPI_ITEM_ID, keybuf, SPI_MAXLEN_ITEM+1); firstRow = 1; } // CLOSE THE QUERY AND RELEASE RESOURCES status= spiQueryDone( sctx, qhnd ); //FREE THE OAB'S status= spiOABFree( sctx, srOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OAB Free Failed, status = %d\n", status); fflush( logFile ); return(1); } status= spiOABFree( sctx, rowOAB ); if ( status!= SPI_STS_SUCCESS ) { fprintf ( logFile, "OAB Free Failed, status = %d\n", status); fflush( logFile ); return(1); } return (0); } // end getFolderNum function