To build upon the previously submitted alias primitive I've added support for 'if'.
I'll submit this change here for potential inclusion, or discussion. It could be improved with the addition of support for "else", but so far I've not had the need. Sample usage: if -x /usr/bin/cmatrix 'idle 420 eval "screen -t cmatrix /usr/bin/cmatrix -f -o -u 10" "idle 0"' The function is used as: if [test] [test arg] "string 1" "string 2" ... "string N" If the test succeeds then each "string" will be passed to eval. The tests are basic and are: -e file -> True if file exists. -d file -> True if file is a directroy. -x file -> True if executable file. hostname str -> True if hostname matches str. username str -> True if username matches str. Each test may be inverted via a "!" prefix, such as : if !-e /etc/passwd "echo 'system broken?'" Patch against git tree attached. My version obviously has this applied already: http://www.steve.org.uk/Software/tscreen/ Steve -- http://www.steve.org.uk/
diff --git a/src/comm.c b/src/comm.c index 27f67c7..7311cf7 100644 --- a/src/comm.c +++ b/src/comm.c @@ -200,6 +200,7 @@ struct comm comms[RC_LAST + 1] = #endif { "hstatus", NEED_FORE|ARGS_1 }, { "idle", ARGS_0|ARGS_ORMORE }, + { "if", ARGS_3|ARGS_ORMORE }, { "ignorecase", ARGS_01 }, { "info", NEED_LAYER|ARGS_0 }, #ifdef ENCODINGS diff --git a/src/process.c b/src/process.c index 79cb716..f921dba 100644 --- a/src/process.c +++ b/src/process.c @@ -165,6 +165,7 @@ extern struct layout *layouts, *layout_attach, layout_last_marker; extern struct layout *laytab[]; extern char screenterm[], HostName[], version[]; +extern char *LoginName; extern struct NewWindow nwin_undef, nwin_default; extern struct LayFuncs WinLf, MarkLf; @@ -416,6 +417,105 @@ static char *resizeprompts[] = { char *noargs[1]; + +#ifdef _WINDOWS /* 1998/01/14 (Wed) 09:16:04 */ +# define isExecutable(mode) (mode & (S_IXUSR)) +#else +# define isExecutable(mode) (mode & (S_IXUSR|S_IXGRP|S_IXOTH)) +#endif + +/** + * Perform a specific test, as used for the 'if' primitive. + * + */ +int +doTest( type, arg ) + char *type; + char *arg; +{ + struct stat buf; + int ret = 0; + int result = 0; + int invert = 0; + +#ifdef expand_tilde + char *expanded = expand_tilde( arg ); +#else + char *expanded = arg; +#endif + + ret = stat(expanded , &buf); + + /** + * test is to be inverted. + */ + if ( type[0] == '!' ) + { + invert = 1; + type += 1; + } + + /** + * Now the tests themselves. + */ + if ( strcmp( type, "-d" ) == 0 ) + { + /* directory? */ + if ( S_ISDIR(buf.st_mode)) + result = 1; + } + else if ( strcmp( type, "-e" ) == 0 ) + { + /* exists ? */ + if ( ret == 0 ) + result = 1; + } + else if ( strcmp( type, "-f" ) == 0 ) + { + /* regular file ? */ + if ( S_ISREG(buf.st_mode ) ) + result = 1; + } + else if ( strcmp( type, "-x" ) == 0 ) + { + /* executable file ? */ + if ( ( S_ISREG(buf.st_mode )) && ( isExecutable(buf.st_mode)) ) + result = 1; + } +#ifdef SKX_H + else if ( strcmp( type, "alias" ) == 0 ) + { + /* does the named alias exist? */ + result = ( FindAlias( arg ) != NULL ); + } +#endif + else if ( strcmp( type, "hostname" ) == 0 ) + { + /* Hostname? */ + if ( strcmp( HostName, arg ) == 0 ) + result =1 ; + } + else if ( strcmp( type, "username" ) == 0 ) + { + /* Username? */ + if ( strcmp( LoginName, arg ) == 0 ) + result = 1; + } + else + { + Msg(0, "Unknown test type : %s", type ); + } + +#ifdef expand_tilde + free( expanded ); +#endif + + if ( invert ) + result = !result; + + return( result ); +} + void InitKeytab() { @@ -3175,6 +3275,25 @@ int key; ClearAction(&ktabp[n]); } break; + case RC_IF: + { + char *type = args[0]; + char *arg = args[1]; + + if ( doTest( type, arg ) ) + { + /* test succeeded - run each remaining arg through eval */ + args = SaveArgs(args); + for (i = 2; args[i] ; i++) + { + if (args[i][0]) + Colonfin(args[i], strlen(args[i]), (char *)0); + free(args[i]); + } + free(args); + } + } + break; #ifdef MAPKEYS case RC_BINDKEY: {