* gpgkeys_mailto.in: Fix regexp to work properly if the "keyid" is not a
[gnupg.git] / tools / shmtest.c
1 /* shmtest.c
2  * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3  *
4  * This file is free software; as a special exception the author gives
5  * unlimited permission to copy and/or distribute it, with or without
6  * modifications, as long as this notice is preserved.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
10  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  */
12
13
14 #include <config.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <signal.h>
20 #include <unistd.h>
21 #ifdef HAVE_SYS_IPC_H
22   #include <sys/types.h>
23   #include <sys/ipc.h>
24 #endif
25 #ifdef HAVE_SYS_SHM_H
26   #include <sys/shm.h>
27 #endif
28 #include "util.h"
29 #include "ttyio.h"
30 #include "i18n.h"
31
32 #ifdef HAVE_DOSISH_SYSTEM
33 int main( int argc, char **argv )
34 {
35     fprintf(stderr, "Sorry, not yet available for DOSish systems\n");
36     exit(1);
37 }
38 #else
39
40 static int serverpid = -1;
41
42 static void
43 my_usage(void)
44 {
45     fprintf(stderr, "usage: shmtest gpg-command-line\n");
46     exit(1);
47 }
48
49 const char *
50 strusage( int level )
51 {
52     return default_strusage(level);
53 }
54
55 static void
56 i18n_init(void)
57 {
58   #ifdef ENABLE_NLS
59     #ifdef HAVE_LC_MESSAGES
60        setlocale( LC_MESSAGES, "" );
61     #else
62        setlocale( LC_ALL, "" );
63     #endif
64     bindtextdomain( PACKAGE, G10_LOCALEDIR );
65     textdomain( PACKAGE );
66   #endif
67 }
68
69
70 static void
71 do_get_string( int mode, const char *keyword, byte *area, size_t areasize )
72 {
73     size_t n, len;
74     char *p=NULL;
75     int yes=0;
76
77     n = area[0] << 8 | area[1];
78     /* fixme: do some sanity checks here */
79     if( mode == 1 )
80         p = tty_get( keyword );
81     else if( mode == 3 )
82         p = tty_get_hidden( keyword );
83     else
84         yes = tty_get_answer_is_yes( keyword );
85     if( p ) {
86         len = strlen(p);
87         memcpy( area+n+2, p, len );
88         area[n] = len >> 8;
89         area[n+1] = len;
90         m_free(p);
91     }
92     else { /* bool */
93         area[n] = 0;
94         area[n+1] = 1;
95         area[n+2] = yes;
96     }
97     area[3] = 1; /* we should better use a semaphore */
98     kill( serverpid, SIGUSR1 );
99 }
100
101
102
103 int
104 main(int argc, char **argv)
105 {
106     void  *area = NULL;
107     size_t areasize = 4096;
108     int shm_id = -1;
109     FILE *fp;
110     char buf[200];
111     char *p, *p2;
112     size_t n;
113     int i;
114
115     log_set_name("shmtest");
116     i18n_init();
117   #ifndef USE_SHM_COPROCESSING
118     log_info("SHM_COPRPOCESSING is not available\n");
119   #else
120     if( argc < 1 )
121         my_usage();
122
123     for(n=0,i=1; i < argc; i++ )
124         n += strlen(argv[i]) + 1;
125     p = m_alloc( 100 + n );
126     strcpy( p, "../g10/gpg --status-fd 1 --run-as-shm-coprocess 0");
127     for(i=1; i < argc; i++ ) {
128         strcat(p, " " );
129         strcat(p, argv[i] );
130     }
131
132     fp = popen( p, "r" );
133     m_free( p );
134     if( !fp )
135         log_error("popen failed: %s\n", strerror(errno));
136
137     while ( fgets (buf, sizeof (buf) - 1, fp ) != NULL ) {
138         size_t len = strlen(buf);
139         if( len >= 9 && !memcmp( buf, "[GNUPG:] ", 9 ) ) {
140             int word=0;
141             int is_info = 0, is_get = 0;
142
143             for( p = strtok(buf+9, " \n"); p ; p = strtok(NULL, " \n")) {
144                 word++;
145                 if( word==1 && !strcmp(p,"SHM_INFO") ) {
146                     if( !area )
147                         is_info=1;
148                     else
149                         log_error("duplicate SHM_INFO ignored\n" );
150                 }
151                 else if( is_info && (p2 = strchr(p, '=' )) ) {
152                     int val;
153                     *p2++ = 0;
154                     val = atoi(p2); /* should be atou() for some values */
155                     if( !strcmp(p, "pv" ) ) {
156                         if( atoi(p2) != 1 )
157                             log_fatal("invalid protocol version %d\n", val );
158                         is_info = 2;
159                     }
160                     else if( !strcmp(p, "pid" ) )
161                         serverpid = val;
162                     else if( !strcmp(p, "shmid" ) )
163                         shm_id = val;
164                 }
165                 else if( word == 1 && !strcmp(p,"SHM_GET") )
166                     is_get = 1;
167                 else if( word == 1 && !strcmp(p,"SHM_GET_BOOL") )
168                     is_get = 2;
169                 else if( word == 1 && !strcmp(p,"SHM_GET_HIDDEN") )
170                     is_get = 3;
171                 else if( word == 2 && is_get )  {
172                     do_get_string( is_get, p, area, areasize );
173                     break;
174                 }
175                 else if( word == 1 )
176                     log_info("Status: %s\n", p);
177             }
178             if( is_info ) {
179                 if( is_info < 2 )
180                     log_fatal("SHM info without protocol version\n");
181                 if( serverpid == -1 )
182                     log_fatal("SHM info without server's pid\n");
183                 if( shm_id == -1 )
184                     log_fatal("SHM info without id\n");
185                 log_info("Shared memory info: server=%d shm_id=%d\n",
186                                                             serverpid, shm_id);
187                 area = shmat( shm_id, 0, 0 );
188                 if( area == (void*)-1 )
189                     log_fatal("attach to shared memory failed: %s\n",
190                                                             strerror(errno));
191             }
192         }
193         else
194             fputs (buf, stdout);
195     }
196
197
198     if( pclose(fp) )
199         log_error("pclose failed\n");
200
201     return 0;
202   #endif
203 }
204
205
206 #endif