summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorQball Cow <qball@gmpclient.org>2014-05-13 10:45:59 +0200
committerQball Cow <qball@gmpclient.org>2014-05-13 10:45:59 +0200
commit87b51f5430bf0f4a4abeea5235618d4b0fba8e80 (patch)
treef8a95e1a7a7d626c8693d965a3b7d223a87af4e7 /source
parentdb9bb13111e1fbb191e8bf073d28315d8798c92d (diff)
Extract out the history code and create functions for it.
(Easier to fix issues later on)
Diffstat (limited to 'source')
-rw-r--r--source/history.c256
-rw-r--r--source/run-dialog.c179
-rw-r--r--source/ssh-dialog.c157
3 files changed, 279 insertions, 313 deletions
diff --git a/source/history.c b/source/history.c
new file mode 100644
index 00000000..5eda4773
--- /dev/null
+++ b/source/history.c
@@ -0,0 +1,256 @@
+/**
+ * rofi
+ *
+ * MIT/X11 License
+ * Copyright 2013-2014 Qball Cow <qball@gmpclient.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <errno.h>
+#include "rofi.h"
+#include "history.h"
+
+#define HISTORY_NAME_LENGTH 256
+#define HISTORY_MAX_ENTRIES 25
+
+typedef struct __element
+{
+ long int index;
+ char name[HISTORY_NAME_LENGTH];
+}_element;
+
+static int __element_sort_func ( const void *ea, const void *eb )
+{
+ _element *a = *(_element * *) ea;
+ _element *b = *(_element * *) eb;
+ return b->index - a->index;
+}
+
+static void __history_write_element_list( FILE *fd, _element **list, unsigned int length)
+{
+ if(list == NULL) {
+ return;
+ }
+ // Sort the list before writing out.
+ qsort ( list, length, sizeof ( _element* ), __element_sort_func );
+
+ // Set the max length of the list.
+ length = (length > HISTORY_MAX_ENTRIES)? HISTORY_MAX_ENTRIES:length;
+
+ // Write out entries.
+ for(unsigned int iter = 0; iter < length ;iter++)
+ {
+ fprintf(fd , "%ld %s\n", list[iter]->index, list[iter]->name);
+ }
+}
+
+static _element ** __history_get_element_list ( FILE *fd, unsigned int *length )
+{
+ _element **retv = NULL;
+
+ if (length == NULL)
+ {
+ return NULL;
+ }
+ *length = 0;
+
+ if( fd == NULL)
+ {
+ return NULL;
+ }
+ char buffer[HISTORY_NAME_LENGTH+16];
+ while ( fgets (buffer, HISTORY_NAME_LENGTH+16, fd ) != NULL)
+ {
+ // Skip empty lines.
+ if ( strlen ( buffer ) == 0 )
+ {
+ continue;
+ }
+ retv = reallocate ( retv, ( *length + 2 ) * sizeof ( _element* ) );
+ retv[(*length)] = allocate ( sizeof ( _element ) );
+ // remove trailing \n
+ buffer[strlen ( buffer ) - 1] = '\0';
+ // Parse the number of times.
+ char * start = NULL;
+ retv[(*length)]->index = strtol ( buffer, &start, 10 );
+ strncpy(retv[(*length)]->name, (start+1),HISTORY_NAME_LENGTH);
+ // Force trailing '\0'
+ retv[(*length)]->name[HISTORY_NAME_LENGTH-1] = '\0';
+ retv[(*length) + 1] = NULL;
+
+ (*length)++;
+ }
+ return retv;
+}
+
+
+void history_set ( const char *filename, const char *entry )
+{
+ int found = 0;
+ unsigned int curr = 0;
+ unsigned int length = 0;
+ // Open file for reading and writing.
+ FILE *fd = fopen(filename, "a+");
+ if(fd == NULL)
+ {
+ fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
+ return ;
+ }
+ // Get list.
+ _element ** list = __history_get_element_list(fd, &length);
+
+ // Look if the entry exists.
+ for(unsigned int iter = 0;!found && iter < length; iter++)
+ {
+ if(strcmp(list[iter]->name, entry) == 0)
+ {
+ curr = iter;
+ found = 1;
+ }
+ }
+
+ if(found) {
+ // If exists, increment list index number
+ list[curr]->index++;
+ }else{
+ // If not exists, add it.
+ // Increase list by one
+ list = reallocate(list,(length+2)*sizeof(_element *));
+ list[length] = allocate(sizeof(_element));
+ // Copy name
+ strncpy(list[length]->name, entry, HISTORY_NAME_LENGTH);
+ list[length]->name[HISTORY_NAME_LENGTH-1] = '\0';
+ // set # hits
+ list[length]->index = 1;
+
+ length++;
+ list[length] = NULL;
+ }
+
+ // Rewind.
+ fseek(fd, 0L, SEEK_SET);
+ // Clear file.
+ ftruncate(fileno(fd), 0);
+
+ // Write list.
+ __history_write_element_list(fd, list, length);
+
+
+ // Free the list.
+ for(unsigned int iter = 0; iter < length; iter++)
+ {
+ if(list[iter] != NULL) { free(list[iter]); }
+ }
+ if(list != NULL) free(list);
+ // Close file.
+ fclose(fd);
+}
+
+void history_remove ( const char *filename, const char *entry )
+{
+ int found = 0;
+ unsigned int curr = 0;
+ unsigned int length = 0;
+ // Open file for reading and writing.
+ FILE *fd = fopen(filename, "a+");
+ if(fd == NULL)
+ {
+ fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
+ return ;
+ }
+ // Get list.
+ _element ** list = __history_get_element_list(fd, &length);
+
+ // Find entry.
+ for(unsigned int iter = 0;!found && iter < length; iter++)
+ {
+ if(strcmp(list[iter]->name, entry) == 0)
+ {
+ curr = iter;
+ found = 1;
+ }
+ }
+
+ // If found, remove it and write out new file.
+ if(found) {
+ // Remove the entry.
+ free(list[curr]);
+ // Swap last to here (if list is size 1, we just swap empty sets).
+ list[curr] = list[length-1];
+ // Empty last.
+ list[length-1] = NULL;
+ length--;
+
+ // Rewind.
+ fseek(fd, 0L, SEEK_SET);
+ // Clear list.
+ ftruncate(fileno(fd), 0);
+
+ // Write list.
+ __history_write_element_list(fd, list, length);
+ }
+
+ // Free the list.
+ for(unsigned int iter = 0; iter < length; iter++)
+ {
+ if(list[iter] != NULL) { free(list[iter]); }
+ }
+ if(list != NULL) free(list);
+ // Close file.
+ fclose(fd);
+}
+
+char ** history_get_list ( const char *filename, unsigned int *length )
+{
+ char **retv = NULL;
+ // Open file.
+ FILE *fd = fopen(filename, "r");
+ if(fd == NULL)
+ {
+ if(errno != ENOENT) {
+ fprintf(stderr, "Failed to open file: %s\n", strerror(errno));
+ }
+ return NULL;
+ }
+ // Get list.
+ _element ** list = __history_get_element_list(fd, length);
+
+ // Copy list in right format.
+ if((*length) > 0 )
+ {
+ retv = allocate(((*length)+1)*sizeof(char *));
+ for ( int iter = 0; iter < (*length); iter++)
+ {
+ retv[iter] = strdup(list[iter]->name);
+ free(list[iter]);
+ }
+ retv[(*length)] = NULL;
+ free(list);
+ }
+
+ fclose(fd);
+ return retv;
+}
diff --git a/source/run-dialog.c b/source/run-dialog.c
index 1b39d438..1fca28da 100644
--- a/source/run-dialog.c
+++ b/source/run-dialog.c
@@ -40,6 +40,7 @@
#include <errno.h>
#include "rofi.h"
+#include "history.h"
#include "run-dialog.h"
#ifdef TIMING
#include <time.h>
@@ -88,10 +89,6 @@ static pid_t exec_cmd ( const char *cmd, int run_in_term )
exit ( EXIT_FAILURE );
}
- int curr = -1;
- unsigned int index = 0;
- element **retv = NULL;
-
/**
* This happens in non-critical time (After launching app)
* It is allowed to be a bit slower.
@@ -100,79 +97,7 @@ static pid_t exec_cmd ( const char *cmd, int run_in_term )
if(asprintf ( &path, "%s/%s", cache_dir, RUN_CACHE_FILE ) == -1) {
return -1;
}
-
- FILE *fd = fopen ( path, "r" );
-
- if ( fd != NULL )
- {
- char buffer[1024];
- while ( fgets ( buffer, 1024, fd ) != NULL )
- {
- if ( strlen ( buffer ) == 0 )
- {
- continue;
- }
- retv = reallocate ( retv, ( index + 2 ) * sizeof ( element* ) );
- retv[index] = allocate ( sizeof ( element ) );
- // remove trailing \n
- buffer[strlen ( buffer ) - 1] = '\0';
- char * start = NULL;
- retv[index]->index = strtol ( buffer, &start, 10 );
- snprintf ( retv[index]->name, RUN_DIALOG_NAME_LENGTH, "%s", start + 1 );
- retv[index + 1] = NULL;
-
- if ( strcasecmp ( retv[index]->name, cmd ) == 0 )
- {
- curr = index;
- }
- index++;
- }
-
- fclose ( fd );
- }
-
- if ( curr < 0 )
- {
- retv = reallocate ( retv, ( index + 2 ) * sizeof ( element* ) );
- retv[index] = allocate ( sizeof ( element ) );
- retv[index]->index = 1;
- snprintf ( retv[index]->name, RUN_DIALOG_NAME_LENGTH, "%s", cmd );
- index++;
- }
- else
- {
- retv[curr]->index++;
- }
- // Sort the list.
- qsort ( retv, index, sizeof ( element* ), element_sort_func );
-
- /**
- * Write out the last 25 results again.
- */
- fd = fopen ( path, "w" );
-
- if ( fd )
- {
- for ( int i = 0; i < ( int ) index && i < 20; i++ )
- {
- if ( retv[i]->name && retv[i]->name[0] != '\0' )
- {
- fprintf ( fd, "%ld %s\n",
- retv[i]->index,
- retv[i]->name
- );
- }
- }
-
- fclose ( fd );
- }
-
- for ( int i = 0; retv != NULL && retv[i] != NULL; i++ )
- {
- free ( retv[i] );
- }
-
- free ( retv );
+ history_set(path, cmd);
free ( path );
@@ -181,11 +106,6 @@ static pid_t exec_cmd ( const char *cmd, int run_in_term )
// execute sub-process
static void delete_entry ( const char *cmd )
{
- int curr = -1;
- unsigned int index = 0;
- element **retv = NULL;
-
-
/**
* This happens in non-critical time (After launching app)
* It is allowed to be a bit slower.
@@ -194,67 +114,7 @@ static void delete_entry ( const char *cmd )
if(asprintf ( &path, "%s/%s", cache_dir, RUN_CACHE_FILE ) == -1) {
return;
}
-
- FILE *fd = fopen ( path, "r" );
-
- if ( fd != NULL )
- {
- char buffer[1024];
- while ( fgets ( buffer, 1024, fd ) != NULL )
- {
- char * start = NULL;
- if ( strlen ( buffer ) == 0 )
- {
- continue;
- }
- retv = reallocate ( retv, ( index + 2 ) * sizeof ( element* ) );
- retv[index] = allocate ( sizeof ( element ) );
- // remove trailing \n
- buffer[strlen ( buffer ) - 1] = '\0';
- retv[index]->index = strtol ( buffer, &start, 10 );
- snprintf ( retv[index]->name, RUN_DIALOG_NAME_LENGTH, "%s", start + 1 );
- retv[index + 1] = NULL;
-
- if ( strcasecmp ( retv[index]->name, cmd ) == 0 )
- {
- curr = index;
- }
- index++;
- }
-
- fclose ( fd );
- }
-
- /**
- * Write out the last 25 results again.
- */
- fd = fopen ( path, "w" );
-
- if ( fd )
- {
- for ( int i = 0; i < ( int ) index && i < 20; i++ )
- {
- if ( i != curr )
- {
- if ( retv[i]->name && retv[i]->name[0] != '\0' )
- {
- fprintf ( fd, "%ld %s\n",
- retv[i]->index,
- retv[i]->name
- );
- }
- }
- }
-
- fclose ( fd );
- }
-
- for ( int i = 0; retv != NULL && retv[i] != NULL; i++ )
- {
- free ( retv[i] );
- }
-
- free ( retv );
+ history_remove(path, cmd);
free ( path );
}
@@ -282,37 +142,10 @@ static char ** get_apps ( )
if(asprintf ( &path, "%s/%s", cache_dir, RUN_CACHE_FILE ) > 0) {
- FILE *fd = fopen ( path, "r" );
-
- if ( fd != NULL )
- {
- char buffer[1024];
- while ( fgets ( buffer, 1024, fd ) != NULL )
- {
- if ( strlen ( buffer ) == 0 )
- {
- continue;
- }
- // remove trailing \n
- buffer[strlen ( buffer ) - 1] = '\0';
- char *start = NULL;
- // Don't use result.
- strtol ( buffer, &start, 10 );
- if ( start == NULL )
- {
- continue;
- }
- retv = reallocate ( retv, ( index + 2 ) * sizeof ( char* ) );
- retv[index] = strdup ( start + 1 );
- retv[index + 1] = NULL;
- index++;
- num_favorites++;
- }
-
- fclose ( fd );
- }
-
+ retv = history_get_list(path, &index);
free ( path );
+ // Keep track of how many where loaded as favorite.
+ num_favorites=index;
}
diff --git a/source/ssh-dialog.c b/source/ssh-dialog.c
index 071d7412..f23670a4 100644
--- a/source/ssh-dialog.c
+++ b/source/ssh-dialog.c
@@ -40,12 +40,13 @@
#include <errno.h>
#include "rofi.h"
+#include "history.h"
#include "ssh-dialog.h"
#ifdef TIMING
#include <time.h>
#endif
-#define SSH_CACHE_FILE "rofi.sshcache"
+#define SSH_CACHE_FILE "rofi-2.sshcache"
static inline int execshssh ( const char *host )
{
@@ -96,71 +97,16 @@ static pid_t exec_ssh ( const char *cmd )
exit ( EXIT_FAILURE );
}
- int curr = -1;
- unsigned int index = 0;
- char **retv = NULL;
-
/**
* This happens in non-critical time (After launching app)
* It is allowed to be a bit slower.
*/
- char *path = allocate ( strlen ( cache_dir ) + strlen ( SSH_CACHE_FILE ) + 3 );
- sprintf ( path, "%s/%s", cache_dir, SSH_CACHE_FILE );
- FILE *fd = fopen ( path, "r" );
-
- if ( fd != NULL )
+ char *path = NULL;
+ if(asprintf ( &path, "%s/%s", cache_dir, SSH_CACHE_FILE ) > 0)
{
- char buffer[1024];
- while ( fgets ( buffer, 1024, fd ) != NULL )
- {
- retv = reallocate ( retv, ( index + 2 ) * sizeof ( char* ) );
- buffer[strlen ( buffer ) - 1] = '\0';
- retv[index] = strdup ( buffer );
- retv[index + 1] = NULL;
-
- if ( strcasecmp ( retv[index], cmd ) == 0 )
- {
- curr = index;
- }
-
- index++;
- }
-
- fclose ( fd );
+ history_set(path, cmd);
+ free(path);
}
-
- /**
- * Write out the last 25 results again.
- */
- fd = fopen ( path, "w" );
-
- if ( fd )
- {
- // Last one goes on top!
- fputs ( cmd, fd );
- fputc ( '\n', fd );
-
- for ( int i = 0; i < ( int ) index && i < 20; i++ )
- {
- if ( i != curr )
- {
- fputs ( retv[i], fd );
- fputc ( '\n', fd );
- }
- }
-
- fclose ( fd );
- }
-
- for ( int i = 0; retv != NULL && retv[i] != NULL; i++ )
- {
- free ( retv[i] );
- }
-
- free ( retv );
-
- free ( path );
-
return pid;
}
static void delete_ssh ( const char *cmd )
@@ -169,67 +115,12 @@ static void delete_ssh ( const char *cmd )
{
return;
}
-
- int curr = -1;
- unsigned int index = 0;
- char **retv = NULL;
-
- /**
- * This happens in non-critical time (After launching app)
- * It is allowed to be a bit slower.
- */
- char *path = allocate ( strlen ( cache_dir ) + strlen ( SSH_CACHE_FILE ) + 3 );
- sprintf ( path, "%s/%s", cache_dir, SSH_CACHE_FILE );
- FILE *fd = fopen ( path, "r" );
-
- if ( fd != NULL )
- {
- char buffer[1024];
- while ( fgets ( buffer, 1024, fd ) != NULL )
- {
- retv = reallocate ( retv, ( index + 2 ) * sizeof ( char* ) );
- buffer[strlen ( buffer ) - 1] = '\0';
- retv[index] = strdup ( buffer );
- retv[index + 1] = NULL;
-
- if ( strcasecmp ( retv[index], cmd ) == 0 )
- {
- curr = index;
- }
-
- index++;
- }
-
- fclose ( fd );
- }
-
- /**
- * Write out the last 25 results again.
- */
- fd = fopen ( path, "w" );
-
- if ( fd )
+ char *path = NULL;
+ if(asprintf ( &path, "%s/%s", cache_dir, SSH_CACHE_FILE ) > 0)
{
- for ( int i = 0; i < ( int ) index && i < 20; i++ )
- {
- if ( i != curr )
- {
- fputs ( retv[i], fd );
- fputc ( '\n', fd );
- }
- }
-
- fclose ( fd );
- }
-
- for ( int i = 0; retv != NULL && retv[i] != NULL; i++ )
- {
- free ( retv[i] );
+ history_remove(path, cmd);
+ free(path);
}
-
- free ( retv );
-
- free ( path );
}
static int sort_func ( const void *a, const void *b )
{
@@ -253,34 +144,20 @@ static char ** get_ssh ( )
return NULL;
}
- path = allocate ( strlen ( cache_dir ) + strlen ( "/"SSH_CACHE_FILE ) + 2 );
- sprintf ( path, "%s/%s", cache_dir, SSH_CACHE_FILE );
- FILE *fd = fopen ( path, "r" );
- char buffer[1024];
-
- if ( fd != NULL )
+ if(asprintf ( &path, "%s/%s", cache_dir, SSH_CACHE_FILE ) > 0)
{
- while ( fgets ( buffer, 1024, fd ) != NULL )
- {
- retv = reallocate ( retv, ( index + 2 ) * sizeof ( char* ) );
- buffer[strlen ( buffer ) - 1] = '\0';
- retv[index] = strdup ( buffer );
- retv[index + 1] = NULL;
- index++;
- num_favorites++;
- }
-
- fclose ( fd );
+ retv = history_get_list(path, &index);
+ free(path);
+ num_favorites = index;
}
- free ( path );
const char *hd = getenv ( "HOME" );
- path = allocate ( strlen ( hd ) + strlen ( ".ssh/config" ) + 3 );
- sprintf ( path, "%s/%s", hd, ".ssh/config" );
- fd = fopen ( path, "r" );
+ asprintf ( &path, "%s/%s", hd, ".ssh/config" );
+ FILE *fd = fopen ( path, "r" );
if ( fd != NULL )
{
+ char buffer[1024];
while ( fgets ( buffer, 1024, fd ) != NULL )
{
if ( strncasecmp ( buffer, "Host", 4 ) == 0 )