~ubuntu-branches/ubuntu/maverick/gnome-session/maverick

« back to all changes in this revision

Viewing changes to gnome-session/remote.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2009-04-14 19:24:09 UTC
  • mto: (1.3.1 upstream) (2.1.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 112.
  • Revision ID: james.westby@ubuntu.com-20090414192409-koxw9bt1lf1zr01z
ImportĀ upstreamĀ versionĀ 2.26.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $XConsortium: remote.c,v 1.15 95/01/03 17:26:52 mor Exp $ */
2
 
/******************************************************************************
3
 
 
4
 
Copyright (c) 1993, 1999  X Consortium
5
 
 
6
 
Permission is hereby granted, free of charge, to any person obtaining a copy
7
 
of this software and associated documentation files (the "Software"), to deal
8
 
in the Software without restriction, including without limitation the rights
9
 
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 
copies of the Software, and to permit persons to whom the Software is
11
 
furnished to do so, subject to the following conditions:
12
 
 
13
 
The above copyright notice and this permission notice shall be included in
14
 
all copies or substantial portions of the Software.
15
 
 
16
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
19
 
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20
 
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
 
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 
 
23
 
Except as contained in this notice, the name of the X Consortium shall not be
24
 
used in advertising or otherwise to promote the sale, use or other dealings
25
 
in this Software without prior written authorization from the X Consortium.
26
 
******************************************************************************/
27
 
 
28
 
/*
29
 
 * We use the rstart protocol to restart clients on remote machines.
30
 
 */
31
 
 
32
 
#include <config.h>
33
 
 
34
 
#include <string.h>
35
 
#include <unistd.h>
36
 
#include <ctype.h>
37
 
 
38
 
#include <X11/ICE/ICElib.h>
39
 
#include <X11/ICE/ICEutil.h>
40
 
 
41
 
#include "remote.h"
42
 
#include "util.h"
43
 
 
44
 
static char *format_rstart_env (char *);
45
 
static void close_child (GPid pid, gint status, gpointer ignore);
46
 
 
47
 
static void
48
 
close_child (GPid pid, gint status, gpointer ignore)
49
 
{
50
 
  g_spawn_close_pid (pid);
51
 
}
52
 
 
53
 
gboolean
54
 
remote_start (char *restart_info, char **argv,
55
 
              char *cwd, char **envp,
56
 
              GPid *child_pid, GError **error)
57
 
{
58
 
    FILE *fp;
59
 
    gint pipefd;
60
 
    char *machine;
61
 
    int  i;
62
 
    GSList *list;
63
 
    gchar *rargv[4];
64
 
 
65
 
    if (! restart_info)
66
 
    {
67
 
        return gsm_exec_async (cwd, argv, envp, child_pid, error);
68
 
    }
69
 
 
70
 
    if (strncmp (restart_info, RSTART_RSH, sizeof (RSTART_RSH))
71
 
        || restart_info[sizeof (RSTART_RSH)] != '/')
72
 
    {
73
 
        return gsm_exec_async (cwd, argv, envp, child_pid, error);
74
 
    }
75
 
 
76
 
    machine = restart_info + sizeof (RSTART_RSH) + 1;
77
 
    if (! *machine)
78
 
    {
79
 
        return gsm_exec_async (cwd, argv, envp, child_pid, error);
80
 
    }
81
 
 
82
 
    g_message ("Attempting to restart remote client on %s\n",
83
 
               machine);
84
 
 
85
 
    rargv[0] = RSH_COMMAND;
86
 
    rargv[1] = machine;
87
 
    rargv[2] = "rstartd";
88
 
    rargv[3] = NULL;
89
 
 
90
 
    /* TODO: we would like to report whether rstartd failed to a log
91
 
       window in the parent.  We could do this by checking all the
92
 
       fprintf()s for error return.  */
93
 
    if (! g_spawn_async_with_pipes (NULL, rargv, NULL,
94
 
                                    G_SPAWN_DO_NOT_REAP_CHILD,
95
 
                                    NULL, NULL, child_pid,
96
 
                                    &pipefd, NULL, NULL, error))
97
 
      return 0;
98
 
    g_child_watch_add (*child_pid, close_child, NULL);
99
 
 
100
 
    fp = (FILE *) fdopen (pipefd, "w");
101
 
 
102
 
    fprintf (fp, "CONTEXT X\n");
103
 
    fprintf (fp, "DIR %s\n", cwd);
104
 
    fprintf (fp, "DETACH\n");
105
 
 
106
 
    if (envp)
107
 
      {
108
 
        /*
109
 
         * The application saved its environment.
110
 
         */
111
 
 
112
 
        for (i = 0; envp[i]; i++)
113
 
          {
114
 
            /*
115
 
             * rstart requires that any spaces, backslashes, or
116
 
             * non-printable characters inside of a string be
117
 
             * represented by octal escape sequences.
118
 
             */
119
 
 
120
 
            char *temp = format_rstart_env (envp[i]);
121
 
            fprintf (fp, "MISC X %s\n", temp);
122
 
            if (temp != envp[i])
123
 
              g_free (temp);
124
 
          }
125
 
      }
126
 
    else
127
 
      {
128
 
        /*
129
 
         * The application did not save its environment.
130
 
         * The default PATH set up by rstart may not contain
131
 
         * the program we want to restart.  We play it safe
132
 
         * and pass xsm's PATH.  This will most likely contain
133
 
         * the path we need.
134
 
         */
135
 
 
136
 
        const char *path = g_getenv ("PATH");
137
 
 
138
 
        if (path)
139
 
          fprintf (fp, "MISC X PATH=%s\n", path);
140
 
      }
141
 
 
142
 
#if 0
143
 
    /* FIXME: implement */
144
 
    fprintf (fp, "MISC X %s\n", non_local_display_env);
145
 
    fprintf (fp, "MISC X %s\n", non_local_session_env);
146
 
#endif
147
 
 
148
 
    /*
149
 
     * Pass the authentication data.
150
 
     * Each transport has auth data for ICE and XSMP.
151
 
     * Don't pass local auth data.
152
 
     */
153
 
    for (list = auth_entries; list != NULL; list = list->next)
154
 
      {
155
 
        IceAuthFileEntry *entry = (IceAuthFileEntry *) list->data;
156
 
        if (strstr (entry->network_id, "local/"))
157
 
          continue;
158
 
 
159
 
        fprintf (fp, "AUTH ICE %s \"\" %s %s ",
160
 
                 entry->protocol_name,
161
 
                 entry->network_id,
162
 
                 entry->auth_name);
163
 
                
164
 
        for (i = 0; i < entry->auth_data_length; ++i)
165
 
          fprintf (fp, "%02x", entry->auth_data[i]);
166
 
 
167
 
        fprintf (fp, "\n");
168
 
      }
169
 
 
170
 
    /*
171
 
     * And execute the program
172
 
     */
173
 
 
174
 
    fprintf (fp, "EXEC %s %s", argv[0], argv[0]);
175
 
    for (i = 1; argv[i]; i++)
176
 
      fprintf (fp, " %s", argv[i]);
177
 
    fprintf (fp, "\n\n");
178
 
    fclose (fp);
179
 
 
180
 
    return 1;
181
 
}
182
 
 
183
 
 
184
 
/*
185
 
 * rstart requires that any spaces/backslashes/non-printable characters
186
 
 * inside of a string be represented by octal escape sequences.
187
 
 */
188
 
 
189
 
static char *
190
 
format_rstart_env (char *str)
191
 
{
192
 
    int escape_count = 0, i;
193
 
    unsigned char *temp = (unsigned char *) str;
194
 
 
195
 
    while (*temp != '\0')
196
 
    {
197
 
        if (!isgraph (*temp) || *temp == '\\')
198
 
            escape_count++;
199
 
        temp++;
200
 
    }
201
 
 
202
 
    if (escape_count == 0)
203
 
        return (str);
204
 
    else
205
 
    {
206
 
        int len = strlen (str) + 1 + (escape_count * 3);
207
 
        char *ret = (char *) g_malloc (len);
208
 
        char *ptr = ret;
209
 
 
210
 
        temp = (unsigned char *) str;
211
 
        while (*temp != '\0')
212
 
        {
213
 
            if (!isgraph (*temp) || *temp == '\\')
214
 
            {
215
 
                char octal[3];
216
 
                g_snprintf (octal, sizeof (octal), "%o", *temp);
217
 
                *(ptr++) = '\\';
218
 
                for (i = 0; i < (3 - (int) strlen (octal)); i++)
219
 
                    *(ptr++) = '0';
220
 
                strcpy (ptr, octal);
221
 
                ptr += strlen (octal);
222
 
            }
223
 
            else
224
 
                *(ptr++) = *temp;
225
 
 
226
 
            temp++;
227
 
        }
228
 
 
229
 
        *ptr = '\0';
230
 
        return (ret);
231
 
    }
232
 
}