| File: | restart.c |
| Location: | line 42, column 13 |
| Description: | Null pointer argument in call to string comparison function |
| 1 | /* $Xorg: restart.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */ | |||
| 2 | /****************************************************************************** | |||
| 3 | ||||
| 4 | Copyright 1993, 1998 The Open Group | |||
| 5 | ||||
| 6 | Permission to use, copy, modify, distribute, and sell this software and its | |||
| 7 | documentation for any purpose is hereby granted without fee, provided that | |||
| 8 | the above copyright notice appear in all copies and that both that | |||
| 9 | copyright notice and this permission notice appear in supporting | |||
| 10 | documentation. | |||
| 11 | ||||
| 12 | The above copyright notice and this permission notice shall be included in | |||
| 13 | all copies or substantial portions of the Software. | |||
| 14 | ||||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| 18 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
| 19 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| 21 | ||||
| 22 | Except as contained in this notice, the name of The Open Group shall not be | |||
| 23 | used in advertising or otherwise to promote the sale, use or other dealings | |||
| 24 | in this Software without prior written authorization from The Open Group. | |||
| 25 | ******************************************************************************/ | |||
| 26 | /* $XFree86: xc/programs/xsm/restart.c,v 1.5 2001/01/17 23:46:30 dawes Exp $ */ | |||
| 27 | ||||
| 28 | #include "xsm.h" | |||
| 29 | #include "log.h" | |||
| 30 | #include "restart.h" | |||
| 31 | #include "saveutil.h" | |||
| 32 | ||||
| 33 | ||||
| 34 | /* | |||
| 35 | * Until XSMP provides a better way to know which clients are "managers", | |||
| 36 | * we have to hard code the list. | |||
| 37 | */ | |||
| 38 | ||||
| 39 | Boolint | |||
| 40 | CheckIsManager(char *program) | |||
| 41 | { | |||
| 42 | return (strcmp (program, "twm") == 0); | |||
| ||||
| 43 | } | |||
| 44 | ||||
| 45 | ||||
| 46 | ||||
| 47 | /* | |||
| 48 | * GetRestartInfo() will determine which method should be used to | |||
| 49 | * restart a client. | |||
| 50 | * | |||
| 51 | * 'restart_service_prop' is a property set by the client, or NULL. | |||
| 52 | * The format is "remote_start_protocol/remote_start_data". An | |||
| 53 | * example is "rstart-rsh/hostname". This is a non-standard property, | |||
| 54 | * which is the whole reason we need this function in order to determine | |||
| 55 | * the restart method. The proxy uses this property to over-ride the | |||
| 56 | * 'client_host_name' from the ICE connection (the proxy is connected to | |||
| 57 | * the SM via a local connection, but the proxy may be acting as a proxy | |||
| 58 | * for a remote client). | |||
| 59 | * | |||
| 60 | * 'client_host_name' is the connection info obtained from the ICE | |||
| 61 | * connection. It's format is "transport/host_info". An example | |||
| 62 | * is "tcp/machine:port". | |||
| 63 | * | |||
| 64 | * If 'restart_service_prop' is NULL, we use 'client_host_name' to | |||
| 65 | * determine the restart method. If the transport is "local", we | |||
| 66 | * do a local restart. Otherwise, we use the default "rstart-rsh" method. | |||
| 67 | * | |||
| 68 | * If 'restart_service_prop' is non-NULL, we check the remote_start_protocol | |||
| 69 | * field. "local" means a local restart. Currently, the only remote | |||
| 70 | * protocol we recognize is "rstart-rsh". If the remote protocol is | |||
| 71 | * "rstart-rsh" but the hostname in the 'restart_service_prop' matches | |||
| 72 | * 'client_host_name', we do a local restart. | |||
| 73 | * | |||
| 74 | * On return, set the run_local flag, restart_protocol and restart_machine. | |||
| 75 | */ | |||
| 76 | ||||
| 77 | void | |||
| 78 | GetRestartInfo(char *restart_service_prop, char *client_host_name, | |||
| 79 | Boolint *run_local, char **restart_protocol, char **restart_machine) | |||
| 80 | { | |||
| 81 | char hostnamebuf[80]; | |||
| 82 | char *temp; | |||
| 83 | ||||
| 84 | *run_local = False0; | |||
| 85 | *restart_protocol = NULL((void*)0); | |||
| 86 | *restart_machine = NULL((void*)0); | |||
| 87 | ||||
| 88 | if (restart_service_prop) | |||
| 89 | { | |||
| 90 | gethostname (hostnamebuf, sizeof hostnamebuf); | |||
| 91 | ||||
| 92 | if ((temp = (char *) strchr ( | |||
| 93 | restart_service_prop, '/')) == NULL((void*)0)) | |||
| 94 | { | |||
| 95 | *restart_protocol = (char *) XtNewString ("rstart-rsh")(("rstart-rsh") != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc ((unsigned)strlen("rstart-rsh") + 1), "rstart-rsh", __builtin_object_size (XtMalloc((unsigned)strlen("rstart-rsh") + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
| 96 | *restart_machine = (char *) XtNewString (restart_service_prop)((restart_service_prop) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned)strlen(restart_service_prop) + 1), restart_service_prop , __builtin_object_size (XtMalloc((unsigned)strlen(restart_service_prop ) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
| 97 | } | |||
| 98 | else | |||
| 99 | { | |||
| 100 | *restart_protocol = (char *) XtNewString (restart_service_prop)((restart_service_prop) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned)strlen(restart_service_prop) + 1), restart_service_prop , __builtin_object_size (XtMalloc((unsigned)strlen(restart_service_prop ) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
| 101 | (*restart_protocol)[temp - restart_service_prop] = '\0'; | |||
| 102 | *restart_machine = (char *) XtNewString (temp + 1)((temp + 1) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc ((unsigned)strlen(temp + 1) + 1), temp + 1, __builtin_object_size (XtMalloc((unsigned)strlen(temp + 1) + 1), 2 > 1 ? 1 : 0) )) : ((void*)0)); | |||
| 103 | } | |||
| 104 | ||||
| 105 | if (strcmp (*restart_machine, hostnamebuf) == 0 || | |||
| 106 | strcmp (*restart_protocol, "local") == 0) | |||
| 107 | { | |||
| 108 | *run_local = True1; | |||
| 109 | } | |||
| 110 | } | |||
| 111 | else | |||
| 112 | { | |||
| 113 | if (strncmp (client_host_name, "tcp/", 4) != 0 && | |||
| 114 | strncmp (client_host_name, "decnet/", 7) != 0) | |||
| 115 | { | |||
| 116 | *run_local = True1; | |||
| 117 | } | |||
| 118 | else | |||
| 119 | { | |||
| 120 | *restart_protocol = (char *) XtNewString ("rstart-rsh")(("rstart-rsh") != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc ((unsigned)strlen("rstart-rsh") + 1), "rstart-rsh", __builtin_object_size (XtMalloc((unsigned)strlen("rstart-rsh") + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
| 121 | ||||
| 122 | if ((temp = (char *) strchr ( | |||
| 123 | client_host_name, '/')) == NULL((void*)0)) | |||
| 124 | { | |||
| 125 | *restart_machine = (char *) XtNewString (client_host_name)((client_host_name) != ((void*)0) ? (__builtin___strcpy_chk ( XtMalloc((unsigned)strlen(client_host_name) + 1), client_host_name , __builtin_object_size (XtMalloc((unsigned)strlen(client_host_name ) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
| 126 | } | |||
| 127 | else | |||
| 128 | { | |||
| 129 | *restart_machine = (char *) XtNewString (temp + 1)((temp + 1) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc ((unsigned)strlen(temp + 1) + 1), temp + 1, __builtin_object_size (XtMalloc((unsigned)strlen(temp + 1) + 1), 2 > 1 ? 1 : 0) )) : ((void*)0)); | |||
| 130 | } | |||
| 131 | } | |||
| 132 | } | |||
| 133 | } | |||
| 134 | ||||
| 135 | ||||
| 136 | ||||
| 137 | /* | |||
| 138 | * Restart clients. The flag indicates RESTART_MANAGERS or | |||
| 139 | * RESTART_REST_OF_CLIENTS. | |||
| 140 | */ | |||
| 141 | ||||
| 142 | Statusint | |||
| 143 | Restart(int flag) | |||
| 144 | { | |||
| 145 | List *cl, *pl, *vl; | |||
| 146 | PendingClient *c; | |||
| 147 | Prop *prop; | |||
| 148 | const char *cwd; | |||
| 149 | char *program; | |||
| 150 | char **args; | |||
| 151 | char **env; | |||
| 152 | char **pp; | |||
| 153 | int cnt; | |||
| 154 | char *p; | |||
| 155 | char *restart_service_prop; | |||
| 156 | char *restart_protocol; | |||
| 157 | char *restart_machine; | |||
| 158 | Boolint run_local; | |||
| 159 | Boolint is_manager; | |||
| 160 | Boolint ran_manager = 0; | |||
| 161 | ||||
| 162 | for(cl = ListFirst(PendingList); cl; cl = ListNext(cl)) { | |||
| ||||
| 163 | c = (PendingClient *)cl->thing; | |||
| 164 | ||||
| 165 | if (verbose) { | |||
| 166 | printf("Restarting id '%s'...\n", c->clientId); | |||
| 167 | printf("Host = %s\n", c->clientHostname); | |||
| 168 | } | |||
| 169 | cwd = "."; | |||
| 170 | env = NULL((void*)0); | |||
| 171 | program=NULL((void*)0); | |||
| 172 | args=NULL((void*)0); | |||
| 173 | restart_service_prop=NULL((void*)0); | |||
| 174 | ||||
| 175 | is_manager = 0; | |||
| 176 | ||||
| 177 | for(pl = ListFirst(c->props); pl; pl = ListNext(pl)) { | |||
| 178 | prop = (Prop *)pl->thing; | |||
| 179 | if(!strcmp(prop->name, SmProgram"Program")) { | |||
| 180 | vl = ListFirst(prop->values); | |||
| 181 | if(vl) program = ((PropValue *)vl->thing)->value; | |||
| 182 | if (CheckIsManager (program)) | |||
| 183 | is_manager = 1; | |||
| 184 | } else if(!strcmp(prop->name, SmCurrentDirectory"CurrentDirectory")) { | |||
| 185 | vl = ListFirst(prop->values); | |||
| 186 | if(vl) cwd = ((PropValue *)vl->thing)->value; | |||
| 187 | } else if(!strcmp(prop->name, "_XC_RestartService")) { | |||
| 188 | vl = ListFirst(prop->values); | |||
| 189 | if(vl) restart_service_prop = | |||
| 190 | ((PropValue *)vl->thing)->value; | |||
| 191 | } else if(!strcmp(prop->name, SmRestartCommand"RestartCommand")) { | |||
| 192 | cnt = ListCount(prop->values); | |||
| 193 | args = (char **)XtMalloc((cnt+1) * sizeof(char *)); | |||
| 194 | pp = args; | |||
| 195 | for(vl = ListFirst(prop->values); vl; vl = ListNext(vl)) { | |||
| 196 | *pp++ = ((PropValue *)vl->thing)->value; | |||
| 197 | } | |||
| 198 | *pp = NULL((void*)0); | |||
| 199 | } else if(!strcmp(prop->name, SmEnvironment"Environment")) { | |||
| 200 | cnt = ListCount(prop->values); | |||
| 201 | env = (char **)XtMalloc((cnt+3+1) * sizeof(char *)); | |||
| 202 | pp = env; | |||
| 203 | for(vl = ListFirst(prop->values); vl; vl = ListNext(vl)) { | |||
| 204 | p = ((PropValue *)vl->thing)->value; | |||
| 205 | if((display_env && strbw(p, "DISPLAY=")) | |||
| 206 | || (session_env && strbw(p, "SESSION_MANAGER=")) | |||
| 207 | || (audio_env && strbw(p, "AUDIOSERVER=")) | |||
| 208 | ) continue; | |||
| 209 | *pp++ = p; | |||
| 210 | } | |||
| 211 | if(display_env) *pp++ = display_env; | |||
| 212 | if(session_env) *pp++ = session_env; | |||
| 213 | if(audio_env) *pp++ = audio_env; | |||
| 214 | *pp = NULL((void*)0); | |||
| 215 | } | |||
| 216 | } | |||
| 217 | ||||
| 218 | if(program && args) { | |||
| 219 | char logtext[256]; | |||
| 220 | ||||
| 221 | if ((flag == RESTART_MANAGERS1 && !is_manager) || | |||
| 222 | (flag == RESTART_REST_OF_CLIENTS2 && is_manager)) | |||
| 223 | { | |||
| 224 | if(args) XtFree((char *)args); | |||
| 225 | if(env) XtFree((char *)env); | |||
| 226 | continue; | |||
| 227 | } | |||
| 228 | ||||
| 229 | if (flag == RESTART_MANAGERS1 && is_manager) | |||
| 230 | ran_manager = 1; | |||
| 231 | ||||
| 232 | if (verbose) { | |||
| 233 | printf("\t%s\n", program); | |||
| 234 | printf("\t"); | |||
| 235 | for(pp = args; *pp; pp++) printf("%s ", *pp); | |||
| 236 | printf("\n"); | |||
| 237 | } | |||
| 238 | ||||
| 239 | GetRestartInfo (restart_service_prop, c->clientHostname, | |||
| 240 | &run_local, &restart_protocol, &restart_machine); | |||
| 241 | ||||
| 242 | if (run_local) | |||
| 243 | { | |||
| 244 | /* | |||
| 245 | * The client is being restarted on the local machine. | |||
| 246 | */ | |||
| 247 | ||||
| 248 | snprintf (logtext, sizeof(logtext), "Restarting locally : ")__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "Restarting locally : "); | |||
| 249 | for (pp = args; *pp; pp++) | |||
| 250 | { | |||
| 251 | strcat (logtext, *pp)__builtin___strcat_chk (logtext, *pp, __builtin_object_size ( logtext, 2 > 1 ? 1 : 0)); | |||
| 252 | strcat (logtext, " ")__builtin___strcat_chk (logtext, " ", __builtin_object_size ( logtext, 2 > 1 ? 1 : 0)); | |||
| 253 | } | |||
| 254 | ||||
| 255 | strcat (logtext, "\n")__builtin___strcat_chk (logtext, "\n", __builtin_object_size ( logtext, 2 > 1 ? 1 : 0)); | |||
| 256 | add_log_text (logtext); | |||
| 257 | ||||
| 258 | switch(fork()) { | |||
| 259 | case -1: | |||
| 260 | snprintf (logtext, sizeof(logtext),__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "%s: Can't fork() %s", Argv[0], program) | |||
| 261 | "%s: Can't fork() %s", Argv[0], program)__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "%s: Can't fork() %s", Argv[0], program); | |||
| 262 | add_log_text (logtext); | |||
| 263 | perror (logtext); | |||
| 264 | break; | |||
| 265 | case 0: /* kid */ | |||
| 266 | chdir(cwd); | |||
| 267 | if(env) environ = env; | |||
| 268 | execvp(program, args); | |||
| 269 | snprintf (logtext, sizeof(logtext),__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "%s: Can't execvp() %s", Argv[0 ], program) | |||
| 270 | "%s: Can't execvp() %s", Argv[0], program)__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "%s: Can't execvp() %s", Argv[0 ], program); | |||
| 271 | perror (logtext); | |||
| 272 | /* | |||
| 273 | * TODO : We would like to send this log information to the | |||
| 274 | * log window in the parent. This would require opening | |||
| 275 | * a pipe between the parent and child. The child would | |||
| 276 | * set close-on-exec. If the exec succeeds, the pipe will | |||
| 277 | * be closed. If it fails, the child can write a message | |||
| 278 | * to the parent. | |||
| 279 | */ | |||
| 280 | _exit(255); | |||
| 281 | default: /* parent */ | |||
| 282 | break; | |||
| 283 | } | |||
| 284 | } | |||
| 285 | else if (!remote_allowed) | |||
| 286 | { | |||
| 287 | fprintf(stderr__stderrp, | |||
| 288 | "Can't remote start client ID '%s': only local supported\n", | |||
| 289 | c->clientId); | |||
| 290 | } | |||
| 291 | else | |||
| 292 | { | |||
| 293 | /* | |||
| 294 | * The client is being restarted on a remote machine. | |||
| 295 | */ | |||
| 296 | ||||
| 297 | snprintf (logtext, sizeof(logtext),__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "Restarting remotely on %s : ", restart_machine) | |||
| 298 | "Restarting remotely on %s : ", restart_machine)__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "Restarting remotely on %s : ", restart_machine); | |||
| 299 | for (pp = args; *pp; pp++) | |||
| 300 | { | |||
| 301 | strcat (logtext, *pp)__builtin___strcat_chk (logtext, *pp, __builtin_object_size ( logtext, 2 > 1 ? 1 : 0)); | |||
| 302 | strcat (logtext, " ")__builtin___strcat_chk (logtext, " ", __builtin_object_size ( logtext, 2 > 1 ? 1 : 0)); | |||
| 303 | } | |||
| 304 | strcat (logtext, "\n")__builtin___strcat_chk (logtext, "\n", __builtin_object_size ( logtext, 2 > 1 ? 1 : 0)); | |||
| 305 | add_log_text (logtext); | |||
| 306 | ||||
| 307 | remote_start (restart_protocol, restart_machine, | |||
| 308 | program, args, cwd, env, | |||
| 309 | non_local_display_env, non_local_session_env); | |||
| 310 | } | |||
| 311 | ||||
| 312 | if (restart_protocol) | |||
| 313 | XtFree (restart_protocol); | |||
| 314 | ||||
| 315 | if (restart_machine) | |||
| 316 | XtFree (restart_machine); | |||
| 317 | ||||
| 318 | } else { | |||
| 319 | fprintf(stderr__stderrp, "Can't restart ID '%s': no program or no args\n", | |||
| 320 | c->clientId); | |||
| 321 | } | |||
| 322 | if(args) XtFree((char *)args); | |||
| 323 | if(env) XtFree((char *)env); | |||
| 324 | } | |||
| 325 | ||||
| 326 | if (flag == RESTART_MANAGERS1 && !ran_manager) | |||
| 327 | return (0); | |||
| 328 | else | |||
| 329 | return (1); | |||
| 330 | } | |||
| 331 | ||||
| 332 | ||||
| 333 | ||||
| 334 | /* | |||
| 335 | * Clone a client | |||
| 336 | */ | |||
| 337 | ||||
| 338 | void | |||
| 339 | Clone(ClientRec *client, Boolint useSavedState) | |||
| 340 | { | |||
| 341 | const char *cwd; | |||
| 342 | char *program; | |||
| 343 | char **args; | |||
| 344 | char **env; | |||
| 345 | char **pp; | |||
| 346 | char *p; | |||
| 347 | char *restart_service_prop; | |||
| 348 | char *restart_protocol; | |||
| 349 | char *restart_machine; | |||
| 350 | Boolint run_local; | |||
| 351 | List *pl, *pj; | |||
| 352 | ||||
| 353 | if (verbose) | |||
| 354 | { | |||
| 355 | printf ("Cloning id '%s', useSavedState = %d...\n", | |||
| 356 | client->clientId, useSavedState); | |||
| 357 | printf ("Host = %s\n", client->clientHostname); | |||
| 358 | } | |||
| 359 | ||||
| 360 | cwd = "."; | |||
| 361 | env = NULL((void*)0); | |||
| 362 | program = NULL((void*)0); | |||
| 363 | args = NULL((void*)0); | |||
| 364 | restart_service_prop = NULL((void*)0); | |||
| 365 | ||||
| 366 | for (pl = ListFirst (client->props); pl; pl = ListNext (pl)) | |||
| 367 | { | |||
| 368 | Prop *pprop = (Prop *) pl->thing; | |||
| 369 | List *vl = ListFirst (pprop->values); | |||
| 370 | PropValue *pval = (PropValue *) vl->thing; | |||
| 371 | ||||
| 372 | if (strcmp (pprop->name, SmProgram"Program") == 0) | |||
| 373 | program = (char *) pval->value; | |||
| 374 | else if (strcmp (pprop->name, SmCurrentDirectory"CurrentDirectory") == 0) | |||
| 375 | cwd = (char *) pval->value; | |||
| 376 | else if (strcmp (pprop->name, "_XC_RestartService") == 0) | |||
| 377 | restart_service_prop = (char *) pval->value; | |||
| 378 | else if ( | |||
| 379 | (!useSavedState && strcmp (pprop->name, SmCloneCommand"CloneCommand") == 0) || | |||
| 380 | (useSavedState && strcmp (pprop->name, SmRestartCommand"RestartCommand") == 0)) | |||
| 381 | { | |||
| 382 | args = (char **) XtMalloc ( | |||
| 383 | (ListCount (pprop->values) + 1) * sizeof (char *)); | |||
| 384 | ||||
| 385 | pp = args; | |||
| 386 | ||||
| 387 | for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj)) | |||
| 388 | { | |||
| 389 | pval = (PropValue *) pj->thing; | |||
| 390 | *pp++ = (char *) pval->value; | |||
| 391 | } | |||
| 392 | *pp = NULL((void*)0); | |||
| 393 | } | |||
| 394 | else if (strcmp (pprop->name, SmEnvironment"Environment") == 0) | |||
| 395 | { | |||
| 396 | env = (char **) XtMalloc ( | |||
| 397 | (ListCount (pprop->values) + 3 + 1) * sizeof (char *)); | |||
| 398 | pp = env; | |||
| 399 | ||||
| 400 | for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj)) | |||
| 401 | { | |||
| 402 | pval = (PropValue *) pj->thing; | |||
| 403 | p = (char *) pval->value; | |||
| 404 | ||||
| 405 | if ((display_env && strbw (p, "DISPLAY=")) | |||
| 406 | || (session_env && strbw (p, "SESSION_MANAGER=")) | |||
| 407 | || (audio_env && strbw (p, "AUDIOSERVER="))) | |||
| 408 | continue; | |||
| 409 | ||||
| 410 | *pp++ = p; | |||
| 411 | } | |||
| 412 | ||||
| 413 | if (display_env) | |||
| 414 | *pp++ = display_env; | |||
| 415 | if (session_env) | |||
| 416 | *pp++ = session_env; | |||
| 417 | if (audio_env) | |||
| 418 | *pp++ = audio_env; | |||
| 419 | ||||
| 420 | *pp = NULL((void*)0); | |||
| 421 | } | |||
| 422 | } | |||
| 423 | ||||
| 424 | if (program && args) | |||
| 425 | { | |||
| 426 | if (verbose) | |||
| 427 | { | |||
| 428 | printf("\t%s\n", program); | |||
| 429 | printf("\t"); | |||
| 430 | for (pp = args; *pp; pp++) | |||
| 431 | printf ("%s ", *pp); | |||
| 432 | printf("\n"); | |||
| 433 | } | |||
| 434 | ||||
| 435 | GetRestartInfo (restart_service_prop, client->clientHostname, | |||
| 436 | &run_local, &restart_protocol, &restart_machine); | |||
| 437 | ||||
| 438 | if (run_local) | |||
| 439 | { | |||
| 440 | /* | |||
| 441 | * The client is being cloned on the local machine. | |||
| 442 | */ | |||
| 443 | ||||
| 444 | char msg[256]; | |||
| 445 | ||||
| 446 | switch(fork()) { | |||
| 447 | case -1: | |||
| 448 | snprintf (msg, sizeof(msg),__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size (msg, 2 > 1 ? 1 : 0), "%s: Can't fork() %s", Argv[0], program ) | |||
| 449 | "%s: Can't fork() %s", Argv[0], program)__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size (msg, 2 > 1 ? 1 : 0), "%s: Can't fork() %s", Argv[0], program ); | |||
| 450 | add_log_text (msg); | |||
| 451 | perror (msg); | |||
| 452 | break; | |||
| 453 | case 0: /* kid */ | |||
| 454 | chdir(cwd); | |||
| 455 | if(env) environ = env; | |||
| 456 | execvp(program, args); | |||
| 457 | snprintf (msg, sizeof(msg),__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size (msg, 2 > 1 ? 1 : 0), "%s: Can't execvp() %s", Argv[0], program ) | |||
| 458 | "%s: Can't execvp() %s", Argv[0], program)__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size (msg, 2 > 1 ? 1 : 0), "%s: Can't execvp() %s", Argv[0], program ); | |||
| 459 | perror (msg); | |||
| 460 | /* | |||
| 461 | * TODO : We would like to send this log information to the | |||
| 462 | * log window in the parent. This would require opening | |||
| 463 | * a pipe between the parent and child. The child would | |||
| 464 | * set close-on-exec. If the exec succeeds, the pipe will | |||
| 465 | * be closed. If it fails, the child can write a message | |||
| 466 | * to the parent. | |||
| 467 | */ | |||
| 468 | _exit(255); | |||
| 469 | default: /* parent */ | |||
| 470 | break; | |||
| 471 | } | |||
| 472 | } | |||
| 473 | else if (!remote_allowed) | |||
| 474 | { | |||
| 475 | fprintf(stderr__stderrp, | |||
| 476 | "Can't remote clone client ID '%s': only local supported\n", | |||
| 477 | client->clientId); | |||
| 478 | } | |||
| 479 | else | |||
| 480 | { | |||
| 481 | /* | |||
| 482 | * The client is being cloned on a remote machine. | |||
| 483 | */ | |||
| 484 | ||||
| 485 | remote_start (restart_protocol, restart_machine, | |||
| 486 | program, args, cwd, env, | |||
| 487 | non_local_display_env, non_local_session_env); | |||
| 488 | } | |||
| 489 | ||||
| 490 | if (restart_protocol) | |||
| 491 | XtFree (restart_protocol); | |||
| 492 | ||||
| 493 | if (restart_machine) | |||
| 494 | XtFree (restart_machine); | |||
| 495 | ||||
| 496 | } | |||
| 497 | else | |||
| 498 | { | |||
| 499 | #ifdef XKB | |||
| 500 | XkbStdBell(XtDisplay(topLevel),XtWindow(topLevel),0,XkbBI_Failure); | |||
| 501 | #else | |||
| 502 | XBell (XtDisplay (topLevel), 0); | |||
| 503 | #endif | |||
| 504 | ||||
| 505 | fprintf(stderr__stderrp, "Can't restart ID '%s': no program or no args\n", | |||
| 506 | client->clientId); | |||
| 507 | } | |||
| 508 | ||||
| 509 | if (args) | |||
| 510 | XtFree ((char *)args); | |||
| 511 | if (env) | |||
| 512 | XtFree ((char *)env); | |||
| 513 | } | |||
| 514 | ||||
| 515 | ||||
| 516 | ||||
| 517 | void | |||
| 518 | StartDefaultApps (void) | |||
| 519 | { | |||
| 520 | FILE *f; | |||
| 521 | char *buf, *p, filename[128]; | |||
| 522 | const char *home; | |||
| 523 | int buflen, len; | |||
| 524 | ||||
| 525 | /* | |||
| 526 | * First try ~/.xsmstartup, then system.xsm | |||
| 527 | */ | |||
| 528 | ||||
| 529 | home = getenv ("HOME"); | |||
| 530 | if (!home) | |||
| 531 | home = "."; | |||
| 532 | snprintf (filename, sizeof(filename), "%s/.xsmstartup", home)__builtin___snprintf_chk (filename, sizeof(filename), 0, __builtin_object_size (filename, 2 > 1 ? 1 : 0), "%s/.xsmstartup", home); | |||
| 533 | ||||
| 534 | f = fopen (filename, "r"); | |||
| 535 | ||||
| 536 | if (!f) | |||
| 537 | { | |||
| 538 | f = fopen (SYSTEM_INIT_FILE"/Users/jeremy/src/freedesktop/jhbuild/build/etc/X11/xsm/system.xsm", "r"); | |||
| 539 | if (!f) | |||
| 540 | { | |||
| 541 | printf ("Could not find default apps file. Make sure you did\n"); | |||
| 542 | printf ("a 'make install' in the xsm build directory.\n"); | |||
| 543 | exit (1); | |||
| 544 | } | |||
| 545 | } | |||
| 546 | fcntl(fileno(f), F_SETFD2, FD_CLOEXEC1); | |||
| 547 | ||||
| 548 | buf = NULL((void*)0); | |||
| 549 | buflen = 0; | |||
| 550 | ||||
| 551 | while (getnextline(&buf, &buflen, f)) | |||
| 552 | { | |||
| 553 | char logtext[256]; | |||
| 554 | ||||
| 555 | if (buf[0] == '!') | |||
| 556 | continue; /* a comment */ | |||
| 557 | ||||
| 558 | if ((p = strchr (buf, '\n'))) | |||
| 559 | *p = '\0'; | |||
| 560 | ||||
| 561 | snprintf (logtext, sizeof(logtext), "Starting locally : %s\n", buf)__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "Starting locally : %s\n", buf); | |||
| 562 | add_log_text (logtext); | |||
| 563 | ||||
| 564 | len = strlen (buf); | |||
| 565 | ||||
| 566 | buf[len] = '&'; | |||
| 567 | buf[len+1] = '\0'; | |||
| 568 | ||||
| 569 | /* let the shell parse the stupid args */ | |||
| 570 | ||||
| 571 | execute_system_command (buf); | |||
| 572 | } | |||
| 573 | ||||
| 574 | if (buf) | |||
| 575 | free (buf); | |||
| 576 | } | |||
| 577 | ||||
| 578 | ||||
| 579 | ||||
| 580 | void | |||
| 581 | StartNonSessionAwareApps(void) | |||
| 582 | { | |||
| 583 | char logtext[256]; | |||
| 584 | int i; | |||
| 585 | ||||
| 586 | for (i = 0; i < non_session_aware_count; i++) | |||
| 587 | { | |||
| 588 | /* | |||
| 589 | * Let the shell parse the stupid args. We need to add an "&" | |||
| 590 | * at the end of the command. We previously allocated an extra | |||
| 591 | * byte for this. | |||
| 592 | */ | |||
| 593 | ||||
| 594 | snprintf (logtext, sizeof(logtext), "Restarting locally : %s\n",__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "Restarting locally : %s\n", non_session_aware_clients [i]) | |||
| 595 | non_session_aware_clients[i])__builtin___snprintf_chk (logtext, sizeof(logtext), 0, __builtin_object_size (logtext, 2 > 1 ? 1 : 0), "Restarting locally : %s\n", non_session_aware_clients [i]); | |||
| 596 | add_log_text (logtext); | |||
| 597 | ||||
| 598 | strcat (non_session_aware_clients[i], "&")__builtin___strcat_chk (non_session_aware_clients[i], "&" , __builtin_object_size (non_session_aware_clients[i], 2 > 1 ? 1 : 0)); | |||
| 599 | execute_system_command (non_session_aware_clients[i]); | |||
| 600 | free ((char *) non_session_aware_clients[i]); | |||
| 601 | } | |||
| 602 | ||||
| 603 | if (non_session_aware_clients) | |||
| 604 | { | |||
| 605 | free ((char *) non_session_aware_clients); | |||
| 606 | non_session_aware_clients = NULL((void*)0); | |||
| 607 | } | |||
| 608 | } |