Ejemplo n.º 1
0
static tn_array *parse_changelog(tn_alloc *na, tn_array *lines)
{
    struct changelog_ent  *ent = NULL;
    int                   i, max_MESSAGE = 1024;
    tn_array              *entries;
    tn_buf                *logmsg;

    entries = n_array_new(8, NULL, (tn_fn_cmp)changelog_ent_cmp);
    logmsg = n_buf_new(1024);
    
    for (i = 0; i < n_array_size(lines); i++) {
        char *line = n_array_nth(lines, i);

        if (*line == '*') {
            char *ts;
            
            if (ent != NULL) {
                n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg));
                n_buf_clean(logmsg);
                n_array_push(entries, ent);
                ent = NULL;
            }
            
            ent = na->na_malloc(na, sizeof(*ent) + max_MESSAGE);
            memset(ent, 0, sizeof(*ent));
            ent->info = na_strdup(na, line, strlen(line));
            ent->message[0] = '\0';

            //* [rREV] YYYY-MM-DD HH:MM:SS rest
            ts = strchr(line, ' ');
            while (*ts && isspace(*ts))
                ts++;
            
            if (ts && *ts == 'r')
                ts = strchr(ts, ' ');
            
            if (ts) {
                while (*ts && isspace(*ts))
                    ts++;
                
                if (ts)
                    ent->ts = parse_datetime(ts);
            }
            continue;
        }
        if (ent)
            n_buf_printf(logmsg, "%s\n", line);
    }
    
    if (ent != NULL) {
        n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg));
        n_array_push(entries, ent);
    }
    n_buf_free(logmsg);
    
    return entries;
}
Ejemplo n.º 2
0
static time_t
parse_time (const char *p, const time_t now)
{
  struct timespec nowspec = { 0, 0 };
  struct timespec thenspec;

  nowspec.tv_sec = now;

  if (!parse_datetime (&thenspec, p, &nowspec))
    return BAD_TIME;

  return thenspec.tv_sec;
}
Ejemplo n.º 3
0
/* FIXME: an error exit at field i leaves fields [0..i) modified. */
bool format_from_json(
	void *dest,
	JsonObject *obj,
	const struct field_desc *fields,
	size_t num_fields,
	GError **err_p)
{
	for(size_t i=0; i < num_fields; i++) {
		const char *name = fields[i].name;
		JsonNode *node = json_object_get_member(obj, name);
		if(node == NULL) {
			/* not present. skip. */
			continue;
		}
		bool null_ok = islower(fields[i].type),
			is_null = json_node_is_null(node);
		if(!null_ok && is_null) {
			g_set_error(err_p, 0, 0,
				"%s: field `%s' is null, but not allowed to",
				__func__, name);
			return false;
		}
		void *ptr = dest + fields[i].offset;
		switch(tolower(fields[i].type)) {
		case 'i':
			*(uint64_t *)ptr = is_null ? 0 : json_object_get_int_member(obj, name);
			break;
		case 'b':
			*(bool *)ptr = is_null ? false : json_object_get_boolean_member(obj, name);
			break;
		case 's':
			g_free(*(char **)ptr);
			*(char **)ptr = is_null ? NULL : g_strdup(json_object_get_string_member(obj, name));
			break;
		case 't': {
			GDateTime **dt_p = ptr;
			if(*dt_p != NULL) {
				g_date_time_unref(*dt_p);
				*dt_p = NULL;
			}
			*dt_p = parse_datetime(json_object_get_string_member(obj, name));
			break;
			}
		default:
			assert(false);
		}
	}

	return true;
}
Ejemplo n.º 4
0
int
Exosite_SyncTime()
{
  char day[11];
  char time[9];
  int http_status = 0;
  int strLen;
  char *testStr = "GET /ip HTTP/1.1\r\n";
  unsigned char serverAddr[6] = {54, 183, 115, 21, 0, 80};
  char strBuf[RX_SIZE];
  DateTime datetime;

  if (!exosite_initialized)
  {
    return -1;
  }

  long sock = connect_to_exosite_with_server_addr("", serverAddr);
  if (sock < 0)
  {
    return -1;
  }

  exoHAL_SocketSend(sock, testStr, strlen(testStr));
  sendLine(sock, HOST_LINE, NULL);
  sendLine(sock, ACCEPT_LINE, "\r\n");

  http_status = get_http_status(sock);
  if (200 != http_status)
     return -1;

  strLen = exoHAL_SocketRecv(sock, strBuf, RX_SIZE);

  exoHAL_SocketClose(sock);

  if(strLen <= 0)
    return -1;
     
  if(parse_datetime(strBuf, strLen, &datetime) < 0)
    return -1;

  sprintf(day, "%s/%02d/%s", datetime.dayStr, month_to_num(datetime.monStr), datetime.yearStr);
  sprintf(time, "%s:%s:%s", datetime.hourStr, datetime.minStr, datetime.secStr);

  if(AtLibGs_SetTime(day, time) != ATLIBGS_MSG_ID_OK)
    return -1;

  return 0;
}
Ejemplo n.º 5
0
int things_list(struct http_request *req) {
    int rc;
    char *zErrMsg = 0;
    char *query = "SELECT * FROM found ORDER BY last DESC";
    template_t tmpl;
	attrlist_t attributes;

    struct timespec when;

    buf = kore_buf_create(mb);

    if(!thing) thing = hashmap_new();

    // load template from assets
    template_load
        (asset_things_list_html, asset_len_things_list_html, &tmpl);

    // initialise attribute list
    attributes = attrinit();

    if( ! parse_datetime(&when, "now", NULL) )
        kore_log(LOG_ERR,"parse-datetime error");
    else {
        struct tm *tt;
        tt = localtime (&when.tv_sec);
        mktime(tt);
        strftime(line, ml, "Dowse :: %d %m %Y - %H:%M:%S", tt);
        attrcat(attributes, "title", line);
    }
    
    sqlquery(query, things_list_cb, attributes);

    template_apply(&tmpl, attributes, buf);

	http_response(req, 200, buf->data, buf->offset);

    template_free(&tmpl);
    attrfree(attributes);

    kore_buf_free(buf);


	return (KORE_RESULT_OK);
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
int
main (int argc _GL_UNUSED, char **argv)
{
  struct timespec result;
  struct timespec result2;
  struct timespec expected;
  struct timespec now;
  const char *p;
  int i;
  long gmtoff;

  set_program_name (argv[0]);

  gmtoff = gmt_offset ();


  /* ISO 8601 extended date and time of day representation,
     'T' separator, local time zone */
  p = "2011-05-01T11:55:18";
  expected.tv_sec = 1304250918 - gmtoff;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);

  /* ISO 8601 extended date and time of day representation,
     ' ' separator, local time zone */
  p = "2011-05-01 11:55:18";
  expected.tv_sec = 1304250918 - gmtoff;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);


  /* ISO 8601, extended date and time of day representation,
     'T' separator, UTC */
  p = "2011-05-01T11:55:18Z";
  expected.tv_sec = 1304250918;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);

  /* ISO 8601, extended date and time of day representation,
     ' ' separator, UTC */
  p = "2011-05-01 11:55:18Z";
  expected.tv_sec = 1304250918;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);


  /* ISO 8601 extended date and time of day representation,
     'T' separator, w/UTC offset */
  p = "2011-05-01T11:55:18-07:00";
  expected.tv_sec = 1304276118;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);

  /* ISO 8601 extended date and time of day representation,
     ' ' separator, w/UTC offset */
  p = "2011-05-01 11:55:18-07:00";
  expected.tv_sec = 1304276118;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);


  /* ISO 8601 extended date and time of day representation,
     'T' separator, w/hour only UTC offset */
  p = "2011-05-01T11:55:18-07";
  expected.tv_sec = 1304276118;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);

  /* ISO 8601 extended date and time of day representation,
     ' ' separator, w/hour only UTC offset */
  p = "2011-05-01 11:55:18-07";
  expected.tv_sec = 1304276118;
  expected.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, 0));
  LOG (p, expected, result);
  ASSERT (expected.tv_sec == result.tv_sec
          && expected.tv_nsec == result.tv_nsec);


  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "now";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  ASSERT (now.tv_sec == result.tv_sec && now.tv_nsec == result.tv_nsec);

  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "tomorrow";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  ASSERT (now.tv_sec + 24 * 60 * 60 == result.tv_sec
          && now.tv_nsec == result.tv_nsec);

  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "yesterday";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  ASSERT (now.tv_sec - 24 * 60 * 60 == result.tv_sec
          && now.tv_nsec == result.tv_nsec);

  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "4 hours";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  ASSERT (now.tv_sec + 4 * 60 * 60 == result.tv_sec
          && now.tv_nsec == result.tv_nsec);

  /* test if timezone is not being ignored for day offset */
  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+400 +24 hours";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC+400 +1 day";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);

  /* test if several time zones formats are handled same way */
  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+14:00";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC+14";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);
  p = "UTC+1400";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);

  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC-14:00";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC-14";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);
  p = "UTC-1400";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);

  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+0:15";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC+0015";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);

  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC-1:30";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC-130";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);


  /* TZ out of range should cause parse_datetime failure */
  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+25:00";
  ASSERT (!parse_datetime (&result, p, &now));

        /* Check for several invalid countable dayshifts */
  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+4:00 +40 yesterday";
  ASSERT (!parse_datetime (&result, p, &now));
  p = "UTC+4:00 next yesterday";
  ASSERT (!parse_datetime (&result, p, &now));
  p = "UTC+4:00 tomorrow ago";
  ASSERT (!parse_datetime (&result, p, &now));
  p = "UTC+4:00 tomorrow hence";
  ASSERT (!parse_datetime (&result, p, &now));
  p = "UTC+4:00 40 now ago";
  ASSERT (!parse_datetime (&result, p, &now));
  p = "UTC+4:00 last tomorrow";
  ASSERT (!parse_datetime (&result, p, &now));
  p = "UTC+4:00 -4 today";
  ASSERT (!parse_datetime (&result, p, &now));

  /* And check correct usage of dayshifts */
  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+400 tomorrow";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC+400 +1 day";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);
  p = "UTC+400 1 day hence";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);
  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+400 yesterday";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC+400 1 day ago";
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);
  now.tv_sec = 4711;
  now.tv_nsec = 1267;
  p = "UTC+400 now";
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  p = "UTC+400 +0 minutes"; /* silly, but simple "UTC+400" is different*/
  ASSERT (parse_datetime (&result2, p, &now));
  LOG (p, now, result2);
  ASSERT (result.tv_sec == result2.tv_sec
          && result.tv_nsec == result2.tv_nsec);

  /* Check that some "next Monday", "last Wednesday", etc. are correct.  */
  setenv ("TZ", "UTC0", 1);
  for (i = 0; day_table[i]; i++)
    {
      unsigned int thur2 = 7 * 24 * 3600; /* 2nd thursday */
      char tmp[32];
      sprintf (tmp, "NEXT %s", day_table[i]);
      now.tv_sec = thur2 + 4711;
      now.tv_nsec = 1267;
      ASSERT (parse_datetime (&result, tmp, &now));
      LOG (tmp, now, result);
      ASSERT (result.tv_nsec == 0);
      ASSERT (result.tv_sec == thur2 + (i == 4 ? 7 : (i + 3) % 7) * 24 * 3600);

      sprintf (tmp, "LAST %s", day_table[i]);
      now.tv_sec = thur2 + 4711;
      now.tv_nsec = 1267;
      ASSERT (parse_datetime (&result, tmp, &now));
      LOG (tmp, now, result);
      ASSERT (result.tv_nsec == 0);
      ASSERT (result.tv_sec == thur2 + ((i + 3) % 7 - 7) * 24 * 3600);
    }

  p = "THURSDAY UTC+00";  /* The epoch was on Thursday.  */
  now.tv_sec = 0;
  now.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  ASSERT (result.tv_sec == now.tv_sec
          && result.tv_nsec == now.tv_nsec);

  p = "FRIDAY UTC+00";
  now.tv_sec = 0;
  now.tv_nsec = 0;
  ASSERT (parse_datetime (&result, p, &now));
  LOG (p, now, result);
  ASSERT (result.tv_sec == 24 * 3600
          && result.tv_nsec == now.tv_nsec);

  return 0;
}
Ejemplo n.º 8
0
int
main (int argc, char **argv)
{
  List nflist;

  short file_flag = FALSE;
  short quit_flag = FALSE;
  int result;

  newts_failed_malloc_hook = curses_malloc_die;

  srand ((unsigned) time (NULL));

  time (&orig_seqtime);
  time (&seqtime);

#ifdef __GLIBC__
  program_name = program_invocation_short_name;
#else
  program_name = base_name (argv[0]);
#endif

  /* Initialize i18n. */

#ifdef HAVE_SETLOCALE
  if (setlocale (LC_ALL, "") == NULL)
    {
      fprintf (stderr, _("%s: could not determine your locale\nCheck the "
                         "environment variables LANG, LC_ALL, etc.\n"),
               program_name);

      exit (EXIT_FAILURE);
    }
#endif

#if ENABLE_NLS
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
#endif

  /* Initial setup and global variable init. */

  init_blacklist ();
  list_init (&nflist,
             (void * (*) (void)) nfref_alloc,
             (void (*) (void *)) nfref_free,
             NULL);

  setup ();

  while (1)
    {
      int opt;
      short override_flag = FALSE;

      static struct option long_options[] =
        {
          {"alternate",       required_argument, 0, 'a'},
          {"black-threads",   no_argument,       0, 'b'},
          {"debug",           no_argument,       0, 'D'},
          {"seq-own-notes",   no_argument,       0, 'e'},
          {"file",            required_argument, 0, 'f'},
          {"no-signature",    no_argument,       0, 'g'},
          {"index",           no_argument,       0, 'i'},
          {"skip-own-notes",  no_argument,       0, 'k'},
          {"modern",          no_argument,       0, 'm'},
          {"no-sequencer",    no_argument,       0, 'n'},
          {"time",            required_argument, 0, 'o'},
          {"sequencer",       no_argument,       0, 's'},
          {"traditional",     no_argument,       0, 't'},
          {"user",            required_argument, 0, 'u'},
          {"white-basenotes", no_argument,       0, 'w'},
          {"extended",        no_argument,       0, 'x'},
          {"imsa",            no_argument,       0, 'y'},
          {"no-blacklist",    no_argument,       0, 'z'},
          {"help",            no_argument,       0, 'h'},
          {"version",         no_argument,       0, 0},
          {0, 0, 0, 0}
        };

      opt = getopt_long (argc, argv, "a:bDef:ghikmno:stu:wxz",
                         long_options, NULL);

      if (opt == -1)
        break;

      switch (opt)
        {
        case 0:
          {
            char *version_string;

            asprintf (&version_string, _("revision: %s"), newts_revision);
            printf (N_("notes - %s %s (%s)\n"), PACKAGE_NAME, VERSION,
                    version_string);

            free (version_string);

            list_destroy (&nflist);
            teardown ();

            if (fclose (stdout) == EOF)
              error (EXIT_FAILURE, errno, _("error writing output"));

            exit (EXIT_SUCCESS);
          }

        case 'a':
          {
            alt_sequencer = TRUE;

            if (sequencer == NONE)
              sequencer = SEQUENCER;

            newts_nrealloc (seqname, strlen (username) + strlen (optarg) + 2,
                            sizeof (char));
            strcpy (seqname, username);
            strcat (seqname, ":");
            strcat (seqname, optarg);

            if (alt_seqname)
              newts_free (alt_seqname);
            alt_seqname = newts_strdup (optarg);

            break;
          }

        case 'b':
          black_skip_seq = TRUE;
          break;

        case 'D':
          debug = TRUE;
          break;

        case 'f':
          if (parse_file (optarg, &nflist))
            file_flag = TRUE;
          break;

        case 'g':
          signature = FALSE;
          break;

        case 'i':
          sequencer = INDEX;
          break;

        case 'k':
          seq_own_notes = FALSE;
          override_flag = TRUE;
          break;

        case 'm':
          seq_own_notes = TRUE;
          break;

        case 'n':
          sequencer = NONE;
          break;

        case 'o':
          {
            struct timespec parsed_time, now;
            now.tv_sec = orig_seqtime;

            if (parse_datetime (&parsed_time, optarg, &now))
              {
                if (alt_time)
                  {
                    fprintf (stderr, _("%s: cannot specify multiple alternate times\n"),
                             program_name);
                    fprintf (stderr, _("See 'info newts' for more information.\n"));

                    list_destroy (&nflist);
                    teardown ();

                    exit (EXIT_FAILURE);
                  }
                else if (parsed_time.tv_sec <= orig_seqtime)
                  {
                    orig_seqtime = seqtime = parsed_time.tv_sec;
                    if (sequencer == NONE)
                      sequencer = SEQUENCER;
                    alt_time = TRUE;
                  }
                else
                  {
                    fprintf (stderr, _("%s: parsed time '%s' in the future\n"),
                             program_name, optarg);
                    fprintf (stderr, _("See 'info newts' for more information.\n"));

                    list_destroy (&nflist);
                    teardown ();

                    exit (EXIT_FAILURE);
                  }
              }
            else
              {
                fprintf (stderr, _("%s: error parsing time '%s'\n"),
                         program_name, optarg);

                list_destroy (&nflist);
                teardown ();

                exit (EXIT_FAILURE);
              }

            break;
          }

        case 's':
          sequencer = SEQUENCER;
          break;

        case 't':
        case 'y':   /* Pseudo-option for --imsa */
          traditional = TRUE;
          if (!override_flag)
            seq_own_notes = TRUE;
          break;

        case 'u':
          {
            struct passwd *pw;

            if (getuid () != 0)
              {
                fprintf (stderr, _("%s: only root is allowed to use '--user'\n"),
                         program_name);

                list_destroy (&nflist);
                teardown ();

                exit (EXIT_FAILURE);
              }

            pw = getpwnam (optarg);
            if (pw)
              {
                seteuid (pw->pw_uid);

                newts_free (username);
                username = newts_strdup (pw->pw_name);

                if (alt_sequencer)
                  {
                    newts_nrealloc (seqname,
                                    strlen (username) + strlen (alt_seqname) + 2,
                                    sizeof (char));
                    strcpy (seqname, username);
                    strcat (seqname, ":");
                    strcat (seqname, alt_seqname);
                  }
                else
                  {
                    newts_free (seqname);
                    seqname = newts_strdup (username);
                  }
              }

            else
              {
                fprintf (stderr, _("%s: no such user: '******'\n"), program_name,
                         optarg);

                list_destroy (&nflist);
                teardown ();

                exit (EXIT_FAILURE);
              }
          }
          break;

        case 'w':
          white_basenotes = TRUE;
          break;

        case 'x':
          sequencer = EXTENDED;
          break;

        case 'z':
          no_blacklist = TRUE;
          break;

        case 'h':
          printf (_("Usage: %s [OPTION]... NOTESFILE...\n"
                    "Run the UIUC-compatible notesfile client.\n\n"),
                  program_name);

          printf (_("If an argument to a long option is mandatory, it is also mandatory "
                    "for the\ncorresponding short option.\n\n"));

          printf (_("General options:\n"
                    "  -f, --file=FILE         Read list of notesfiles to view from specified file\n"
                    "  -g, --no-signature      Turn off automatic signature inclusion\n"
                    "  -h, --help              Display this help and exit\n"
                    "  -u, --user=USER         As root, run notes as the specified user\n"
                    "      --debug             Print debugging messages to stderr\n"
                    "      --version           Display version information and exit\n\n"));

          printf (_("Display options:\n"
                    "  -m, --modern            Use modern, consistent display style (default)\n"
                    "  -t, --traditional       Use traditional UIUC-style display\n"
                    "      --imsa              Use IMSA-style display (same as -t)\n\n"));

          printf (_("Blacklist options:\n"
                    "  -b, --black-threads     Skip threads with blacklisted basenotes while seqing\n"
                    "  -w, --white-basenotes   Do not apply blacklist to basenotes\n"
                    "  -z, --no-blacklist      Do not use the blacklist\n\n"));

          printf (_("Sequencer options:\n"
                    "  -a, --alternate=SEQ     Use alternate sequencer SEQ\n"
                    "  -e, --seq-own-notes     Make the sequencer view your notes\n"
                    "  -i, --index             Use the index sequencer\n"
                    "  -k, --skip-own-notes    Make the sequencer ignore your notes (default)\n"
                    "  -n, --no-sequencer      Do not use the sequencer (default)\n"
                    "  -o, --time=TIME         Use this date and time for the sequencer\n"
                    "  -s, --sequencer         Use the sequencer to read notes\n"
                    "  -x, --extended          Use the extended sequencer\n\n"));

          printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);

          list_destroy (&nflist);
          teardown ();

          if (fclose (stdout) == EOF)
            error (EXIT_FAILURE, errno, _("error writing output"));

          exit (EXIT_SUCCESS);

        case '?':
          fprintf (stderr, _("Try '%s --help' for more information.\n"),
                   program_name);

          list_destroy (&nflist);
          teardown ();

          exit (EXIT_FAILURE);
        }
    }

  if (optind == argc && !file_flag)
    {
      if (sequencer == NONE)
        {
          struct stat statbuf;

          fprintf (stderr, _("%s: too few arguments\n"), program_name);
          fprintf (stderr, _("Try '%s --help' for more information.\n"),
                   program_name);

          /* FIXME: should be a call to the notes system. */

          if (stat ("/etc/avail.notes", &statbuf) == 0)
            {
              fprintf (stderr,
                       _("Hit <RET> for a list of notesfiles on this system.\n"));
              getchar ();

              spawn_process (NULL, pager, "/etc/avail.notes", NULL);
            }

          list_destroy (&nflist);
          teardown ();

          exit (EXIT_FAILURE);
        }
      else
        {
          char *copy, *list, *token, *nfseq;

          nfseq = getenv ("NFSEQ");
          if (nfseq == NULL)
            {
              fprintf (stderr, _("%s: NFSEQ environment variable not set\n"),
                       program_name);
              fprintf (stderr, _("See 'info newts' for more information.\n"));

              list_destroy (&nflist);
              teardown ();

              exit (EXIT_FAILURE);
            }

          copy = newts_strdup (nfseq);

          token = strtok_r (copy, ", ", &list);
          while (token != NULL)
            {
              parse_nf (token, &nflist);
              token = strtok_r (NULL, ", ", &list);
            }

          newts_free (copy);
        }
    }
  else
    {
      while (optind < argc)
        parse_nf (argv[optind++], &nflist);
    }

  handle_signals ();

  /* For each notesfile, start up the master routine and go. */

  {
    ListNode *node = list_head (&nflist);

    while (node && !quit_flag)
      {
        newts_nfref *ref = (newts_nfref *) list_data (node);

        result = master (ref);

        node = list_next (node);

        if (result == QUITSEQ || result == QUITNOSEQ)
          quit_flag = TRUE;
      }
  }

  ignore_signals ();
  exit_curses ();

  if (*messages != '\0')
    printf ("%s", messages);

  teardown ();

  if (fclose (stdout) == EOF)
    error (EXIT_FAILURE, errno, _("error writing output"));

  exit (EXIT_SUCCESS);
}
Ejemplo n.º 9
0
static gboolean
prune_commits_keep_younger_than_date (OstreeRepo *repo, const char *date, GCancellable *cancellable, GError **error)
{
  g_autoptr(GHashTable) refs = NULL;
  g_autoptr(GHashTable) ref_heads = g_hash_table_new (g_str_hash, g_str_equal);
  g_autoptr(GHashTable) objects = NULL;
  GHashTableIter hash_iter;
  gpointer key, value;
  struct timespec ts;
  gboolean ret = FALSE;

  if (!parse_datetime (&ts, date, NULL))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Could not parse '%s'", date);
      goto out;
    }

  if (!ot_enable_tombstone_commits (repo, error))
    goto out;

  if (!ostree_repo_list_refs (repo, NULL, &refs, cancellable, error))
    goto out;

  /* We used to prune the HEAD of a given ref by default, but that's
   * broken for a few reasons.  One is that people may use branches as
   * tags.  Second is that if we do it, we should be deleting the ref
   * too, otherwise e.g. `summary -u` breaks trying to load it, etc.
   */
  g_hash_table_iter_init (&hash_iter, refs);
  while (g_hash_table_iter_next (&hash_iter, &key, &value))
    {
      /* Value is lifecycle bound to refs */
      g_hash_table_add (ref_heads, (char*)value);
    }

  if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL, &objects,
                                 cancellable, error))
    goto out;

  g_hash_table_iter_init (&hash_iter, objects);

  while (g_hash_table_iter_next (&hash_iter, &key, &value))
    {
      GVariant *serialized_key = key;
      const char *checksum;
      OstreeObjectType objtype;
      guint64 commit_timestamp;
      g_autoptr(GVariant) commit = NULL;

      ostree_object_name_deserialize (serialized_key, &checksum, &objtype);

      if (objtype != OSTREE_OBJECT_TYPE_COMMIT)
        continue;

      if (g_hash_table_contains (ref_heads, checksum))
        continue;

      if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum,
                                     &commit, error))
        goto out;

      commit_timestamp = ostree_commit_get_timestamp (commit);
      if (commit_timestamp < ts.tv_sec)
        {
          if (opt_static_deltas_only)
            {
              if(!ostree_repo_prune_static_deltas (repo, checksum, cancellable, error))
                goto out;
            }
          else
            {
              if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, cancellable, error))
                goto out;
            }
        }
    }

  ret = TRUE;

 out:
  return ret;
}
gboolean
flatpak_builtin_build_commit_from (int argc, char **argv, GCancellable *cancellable, GError **error)
{
  g_autoptr(GOptionContext) context = NULL;
  g_autoptr(GFile) dst_repofile = NULL;
  g_autoptr(OstreeRepo) dst_repo = NULL;
  g_autoptr(GFile) src_repofile = NULL;
  g_autoptr(OstreeRepo) src_repo = NULL;
  g_autofree char *src_repo_uri = NULL;
  const char *dst_repo_arg;
  const char **dst_refs;
  int n_dst_refs = 0;
  g_autoptr(FlatpakRepoTransaction) transaction = NULL;
  g_autoptr(GPtrArray) src_refs = NULL;
  g_autoptr(GPtrArray) resolved_src_refs = NULL;
  OstreeRepoCommitState src_commit_state;
  struct timespec ts;
  guint64 timestamp;
  int i;

  context = g_option_context_new (_("DST-REPO [DST-REF…] - Make a new commit from existing commits"));
  g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);

  if (!flatpak_option_context_parse (context, options, &argc, &argv, FLATPAK_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
    return FALSE;

  if (argc < 2)
    return usage_error (context, _("DST-REPO must be specified"), error);

  dst_repo_arg = argv[1];

  dst_refs = (const char **) argv + 2;
  n_dst_refs = argc - 2;

  if (opt_src_repo == NULL && n_dst_refs != 1)
    return usage_error (context, _("If --src-repo is not specified, exactly one destination ref must be specified"), error);

  if (opt_src_ref != NULL && n_dst_refs != 1)
    return usage_error (context, _("If --src-ref is specified, exactly one destination ref must be specified"), error);

  if (opt_src_repo == NULL && opt_src_ref == NULL)
    return flatpak_fail (error, _("Either --src-repo or --src-ref must be specified."));

  /* Always create a commit if we're eol:ing, even though the app is the same */
  if (opt_endoflife != NULL || opt_endoflife_rebase != NULL)
    opt_force = TRUE;

  if (opt_endoflife_rebase)
    {
      opt_endoflife_rebase_new = g_new0 (char *, g_strv_length (opt_endoflife_rebase));

      for (i = 0; opt_endoflife_rebase[i] != NULL; i++)
        {
          char *rebase_old = opt_endoflife_rebase[i];
          char *rebase_new = strchr (rebase_old, '=');

          if (rebase_new == NULL) {
            return usage_error (context, _("Invalid argument format of use  --end-of-life-rebase=OLDID=NEWID"), error);
          }
          *rebase_new = 0;
          rebase_new++;

          if (!flatpak_is_valid_name (rebase_old, error))
            return glnx_prefix_error (error, _("Invalid name %s in --end-of-life-rebase"), rebase_old);

          if (!flatpak_is_valid_name (rebase_new, error))
            return glnx_prefix_error (error, _("Invalid name %s in --end-of-life-rebase"), rebase_new);

          opt_endoflife_rebase_new[i] = rebase_new;
        }
    }

  if (opt_timestamp)
    {
      if (!parse_datetime (&ts, opt_timestamp, NULL))
        return flatpak_fail (error, _("Could not parse '%s'"), opt_timestamp);
    }

  dst_repofile = g_file_new_for_commandline_arg (dst_repo_arg);
  if (!g_file_query_exists (dst_repofile, cancellable))
    return flatpak_fail (error, _("'%s' is not a valid repository"), dst_repo_arg);

  dst_repo = ostree_repo_new (dst_repofile);
  if (!ostree_repo_open (dst_repo, cancellable, error))
    return FALSE;

  if (opt_disable_fsync)
    ostree_repo_set_disable_fsync (dst_repo, TRUE);

  if (opt_src_repo)
    {
      src_repofile = g_file_new_for_commandline_arg (opt_src_repo);
      if (!g_file_query_exists (src_repofile, cancellable))
        return flatpak_fail (error, _("'%s' is not a valid repository"), opt_src_repo);

      src_repo_uri = g_file_get_uri (src_repofile);
      src_repo = ostree_repo_new (src_repofile);
      if (!ostree_repo_open (src_repo, cancellable, error))
        return FALSE;
    }
  else
    {
      src_repo = g_object_ref (dst_repo);
    }

  src_refs = g_ptr_array_new_with_free_func (g_free);
  if (opt_src_ref)
    {
      g_assert (n_dst_refs == 1);
      g_ptr_array_add (src_refs, g_strdup (opt_src_ref));
    }
  else
    {
      g_assert (opt_src_repo != NULL);
      if (n_dst_refs == 0)
        {
          g_autofree const char **keys = NULL;
          g_autoptr(GHashTable) all_src_refs = NULL;

          if (!ostree_repo_list_refs (src_repo, NULL, &all_src_refs,
                                      cancellable, error))
            return FALSE;

          keys = (const char **) g_hash_table_get_keys_as_array (all_src_refs, NULL);

          for (i = 0; keys[i] != NULL; i++)
            {
              if (g_str_has_prefix (keys[i], "runtime/") ||
                  g_str_has_prefix (keys[i], "app/"))
                g_ptr_array_add (src_refs, g_strdup (keys[i]));
            }
          n_dst_refs = src_refs->len;
          dst_refs = (const char **) src_refs->pdata;
        }
      else
        {
          for (i = 0; i < n_dst_refs; i++)
            g_ptr_array_add (src_refs, g_strdup (dst_refs[i]));
        }
    }

  resolved_src_refs = g_ptr_array_new_with_free_func (g_free);
  for (i = 0; i < src_refs->len; i++)
    {
      const char *src_ref = g_ptr_array_index (src_refs, i);
      char *resolved_ref;

      if (!ostree_repo_resolve_rev (src_repo, src_ref, FALSE, &resolved_ref, error))
        return FALSE;

      g_ptr_array_add (resolved_src_refs, resolved_ref);
    }

  if (src_repo_uri != NULL)
    {
      OstreeRepoPullFlags pullflags = 0;
      GVariantBuilder builder;
      g_autoptr(OstreeAsyncProgress) progress = NULL;
      g_auto(GLnxConsoleRef) console = { 0, };
      g_autoptr(GVariant) options = NULL;
      gboolean res;

      if (opt_untrusted)
        pullflags |= OSTREE_REPO_PULL_FLAGS_UNTRUSTED;

      glnx_console_lock (&console);
      if (console.is_tty)
        progress = ostree_async_progress_new_and_connect (ostree_repo_pull_default_console_progress_changed, &console);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
      g_variant_builder_add (&builder, "{s@v}", "flags",
                             g_variant_new_variant (g_variant_new_int32 (pullflags)));
      g_variant_builder_add (&builder, "{s@v}", "refs",
                             g_variant_new_variant (g_variant_new_strv ((const char * const *) resolved_src_refs->pdata,
                                                                        resolved_src_refs->len)));
      g_variant_builder_add (&builder, "{s@v}", "depth",
                             g_variant_new_variant (g_variant_new_int32 (0)));

      options = g_variant_ref_sink (g_variant_builder_end (&builder));
      res = ostree_repo_pull_with_options (dst_repo, src_repo_uri,
                                           options,
                                           progress,
                                           cancellable, error);

      if (progress)
        ostree_async_progress_finish (progress);

      if (!res)
        return FALSE;
    }

  /* By now we have the commit with commit_id==resolved_ref and dependencies in dst_repo. We now create a new
   * commit based on the toplevel tree ref from that commit.
   * This is equivalent to:
   *   ostree commit --skip-if-unchanged --repo=${destrepo} --tree=ref=${resolved_ref}
   */

  transaction = flatpak_repo_transaction_start (dst_repo, cancellable, error);
  if (transaction == NULL)
    return FALSE;

  for (i = 0; i < resolved_src_refs->len; i++)
    {
      const char *dst_ref = dst_refs[i];
      const char *resolved_ref = g_ptr_array_index (resolved_src_refs, i);
      g_autofree char *dst_parent = NULL;
      g_autoptr(GFile) dst_parent_root = NULL;
      g_autoptr(GFile) src_ref_root = NULL;
      g_autoptr(GVariant) src_commitv = NULL;
      g_autoptr(GVariant) dst_commitv = NULL;
      g_autoptr(OstreeMutableTree) mtree = NULL;
      g_autoptr(GFile) dst_root = NULL;
      g_autoptr(GVariant) commitv_metadata = NULL;
      g_autoptr(GVariant) metadata = NULL;
      const char *subject;
      const char *body;
      g_autofree char *commit_checksum = NULL;
      GVariantBuilder metadata_builder;
      gint j;
      const char *dst_collection_id = NULL;
      const char *main_collection_id = NULL;
      g_autoptr(GPtrArray) collection_ids = NULL;

      if (!ostree_repo_resolve_rev (dst_repo, dst_ref, TRUE, &dst_parent, error))
        return FALSE;

      if (dst_parent != NULL &&
          !ostree_repo_read_commit (dst_repo, dst_parent, &dst_parent_root, NULL, cancellable, error))
        return FALSE;

      if (!ostree_repo_read_commit (dst_repo, resolved_ref, &src_ref_root, NULL, cancellable, error))
        return FALSE;

      if (!ostree_repo_load_commit (dst_repo, resolved_ref, &src_commitv, &src_commit_state, error))
        return FALSE;

      if (src_commit_state & OSTREE_REPO_COMMIT_STATE_PARTIAL)
        return flatpak_fail (error, _("Can't commit from partial source commit."));

      /* Don't create a new commit if this is the same tree */
      if (!opt_force && dst_parent_root != NULL && g_file_equal (dst_parent_root, src_ref_root))
        {
          g_print (_("%s: no change\n"), dst_ref);
          continue;
        }

      mtree = ostree_mutable_tree_new ();
      if (!ostree_repo_write_directory_to_mtree (dst_repo, src_ref_root, mtree, NULL,
                                                 cancellable, error))
        return FALSE;

      if (!ostree_repo_write_mtree (dst_repo, mtree, &dst_root, cancellable, error))
        return FALSE;

      commitv_metadata = g_variant_get_child_value (src_commitv, 0);

      g_variant_get_child (src_commitv, 3, "&s", &subject);
      if (opt_subject)
        subject = (const char *) opt_subject;
      g_variant_get_child (src_commitv, 4, "&s", &body);
      if (opt_body)
        body = (const char *) opt_body;

      dst_collection_id = ostree_repo_get_collection_id (dst_repo);

      collection_ids = g_ptr_array_new_with_free_func (g_free);
      if (dst_collection_id)
        {
          main_collection_id = dst_collection_id;
          g_ptr_array_add (collection_ids, g_strdup (dst_collection_id));
        }

      if (opt_extra_collection_ids != NULL)
        {
          for (j = 0; opt_extra_collection_ids[j] != NULL; j++)
            {
              const char *cid = opt_extra_collection_ids[j];
              if (main_collection_id == NULL)
                main_collection_id = cid; /* Fall back to first arg */

              if (g_strcmp0 (cid, dst_collection_id) != 0)
                g_ptr_array_add (collection_ids, g_strdup (cid));
            }
        }

      g_ptr_array_sort (collection_ids, (GCompareFunc) flatpak_strcmp0_ptr);

      /* Copy old metadata */
      g_variant_builder_init (&metadata_builder, G_VARIANT_TYPE ("a{sv}"));

      /* Bindings. xa.ref is deprecated but added anyway for backwards compatibility. */
      g_variant_builder_add (&metadata_builder, "{sv}", "ostree.collection-binding",
                             g_variant_new_string (main_collection_id ? main_collection_id : ""));
      if (collection_ids->len > 0)
        {
          g_autoptr(GVariantBuilder) cr_builder = g_variant_builder_new (G_VARIANT_TYPE ("a(ss)"));

          for (j = 0; j < collection_ids->len; j++)
            g_variant_builder_add (cr_builder, "(ss)", g_ptr_array_index (collection_ids, j), dst_ref);

          g_variant_builder_add (&metadata_builder, "{sv}", "ostree.collection-refs-binding",
                                 g_variant_builder_end (cr_builder));
        }
      g_variant_builder_add (&metadata_builder, "{sv}", "ostree.ref-binding",
                             g_variant_new_strv (&dst_ref, 1));
      g_variant_builder_add (&metadata_builder, "{sv}", "xa.ref", g_variant_new_string (dst_ref));

      /* Record the source commit. This is nice to have, but it also
         means the commit-from gets a different commit id, which
         avoids problems with e.g.  sharing .commitmeta files
         (signatures) */
      g_variant_builder_add (&metadata_builder, "{sv}", "xa.from_commit", g_variant_new_string (resolved_ref));

      for (j = 0; j < g_variant_n_children (commitv_metadata); j++)
        {
          g_autoptr(GVariant) child = g_variant_get_child_value (commitv_metadata, j);
          g_autoptr(GVariant) keyv = g_variant_get_child_value (child, 0);
          const char *key = g_variant_get_string (keyv, NULL);

          if (strcmp (key, "xa.ref") == 0 ||
              strcmp (key, "xa.from_commit") == 0 ||
              strcmp (key, "ostree.collection-binding") == 0 ||
              strcmp (key, "ostree.collection-refs-binding") == 0 ||
              strcmp (key, "ostree.ref-binding") == 0)
            continue;

          if (opt_endoflife &&
              strcmp (key, OSTREE_COMMIT_META_KEY_ENDOFLIFE) == 0)
            continue;

          if (opt_endoflife_rebase &&
              strcmp (key, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE) == 0)
            continue;

          g_variant_builder_add_value (&metadata_builder, child);
        }

      if (opt_endoflife && *opt_endoflife)
        g_variant_builder_add (&metadata_builder, "{sv}", OSTREE_COMMIT_META_KEY_ENDOFLIFE,
                               g_variant_new_string (opt_endoflife));

      if (opt_endoflife_rebase)
        {
          g_auto(GStrv) dst_ref_parts = g_strsplit (dst_ref, "/", 0);

          for (j = 0; opt_endoflife_rebase[j] != NULL; j++)
            {
              const char *old_prefix = opt_endoflife_rebase[j];

              if (flatpak_has_name_prefix (dst_ref_parts[1], old_prefix))
                {
                  g_autofree char *new_id = g_strconcat (opt_endoflife_rebase_new[j], dst_ref_parts[1] + strlen(old_prefix), NULL);
                  g_autofree char *rebased_ref = g_build_filename (dst_ref_parts[0], new_id, dst_ref_parts[2], dst_ref_parts[3], NULL);

                  g_variant_builder_add (&metadata_builder, "{sv}", OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE,
                                         g_variant_new_string (rebased_ref));
                  break;
                }
            }
        }

      timestamp = ostree_commit_get_timestamp (src_commitv);
      if (opt_timestamp)
        timestamp = ts.tv_sec;

      metadata = g_variant_ref_sink (g_variant_builder_end (&metadata_builder));
      if (!ostree_repo_write_commit_with_time (dst_repo, dst_parent, subject, body, metadata,
                                               OSTREE_REPO_FILE (dst_root),
                                               timestamp,
                                               &commit_checksum, cancellable, error))
        return FALSE;

      g_print ("%s: %s\n", dst_ref, commit_checksum);

      if (!ostree_repo_load_commit (dst_repo, commit_checksum, &dst_commitv, NULL, error))
        return FALSE;

      /* This doesn't copy the detached metadata. I'm not sure if this is a problem.
       * The main thing there is commit signatures, and we can't copy those, as the commit hash changes.
       */

      if (opt_gpg_key_ids)
        {
          char **iter;

          for (iter = opt_gpg_key_ids; iter && *iter; iter++)
            {
              const char *keyid = *iter;
              g_autoptr(GError) my_error = NULL;

              if (!ostree_repo_sign_commit (dst_repo,
                                            commit_checksum,
                                            keyid,
                                            opt_gpg_homedir,
                                            cancellable,
                                            &my_error) &&
                  !g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
                {
                  g_propagate_error (error, g_steal_pointer (&my_error));
                  return FALSE;
                }
            }
        }

      if (dst_collection_id != NULL)
        {
          OstreeCollectionRef ref = { (char *) dst_collection_id, (char *) dst_ref };
          ostree_repo_transaction_set_collection_ref (dst_repo, &ref, commit_checksum);
        }
      else
        {
          ostree_repo_transaction_set_ref (dst_repo, NULL, dst_ref, commit_checksum);
        }

      if (opt_extra_collection_ids)
        {
          for (j = 0; opt_extra_collection_ids[j] != NULL; j++)
            {
              OstreeCollectionRef ref = { (char *) opt_extra_collection_ids[j], (char *) dst_ref };
              ostree_repo_transaction_set_collection_ref (dst_repo, &ref, commit_checksum);
            }
        }

      /* Copy + Rewrite any deltas */
      {
        const char *from[2];
        gsize j, n_from = 0;

        if (dst_parent != NULL)
          from[n_from++] = dst_parent;
        from[n_from++] = NULL;

        for (j = 0; j < n_from; j++)
          {
            g_autoptr(GError) local_error = NULL;
            if (!rewrite_delta (src_repo, resolved_ref, dst_repo, commit_checksum, dst_commitv, from[j], &local_error))
              g_debug ("Failed to copy delta: %s", local_error->message);
          }
      }
    }

  if (!ostree_repo_commit_transaction (dst_repo, NULL, cancellable, error))
    return FALSE;

  if (opt_update_appstream &&
      !flatpak_repo_generate_appstream (dst_repo, (const char **) opt_gpg_key_ids, opt_gpg_homedir, 0, cancellable, error))
    return FALSE;

  if (!opt_no_update_summary &&
      !flatpak_repo_update (dst_repo,
                            (const char **) opt_gpg_key_ids,
                            opt_gpg_homedir,
                            cancellable,
                            error))
    return FALSE;

  return TRUE;
}
Ejemplo n.º 11
0
bool hp98035_io_card::parse_unit_command(const uint8_t*& p, unsigned unit_no)
{
	unit_no--;
	timer_unit_t& unit = m_units[ unit_no ];
	bool get_out = false;
	unsigned msec;
	uint8_t to_match[ 5 ];
	std::ostringstream out;

	LOG(("U %c %u %p\n" , *p , unit_no , &unit));

	switch (*p++) {
	case '=':
		// Assign unit
		if (*p == 'I') {
			p++;
			get_out = assign_unit(unit , p , true);
		} else if (*p == 'O') {
			p++;
			get_out = assign_unit(unit , p , false);
		}
		break;

	case 'C':
		// Clear input unit
		if (unit.m_input && unit.m_port) {
			unit.m_value = 0;
		} else {
			set_error(ERR_MASK_WRONG_UNIT);
		}
		break;

	case 'D':
		// Set delay on output unit
		if (parse_msec(p , msec)) {
			if (!unit.m_input && unit.m_port) {
				if (unit.m_state == UNIT_IDLE) {
					unit.m_delay = msec;
				} else {
					set_error(ERR_MASK_CANT_EXEC);
				}
			} else {
				set_error(ERR_MASK_WRONG_UNIT);
			}
		} else {
			set_error(ERR_MASK_WRONG_INS);
		}
		get_out = true;
		break;

	case 'G':
		// Activate unit
		if (unit.m_port && unit.m_state == UNIT_IDLE) {
			unit.adv_state(true);

			LOG(("act %p %d %d %u %02u:%02u:%02u:%02u %u %u %u\n" , &unit , unit.m_state , unit.m_input , unit.m_port , unit.m_match_datetime[ 0 ] , unit.m_match_datetime[ 1 ] , unit.m_match_datetime[ 2 ] , unit.m_match_datetime[ 3 ] , unit.m_delay , unit.m_period , unit.m_value));
		} else {
			set_error(ERR_MASK_WRONG_UNIT);
		}
		break;

	case 'H':
		// Halt unit
		if (unit.m_port) {
			unit.deactivate();
		} else {
			set_error(ERR_MASK_WRONG_UNIT);
		}
		break;

	case 'M':
		// Set date/time to match on output unit
		if (!unit.m_input && unit.m_port) {
			if (unit.m_state == UNIT_IDLE) {
				if (*p == '\0') {
					unit.m_match_datetime[ 0 ] = EMPTY_FIELD;
					unit.m_match_datetime[ 1 ] = EMPTY_FIELD;
					unit.m_match_datetime[ 2 ] = EMPTY_FIELD;
					unit.m_match_datetime[ 3 ] = EMPTY_FIELD;
				} else if (parse_datetime(p , to_match) && *p == '\0') {
					unit.m_match_datetime[ 0 ] = to_match[ 1 ];
					unit.m_match_datetime[ 1 ] = to_match[ 2 ];
					unit.m_match_datetime[ 2 ] = to_match[ 3 ];
					unit.m_match_datetime[ 3 ] = to_match[ 4 ];
				} else {
					set_error(ERR_MASK_WRONG_INS);
				}
			} else {
				set_error(ERR_MASK_CANT_EXEC);
			}
		} else {
			set_error(ERR_MASK_WRONG_UNIT);
		}
		get_out = true;
		break;

	case 'P':
		// Set period on output unit
		if (parse_msec(p , msec)) {
			if (!unit.m_input && unit.m_port) {
				if (unit.m_state == UNIT_IDLE) {
					unit.m_period = msec;
				} else {
					set_error(ERR_MASK_CANT_EXEC);
				}
			} else {
				set_error(ERR_MASK_WRONG_UNIT);
			}
		} else {
			set_error(ERR_MASK_WRONG_INS);
		}
		get_out = true;
		break;

	case 'V':
		// Get value of input unit
		if (unit.m_input && unit.m_port) {
			util::stream_format(out , "%010u" , unit.m_value);
			set_obuffer(out.str().c_str());
		} else {
			set_error(ERR_MASK_WRONG_UNIT);
		}
		break;
	}

	return get_out;
}
Ejemplo n.º 12
0
void hp98035_io_card::process_ibuffer(void)
{
	m_ibuffer[ m_ibuffer_ptr ] = '\0';
	const uint8_t *p = &m_ibuffer[ 0 ];

	clear_obuffer();

	bool get_out = false;

	while (*p != '\0' && !get_out) {
		std::ostringstream out;
		uint8_t datetime[ 5 ];
		unsigned unit_no;

		switch (*p++) {
		case 'A':
			// Halt all timer units
			for (timer_unit_t& unit : m_units) {
				unit.deactivate();
			}
			m_inten = false;
			m_intflag = false;
			update_irq();
			break;

		case 'B':
			// Warm reset
			half_init();
			get_out = true;
			break;

		case 'E':
			// Read and clear errors
			set_obuffer(m_error);
			m_error = 0;
			break;

		case 'F':
			// Activate all timer units
			for (timer_unit_t& unit : m_units) {
				if (unit.m_port) {
					unit.adv_state(true);
				}
			}
			break;

		case 'R':
			// Read time
			// Assume US format of dates
			util::stream_format(out , "%02u:%02u:%02u:%02u:%02u" , m_mon , m_dom , m_hrs , m_min , m_sec);
			set_obuffer(out.str().c_str());
			break;

		case 'S':
			// Set time
			if (parse_datetime(p , datetime)) {
				// Cannot set time when there's one or more active output units
				if (std::any_of(std::begin(m_units) , std::end(m_units) , [](const timer_unit_t& u) { return u.m_state != UNIT_IDLE && !u.m_input; })) {
					set_error(ERR_MASK_CANT_EXEC);
				} else {
					m_msec = 0;
					m_sec = datetime[ 4 ];
					if (datetime[ 3 ] != EMPTY_FIELD) {
						m_min = datetime[ 3 ];
						if (datetime[ 2 ] != EMPTY_FIELD) {
							m_hrs = datetime[ 2 ];
							if (datetime[ 1 ] != EMPTY_FIELD) {
								m_dom = datetime[ 1 ];
								if (datetime[ 0 ] != EMPTY_FIELD) {
									m_mon = datetime[ 0 ];
								}
							}
						}
					}
				}
			} else {
				set_error(ERR_MASK_WRONG_INS);
				get_out = true;
			}
			break;

		case 'T':
			// Read triggered outputs
			set_obuffer(m_triggered);
			m_triggered = 0;
			break;

		case 'U':
			// Control timer units
			if (parse_unit_no(p , unit_no)) {
				get_out = parse_unit_command(p , unit_no);
			} else {
				set_error(ERR_MASK_WRONG_INS);
				get_out = true;
			}
			break;

		case 'W':
			// Read unserviced interrupts
			set_obuffer(m_lost_irq);
			m_lost_irq = 0;
			break;

		default:
			set_error(ERR_MASK_WRONG_INS);
			get_out = true;
			break;
		}
	}

	m_ibuffer_ptr = 0;
}
Ejemplo n.º 13
0
/* remove header; add '*'s; replace "Revision REV" with "rREV" */
static
char *prepare_pld_changelog(tn_alloc *na, const char *changelog)
{
    struct changelog_ent  *ent = NULL;
    char                  *entmark = "Revision", *prepared_log;
    int                   i, started, max_MESSAGE = 1024, len;
    tn_array              *entries, *lines;
    tn_buf                *logmsg;

    lines = n_str_etokl_ext(changelog, "\n", "", "", '\\');


    len = strlen(entmark);
    entries = n_array_new(8, NULL, (tn_fn_cmp)changelog_ent_cmp);
    logmsg = n_buf_new(1024);
    started = 0;
    
    for (i = 0; i < n_array_size(lines); i++) {
        char *line = n_array_nth(lines, i);
        
        if (strncmp(line, entmark, len) == 0)
             started = 1;
        
        if (!started)
            continue;
        
        if (strncmp(line, entmark, len) == 0) {
            char *tstr, *rev, info[80];
            time_t ts;
            int n;
            
            if (ent != NULL) {
                n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg));
                n_buf_clean(logmsg);
                n_array_push(entries, ent);
                ent = NULL;
            }

            //Revision REV YYYY-MM-DD HH:MM:SS rest
            rev = line + len + 1;       /* skip Revision */
            while (*rev && isspace(*rev))
                rev++;
            
            tstr = strchr(rev, ' ');
            if (tstr) {
                *tstr = '\0';
                tstr++;
                while (*tstr && isspace(*tstr))
                    tstr++;
            }
            
            if (rev && tstr) {
                ts = parse_datetime(tstr);
                if (ts == 0)
                    continue;
            }

            n = n_snprintf(info, sizeof(info), "* r%s %s", rev, tstr);
            
            ent = n_malloc(sizeof(*ent) + max_MESSAGE);
            memset(ent, 0, sizeof(*ent));
            ent->info = n_strdupl(info, n);
            ent->message[0] = '\0';
            continue;
        }
        
        if (ent)
            n_buf_printf(logmsg, "%s\n", line);
    } 
    
    if (ent != NULL) {
        n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg));
        n_array_push(entries, ent);
    }
    
    n_array_free(lines);
    n_buf_clean(logmsg);

    /* shift && free entries cause ents are simply malloc()ed here */
    while (n_array_size(entries)) {
        ent = n_array_shift(entries);
        n_buf_printf(logmsg, "%s\n", ent->info);
        n_buf_printf(logmsg, "%s\n", ent->message);
    }
    n_array_free(entries);

    prepared_log = na_strdup(na, n_buf_ptr(logmsg), n_buf_size(logmsg));
    n_buf_free(logmsg);

    return prepared_log;
}
Ejemplo n.º 14
0
static gboolean
prune_commits_keep_younger_than_date (OstreeRepo *repo, const char *date, GCancellable *cancellable, GError **error)
{
  g_autoptr(GHashTable) objects = NULL;
  GHashTableIter hash_iter;
  gpointer key, value;
  struct timespec ts;
  gboolean ret = FALSE;

  if (!parse_datetime (&ts, date, NULL))
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Could not parse '%s'", date);
      goto out;
    }

  if (!ot_enable_tombstone_commits (repo, error))
    goto out;

  if (!ostree_repo_list_objects (repo, OSTREE_REPO_LIST_OBJECTS_ALL, &objects,
                                 cancellable, error))
    goto out;

  g_hash_table_iter_init (&hash_iter, objects);

  while (g_hash_table_iter_next (&hash_iter, &key, &value))
    {
      GVariant *serialized_key = key;
      const char *checksum;
      OstreeObjectType objtype;
      guint64 commit_timestamp;
      g_autoptr(GVariant) commit = NULL;

      ostree_object_name_deserialize (serialized_key, &checksum, &objtype);

      if (objtype != OSTREE_OBJECT_TYPE_COMMIT)
        continue;

      if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum,
                                     &commit, error))
        goto out;

      commit_timestamp = ostree_commit_get_timestamp (commit);
      if (commit_timestamp < ts.tv_sec)
        {
          if (opt_static_deltas_only)
            {
              if(!ostree_repo_prune_static_deltas (repo, checksum, cancellable, error))
                goto out;
            }
          else
            {
              if (!ostree_repo_delete_object (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, cancellable, error))
                goto out;
            }
        }
    }

  ret = TRUE;

 out:
  return ret;
}