#include "interface.h" void ui_init() { static char readline_name[] = "fs_client"; fprintf( stderr, "Gustavo Sverzut Barbieri \n" \ "Type 'help' for help.\n" ); rl_readline_name = readline_name; rl_attempted_completion_function = ui_completion; } char **ui_completion( const char *text, int start, int end ) { char **matches = NULL; /* If this word is at the start of the line, then it is a command to complete. Otherwise it is the name of a file in the current directory. */ if ( start == 0 ) matches = rl_completion_matches( text, ui_command_generator ); return( matches ); } char *ui_command_generator( const char *text, int state ) { static int list_index=0, len; char *name; /* If this is a new word to complete, initialize now. This includes saving the length of TEXT for efficiency, and initializing the index variable to 0. */ if ( state != 0 ) { list_index = 0; len = (int)strlen( text ); } /* Return the next name which partially matches from the command list. */ while ( ( name = commands[ list_index ].name ) != NULL ) { list_index ++; if ( strncmp( name, text, (size_t)len ) == 0 ) return( strdup( name ) ); } /* If no names matched, then return NULL. */ return NULL; } char *ui_get_word( char *s ) { char *w = NULL; int i=0; assert( s != NULL ); while ( ( s[ i ] != '\0' ) && ( whitespace( s[ i ] ) ) ) i++; // there is a word? if ( s[ i ] == '\0' ) return NULL; w = s + i; // mark word's start // find the word's end while ( ( ( s[ i ] >= 'A' ) && ( s[ i ] <= 'Z' ) ) || ( ( s[ i ] >= 'a' ) && ( s[ i ] <= 'z' ) ) || ( ( s[ i ] >= '0' ) && ( s[ i ] <= '9' ) ) || ( ( s[ i ] == '-' ) || ( s[ i ] == '_' ) ) ) i++; // mark word's end s[ i ] = '\0'; return w; } int ui_execute_line( char *line ) { register int i; command_t *command; char *word; /* Isolate the command word. */ i = 0; while ( ( line[ i ] != '\0' ) && ( whitespace( line[ i ] ) ) ) i++; word = line + i; while ( ( line[ i ] != '\0' ) && ( ! whitespace( line[ i ] ) ) ) i++; if ( line[ i ] != '\0' ) line[ i++ ] = '\0'; command = ui_find_command( word ); if ( ! command ) { fprintf( stderr, "%s: No such command.\n", word ); return -1; } /* Get argument to command, if any. */ while ( whitespace( line[ i ] ) ) i++; line = line + i; word = NULL; /* Call the function. */ return ( *( command->func ) )( line ); } command_t *ui_find_command( char *name ) { register int i; for ( i = 0; commands[ i ].name; i ++ ) if ( strcmp( name, commands[ i ].name ) == 0 ) return &(commands[ i ]); return NULL; } char *stripwhite( char *string ) { register char *s = NULL, *t = NULL; for ( s = string; whitespace( *s ); s ++ ); if ( *s == '\0' ) return s; t = s + strlen( s ) - 1; while ( ( t > s ) && ( whitespace( *t ) ) ) t --; *( ++ t ) = '\0'; string = s; t = NULL; s = NULL; return string; } int ui_comm_help( char *argument ) { register int i; int printed = 0; assert( argument != NULL ); for ( i = 0; commands[ i ].name; i ++ ) { if ( ( *argument == '\0' ) || ( strcmp( argument, commands[ i ].name ) == 0 ) ) { printf( "%s\t\t%s.\n", commands[ i ].name, commands[ i ].doc ); printed ++; } } if ( printed == 0 ) { printf( "No commands match `%s'. Possibilties are:\n", argument ); for ( i = 0; commands[ i ].name; i ++ ) { /* Print in six columns. */ if ( printed == 6 ) { printed = 0; printf( "\n" ); } printf( "%s\t", commands[ i ].name ); printed ++; } if ( printed ) printf( "\n" ); } return 0; } int ui_comm_quit( char *argument ) { ui_stop = 1; return 0; } int ui_comm_list( char *argument ) { char *w, *dir; assert( argument != NULL ); w = ui_get_word( argument ); if ( w ) { dir = (char *)malloc( strlen( w ) ); assert( dir != NULL ); strcpy( dir, w ); } else { dir = (char *)malloc( 3 ); assert( dir != NULL ); strcpy( dir, "." ); } list( dir ); free( dir ); dir = NULL; w = NULL; return 0; } int ui_comm_cred( char *argument ) { cred(); return 0; } int ui_comm_get( char *argument ) { struct stat fstat; int l; char *src = NULL, *dst = NULL; assert( argument != NULL ); l = (int)strlen( argument ); if ( ( l == 0 ) || ( ( src = ui_get_word( argument ) ) == NULL ) ) { fprintf( stderr, "ERROR: argument 'source filename' required.\n" ); return -1; } if ( ( ( src + strlen( src ) +1 ) >= ( argument + l ) ) || ( ( dst = ui_get_next_word( src ) ) == NULL ) ) dst = src; assert( dst != NULL && src != NULL ); if ( ( stat( dst, &fstat ) == 0 ) && S_ISREG( fstat.st_mode ) ) { fprintf( stderr, "ERROR: file already exists, aborted.\n" ); return -1; } get( src, dst, 0 ); dst = NULL; src = NULL; return 0; } int ui_comm_get_stat( char *argument ) { struct stat fstat; int l; char *src = NULL, *dst = NULL; assert( argument != NULL ); l = (int)strlen( argument ); if ( ( l == 0 ) || ( ( src = ui_get_word( argument ) ) == NULL ) ) { fprintf( stderr, "ERROR: argument 'source filename' required.\n" ); return -1; } if ( ( ( src + strlen( src ) +1 ) >= ( argument + l ) ) || ( ( dst = ui_get_next_word( src ) ) != NULL ) ) dst = src; assert( dst != NULL && src != NULL ); if ( ( stat( dst, &fstat ) == 0 ) && S_ISREG( fstat.st_mode ) ) { fprintf( stderr, "ERROR: file already exists, aborted.\n" ); return -1; } get( src, dst, 1 ); return 0; } int ui_comm_exist( char *argument ) { char *w; assert( argument != NULL ); w = ui_get_word( argument ); if ( ! w ) { fprintf( stderr, "ERROR: argument 'filename' required.\n" ); return -1; } else exist( w ); return 0; } /* author: Gustavo Sverzut Barbieri (http://www.gustavobarbieri.com.br) */