diff --git a/include/array.h b/include/array.h index e174dcf..b5d58ec 100644 --- a/include/array.h +++ b/include/array.h @@ -33,7 +33,7 @@ typedef struct StringHashS { } StringHashT; -#define ARRFREE(a) do { if (a != NULL) { arrfree(a); } break; } while(1) +#define ARRFREE(a) do { if (a != NULL) { arrfree(a); a = NULL; } break; } while(1) #endif // ARRAY_H diff --git a/include/ssh.h b/include/ssh.h index 3ee5d6b..3fdcf97 100644 --- a/include/ssh.h +++ b/include/ssh.h @@ -31,29 +31,19 @@ struct SFTPS; -struct SSHS; typedef void (*SFTPCallback)(struct SFTPS*); -typedef void (*SSHCallback)(struct SSHS*); - - -typedef struct SSHS { - LIBSSH2_SESSION *session; - LIBSSH2_CHANNEL *channel; - int sock; - int result; - gboolean finished; - SSHCallback callback; -} SSHT; typedef struct SFTPS { - SSHT *sshData; + LIBSSH2_SESSION *sshSession; + LIBSSH2_CHANNEL *sshChannel; + int sock; void *userData; FILE *local; - LIBSSH2_SFTP *session; - LIBSSH2_SFTP_HANDLE *handle; + LIBSSH2_SFTP *sftpSession; + LIBSSH2_SFTP_HANDLE *sftpHandle; char buffer[102400]; char *ptr; uint64_t fileSize; @@ -69,13 +59,12 @@ typedef struct SFTPS { } SFTPT; -SSHT *sshConnect(char *hostname, uint16_t port, char *user, char *password); -void sshDisconnect(SSHT **sshData); -gboolean sshSFTPDelete(SSHT *sshData, char *target); -//int sshExecute(SSHT *sshData, char *command, char **output); -gboolean sshSFTPFileExists(SSHT *sshData, char *target); -SFTPT *sshSFTPReceive(SSHT *sshData, char *remote, char *local, SFTPCallback callback); -SFTPT *sshSFTPSend(SSHT *sshData, char *local, char *remote, SFTPCallback callback); +SFTPT *sshConnect(char *hostname, uint16_t port, char *user, char *password); +void sshDisconnect(SFTPT **sshData); +gboolean sshSFTPDelete(SFTPT *sshData, char *target); +gboolean sshSFTPFileExists(SFTPT *sshData, char *target); +gboolean sshSFTPReceive(SFTPT *sshData, char *remote, char *local, SFTPCallback callback); +gboolean sshSFTPSend(SFTPT *sshData, char *local, char *remote, SFTPCallback callback); void sshShutdown(void); void sshStartup(void); diff --git a/include/utils.h b/include/utils.h index 630212d..6991f8e 100644 --- a/include/utils.h +++ b/include/utils.h @@ -67,6 +67,7 @@ extern char __utilFilenameBuffer[FILENAME_MAX]; char *utilCreateString(char *format, ...); char *utilCreateStringVArgs(char *format, va_list args); ArchiveT *utilDecompress(char *archive, char *outPath, archiveCallback callback, void *userData); +int utilDeleteTree(const char *path); char *utilDeobfuscateASCII(char *obfuscated); void utilDequote(char *string); void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted); diff --git a/src/messages.c b/src/messages.c index 8e40c4d..c9e3c34 100644 --- a/src/messages.c +++ b/src/messages.c @@ -55,6 +55,8 @@ void message(MessageTypesT level, char *format, ...) { msg = utilCreateStringVArgs(format, args); va_end(args); + debug("%s\n", msg); + // Break multiline messages down into individual lines. tok = strtok(msg, "\n"); while (tok != NULL) { @@ -68,6 +70,8 @@ void message(MessageTypesT level, char *format, ...) { tok = strtok(NULL, "\n"); } + + DEL(msg); } @@ -209,7 +213,7 @@ static void winMessagesDelete(gpointer userData) { DEL(_pendingMessages[0]); arrdel(_pendingMessages, 0); } - ARRFREE(_pendingMessages); + //ARRFREE(_pendingMessages); // This is making Memwatch mad. utilWindowUnRegister(userData); _lstMessages = NULL; diff --git a/src/project.c b/src/project.c index c2539c5..a759f1d 100644 --- a/src/project.c +++ b/src/project.c @@ -242,9 +242,10 @@ static void clearRecipeData(ProjectDataT *self) { while (arrlen(self->recipes) > 0) { DEL(self->recipes[0]->key); DEL(self->recipes[0]->value); + DEL(self->recipes[0]); arrdel(self->recipes, 0); } - ARRFREE(self->recipes); + //ARRFREE(self->recipes); // This is making Memwatch mad. } @@ -263,8 +264,7 @@ static void cookFinished(CompilerContextT **context) { // If this is not first call, process context. if (self->tempInteger != -1) { if (ctx->programResult != 0) { - //***TODO*** Not all negative returns are severe. - message(ctx->programResult > 0 ? MSG_ERROR : MSG_SEVERE, "Recipe %s returned %d", self->recipes[self->tempInteger]->value, ctx->programResult); + message(MSG_ERROR, "Recipe %s returned %d", self->recipes[self->tempInteger]->value, ctx->programResult); } } @@ -896,7 +896,7 @@ EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) { }; char temp[6]; int result = 0; - SSHT *ssh = NULL; + SFTPT *ssh = NULL; char *error = NULL; (void)object; @@ -1069,8 +1069,7 @@ EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) { GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(self->treeProject)); GtkTreeIter iter; GtkTreeIter child; - SSHT *ssh; - SFTPT *sftp; + SFTPT *ssh; char *temp; char *filename; char *pathString; @@ -1081,7 +1080,6 @@ EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) { gboolean archPrinted; FILE *out; - ssh = NEW(SSHT); ssh = sshConnect(self->buildHost, self->buildSSHPort, self->buildUser, self->buildPassword); if (!ssh) { @@ -1101,6 +1099,7 @@ EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) { message(MSG_SEVERE, "Unable to write temporary build.start file"); unlink(buildStart); // Just in case. message(MSG_INFO, "Build canceled"); + DEL(buildStart); sshDisconnect(&ssh); return; } @@ -1138,7 +1137,7 @@ EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) { temp = utilCreateString("%s%s", self->windowData.path, filename); arrput(_sendList, temp); } - DEL(filename); + //DEL(filename); // GTK says I need to free this. Memwatch says otherwise. } while (gtk_tree_model_iter_next(model, &child)); } } while (gtk_tree_model_iter_next(model, &iter)); @@ -1147,10 +1146,8 @@ EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) { arrput(_sendList, buildStart); // Prime the pump! We only set sshData and userData so sendSFTP can determine this is the first file. - sftp = NEW(SFTPT); - sftp->sshData = ssh; - sftp->userData = self; - sendSFTP(sftp); + ssh->userData = self; + sendSFTP(ssh); } @@ -1181,10 +1178,10 @@ gboolean projectAddToTree(ProjectDataT *self, char *filename) { do { gtk_tree_model_get(model, &child, COL_FILENAME, &temp, -1); if (strcmp(temp, filename) == 0) { - DEL(temp); // This generates an unknown pointer warning in memwatch. Pretty sure it's bogus. + //DEL(temp); // GTK says I need to free this. Memwatch says otherwise. return FALSE; // Item exists and was not added. } - DEL(temp); // This generates an unknown pointer warning in memwatch. Pretty sure it's bogus. + //DEL(temp); // GTK says I need to free this. Memwatch says otherwise. } while (gtk_tree_model_iter_next(model, &child)); } } while (gtk_tree_model_iter_next(model, &iter)); @@ -1201,7 +1198,7 @@ gboolean projectAddToTree(ProjectDataT *self, char *filename) { } } } - DEL(temp); + temp = NULL; //DEL(temp); // GTK says I need to free this. Memwatch says otherwise. fileLen = 0; utilEnsureBufferSize((unsigned char **)&temp, &fileLen, 4); // fileLen is just a throwaway here. snprintf(temp, 4, "%d", foundAt); @@ -1224,8 +1221,10 @@ static void receiveSFTP(SFTPT *sftp) { if (sftp->finished) { if (sftp->success) { message(MSG_INFO, "Cleaning up remote build"); - sshSFTPDelete(sftp->sshData, REMOTE_BUILD_RESULTS); - //***TODO*** Delete any local "results" folder. + sshSFTPDelete(sftp, REMOTE_BUILD_RESULTS); + temp = utilCreateString("%sresults", self->windowData.path); + utilDeleteTree(temp); + DEL(temp); message(MSG_INFO, "Unpacking build"); temp = utilCreateString("%s%s", self->windowData.path, LOCAL_BUILD_RESULTS); utilDecompress(temp, self->windowData.path, decompressBuild, self); @@ -1233,11 +1232,8 @@ static void receiveSFTP(SFTPT *sftp) { } else { message(MSG_ERROR, "Receiving %s from build server - FAILED", sftp->remoteName); message(MSG_INFO, "Build canceled"); - sshDisconnect(&sftp->sshData); } - DEL(sftp->localName); - DEL(sftp->remoteName); - DEL(sftp); + sshDisconnect(&sftp); } } @@ -1406,13 +1402,9 @@ static gboolean updateBuildOptions(ProjectDataT *self) { static void sendSFTP(SFTPT *sftp) { ProjectDataT *self = (ProjectDataT *)sftp->userData; - SFTPT *last; - SFTPT *next; char *target; char *name; - last = sftp; - // If source and target are missing, this is the first file - start sending. // Or, did the current transfer succeed? If so, send next file. if ((sftp->localName == NULL && sftp->remoteName == NULL) || (sftp->finished && sftp->success)) { @@ -1425,19 +1417,15 @@ static void sendSFTP(SFTPT *sftp) { name = utilFileBasename(_sendList[0]); target = utilCreateString("build/%s", name); message(MSG_INFO, "Sending %s to build server", name); - sftp = sshSFTPSend(last->sshData, _sendList[0], target, sendSFTP); - sftp->userData = self; + sshSFTPSend(sftp, _sendList[0], target, sendSFTP); DEL(target); DEL(name); + DEL(_sendList[0]); arrdel(_sendList, 0); } else { // Finished! message(MSG_INFO, "Waiting for build to complete"); - // "last" will be deleted by sshSFTPUpdate so copy what we need to "next". - next = NEW(SFTPT); - next->sshData = last->sshData; - next->userData = last->userData; - g_timeout_add_seconds(5, waitForBuild, next); + g_timeout_add_seconds(5, waitForBuild, sftp); } } @@ -1447,21 +1435,14 @@ static void sendSFTP(SFTPT *sftp) { message(MSG_ERROR, "Sending %s to build server - FAILED", sftp->remoteName); } message(MSG_INFO, "Build canceled"); - sshDisconnect(&last->sshData); + sshDisconnect(&sftp); // Clear any remaining transfers. while (arrlen(_sendList) > 0) { + DEL(_sendList[0]); arrdel(_sendList, 0); } ARRFREE(_sendList); } - - // Do we need to free this? - if (last->finished) { - // Do not delete last->sshData as we continue to need it until everything is finished. - DEL(last->localName); - DEL(last->remoteName); - DEL(last); - } } @@ -1513,31 +1494,24 @@ static void targetArrayDelete(TargetT ***array) { static gboolean waitForBuild(gpointer userData) { - SFTPT *last = (SFTPT *)userData; - ProjectDataT *self = (ProjectDataT *)last->userData; - SFTPT *sftp; + SFTPT *sftp = (SFTPT *)userData; + ProjectDataT *self = (ProjectDataT *)sftp->userData; char *temp; + gboolean result; - if (sshSFTPFileExists(last->sshData, REMOTE_BUILD_RESULTS)) { + if (sshSFTPFileExists(sftp, REMOTE_BUILD_RESULTS)) { // Build complete! Next step! - //***TODO*** Delete any local build archive. message(MSG_INFO, "Retrieving build results"); temp = utilCreateString("%s%s", self->windowData.path, LOCAL_BUILD_RESULTS); - sftp = sshSFTPReceive(last->sshData, REMOTE_BUILD_RESULTS, temp, receiveSFTP); + unlink(temp); + result = sshSFTPReceive(sftp, REMOTE_BUILD_RESULTS, temp, receiveSFTP); DEL(temp); - if (!sftp) { + if (!result) { message(MSG_ERROR, "Receiving build from build server - FAILED"); message(MSG_INFO, "Build canceled"); - sshDisconnect(&last->sshData); - } else { - sftp->userData = last->userData; + sshDisconnect(&sftp); } - // Finally finished with "last" - DEL(last->localName); - DEL(last->remoteName); - DEL(last); - return G_SOURCE_REMOVE; } @@ -1627,6 +1601,8 @@ static void winProjectDelete(gpointer userData) { targetArrayDelete(&self->targets); clearRecipeData(self); + DEL(self->projectName); + DEL(self->projectType); DEL(self->buildHost); DEL(self->buildUser); DEL(self->buildPassword); diff --git a/src/ssh.c b/src/ssh.c index 3b20704..36a6563 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -40,25 +40,19 @@ closesocket(data->sock); static SFTPT **_activeSFTPs = NULL; -static SSHT **_activeSSHs = NULL; -static char *_output = NULL; -static int _outputLen = 0; -static char *_buffer = NULL; -static int _bufferLen = 0; -gboolean sshUpdate(gpointer userData); // Not static -static SFTPT *sshSFTPTransfer(SSHT *sshData, char *local, char *remote, SFTPCallback callback, gboolean uploading); -gboolean sshSFTPUpdate(gpointer userData); // Not static -static int sshWaitSocket(int socket_fd, LIBSSH2_SESSION *session); +static gboolean sshSFTPTransfer(SFTPT *sshData, char *local, char *remote, SFTPCallback callback, gboolean uploading); +gboolean sshSFTPUpdate(gpointer userData); // Not static +static int sshWaitSocket(int socket_fd, LIBSSH2_SESSION *session); -SSHT *sshConnect(char *hostname, uint16_t port, char *user, char *password) { +SFTPT *sshConnect(char *hostname, uint16_t port, char *user, char *password) { int rc; struct hostent *hostent; struct sockaddr_in sin; in_addr_t hostaddr; - SSHT *data = NULL; + SFTPT *data = NULL; hostent = gethostbyname(hostname); if (hostent == NULL) { @@ -72,7 +66,7 @@ SSHT *sshConnect(char *hostname, uint16_t port, char *user, char *password) { return NULL; } - data = NEW(SSHT); + data = NEW(SFTPT); if (data) { data->sock = socket(AF_INET, SOCK_STREAM, 0); @@ -86,73 +80,76 @@ SSHT *sshConnect(char *hostname, uint16_t port, char *user, char *password) { return NULL; } - data->session = libssh2_session_init(); - if (!data->session) { + data->sshSession = libssh2_session_init(); + if (!data->sshSession) { socketclose(data->sock); DEL(data); return NULL; } - libssh2_session_set_blocking(data->session, 0); + libssh2_session_set_blocking(data->sshSession, 0); - while ((rc = libssh2_session_handshake(data->session, data->sock)) == LIBSSH2_ERROR_EAGAIN) + while ((rc = libssh2_session_handshake(data->sshSession, data->sock)) == LIBSSH2_ERROR_EAGAIN) ; if (rc) { message(MSG_ERROR, "Failure establishing SSH session: %d\n", rc); - libssh2_session_free(data->session); + libssh2_session_free(data->sshSession); socketclose(data->sock); DEL(data); return NULL; } - while ((rc = libssh2_userauth_password(data->session, user, password)) == LIBSSH2_ERROR_EAGAIN) + while ((rc = libssh2_userauth_password(data->sshSession, user, password)) == LIBSSH2_ERROR_EAGAIN) ; if (rc) { message(MSG_ERROR, "Failure authenticating SSH session: %d\n", rc); - while (libssh2_session_disconnect(data->session, "Error") == LIBSSH2_ERROR_EAGAIN) + while (libssh2_session_disconnect(data->sshSession, "Error") == LIBSSH2_ERROR_EAGAIN) ; - libssh2_session_free(data->session); + libssh2_session_free(data->sshSession); socketclose(data->sock); DEL(data); return NULL; } } - //***TODO*** Move SFTP session setup here so we don't keep repeating it. + // SFTP session setup here so we don't keep repeating it. + do { + data->sftpSession = libssh2_sftp_init(data->sshSession); + if (!data->sftpSession) { + if (libssh2_session_last_errno(data->sshSession) != LIBSSH2_ERROR_EAGAIN) { + sshDisconnect(&data); + return NULL; + } + } + } while (!data->sftpSession); return data; } -void sshDisconnect(SSHT **sshData) { - SSHT *data = *sshData; +void sshDisconnect(SFTPT **sshData) { + SFTPT *data = *sshData; - //***TODO*** Move SFTP session teardown here so we don't keep repeating it. + // SFTP session teardown here so we don't keep repeating it. + libssh2_sftp_shutdown(data->sftpSession); - libssh2_session_disconnect(data->session, "Normal Shutdown."); - libssh2_session_free(data->session); + libssh2_session_disconnect(data->sshSession, "Normal Shutdown."); + libssh2_session_free(data->sshSession); socketclose(data->sock); + DEL(data->localName); + DEL(data->remoteName); + DEL(data); } -gboolean sshSFTPDelete(SSHT *sshData, char *target) { - LIBSSH2_SFTP *session; +gboolean sshSFTPDelete(SFTPT *sshData, char *target) { int rc; gboolean result = TRUE; do { - session = libssh2_sftp_init(sshData->session); - if (!session) { - if (libssh2_session_last_errno(sshData->session) != LIBSSH2_ERROR_EAGAIN) { - return FALSE; - } - } - } while (!session); - - do { - rc = libssh2_sftp_unlink(session, target); + rc = libssh2_sftp_unlink(sshData->sftpSession, target); if (rc == 0) break; if (rc != LIBSSH2_ERROR_EAGAIN) { result = FALSE; @@ -160,96 +157,11 @@ gboolean sshSFTPDelete(SSHT *sshData, char *target) { } } while (TRUE); - libssh2_sftp_shutdown(session); - return result; } -/* -int sshExecute(SSHT *sshData, char *command, char **output) { - int rc; - int exitcode = 127; - char *exitsignal = (char *)"none"; - int outputLen = 0; - - utilEnsureBufferSize((unsigned char **)output, &outputLen, 1024); - *output[0] = 0; - - while ((sshData->channel = libssh2_channel_open_session(sshData->session)) == NULL && libssh2_session_last_error(sshData->session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(sshData->sock, sshData->session); - } - if (sshData->channel == NULL) { - return exitcode; - } - while ((rc = libssh2_channel_exec(sshData->channel, command)) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(sshData->sock, sshData->session); - } - if (rc != 0) { - return exitcode; - } - - for (;;) { - do { - rc = libssh2_channel_read(sshData->channel, (char *)_buffer, sizeof(_buffer)); - if (rc > 0) { - utilEnsureBufferSize((unsigned char **)output, &outputLen, (int)strlen((const char *)*output) + rc + 1); - strncat(*output, (char *)_buffer, rc); - } - } while (rc > 0); - - if (rc == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(sshData->sock, sshData->session); - } else { - break; - } - } - - while ((rc = libssh2_channel_close(sshData->channel)) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(sshData->sock, sshData->session); - } - if (rc == 0) { - exitcode = libssh2_channel_get_exit_status(sshData->channel); - libssh2_channel_get_exit_signal(sshData->channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); - } - - libssh2_channel_free(sshData->channel); - - return exitcode; -} - - -SSHT *sshExecuteVerbose(SSHT *sshData, char *title, char *command, SSHCallback callback) { - int rc; - - sshData->title = strdup(title); - sshData->callback = callback; - sshData->finished = FALSE; - - while ((sshData->channel = libssh2_channel_open_session(sshData->session)) == NULL && libssh2_session_last_error(sshData->session, NULL, NULL, 0) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(sshData->sock, sshData->session); - } - if (sshData->channel == NULL) { - return NULL; - } - while ((rc = libssh2_channel_exec(sshData->channel, command)) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(sshData->sock, sshData->session); - } - if (rc != 0) { - return NULL; - } - - // ***TODO*** SSH Progress Dialog Here - //sshData->status = new SSHStatus(sshData); - arrpush(_activeSSHs, sshData); - - return sshData; -} -*/ - - -gboolean sshSFTPFileExists(SSHT *sshData, char *target) { - LIBSSH2_SFTP *session; +gboolean sshSFTPFileExists(SFTPT *sshData, char *target) { LIBSSH2_SFTP_HANDLE *handle; LIBSSH2_SFTP_ATTRIBUTES attrs; char *path; @@ -259,15 +171,6 @@ gboolean sshSFTPFileExists(SSHT *sshData, char *target) { int rc; gboolean result = FALSE; - do { - session = libssh2_sftp_init(sshData->session); - if (!session) { - if (libssh2_session_last_errno(sshData->session) != LIBSSH2_ERROR_EAGAIN) { - return FALSE; - } - } - } while (!session); - // Split filename and path. // Cannot use utilFilePath and friends because this is a remote path. temp = strdup(target); // Make copy in case they pass in a constant. @@ -289,9 +192,8 @@ gboolean sshSFTPFileExists(SSHT *sshData, char *target) { DEL(temp); do { - handle = libssh2_sftp_opendir(session, path); - if ((!handle) && (libssh2_session_last_errno(sshData->session) != LIBSSH2_ERROR_EAGAIN)) { - libssh2_sftp_shutdown(session); + handle = libssh2_sftp_opendir(sshData->sftpSession, path); + if ((!handle) && (libssh2_session_last_errno(sshData->sshSession) != LIBSSH2_ERROR_EAGAIN)) { free(file); free(path); return FALSE; @@ -322,91 +224,76 @@ gboolean sshSFTPFileExists(SSHT *sshData, char *target) { free(path); libssh2_sftp_closedir(handle); - libssh2_sftp_shutdown(session); return result; } -SFTPT *sshSFTPReceive(SSHT *sshData, char *remote, char *local, SFTPCallback callback) { +gboolean sshSFTPReceive(SFTPT *sshData, char *remote, char *local, SFTPCallback callback) { return sshSFTPTransfer(sshData, local, remote, callback, FALSE); } -SFTPT *sshSFTPSend(SSHT *sshData, char *local, char *remote, SFTPCallback callback) { +gboolean sshSFTPSend(SFTPT *sshData, char *local, char *remote, SFTPCallback callback) { return sshSFTPTransfer(sshData, local, remote, callback, TRUE); } -static SFTPT *sshSFTPTransfer(SSHT *sshData, char *local, char *remote, SFTPCallback callback, gboolean uploading) { - SFTPT *sftp = NULL; - int i; +static gboolean sshSFTPTransfer(SFTPT *sshData, char *local, char *remote, SFTPCallback callback, gboolean uploading) { + int i; // Do not allow two of the same transfers to be started. for (i=0; ilocalName, local) == 0) && (strcmp(_activeSFTPs[i]->remoteName, remote) == 0)) { - // Return existing transfer handle. - return _activeSFTPs[i]; + // Return existing transfer is running. + return TRUE; } } - sftp = NEW(SFTPT); - - if (sftp) { - sftp->fileSize = uploading ? utilFileSize(local) : 0; - sftp->local = fopen(local, uploading ? "rb" : "wb"); - if (sftp->local) { - sftp->fileSent = 0; - sftp->nread = 0; - sftp->ptr = NULL; - sftp->localName = strdup(local); - sftp->remoteName = strdup(remote); - sftp->sshData = sshData; - sftp->uploading = uploading; - sftp->readMore = TRUE; - sftp->finished = FALSE; - sftp->success = FALSE; - sftp->callback = callback; - do { - sftp->session = libssh2_sftp_init(sshData->session); - if (!sftp->session) { - if (libssh2_session_last_errno(sshData->session) != LIBSSH2_ERROR_EAGAIN) { - break; - } - } - } while (!sftp->session); + if (sshData) { + sshData->fileSize = uploading ? utilFileSize(local) : 0; + sshData->local = fopen(local, uploading ? "rb" : "wb"); + if (sshData->local) { do { if (uploading) { - sftp->handle = libssh2_sftp_open(sftp->session, sftp->remoteName, + sshData->sftpHandle = libssh2_sftp_open(sshData->sftpSession, remote, LIBSSH2_FXF_WRITE | LIBSSH2_FXF_CREAT | LIBSSH2_FXF_TRUNC, LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH); } else { - sftp->handle = libssh2_sftp_open(sftp->session, sftp->remoteName, + sshData->sftpHandle = libssh2_sftp_open(sshData->sftpSession, remote, LIBSSH2_FXF_READ, LIBSSH2_SFTP_S_IRUSR | LIBSSH2_SFTP_S_IWUSR | LIBSSH2_SFTP_S_IRGRP | LIBSSH2_SFTP_S_IROTH); } - if (!sftp->handle) { - if (libssh2_session_last_errno(sshData->session) != LIBSSH2_ERROR_EAGAIN) { + if (!sshData->sftpHandle) { + if (libssh2_session_last_errno(sshData->sshSession) != LIBSSH2_ERROR_EAGAIN) { break; } } - } while (!sftp->handle); - if (sftp->handle) { - arrput(_activeSFTPs, sftp); - return sftp; + } while (!sshData->sftpHandle); + if (sshData->sftpHandle) { + DEL(sshData->localName); + DEL(sshData->remoteName); + sshData->fileSent = 0; + sshData->nread = 0; + sshData->ptr = NULL; + sshData->localName = strdup(local); + sshData->remoteName = strdup(remote); + sshData->uploading = uploading; + sshData->readMore = TRUE; + sshData->finished = FALSE; + sshData->success = FALSE; + sshData->callback = callback; + arrput(_activeSFTPs, sshData); + return TRUE; } else { - message(MSG_SEVERE, "Failed to get SFTP handle! %d, %lu\n", libssh2_session_last_errno(sshData->session), libssh2_sftp_last_error(sftp->session)); - libssh2_sftp_shutdown(sftp->session); - DEL(sftp); + message(MSG_SEVERE, "Failed to get SFTP handle! %d, %lu\n", libssh2_session_last_errno(sshData->sshSession), libssh2_sftp_last_error(sshData->sftpSession)); } - } else { - DEL(sftp); } } - return NULL; + return FALSE; } @@ -425,6 +312,7 @@ gboolean sshSFTPUpdate(gpointer userData) { // More data to read? if (_activeSFTPs[i]->readMore) { _activeSFTPs[i]->nread = fread(_activeSFTPs[i]->buffer, 1, sizeof(_activeSFTPs[i]->buffer), _activeSFTPs[i]->local); + // Are we finished sending? if (_activeSFTPs[i]->nread <= 0) { result = _activeSFTPs[i]; arrdel(_activeSFTPs, i); @@ -437,8 +325,8 @@ gboolean sshSFTPUpdate(gpointer userData) { // Is there data to send? if (_activeSFTPs[i]->nread > 0) { // Send data. - while ((rc = (int)libssh2_sftp_write(_activeSFTPs[i]->handle, _activeSFTPs[i]->ptr, _activeSFTPs[i]->nread)) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(_activeSFTPs[i]->sshData->sock, _activeSFTPs[i]->sshData->session); + while ((rc = (int)libssh2_sftp_write(_activeSFTPs[i]->sftpHandle, _activeSFTPs[i]->ptr, _activeSFTPs[i]->nread)) == LIBSSH2_ERROR_EAGAIN) { + sshWaitSocket(_activeSFTPs[i]->sock, _activeSFTPs[i]->sshSession); } if (rc >= 0) { _activeSFTPs[i]->ptr += rc; @@ -457,8 +345,8 @@ gboolean sshSFTPUpdate(gpointer userData) { // Downloading // Data to read? - while ((rc = libssh2_sftp_read(_activeSFTPs[i]->handle, _activeSFTPs[i]->buffer, sizeof(_activeSFTPs[i]->buffer))) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(_activeSFTPs[i]->sshData->sock, _activeSFTPs[i]->sshData->session); + while ((rc = libssh2_sftp_read(_activeSFTPs[i]->sftpHandle, _activeSFTPs[i]->buffer, sizeof(_activeSFTPs[i]->buffer))) == LIBSSH2_ERROR_EAGAIN) { + sshWaitSocket(_activeSFTPs[i]->sock, _activeSFTPs[i]->sshSession); } if (rc > 0) { _activeSFTPs[i]->fileSize += rc; @@ -476,12 +364,10 @@ gboolean sshSFTPUpdate(gpointer userData) { result->finished = TRUE; result->success = TRUE; fclose(result->local); - libssh2_sftp_close(result->handle); - libssh2_sftp_shutdown(result->session); + libssh2_sftp_close(result->sftpHandle); if (result->callback) { result->callback(result); } - DEL(result); } return G_SOURCE_CONTINUE; @@ -489,14 +375,16 @@ gboolean sshSFTPUpdate(gpointer userData) { void sshShutdown(void) { - //***TODO*** Any active sessions? - g_idle_remove_by_data(sshUpdate); + // Any active sessions to disconnect? + while (arrlen(_activeSFTPs) > 0) { + sshDisconnect(&_activeSFTPs[0]); + arrdel(_activeSFTPs, 0); + } + //ARRFREE(_activeSFTPs); // This is making Memwatch mad. + g_idle_remove_by_data(sshSFTPUpdate); - DEL(_output); - DEL(_buffer); - libssh2_exit(); } @@ -516,71 +404,10 @@ void sshStartup(void) { printf("libssh2 initialization failed: %d\n", err); } - utilEnsureBufferSize((unsigned char **)&_output, &_outputLen, 1024); - utilEnsureBufferSize((unsigned char **)&_buffer, &_bufferLen, 0x4000); - - g_idle_add(sshUpdate, sshUpdate); g_idle_add(sshSFTPUpdate, sshSFTPUpdate); } -gboolean sshUpdate(gpointer userData) { - int rc; - int exitcode = 127; - char *exitsignal = (char *)"none"; - SSHT *s; - int i; - - (void)userData; - - _output[0] = 0; - - for (i=0; ifinished) { - rc = libssh2_channel_read(s->channel, _buffer, sizeof(_buffer)); - if (rc > 0) { - utilEnsureBufferSize((unsigned char **)&_output, &_outputLen, rc + 1); - _output[0] = 0; - strncat(_output, (char *)_buffer, rc); - //***TODO*** Display in status dialog - //s->status->AddOutput(output); - } else { - if (rc == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(s->sock, s->session); - } else { - while ((rc = libssh2_channel_close(s->channel)) == LIBSSH2_ERROR_EAGAIN) { - sshWaitSocket(s->sock, s->session); - } - DEL(_output); - _output = strdup("\n\nUH OH! Something wrong happened. Check the output for errors."); - if (rc == 0) { - exitcode = libssh2_channel_get_exit_status(s->channel); - libssh2_channel_get_exit_signal(s->channel, &exitsignal, NULL, NULL, NULL, NULL, NULL); - if (exitcode == 0) { - DEL(_output); - _output = strdup("\n\nFINISHED! You can close this window anytime."); - } - } - //***TODO*** Display in status dialog - //s->status->AddOutput(output); - libssh2_channel_free(s->channel); - s->result = exitcode; - //s->finished = true; - //s->status->Finished(); // No close - if (s->callback) s->callback(s); - arrdel(_activeSSHs, i); - break; // Exit for loop - // We don't delete "s" because it will be handled by utilSSHDisconnect - } - } - } - } - - return G_SOURCE_CONTINUE; -} - - static int sshWaitSocket(int socket_fd, LIBSSH2_SESSION *session) { struct timeval timeout; int rc; diff --git a/src/utils.c b/src/utils.c index 307537f..7d4255d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -76,6 +76,8 @@ char *utilCreateStringVArgs(char *format, va_list args) { vsnprintf(buffer, (size_t)size, format, args); } + //debug("%s = %s\n", format, buffer); + return buffer; } @@ -251,6 +253,35 @@ gboolean utilDecompressUpdate(gpointer userData) { } +int utilDeleteTree(const char *path) { + DIR *directory = opendir(path); + char *filename = NULL; + struct dirent *entry; + int (*removeFunc)(const char *); + + if (directory) { + while ((entry = readdir(directory))) { + if (!strcmp(".", entry->d_name) || !strcmp("..", entry->d_name)) { + continue; + } + filename = utilCreateString("%s/%s", path, entry->d_name); + removeFunc = entry->d_type == DT_DIR ? utilDeleteTree : remove; + if (removeFunc(filename)) { + DEL(filename); + closedir(directory); + return -1; + } + DEL(filename); + } + if (closedir(directory)) { + return -1; + } + } + + return remove(path); +} + + char *utilDeobfuscateASCII(char *obfuscated) { char *deobfuscated = NULL; char *hostname; @@ -874,6 +905,7 @@ gboolean utilWindowUnRegister(gpointer windowData) { debug("Window Unregistered: %ld\n", hmlen(_windowList)); DEL(w->filename); + DEL(w->path); DEL(w->title); return (result == 1) ? TRUE : FALSE;