gboolean gitg_commit_add_ignore(GitgCommit *commit, GitgChangedFile *file, GError **error) { g_return_if_fail(GITG_IS_COMMIT(commit)); g_return_if_fail(GITG_IS_CHANGED_FILE(file)); GFile *f = gitg_changed_file_get_file(file); gchar *path = gitg_repository_relative(commit->priv->repository, f); gchar *ignore = g_strdup_printf("%s/.gitignore", gitg_repository_get_path(commit->priv->repository)); GFile *ig = g_file_new_for_path(ignore); GFileOutputStream *stream = g_file_append_to(ig, G_FILE_CREATE_NONE, NULL, error); gboolean ret = FALSE; if (stream) { gchar *line = g_strdup_printf("/%s\n", path); ret = g_output_stream_write_all(G_OUTPUT_STREAM(stream), line, strlen(line), NULL, NULL, error); g_output_stream_close(G_OUTPUT_STREAM(stream), NULL, NULL); g_object_unref(stream); g_free(line); } if (ret) remove_file(commit, file); g_object_unref(f); g_free(ignore); g_free(path); }
gboolean media_append (gchar *path, gchar *buf, gssize size) { GFile *gfile; GOutputStream *out; GError *err = NULL; gssize written; gfile = g_file_new_for_path (path); out = (GOutputStream *)g_file_append_to (gfile, G_FILE_CREATE_NONE, NULL, &err); if (out == NULL) { GST_ERROR ("Error opening file: %s\n", err->message); g_error_free (err); g_object_unref (gfile); return FALSE; } written = g_output_stream_write (out, buf, size, NULL, &err); if (written == -1) { GST_ERROR ("Error writing to stream: %s", err->message); g_error_free (err); } g_object_unref (out); g_object_unref (gfile); return TRUE; }
static void write_output_file (gpointer data) { g_assert (data != NULL); GError *error = NULL; GDownloadable *download = G_DOWNLOADABLE (data); SoupDownload *soup_download = SOUP_DOWNLOAD (data); if (soup_download->priv->need_to_write) { GFileOutputStream *ostream = g_file_append_to (download->priv->local_file, G_FILE_CREATE_NONE, NULL, &error); handle_error (error); SoupBuffer *buffer = soup_message_body_flatten (soup_download->priv->message->response_body); g_output_stream_write (G_OUTPUT_STREAM (ostream), buffer->data, buffer->length, NULL, &error); handle_error (error); g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, &error); handle_error (error); download->priv->downloaded_size = soup_download->priv->prev_downloaded + buffer->length; soup_buffer_free (buffer); soup_download->priv->need_to_write = FALSE; } }
gboolean ostree_create_temp_regular_file (GFile *dir, const char *prefix, const char *suffix, GFile **out_file, GOutputStream **out_stream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; ot_lobj GFile *ret_file = NULL; ot_lobj GOutputStream *ret_stream = NULL; if (!ostree_create_temp_file_from_input (dir, prefix, suffix, NULL, NULL, NULL, &ret_file, cancellable, error)) goto out; ret_stream = (GOutputStream*)g_file_append_to (ret_file, 0, cancellable, error); if (ret_stream == NULL) goto out; ret = TRUE; ot_transfer_out_value(out_file, &ret_file); ot_transfer_out_value(out_stream, &ret_stream); out: return ret; }
/** * camel_stream_vfs_new_with_uri: * @uri: a file uri * @mode: opening mode for the uri file * * Creates a new #CamelStreamVFS corresponding to the named file and mode. * * Returns the new stream, or %NULL on error. **/ CamelStream * camel_stream_vfs_new_with_uri (const char *uri, CamelStreamVFSOpenMethod mode) { GFile *file; GObject *stream; GError *error = NULL; file = g_file_new_for_uri (uri); switch (mode) { case CAMEL_STREAM_VFS_CREATE: stream = G_OBJECT (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error)); break; case CAMEL_STREAM_VFS_APPEND: stream = G_OBJECT (g_file_append_to (file, G_FILE_CREATE_NONE, NULL, &error)); break; case CAMEL_STREAM_VFS_READ: stream = G_OBJECT (g_file_read (file, NULL, &error)); break; default: errno = EINVAL; g_return_val_if_reached (NULL); } g_object_unref (file); if (error) { errno = error->code; g_warning ("%s", error->message); g_error_free (error); return NULL; } return camel_stream_vfs_new_with_stream (stream); }
static void do_append_to (GVfsBackend *backend, GVfsJobOpenForWrite *job, const char *filename, GFileCreateFlags flags) { GFile *file; GFileOutputStream *out; GError *error; file = g_vfs_get_file_for_path (g_vfs_get_local (), filename); error = NULL; out = g_file_append_to (file, flags, G_VFS_JOB (job)->cancellable, &error); g_object_unref (file); if (out) { g_vfs_job_open_for_write_set_can_seek (job, FALSE); g_vfs_job_open_for_write_set_handle (job, out); g_vfs_job_succeeded (G_VFS_JOB (job)); } else { g_vfs_job_failed_from_error (G_VFS_JOB (job), error); g_error_free (error); } }
static GFile * get_g_file_with_encrypted_data (GFileInputStream *in_stream, goffset file_size) { GError *err = NULL; GFileIOStream *ostream; gssize read_len; guchar *buf; gsize len_file_data = file_size - SHA512_DIGEST_SIZE; gsize done_size = 0; GFile *tmp_encrypted_file = g_file_new_tmp (NULL, &ostream, &err); if (tmp_encrypted_file == NULL) { g_printerr ("%s\n", err->message); // TODO return NULL; } GFileOutputStream *out_enc_stream = g_file_append_to (tmp_encrypted_file, G_FILE_CREATE_NONE, NULL, &err); if (out_enc_stream == NULL) { g_printerr ("%s\n", err->message); // TODO return NULL; } if (len_file_data < FILE_BUFFER) { buf = g_malloc (len_file_data); g_input_stream_read (G_INPUT_STREAM (in_stream), buf, len_file_data, NULL, &err); g_output_stream_write (G_OUTPUT_STREAM (out_enc_stream), buf, len_file_data, NULL, &err); } else { buf = g_malloc (FILE_BUFFER); while (done_size < len_file_data) { if ((len_file_data - done_size) > FILE_BUFFER) { read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), buf, FILE_BUFFER, NULL, &err); } else { read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), buf, len_file_data - done_size, NULL, &err); } if (read_len == -1) { g_printerr ("%s\n", err->message); // TODO return NULL; } g_output_stream_write (G_OUTPUT_STREAM (out_enc_stream), buf, read_len, NULL, &err); done_size += read_len; memset (buf, 0, FILE_BUFFER); } } g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); g_output_stream_close (G_OUTPUT_STREAM (out_enc_stream), NULL, NULL); g_object_unref (out_enc_stream); g_free (buf); return tmp_encrypted_file; }
/** * ly_log_logger_add: * @logger: the logger * @str: the string data to be write to log file. * * Add a log item to log file. */ void ly_log_logger_add (LyLogLogger *logger, gchar *str) { LyLogLoggerPrivate *priv=LY_LOG_LOGGER_GET_PRIVATE(LY_LOG_LOGGER(logger)); GFileOutputStream *ostream; ostream=g_file_append_to(G_FILE(priv->file), G_FILE_CREATE_NONE, \ NULL, NULL); g_output_stream_write(G_OUTPUT_STREAM(ostream), (const void *)str, \ strlen(str), NULL, NULL); g_output_stream_close(G_OUTPUT_STREAM(ostream), NULL, NULL); g_object_unref(ostream); }
/* * Function to use anywhere in the application to send a message to the LogList */ void Log_Print (Log_Error_Type error_type, gchar const *format, ...) { va_list args; gchar *string; GtkTreeIter iter; static gboolean first_time = TRUE; static gchar *file_path = NULL; GFile *file; GFileOutputStream *file_ostream; GError *error = NULL; va_start (args, format); string = g_strdup_vprintf(format, args); va_end (args); // If the log window is displayed then messages are displayed, else // the messages are stored in a temporary list. if (LogList && logListModel) { gint n_items; gchar *time = Log_Format_Date(); /* Remove lines that exceed the limit. */ n_items = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (logListModel), NULL); if (n_items > LOG_MAX_LINES - 1 && gtk_tree_model_get_iter_first(GTK_TREE_MODEL(logListModel), &iter)) { gtk_list_store_remove(GTK_LIST_STORE(logListModel), &iter); } gtk_list_store_insert_with_values (logListModel, &iter, G_MAXINT, LOG_PIXBUF, Log_Get_Stock_Id_From_Error_Type (error_type), LOG_TIME_TEXT, time, LOG_TEXT, string, -1); Log_List_Set_Row_Visible(GTK_TREE_MODEL(logListModel), &iter); g_free(time); }else { Log_Data *LogData = g_malloc0(sizeof(Log_Data)); LogData->time = Log_Format_Date(); LogData->error_type = error_type; LogData->string = g_strdup(string); LogPrintTmpList = g_list_append(LogPrintTmpList,LogData); //g_print("%s",string); } // Store also the messages in the log file. if (!file_path) { gchar *cache_path = g_build_filename (g_get_user_cache_dir (), PACKAGE_TARNAME, NULL); if (!g_file_test (cache_path, G_FILE_TEST_IS_DIR)) { gint result = g_mkdir_with_parents (cache_path, S_IRWXU); if (result == -1) { g_printerr ("%s", "Unable to create cache directory"); g_free (cache_path); g_free (string); return; } } file_path = g_build_filename (cache_path, LOG_FILE, NULL); g_free (cache_path); } file = g_file_new_for_path (file_path); /* On startup, the log is cleared. The log is then appended to for the * remainder of the application lifetime. */ if (first_time) { file_ostream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error); } else { file_ostream = g_file_append_to (file, G_FILE_CREATE_NONE, NULL, &error); } if (file_ostream) { gchar *time; GString *data; gsize bytes_written; time = Log_Format_Date (); data = g_string_new (time); g_free (time); data = g_string_append_c (data, ' '); data = g_string_append (data, string); g_free (string); data = g_string_append_c (data, '\n'); if (!g_output_stream_write_all (G_OUTPUT_STREAM (file_ostream), data->str, data->len, &bytes_written, NULL, &error)) { g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %" G_GSIZE_FORMAT "bytes of data were written", bytes_written, data->len); /* To avoid recursion of Log_Print. */ g_warning ("Error writing to the log file '%s' ('%s')", file_path, error->message); g_error_free (error); g_string_free (data, TRUE); g_object_unref (file_ostream); g_object_unref (file); return; } first_time = FALSE; g_string_free (data, TRUE); } else { g_warning ("Error opening output stream of file '%s' ('%s')", file_path, error->message); g_error_free (error); } g_object_unref (file_ostream); g_object_unref (file); }
static void scrollback_save (session *sess, char *text, time_t stamp) { GOutputStream *ostream; char *buf; if (sess->type == SESS_SERVER && prefs.hex_gui_tab_server == 1) return; if (sess->text_scrollback == SET_DEFAULT) { if (!prefs.hex_text_replay) return; } else { if (sess->text_scrollback != SET_ON) return; } if (!sess->scrollfile) { if ((buf = scrollback_get_filename (sess)) == NULL) return; sess->scrollfile = g_file_new_for_path (buf); g_free (buf); } else { /* Users can delete the folder after it's created... */ GFile *parent = g_file_get_parent (sess->scrollfile); g_file_make_directory_with_parents (parent, NULL, NULL); g_object_unref (parent); } ostream = G_OUTPUT_STREAM(g_file_append_to (sess->scrollfile, G_FILE_CREATE_PRIVATE, NULL, NULL)); if (!ostream) return; if (!stamp) stamp = time(0); if (sizeof (stamp) == 4) /* gcc will optimize one of these out */ buf = g_strdup_printf ("T %d ", (int) stamp); else buf = g_strdup_printf ("T %" G_GINT64_FORMAT " ", (gint64)stamp); g_output_stream_write (ostream, buf, strlen (buf), NULL, NULL); g_output_stream_write (ostream, text, strlen (text), NULL, NULL); if (!g_str_has_suffix (text, "\n")) g_output_stream_write (ostream, "\n", 1, NULL, NULL); g_free (buf); g_object_unref (ostream); sess->scrollwritten++; if ((sess->scrollwritten > prefs.hex_text_max_lines && prefs.hex_text_max_lines > 0) || sess->scrollwritten > SCROLLBACK_MAX) scrollback_shrink (sess); }
gboolean create_bundle(const gchar *bundlename, const gchar *contentdir, GError **error) { GError *ierror = NULL; GBytes *sig = NULL; GFile *bundlefile = NULL; GFileOutputStream *bundlestream = NULL; gboolean res = FALSE; guint64 offset; g_assert_nonnull(r_context()->certpath); g_assert_nonnull(r_context()->keypath); res = mksquashfs(bundlename, contentdir, &ierror); if (!res) { g_propagate_error(error, ierror); goto out; } sig = cms_sign_file(bundlename, r_context()->certpath, r_context()->keypath, &ierror); if (sig == NULL) { g_propagate_prefixed_error( error, ierror, "failed signing bundle: "); goto out; } bundlefile = g_file_new_for_path(bundlename); bundlestream = g_file_append_to(bundlefile, G_FILE_CREATE_NONE, NULL, &ierror); if (bundlestream == NULL) { g_propagate_prefixed_error( error, ierror, "failed to open bundle for appending: "); goto out; } res = g_seekable_seek(G_SEEKABLE(bundlestream), 0, G_SEEK_END, NULL, &ierror); if (!res) { g_propagate_prefixed_error( error, ierror, "failed to seek to end of bundle: "); goto out; } offset = g_seekable_tell((GSeekable *)bundlestream); res = output_stream_write_bytes_all((GOutputStream *)bundlestream, sig, NULL, &ierror); if (!res) { g_propagate_prefixed_error( error, ierror, "failed to append signature to bundle: "); goto out; } offset = g_seekable_tell((GSeekable *)bundlestream) - offset; res = output_stream_write_uint64_all((GOutputStream *)bundlestream, offset, NULL, &ierror); if (!res) { g_propagate_prefixed_error( error, ierror, "failed to append signature size to bundle: "); goto out; } res = TRUE; out: g_clear_object(&bundlestream); g_clear_object(&bundlefile); g_clear_pointer(&sig, g_bytes_unref); return res; }
static gboolean handle_install_authorized_keys (MinCloudAgentApp *self, GInputStream *instream, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; int fd; guint i; gs_unref_object GOutputStream *outstream = NULL; gs_unref_object GDataInputStream *datain = NULL; gs_unref_ptrarray GPtrArray *lines = g_ptr_array_new_with_free_func (g_free); datain = g_data_input_stream_new (instream); while (TRUE) { gsize len; GError *temp_error = NULL; char *line = g_data_input_stream_read_line_utf8 (datain, &len, cancellable, &temp_error); if (temp_error != NULL) { g_propagate_error (error, temp_error); g_prefix_error (error, "Reading ssh keys: "); goto out; } if (!line) break; g_ptr_array_add (lines, line); } (void) g_input_stream_close ((GInputStream*)datain, NULL, NULL); outstream = (GOutputStream*)g_file_append_to (self->authorized_keys_path, 0, cancellable, error); if (!outstream) { g_prefix_error (error, "Appending to '%s': ", gs_file_get_path_cached (self->authorized_keys_path)); goto out; } fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)outstream); if (fchmod (fd, 0600) != 0) { int errsv = errno; g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to chmod authorized_keys: %s", g_strerror (errsv)); goto out; } for (i = 0; i < lines->len; i++) { const char *line = lines->pdata[i]; char nl[] = { '\n' }; gsize bytes_written; if (!g_output_stream_write_all (outstream, line, strlen (line), &bytes_written, cancellable, error)) goto out; if (!g_output_stream_write_all (outstream, nl, sizeof (nl), &bytes_written, cancellable, error)) goto out; } if (!g_output_stream_flush (outstream, cancellable, error)) goto out; gs_log_structured_print_id_v (MCA_KEY_INSTALLED_SUCCESS_ID, "Successfully installed ssh key for '%s'", "root"); ret = TRUE; out: return ret; }
static GOutputStream * get_checksum_stream (CheckcopyFileList * list, GFile * dest) { CheckcopyFileListPrivate *priv = GET_PRIVATE (list); gchar * basename; gchar * checksum_name; GFileOutputStream * out = NULL; GError *error = NULL; GCancellable * cancel; GFile *checksum = NULL; gint i; gchar *ext = "CHECKSUM"; cancel = checkcopy_get_cancellable (); if (priv->checksum_file) { /* We already have a file. Just append to it. */ out = g_file_append_to (priv->checksum_file, 0, cancel, &error); if (!out || error) { thread_show_gerror (dest, error); g_error_free (error); error = NULL; return NULL; } else { return G_OUTPUT_STREAM (out); } } /* We do not have a file yet, search for one */ basename = g_file_get_basename (dest); i = 0; do { DBG ("Try %d to generate a checksum file name", i); if (checksum) { g_object_unref (checksum); checksum = NULL; } if (error) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) { /* There was an error, but it was not that the file already exists. * We should abort at this point. */ thread_show_error (_("Failed to create checksum file: %s"), error->message); g_error_free (error); error = NULL; break; } else { /* continue with next iteration */ g_error_free (error); error = NULL; if (i > MAX_CHECKSUM_FILE_RETRIES) { thread_show_error (_("Maximum number of retries reached.\nCould not create a checksum file.")); break; } } } if (basename == NULL) { checksum_name = g_strdup (ext); } else { if (i==0) checksum_name = g_strconcat (basename, ".", ext, NULL); else checksum_name = g_strdup_printf ("%s-%d.%s", basename, i, ext); } checksum = g_file_resolve_relative_path (dest, checksum_name); i++; if (g_cancellable_set_error_if_cancelled (cancel, &error)) { break; } } while ((out = g_file_create (checksum, 0, cancel, &error)) == NULL); g_free (basename); if (out) { priv->checksum_file = checksum; return G_OUTPUT_STREAM (out); } else { if (checksum) g_object_unref (checksum); return NULL; } }
int main(int argc, char *argv[]) { EventdCoreContext *context; gchar *runtime_dir = NULL; gchar *control_socket = NULL; gchar **binds = NULL; gboolean take_over_socket = FALSE; gboolean enable_relay = TRUE; gboolean enable_sd_modules = TRUE; gchar *config_dir = NULL; gboolean daemonize = FALSE; gboolean print_paths = FALSE; gboolean print_version = FALSE; EventdReturnCode retval = EVENTD_RETURN_CODE_OK; GError *error = NULL; GOptionContext *option_context = NULL; #ifdef EVENTD_DEBUG g_setenv("G_MESSAGES_DEBUG", "all", FALSE); #endif /* EVENTD_DEBUG */ setlocale(LC_ALL, ""); #ifdef ENABLE_NLS bindtextdomain(GETTEXT_PACKAGE, EVENTD_LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); #endif /* ENABLE_NLS */ if ( ! g_get_filename_charsets(NULL) ) { g_warning(PACKAGE_NAME " does not support non-UTF-8 filename encoding"); return EVENTD_RETURN_CODE_FILESYSTEM_ENCODING_ERROR; } if ( G_UNLIKELY(! g_module_supported()) ) { g_warning("No loadable module support"); return EVENTD_RETURN_CODE_NO_MODULE_SUPPORT_ERROR; } #ifdef EVENTD_DEBUG setvbuf(stdout, NULL, _IOLBF, 0); const gchar *debug_log_filename = g_getenv("EVENTD_DEBUG_LOG_FILENAME"); GDataOutputStream *debug_stream = NULL; if ( debug_log_filename != NULL ) { GFile *debug_log; debug_log = g_file_new_for_path(debug_log_filename); GError *error = NULL; GFileOutputStream *debug_log_stream; debug_log_stream = g_file_append_to(debug_log, G_FILE_CREATE_NONE, NULL, &error); if ( debug_log_stream == NULL ) { g_warning("Couldn't open debug log file: %s", error->message); g_clear_error(&error); } else { debug_stream = g_data_output_stream_new(G_OUTPUT_STREAM(debug_log_stream)); g_object_unref(debug_log_stream); g_log_set_default_handler(_eventd_core_debug_log_handler, debug_stream); } g_object_unref(debug_log); } #endif /* EVENTD_DEBUG */ context = g_new0(EventdCoreContext, 1); context->interface.get_sockets = eventd_core_get_sockets; context->interface.push_event = eventd_core_push_event; #ifdef G_OS_UNIX context->system_mode = ( g_getenv("XDG_RUNTIME_DIR") == NULL ); if ( context->system_mode ) g_setenv("XDG_RUNTIME_DIR", "/run", TRUE); #endif /* G_OS_UNIX */ GOptionEntry entries[] = { { "private-socket", 'i', 0, G_OPTION_ARG_FILENAME, &control_socket, "Socket to listen for internal control", "<socket>" }, { "listen", 'l', 0, G_OPTION_ARG_STRING_ARRAY, &binds, "Add a socket to listen to", "<socket>" }, { "take-over", 't', GIO_UNIX_OPTION_FLAG, G_OPTION_ARG_NONE, &take_over_socket, "Take over socket", NULL }, { "no-relay", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &enable_relay, "Disable the relay feature", NULL }, { "no-service-discovery", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &enable_sd_modules, "Disable the service discovery feature", NULL }, { "config-dir", 'c', 0, G_OPTION_ARG_FILENAME, &config_dir, "Additionnal configuration directory", "<directory>" }, { "daemonize", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &daemonize, NULL, NULL }, { "paths", 'P', 0, G_OPTION_ARG_NONE, &print_paths, "Print search paths", NULL }, { "version", 'V', 0, G_OPTION_ARG_NONE, &print_version, "Print version", NULL }, { .long_name = NULL } };
static void * gio_fopen (const char * filename, const char * mode) { GError * error = 0; FileData * data = g_new0 (FileData, 1); data->file = g_file_new_for_uri (filename); switch (mode[0]) { case 'r': if (strchr (mode, '+')) { data->iostream = (GIOStream *) g_file_open_readwrite (data->file, 0, & error); CHECK_ERROR ("open", filename); data->istream = g_io_stream_get_input_stream (data->iostream); data->ostream = g_io_stream_get_output_stream (data->iostream); data->seekable = (GSeekable *) data->iostream; } else { data->istream = (GInputStream *) g_file_read (data->file, 0, & error); CHECK_ERROR ("open", filename); data->seekable = (GSeekable *) data->istream; } break; case 'w': if (strchr (mode, '+')) { data->iostream = (GIOStream *) g_file_replace_readwrite (data->file, 0, 0, 0, 0, & error); CHECK_ERROR ("open", filename); data->istream = g_io_stream_get_input_stream (data->iostream); data->ostream = g_io_stream_get_output_stream (data->iostream); data->seekable = (GSeekable *) data->iostream; } else { data->ostream = (GOutputStream *) g_file_replace (data->file, 0, 0, 0, 0, & error); CHECK_ERROR ("open", filename); data->seekable = (GSeekable *) data->ostream; } break; case 'a': if (strchr (mode, '+')) { gio_error ("Cannot open %s: GIO does not support read-and-append mode.", filename); goto FAILED; } else { data->ostream = (GOutputStream *) g_file_append_to (data->file, 0, 0, & error); CHECK_ERROR ("open", filename); data->seekable = (GSeekable *) data->ostream; } break; default: gio_error ("Cannot open %s: invalid mode.", filename); goto FAILED; } return data; FAILED: g_free (data); return 0; }
void decrypt_file (const gchar *input_file_path, const gchar *pwd) { GError *err = NULL; goffset file_size = get_file_size (input_file_path); if (file_size == -1) { return; } if (file_size < (goffset) (sizeof (Metadata) + SHA512_DIGEST_SIZE)) { g_printerr ("The selected file is not encrypted.\n"); return; } GFile *in_file = g_file_new_for_path (input_file_path); GFileInputStream *in_stream = g_file_read (in_file, NULL, &err); if (err != NULL) { g_printerr ("%s\n", err->message); // TODO return; } gchar *output_file_path; if (!g_str_has_suffix (input_file_path, ".enc")) { g_printerr ("The selected file may not be encrypted\n"); output_file_path = g_strconcat (input_file_path, ".decrypted", NULL); } else { output_file_path = g_strndup (input_file_path, (gsize) g_utf8_strlen (input_file_path, -1) - 4); // remove .enc } GFile *out_file = g_file_new_for_path (output_file_path); GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err); if (err != NULL) { g_printerr ("%s\n", err->message); // TODO return; } Metadata *header_metadata = g_new0 (Metadata, 1); CryptoKeys *decryption_keys = g_new0 (CryptoKeys, 1); gssize rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), header_metadata, sizeof (Metadata), NULL, &err); if (rw_len == -1) { g_printerr ("%s\n", err->message); // TODO return; } guchar *original_hmac = g_malloc (SHA512_DIGEST_SIZE); if (!g_seekable_seek (G_SEEKABLE (in_stream), file_size - SHA512_DIGEST_SIZE, G_SEEK_SET, NULL, &err)) { g_printerr ("Couldn't set the position, exiting...\n"); //TODO return; } rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), original_hmac, SHA512_DIGEST_SIZE, NULL, &err); if (rw_len == -1) { g_printerr ("%s\n", err->message); // TODO return; } if (!g_seekable_seek (G_SEEKABLE (in_stream), 0, G_SEEK_SET, NULL, &err)) { g_printerr ("Couldn't set the position, exiting...\n"); //TODO return; } GFile *file_encrypted_data = get_g_file_with_encrypted_data (in_stream, file_size); if (file_encrypted_data == NULL) { // TODO return; } if (!setup_keys (pwd, gcry_cipher_get_algo_keylen (header_metadata->algo), header_metadata, decryption_keys)) { g_printerr ("Error during key derivation or during memory allocation\n"); //TODO return; } if (!compare_hmac (decryption_keys->hmac_key, original_hmac, file_encrypted_data)) { g_printerr ("HMAC differs from the one stored inside the file.\nEither the password is wrong or the file has been corrupted.\n"); // TODO return; } decrypt (header_metadata, decryption_keys, file_encrypted_data, file_size - sizeof (Metadata) - SHA512_DIGEST_SIZE, out_stream); g_unlink (g_file_get_path (file_encrypted_data)); // TODO remove encrypted file? Give option to the user multiple_unref (5, (gpointer) &file_encrypted_data, (gpointer) &in_stream, (gpointer) &out_stream, (gpointer) &in_file, (gpointer) &out_file); multiple_gcry_free (3, (gpointer) &decryption_keys->crypto_key, (gpointer) &decryption_keys->derived_key, (gpointer) &decryption_keys->hmac_key); multiple_free (4, (gpointer) &header_metadata, (gpointer) &output_file_path, (gpointer) &original_hmac, (gpointer) &decryption_keys); }
static GjsAutoUnref<GFile> write_statistics_internal(GjsCoverage *coverage, JSContext *cx, GError **error) { using AutoCChar = std::unique_ptr<char, decltype(&free)>; using AutoStrv = std::unique_ptr<char *, decltype(&g_strfreev)>; GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage); /* Create output directory if it doesn't exist */ if (!g_file_make_directory_with_parents(priv->output_dir, nullptr, error)) { if (!g_error_matches(*error, G_IO_ERROR, G_IO_ERROR_EXISTS)) return nullptr; g_clear_error(error); } GFile *output_file = g_file_get_child(priv->output_dir, "coverage.lcov"); size_t lcov_length; AutoCChar lcov(js::GetCodeCoverageSummary(cx, &lcov_length), free); GjsAutoUnref<GOutputStream> ostream = G_OUTPUT_STREAM(g_file_append_to(output_file, G_FILE_CREATE_NONE, NULL, error)); if (!ostream) return nullptr; AutoStrv lcov_lines(g_strsplit(lcov.get(), "\n", -1), g_strfreev); GjsAutoChar test_name; bool ignoring_file = false; for (const char * const *iter = lcov_lines.get(); *iter; iter++) { if (ignoring_file) { if (strcmp(*iter, "end_of_record") == 0) ignoring_file = false; continue; } if (g_str_has_prefix(*iter, "TN:")) { /* Don't write the test name if the next line shows we are * ignoring the source file */ test_name = *iter; continue; } else if (g_str_has_prefix(*iter, "SF:")) { const char *filename = *iter + 3; if (!filename_has_coverage_prefixes(coverage, filename)) { ignoring_file = true; continue; } /* Now we can write the test name before writing the source file */ if (!write_line(ostream, test_name.get(), error)) return nullptr; /* The source file could be a resource, so we must use * g_file_new_for_commandline_arg() to disambiguate between URIs and * filesystem paths. */ GjsAutoUnref<GFile> source_file = g_file_new_for_commandline_arg(filename); GjsAutoChar diverged_paths = find_diverging_child_components(source_file, priv->output_dir); GjsAutoUnref<GFile> destination_file = g_file_resolve_relative_path(priv->output_dir, diverged_paths); if (!copy_source_file_to_coverage_output(source_file, destination_file, error)) return nullptr; /* Rewrite the source file path to be relative to the output * dir so that genhtml will find it */ if (!write_source_file_header(ostream, destination_file, error)) return nullptr; continue; } if (!write_line(ostream, *iter, error)) return nullptr; } return output_file; }
int main(int argc, char *argv[]) { gboolean print_version = FALSE; gboolean one_shot = FALSE; gchar *output_plugin = NULL; gchar **servers_desc = NULL; gchar **streams_desc = NULL; gchar **input_plugins = NULL; gchar **order = NULL; gchar *config = NULL; int retval = 0; GError *error = NULL; GOptionContext *option_context = NULL; GOptionGroup *option_group; #if DEBUG g_setenv("G_MESSAGES_DEBUG", "all", FALSE); #endif /* ! DEBUG */ setlocale(LC_ALL, ""); #ifdef ENABLE_NLS bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); #endif /* ENABLE_NLS */ #if DEBUG const gchar *debug_log_filename = g_getenv("J4STATUS_DEBUG_LOG_FILENAME"); GDataOutputStream *debug_stream = NULL; if ( debug_log_filename != NULL ) { GFile *debug_log; debug_log = g_file_new_for_path(debug_log_filename); GError *error = NULL; GFileOutputStream *debug_log_stream; debug_log_stream = g_file_append_to(debug_log, G_FILE_CREATE_NONE, NULL, &error); if ( debug_log_stream == NULL ) { g_warning("Couldn't open debug log file: %s", error->message); g_clear_error(&error); } else { debug_stream = g_data_output_stream_new(G_OUTPUT_STREAM(debug_log_stream)); g_object_unref(debug_log_stream); g_log_set_default_handler(_j4status_core_debug_log_handler, debug_stream); } g_object_unref(debug_log); } #endif /* DEBUG */ GOptionEntry entries[] = { { "output", 'o', 0, G_OPTION_ARG_STRING, &output_plugin, "Output plugin to use", "<plugin>" }, { "listen", 'l', 0, G_OPTION_ARG_STRING_ARRAY, &servers_desc, "Socket to listen on, will create a stream on connection (may be specified several times)", "<listen description>" }, { "stream", 't', 0, G_OPTION_ARG_STRING_ARRAY, &streams_desc, "Stream to read from/write to (may be specified several times)", "<stream description>" }, { "input", 'i', 0, G_OPTION_ARG_STRING_ARRAY, &input_plugins, "Input plugins to use (may be specified several times)", "<plugin>" }, { "order", 'O', 0, G_OPTION_ARG_STRING_ARRAY, &order, "Order of sections, specified once a section (see man)", "<section id>" }, { "one-shot", '1', 0, G_OPTION_ARG_NONE, &one_shot, "Tells j4status to stop right after starting", NULL }, { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "Config file to use", "<config>" }, { "version", 'V', 0, G_OPTION_ARG_NONE, &print_version, "Print version", NULL }, { NULL } }; option_context = g_option_context_new("- status line generator"); option_group = g_option_group_new(NULL, NULL, NULL, NULL, NULL); g_option_group_set_translation_domain(option_group, GETTEXT_PACKAGE); g_option_group_add_entries(option_group, entries); g_option_context_set_main_group(option_context, option_group); if ( ! g_option_context_parse(option_context, &argc, &argv, &error) ) { g_warning("Option parsing failed: %s\n", error->message); g_clear_error(&error); retval = 1; goto end; } g_option_context_free(option_context); if ( print_version ) { g_fprintf(stdout, PACKAGE_NAME " " PACKAGE_VERSION "\n"); goto end; } if ( config != NULL ) { g_setenv("J4STATUS_CONFIG_FILE", config, TRUE); g_free(config); } GKeyFile *key_file; key_file = j4status_config_get_key_file("Plugins"); if ( key_file != NULL ) { if ( output_plugin == NULL ) output_plugin = g_key_file_get_string(key_file, "Plugins", "Output", NULL); if ( input_plugins == NULL ) input_plugins = g_key_file_get_string_list(key_file, "Plugins", "Input", NULL, NULL); if ( order == NULL ) order = g_key_file_get_string_list(key_file, "Plugins", "Order", NULL, NULL); g_key_file_free(key_file); } J4statusCoreContext *context; context = g_new0(J4statusCoreContext, 1); J4statusCoreInterface interface = { .context = context, .add_section = _j4status_core_add_section, .remove_section = _j4status_core_remove_section, .trigger_generate = _j4status_core_trigger_generate, .trigger_action = _j4status_core_trigger_action, }; #ifdef G_OS_UNIX g_unix_signal_add(SIGTERM, _j4status_core_source_quit, context); g_unix_signal_add(SIGINT, _j4status_core_source_quit, context); g_unix_signal_add(SIGUSR1, _j4status_core_signal_usr1, context); g_unix_signal_add(SIGUSR2, _j4status_core_signal_usr2, context); /* Ignore SIGPIPE as it is useless */ signal(SIGPIPE, SIG_IGN); #endif /* G_OS_UNIX */ context->output_plugin = j4status_plugins_get_output_plugin(&interface, output_plugin); if ( context->output_plugin == NULL ) { g_warning("No usable output plugin, tried '%s'", output_plugin); retval = 10; goto end; } gchar *header = NULL; if ( context->output_plugin->interface.generate_header != NULL ) header = context->output_plugin->interface.generate_header(context->output_plugin->context); /* Creating input/output stream */ context->io = j4status_io_new(context, header, (const gchar * const *) servers_desc, (const gchar * const *) streams_desc); if ( context->io == NULL ) { g_warning("Couldn't create input/output streams"); retval = 2; goto end; } if ( order != NULL ) { context->order_weights = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); gchar **id; for ( id = order ; *id != NULL ; ++id ) g_hash_table_insert(context->order_weights, *id, GINT_TO_POINTER(1 + id - order)); g_free(order); } context->sections_hash = g_hash_table_new(g_str_hash, g_str_equal); context->input_plugins = j4status_plugins_get_input_plugins(&interface, input_plugins); if ( context->input_plugins == NULL ) { g_warning("No input plugins, will stop early"); one_shot = TRUE; retval = 11; } context->sections = g_list_reverse(context->sections); if ( context->order_weights != NULL ) context->sections = g_list_sort(context->sections, _j4status_core_compare_sections); _j4status_core_start(context); if ( one_shot ) g_idle_add(_j4status_core_source_quit, context); context->loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(context->loop); g_main_loop_unref(context->loop); context->loop = NULL; GList *input_plugin_; J4statusInputPlugin *input_plugin; for ( input_plugin_ = context->input_plugins ; input_plugin_ != NULL ; input_plugin_ = g_list_next(input_plugin_) ) { input_plugin = input_plugin_->data; input_plugin->interface.uninit(input_plugin->context); } if ( context->output_plugin->interface.uninit != NULL ) context->output_plugin->interface.uninit(context->output_plugin->context); j4status_io_free(context->io); if ( context->order_weights != NULL ) g_hash_table_unref(context->order_weights); g_hash_table_unref(context->sections_hash); end: #if DEBUG if ( debug_stream != NULL ) g_object_unref(debug_stream); #endif /* DEBUG */ return retval; }
gpointer sign_file (const gchar *input_file_path, const gchar *fpr) { gpgme_error_t error; gpgme_ctx_t context; gpgme_key_t signing_key; gpgme_data_t clear_text, signed_text; gpgme_sign_result_t result; gchar *buffer; gssize nbytes; error = gpgme_new (&context); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); return GPGME_ERROR; } gpgme_set_armor (context, 0); error = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } const char *keyring_dir = gpgme_get_dirinfo ("homedir"); error = gpgme_ctx_set_engine_info (context, GPGME_PROTOCOL_OpenPGP, NULL, keyring_dir); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_get_key (context, fpr, &signing_key, 1); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); gpgme_release (context); return GPGME_ERROR; } error = gpgme_signers_add (context, signing_key); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } FILE *infp = g_fopen (input_file_path, "r"); if (infp == NULL) { g_printerr ("Couldn't open input file\n"); cleanup (NULL, NULL, NULL, NULL, &signing_key, &context); return FILE_OPEN_ERROR; } error = gpgme_data_new_from_stream (&clear_text, infp); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_new (&signed_text); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_op_sign (context, clear_text, signed_text, GPGME_SIG_MODE_DETACH); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } result = gpgme_op_sign_result (context); if (result->invalid_signers) { g_printerr ("Invalid signer found: %s\n", result->invalid_signers->fpr); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } if (!result->signatures || result->signatures->next) { g_printerr ("Unexpected number of signatures created\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } error = gpgme_data_seek (signed_text, 0, SEEK_SET); if (error) { g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error)); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } buffer = g_try_malloc0 (SIG_MAXLEN); if (buffer == NULL) { g_printerr ("Couldn't allocate memory\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return MEMORY_ALLOCATION_ERROR; } nbytes = gpgme_data_read (signed_text, buffer, SIG_MAXLEN); if (nbytes == -1) { g_printerr ("Error while reading data\n"); cleanup (infp, NULL, NULL, NULL, &signing_key, &context); return GPGME_ERROR; } GError *gerr = NULL; gchar *output_file_path = g_strconcat (input_file_path, ".sig", NULL); GFile *fpout = g_file_new_for_path (output_file_path); GFileOutputStream *ostream = g_file_append_to (fpout, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &gerr); if (gerr != NULL) { g_printerr ("Couldn't open output file for writing\n"); cleanup (infp, fpout, NULL, output_file_path, &signing_key, &context); return FILE_OPEN_ERROR; } gssize wbytes = g_output_stream_write (G_OUTPUT_STREAM (ostream), buffer, nbytes, NULL, &gerr); if (wbytes == -1) { g_printerr ("Couldn't write the request number of bytes (%s)\n", gerr->message); cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return FILE_WRITE_ERROR; } cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context); return SIGN_OK; }
gpointer encrypt_file (const gchar *input_file_path, const gchar *pwd, const gchar *algo, const gchar *algo_mode) { Metadata *header_metadata = g_new0 (Metadata, 1); CryptoKeys *encryption_keys = g_new0 (CryptoKeys, 1); set_algo_and_mode (header_metadata, algo, algo_mode); gsize algo_key_len = gcry_cipher_get_algo_keylen (header_metadata->algo); gsize algo_blk_len = gcry_cipher_get_algo_blklen (header_metadata->algo); header_metadata->iv_size = algo_blk_len; // iv must be the same size as the block size gcry_create_nonce (header_metadata->iv, header_metadata->iv_size); gcry_create_nonce (header_metadata->salt, KDF_SALT_SIZE); if (!setup_keys (pwd, algo_key_len, header_metadata, encryption_keys)) { multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata); return g_strdup ("Couldn't setup the encryption keys, exiting..."); } goffset filesize = get_file_size (input_file_path); GError *err = NULL; GFile *in_file = g_file_new_for_path (input_file_path); GFileInputStream *in_stream = g_file_read (in_file, NULL, &err); if (err != NULL) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata); g_object_unref (in_file); return g_strdup (err->message); } gchar *output_file_path = g_strconcat (input_file_path, ".enc", NULL); GFile *out_file = g_file_new_for_path (output_file_path); GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err); if (err != NULL) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path); multiple_unref (3, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream); g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); return g_strdup (err->message); } gcry_cipher_hd_t hd; gcry_cipher_open (&hd, header_metadata->algo, header_metadata->algo_mode, 0); gcry_cipher_setkey (hd, encryption_keys->crypto_key, algo_key_len); gint64 number_of_blocks; gint number_of_padding_bytes; gchar *ret_msg; if (header_metadata->algo_mode == GCRY_CIPHER_MODE_CBC) { set_number_of_blocks_and_padding_bytes (filesize, algo_blk_len, &number_of_blocks, &number_of_padding_bytes); gcry_cipher_setiv (hd, header_metadata->iv, header_metadata->iv_size); ret_msg = encrypt_using_cbc_mode (header_metadata, &hd, number_of_blocks, number_of_padding_bytes, algo_blk_len, in_stream, out_stream); } else { gcry_cipher_setctr (hd, header_metadata->iv, header_metadata->iv_size); ret_msg = encrypt_using_ctr_mode (header_metadata, &hd, filesize, in_stream, out_stream); } if (ret_msg != NULL) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path); multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream, (gpointer) &out_stream); g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL); return g_strdup (ret_msg); } gcry_cipher_close (hd); guchar *hmac = calculate_hmac (output_file_path, encryption_keys->hmac_key, NULL); gssize written_bytes = g_output_stream_write (G_OUTPUT_STREAM (out_stream), hmac, SHA512_DIGEST_SIZE, NULL, &err); if (written_bytes == -1) { multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (4, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path, (gpointer) &hmac); multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream, (gpointer) &out_stream); g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL); return g_strdup (err->message); } g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL); g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL); multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key, (gpointer) &encryption_keys->hmac_key); multiple_free (4, (gpointer) &output_file_path, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &hmac); multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream, (gpointer) &out_stream); return NULL; }
static gboolean save (GFile *file) { GOutputStream *out; GFileCreateFlags flags; char buffer[1025]; char *p; gssize res; gboolean close_res; GError *error; gboolean save_res; error = NULL; flags = priv ? G_FILE_CREATE_PRIVATE : G_FILE_CREATE_NONE; flags |= replace_dest ? G_FILE_CREATE_REPLACE_DESTINATION : 0; if (create) out = (GOutputStream *)g_file_create (file, flags, NULL, &error); else if (append) out = (GOutputStream *)g_file_append_to (file, flags, NULL, &error); else out = (GOutputStream *)g_file_replace (file, etag, backup, flags, NULL, &error); if (out == NULL) { g_printerr (_("Error opening file: %s\n"), error->message); g_error_free (error); return FALSE; } save_res = TRUE; while (1) { res = read (STDIN_FILENO, buffer, 1024); if (res > 0) { ssize_t written; p = buffer; while (res > 0) { error = NULL; written = g_output_stream_write (out, p, res, NULL, &error); if (written == -1) { save_res = FALSE; g_printerr ("Error writing to stream: %s", error->message); g_error_free (error); goto out; } res -= written; p += written; } } else if (res < 0) { save_res = FALSE; perror (_("Error reading stdin")); break; } else if (res == 0) break; } out: close_res = g_output_stream_close (out, NULL, &error); if (!close_res) { save_res = FALSE; g_printerr (_("Error closing: %s\n"), error->message); g_error_free (error); } if (close_res && print_etag) { char *etag; etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (out)); if (etag) g_print ("Etag: %s\n", etag); else /* Translators: The "etag" is a token allowing to verify whether a file has been modified */ g_print (_("Etag not available\n")); g_free (etag); } g_object_unref (out); return save_res; }