/* shmtest.c * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. * * This file is free software; as a special exception the author gives * unlimited permission to copy and/or distribute it, with or without * modifications, as long as this notice is preserved. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include #include #include #include #include #include #include #ifdef HAVE_SYS_IPC_H #include #include #endif #ifdef HAVE_SYS_SHM_H #include #endif #include "util.h" #include "ttyio.h" #include "i18n.h" #ifdef HAVE_DOSISH_SYSTEM int main( int argc, char **argv ) { fprintf(stderr, "Sorry, not yet available for DOSish systems\n"); exit(1); } #else static int serverpid = -1; static void my_usage(void) { fprintf(stderr, "usage: shmtest gpg-command-line\n"); exit(1); } const char * strusage( int level ) { return default_strusage(level); } static void i18n_init(void) { #ifdef ENABLE_NLS #ifdef HAVE_LC_MESSAGES setlocale( LC_MESSAGES, "" ); #else setlocale( LC_ALL, "" ); #endif bindtextdomain( PACKAGE, G10_LOCALEDIR ); textdomain( PACKAGE ); #endif } static void do_get_string( int mode, const char *keyword, byte *area, size_t areasize ) { size_t n, len; char *p=NULL; int yes=0; n = area[0] << 8 | area[1]; /* fixme: do some sanity checks here */ if( mode == 1 ) p = tty_get( keyword ); else if( mode == 3 ) p = tty_get_hidden( keyword ); else yes = tty_get_answer_is_yes( keyword ); if( p ) { len = strlen(p); memcpy( area+n+2, p, len ); area[n] = len >> 8; area[n+1] = len; m_free(p); } else { /* bool */ area[n] = 0; area[n+1] = 1; area[n+2] = yes; } area[3] = 1; /* we should better use a semaphore */ kill( serverpid, SIGUSR1 ); } int main(int argc, char **argv) { void *area = NULL; size_t areasize = 4096; int shm_id = -1; FILE *fp; char buf[200]; char *p, *p2; size_t n; int i; log_set_name("shmtest"); i18n_init(); #ifndef USE_SHM_COPROCESSING log_info("SHM_COPRPOCESSING is not available\n"); #else if( argc < 1 ) my_usage(); for(n=0,i=1; i < argc; i++ ) n += strlen(argv[i]) + 1; p = m_alloc( 100 + n ); strcpy( p, "../g10/gpg --status-fd 1 --run-as-shm-coprocess 0"); for(i=1; i < argc; i++ ) { strcat(p, " " ); strcat(p, argv[i] ); } fp = popen( p, "r" ); m_free( p ); if( !fp ) log_error("popen failed: %s\n", strerror(errno)); while ( fgets (buf, sizeof (buf) - 1, fp ) != NULL ) { size_t len = strlen(buf); if( len >= 9 && !memcmp( buf, "[GNUPG:] ", 9 ) ) { int word=0; int is_info = 0, is_get = 0; for( p = strtok(buf+9, " \n"); p ; p = strtok(NULL, " \n")) { word++; if( word==1 && !strcmp(p,"SHM_INFO") ) { if( !area ) is_info=1; else log_error("duplicate SHM_INFO ignored\n" ); } else if( is_info && (p2 = strchr(p, '=' )) ) { int val; *p2++ = 0; val = atoi(p2); /* should be atou() for some values */ if( !strcmp(p, "pv" ) ) { if( atoi(p2) != 1 ) log_fatal("invalid protocol version %d\n", val ); is_info = 2; } else if( !strcmp(p, "pid" ) ) serverpid = val; else if( !strcmp(p, "shmid" ) ) shm_id = val; } else if( word == 1 && !strcmp(p,"SHM_GET") ) is_get = 1; else if( word == 1 && !strcmp(p,"SHM_GET_BOOL") ) is_get = 2; else if( word == 1 && !strcmp(p,"SHM_GET_HIDDEN") ) is_get = 3; else if( word == 2 && is_get ) { do_get_string( is_get, p, area, areasize ); break; } else if( word == 1 ) log_info("Status: %s\n", p); } if( is_info ) { if( is_info < 2 ) log_fatal("SHM info without protocol version\n"); if( serverpid == -1 ) log_fatal("SHM info without server's pid\n"); if( shm_id == -1 ) log_fatal("SHM info without id\n"); log_info("Shared memory info: server=%d shm_id=%d\n", serverpid, shm_id); area = shmat( shm_id, 0, 0 ); if( area == (void*)-1 ) log_fatal("attach to shared memory failed: %s\n", strerror(errno)); } } else fputs (buf, stdout); } if( pclose(fp) ) log_error("pclose failed\n"); return 0; #endif } #endif