diff --git a/config/config.def.c b/config/config.def.c index 873977ac..b79d35ea 100644 --- a/config/config.def.c +++ b/config/config.def.c @@ -104,6 +104,7 @@ Settings config = { /** Lazy mode setting */ .lazy_filter_limit = 5000, /** auto select */ - .auto_select = FALSE + .auto_select = FALSE, + .parse_hosts = FALSE }; diff --git a/doc/rofi-manpage.markdown b/doc/rofi-manpage.markdown index fd112515..1adf40f0 100644 --- a/doc/rofi-manpage.markdown +++ b/doc/rofi-manpage.markdown @@ -44,6 +44,7 @@ rofi - A window switcher, run dialog and dmenu replacement [ -help] [ -dump-xresources ] [ -auto-select ] +[ -parse-hosts ] ## DESCRIPTION @@ -300,6 +301,11 @@ daemon listening to specific key-combinations. Default: *{terminal} -e {ssh-client} {host}* +`-parse-hosts` + + Parse the `/etc/hosts` files for entries. + + ### Run settings `-run-command` *cmd* diff --git a/doc/rofi.1 b/doc/rofi.1 index fc3b494f..d865000a 100644 --- a/doc/rofi.1 +++ b/doc/rofi.1 @@ -42,6 +42,7 @@ rofi \- A window switcher, run dialog and dmenu replacement [ \-help] [ \-dump\-xresources ] [ \-auto\-select ] +[ \-parse\-hosts ] .SH DESCRIPTION .PP \fBrofi\fP is an X11 popup window switcher, run dialog, dmenu replacement and more. It focusses on @@ -378,6 +379,14 @@ Set the command to execute when starting a ssh session. The pattern \fI{host}\fP is replaced by the selected ssh entry. .IP Default: \fI{terminal} \-e {ssh\-client} {host}\fP +.PP +\fB\fC\-parse\-hosts\fR +.PP +.RS +.nf +Parse the `/etc/hosts` files for entries. +.fi +.RE .SS Run settings .PP \fB\fC\-run\-command\fR \fIcmd\fP @@ -607,14 +616,18 @@ Check quotes used on the commandline: e.g. used “ instead of ". .SH WEBSITE .PP \fBrofi\fP website can be found at here -\[la]https://davedavenport.github.io/rofi/\[ra] +.UR https://davedavenport.github.io/rofi/ +.UE .PP \fBrofi\fP bugtracker can be found here -\[la]https://github.com/DaveDavenport/rofi/issues\[ra] +.UR https://github.com/DaveDavenport/rofi/issues +.UE .SH AUTHOR .PP Qball Cow -\[la]qball@gmpclient.org\[ra] +.MT qball@gmpclient.org +.ME .PP Original code based on work by: Sean Pringle -\[la]sean.pringle@gmail.com\[ra] +.MT sean.pringle@gmail.com +.ME diff --git a/include/rofi.h b/include/rofi.h index d5932f7c..ad8190dd 100644 --- a/include/rofi.h +++ b/include/rofi.h @@ -201,6 +201,8 @@ typedef struct _Settings unsigned int lazy_filter_limit; /** Auto select. */ unsigned int auto_select; + /** Hosts file parsing */ + unsigned int parse_hosts; } Settings; /** Global Settings structure. */ diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c index 0498a2be..675ffa10 100644 --- a/source/dialogs/ssh.c +++ b/source/dialogs/ssh.c @@ -109,6 +109,70 @@ static int ssh_sort_func ( const void *a, const void *b ) const char *bstr = *( const char * const * ) b; return g_utf8_collate ( astr, bstr ); } + +/** + * Read /etc/hosts + */ +static char **read_hosts_file ( char ** retv, unsigned int *length ) +{ + // Read the hosts file. + FILE *fd = fopen ( "/etc/hosts", "r" ); + if ( fd != NULL ) { + char buffer[1024]; + // Reading one line per time. + while ( fgets ( buffer, sizeof ( buffer ), fd ) ) { + // Evaluate one line. + unsigned int index = 0, ti = 0; + char *token = buffer; + + // Tokenize it. + do { + char c = buffer[index]; + // Break on space, tab, newline and \0. + if ( c == ' ' || c == '\t' || c == '\n' || c == '\0' || c == '#' ) { + buffer[index] = '\0'; + // Ignore empty tokens + if ( token[0] != '\0' ) { + ti++; + // and first token. + if ( ti > 1 ) { + // Is this host name already in the list? + // We often get duplicates in hosts file, so lets check this. + int found = 0; + for ( unsigned int j = 0; j < ( *length ); j++ ) { + if ( !g_ascii_strcasecmp ( token, retv[j] ) ) { + found = 1; + break; + } + } + + if ( !found ) { + // Add this host name to the list. + retv = g_realloc ( retv, + ( ( *length ) + 2 ) * sizeof ( char* ) ); + retv[( *length )] = g_strdup ( token ); + retv[( *length ) + 1] = NULL; + ( *length )++; + } + } + } + // Set start to next element. + token = &buffer[index + 1]; + // Everything after comment ignore. + if ( c == '#' ) { + break; + } + } + // Skip to the next entry. + index++; + } while ( buffer[index] != '\0' && buffer[index] != '#' ); + } + fclose ( fd ); + } + + return retv; +} + static char ** get_ssh ( unsigned int *length ) { char **retv = NULL; @@ -124,6 +188,10 @@ static char ** get_ssh ( unsigned int *length ) g_free ( path ); num_favorites = ( *length ); + if ( config.parse_hosts == TRUE ) { + retv = read_hosts_file ( retv, length ); + } + FILE *fd = NULL; const char *hd = getenv ( "HOME" ); path = g_strdup_printf ( "%s/%s", hd, ".ssh/config" ); diff --git a/source/xrmoptions.c b/source/xrmoptions.c index b5133ae2..c7a3f4fe 100644 --- a/source/xrmoptions.c +++ b/source/xrmoptions.c @@ -104,7 +104,8 @@ static XrmOption xrmOptions[] = { { xrm_Boolean, "sidebar-mode", { .num = &config.sidebar_mode }, NULL }, { xrm_Number, "lazy-filter-limit", { .num = &config.lazy_filter_limit }, NULL }, { xrm_SNumber, "eh", { .snum = &config.element_height }, NULL }, - { xrm_Boolean, "auto-select", { .num = &config.auto_select }, NULL } + { xrm_Boolean, "auto-select", { .num = &config.auto_select }, NULL }, + { xrm_Boolean, "parse-hosts", { .num = &config.parse_hosts }, NULL } }; // Dynamic options.