31 #if !defined(NO_PERSISTENCE) 39 #if defined(_WIN32) || defined(_WIN64) 42 #define strtok_r( A, B, C ) strtok( A, B ) 43 int keysWin32(
char *,
char ***,
int *);
44 int clearWin32(
char *);
45 int containskeyWin32(
char *,
char *);
50 int keysUnix(
char *,
char ***,
int *);
64 int pstopen(
void **handle,
const char* clientID,
const char* serverURI,
void*
context)
70 char *save_ptr = NULL;
71 char *pCrtDirName = NULL;
72 char *pTokDirName = NULL;
73 char *perserverURI = NULL, *ptraux;
77 if ((perserverURI =
malloc(strlen(serverURI) + 1)) == NULL)
82 strcpy(perserverURI, serverURI);
83 while ((ptraux = strstr(perserverURI,
":")) != NULL)
87 clientDir =
malloc(strlen(dataDir) + strlen(clientID) + strlen(perserverURI) + 3);
94 sprintf(clientDir,
"%s/%s-%s", dataDir, clientID, perserverURI);
102 if ((pCrtDirName = (
char*)
malloc(strlen(clientDir) + 1)) == NULL)
109 if ((pTokDirName = (
char*)
malloc( strlen(clientDir) + 1 )) == NULL)
117 strcpy( pTokDirName, clientDir );
120 if (*pTokDirName ==
'/' || *pTokDirName ==
'\\')
122 *pCrtDirName = *pTokDirName;
123 pToken = strtok_r( pTokDirName + 1,
"\\/", &save_ptr );
124 strcpy( pCrtDirName + 1, pToken );
128 pToken = strtok_r( pTokDirName,
"\\/", &save_ptr );
129 strcpy( pCrtDirName, pToken );
133 pToken = strtok_r( NULL,
"\\/", &save_ptr );
134 while ( (pToken != NULL) && (rc == 0) )
137 strcat( pCrtDirName,
"/" );
138 strcat( pCrtDirName, pToken );
140 pToken = strtok_r( NULL,
"\\/", &save_ptr );
162 #if defined(_WIN32) || defined(_WIN64) 163 if ( _mkdir( pPathname ) != 0 )
167 #if !defined(_WRS_KERNEL) 168 if ( mkdir( pPathname, S_IRWXU | S_IRGRP ) != 0 )
170 if ( mkdir( pPathname ) != 0 )
174 if ( errno != EEXIST )
187 int pstput(
void* handle,
char* key,
int bufcount,
char* buffers[],
int buflens[])
190 char *clientDir = handle;
193 size_t bytesWritten = 0,
198 if (clientDir == NULL)
213 fp = fopen(file,
"wb");
216 for(i=0; i<bufcount; i++)
218 bytesTotal += buflens[i];
219 bytesWritten += fwrite(buffers[i],
sizeof(
char), buflens[i], fp );
226 if (bytesWritten != bytesTotal)
243 int pstget(
void* handle,
char* key,
char** buffer,
int* buflen)
247 char *clientDir = handle;
248 char *filename = NULL;
250 unsigned long fileLen = 0;
251 unsigned long bytesRead = 0;
254 if (clientDir == NULL)
268 fp = fopen(filename,
"rb");
272 fseek(fp, 0, SEEK_END);
274 fseek(fp, 0, SEEK_SET);
275 if ((buf = (
char *)
malloc(fileLen)) == NULL)
280 bytesRead = (int)fread(buf,
sizeof(
char), fileLen, fp);
283 if ( bytesRead != fileLen )
303 char *clientDir = handle;
307 if (clientDir == NULL)
322 #if defined(_WIN32) || defined(_WIN64) 326 if ( unlink(file) != 0 )
329 if ( errno != ENOENT )
347 char *clientDir = handle;
350 if (clientDir == NULL)
356 #if defined(_WIN32) || defined(_WIN64) 357 if ( _rmdir(clientDir) != 0 )
360 if ( rmdir(clientDir) != 0 )
363 if ( errno != ENOENT && errno != ENOTEMPTY )
381 char *clientDir = handle;
384 if (clientDir == NULL)
390 #if defined(_WIN32) || defined(_WIN64) 391 rc = containskeyWin32(clientDir, key);
402 #if defined(_WIN32) || defined(_WIN64) 403 int containskeyWin32(
char *dirname,
char *key)
407 char *filekey, *ptraux;
408 char dir[MAX_PATH+1];
409 WIN32_FIND_DATAA FileData;
413 sprintf(dir,
"%s/*", dirname);
415 hDir = FindFirstFileA(dir, &FileData);
416 if (hDir != INVALID_HANDLE_VALUE)
420 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
422 if ((filekey =
malloc(strlen(FileData.cFileName) + 1)) == NULL)
427 strcpy(filekey, FileData.cFileName);
429 if ( ptraux != NULL )
431 if(strcmp(filekey, key) == 0)
438 if (!FindNextFileA(hDir, &FileData))
440 if (GetLastError() == ERROR_NO_MORE_FILES)
454 char *filekey, *ptraux;
456 struct dirent *dir_entry;
457 struct stat stat_info;
460 if((dp = opendir(dirname)) != NULL)
462 while((dir_entry = readdir(dp)) != NULL && notFound)
464 char* filename =
malloc(strlen(dirname) + strlen(dir_entry->d_name) + 2);
471 sprintf(filename,
"%s/%s", dirname, dir_entry->d_name);
472 lstat(filename, &stat_info);
474 if(S_ISREG(stat_info.st_mode))
476 if ((filekey =
malloc(strlen(dir_entry->d_name) + 1)) == NULL)
481 strcpy(filekey, dir_entry->d_name);
483 if ( ptraux != NULL )
485 if(strcmp(filekey, key) == 0)
507 char *clientDir = handle;
510 if (clientDir == NULL)
516 #if defined(_WIN32) || defined(_WIN64) 517 rc = clearWin32(clientDir);
528 #if defined(_WIN32) || defined(_WIN64) 529 int clearWin32(
char *dirname)
534 char dir[MAX_PATH+1];
535 WIN32_FIND_DATAA FileData;
539 sprintf(dir,
"%s/*", dirname);
541 hDir = FindFirstFileA(dir, &FileData);
542 if (hDir != INVALID_HANDLE_VALUE)
546 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
548 file =
malloc(strlen(dirname) + strlen(FileData.cFileName) + 2);
554 sprintf(file,
"%s/%s", dirname, FileData.cFileName);
563 if (!FindNextFileA(hDir, &FileData))
565 if (GetLastError() == ERROR_NO_MORE_FILES)
582 struct dirent *dir_entry;
583 struct stat stat_info;
586 if((dp = opendir(dirname)) != NULL)
588 while((dir_entry = readdir(dp)) != NULL && rc == 0)
590 if (lstat(dir_entry->d_name, &stat_info) == 0 && S_ISREG(stat_info.st_mode))
592 if (
remove(dir_entry->d_name) != 0 && errno != ENOENT)
609 int pstkeys(
void *handle,
char ***keys,
int *nkeys)
612 char *clientDir = handle;
615 if (clientDir == NULL)
621 #if defined(_WIN32) || defined(_WIN64) 622 rc = keysWin32(clientDir, keys, nkeys);
624 rc =
keysUnix(clientDir, keys, nkeys);
633 #if defined(_WIN32) || defined(_WIN64) 634 int keysWin32(
char *dirname,
char ***keys,
int *nkeys)
639 char dir[MAX_PATH+1];
640 WIN32_FIND_DATAA FileData;
647 sprintf(dir,
"%s/*", dirname);
650 hDir = FindFirstFileA(dir, &FileData);
651 if (hDir != INVALID_HANDLE_VALUE)
655 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
657 if (!FindNextFileA(hDir, &FileData))
659 if (GetLastError() == ERROR_NO_MORE_FILES)
672 if ((fkeys = (
char **)
malloc(nfkeys *
sizeof(
char *))) == NULL)
680 hDir = FindFirstFileA(dir, &FileData);
681 if (hDir != INVALID_HANDLE_VALUE)
687 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
689 if ((fkeys[i] =
malloc(strlen(FileData.cFileName) + 1)) == NULL)
694 strcpy(fkeys[i], FileData.cFileName);
696 if ( ptraux != NULL )
700 if (!FindNextFileA(hDir, &FileData))
702 if (GetLastError() == ERROR_NO_MORE_FILES)
722 int keysUnix(
char *dirname,
char ***keys,
int *nkeys)
730 struct dirent *dir_entry;
731 struct stat stat_info;
735 if((dp = opendir(dirname)) != NULL)
737 while((dir_entry = readdir(dp)) != NULL)
739 char* temp =
malloc(strlen(dirname)+strlen(dir_entry->d_name)+2);
746 sprintf(temp,
"%s/%s", dirname, dir_entry->d_name);
747 if (lstat(temp, &stat_info) == 0 && S_ISREG(stat_info.st_mode))
761 if ((fkeys = (
char **)
malloc(nfkeys *
sizeof(
char *))) == NULL)
768 if((dp = opendir(dirname)) != NULL)
771 while((dir_entry = readdir(dp)) != NULL)
773 char* temp =
malloc(strlen(dirname)+strlen(dir_entry->d_name)+2);
781 sprintf(temp,
"%s/%s", dirname, dir_entry->d_name);
782 if (lstat(temp, &stat_info) == 0 && S_ISREG(stat_info.st_mode))
784 if ((fkeys[i] =
malloc(strlen(dir_entry->d_name) + 1)) == NULL)
791 strcpy(fkeys[i], dir_entry->d_name);
793 if ( ptraux != NULL )
820 #if defined(UNIT_TESTS) 821 int main (
int argc,
char *argv[])
827 #define RC !rc ? "(Success)" : "(Failed) " 832 const char *clientID =
"TheUTClient";
833 const char *serverURI =
"127.0.0.1:1883";
837 int nm[NDEL] = {5 , 8};
846 char *bufs[NBUFS] = {
"m0",
"mm1",
"mmm2" ,
"mmmm3"};
849 buflens[i]=strlen(bufs[i]);
853 rc =
pstopen((
void**)&handle, clientID, serverURI, perdir);
854 printf(
"%s Persistence directory for client %s : %s\n",
RC, clientID, handle);
857 for(msgId=0;msgId<NMSGS;msgId++)
860 sprintf(key,
"%s%d", stem, msgId);
861 rc =
pstput(handle, key, nbufs, bufs, buflens);
862 printf(
"%s Adding message %s\n",
RC, key);
867 rc =
pstkeys(handle, &keys, &nkeys);
868 printf(
"%s Found %d messages persisted in %s\n",
RC, nkeys, handle);
870 printf(
"%13s\n", keys[i]);
879 sprintf(key,
"%s%d", stem, nm[i]);
881 printf(
"%s Message %s is persisted ?\n",
RC, key);
889 sprintf(key,
"%s%d", stem, nm[i]);
890 rc =
pstget(handle, key, &buffer, &buflen);
892 memcpy(buff, buffer, buflen);
894 printf(
"%s Retrieving message %s : %s\n",
RC, key, buff);
896 printf(
"%s Removing message %s\n",
RC, key);
906 sprintf(key,
"%s%d", stem, nm[i]);
908 printf(
"%s Message %s is persisted ?\n",
RC, key);
913 rc =
pstkeys(handle, &keys, &nkeys);
914 printf(
"%s Found %d messages persisted in %s\n",
RC, nkeys, handle);
916 printf(
"%13s\n", keys[i]);
924 printf(
"%s Closing client persistence directory for client %s\n",
RC, clientID);
928 printf(
"%s Deleting all persisted messages in %s\n",
RC, handle);
931 rc =
pstkeys(handle, &keys, &nkeys);
932 printf(
"%s Found %d messages persisted in %s\n",
RC, nkeys, handle);
934 printf(
"%13s\n", keys[i]);
941 printf(
"%s Closing client persistence directory for client %s\n",
RC, clientID);
int pstopen(void **handle, const char *clientID, const char *serverURI, void *context)
#define MQTTCLIENT_PERSISTENCE_ERROR
int pstmkdir(char *pPathname)
#define PAHO_MEMORY_ERROR
int pstclear(void *handle)
int keysUnix(char *, char ***, int *)
This structure represents a persistent data store, used to store outbound and inbound messages...
int pstcontainskey(void *handle, char *key)
#define MESSAGE_FILENAME_EXTENSION
int pstget(void *handle, char *key, char **buffer, int *buflen)
int pstclose(void *handle)
int pstput(void *handle, char *key, int bufcount, char *buffers[], int buflens[])
#define MESSAGE_FILENAME_LENGTH
int pstremove(void *handle, char *key)
int containskeyUnix(char *, char *)
int main(int argc, char **argv)
int pstkeys(void *handle, char ***keys, int *nkeys)