~ubuntu-branches/ubuntu/maverick/uim/maverick

« back to all changes in this revision

Viewing changes to uim/uim-helper.c

  • Committer: Bazaar Package Importer
  • Author(s): Masahito Omote
  • Date: 2008-06-25 19:56:33 UTC
  • mfrom: (3.1.18 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080625195633-8jljph4rfq00l8o7
Tags: 1:1.5.1-2
* uim-tcode: provide tutcode-custom.scm, tutcode-bushudic.scm
  and tutcode-rule.scm (Closes: #482659)
* Fix FTBFS: segv during compile (Closes: #483078).
  I personally think this bug is not specific for uim but is a optimization
  problem on gcc-4.3.1. (https://bugs.freedesktop.org/show_bug.cgi?id=16477)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 
3
 
  Copyright (c) 2003-2006 uim Project http://uim.freedesktop.org/
 
3
  Copyright (c) 2003-2008 uim Project http://code.google.com/p/uim/
4
4
 
5
5
  All rights reserved.
6
6
 
37
37
#include <sys/socket.h>
38
38
#include <sys/types.h>
39
39
#include <sys/time.h>
 
40
#include <sys/param.h>
40
41
#include <sys/un.h>
41
42
#include <netinet/in.h>
42
43
#include <netdb.h>
46
47
#include <pwd.h>
47
48
#include <signal.h>
48
49
#include <errno.h>
 
50
#include <sys/stat.h>
 
51
 
49
52
#include "uim-internal.h"
50
53
#include "uim-helper.h"
51
 
#include "uim-util.h"
 
54
#include "uim-posix.h"
 
55
 
 
56
/*
 
57
 * uim-notify is disabled since I'm not confident about:
 
58
 *   1. its stability when low-level error handling is being involved
 
59
 *   2. whether these errors should be notified to endusers
 
60
 * -- 2008-01-15 YamaKen
 
61
 */
 
62
#undef USE_UIM_NOTIFY
 
63
#define USE_UIM_NOTIFY 0
 
64
 
 
65
#if USE_UIM_NOTIFY && !UIM_NON_LIBUIM_PROG
 
66
#include "uim-notify.h"
 
67
#endif
52
68
 
53
69
#ifndef HAVE_SIG_T
54
70
typedef void (*sig_t)(int);
93
109
  sig_t old_sigpipe;
94
110
  char *buf, *bufp;
95
111
 
 
112
  if (UIM_CATCH_ERROR_BEGIN())
 
113
    return;
 
114
 
 
115
#if 0
 
116
  if (fd < 0)
 
117
    uim_fatal_error("uim_helper_send_message(): invaid fd");
 
118
  if (!message)
 
119
    uim_fatal_error("uim_helper_send_message(): NULL message");
 
120
#else
 
121
  /* The condition fd < 0 ordinarily occurs. */
96
122
  if (fd < 0 || !message)
97
123
    return;
 
124
#endif
98
125
 
99
126
  len = strlen(message) + 1;
100
 
  buf = malloc(len + 1);
 
127
  buf = uim_malloc(len + 1);
101
128
  snprintf(buf, len + 1, "%s\n", message);
102
129
 
103
130
  old_sigpipe = signal(SIGPIPE, SIG_IGN);
108
135
    if ((res = write(fd, bufp, out_len)) < 0) {
109
136
      if (errno == EAGAIN || errno == EINTR)
110
137
        continue;
111
 
      fprintf(stderr, "uim_helper_send_message(): unknown error\n");
 
138
      perror("uim_helper_send_message(): unhandled error");
112
139
      break;
113
140
    }
114
141
 
117
144
  }
118
145
  free(buf);
119
146
  signal(SIGPIPE, old_sigpipe);
 
147
 
 
148
  UIM_CATCH_ERROR_END();
 
149
 
120
150
  return;
121
151
}
122
152
 
123
 
char *
124
 
uim_helper_get_pathname(void)
125
 
{
126
 
  char *path;
127
 
  char *login = NULL;
128
 
  struct passwd *pw = NULL;
129
 
 
130
 
  if (!uim_issetugid()) {
131
 
    login = getenv("LOGNAME");
132
 
  }
133
 
 
134
 
  if (!login) {
135
 
    pw = getpwuid(getuid());
136
 
    login = strdup(pw->pw_name);
137
 
  }
138
 
 
139
 
  path = (char *)malloc(strlen(login)+ 20);
140
 
  sprintf(path, "/tmp/uimhelper-%s",login);
141
 
  if (pw) {
142
 
    free(login);
143
 
  }
144
 
  return path;
 
153
static uim_bool
 
154
check_dir(const char *dir)
 
155
{
 
156
  struct stat st;
 
157
 
 
158
  if (stat(dir, &st) < 0)
 
159
    return (mkdir(dir, 0700) < 0) ? UIM_FALSE : UIM_TRUE;
 
160
  else {
 
161
    mode_t mode = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR;
 
162
    return ((st.st_mode & mode) == mode) ? UIM_TRUE : UIM_FALSE;
 
163
  }
 
164
}
 
165
 
 
166
uim_bool
 
167
uim_helper_get_pathname(char *helper_path, int len)
 
168
{
 
169
  struct passwd *pw;
 
170
 
 
171
  if (len <= 0)
 
172
    return UIM_FALSE;
 
173
 
 
174
  if (UIM_CATCH_ERROR_BEGIN())
 
175
    return UIM_FALSE;
 
176
 
 
177
  pw = getpwuid(getuid());
 
178
  if (!pw) {
 
179
    endpwent();
 
180
    goto path_error;
 
181
  }
 
182
 
 
183
  if (strlcpy(helper_path, pw->pw_dir, len) >= (size_t)len) {
 
184
    endpwent();
 
185
    goto path_error;
 
186
  }
 
187
  if (strlcat(helper_path, "/.uim.d", len) >= (size_t)len) {
 
188
    endpwent();
 
189
    goto path_error;
 
190
  }
 
191
  endpwent();
 
192
 
 
193
  /* check ~/.uim.d/ */
 
194
  if (!check_dir(helper_path))
 
195
    goto path_error;
 
196
 
 
197
  /* check ~/.uim.d/socket/ */
 
198
  if (strlcat(helper_path, "/socket", len) >= (size_t)len)
 
199
    goto path_error;
 
200
 
 
201
  if (!check_dir(helper_path))
 
202
    goto path_error;
 
203
 
 
204
  if (strlcat(helper_path, "/uim-helper", len) >= (size_t)len)
 
205
    goto path_error;
 
206
 
 
207
  UIM_CATCH_ERROR_END();
 
208
 
 
209
  return UIM_TRUE;
 
210
 
 
211
 path_error:
 
212
  uim_fatal_error("uim_helper_get_pathname()");
 
213
  helper_path[0] = '\0';
 
214
 
 
215
  UIM_CATCH_ERROR_END();
 
216
  return UIM_FALSE;
 
217
}
 
218
 
 
219
int
 
220
uim_helper_check_connection_fd(int fd)
 
221
{
 
222
  uid_t euid;
 
223
  gid_t egid;
 
224
  if (getpeereid(fd, &euid, &egid) < 0) {
 
225
#if USE_UIM_NOTIFY && !UIM_NON_LIBUIM_PROG
 
226
    uim_notify_fatal("uim_helper: %s", strerror(errno));
 
227
#else
 
228
    perror("getpeereid failed");
 
229
#endif
 
230
    return -1;
 
231
  }
 
232
  if ((euid != 0) && (euid != getuid())) {
 
233
#if USE_UIM_NOTIFY && !UIM_NON_LIBUIM_PROG
 
234
    uim_notify_fatal("uim_helper: uid mismatch");
 
235
#else
 
236
    fprintf(stderr, "uid mismatch\n");
 
237
#endif
 
238
    return -1;
 
239
  }
 
240
  return 0;
145
241
}
146
242
 
147
243
int uim_helper_fd_readable(int fd)
175
271
 
176
272
  buf_size = strlen(buf);
177
273
  extended_size = buf_size + fragment_size + 1;
178
 
  buf = (char *)realloc(buf, extended_size);
 
274
  buf = realloc(buf, extended_size);
179
275
  if (buf) {
180
276
    memcpy(&buf[buf_size], fragment, fragment_size);
181
277
    buf[extended_size - 1] = '\0';
198
294
  size_t msg_size;
199
295
  char *msg, *msg_term;
200
296
 
 
297
  if (UIM_CATCH_ERROR_BEGIN())
 
298
    return NULL;
 
299
 
201
300
  msg_term = strstr(buf, "\n\n");
202
301
  if (msg_term) {
203
302
    msg_size = msg_term + 2 - buf;
204
 
    msg = (char *)malloc(msg_size + 1);
 
303
    msg = uim_malloc(msg_size + 1);
205
304
    memcpy(msg, buf, msg_size);
206
305
    msg[msg_size] = '\0';
207
306
    uim_helper_buffer_shift(buf, msg_size);
208
 
    return msg;
 
307
  } else {
 
308
    msg = NULL;
209
309
  }
210
 
  return NULL;
 
310
 
 
311
  UIM_CATCH_ERROR_END();
 
312
 
 
313
  return msg;
211
314
}
212
315
 
213
316
/* Public API for uim_issetugid(). */
218
321
  return (uim_issetugid()) ? UIM_TRUE : UIM_FALSE;
219
322
}
220
323
 
 
324
#if !HAVE_ISSETUGID
221
325
/* For internal use only. libuim clients should use uim_helper_is_setugid()
222
326
 * since this is not a core uim function. */
223
327
uim_bool
230
334
 
231
335
  return (ruid != euid || rgid != egid);
232
336
}
 
337
#endif /* !HAVE_ISSETUGID */