static GIOStatus g_io_unix_seek (GIOChannel *channel, gint64 offset, GSeekType type, GError **err) { GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; int whence; off_t tmp_offset; off_t result; switch (type) { case G_SEEK_SET: whence = SEEK_SET; break; case G_SEEK_CUR: whence = SEEK_CUR; break; case G_SEEK_END: whence = SEEK_END; break; default: whence = -1; /* Shut the compiler up */ g_assert_not_reached (); } tmp_offset = offset; if (tmp_offset != offset) { g_set_error_literal (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (EINVAL), g_strerror (EINVAL)); return G_IO_STATUS_ERROR; } result = lseek (unix_channel->fd, tmp_offset, whence); if (result < 0) { int errsv = errno; g_set_error_literal (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errsv), g_strerror (errsv)); return G_IO_STATUS_ERROR; } return G_IO_STATUS_NORMAL; }
static GIOStatus g_io_win32_fd_seek (GIOChannel *channel, gint64 offset, GSeekType type, GError **err) { GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; int whence; off_t tmp_offset; off_t result; switch (type) { case G_SEEK_SET: whence = SEEK_SET; break; case G_SEEK_CUR: whence = SEEK_CUR; break; case G_SEEK_END: whence = SEEK_END; break; default: whence = -1; /* Keep the compiler quiet */ g_assert_not_reached(); } tmp_offset = offset; if (tmp_offset != offset) { g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (EINVAL), g_strerror (EINVAL)); return G_IO_STATUS_ERROR; } result = lseek (win32_channel->fd, tmp_offset, whence); if (result < 0) { g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), g_strerror (errno)); return G_IO_STATUS_ERROR; } return G_IO_STATUS_NORMAL; }
static GIOStatus g_io_win32_fd_write (GIOChannel *channel, const gchar *buf, gsize count, gsize *bytes_written, GError **err) { GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; gint result; result = write (win32_channel->fd, buf, count); if (result < 0) { *bytes_written = 0; switch (errno) { #ifdef EAGAIN case EAGAIN: return G_IO_STATUS_AGAIN; #endif default: g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), g_strerror (errno)); return G_IO_STATUS_ERROR; } } *bytes_written = result; return G_IO_STATUS_NORMAL; }
static GIOStatus g_io_unix_set_flags (GIOChannel *channel, GIOFlags flags, GError **err) { glong fcntl_flags; GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel; fcntl_flags = 0; if (flags & G_IO_FLAG_APPEND) fcntl_flags |= O_APPEND; if (flags & G_IO_FLAG_NONBLOCK) #ifdef O_NONBLOCK fcntl_flags |= O_NONBLOCK; #else fcntl_flags |= O_NDELAY; #endif if (fcntl (unix_channel->fd, F_SETFL, fcntl_flags) == -1) { g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), g_strerror (errno)); return G_IO_STATUS_ERROR; } return G_IO_STATUS_NORMAL; }
static gboolean create_file (const gchar *file, mode_t mode, GError **err) { int fd; g_assert (err && !*err); if ((fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, mode)) == -1) { g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), "%s", g_strerror (errno)); return FALSE; } /* Write the header when we make a new file */ if (write (fd, GPG_CONF_HEADER, strlen (GPG_CONF_HEADER)) == -1) { g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), "%s", strerror (errno)); } close (fd); return *err ? FALSE : TRUE; }
static GIOStatus g_io_unix_close (GIOChannel *channel, GError **err) { GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; if (close (unix_channel->fd) < 0) { g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), g_strerror (errno)); return G_IO_STATUS_ERROR; } return G_IO_STATUS_NORMAL; }
static GIOStatus g_io_win32_fd_read (GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read, GError **err) { GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; gint result; if (win32_channel->debug) g_print ("g_io_win32_fd_read: fd:%d count:%d\n", win32_channel->fd, count); if (win32_channel->thread_id) { return buffer_read (win32_channel, buf, count, bytes_read, err); } result = read (win32_channel->fd, buf, count); if (win32_channel->debug) g_print ("g_io_win32_fd_read: read() = %d\n", result); if (result < 0) { *bytes_read = 0; switch(errno) { #ifdef EAGAIN case EAGAIN: return G_IO_STATUS_AGAIN; #endif default: g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), g_strerror (errno)); return G_IO_STATUS_ERROR; } } *bytes_read = result; return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; }
/* Finds relevant configuration file, creates if not found */ static gchar * find_config_file (gboolean read, GError **err) { gchar *conf = NULL; g_assert (!err || !*err); if (!gpg_options_inited) return NULL; if (!gpg_homedir) return NULL; /* Check for and open ~/.gnupg/gpg.conf */ conf = g_strconcat (gpg_homedir, "/gpg.conf", NULL); if (g_file_test (conf, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS)) return conf; g_free (conf); /* Check for and open ~/.gnupg/options */ conf = g_strconcat (gpg_homedir, "/options", NULL); if (g_file_test (conf, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS)) return conf; g_free (conf); /* Make sure directory exists */ if (!g_file_test (gpg_homedir, G_FILE_TEST_EXISTS)) { if (mkdir (gpg_homedir, 0700) == -1) { g_set_error (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errno), "%s", strerror (errno)); return NULL; } } /* For writers just return the file name */ conf = g_strconcat (gpg_homedir, "/gpg.conf", NULL); if (!read) return conf; /* ... for readers we create ~/.gnupg/gpg.conf */ if (create_file (conf, 0600, err)) return conf; g_free (conf); return NULL; }
static GIOStatus g_io_unix_read (GIOChannel *channel, gchar *buf, gsize count, gsize *bytes_read, GError **err) { GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; gssize result; if (count > SSIZE_MAX) /* At least according to the Debian manpage for read */ count = SSIZE_MAX; retry: result = read (unix_channel->fd, buf, count); if (result < 0) { int errsv = errno; *bytes_read = 0; switch (errsv) { #ifdef EINTR case EINTR: goto retry; #endif #ifdef EAGAIN case EAGAIN: return G_IO_STATUS_AGAIN; #endif default: g_set_error_literal (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errsv), g_strerror (errsv)); return G_IO_STATUS_ERROR; } } *bytes_read = result; return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; }
static GIOStatus g_io_unix_write (GIOChannel *channel, const gchar *buf, gsize count, gsize *bytes_written, GError **err) { GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; gssize result; retry: result = write (unix_channel->fd, buf, count); if (result < 0) { int errsv = errno; *bytes_written = 0; switch (errsv) { #ifdef EINTR case EINTR: goto retry; #endif #ifdef EAGAIN case EAGAIN: return G_IO_STATUS_AGAIN; #endif default: g_set_error_literal (err, G_IO_CHANNEL_ERROR, g_io_channel_error_from_errno (errsv), g_strerror (errsv)); return G_IO_STATUS_ERROR; } } *bytes_written = result; return G_IO_STATUS_NORMAL; }