/* * file-tool.c * * This example demonstrates the usage of the file services * * - How to browse the file system of the server * - How to download a file from the server * * Note: intended to be used with server_example3 or server_example_files * * Note: DOES NOT WORK WITH VISUAL STUDIO because of libgen.h * */ #include "iec61850_client.h" #include #include #include static char* hostname = "localhost"; static int tcpPort = 102; static char* filename = NULL; typedef enum { FileOperationType_None = 0, FileOperationType_Dir, FileOperationType_Info, FileOperationType_Del, FileOperationType_Get, FileOperationType_Set } FileOperationType; static FileOperationType operation = FileOperationType_None; static bool downloadHandler(void* parameter, uint8_t* buffer, uint32_t bytesRead) { FILE* fp = (FILE*) parameter; printf("received %i bytes\n", bytesRead); if (fwrite(buffer, bytesRead, 1, fp) == 1) return true; else { printf("Failed to write local file!\n"); return false; } } static void printHelp() { printf("file-tool [options] []\n"); printf(" Options:\n"); printf(" -h \n"); printf(" -p portnumber\n"); printf(" Operations\n"); printf(" dir - show directory\n"); printf(" info - show file info\n"); printf(" del - delete file\n"); printf(" get - get file\n"); printf(" set - set file\n"); } static int parseOptions(int argc, char** argv) { int currentArgc = 1; int retVal = 0; while (currentArgc < argc) { if (strcmp(argv[currentArgc], "-h") == 0) { hostname = argv[++currentArgc]; } else if (strcmp(argv[currentArgc], "-p") == 0) { tcpPort = atoi(argv[++currentArgc]); } else if (strcmp(argv[currentArgc], "del") == 0) { operation = FileOperationType_Del; filename = argv[++currentArgc]; } else if (strcmp(argv[currentArgc], "dir") == 0) { operation = FileOperationType_Dir; } else if (strcmp(argv[currentArgc], "info") == 0) { operation = FileOperationType_Info; filename = argv[++currentArgc]; } else if (strcmp(argv[currentArgc], "get") == 0) { operation = FileOperationType_Get; filename = argv[++currentArgc]; } else if (strcmp(argv[currentArgc], "set") == 0) { operation = FileOperationType_Set; filename = argv[++currentArgc]; } else { printf("Unknown operation!\n"); return 1; } currentArgc++; } return retVal; } void showDirectory(IedConnection con) { IedClientError error; /* Get the root directory */ LinkedList rootDirectory = IedConnection_getFileDirectory(con, &error, NULL); if (error != IED_ERROR_OK) { printf("Error retrieving file directory\n"); } else { LinkedList directoryEntry = LinkedList_getNext(rootDirectory); while (directoryEntry != NULL) { FileDirectoryEntry entry = (FileDirectoryEntry) directoryEntry->data; printf("%s %i\n", FileDirectoryEntry_getFileName(entry), FileDirectoryEntry_getFileSize(entry)); directoryEntry = LinkedList_getNext(directoryEntry); } LinkedList_destroyDeep(rootDirectory, (LinkedListValueDeleteFunction) FileDirectoryEntry_destroy); } } void getFile(IedConnection con) { IedClientError error; char* bname = strdup(filename); char* localFilename = basename(bname); FILE* fp = fopen(localFilename, "w"); if (fp != NULL) { /* Download a file from the server */ IedConnection_getFile(con, &error, filename, downloadHandler, (void*) fp); if (error != IED_ERROR_OK) printf("Failed to get file!\n"); fclose(fp); } else printf("Failed to open file %s\n", localFilename); free(bname); } void setFile(IedConnection con) { IedClientError error; char* dirc = strdup(filename); char* basec = strdup(filename); char* localDirName = dirname(dirc); char* localFileName = basename(basec); printf("local dir: %s\n", localDirName); printf("local file: %s\n", localFileName); /* IedConnection_setFilestoreBasepath requires the file separator at the end! */ strcpy(dirc, localDirName); strcat(dirc, "/"); printf("filestore basepath: %s\n", dirc); IedConnection_setFilestoreBasepath(con, dirc); IedConnection_setFile(con, &error, localFileName, localFileName); if (error != IED_ERROR_OK) printf("Failed to set file! (code=%i)\n", error); free(dirc); free(basec); } void deleteFile(IedConnection con) { IedClientError error; /* Delete file at server */ IedConnection_deleteFile(con, &error, filename); if (error != IED_ERROR_OK) printf("Failed to delete file! (code=%i)\n", error); } int main(int argc, char** argv) { if (argc < 2) { printHelp(); return 0; } parseOptions(argc, argv); if (operation == FileOperationType_None) { printHelp(); return 0; } IedClientError error; IedConnection con = IedConnection_create(); IedConnection_connect(con, &error, hostname, tcpPort); if (error == IED_ERROR_OK) { switch (operation) { case FileOperationType_Dir: showDirectory(con); break; case FileOperationType_Get: getFile(con); break; case FileOperationType_Del: deleteFile(con); break; case FileOperationType_Info: break; case FileOperationType_Set: setFile(con); break; } IedConnection_abort(con, &error); } else { printf("Failed to connect to %s:%i\n", hostname, tcpPort); } IedConnection_destroy(con); }