00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "auto-host.h"
00049
00050 #include "ansidecl.h"
00051 #include "system.h"
00052 #include <signal.h>
00053
00054 #include "server.h"
00055
00056 #if !defined(volatile) && !defined(HAVE_VOLATILE)
00057 # define volatile
00058 #endif
00059
00060 STATIC volatile enum t_bool read_pipe_timeout;
00061 STATIC pid_t server_master_pid = NOPROCESS;
00062
00063 tSCC* def_args[] =
00064 { (char *) NULL, (char *) NULL };
00065 STATIC t_pf_pair server_pair =
00066 { (FILE *) NULL, (FILE *) NULL };
00067 STATIC pid_t server_id = NULLPROCESS;
00068
00069
00070
00071
00072
00073 tSCC z_done[] = "ShElL-OuTpUt-HaS-bEeN-cOmPlEtEd";
00074 tSCC* p_cur_dir = (char *) NULL;
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 static char *load_data PARAMS ((FILE *));
00085 static char *
00086 load_data (fp)
00087 FILE *fp;
00088 {
00089 char *pz_text;
00090 size_t text_size;
00091 char *pz_scan;
00092 char z_line[1024];
00093 t_bool got_done = BOOL_FALSE;
00094
00095 text_size = sizeof (z_line) * 2;
00096 pz_scan = pz_text = xmalloc (text_size);
00097
00098 for (;;)
00099 {
00100 size_t used_ct;
00101
00102 alarm (10);
00103 read_pipe_timeout = BOOL_FALSE;
00104 if (fgets (z_line, sizeof (z_line), fp) == (char *) NULL)
00105 break;
00106
00107 if (strncmp (z_line, z_done, sizeof (z_done) - 1) == 0)
00108 {
00109 got_done = BOOL_TRUE;
00110 break;
00111 }
00112
00113 strcpy (pz_scan, z_line);
00114 pz_scan += strlen (z_line);
00115 used_ct = (size_t) (pz_scan - pz_text);
00116
00117 if (text_size - used_ct < sizeof (z_line))
00118 {
00119 size_t off = (size_t) (pz_scan - pz_text);
00120
00121 text_size += 4096;
00122 pz_text = xrealloc ((void *) pz_text, text_size);
00123 pz_scan = pz_text + off;
00124 }
00125 }
00126
00127 alarm (0);
00128 if (read_pipe_timeout || ! got_done)
00129 {
00130 free ((void *) pz_text);
00131 return (char *) NULL;
00132 }
00133
00134 while ((pz_scan > pz_text) && ISSPACE (pz_scan[-1]))
00135 pz_scan--;
00136 *pz_scan = NUL;
00137 return xrealloc ((void *) pz_text, strlen (pz_text) + 1);
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147 void
00148 close_server ()
00149 {
00150 if ( (server_id != NULLPROCESS)
00151 && (server_master_pid == getpid ()))
00152 {
00153 kill ((pid_t) server_id, SIGKILL);
00154 server_id = NULLPROCESS;
00155 server_master_pid = NOPROCESS;
00156 fclose (server_pair.pf_read);
00157 fclose (server_pair.pf_write);
00158 server_pair.pf_read = server_pair.pf_write = (FILE *) NULL;
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 static void sig_handler PARAMS ((int));
00169 static void
00170 sig_handler (signo)
00171 int signo ATTRIBUTE_UNUSED;
00172 {
00173 #ifdef DEBUG
00174
00175 fprintf (stderr,
00176 "fixincl ERROR: sig_handler: killed pid %ld due to %s\n",
00177 (long) server_id, signo == SIGPIPE ? "SIGPIPE" : "SIGALRM");
00178 #endif
00179 close_server ();
00180 read_pipe_timeout = BOOL_TRUE;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 static void server_setup PARAMS ((void));
00190 static void
00191 server_setup ()
00192 {
00193 static int atexit_done = 0;
00194
00195 if (atexit_done++ == 0)
00196 atexit (close_server);
00197 else
00198 fputs ("NOTE: server restarted\n", stderr);
00199
00200 server_master_pid = getpid ();
00201
00202 signal (SIGPIPE, sig_handler);
00203 signal (SIGALRM, sig_handler);
00204
00205 fputs ("trap : 1\n", server_pair.pf_write);
00206 fflush (server_pair.pf_write);
00207 p_cur_dir = getcwd ((char *) NULL, MAXPATHLEN + 1);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 static const char *find_shell PARAMS ((void));
00223 static const char *
00224 find_shell ()
00225 {
00226 char * shell = getenv ("CONFIG_SHELL");
00227 if (shell)
00228 return shell;
00229
00230 return "/bin/sh";
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 char *
00254 run_shell (pz_cmd)
00255 const char *pz_cmd;
00256 {
00257 tSCC zNoServer[] = "Server not running, cannot run:\n%s\n\n";
00258 t_bool retry = BOOL_TRUE;
00259
00260 do_retry:
00261
00262
00263 if (server_id == NULLPROCESS)
00264 {
00265 def_args[0] = find_shell ();
00266
00267 server_id = proc2_fopen (&server_pair, def_args);
00268 if (server_id > 0)
00269 server_setup ();
00270 }
00271
00272
00273 if (server_id <= 0)
00274 {
00275 fprintf (stderr, zNoServer, pz_cmd);
00276 return xcalloc (1, 1);
00277 }
00278
00279
00280
00281
00282 fprintf (server_pair.pf_write, "cd %s\n%s\n\necho\necho %s\n",
00283 p_cur_dir, pz_cmd, z_done);
00284 fflush (server_pair.pf_write);
00285
00286
00287
00288 if (server_id == NULLPROCESS)
00289 {
00290 fprintf (stderr, zNoServer, pz_cmd);
00291 return xcalloc (1, 1);
00292 }
00293
00294
00295
00296 {
00297 char *pz = load_data (server_pair.pf_read);
00298
00299 if (pz == (char *) NULL)
00300 {
00301 close_server ();
00302
00303 if (retry)
00304 {
00305 retry = BOOL_FALSE;
00306 goto do_retry;
00307 }
00308
00309 fprintf (stderr, "CLOSING SHELL SERVER - command failure:\n\t%s\n",
00310 pz_cmd);
00311 pz = xcalloc (1, 1);
00312 }
00313 #ifdef DEBUG
00314 fprintf( stderr, "run_shell command success: %s\n", pz );
00315 #endif
00316 return pz;
00317 }
00318 }