/** * _gnome_date_time_source_new: * @now: The expected current time * @expiry: Time to await * @cancel_on_set: Also invoke callback if the system clock changes discontiguously * * This function is designed for programs that want to schedule an * event based on real (wall clock) time, as returned by * g_get_real_time(). For example, HOUR:MINUTE wall-clock displays * and calendaring software. The callback will be invoked when the * specified wall clock time @expiry is reached. This includes * events such as the system clock being set past the given time. * * Compare versus g_timeout_source_new() which is defined to use * monotonic time as returned by g_get_monotonic_time(). * * The parameter @now is necessary to avoid a race condition in * between getting the current time and calling this function. * * If @cancel_on_set is given, the callback will also be invoked at * most a second after the system clock is changed. This includes * being set backwards or forwards, and system * resume from suspend. Not all operating systems allow detecting all * relevant events efficiently - this function may cause the process * to wake up once a second in those cases. * * A wall clock display should use @cancel_on_set; a calendaring * program shouldn't need to. * * Note that the return value from the associated callback will be * ignored; this is a one time watch. * * <note><para>This function currently does not detect time zone * changes. On Linux, your program should also monitor the * <literal>/etc/timezone</literal> file using * #GFileMonitor.</para></note> * * <example id="gdatetime-example-watch"><title>Clock example</title><programlisting><xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../glib/tests/glib-clock.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include></programlisting></example> * * Return value: A newly-constructed #GSource * * Since: 2.30 **/ GSource * _gnome_datetime_source_new (GDateTime *now, GDateTime *expiry, gboolean cancel_on_set) { GDateTimeSource *datetime_source; gint64 unix_seconds; unix_seconds = g_date_time_to_unix (expiry); datetime_source = (GDateTimeSource*) g_source_new (&g_datetime_source_funcs, sizeof (GDateTimeSource)); datetime_source->cancel_on_set = cancel_on_set; #ifdef HAVE_TIMERFD { gint64 expected_now_seconds = g_date_time_to_unix (now); if (g_datetime_source_init_timerfd (datetime_source, expected_now_seconds, unix_seconds)) return (GSource*)datetime_source; /* Fall through to non-timerfd code */ } #endif datetime_source->real_expiration = unix_seconds * 1000000; g_datetime_source_reschedule (datetime_source, g_get_monotonic_time ()); return (GSource*)datetime_source; }
static void _tgenmain_log(GLogLevelFlags level, const gchar* fileName, const gint lineNum, const gchar* functionName, const gchar* format, ...) { if(level > tgenLogFilterLevel) { return; } va_list vargs; va_start(vargs, format); gchar* fileStr = fileName ? g_path_get_basename(fileName) : g_strdup("n/a"); const gchar* functionStr = functionName ? functionName : "n/a"; GDateTime* dt = g_date_time_new_now_local(); GString* newformat = g_string_new(NULL); g_string_append_printf(newformat, "%04i-%02i-%02i %02i:%02i:%02i %"G_GINT64_FORMAT".%06i [%s] [%s:%i] [%s] %s", g_date_time_get_year(dt), g_date_time_get_month(dt), g_date_time_get_day_of_month(dt), g_date_time_get_hour(dt), g_date_time_get_minute(dt), g_date_time_get_second(dt), g_date_time_to_unix(dt), g_date_time_get_microsecond(dt), _tgenmain_logLevelToString(level), fileStr, lineNum, functionName, format); gchar* message = g_strdup_vprintf(newformat->str, vargs); g_print("%s\n", message); g_free(message); g_string_free(newformat, TRUE); g_date_time_unref(dt); g_free(fileStr); va_end(vargs); }
static time_t date_to_time_t (const xmlChar *str, const char * tzid) { struct tm time = { 0 }; GTimeZone *tz; GDateTime *dt; time_t rval; char *after; after = strptime ((const char*) str, "%Y-%m-%dT%T", &time); if (after == NULL) { g_warning ("Cannot parse date string \"%s\"", str); return 0; } if (*after == 'Z') tzid = "UTC"; tz = g_time_zone_new (tzid); dt = g_date_time_new (tz, time.tm_year + 1900, time.tm_mon + 1, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec); rval = g_date_time_to_unix (dt); g_time_zone_unref (tz); g_date_time_unref (dt); return rval; }
time64 gnc_mktime (struct tm* time) { GDateTime *gdt; time64 secs; normalize_struct_tm (time); gdt = gnc_g_date_time_new_local (time->tm_year + 1900, time->tm_mon, time->tm_mday, time->tm_hour, time->tm_min, (gdouble)(time->tm_sec)); if (gdt == NULL) { g_warning("Invalid time passed to gnc_mktime"); return -1; } time->tm_mon = time->tm_mon > 0 ? time->tm_mon - 1 : 11; // Watch out: struct tm has wday=0..6 with Sunday=0, but GDateTime has wday=1..7 with Sunday=7. time->tm_wday = g_date_time_get_day_of_week (gdt) % 7; time->tm_yday = g_date_time_get_day_of_year (gdt); time->tm_isdst = g_date_time_is_daylight_savings (gdt); #ifdef HAVE_STRUCT_TM_GMTOFF time->tm_gmtoff = g_date_time_get_utc_offset (gdt) / G_TIME_SPAN_SECOND; #endif secs = g_date_time_to_unix (gdt); g_date_time_unref (gdt); return secs; }
static void pdf_load_job_from_skydrive (PdfLoadJob *job) { gchar *tmp_name; gchar *tmp_path, *pdf_path; GDateTime *updated_time; GFile *pdf_file; updated_time = zpj_skydrive_entry_get_updated_time (job->zpj_entry); job->original_file_mtime = (guint64) g_date_time_to_unix (updated_time); tmp_name = g_strdup_printf ("gnome-documents-%u.pdf", g_str_hash (zpj_skydrive_entry_get_id (job->zpj_entry))); tmp_path = g_build_filename (g_get_user_cache_dir (), "gnome-documents", NULL); job->pdf_path = pdf_path = g_build_filename (tmp_path, tmp_name, NULL); g_mkdir_with_parents (tmp_path, 0700); pdf_file = g_file_new_for_path (pdf_path); g_file_query_info_async (pdf_file, G_FILE_ATTRIBUTE_TIME_MODIFIED, G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, job->cancellable, zpj_cache_query_info_ready_cb, job); g_free (tmp_name); g_free (tmp_path); g_object_unref (pdf_file); }
static gchar* _get_timestamp() { GDateTime* now = g_date_time_new_now_utc(); gint64 timestamp = g_date_time_to_unix(now); g_date_time_unref(now); return g_strdup_printf("%"G_GINT64_FORMAT, timestamp); }
gint64 daemon_helpers_date_time_converter_ToUnixTimestamp (GDateTime* dateTime) { gint64 result = 0LL; gint64 _tmp0_; g_return_val_if_fail (dateTime != NULL, 0LL); _tmp0_ = g_date_time_to_unix (dateTime); result = _tmp0_; return result; }
/** * gcal_event_widget_compare_by_length: * @widget1: * @widget2: * * Compare two widgets by the duration of the events they represent. From shortest to longest span. * * Returns: negative value if a < b ; zero if a = b ; positive value if a > b **/ gint gcal_event_widget_compare_by_length (GcalEventWidget *widget1, GcalEventWidget *widget2) { time_t time_s1, time_s2; time_t time_e1, time_e2; time_e1 = time_s1 = g_date_time_to_unix (widget1->dt_start); time_e2 = time_s2 = g_date_time_to_unix (widget2->dt_start); if (widget1->dt_end != NULL) time_e1 = g_date_time_to_unix (widget1->dt_end); if (widget2->dt_end) time_e2 = g_date_time_to_unix (widget2->dt_end); return (time_e2 - time_s2) - (time_e1 - time_s1); }
static gboolean schedule_wakeups_with_timerfd (GoaAlarm *self) { #ifdef HAVE_TIMERFD struct itimerspec timer_spec; int fd; int result; GSource *source; static gboolean seen_before = FALSE; if (!seen_before) { g_debug ("GoaAlarm: trying to use kernel timer"); seen_before = TRUE; } fd = timerfd_create (CLOCK_REALTIME, TFD_CLOEXEC | TFD_NONBLOCK); if (fd < 0) { g_debug ("GoaAlarm: could not create timer fd: %m"); return FALSE; } memset (&timer_spec, 0, sizeof (timer_spec)); timer_spec.it_value.tv_sec = g_date_time_to_unix (self->priv->time) + 1; result = timerfd_settime (fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &timer_spec, NULL); if (result < 0) { g_debug ("GoaAlarm: could not set timer: %m"); return FALSE; } self->priv->type = GOA_ALARM_TYPE_TIMER; self->priv->stream = g_unix_input_stream_new (fd, TRUE); source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (self->priv->stream), NULL); self->priv->scheduled_wakeup_source = source; g_source_set_callback (self->priv->scheduled_wakeup_source, (GSourceFunc) on_timer_source_ready, self, (GDestroyNotify) clear_wakeup_source_pointer); g_source_attach (self->priv->scheduled_wakeup_source, self->priv->context); g_source_unref (source); return TRUE; #endif /*HAVE_TIMERFD */ return FALSE; }
GDateTime* gnc_g_date_time_new_from_timespec_local (Timespec ts) { GDateTime *gdt1 = gnc_g_date_time_new_from_unix_local (ts.tv_sec); double nsecs = ((double)ts.tv_nsec + 0.5)/ 1000000000.0L; GDateTime *gdt2 = g_date_time_add_seconds (gdt1, nsecs); g_date_time_unref (gdt1); g_assert (g_date_time_to_unix (gdt2) == ts.tv_sec + (nsecs >= 1.0 ? (gint64)nsecs : 0)); return gdt2; }
time64 gnc_time_utc (time64 *tbuf) { GDateTime *gdt = g_date_time_new_now_utc (); time64 secs = g_date_time_to_unix (gdt); g_date_time_unref (gdt); if (tbuf != NULL) *tbuf = secs; return secs; }
gint64 utils_timestamp_now(void) { gint64 timestamp; GDateTime* now; now = g_date_time_new_now_utc(); timestamp = g_date_time_to_unix(now); g_date_time_unref(now); return timestamp; }
gint64 empathy_time_get_current (void) { GDateTime *now; gint64 result; now = g_date_time_new_now_utc (); result = g_date_time_to_unix (now); g_date_time_unref (now); return result; }
static gboolean handle_get_server_time (CockpitManager *object, GDBusMethodInvocation *invocation) { GDateTime *now = g_date_time_new_now_local (); cockpit_manager_complete_get_server_time (object, invocation, g_date_time_to_unix (now), g_date_time_get_timezone_abbreviation (now), g_date_time_get_utc_offset (now) / 1.0e6); g_date_time_unref (now); return TRUE; }
Timespec gnc_iso8601_to_timespec_gmt(const char *str) { Timespec time = { 0L, 0L }; GDateTime *gdt; gint hour = 0, minute = 0, day = 0, month = 0, year = 0; gchar zone[12]; gdouble second = 0.0; gint fields; memset (zone, 0, sizeof (zone)); if (!str) return time; fields = sscanf (str, ISO_DATE_FORMAT, &year, &month, &day, &hour, &minute, &second, zone); if (fields < 1) return time; else if (fields > 6 && strlen (zone) > 0) /* Date string included a timezone */ { GTimeZone *tz = g_time_zone_new (zone); time64 secs; second += 5e-10; gdt = g_date_time_new (tz, year, month, day, hour, minute, second); secs = g_date_time_to_unix (gdt); g_time_zone_unref (tz); } else /* No zone info, assume UTC */ { second += 5e-10; gdt = g_date_time_new_utc (year, month, day, hour, minute, second); } time.tv_sec = g_date_time_to_unix (gdt); time.tv_nsec = g_date_time_get_microsecond (gdt) * 1000; g_date_time_unref (gdt); return time; }
gint __gst_date_time_compare (const GstDateTime * dt1, const GstDateTime * dt2) { gint64 diff; /* we assume here that GST_DATE_TIME_FIELDS_YMD_HMS is the highest * resolution, and ignore microsecond differences on purpose for now */ if (dt1->fields != dt2->fields) return GST_VALUE_UNORDERED; /* This will round down to nearest second, which is what we want. We're * not comparing microseconds on purpose here, since we're not * serialising them when doing new_utc_now() + to_string() */ diff = g_date_time_to_unix (dt1->datetime) - g_date_time_to_unix (dt2->datetime); if (diff < 0) return GST_VALUE_LESS_THAN; else if (diff > 0) return GST_VALUE_GREATER_THAN; else return GST_VALUE_EQUAL; }
static GSignondDictionary* _respond_with_stored_token(GSignondDictionary *token) { if (token == NULL) return FALSE; gint64 duration; gboolean has_duration = gsignond_dictionary_get_int64(token, "Duration", &duration); gint64 timestamp; gboolean has_timestamp = gsignond_dictionary_get_int64(token, "Timestamp", ×tamp); gint64 expires_in = 0; if (has_duration && has_timestamp) { GDateTime* now = g_date_time_new_now_utc(); expires_in = duration + timestamp - g_date_time_to_unix(now); g_date_time_unref(now); if (expires_in < 0) return FALSE; } GVariant* token_variant = gsignond_dictionary_get(token, "AccessToken"); if (token_variant != NULL) { GSignondSessionData* response = gsignond_dictionary_new(); gsignond_dictionary_set(response, "AccessToken", token_variant); GVariant* refresh_token = gsignond_dictionary_get(token, "RefreshToken"); if (refresh_token != NULL) gsignond_dictionary_set(response, "RefreshToken", refresh_token); GVariant* token_type = gsignond_dictionary_get(token, "TokenType"); if (token_type != NULL) gsignond_dictionary_set(response, "TokenType", token_type); GVariant* token_params = gsignond_dictionary_get(token, "TokenParameters"); if (token_params != NULL) gsignond_dictionary_set(response, "TokenParameters", token_params); const gchar* token_scope_s = gsignond_dictionary_get_string(token, "Scope"); if (token_scope_s != NULL) { gsignond_dictionary_set_string(response, "Scope", token_scope_s); } if (has_duration) { gsignond_dictionary_set_int64(response, "Duration", duration); } if (has_timestamp) { gsignond_dictionary_set_int64(response, "Timestamp", timestamp); } return response; } return NULL; }
static void queue_set_datetime (CcDateTimePanel *self) { gint64 unixtime; /* for now just do it */ unixtime = g_date_time_to_unix (self->priv->date); date_time_mechanism_call_set_time (self->priv->dtm, unixtime, self->priv->cancellable, set_time_cb, self); }
//-------------------------------------------------------------------- // // 函数功能 :对日期字符串转换为从1970-01-01 00:00:00 UTC开始的秒数。 // 支持格式为: // 1. YYYY-mm-DD HH:MM:SS; // 2. YYYY-mm-DD HH:MM; // 3. YYYY/mm/DD HH:MM:SS; // 4. YYYY/mm/DD HH:MM; // // 函数参数 :gchar* strdate : 日期字符串。 // // 返回值 :gint64 : 对应秒数或0(非法日期格式)。 // // 用法示例 :getStrDate2Int ( "2014-01-01 00:00:00" ); // 返回 : 1388505600 // // 修改记录 : // //-------------------------------------------------------------------- gint64 getStrDate2Int ( gchar *strdate ) { gchar **datetime = g_strsplit ( strdate, " ", 0 ); GDateTime *dt = NULL; if ( g_strv_length(datetime) == 2 ) { gint year, month, day, hour, minute, second; gchar **dates1 = g_strsplit ( datetime[0], "-", 0 ); gchar **dates2 = g_strsplit ( datetime[0], "/", 0 ); if ( g_strv_length(dates1) == 3 ) { year = atoi ( dates1[0] ); month = atoi ( dates1[1] ); day = atoi ( dates1[2] ); } else if ( g_strv_length(dates2) == 3 ) { year = atoi ( dates2[2] ); month = atoi ( dates2[1] ); day = atoi ( dates2[0] ); } else { g_strfreev ( dates1 ); g_strfreev ( dates2 ); g_strfreev ( datetime ); return 0; } gchar **times = g_strsplit ( datetime[1], ":", 0 ); if ( g_strv_length(times) == 3 ) { hour = atoi ( times[0] ); minute = atoi ( times[1] ); second = atoi ( times[2] ); } else if ( g_strv_length(times) == 2 ) { hour = atoi ( times[0] ); minute = atoi ( times[1] ); second = 0; } else { g_strfreev ( times ); g_strfreev ( dates1 ); g_strfreev ( dates2 ); g_strfreev ( datetime ); return 0; } dt = g_date_time_new_local ( year, month, day, hour, minute, second ); g_strfreev ( dates1 ); g_strfreev ( dates2 ); g_strfreev ( times ); g_strfreev ( datetime ); return g_date_time_to_unix ( dt ); } g_strfreev ( datetime ); return 0; }
void cb_mini_tweet_parse (CbMiniTweet *t, JsonObject *obj) { GDateTime *time; JsonObject *extended_object; const char *tweet_text; if (json_object_has_member (obj, "extended_tweet")) extended_object = json_object_get_object_member (obj, "extended_tweet"); else extended_object = obj; time = cb_utils_parse_date (json_object_get_string_member (obj, "created_at")); t->id = json_object_get_int_member (obj, "id"); if (json_object_has_member (extended_object, "full_text")) tweet_text = json_object_get_string_member (extended_object, "full_text"); else tweet_text = json_object_get_string_member (extended_object, "text"); if (json_object_has_member (extended_object, "display_text_range")) { /* We only remove the prefix */ guint start = (guint)json_array_get_int_element ( json_object_get_array_member (extended_object, "display_text_range"), 0); guint i; const char *p = tweet_text; /* Skip ahead */ for (i = 0; i < start; i ++) p = g_utf8_next_char (p); t->text = g_strdup (p); t->display_range_start = start; } else { t->text = g_strdup (tweet_text); t->display_range_start= 0; } t->created_at = g_date_time_to_unix (time); cb_user_identity_parse (&t->author, json_object_get_object_member (obj, "user")); g_date_time_unref (time); }
static gchar * generate_new_id (GoaDaemon *daemon) { static guint counter = 0; GDateTime *dt; gchar *ret; dt = g_date_time_new_now_local (); ret = g_strdup_printf ("account_%" G_GINT64_FORMAT "_%u", g_date_time_to_unix (dt), /* seconds since Epoch */ counter); /* avoids collisions */ g_date_time_unref (dt); counter++; return ret; }
static void queue_set_datetime (CcDateTimePanel *self) { gint64 unixtime; /* timedated expects number of microseconds since 1 Jan 1970 UTC */ unixtime = g_date_time_to_unix (self->priv->date); timedate1_call_set_time (self->priv->dtm, unixtime * 1000000, FALSE, TRUE, self->priv->cancellable, set_time_cb, self); }
static void set_sensitivity (UmHistoryDialog *um) { GArray *login_history; UmLoginHistory history; gboolean sensitive = FALSE; login_history = get_login_history (um->user); if (login_history != NULL) { history = g_array_index (login_history, UmLoginHistory, 0); sensitive = g_date_time_to_unix (um->week) > history.login_time; g_array_free (login_history, TRUE); } gtk_widget_set_sensitive (get_widget (um, "previous-button"), sensitive); sensitive = (g_date_time_compare (um->current_week, um->week) == 1); gtk_widget_set_sensitive (get_widget (um, "next-button"), sensitive); }
static void _pcapmain_log(GLogLevelFlags level, const gchar* functionName, const gchar* format, ...) { va_list vargs; va_start(vargs, format); GDateTime* dt = g_date_time_new_now_local(); GString* newformat = g_string_new(NULL); g_string_append_printf(newformat, "%04i-%02i-%02i %02i:%02i:%02i %"G_GINT64_FORMAT".%06i [%s] [%s] %s", g_date_time_get_year(dt), g_date_time_get_month(dt), g_date_time_get_day_of_month(dt), g_date_time_get_hour(dt), g_date_time_get_minute(dt), g_date_time_get_second(dt), g_date_time_to_unix(dt), g_date_time_get_microsecond(dt), _pcapmain_logLevelToString(level), functionName, format); g_logv(PCAP_LOG_DOMAIN, level, newformat->str, vargs); g_string_free(newformat, TRUE); g_date_time_unref(dt); va_end(vargs); }
time64 gnc_timegm (struct tm* time) { GDateTime *gdt; time64 secs; normalize_struct_tm (time); gdt = g_date_time_new_utc (time->tm_year + 1900, time->tm_mon, time->tm_mday, time->tm_hour, time->tm_min, (gdouble)(time->tm_sec)); time->tm_mon = time->tm_mon > 0 ? time->tm_mon - 1 : 11; // Watch out: struct tm has wday=0..6 with Sunday=0, but GDateTime has wday=1..7 with Sunday=7. time->tm_wday = g_date_time_get_day_of_week (gdt) % 7; time->tm_yday = g_date_time_get_day_of_year (gdt); time->tm_isdst = g_date_time_is_daylight_savings (gdt); secs = g_date_time_to_unix (gdt); g_date_time_unref (gdt); return secs; }
static void element_browser (gpointer data, gpointer user_data) { GrlMedia *media = GRL_MEDIA (data); GrlSource *source = GRL_SOURCE (user_data); /* Check if we got a valid media object as some plugins may call the callback with a NULL media under certain circumstances (for example when they cannot estimate the number of remaining results and they find suddenly they don't have any more results to send) */ if (!media) { g_debug ("Media element is NULL!"); goto out; } const gchar *title = grl_media_get_title (media); /* If the media is a container, that means we will browse it again */ if (grl_media_is_container (media)) { guint childcount = grl_media_get_childcount (media); g_debug ("\t Got '%s' (container with %d elements)", title, childcount); source_browser (source, media); } else { const gchar *url = grl_media_get_url (media); const gchar *mime = grl_media_get_mime (media); GDateTime *date = grl_media_get_modification_date (media); time_t rawdate = g_date_time_to_unix(date); g_printf ("\t Got '%s', of type '%s', ctime is '%s'\n", title, mime, ctime(&rawdate)); g_printf ("\t\t URL: %s\n", url); } out: g_object_unref (media); }
static gboolean add_single_file_from_media (BgPicturesSource *bg_source, GFile *file, GrlMedia *media) { GDateTime *mtime; const gchar *content_type; gint64 mtime_unix; content_type = grl_media_get_mime (media); /* only GRL_METADATA_KEY_CREATION_DATE is implemented in the Flickr * plugin, GRL_METADATA_KEY_MODIFICATION_DATE is not */ mtime = grl_media_get_creation_date (media); if (!mtime) mtime = grl_media_get_modification_date (media); if (mtime) mtime_unix = g_date_time_to_unix (mtime); else mtime_unix = g_get_real_time () / G_USEC_PER_SEC; return add_single_file (bg_source, file, content_type, (guint64) mtime_unix, NULL); }
/** * ggit_index_entry_set_commit: * @entry: a #GgitIndexEntry. * @commit: a #GgitCommit. * * Set the index entry to point to a given commit. This sets the index entry * id to the commit id, changes the mode to #GGIT_FILE_MODE_COMMIT and updates * the timestamps to when the commit was made. * **/ void ggit_index_entry_set_commit (GgitIndexEntry *entry, GgitCommit *commit) { GgitSignature *sig; gint64 ut; g_return_if_fail (entry != NULL); g_return_if_fail (GGIT_IS_COMMIT (commit)); ggit_index_entry_set_id (entry, ggit_object_get_id (GGIT_OBJECT (commit))); ggit_index_entry_set_mode (entry, GIT_FILEMODE_COMMIT); sig = ggit_commit_get_committer (commit); ut = g_date_time_to_unix (ggit_signature_get_time (sig)); entry->entry->ctime.seconds = ut; entry->entry->ctime.nanoseconds = 0; entry->entry->mtime.seconds = ut; entry->entry->mtime.nanoseconds = 0; g_object_unref (sig); }
gboolean ostree_builtin_commit (int argc, char **argv, GCancellable *cancellable, GError **error) { GOptionContext *context; glnx_unref_object OstreeRepo *repo = NULL; gboolean ret = FALSE; gboolean skip_commit = FALSE; g_autoptr(GFile) object_to_commit = NULL; g_autofree char *parent = NULL; g_autofree char *commit_checksum = NULL; g_autoptr(GFile) root = NULL; g_autoptr(GVariant) metadata = NULL; g_autoptr(GVariant) detached_metadata = NULL; glnx_unref_object OstreeMutableTree *mtree = NULL; g_autofree char *tree_type = NULL; g_autoptr(GHashTable) mode_adds = NULL; g_autoptr(GHashTable) skip_list = NULL; OstreeRepoCommitModifierFlags flags = 0; OstreeRepoCommitModifier *modifier = NULL; OstreeRepoTransactionStats stats; struct CommitFilterData filter_data = { 0, }; context = g_option_context_new ("[PATH] - Commit a new revision"); if (!ostree_option_context_parse (context, options, &argc, &argv, OSTREE_BUILTIN_FLAG_NONE, &repo, cancellable, error)) goto out; if (!ostree_ensure_repo_writable (repo, error)) goto out; if (opt_statoverride_file) { mode_adds = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); if (!parse_file_by_line (opt_statoverride_file, handle_statoverride_line, mode_adds, cancellable, error)) goto out; } if (opt_skiplist_file) { skip_list = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); if (!parse_file_by_line (opt_skiplist_file, handle_skiplist_line, skip_list, cancellable, error)) goto out; } if (opt_metadata_strings) { if (!parse_keyvalue_strings (opt_metadata_strings, &metadata, error)) goto out; } if (opt_detached_metadata_strings) { if (!parse_keyvalue_strings (opt_detached_metadata_strings, &detached_metadata, error)) goto out; } if (!(opt_branch || opt_orphan)) { g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED, "A branch must be specified with --branch, or use --orphan"); goto out; } if (opt_no_xattrs) flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS; if (opt_generate_sizes) flags |= OSTREE_REPO_COMMIT_MODIFIER_FLAGS_GENERATE_SIZES; if (opt_disable_fsync) ostree_repo_set_disable_fsync (repo, TRUE); if (flags != 0 || opt_owner_uid >= 0 || opt_owner_gid >= 0 || opt_statoverride_file != NULL || opt_skiplist_file != NULL || opt_no_xattrs) { filter_data.mode_adds = mode_adds; filter_data.skip_list = skip_list; modifier = ostree_repo_commit_modifier_new (flags, commit_filter, &filter_data, NULL); } if (opt_parent) { if (g_str_equal (opt_parent, "none")) parent = NULL; else { if (!ostree_validate_checksum_string (opt_parent, error)) goto out; parent = g_strdup (opt_parent); } } else if (!opt_orphan) { if (!ostree_repo_resolve_rev (repo, opt_branch, TRUE, &parent, error)) { if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY)) { /* A folder exists with the specified ref name, * which is handled by _ostree_repo_write_ref */ g_clear_error (error); } else goto out; } } if (opt_editor) { if (!commit_editor (repo, opt_branch, &opt_subject, &opt_body, cancellable, error)) goto out; } if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error)) goto out; if (opt_link_checkout_speedup && !ostree_repo_scan_hardlinks (repo, cancellable, error)) goto out; mtree = ostree_mutable_tree_new (); if (argc <= 1 && (opt_trees == NULL || opt_trees[0] == NULL)) { if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, ".", mtree, modifier, cancellable, error)) goto out; } else if (opt_trees != NULL) { const char *const*tree_iter; const char *tree; const char *eq; for (tree_iter = (const char *const*)opt_trees; *tree_iter; tree_iter++) { tree = *tree_iter; eq = strchr (tree, '='); if (!eq) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Missing type in tree specification '%s'", tree); goto out; } g_free (tree_type); tree_type = g_strndup (tree, eq - tree); tree = eq + 1; g_clear_object (&object_to_commit); if (strcmp (tree_type, "dir") == 0) { if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, tree, mtree, modifier, cancellable, error)) goto out; } else if (strcmp (tree_type, "tar") == 0) { object_to_commit = g_file_new_for_path (tree); if (!ostree_repo_write_archive_to_mtree (repo, object_to_commit, mtree, modifier, opt_tar_autocreate_parents, cancellable, error)) goto out; } else if (strcmp (tree_type, "ref") == 0) { if (!ostree_repo_read_commit (repo, tree, &object_to_commit, NULL, cancellable, error)) goto out; if (!ostree_repo_write_directory_to_mtree (repo, object_to_commit, mtree, modifier, cancellable, error)) goto out; } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Invalid tree type specification '%s'", tree_type); goto out; } } } else { g_assert (argc > 1); if (!ostree_repo_write_dfd_to_mtree (repo, AT_FDCWD, argv[1], mtree, modifier, cancellable, error)) goto out; } if (mode_adds && g_hash_table_size (mode_adds) > 0) { GHashTableIter hash_iter; gpointer key, value; g_hash_table_iter_init (&hash_iter, mode_adds); while (g_hash_table_iter_next (&hash_iter, &key, &value)) { g_printerr ("Unmatched statoverride path: %s\n", (char*)key); } g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unmatched statoverride paths"); goto out; } if (skip_list && g_hash_table_size (skip_list) > 0) { GHashTableIter hash_iter; gpointer key; g_hash_table_iter_init (&hash_iter, skip_list); while (g_hash_table_iter_next (&hash_iter, &key, NULL)) { g_printerr ("Unmatched skip-list path: %s\n", (char*)key); } g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Unmatched skip-list paths"); goto out; } if (!ostree_repo_write_mtree (repo, mtree, &root, cancellable, error)) goto out; if (opt_skip_if_unchanged && parent) { g_autoptr(GFile) parent_root; if (!ostree_repo_read_commit (repo, parent, &parent_root, NULL, cancellable, error)) goto out; if (g_file_equal (root, parent_root)) skip_commit = TRUE; } if (!skip_commit) { gboolean update_summary; guint64 timestamp; if (!opt_timestamp) { GDateTime *now = g_date_time_new_now_utc (); timestamp = g_date_time_to_unix (now); g_date_time_unref (now); if (!ostree_repo_write_commit (repo, parent, opt_subject, opt_body, metadata, OSTREE_REPO_FILE (root), &commit_checksum, cancellable, error)) goto out; } else { struct timespec ts; if (!parse_datetime (&ts, opt_timestamp, NULL)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Could not parse '%s'", opt_timestamp); goto out; } timestamp = ts.tv_sec; if (!ostree_repo_write_commit_with_time (repo, parent, opt_subject, opt_body, metadata, OSTREE_REPO_FILE (root), timestamp, &commit_checksum, cancellable, error)) goto out; } if (detached_metadata) { if (!ostree_repo_write_commit_detached_metadata (repo, commit_checksum, detached_metadata, cancellable, error)) goto out; } if (opt_key_ids) { char **iter; for (iter = opt_key_ids; iter && *iter; iter++) { const char *keyid = *iter; if (!ostree_repo_sign_commit (repo, commit_checksum, keyid, opt_gpg_homedir, cancellable, error)) goto out; } } if (opt_branch) ostree_repo_transaction_set_ref (repo, NULL, opt_branch, commit_checksum); else g_assert (opt_orphan); if (!ostree_repo_commit_transaction (repo, &stats, cancellable, error)) goto out; /* The default for this option is FALSE, even for archive-z2 repos, * because ostree supports multiple processes committing to the same * repo (but different refs) concurrently, and in fact gnome-continuous * actually does this. In that context it's best to update the summary * explicitly instead of automatically here. */ if (!ot_keyfile_get_boolean_with_default (ostree_repo_get_config (repo), "core", "commit-update-summary", FALSE, &update_summary, error)) goto out; if (update_summary && !ostree_repo_regenerate_summary (repo, NULL, cancellable, error)) goto out; } else { commit_checksum = g_strdup (parent); } if (opt_table_output) { g_print ("Commit: %s\n", commit_checksum); g_print ("Metadata Total: %u\n", stats.metadata_objects_total); g_print ("Metadata Written: %u\n", stats.metadata_objects_written); g_print ("Content Total: %u\n", stats.content_objects_total); g_print ("Content Written: %u\n", stats.content_objects_written); g_print ("Content Bytes Written: %" G_GUINT64_FORMAT "\n", stats.content_bytes_written); } else { g_print ("%s\n", commit_checksum); } ret = TRUE; out: if (repo) ostree_repo_abort_transaction (repo, cancellable, NULL); if (context) g_option_context_free (context); if (modifier) ostree_repo_commit_modifier_unref (modifier); return ret; }
static gboolean gsf_output_stdio_close (GsfOutput *output) { GsfOutputStdio *stdio = GSF_OUTPUT_STDIO (output); gboolean res; char *backup_filename = NULL; GDateTime *modtime; if (stdio->file == NULL) return FALSE; if (gsf_output_error (output)) { res = TRUE; if (!stdio->keep_open && !close_file_helper (stdio, FALSE)) res = FALSE; if (!unlink_file_helper (stdio)) res = FALSE; return res; } if (stdio->keep_open) { gboolean res = (0 == fflush (stdio->file)); if (!res) gsf_output_set_error (output, errno, "Failed to flush."); stdio->file = NULL; return res; } res = close_file_helper (stdio, TRUE); /* short circuit our when dealing with raw FILE */ if (!stdio->real_filename) return res; if (!res) { unlink_file_helper (stdio); return FALSE; } /* Move the original file to a backup */ if (stdio->create_backup_copy) { gint result; backup_filename = g_strconcat (stdio->real_filename, ".bak", NULL); result = rename_wrapper (stdio->real_filename, backup_filename); if (result != 0) { char *utf8name = g_filename_display_name (backup_filename); gsf_output_set_error (output, errno, "Could not backup the original as %s.", utf8name); g_free (utf8name); g_unlink (stdio->temp_filename); res = FALSE; goto out; } } /* Move the temp file to the original file */ if (rename_wrapper (stdio->temp_filename, stdio->real_filename) != 0) { gint saved_errno = errno; if (backup_filename != NULL && rename_wrapper (backup_filename, stdio->real_filename) != 0) saved_errno = errno; res = gsf_output_set_error (output, saved_errno, "%s", g_strerror (saved_errno)); goto out; } modtime = gsf_output_get_modtime (output); if (modtime) { #ifdef UTIME_AVAILABLE struct utimbuf ut; ut.actime = time (NULL); ut.modtime = g_date_time_to_unix (modtime); /* Ignore errors */ /* utimes() provides better accuracy, but doesn't have gstdio version. gio seems to provide access. */ (void)utime (stdio->real_filename, &ut); #endif } /* Restore permissions. There is not much error checking we * can do here, I'm afraid. The final data is saved anyways. * Note the order: mode, uid+gid, gid, uid, mode. */ g_chmod (stdio->real_filename, stdio->st.st_mode); #ifdef HAVE_CHOWN if (chown_wrapper (stdio->real_filename, stdio->st.st_uid, stdio->st.st_gid)) { /* We cannot set both. Maybe we can set one. */ chown_wrapper (stdio->real_filename, -1, stdio->st.st_gid); chown_wrapper (stdio->real_filename, stdio->st.st_uid, -1); } g_chmod (stdio->real_filename, stdio->st.st_mode); #endif out: g_free (backup_filename); return res; }