/**
 * @test 
 */
void test_file_permissions(void)
{
	char filename[MAXPATHLEN] = "/tmp/permsXXXXXX";
	int	 fd;
	int ret;
	GError *gerr = NULL;
	
	g_log_set_always_fatal(G_LOG_FATAL_MASK);

	/* 1st test: non-existent file */
	g_assert_cmpint(chassis_filemode_check_full("/tmp/a_non_existent_file", CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, -1);
	g_assert_cmpint(gerr->code, ==, G_FILE_ERROR_NOENT);
	g_clear_error(&gerr);

	fd = mkstemp(filename);
	if (fd < 0) {
		g_critical("%s: mkstemp(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(fd, >=, 0);

	/* 2nd test: too permissive */
	ret = chmod(filename, TOO_OPEN);
	if (ret < 0) {
		g_critical("%s: chmod(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);
	g_assert_cmpint(chassis_filemode_check_full(filename, CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, 1);
	g_assert_cmpint(gerr->code, ==, G_FILE_ERROR_PERM);
	g_clear_error(&gerr);

	/* 3rd test: OK */
	ret = chmod(filename, GOOD_PERMS);
	if (ret < 0) {
		g_critical("%s: chmod(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);
	g_assert_cmpint(chassis_filemode_check_full(filename, CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, 0);
	g_assert(gerr == NULL);

	/* 4th test: non-regular file */
	close(fd);
	remove(filename);
	ret = mkdir(filename, GOOD_PERMS);
	if (ret < 0) {
		g_critical("%s: mkdir(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);
	g_assert_cmpint(chassis_filemode_check_full(filename, CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, -1);
	g_assert_cmpint(gerr->code, ==, G_FILE_ERROR_INVAL);
	g_clear_error(&gerr);

	/* clean up */
	ret = rmdir(filename);
	if (ret < 0) {
		g_critical("%s: rmdir(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);

}
Exemple #2
0
/**********************
 *** Initialization ***
 **********************/
int main(int argc, char** argv) {
    gboolean daemon_mode = TRUE;
    const char* username;
    const char* password;
    GMainLoop* main_loop;

    /* Parse command line options */
    int opt;
    while ((opt = getopt(argc, argv, "dfhv")) != -1) {
        switch (opt) {
        case 'd':
            debug_mode = TRUE;
        case 'v':
            verbose_mode = TRUE;
        case 'f':
            daemon_mode = FALSE; break;
        default:
            printf("Usage: spopd [options]\n"
                   "Options:\n"
                   "  -d        debug mode (implies -f and -v)\n"
                   "  -f        run in foreground (default: fork to background)\n"
                   "  -v        verbose mode (implies -f)\n"
                   "  -h        display this message\n");
            return 0;
        }
    }

    g_set_application_name("spop " SPOP_VERSION);
    g_set_prgname("spop");
    g_type_init();

    printf("%s\n", copyright_notice);

    /* Log handler */
    logging_init();

    if (!daemon_mode) {
        /* Stay in foreground: do everything here */
        if (debug_mode)
            g_info("Running in debug mode");
    }
    else {
        /* Run in daemon mode: fork to background */
        printf("Switching to daemon mode...\n");
        if (daemon(0, 0) != 0)
            g_error("Error while forking process: %s", g_strerror(errno));

    }

    /* Init essential stuff */
    main_loop = g_main_loop_new(NULL, FALSE);
    exit_handler_init();

    /* Read username and password */
    username = config_get_string("spotify_username");
    password = config_get_string("spotify_password");

    /* Init plugins */
    plugins_init();

    /* Init login */
    session_init();
    session_login(username, password);

    /* Init various subsystems */
    interface_init();

    /* Event loop */
    g_main_loop_run(main_loop);

    return 0;
}
Exemple #3
0
static gssize
g_unix_output_stream_write (GOutputStream  *stream,
			    const void     *buffer,
			    gsize           count,
			    GCancellable   *cancellable,
			    GError        **error)
{
  GUnixOutputStream *unix_stream;
  gssize res = -1;
  GPollFD poll_fds[2];
  int nfds = 0;
  int poll_ret;

  unix_stream = G_UNIX_OUTPUT_STREAM (stream);

  poll_fds[0].fd = unix_stream->priv->fd;
  poll_fds[0].events = G_IO_OUT;
  nfds++;

  if (unix_stream->priv->is_pipe_or_socket &&
      g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
    nfds++;

  while (1)
    {
      int errsv;

      poll_fds[0].revents = poll_fds[1].revents = 0;
      do
        {
          poll_ret = g_poll (poll_fds, nfds, -1);
          errsv = errno;
        }
      while (poll_ret == -1 && errsv == EINTR);

      if (poll_ret == -1)
	{
	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to file descriptor: %s"),
		       g_strerror (errsv));
	  break;
	}

      if (g_cancellable_set_error_if_cancelled (cancellable, error))
	break;

      if (!poll_fds[0].revents)
	continue;

      res = write (unix_stream->priv->fd, buffer, count);
      errsv = errno;
      if (res == -1)
	{
	  if (errsv == EINTR || errsv == EAGAIN)
	    continue;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to file descriptor: %s"),
		       g_strerror (errsv));
	}

      break;
    }

  if (nfds == 2)
    g_cancellable_release_fd (cancellable);
  return res;
}
gboolean
tracker_memory_setrlimits (void)
{
#ifndef DISABLE_MEM_LIMITS
	struct rlimit rl = { 0 };
	glong total;
	glong total_halfed;
	glong limit;

	total = get_memory_total ();

	if (!total) {
		/* total amount of memory unknown */
		return FALSE;
	}

	total_halfed = total / 2;

	/* Clamp memory between 50% of total and MAXLONG (2GB on 32-bit) */
	limit = CLAMP (total_halfed, MEM_LIMIT_MIN, G_MAXLONG);

	/* We want to limit the max virtual memory
	 * most extractors use mmap() so only virtual memory can be
	 * effectively limited.
	 */
	getrlimit (RLIMIT_AS, &rl);
	rl.rlim_cur = limit;

	if (setrlimit (RLIMIT_AS, &rl) == -1) {
		const gchar *str = g_strerror (errno);

		g_critical ("Could not set virtual memory limit with setrlimit(RLIMIT_AS), %s",
		            str ? str : "no error given");

		return FALSE;
	} else {
		getrlimit (RLIMIT_DATA, &rl);
		rl.rlim_cur = limit;

		if (setrlimit (RLIMIT_DATA, &rl) == -1) {
			const gchar *str = g_strerror (errno);

			g_critical ("Could not set heap memory limit with setrlimit(RLIMIT_DATA), %s",
			            str ? str : "no error given");

			return FALSE;
		} else {
			gchar *str1, *str2;

			str1 = g_format_size (total);
			str2 = g_format_size (limit);

			g_message ("Setting memory limitations: total is %s, minimum is 256 MB, recommended is ~1 GB", str1);
			g_message ("  Virtual/Heap set to %s (50%% of total or MAXLONG)", str2);

			g_free (str2);
			g_free (str1);
		}
	}
#endif /* DISABLE_MEM_LIMITS */

	return TRUE;
}
int main(int argc, char **argv)
{
  unsigned i;
  GError *error = NULL;
  GOptionContext *op_context;
  unsigned line_no = 0;
  GHashTable *contexts_by_str;
  GPtrArray *all_contexts;
  GHashTable *code_points_by_line;
  GPtrArray *all_code_points;
  char *tmp_fname;
  char **files;
  guint n_files;
  AllocInfo *total_by_time;
  op_context = g_option_context_new (NULL);
  g_option_context_set_summary (op_context, "gsk-analyze-successive-memdumps");
  g_option_context_add_main_entries (op_context, op_entries, NULL);
  if (!g_option_context_parse (op_context, &argc, &argv, &error))
    gsk_fatal_user_error ("error parsing command-line options: %s", error->message);
  g_option_context_free (op_context);

  contexts_by_str = g_hash_table_new (g_str_hash, g_str_equal);
  code_points_by_line = g_hash_table_new (g_str_hash, g_str_equal);
  all_contexts = g_ptr_array_new ();
  all_code_points = g_ptr_array_new ();

  if (dir_name == NULL)
    g_error ("missing argument directory");

  n_files = argc - 1;
  files = argv + 1;
  g_printerr ("Scanning %u input files... ", n_files);
  total_by_time = g_new0 (AllocInfo, n_files);
  for (i = 0; i < n_files; i++)
    {
      FILE *fp = fopen (files[i], "r");
      char buf[4096];
      GString *context_str = g_string_new ("");
      AllocInfo ai;
      Context *context;
      update_percent_bar (i, n_files);
      if (fp == NULL)
        gsk_fatal_user_error ("opening %s failed: %s",
	                      files[i], g_strerror (errno));
      do
        {
          if (!fgets (buf, sizeof (buf), fp))
            gsk_fatal_user_error ("file %s: unexpected eof", files[i]);
          line_no++;
        }
      while (is_preamble_line (buf));
next_block_start:
      if (g_str_has_prefix (buf, "Summary: "))
        goto done_file;
      if (sscanf (buf, "%u bytes allocated in %u blocks from:",
                      &ai.n_bytes, &ai.n_blocks) != 2)
        gsk_fatal_user_error ("error parsing line %u from %s",
                              line_no, files[i]);
      g_string_set_size (context_str, 0);
      for (;;)
        {
          if (fgets (buf, sizeof (buf), fp) == NULL)
            gsk_fatal_user_error ("file %s: unexpected eof", files[i]);
          line_no++;
          if (buf[0] != ' ')
            break;
          g_string_append (context_str, buf + 2);
        }

      /* find or create context */
      context = g_hash_table_lookup (contexts_by_str, context_str->str);
      if (context == NULL)
        {
          context = g_new (Context, 1);
          context->str = g_strdup (context_str->str);
          context->alloc_infos = g_new0 (AllocInfo, n_files);
          g_hash_table_insert (contexts_by_str, context->str, context);
          context->total_bytes = 0;
          g_ptr_array_add (all_contexts, context);
        }
      context->alloc_infos[i] = ai;
      context->total_bytes += ai.n_bytes;
      total_by_time[i].n_bytes += ai.n_bytes;
      total_by_time[i].n_blocks += ai.n_blocks;
      goto next_block_start;

done_file:
      fclose (fp);
    }
  update_percent_bar (i, n_files);

  g_ptr_array_sort (all_contexts, compare_p_context_by_total_bytes_descending);
  if (!gsk_mkdir_p (dir_name, 0755, &error))
    gsk_fatal_user_error ("error making directory %s: %s", dir_name, error->message);
  static const char *subdirs[] = { "data", "images", "code-points" };
  for (i = 0; i < G_N_ELEMENTS (subdirs); i++)
    {
      tmp_fname = g_strdup_printf ("%s/%s", dir_name, subdirs[i]);
      if (!gsk_mkdir_p (tmp_fname, 0755, &error))
        g_error ("error mkdir(%s): %s", tmp_fname, error->message);
      g_free (tmp_fname);
    }
  FILE *gnuplot_script_fp, *index_html_fp, *main_html_fp;
  tmp_fname = g_strdup_printf ("%s/gnuplot.input", dir_name);
  gnuplot_script_fp = fopen (tmp_fname, "w");
  if (gnuplot_script_fp == NULL)
    g_error ("error creating %s: %s", tmp_fname, g_strerror (errno));
  g_free (tmp_fname);
  fprintf (gnuplot_script_fp,
           "set terminal png\n\n");
  index_html_fp = NULL;

  {
    FILE *fp;
    tmp_fname = g_strdup_printf ("%s/data/total.data", dir_name);
    fp = fopen (tmp_fname, "w");
    if (fp == NULL)
      g_error ("creating %s failed", tmp_fname);
    g_free (tmp_fname);
    for (i = 0; i < n_files; i++)
      fprintf (fp, "%u %u %u\n", i,
               total_by_time[i].n_bytes,
               total_by_time[i].n_blocks);
    fclose (fp);

    fprintf (gnuplot_script_fp,
             "set output \"%s/images/total.png\"\n", dir_name);
    fprintf (gnuplot_script_fp,
             "plot \"%s/data/total.data\" using 1:2 title \"bytes\", \"%s/data/total.data\" using 1:3 title \"blocks\"\n",
             dir_name, dir_name);
  }

  tmp_fname = g_strdup_printf ("%s/index.html", dir_name);
  main_html_fp = fopen (tmp_fname, "w");
  if (main_html_fp == NULL)
    g_error ("error creating %s: %s", tmp_fname, g_strerror (errno));
  fprintf (main_html_fp, "<html><body>\n"
                         "Total:\n<br/><img src=\"images/total.png\" /><br/>\n"
                         "<ul>\n");

  g_printerr ("Writing data files for %u contexts... ", all_contexts->len);
  for (i = 0; i < all_contexts->len; i++)
    {
      FILE *fp;
      Context *context = all_contexts->pdata[i];
      guint j;
      update_percent_bar (i, all_contexts->len);
      if (i % 100 == 0)
        {
          if (index_html_fp != NULL)
            {
              fprintf (index_html_fp, "</body></html>\n");
              fclose (index_html_fp);
            }
          tmp_fname = g_strdup_printf ("%s/index-%03u.html", dir_name, i / 100);
          index_html_fp = fopen (tmp_fname, "w");
          if (index_html_fp == NULL)
            g_error ("error creating %s: %s", tmp_fname, g_strerror (errno));
          g_free (tmp_fname);
          fprintf (index_html_fp, "<html><body>\n");
          fprintf (index_html_fp, "<h1>Contexts %u .. %u</h1>\n", i, MIN (i + 99, all_contexts->len - 1));

          fprintf (main_html_fp, "<li><a href=\"index-%03u.html\">Contexts %u .. %u</a></li>\n",
                   i / 100,  i, MIN (i + 99, all_contexts->len - 1));
        }

      tmp_fname = g_strdup_printf ("%s/data/context-%05u.data", dir_name, i);
      fp = fopen (tmp_fname, "w");
      if (fp == NULL)
        g_error ("error creating %s: %s", tmp_fname, g_strerror (errno));
      for (j = 0; j < n_files; j++)
        fprintf (fp, "%u %u %u\n", j,
                 context->alloc_infos[j].n_bytes,
                 context->alloc_infos[j].n_blocks);
      fclose (fp);
      fprintf (gnuplot_script_fp,
               "set output \"%s/images/context-%05u.png\"\n", dir_name, i);
      fprintf (gnuplot_script_fp,
               "plot \"%s/data/context-%05u.data\" using 1:2 title \"bytes\", \"%s/data/context-%05u.data\" using 1:3 title \"blocks\"\n",
               dir_name, i,
               dir_name, i);

      pr_context (index_html_fp, i, context, "images");
    }
  update_percent_bar (i, all_contexts->len);
  fprintf (main_html_fp, "</ul>\n"
                         "<h1>Code Point Index</h1>\n"
                          "<a href=\"index-by-code-point.html\">here</a>\n");
  if (index_html_fp != NULL)
    {
      fprintf (index_html_fp, "</body></html>\n");
      fclose (index_html_fp);
    }
  fprintf (main_html_fp, "</body></html>\n");
  fclose (main_html_fp);

  g_printerr ("Calculating code-points... ");
  for (i = 0; i < all_contexts->len; i++)
    {
      Context *context = all_contexts->pdata[i];
      CodePoint *cp;
      char **strs = g_strsplit (context->str, "\n", 0);
      unsigned j;
      for (j = 0; strs[j] != NULL; j++)
        {
          g_strstrip (strs[j]);
          if (strs[j][0] != 0)
            {
              cp = g_hash_table_lookup (code_points_by_line, strs[j]);
              if (cp == NULL)
                {
                  cp = g_new (CodePoint, 1);
                  cp->line = g_strdup (strs[j]);
                  cp->context_indices = g_array_new (FALSE, FALSE, sizeof (guint));
                  g_hash_table_insert (code_points_by_line, cp->line, cp);
                  g_ptr_array_add (all_code_points, cp);
                }
              if (cp->context_indices->len == 0
               || g_array_index (cp->context_indices, guint, cp->context_indices->len - 1) != i)
                g_array_append_val (cp->context_indices, i);
            }
        }
      g_strfreev (strs);
    }
  g_printerr (" done [%u code points].\n", all_code_points->len);
  g_ptr_array_sort (all_code_points, compare_p_code_point_by_line);
  tmp_fname = g_strdup_printf ("%s/index-by-code-point.html", dir_name);
  main_html_fp = fopen (tmp_fname, "w");
  if (main_html_fp == NULL)
    g_error ("error creating %s: %s", tmp_fname, g_strerror (errno));
  g_free (tmp_fname);
  fprintf (main_html_fp,
           "<html><body><h1>Code Points</h1>\n");
  fprintf (main_html_fp,
           "<ul>\n");
  AllocInfo *totals;
  totals = g_new (AllocInfo, n_files);
  g_printerr ("Creating code-point data... ");
  for (i = 0; i < all_code_points->len; i++)
    {
      CodePoint *cp = all_code_points->pdata[i];
      FILE *fp;
      unsigned j;
      update_percent_bar (i, all_code_points->len);
      memset (totals, 0, sizeof (AllocInfo) * n_files);
      for (j = 0; j < cp->context_indices->len; j++)
        {
          guint context_index = g_array_index (cp->context_indices, guint, j);
          Context *context = all_contexts->pdata[context_index];
          guint k;
          for (k = 0; k < n_files; k++)
            {
              totals[k].n_bytes += context->alloc_infos[k].n_bytes;
              totals[k].n_blocks += context->alloc_infos[k].n_blocks;
            }
        }
      tmp_fname = g_strdup_printf ("%s/data/codepoint-%05u.data", dir_name, i);
      fp = fopen (tmp_fname, "w");
      for (j = 0; j < n_files; j++)
        fprintf (fp, "%u %u %u\n", j,
                 totals[j].n_bytes,
                 totals[j].n_blocks);
      fclose (fp);

      fprintf (gnuplot_script_fp,
               "set output \"%s/images/codepoint-%05u.png\"\n", dir_name, i);
      fprintf (gnuplot_script_fp,
               "plot \"%s/data/codepoint-%05u.data\" using 1:2 title \"bytes\", \"%s/data/codepoint-%05u.data\" using 1:3 title \"blocks\"\n",
               dir_name, i,
               dir_name, i);

      fprintf (main_html_fp, "<li>Code point %05u: <a href=\"code-points/%05u.html\">%s</a> (%u contexts)</li>\n",
               i, i, cp->line, cp->context_indices->len);
      tmp_fname = g_strdup_printf ("%s/code-points/%05u.html", dir_name, i);
      fp = fopen (tmp_fname, "w");
      if (fp == NULL)
        g_error ("error creating %s: %s", tmp_fname, g_strerror (errno));
      g_free (tmp_fname);



      fprintf (fp, "<html><body><h1>Code Point %u</h1>\n"
               "<b><pre>\n"
               "%s\n"
               "</pre>\n"
               "</b>\n", i, cp->line);
      fprintf (fp, "<p>Summary<br /><img src=\"../images/codepoint-%05u.png\" /></p>\n", i);
      for (j = 0; j < MIN (cp->context_indices->len, 100); j++)
        pr_context (fp, g_array_index (cp->context_indices, guint, j),
                    all_contexts->pdata[g_array_index (cp->context_indices, guint, j)],
                    "../images");
      if (j < cp->context_indices->len)
        fprintf (fp, "<p><b>%u Contexts omitted</b></p>\n",
                 (guint)(cp->context_indices->len - j));
      fprintf (fp,
               "</body></html>\n");
      fclose (fp);
    }
  update_percent_bar (i, all_code_points->len);
  fprintf (main_html_fp,
           "</ul>\n"
           "</body></html>\n");
  fclose (main_html_fp);

  fclose (gnuplot_script_fp);

  g_printerr ("Running gnuplot... ");
  tmp_fname = g_strdup_printf ("gnuplot < %s/gnuplot.input", dir_name);
  if (system (tmp_fname) != 0)
    gsk_fatal_user_error ("error running gnuplot");
  g_free (tmp_fname);
  g_printerr (" done.\n");

  return 0;
}
Exemple #6
0
static void
host_resolved(gpointer data, gint source, PurpleInputCondition cond)
{
	PurpleDnsQueryData *query_data;
	int rc, err;
	GSList *hosts = NULL;
	struct sockaddr *addr = NULL;
	size_t addrlen;
	char message[1024];

	query_data = data;

	purple_debug_info("dns", "Got response for '%s'\n", query_data->hostname);
	purple_input_remove(query_data->resolver->inpa);
	query_data->resolver->inpa = 0;

	rc = read(query_data->resolver->fd_out, &err, sizeof(err));
	if ((rc == 4) && (err != 0))
	{
#ifdef HAVE_GETADDRINFO
		g_snprintf(message, sizeof(message), _("Error resolving %s:\n%s"),
				query_data->hostname, purple_gai_strerror(err));
#else
		g_snprintf(message, sizeof(message), _("Error resolving %s: %d"),
				query_data->hostname, err);
#endif
		/* Re-read resolv.conf and friends in case DNS servers have changed */
		res_init();

		purple_dnsquery_failed(query_data, message);
	} else if (rc > 0) {
		/* Success! */
		while (rc > 0) {
			rc = read(query_data->resolver->fd_out, &addrlen, sizeof(addrlen));
			if (rc > 0 && addrlen > 0 && addrlen < MAX_ADDR_RESPONSE_LEN) {
				addr = g_malloc(addrlen);
				rc = read(query_data->resolver->fd_out, addr, addrlen);
				hosts = g_slist_append(hosts, GINT_TO_POINTER(addrlen));
				hosts = g_slist_append(hosts, addr);
			} else {
				break;
			}
		}
		/*	wait4(resolver->dns_pid, NULL, WNOHANG, NULL); */
		purple_dnsquery_resolved(query_data, hosts);

	} else if (rc == -1) {
		g_snprintf(message, sizeof(message), _("Error reading from resolver process:\n%s"), g_strerror(errno));
		purple_dnsquery_failed(query_data, message);

	} else if (rc == 0) {
		g_snprintf(message, sizeof(message), _("Resolver process exited without answering our request"));
		purple_dnsquery_failed(query_data, message);
	}

	handle_next_queued_request();
}
static void
svgtopng (const gchar *src)
{
  gchar *dest;
  gchar *tmp;
  GdkPixbuf *pix;
  gchar *link;
  gchar *newlink;
  GError *error = NULL;
  gchar *dirname;
  gchar *basename;
  gint icon_size;

  if (!g_str_has_suffix (src, ".svg"))
    return;

  /* get parent directory name */
  dirname = g_path_get_dirname (src);
  basename = g_path_get_basename (dirname);
  g_free (dirname);
  if (basename == NULL)
    return;

  /* to go get an icon size */
  icon_size = atoi (basename);
  g_free (basename);
  if (icon_size == 0)
    {
      g_message ("Unable to extract icon size from directory name %s", src);
      return;
    }

  tmp = g_strndup (src, strlen (src) - 3);
  dest = g_strconcat (tmp, "png", NULL);
  g_free (tmp);

  if (!g_file_test (dest, G_FILE_TEST_EXISTS))
    {
      if (g_file_test (src, G_FILE_TEST_IS_SYMLINK))
        {
          link = g_file_read_link (src, NULL);
          if (link
              && g_str_has_suffix (link, ".svg"))
            {
              tmp = g_strndup (link, strlen (link) - 3);
              newlink = g_strconcat (tmp, "png", NULL);
              g_free (tmp);

              if (symlink (newlink, dest) == -1)
                g_message ("failed to create symlink: %s", g_strerror (errno));

              g_free (newlink);
            }
          g_free (link);
        }
      else
        {
          pix = gdk_pixbuf_new_from_file (src, &error);
          if (pix)
            {
              if (gdk_pixbuf_get_width (pix) > icon_size
                  || gdk_pixbuf_get_height (pix) > icon_size)
                {
                  g_message ("Skipping %s, size too big (%dx%d instead of %dx%d)",
                             dest, gdk_pixbuf_get_width (pix),
                             gdk_pixbuf_get_height (pix),
                             icon_size, icon_size);

                  g_object_unref (pix);
                  return;
                }

              if (!gdk_pixbuf_save (pix, dest, "png", &error, NULL))
                {
                  g_message ("Failed to save pixmap to %s: %s", dest, error->message);
                  g_error_free (error);
                }
              g_object_unref (pix);
            }
          else
            {
              g_message ("Failed to load svg %s: %s", src, error->message);
              g_error_free (error);
            }
        }
    }

  g_free (dest);
}
Exemple #8
0
static void
import_mbox_exec (struct _import_mbox_msg *m,
                  GCancellable *cancellable,
                  GError **error)
{
	CamelFolder *folder;
	CamelMimeParser *mp = NULL;
	struct stat st;
	gint fd;

	if (g_stat (m->path, &st) == -1) {
		g_warning (
			"cannot find source file to import '%s': %s",
			m->path, g_strerror (errno));
		return;
	}

	if (m->uri == NULL || m->uri[0] == 0)
		folder = e_mail_session_get_local_folder (
			m->session, E_MAIL_LOCAL_FOLDER_INBOX);
	else
		folder = e_mail_session_uri_to_folder_sync (
			m->session, m->uri, CAMEL_STORE_FOLDER_CREATE,
			cancellable, error);

	if (folder == NULL)
		return;

	if (S_ISREG (st.st_mode)) {
		gboolean any_read = FALSE;

		fd = g_open (m->path, O_RDONLY | O_BINARY, 0);
		if (fd == -1) {
			g_warning (
				"cannot find source file to import '%s': %s",
				m->path, g_strerror (errno));
			goto fail1;
		}

		mp = camel_mime_parser_new ();
		camel_mime_parser_scan_from (mp, TRUE);
		if (camel_mime_parser_init_with_fd (mp, fd) == -1) {
			/* will never happen - 0 is unconditionally returned */
			goto fail2;
		}

		camel_operation_push_message (
			cancellable, _("Importing '%s'"),
			camel_folder_get_display_name (folder));
		camel_folder_freeze (folder);
		while (camel_mime_parser_step (mp, NULL, NULL) == CAMEL_MIME_PARSER_STATE_FROM &&
		       !g_cancellable_is_cancelled (cancellable)) {

			CamelMimeMessage *msg;
			gint pc = 0;

			any_read = TRUE;

			if (st.st_size > 0)
				pc = (gint) (100.0 * ((gdouble)
					camel_mime_parser_tell (mp) /
					(gdouble) st.st_size));
			camel_operation_progress (cancellable, pc);

			msg = camel_mime_message_new ();
			if (!camel_mime_part_construct_from_parser_sync (
				(CamelMimePart *) msg, mp, NULL, NULL)) {
				/* set exception? */
				g_object_unref (msg);
				break;
			}

			import_mbox_add_message (folder, msg, cancellable, error);

			g_object_unref (msg);

			if (error && *error != NULL)
				break;

			camel_mime_parser_step (mp, NULL, NULL);
		}

		if (!any_read && !g_cancellable_is_cancelled (cancellable)) {
			CamelStream *stream;

			stream = camel_stream_fs_new_with_name (m->path, O_RDONLY, 0, NULL);
			if (stream) {
				CamelMimeMessage *msg;

				msg = camel_mime_message_new ();

				if (camel_data_wrapper_construct_from_stream_sync ((CamelDataWrapper *) msg, stream, NULL, NULL))
					import_mbox_add_message (folder, msg, cancellable, error);

				g_object_unref (msg);
				g_object_unref (stream);
			}
		}
		/* Not passing a GCancellable or GError here. */
		camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
		camel_folder_thaw (folder);
		camel_operation_pop_message (cancellable);
	fail2:
		g_object_unref (mp);
	}
fail1:
	/* Not passing a GCancellable or GError here. */
	camel_folder_synchronize_sync (folder, FALSE, NULL, NULL);
	g_object_unref (folder);
	/* 'fd' is freed together with 'mp' */
	/* coverity[leaked_handle] */
}
Exemple #9
0
static GstClockTime send_chunk (EncoderOutput *encoder_output, RequestData *request_data)
{
        HTTPStreamingPrivateData *priv_data;
        gint64 current_gop_end_addr, tail_addr;
        gint32 ret;

        priv_data = request_data->priv_data;

        if (sem_wait (encoder_output->semaphore) == -1) {
                GST_WARNING ("send_chunk sem_wait failure: %s", g_strerror (errno));
                /* sem_wait failure, wait a while. */
                return 100 * GST_MSECOND + g_random_int_range (1, 1000000);
        }
        tail_addr = *(encoder_output->tail_addr);
        current_gop_end_addr = get_current_gop_end (encoder_output, priv_data);

        if (priv_data->send_count == priv_data->chunk_size + priv_data->chunk_size_str_len + 2) {
                /* completly send a chunk, prepare next. */
                priv_data->send_position += priv_data->send_count - priv_data->chunk_size_str_len - 2;
                if (priv_data->send_position == encoder_output->cache_size) {
                        priv_data->send_position = 0;
                }
                g_free (priv_data->chunk_size_str);
                priv_data->chunk_size_str_len = 0;
                priv_data->chunk_size = 0;
        }

        if (priv_data->send_position == current_gop_end_addr) {
                /* next gop. */
                priv_data->rap_addr = current_gop_end_addr;
                if (priv_data->send_position + 12 < encoder_output->cache_size) {
                        priv_data->send_position += 12;

                } else {
                        priv_data->send_position = priv_data->send_position + 12 - encoder_output->cache_size;
                }
                current_gop_end_addr = get_current_gop_end (encoder_output, priv_data);
        }
        sem_post (encoder_output->semaphore);

        if (priv_data->chunk_size == 0) {
                if (current_gop_end_addr == -1) {
                        /* current output gop. */
                        if ((tail_addr - priv_data->send_position) > 16384) {
                                priv_data->chunk_size = 16384;

                        } else if (tail_addr > priv_data->send_position) {
                                /* send to tail. */
                                priv_data->chunk_size = tail_addr - priv_data->send_position;

                        } else if (tail_addr == priv_data->send_position) {
                                /* no data available, wait a while. */
                                return 100 * GST_MSECOND + g_random_int_range (1, 1000000);

                        } else if ((encoder_output->cache_size - priv_data->send_position) > 16384) {
                                priv_data->chunk_size = 16384;

                        } else {
                                priv_data->chunk_size = encoder_output->cache_size - priv_data->send_position;
                        }

                } else {
                        /* completely output gop. */
                        if ((current_gop_end_addr - priv_data->send_position) > 16384) {
                                priv_data->chunk_size = 16384;

                        } else if (current_gop_end_addr > priv_data->send_position) {
                                /* send to gop end. */
                                priv_data->chunk_size = current_gop_end_addr - priv_data->send_position;

                        } else if (current_gop_end_addr == priv_data->send_position) {
                                /* no data available, wait a while. */
                                return 100 * GST_MSECOND + g_random_int_range (1, 1000000); //FIXME FIXME

                        } else {
                                /* send to cache end. */
                                priv_data->chunk_size = encoder_output->cache_size - priv_data->send_position;
                        }
                }
                priv_data->chunk_size_str = g_strdup_printf ("%x\r\n", priv_data->chunk_size);
                priv_data->chunk_size_str_len = strlen (priv_data->chunk_size_str);
                priv_data->send_count = 0;
        }

        /* send data. */
        ret = send_data (encoder_output, request_data);
        if (ret == -1) {
                return GST_CLOCK_TIME_NONE;

        } else {
                priv_data->send_count += ret;
                request_data->bytes_send += ret;
        }
        if (priv_data->send_count == priv_data->chunk_size + priv_data->chunk_size_str_len + 2) {
                /* send complete, wait 10 ms. */
                return 10 * GST_MSECOND + g_random_int_range (1, 1000000);

        } else {
                /* not send complete, blocking, wait 200 ms. */
                return 200 * GST_MSECOND + g_random_int_range (1, 1000000);
        }
}
Exemple #10
0
int himd_blockstream_read(struct himd_blockstream * stream, unsigned char * block,
                            unsigned int * firstframe, unsigned int * lastframe,
                            unsigned char * fragkey, struct himderrinfo * status)
{
    struct fraginfo * curfrag;

    g_return_val_if_fail(stream != NULL, -1);
    g_return_val_if_fail(block != NULL, -1);

    if(stream->curfragno == stream->fragcount)
    {
        set_status_const(status, HIMD_STATUS_AUDIO_EOF, _("EOF of audio stream reached"));
        return -1;
    }

    curfrag = &stream->frags[stream->curfragno];

    if(stream->curblockno == curfrag->firstblock)
    {
        if(firstframe)
            *firstframe = curfrag->firstframe;
        if(fseek(stream->atdata, stream->curblockno*16384L, SEEK_SET) < 0)
        {
            set_status_printf(status, HIMD_ERROR_CANT_SEEK_AUDIO,
                              _("Can't seek in audio data: %s"), g_strerror(errno));
            return -1;
        }
    }
    else if(firstframe)
        *firstframe = 0;

    if(fread(block, 16384, 1, stream->atdata) != 1)
    {
        if(feof(stream->atdata))
            set_status_printf(status, HIMD_ERROR_CANT_READ_AUDIO, _("Unexpected EOF while reading audio block %d"),stream->curblockno);
        else
            set_status_printf(status, HIMD_ERROR_CANT_READ_AUDIO, _("Read error on block audio %d: %s"), stream->curblockno, g_strerror(errno));
        return -1;
    }

    if(fragkey)
        memcpy(fragkey, curfrag->key, sizeof curfrag->key);

    if(stream->curblockno == curfrag->lastblock)
    {
        if(lastframe)
        {
            if(is_mpeg(stream))
                *lastframe = curfrag->lastframe - 1;
            else
                *lastframe = curfrag->lastframe;
        }
        stream->curfragno++;
        curfrag++;
        if(stream->curfragno < stream->fragcount)
            stream->curblockno = curfrag->firstblock;
    }
    else
    {
        if(lastframe)
        {
            if(is_mpeg(stream))
                *lastframe = beword16(block+4) - 1;
            else
                *lastframe = stream->frames_per_block - 1;
        }
        stream->curblockno++;
    }

    return 0;
}
static GstFlowReturn
gst_multi_file_src_create (GstPushSrc * src, GstBuffer ** buffer)
{
  GstMultiFileSrc *multifilesrc;
  gsize size;
  gchar *data;
  gchar *filename;
  GstBuffer *buf;
  gboolean ret;
  GError *error = NULL;

  multifilesrc = GST_MULTI_FILE_SRC (src);

  if (multifilesrc->index < multifilesrc->start_index) {
    multifilesrc->index = multifilesrc->start_index;
  }

  if (multifilesrc->stop_index != -1 &&
      multifilesrc->index > multifilesrc->stop_index) {
    if (multifilesrc->loop)
      multifilesrc->index = multifilesrc->start_index;
    else
      return GST_FLOW_EOS;
  }

  filename = gst_multi_file_src_get_filename (multifilesrc);

  GST_DEBUG_OBJECT (multifilesrc, "reading from file \"%s\".", filename);

  ret = g_file_get_contents (filename, &data, &size, &error);
  if (!ret) {
    if (multifilesrc->successful_read) {
      /* If we've read at least one buffer successfully, not finding the
       * next file is EOS. */
      g_free (filename);
      if (error != NULL)
        g_error_free (error);

      if (multifilesrc->loop) {
        error = NULL;
        multifilesrc->index = multifilesrc->start_index;

        filename = gst_multi_file_src_get_filename (multifilesrc);
        ret = g_file_get_contents (filename, &data, &size, &error);
        if (!ret) {
          g_free (filename);
          if (error != NULL)
            g_error_free (error);

          return GST_FLOW_EOS;
        }
      } else {
        return GST_FLOW_EOS;
      }
    } else {
      goto handle_error;
    }
  }

  multifilesrc->successful_read = TRUE;
  multifilesrc->index++;

  buf = gst_buffer_new ();
  gst_buffer_append_memory (buf,
      gst_memory_new_wrapped (0, data, size, 0, size, data, g_free));
  GST_BUFFER_OFFSET (buf) = multifilesrc->offset;
  GST_BUFFER_OFFSET_END (buf) = multifilesrc->offset + size;
  multifilesrc->offset += size;

  GST_DEBUG_OBJECT (multifilesrc, "read file \"%s\".", filename);

  g_free (filename);
  *buffer = buf;
  return GST_FLOW_OK;

handle_error:
  {
    if (error != NULL) {
      GST_ELEMENT_ERROR (multifilesrc, RESOURCE, READ,
          ("Error while reading from file \"%s\".", filename),
          ("%s", error->message));
      g_error_free (error);
    } else {
      GST_ELEMENT_ERROR (multifilesrc, RESOURCE, READ,
          ("Error while reading from file \"%s\".", filename),
          ("%s", g_strerror (errno)));
    }
    g_free (filename);
    return GST_FLOW_ERROR;
  }
}
Exemple #12
0
DonnaTaskHelperRc
donna_task_helper (DonnaTask          *task,
                   task_helper_ui      show_ui,
                   task_helper_ui      destroy_ui,
                   gpointer            data)
{
    DonnaTaskHelper th;
    fd_set fds;
    gint fd_task;

    g_return_val_if_fail (DONNA_IS_TASK (task), DONNA_TASK_HELPER_RC_ERROR);
    g_return_val_if_fail (show_ui != NULL, DONNA_TASK_HELPER_RC_ERROR);
    g_return_val_if_fail (destroy_ui != NULL, DONNA_TASK_HELPER_RC_ERROR);

    /* create our eventfd */
    th.fd = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK);
    if (th.fd == -1)
        return DONNA_TASK_HELPER_RC_ERROR;

    /* init th */
    g_mutex_init (&th.mutex);
    th.has_destroy = 0;
    th.show_ui = show_ui;
    th.destroy_ui = destroy_ui;
    th.data = data;
    th.rc = DONNA_TASK_HELPER_RC_SUCCESS;

    /* get the task-s fd, in case it gets paused/cancelled */
    fd_task = donna_task_get_fd (task);

    g_idle_add ((GSourceFunc) do_show_ui, &th);

    for (;;)
    {
        gint ret;

        FD_ZERO (&fds);
        FD_SET (th.fd, &fds);
        if (fd_task >= 0)
            FD_SET (fd_task, &fds);

        /* block thread until user "answered" (helper_done() was called,
         * unblocking our fd) or the task gets paused/cancelled */
        ret = select (MAX (th.fd, fd_task) + 1, &fds, NULL, NULL, 0);
        if (ret < 0)
        {
            gint _errno = errno;

            if (errno == EINTR)
                continue;

            g_warning ("TaskHelper: Call to select() failed: %s",
                    g_strerror (_errno));
            continue;
        }

        g_mutex_lock (&th.mutex);

        /* normal ending, i.e. user did "answer" -- meaning the UI was
         * destroyed, nothing more to do but free stuff & return */
        if (FD_ISSET (th.fd, &fds))
        {
            g_mutex_unlock (&th.mutex);
            break;
        }

        /* task was paused/cancelled */
        if (FD_ISSET (fd_task, &fds))
        {
            th.rc = DONNA_TASK_HELPER_RC_CANCELLING;
            /* flag that there is (will be) a pending call to destroy_ui. This
             * is used to handle race condition where the user answers while
             * we're doing this */
            th.has_destroy = 1;
            /* disable this for now */
            fd_task = -1;
            /* install the call to destroy the ui */
            g_idle_add ((GSourceFunc) do_destroy_ui, &th);
            /* and block again on our fd (waiting for UI to be destroyed) */
        }

        g_mutex_unlock (&th.mutex);
    }

    close (th.fd);
    g_mutex_clear (&th.mutex);
    return th.rc;
}
Exemple #13
0
/******************************************************
 * gst_v4l2src_grab_frame ():
 *   grab a frame for capturing
 * return value: GST_FLOW_OK, GST_FLOW_WRONG_STATE or GST_FLOW_ERROR
 ******************************************************/
GstFlowReturn
gst_v4l2src_grab_frame (GstV4l2Src * v4l2src, GstBuffer ** buf)
{
#define NUM_TRIALS 50
  GstV4l2Object *v4l2object;
  GstV4l2BufferPool *pool;
  gint32 trials = NUM_TRIALS;
  GstBuffer *pool_buffer;
  gboolean need_copy;
  gint ret;

  v4l2object = v4l2src->v4l2object;
  pool = v4l2src->pool;

  GST_DEBUG_OBJECT (v4l2src, "grab frame");

  for (;;) {
    if (v4l2object->can_poll_device) {
      ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
      if (G_UNLIKELY (ret < 0)) {
        if (errno == EBUSY)
          goto stopped;
        if (errno == ENXIO) {
          GST_DEBUG_OBJECT (v4l2src,
              "v4l2 device doesn't support polling. Disabling");
          v4l2object->can_poll_device = FALSE;
        } else {
          if (errno != EAGAIN && errno != EINTR)
            goto select_error;
        }
      }
    }

    pool_buffer = GST_BUFFER (gst_v4l2_buffer_pool_dqbuf (pool));
    if (pool_buffer)
      break;

    GST_WARNING_OBJECT (pool->v4l2elem, "trials=%d", trials);

    /* if the sync() got interrupted, we can retry */
    switch (errno) {
      case EINVAL:
      case ENOMEM:
        /* fatal */
        return GST_FLOW_ERROR;

      case EAGAIN:
      case EIO:
      case EINTR:
      default:
        /* try again, until too many trials */
        break;
    }

    /* check nr. of attempts to capture */
    if (--trials == -1) {
      goto too_many_trials;
    }
  }

  /* if we are handing out the last buffer in the pool, we need to make a
   * copy and bring the buffer back in the pool. */
  need_copy = v4l2src->always_copy
      || !gst_v4l2_buffer_pool_available_buffers (pool);

  if (G_UNLIKELY (need_copy)) {
    if (!v4l2src->always_copy) {
      GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, v4l2src,
          "running out of buffers, making a copy to reuse current one");
    }
    *buf = gst_buffer_copy (pool_buffer);
    GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY);
    /* this will requeue */
    gst_buffer_unref (pool_buffer);
  } else {
    *buf = pool_buffer;
  }
  /* we set the buffer metadata in gst_v4l2src_create() */

  return GST_FLOW_OK;

  /* ERRORS */
select_error:
  {
    GST_ELEMENT_ERROR (pool->v4l2elem, RESOURCE, READ, (NULL),
        ("select error %d: %s (%d)", ret, g_strerror (errno), errno));
    return GST_FLOW_ERROR;
  }
stopped:
  {
    GST_DEBUG ("stop called");
    return GST_FLOW_WRONG_STATE;
  }
too_many_trials:
  {
    GST_ELEMENT_ERROR (pool->v4l2elem, RESOURCE, FAILED,
        (_("Failed trying to get video frames from device '%s'."),
            v4l2object->videodev),
        (_("Failed after %d tries. device %s. system error: %s"),
            NUM_TRIALS, v4l2object->videodev, g_strerror (errno)));
    return GST_FLOW_ERROR;
  }
}
Exemple #14
0
static void
gftp_read_bookmarks (char *global_data_path)
{
  char *tempstr, *temp1str, buf[255], *curpos;
  gftp_config_vars * global_entry;
  gftp_bookmarks_var * newentry;
  FILE *bmfile;
  size_t len;
  int line;

  if ((tempstr = gftp_expand_path (NULL, BOOKMARKS_FILE)) == NULL)
    {
      printf (_("gFTP Error: Bad bookmarks file name %s\n"), BOOKMARKS_FILE);
      exit (EXIT_FAILURE);
    }

  if (access (tempstr, F_OK) == -1)
    {
      temp1str = g_strdup_printf ("%s/bookmarks", global_data_path);
      if (access (temp1str, F_OK) == -1)
	{
	  printf (_("Warning: Cannot find master bookmark file %s\n"),
		  temp1str);
	  g_free (temp1str);
	  return;
	}
      copyfile (temp1str, tempstr);
      g_free (temp1str);
    }

  if ((bmfile = fopen (tempstr, "r")) == NULL)
    {
      printf (_("gFTP Error: Cannot open bookmarks file %s: %s\n"), tempstr,
	      g_strerror (errno));
      exit (EXIT_FAILURE);
    }
  g_free (tempstr);

  line = 0;
  newentry = NULL;
  while (fgets (buf, sizeof (buf), bmfile))
    {
      len = strlen (buf);
      if (len > 0 && buf[len - 1] == '\n')
        buf[--len] = '\0';
      if (len > 0 && buf[len - 1] == '\r')
        buf[--len] = '\0';
      line++;

      if (*buf == '[')
	{
	  newentry = g_malloc0 (sizeof (*newentry));
          for (; buf[len - 1] == ' ' || buf[len - 1] == ']'; buf[--len] = '\0');
	  newentry->path = g_strdup (buf + 1);
	  newentry->isfolder = 0;
	  gftp_add_bookmark (newentry);
	}
      else if (strncmp (buf, "hostname", 8) == 0 && newentry)
	{
	  curpos = buf + 9;
	  if (newentry->hostname)
	    g_free (newentry->hostname);
	  newentry->hostname = g_strdup (curpos);
	}
      else if (strncmp (buf, "port", 4) == 0 && newentry)
	newentry->port = strtol (buf + 5, NULL, 10);
      else if (strncmp (buf, "protocol", 8) == 0 && newentry)
	{
	  curpos = buf + 9;
	  if (newentry->protocol)
	    g_free (newentry->protocol);
	  newentry->protocol = g_strdup (curpos);
	}
      else if (strncmp (buf, "remote directory", 16) == 0 && newentry)
	{
	  curpos = buf + 17;
	  if (newentry->remote_dir)
	    g_free (newentry->remote_dir);
	  newentry->remote_dir = g_strdup (curpos);
	}
      else if (strncmp (buf, "local directory", 15) == 0 && newentry)
	{
	  curpos = buf + 16;
	  if (newentry->local_dir)
	    g_free (newentry->local_dir);
	  newentry->local_dir = g_strdup (curpos);
	}
      else if (strncmp (buf, "username", 8) == 0 && newentry)
	{
	  curpos = buf + 9;
	  if (newentry->user)
	    g_free (newentry->user);
	  newentry->user = g_strdup (curpos);
	}
      else if (strncmp (buf, "password", 8) == 0 && newentry)
	{
	  curpos = buf + 9;
	  if (newentry->pass)
	    g_free (newentry->pass);

	  /* Always try to descramble passords. If the password is not
             scrambled, descramble_password returns the string unchanged */
	  newentry->pass = gftp_descramble_password (curpos);
	  newentry->save_password = *newentry->pass != '\0';
	}
      else if (strncmp (buf, "account", 7) == 0 && newentry)
	{
	  curpos = buf + 8;
	  if (newentry->acct)
	    g_free (newentry->acct);
	  newentry->acct = g_strdup (curpos);
	}
      else if (*buf == '#' || *buf == '\0')
        continue;
      else
        {
          if ((curpos = strchr (buf, '=')) == NULL)
            continue;
          *curpos = '\0';

          if ((global_entry = g_hash_table_lookup (gftp_global_options_htable,
                                                   buf)) == NULL ||
               gftp_option_types[global_entry->otype].read_function == NULL)
            {
	      printf (_("gFTP Warning: Skipping line %d in bookmarks file: %s\n"),
                      line, buf);
              continue;
            }

          if (newentry->local_options_hash == NULL)
            newentry->local_options_hash = g_hash_table_new (string_hash_function,
                                                             string_hash_compare);

          newentry->num_local_options_vars++;
          newentry->local_options_vars = g_realloc (newentry->local_options_vars,
                                                    (gulong) sizeof (gftp_config_vars) * newentry->num_local_options_vars);

          memcpy (&newentry->local_options_vars[newentry->num_local_options_vars - 1], global_entry, 
                  sizeof (newentry->local_options_vars[newentry->num_local_options_vars - 1]));

          newentry->local_options_vars[newentry->num_local_options_vars - 1].flags &= ~GFTP_CVARS_FLAGS_DYNMEM;
          newentry->local_options_vars[newentry->num_local_options_vars - 1].value = NULL;

          if (gftp_option_types[global_entry->otype].read_function (curpos + 1,
                                &newentry->local_options_vars[newentry->num_local_options_vars - 1], line) != 0)
            {
	      printf (_("gFTP Warning: Skipping line %d in bookmarks file: %s\n"),
                      line, buf);
              continue;
            }

          g_hash_table_insert (newentry->local_options_hash, newentry->local_options_vars[newentry->num_local_options_vars - 1].key, &newentry->local_options_vars[newentry->num_local_options_vars - 1]);
        }
    }
}
GList *
get_interface_list(int *err, char **err_str)
{
#ifdef HAVE_PCAP_FINDALLDEVS
	return get_interface_list_findalldevs(err, err_str);
#else
	GList  *il = NULL;
	gint    nonloopback_pos = 0;
	struct  ifreq *ifr, *last;
	struct  ifconf ifc;
	struct  ifreq ifrflags;
	int     sock = socket(AF_INET, SOCK_DGRAM, 0);
	struct search_user_data user_data;
	pcap_t *pch;
	int len, lastlen;
	char *buf;
	if_info_t *if_info;
	char errbuf[PCAP_ERRBUF_SIZE];
	gboolean loopback;

	if (sock < 0) {
		*err = CANT_GET_INTERFACE_LIST;
		if (err_str != NULL) {
			*err_str = g_strdup_printf(
			    "Can't get list of interfaces: error opening socket: %s",
			    g_strerror(errno));
		}
		return NULL;
	}

	/*
	 * This code came from: W. Richard Stevens: "UNIX Network Programming",
	 * Networking APIs: Sockets and XTI, Vol 1, page 434.
	 */
	lastlen = 0;
	len = 100 * sizeof(struct ifreq);
	for ( ; ; ) {
		buf = g_malloc(len);
		ifc.ifc_len = len;
		ifc.ifc_buf = buf;
		memset (buf, 0, len);
		if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
			if (errno != EINVAL || lastlen != 0) {
				if (err_str != NULL) {
					*err_str = g_strdup_printf(
					    "Can't get list of interfaces: SIOCGIFCONF ioctl error: %s",
					    g_strerror(errno));
				}
				goto fail;
			}
		} else {
			if ((unsigned int) ifc.ifc_len < sizeof(struct ifreq)) {
				if (err_str != NULL) {
					*err_str = g_strdup(
					    "Can't get list of interfaces: SIOCGIFCONF ioctl gave too small return buffer");
				}
				goto fail;
			}
			if (ifc.ifc_len == lastlen)
				break;			/* success, len has not changed */
			lastlen = ifc.ifc_len;
		}
		len += 10 * sizeof(struct ifreq);	/* increment */
		g_free(buf);
	}
	ifr = (struct ifreq *) ifc.ifc_req;
	last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
	while (ifr < last) {
		/*
		 * Skip entries that begin with "dummy", or that include
		 * a ":" (the latter are Solaris virtuals).
		 */
		if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
		    strchr(ifr->ifr_name, ':') != NULL)
			goto next;

		/*
		 * If we already have this interface name on the list,
		 * don't add it, but, if we don't already have an IP
		 * address for it, add that address (SIOCGIFCONF returns,
		 * at least on BSD-flavored systems, one entry per
		 * interface *address*; if an interface has multiple
		 * addresses, we get multiple entries for it).
		 */
		user_data.name = ifr->ifr_name;
		user_data.if_info = NULL;
		g_list_foreach(il, search_for_if_cb, &user_data);
		if (user_data.if_info != NULL) {
			if_info_add_address(user_data.if_info, &ifr->ifr_addr);
			goto next;
		}

		/*
		 * Get the interface flags.
		 */
		memset(&ifrflags, 0, sizeof ifrflags);
		g_strlcpy(ifrflags.ifr_name, ifr->ifr_name,
		    sizeof ifrflags.ifr_name);
		if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
			if (errno == ENXIO)
				goto next;
			if (err_str != NULL) {
				*err_str = g_strdup_printf(
				    "Can't get list of interfaces: SIOCGIFFLAGS error getting flags for interface %s: %s",
				    ifr->ifr_name, g_strerror(errno));
			}
			goto fail;
		}

		/*
		 * Skip interfaces that aren't up.
		 */
		if (!(ifrflags.ifr_flags & IFF_UP))
			goto next;

		/*
		 * Skip interfaces that we can't open with "libpcap".
		 * Open with the minimum packet size - it appears that the
		 * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
		 * supplied is too large, rather than just truncating it.
		 */
		pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
		    errbuf);
		if (pch == NULL)
			goto next;
		pcap_close(pch);

		/*
		 * If it's a loopback interface, add it at the end of the
		 * list, otherwise add it after the last non-loopback
		 * interface, so all loopback interfaces go at the end - we
		 * don't want a loopback interface to be the default capture
		 * device unless there are no non-loopback devices.
		 */
		loopback = ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
		    strncmp(ifr->ifr_name, "lo", 2) == 0);
		if_info = if_info_new(ifr->ifr_name, NULL, loopback);
		if_info_add_address(if_info, &ifr->ifr_addr);
		if (loopback)
			il = g_list_append(il, if_info);
		else {
			il = g_list_insert(il, if_info, nonloopback_pos);
			/*
			 * Insert the next non-loopback interface after this
			 * one.
			 */
			nonloopback_pos++;
		}

	next:
#ifdef HAVE_SA_LEN
		ifr = (struct ifreq *) ((char *) ifr +
		    (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr) ?
			ifr->ifr_addr.sa_len : sizeof(ifr->ifr_addr)) +
		    IFNAMSIZ);
#else
		ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
#endif
	}

#ifdef linux
	/*
	 * OK, maybe we have support for the "any" device, to do a cooked
	 * capture on all interfaces at once.
	 * Try opening it and, if that succeeds, add it to the end of
	 * the list of interfaces.
	 */
	pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, errbuf);
	if (pch != NULL) {
		/*
		 * It worked; we can use the "any" device.
		 */
		if_info = if_info_new("any",
		    "Pseudo-device that captures on all interfaces", FALSE);
		il = g_list_insert(il, if_info, -1);
		pcap_close(pch);
	}
#endif

	g_free(ifc.ifc_buf);
	close(sock);

	if (il == NULL) {
		/*
		 * No interfaces found.
		 */
		*err = NO_INTERFACES_FOUND;
		if (err_str != NULL)
			*err_str = NULL;
	}
	return il;

fail:
	if (il != NULL)
		free_interface_list(il);
	g_free(ifc.ifc_buf);
	close(sock);
	*err = CANT_GET_INTERFACE_LIST;
	return NULL;
#endif /* HAVE_PCAP_FINDALLDEVS */
}
Exemple #16
0
static gsize get_mpeg2ts_segment (RequestData *request_data, EncoderOutput *encoder_output, gchar **buf)
{
        GstClockTime timestamp;
        gchar *header, *path, *file;
        guint64 rap_addr;
        gsize buf_size;
        GError *err = NULL;

        /* dvr segment */
        if (g_str_has_prefix (request_data->uri, "/dvr/")) {
                file = g_path_get_basename (request_data->uri);
                path = g_strdup_printf ("%s/%s", encoder_output->record_path, file);
                g_free (file);
                if (!g_file_get_contents (path, &file, &buf_size, &err)) {
                        GST_WARNING ("read %s failure: %s", path, err->message);
                        g_free (path);
                        g_error_free (err);
                        return 0;
                }
                header = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "video/mpeg", buf_size, CACHE_60s, "");
                *buf = g_malloc (buf_size + strlen (header));
                memcpy (*buf, header, strlen (header));
                memcpy (*buf + strlen (header), file, buf_size);
                g_free (header);
                g_free (file); 
                return buf_size;
        }

        /* live segment */
        sscanf (request_data->uri, "/live/%*[^/]/encoder/%*[^/]/%lu.ts", &timestamp);
        if (sem_wait (encoder_output->semaphore) == -1) {
                GST_WARNING ("get_mpeg2ts_segment sem_wait failure: %s", g_strerror (errno));
                return 0;
        }
        /* seek gop */
        rap_addr = encoder_output_gop_seek (encoder_output, timestamp);
        if (rap_addr != G_MAXUINT64) {
                /* segment found, send it */
                gsize gop_size;

                gop_size = encoder_output_gop_size (encoder_output, rap_addr);
                header = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "video/mpeg", gop_size, CACHE_60s, "");
                *buf = g_malloc (strlen (header) + gop_size);
                memcpy (*buf, header, strlen(header));
                if (rap_addr + gop_size + 12 < encoder_output->cache_size) {
                        memcpy (*buf + strlen (header), encoder_output->cache_addr + rap_addr + 12, gop_size);

                } else {
                        gint n;

                        n = encoder_output->cache_size - rap_addr - 12;
                        memcpy (*buf + strlen (header), encoder_output->cache_addr + rap_addr + 12, n);
                        memcpy (*buf + strlen (header) + n, encoder_output->cache_addr, gop_size - n);
                }
                buf_size = strlen (header) + gop_size;
                g_free (header);

        } else {
                /* segment not found */
                GST_WARNING ("segment not found: %s", request_data->uri);
                *buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
                buf_size = strlen (*buf);
        }
        sem_post (encoder_output->semaphore);

        return buf_size;
}
Exemple #17
0
static gboolean
dbx_read_mail_body (DbxImporter *m,
                    guint32 offset,
                    gint bodyfd)
{
	/* FIXME: We really ought to set up CamelStream that we can feed to the
	 * MIME parser, rather than using a temporary file */

	struct _dbx_block_hdrstruct hdr;
	guint32 buflen = 0x200;
	guchar *buffer = g_malloc (buflen);

	if (ftruncate (bodyfd, 0) == -1)
		g_warning ("%s: Failed to truncate file: %s", G_STRFUNC, g_strerror (errno));
	lseek (bodyfd, 0, SEEK_SET);

	while (offset) {
		d (printf ("Reading mail data chunk from %x\n", offset));

		if (dbx_pread (m->dbx_fd, &hdr, sizeof (hdr), offset) != sizeof (hdr)) {
			g_set_error (
				&m->base.error,
				CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				"Failed to read mail data block from "
				"DBX file at offset %x", offset);
			return FALSE;
		}
		hdr.self = GUINT32_FROM_LE (hdr.self);
		hdr.blocksize = GUINT16_FROM_LE (hdr.blocksize);
		hdr.nextaddress = GUINT32_FROM_LE (hdr.nextaddress);

		if (hdr.self != offset) {
			g_set_error (
				&m->base.error,
				CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				"Corrupt DBX file: Mail data block at "
				"0x%x does not point to itself", offset);
			return FALSE;
		}

		if (hdr.blocksize > buflen) {
			g_free (buffer);
			buflen = hdr.blocksize;
			buffer = g_malloc (buflen);
		}
		if (dbx_pread (m->dbx_fd, buffer, hdr.blocksize,
			offset + sizeof (hdr)) != hdr.blocksize) {
			g_set_error (
				&m->base.error,
				CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				"Failed to read mail data from DBX file "
				"at offset %lx",
				(long)(offset + sizeof (hdr)));
			return FALSE;
		}
		if (write (bodyfd, buffer, hdr.blocksize) != hdr.blocksize) {
			g_set_error (
				&m->base.error,
				CAMEL_ERROR, CAMEL_ERROR_GENERIC,
				"Failed to write mail data to temporary file");
			return FALSE;
		}
		offset = hdr.nextaddress;
	}
	return TRUE;
}
Exemple #18
0
static GstClockTime http_request_process (HTTPStreaming *httpstreaming, RequestData *request_data)
{
        EncoderOutput *encoder_output;
        GstClock *system_clock = httpstreaming->httpserver->system_clock;
        HTTPStreamingPrivateData *priv_data;
        gchar *buf = NULL;
        gsize buf_size;
        gint ret;
        gboolean is_http_progress_play_request = FALSE;

        encoder_output = gstreamill_get_encoder_output (httpstreaming->gstreamill, request_data->uri);
        if (encoder_output == NULL) {
                buf = request_crossdomain (request_data);
                /* not crossdomain request if buf == NULL */
                if ((buf == NULL) && g_str_has_suffix (request_data->uri, "playlist.m3u8")) {
                        buf = request_master_m3u8_playlist (httpstreaming, request_data);
                }
                /* not master m3u8 playlist request if buf == NULL */
                if (buf == NULL) {
                        buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
                }
                buf_size = strlen (buf);

        } else if (!is_encoder_output_ready (encoder_output)) {
                /* not ready */
                GST_DEBUG ("%s not ready.", request_data->uri);
                buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
                buf_size = strlen (buf);

        } else if (g_str_has_suffix (request_data->uri, ".ts")) {
                /* get mpeg2 transport stream segment */
                buf_size = get_mpeg2ts_segment (request_data, encoder_output, &buf);

        } else if (g_str_has_suffix (request_data->uri, "playlist.m3u8")) {
                /* get m3u8 playlist */
                gchar *m3u8playlist;

                m3u8playlist = get_m3u8playlist (request_data, encoder_output);
                if (m3u8playlist == NULL) {
                        buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);

                } else {
                        buf = g_strdup_printf (http_200,
                                       PACKAGE_NAME,
                                       PACKAGE_VERSION,
                                       "application/vnd.apple.mpegurl",
                                       strlen (m3u8playlist),
                                       CACHE_60s,
                                       m3u8playlist);
                        g_free (m3u8playlist);
                }
                buf_size = strlen (buf);

        } else if (is_http_progress_play_url (request_data)) {
                /* http progressive streaming request */
                GST_INFO ("Play %s.", request_data->uri);
                buf = g_strdup_printf (http_chunked, PACKAGE_NAME, PACKAGE_VERSION);
                buf_size = strlen (buf);
                is_http_progress_play_request = TRUE;

        } else {
                buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
                buf_size = strlen (buf);
        }

        /* write out buf */
        ret = write (request_data->sock, buf, buf_size);
        if (((ret > 0) && (ret != buf_size)) || ((ret == -1) && (errno == EAGAIN))) {
                /* send not completed or socket block, resend late */
                priv_data = (HTTPStreamingPrivateData *)g_malloc (sizeof (HTTPStreamingPrivateData));
                priv_data->buf = buf;
                priv_data->buf_size = buf_size;
                priv_data->job = NULL;
                priv_data->send_position = ret > 0? ret : 0;
                priv_data->encoder_output = encoder_output;
                request_data->priv_data = priv_data;
                if (is_http_progress_play_request) {
                        http_progress_play_priv_data_init (httpstreaming, request_data, priv_data);
                        priv_data->rap_addr = *(encoder_output->last_rap_addr);
                }
                return ret > 0? 10 * GST_MSECOND + g_random_int_range (1, 1000000) : GST_CLOCK_TIME_NONE;

        } else if (ret == -1) {
                GST_ERROR ("Write sock error: %s", g_strerror (errno));
        }

        /* send complete or socket error */
        g_free (buf);
        if ((is_http_progress_play_request) && (ret == buf_size)) {
                /* http progress play request and send complete */
                priv_data = (HTTPStreamingPrivateData *)g_malloc (sizeof (HTTPStreamingPrivateData));
                http_progress_play_priv_data_init (httpstreaming, request_data, priv_data);
                priv_data->encoder_output = encoder_output;
                priv_data->rap_addr = *(encoder_output->last_rap_addr);
                priv_data->send_position = *(encoder_output->last_rap_addr) + 12;
                priv_data->buf = NULL;
                request_data->priv_data = priv_data;
                return gst_clock_get_time (system_clock);
        }
        if (encoder_output != NULL) {
                gstreamill_unaccess (httpstreaming->gstreamill, request_data->uri);
        }
        return 0;
}
Exemple #19
0
static void
output_image (gpointer key, gpointer value, gpointer user_data)
{
	MonoImage *image = (MonoImage*)key;
	PerImageData *image_data = (PerImageData*)value;
	MonoProfiler *prof = (MonoProfiler*)user_data;
	char *tmp, *outfile_name;
	FILE *outfile;
	int i, err;
	ForeachData data;

	tmp = g_strdup_printf ("%s/.mono/aot-profile-data", g_get_home_dir ());

	if (!g_file_test (tmp, G_FILE_TEST_IS_DIR)) {
#ifdef HOST_WIN32
		err = mkdir (tmp);
#else
		err = mkdir (tmp, 0777);
#endif
		if (err) {
			fprintf (stderr, "mono-profiler-aot: Unable to create output directory '%s': %s\n", tmp, g_strerror (errno));
			exit (1);
		}
	}

	i = 0;
	while (TRUE) {
		outfile_name = g_strdup_printf ("%s/%s-%d", tmp, mono_image_get_name (image), i);

		if (!g_file_test (outfile_name, G_FILE_TEST_IS_REGULAR))
			break;

		i ++;
	}

	printf ("Creating output file: %s\n", outfile_name);

	outfile = fopen (outfile_name, "w+");
	g_assert (outfile);

	fprintf (outfile, "#VER:%d\n", 2);

	data.prof = prof;
	data.outfile = outfile;
	data.image = image;

	g_list_foreach (image_data->methods, foreach_method, &data);
}
Exemple #20
0
static GstClockTime http_continue_process (HTTPStreaming *httpstreaming, RequestData *request_data)
{
        HTTPStreamingPrivateData *priv_data;
        EncoderOutput *encoder_output;
        GstClock *system_clock = httpstreaming->httpserver->system_clock;
        gint ret;

        priv_data = request_data->priv_data;
        encoder_output = priv_data->encoder_output;
        if (priv_data->buf != NULL) {
                ret = write (request_data->sock,
                             priv_data->buf + priv_data->send_position,
                             priv_data->buf_size - priv_data->send_position);
                /* send complete or send error */
                if ((ret + priv_data->send_position == priv_data->buf_size) ||
                    ((ret == -1) && (errno != EAGAIN))) {
                        if ((ret == -1) && (errno != EAGAIN)) {
                                GST_ERROR ("Write sock error: %s", g_strerror (errno));
                        }
                        g_free (priv_data->buf);
                        priv_data->buf = NULL;
                        /* progressive play? continue */
                        if (is_http_progress_play_url (request_data)) {
                                priv_data->send_position = *(encoder_output->last_rap_addr) + 12;
                                priv_data->buf = NULL;
                                return gst_clock_get_time (system_clock);
                        }
                        if (encoder_output != NULL) {
                                gstreamill_unaccess (httpstreaming->gstreamill, request_data->uri);
                        }
                        if (priv_data->job != NULL) {
                                g_object_unref (priv_data->job);
                        }
                        g_free (priv_data);
                        request_data->priv_data = NULL;
                        return 0;

                } else if ((ret > 0) || ((ret == -1) && (errno == EAGAIN))) {
                        /* send not completed or socket block, resend late */
                        priv_data->send_position += ret > 0? ret : 0;
                        return ret > 0? 10 * GST_MSECOND + g_random_int_range (1, 1000000) : GST_CLOCK_TIME_NONE;
                }
        }
        if ((priv_data->livejob_age != priv_data->job->age) ||
            (*(priv_data->job->output->state) != JOB_STATE_PLAYING)) {
                if (priv_data->encoder_output != NULL) {
                        gstreamill_unaccess (httpstreaming->gstreamill, request_data->uri);
                }
                if (priv_data->job != NULL) {
                        g_object_unref (priv_data->job);
                }
                g_free (request_data->priv_data);
                request_data->priv_data = NULL;
                return 0;
        }
        if (priv_data->send_position == *(encoder_output->tail_addr)) {
                /* no more stream, wait 10ms */
                GST_DEBUG ("current:%lu == tail:%lu", priv_data->send_position, *(encoder_output->tail_addr));
                return gst_clock_get_time (system_clock) + 500 * GST_MSECOND + g_random_int_range (1, 1000000);
        }
        return send_chunk (encoder_output, request_data) + gst_clock_get_time (system_clock);
}
Exemple #21
0
static void process_exec(PROCESS_REC *rec, const char *cmd)
{
	const char *shell_args[4] = { "/bin/sh", "-c", NULL, NULL };
        char **args;
	int in[2], out[2];
        int n;

	if (pipe(in) == -1)
                return;
	if (pipe(out) == -1)
		return;

	shell_args[2] = cmd;
	rec->pid = fork();
	if (rec->pid == -1) {
                /* error */
		close(in[0]); close(in[1]);
                close(out[0]); close(out[1]);
		return;
	}

	if (rec->pid != 0) {
		/* parent process */
                GIOChannel *outio = g_io_channel_unix_new(in[1]);

		rec->in = g_io_channel_unix_new(out[0]);
		rec->out = net_sendbuffer_create(outio, 0);

                close(out[1]);
		close(in[0]);
		pidwait_add(rec->pid);
                return;
	}

	/* child process, try to clean up everything */
	setsid();
	setuid(getuid());
	setgid(getgid());
	signal(SIGINT, SIG_IGN);
	signal(SIGQUIT, SIG_DFL);

	putenv("TERM=tty");

	/* set stdin, stdout and stderr */
        dup2(in[0], STDIN_FILENO);
        dup2(out[1], STDOUT_FILENO);
	dup2(out[1], STDERR_FILENO);

        /* don't let child see our files */
	for (n = 3; n < 256; n++)
                close(n);

	if (rec->shell) {
		execvp(shell_args[0], (char **) shell_args);

		fprintf(stderr, "Exec: /bin/sh: %s\n", g_strerror(errno));
	} else {
		args = g_strsplit(cmd, " ", -1);
                execvp(args[0], args);

		fprintf(stderr, "Exec: %s: %s\n", args[0], g_strerror(errno));
	}

	_exit(-1);
}
/* this internal thread does nothing else but write samples to the audio device.
 * It will write each segment in the ringbuffer and will update the play
 * pointer.
 * The start/stop methods control the thread.
 */
static void
audioringbuffer_thread_func (GstAudioRingBuffer * buf)
{
    GstAudioSink *sink;
    GstAudioSinkClass *csink;
    GstAudioSinkRingBuffer *abuf = GST_AUDIO_SINK_RING_BUFFER_CAST (buf);
    WriteFunc writefunc;
    GstMessage *message;
    GValue val = { 0 };

    sink = GST_AUDIO_SINK (GST_OBJECT_PARENT (buf));
    csink = GST_AUDIO_SINK_GET_CLASS (sink);

    GST_DEBUG_OBJECT (sink, "enter thread");

    GST_OBJECT_LOCK (abuf);
    GST_DEBUG_OBJECT (sink, "signal wait");
    GST_AUDIO_SINK_RING_BUFFER_SIGNAL (buf);
    GST_OBJECT_UNLOCK (abuf);

    writefunc = csink->write;
    if (writefunc == NULL)
        goto no_function;

    message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
              GST_STREAM_STATUS_TYPE_ENTER, GST_ELEMENT_CAST (sink));
    g_value_init (&val, GST_TYPE_G_THREAD);
    g_value_set_boxed (&val, g_thread_self ());
    gst_message_set_stream_status_object (message, &val);
    g_value_unset (&val);
    GST_DEBUG_OBJECT (sink, "posting ENTER stream status");
    gst_element_post_message (GST_ELEMENT_CAST (sink), message);

    while (TRUE) {
        gint left, len;
        guint8 *readptr;
        gint readseg;

        /* buffer must be started */
        if (gst_audio_ring_buffer_prepare_read (buf, &readseg, &readptr, &len)) {
            gint written;

            left = len;
            do {
                written = writefunc (sink, readptr, left);
                GST_LOG_OBJECT (sink, "transfered %d bytes of %d from segment %d",
                                written, left, readseg);
                if (written < 0 || written > left) {
                    /* might not be critical, it e.g. happens when aborting playback */
                    GST_WARNING_OBJECT (sink,
                                        "error writing data in %s (reason: %s), skipping segment (left: %d, written: %d)",
                                        GST_DEBUG_FUNCPTR_NAME (writefunc),
                                        (errno > 1 ? g_strerror (errno) : "unknown"), left, written);
                    break;
                }
                left -= written;
                readptr += written;
            } while (left > 0);

            /* clear written samples */
            gst_audio_ring_buffer_clear (buf, readseg);

            /* we wrote one segment */
            gst_audio_ring_buffer_advance (buf, 1);
        } else {
            GST_OBJECT_LOCK (abuf);
            if (!abuf->running)
                goto stop_running;
            if (G_UNLIKELY (g_atomic_int_get (&buf->state) ==
                            GST_AUDIO_RING_BUFFER_STATE_STARTED)) {
                GST_OBJECT_UNLOCK (abuf);
                continue;
            }
            GST_DEBUG_OBJECT (sink, "signal wait");
            GST_AUDIO_SINK_RING_BUFFER_SIGNAL (buf);
            GST_DEBUG_OBJECT (sink, "wait for action");
            GST_AUDIO_SINK_RING_BUFFER_WAIT (buf);
            GST_DEBUG_OBJECT (sink, "got signal");
            if (!abuf->running)
                goto stop_running;
            GST_DEBUG_OBJECT (sink, "continue running");
            GST_OBJECT_UNLOCK (abuf);
        }
    }

    /* Will never be reached */
    g_assert_not_reached ();
    return;

    /* ERROR */
no_function:
    {
        GST_DEBUG_OBJECT (sink, "no write function, exit thread");
        return;
    }
stop_running:
    {
        GST_OBJECT_UNLOCK (abuf);
        GST_DEBUG_OBJECT (sink, "stop running, exit thread");
        message = gst_message_new_stream_status (GST_OBJECT_CAST (buf),
                  GST_STREAM_STATUS_TYPE_LEAVE, GST_ELEMENT_CAST (sink));
        g_value_init (&val, GST_TYPE_G_THREAD);
        g_value_set_boxed (&val, g_thread_self ());
        gst_message_set_stream_status_object (message, &val);
        g_value_unset (&val);
        GST_DEBUG_OBJECT (sink, "posting LEAVE stream status");
        gst_element_post_message (GST_ELEMENT_CAST (sink), message);
        return;
    }
}
/* Adapted from auditd auditd-event.c */
static gboolean
open_log_file (const char *filename,
               int        *fdp,
               FILE      **filep)
{
        int      flags;
        int      fd;
        FILE    *file;
        gboolean ret;

        ret = FALSE;

        /*
         * Likely errors on rotate: ENFILE, ENOMEM, ENOSPC
         */
        flags = O_WRONLY | O_APPEND;
#ifdef O_NOFOLLOW
        flags |= O_NOFOLLOW;
#endif

retry:
        fd = g_open (filename, flags, 0600);
        if (fd < 0) {
                if (errno == ENOENT) {
                        /* FIXME: should we just skip if file doesn't exist? */
                        fd = g_open (filename,
                                     O_CREAT | O_EXCL | O_APPEND,
                                     S_IRUSR | S_IWUSR | S_IRGRP);
                        if (fd < 0) {
                                g_warning ("Couldn't create log file %s (%s)",
                                           filename,
                                           g_strerror (errno));
                                goto out;
                        }

                        close (fd);
                        fd = g_open (filename, flags, 0600);
                } else if (errno == ENFILE) {
                        /* All system descriptors used, try again... */
                        goto retry;
                }
                if (fd < 0) {
                        g_warning ("Couldn't open log file %s (%s)",
                                   filename,
                                   g_strerror (errno));
                        goto out;
                }
        }

        if (fcntl (fd, F_SETFD, FD_CLOEXEC) == -1) {
                close (fd);
                g_warning ("Error setting log file CLOEXEC flag (%s)",
                           g_strerror (errno));
                goto out;
        }

        if (fchown (fd, 0, 0) == -1) {
                g_warning ("Error changing owner of log file (%s)",
                           g_strerror (errno));
        }

        file = fdopen (fd, "a");
        if (file == NULL) {
                g_warning ("Error setting up log descriptor (%s)",
                           g_strerror (errno));
                close (fd);
                goto out;
        }

        /* Set it to line buffering */
        setlinebuf (file);

        ret = TRUE;

        if (fdp != NULL) {
                *fdp = fd;
        }
        if (filep != NULL) {
                *filep = file;
        }

 out:

        return ret;
}
Exemple #24
0
EvaDebugLog       *
eva_debug_log_open (const char *filename,
                    GError    **error)
{
  guint8 data[8];
  FILE *fp;
  EvaDebugLog *log;
  guint32 magic_le = GUINT32_TO_LE (EVA_DEBUG_LOG_PACKET_INIT);
  guint32 magic_be = GUINT32_TO_BE (EVA_DEBUG_LOG_PACKET_INIT);
  guint32 zeroes = 0;
  guint64 v;
  fp = fopen (filename, "rb");
  if (fp == NULL)
    {
      g_set_error (error,
                   EVA_G_ERROR_DOMAIN,
                   eva_error_code_from_errno (errno),
                   "error opening %s: %s", filename, g_strerror (errno));
      return NULL;
    }
  log = g_new (EvaDebugLog, 1);
  log->fp = fp;

  if (fread (data, 8, 1, fp) != 1)
    {
      g_set_error (error,
                   EVA_G_ERROR_DOMAIN,
                   EVA_ERROR_END_OF_FILE,
                   "error reading %s: too short", filename);
      return NULL;
    }
  if (memcmp (data, &magic_le, 4) == 0
   && memcmp (data + 4, "\4\3\2\1", 4) == 0)
    {
      log->little_endian = TRUE;
      log->is_64bit = FALSE;
    }
  else if (memcmp (data, &magic_be, 4) == 0
   && memcmp (data + 4, "\1\2\3\4", 4) == 0)
    {
      log->little_endian = FALSE;
      log->is_64bit = FALSE;
    }
  else if (memcmp (data, &zeroes, 4) == 0
   && memcmp (data + 4, &magic_be, 4) == 0)
    {
      log->little_endian = FALSE;
      log->is_64bit = TRUE;
    }
  else if (memcmp (data + 4, &zeroes, 4) == 0
        && memcmp (data, &magic_le, 4) == 0)
    {
      log->little_endian = TRUE;
      log->is_64bit = TRUE;
    }
  else
    {
      g_set_error (error,
                   EVA_G_ERROR_DOMAIN,
                   EVA_ERROR_BAD_FORMAT,
                   "magic invalid: cannot determine big/little 32/64 headers");
      g_free (log);
      fclose (fp);
      return NULL;
    }

  if (log->is_64bit)
    {
      /* read the \1\2\3\4 number */
      if (fread (data, 8, 1, fp) != 1)
        g_error ("debug-log-magic: too short");
      if (log->little_endian)
        g_assert (memcmp (data, "\4\3\2\1\0\0\0\0", 8) == 0);
      else
        g_assert (memcmp (data, "\0\0\0\0\4\3\2\1", 8) == 0);
    }
  if (!read_word (log, &v))
    g_error ("error reading version");
  g_assert (v == 0); /* version 0 only */
  if (!read_word (log, &v))
    g_error ("error reading timestamp");
  log->timestamp = v;
  return log;
}
Exemple #25
0
static void
save_state (void)
{
  char *metacity_dir;
  char *session_dir;
  FILE *outfile;
  GSList *windows;
  GSList *tmp;
  int stack_position;
  
  g_assert (client_id);

  outfile = NULL;
  
  /*
   * g_get_user_config_dir() is guaranteed to return an existing directory.
   * Eventually, if SM stays with the WM, I'd like to make this
   * something like <config>/window_placement in a standard format.
   * Future optimisers should note also that by the time we get here
   * we probably already have full_save_path figured out and therefore
   * can just use the directory name from that.
   */
  metacity_dir = g_strconcat (g_get_user_config_dir (),
                              G_DIR_SEPARATOR_S "metacity",
                              NULL);
  
  session_dir = g_strconcat (metacity_dir,
                             G_DIR_SEPARATOR_S "sessions",
                             NULL);

  if (mkdir (metacity_dir, 0700) < 0 &&
      errno != EEXIST)
    {
      meta_warning (_("Could not create directory '%s': %s\n"),
                    metacity_dir, g_strerror (errno));
    }

  if (mkdir (session_dir, 0700) < 0 &&
      errno != EEXIST)
    {
      meta_warning (_("Could not create directory '%s': %s\n"),
                    session_dir, g_strerror (errno));
    }

  meta_topic (META_DEBUG_SM, "Saving session to '%s'\n", full_save_file ());
  
  outfile = fopen (full_save_file (), "w");

  if (outfile == NULL)
    {
      meta_warning (_("Could not open session file '%s' for writing: %s\n"),
                    full_save_file (), g_strerror (errno));
      goto out;
    }

  /* The file format is:
   * <metacity_session id="foo">
   *   <window id="bar" class="XTerm" name="xterm" title="/foo/bar" role="blah" type="normal" stacking="5">
   *     <workspace index="2"/>
   *     <workspace index="4"/>
   *     <sticky/> <minimized/> <maximized/>
   *     <geometry x="100" y="100" width="200" height="200" gravity="northwest"/>
   *   </window>
   * </metacity_session>
   *
   * Note that attributes on <window> are the match info we use to
   * see if the saved state applies to a restored window, and
   * child elements are the saved state to be applied.
   * 
   */
  
  fprintf (outfile, "<metacity_session id=\"%s\">\n",
           client_id);

  windows = meta_display_list_windows (meta_get_display ());
  stack_position = 0;

  windows = g_slist_sort (windows, meta_display_stack_cmp);
  tmp = windows;
  stack_position = 0;

  while (tmp != NULL)
    {
      MetaWindow *window;

      window = tmp->data;

      if (window->sm_client_id)
        {
          char *sm_client_id;
          char *res_class;
          char *res_name;
          char *role;
          char *title;

          /* client id, class, name, role are not expected to be
           * in UTF-8 (I think they are in XPCS which is Latin-1?
           * in practice they are always ascii though.)
           */
              
          sm_client_id = encode_text_as_utf8_markup (window->sm_client_id);
          res_class = window->res_class ?
            encode_text_as_utf8_markup (window->res_class) : NULL;
          res_name = window->res_name ?
            encode_text_as_utf8_markup (window->res_name) : NULL;
          role = window->role ?
            encode_text_as_utf8_markup (window->role) : NULL;
          if (window->title)
            title = g_markup_escape_text (window->title, -1);
          else
            title = NULL;
              
          meta_topic (META_DEBUG_SM, "Saving session managed window %s, client ID '%s'\n",
                      window->desc, window->sm_client_id);

          fprintf (outfile,
                   "  <window id=\"%s\" class=\"%s\" name=\"%s\" title=\"%s\" role=\"%s\" type=\"%s\" stacking=\"%d\">\n",
                   sm_client_id,
                   res_class ? res_class : "",
                   res_name ? res_name : "",
                   title ? title : "",
                   role ? role : "",
                   window_type_to_string (window->type),
                   stack_position);

          g_free (sm_client_id);
          g_free (res_class);
          g_free (res_name);
          g_free (role);
          g_free (title);
              
          /* Sticky */
          if (window->on_all_workspaces)
            fputs ("    <sticky/>\n", outfile);

          /* Minimized */
          if (window->minimized)
            fputs ("    <minimized/>\n", outfile);

          /* Maximized */
          if (META_WINDOW_MAXIMIZED (window))
            {
              fprintf (outfile,
                       "    <maximized saved_x=\"%d\" saved_y=\"%d\" saved_width=\"%d\" saved_height=\"%d\"/>\n", 
                       window->saved_rect.x,
                       window->saved_rect.y,
                       window->saved_rect.width,
                       window->saved_rect.height);
            }
              
          /* Workspaces we're on */
          {
            int n;
            n = meta_workspace_index (window->workspace);
            fprintf (outfile,
                     "    <workspace index=\"%d\"/>\n", n);
          }

          /* Gravity */
          {
            int x, y, w, h;
            meta_window_get_geometry (window, &x, &y, &w, &h);
            
            fprintf (outfile,
                     "    <geometry x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" gravity=\"%s\"/>\n",
                     x, y, w, h,
                     meta_gravity_to_string (window->size_hints.win_gravity));
          }
              
          fputs ("  </window>\n", outfile);
        }
      else
        {
          meta_topic (META_DEBUG_SM, "Not saving window '%s', not session managed\n",
                      window->desc);
        }
          
      tmp = tmp->next;
      ++stack_position;
    }
      
  g_slist_free (windows);

  fputs ("</metacity_session>\n", outfile);
  
 out:
  if (outfile)
    {
      /* FIXME need a dialog for this */
      if (ferror (outfile))
        {
          meta_warning (_("Error writing session file '%s': %s\n"),
                        full_save_file (), g_strerror (errno));
        }
      if (fclose (outfile))
        {
          meta_warning (_("Error closing session file '%s': %s\n"),
                        full_save_file (), g_strerror (errno));
        }
    }
  
  g_free (metacity_dir);
  g_free (session_dir);
}
static void cache_etag_file_finish(liVRequest *vr, cache_etag_file *cfile) {
	close(cfile->fd);
	cfile->fd = -1;
	if (-1 == rename(cfile->tmpfilename->str, cfile->filename->str)) {
		VR_ERROR(vr, "Couldn't move temporary cache file '%s': '%s'", cfile->tmpfilename->str, g_strerror(errno));
		unlink(cfile->tmpfilename->str);
	}
	cache_etag_file_free(cfile);
}
gboolean
moov_recov_write_file (MoovRecovFile * moovrf, MdatRecovFile * mdatrf,
    FILE * outf, GError ** err)
{
  guint8 auxdata[16];
  guint8 *data = NULL;
  guint8 *prefix_data = NULL;
  guint8 *mvhd_data = NULL;
  guint8 *trak_data = NULL;
  guint32 moov_size = 0;
  gint i;
  guint64 stbl_children_size = 0;
  guint8 *stbl_children = NULL;
  guint32 longest_duration = 0;
  guint16 version;

  /* check the version */
  if (fseek (moovrf->file, 0, SEEK_SET) != 0) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
        "Failed to seek to the start of the moov recovery file");
    goto fail;
  }
  if (fread (auxdata, 1, 2, moovrf->file) != 2) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
        "Failed to read version from file");
  }

  version = GST_READ_UINT16_BE (auxdata);
  if (version != ATOMS_RECOV_FILE_VERSION) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_VERSION,
        "Input file version (%u) is not supported in this version (%u)",
        version, ATOMS_RECOV_FILE_VERSION);
    return FALSE;
  }

  /* write the ftyp */
  prefix_data = g_malloc (moovrf->prefix_size);
  if (fread (prefix_data, 1, moovrf->prefix_size,
          moovrf->file) != moovrf->prefix_size) {
    g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
        "Failed to read the ftyp atom from file");
    goto fail;
  }
  if (fwrite (prefix_data, 1, moovrf->prefix_size, outf) != moovrf->prefix_size) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }
  g_free (prefix_data);
  prefix_data = NULL;

  /* need to calculate the moov size beforehand to add the offset to
   * chunk offset entries */
  moov_size += moovrf->mvhd_size + 8;   /* mvhd + moov size + fourcc */
  for (i = 0; i < moovrf->num_traks; i++) {
    TrakRecovData *trak = &(moovrf->traks_rd[i]);
    guint32 duration;           /* in moov's timescale */
    guint32 trak_size;

    /* convert trak duration to moov's duration */
    duration = gst_util_uint64_scale_round (trak->duration, moovrf->timescale,
        trak->timescale);

    if (duration > longest_duration)
      longest_duration = duration;
    trak_size = trak_recov_data_get_trak_atom_size (trak);
    if (trak_size == 0) {
      g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_GENERIC,
          "Failed to estimate trak atom size");
      goto fail;
    }
    moov_size += trak_size;
  }

  /* add chunks offsets */
  for (i = 0; i < moovrf->num_traks; i++) {
    TrakRecovData *trak = &(moovrf->traks_rd[i]);
    /* 16 for the mdat header */
    gint64 offset = moov_size + ftell (outf) + 16;
    atom_stco64_chunks_add_offset (&trak->stbl.stco64, offset);
  }

  /* write the moov */
  GST_WRITE_UINT32_BE (auxdata, moov_size);
  GST_WRITE_UINT32_LE (auxdata + 4, FOURCC_moov);
  if (fwrite (auxdata, 1, 8, outf) != 8) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }

  /* write the mvhd */
  mvhd_data = g_malloc (moovrf->mvhd_size);
  if (fseek (moovrf->file, moovrf->mvhd_pos, SEEK_SET) != 0)
    goto fail;
  if (fread (mvhd_data, 1, moovrf->mvhd_size,
          moovrf->file) != moovrf->mvhd_size)
    goto fail;
  GST_WRITE_UINT32_BE (mvhd_data + 20, moovrf->timescale);
  GST_WRITE_UINT32_BE (mvhd_data + 24, longest_duration);
  if (fwrite (mvhd_data, 1, moovrf->mvhd_size, outf) != moovrf->mvhd_size) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }
  g_free (mvhd_data);
  mvhd_data = NULL;

  /* write the traks, this is the tough part because we need to update:
   * - stbl atom
   * - sizes of atoms from stbl to trak
   * - trak duration
   */
  for (i = 0; i < moovrf->num_traks; i++) {
    TrakRecovData *trak = &(moovrf->traks_rd[i]);
    guint trak_data_size;
    guint32 stbl_new_size;
    guint32 minf_new_size;
    guint32 mdia_new_size;
    guint32 trak_new_size;
    guint32 size_diff;
    guint32 duration;           /* in moov's timescale */

    /* convert trak duration to moov's duration */
    duration = gst_util_uint64_scale_round (trak->duration, moovrf->timescale,
        trak->timescale);

    stbl_children = moov_recov_get_stbl_children_data (moovrf, trak,
        &stbl_children_size);
    if (stbl_children == NULL)
      goto fail;

    /* calc the new size of the atoms from stbl to trak in the atoms tree */
    stbl_new_size = trak->stsd_size + stbl_children_size + 8;
    size_diff = stbl_new_size - trak->stbl_size;
    minf_new_size = trak->minf_size + size_diff;
    mdia_new_size = trak->mdia_size + size_diff;
    trak_new_size = trak->trak_size + size_diff;

    if (fseek (moovrf->file, trak->file_offset, SEEK_SET) != 0)
      goto fail;
    trak_data_size = trak->post_stsd_offset - trak->file_offset;
    trak_data = g_malloc (trak_data_size);
    if (fread (trak_data, 1, trak_data_size, moovrf->file) != trak_data_size) {
      goto fail;
    }
    /* update the size values in those read atoms before writing */
    GST_WRITE_UINT32_BE (trak_data, trak_new_size);
    GST_WRITE_UINT32_BE (trak_data + (trak->mdia_file_offset -
            trak->file_offset), mdia_new_size);
    GST_WRITE_UINT32_BE (trak_data + (trak->minf_file_offset -
            trak->file_offset), minf_new_size);
    GST_WRITE_UINT32_BE (trak_data + (trak->stbl_file_offset -
            trak->file_offset), stbl_new_size);

    /* update duration values in tkhd and mdhd */
    GST_WRITE_UINT32_BE (trak_data + (trak->tkhd_file_offset -
            trak->file_offset) + 28, duration);
    GST_WRITE_UINT32_BE (trak_data + (trak->mdhd_file_offset -
            trak->file_offset) + 24, trak->duration);

    if (fwrite (trak_data, 1, trak_data_size, outf) != trak_data_size) {
      ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
      goto fail;
    }
    if (fwrite (stbl_children, 1, stbl_children_size, outf) !=
        stbl_children_size) {
      ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
      goto fail;
    }
    g_free (trak_data);
    trak_data = NULL;
    g_free (stbl_children);
    stbl_children = NULL;
  }

  /* write the mdat */
  /* write the header first */
  GST_WRITE_UINT32_BE (auxdata, 1);
  GST_WRITE_UINT32_LE (auxdata + 4, FOURCC_mdat);
  GST_WRITE_UINT64_BE (auxdata + 8, mdatrf->mdat_size);
  if (fwrite (auxdata, 1, 16, outf) != 16) {
    ATOMS_RECOV_OUTPUT_WRITE_ERROR (err);
    goto fail;
  }

  /* now read the mdat data and output to the file */
  if (fseek (mdatrf->file, mdatrf->mdat_start +
          (mdatrf->rawfile ? 0 : mdatrf->mdat_header_size), SEEK_SET) != 0)
    goto fail;

  data = g_malloc (4096);
  while (!feof (mdatrf->file)) {
    gint read, write;

    read = fread (data, 1, 4096, mdatrf->file);
    write = fwrite (data, 1, read, outf);

    if (write != read) {
      g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
          "Failed to copy data to output file: %s", g_strerror (errno));
      goto fail;
    }
  }
  g_free (data);

  return TRUE;

fail:
  g_free (stbl_children);
  g_free (mvhd_data);
  g_free (prefix_data);
  g_free (trak_data);
  g_free (data);
  return FALSE;
}
static liHandlerResult cache_etag_filter_miss(liVRequest *vr, liFilter *f) {
	cache_etag_file *cfile = (cache_etag_file*) f->param;
	ssize_t res;
	gchar *buf;
	off_t buflen;
	liChunkIter citer;
	GError *err = NULL;

	if (NULL == f->in) {
		cache_etag_filter_free(vr, f);
		/* didn't handle f->in->is_closed? abort forwarding */
		if (!f->out->is_closed) li_stream_reset(&f->stream);
		return LI_HANDLER_GO_ON;
	}

	if (NULL == cfile) goto forward;

	if (f->in->length > 0) {
		citer = li_chunkqueue_iter(f->in);
		if (LI_HANDLER_GO_ON != li_chunkiter_read(citer, 0, 64*1024, &buf, &buflen, &err)) {
			if (NULL != err) {
				if (NULL != vr) VR_ERROR(vr, "Couldn't read data from chunkqueue: %s", err->message);
				g_error_free(err);
			} else {
				if (NULL != vr) VR_ERROR(vr, "%s", "Couldn't read data from chunkqueue");
			}
			cache_etag_filter_free(vr, f);
			goto forward;
		}

		res = write(cfile->fd, buf, buflen);
		if (res < 0) {
			switch (errno) {
			case EINTR:
			case EAGAIN:
				return LI_HANDLER_COMEBACK;
			default:
				if (NULL != vr) VR_ERROR(vr, "Couldn't write to temporary cache file '%s': %s",
					cfile->tmpfilename->str, g_strerror(errno));
				cache_etag_filter_free(vr, f);
				goto forward;
			}
		} else {
			if (!f->out->is_closed) {
				li_chunkqueue_steal_len(f->out, f->in, res);
			} else {
				li_chunkqueue_skip(f->in, res);
			}
		}
	}

	if (0 == f->in->length && f->in->is_closed) {
		f->out->is_closed = TRUE;
		f->param = NULL;
		cache_etag_file_finish(vr, cfile);
		return LI_HANDLER_GO_ON;
	}

	return LI_HANDLER_GO_ON;

forward:
	if (f->out->is_closed) {
		li_chunkqueue_skip_all(f->in);
		li_stream_disconnect(&f->stream);
	} else {
		li_chunkqueue_steal_all(f->out, f->in);
		if (f->in->is_closed) f->out->is_closed = f->in->is_closed;
	}
	return LI_HANDLER_GO_ON;
}
Exemple #29
0
static gboolean
g_unix_output_stream_writev (GOutputStream        *stream,
			     const GOutputVector  *vectors,
			     gsize                 n_vectors,
			     gsize                *bytes_written,
			     GCancellable         *cancellable,
			     GError              **error)
{
  GUnixOutputStream *unix_stream;
  gssize res = -1;
  GPollFD poll_fds[2];
  int nfds = 0;
  int poll_ret;
  struct iovec *iov;

  if (bytes_written)
    *bytes_written = 0;

  /* Clamp to G_MAXINT as writev() takes an integer for the number of vectors.
   * We handle this like a short write in this case
   */
  if (n_vectors > G_MAXINT)
    n_vectors = G_MAXINT;

  unix_stream = G_UNIX_OUTPUT_STREAM (stream);

  if (G_OUTPUT_VECTOR_IS_IOVEC)
    {
      /* ABI is compatible */
      iov = (struct iovec *) vectors;
    }
  else
    {
      gsize i;

      /* ABI is incompatible */
      iov = g_newa (struct iovec, n_vectors);
      for (i = 0; i < n_vectors; i++)
        {
          iov[i].iov_base = (void *)vectors[i].buffer;
          iov[i].iov_len = vectors[i].size;
        }
    }

  poll_fds[0].fd = unix_stream->priv->fd;
  poll_fds[0].events = G_IO_OUT;
  nfds++;

  if (unix_stream->priv->is_pipe_or_socket &&
      g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
    nfds++;

  while (1)
    {
      int errsv;

      poll_fds[0].revents = poll_fds[1].revents = 0;
      do
        {
          poll_ret = g_poll (poll_fds, nfds, -1);
          errsv = errno;
        }
      while (poll_ret == -1 && errsv == EINTR);

      if (poll_ret == -1)
	{
	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to file descriptor: %s"),
		       g_strerror (errsv));
	  break;
	}

      if (g_cancellable_set_error_if_cancelled (cancellable, error))
	break;

      if (!poll_fds[0].revents)
	continue;

      res = writev (unix_stream->priv->fd, iov, n_vectors);
      errsv = errno;
      if (res == -1)
	{
	  if (errsv == EINTR || errsv == EAGAIN)
	    continue;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to file descriptor: %s"),
		       g_strerror (errsv));
	}

      if (bytes_written)
        *bytes_written = res;

      break;
    }

  if (nfds == 2)
    g_cancellable_release_fd (cancellable);
  return res != -1;
}
static gsize get_mpeg2ts_segment (RequestData *request_data, EncoderOutput *encoder_output, gchar **buf)
{
    GstClockTime timestamp;
    gint number;
    guint64 year, month, mday, hour, sequence, duration, rap_addr, max_age;
    GstClockTime us; /* microseconds */
    struct tm tm;
    gchar date[20], *header, *path, *file, *cache_control;
    gsize buf_size;
    GError *err = NULL;
    struct timespec ts;

    number = sscanf (request_data->uri, "/%*[^/]/encoder/%*[^/]/%04lu%02lu%02lu%02lu/%lu_%lu_%lu.ts$",
            &year, &month, &mday, &hour, &us, &sequence, &duration);
    if (number != 7) {
        GST_WARNING ("uri not found: %s", request_data->uri);
        *buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
        buf_size = strlen (*buf);
        return buf_size;
    }
    sprintf (date, "%04lu-%02lu-%02lu %02lu:00:00", year, month, mday, hour);
    memset (&tm, 0, sizeof (struct tm));
    strptime (date, "%Y-%m-%d %H:%M:%S", &tm);
    tm.tm_isdst = daylight;
    timestamp = mktime (&tm) * 1000000 + us;

    /* read from memory */
    if (clock_gettime (CLOCK_REALTIME, &ts) == -1) {
        GST_ERROR ("get_mpeg2ts_segment clock_gettime error: %s", g_strerror (errno));
        *buf = g_strdup_printf (http_500, PACKAGE_NAME, PACKAGE_VERSION);
        buf_size = strlen (*buf);
        return buf_size;
    }
    ts.tv_sec += 2;
    while (sem_timedwait (encoder_output->semaphore, &ts) == -1) {
        if (errno == EINTR) {
            continue;
        }
        GST_ERROR ("get_mpeg2ts_segment sem_timedwait failure: %s", g_strerror (errno));
        *buf = g_strdup_printf (http_500, PACKAGE_NAME, PACKAGE_VERSION);
        buf_size = strlen (*buf);
        return buf_size;
    }
    /* seek gop */
    rap_addr = encoder_output_gop_seek (encoder_output, timestamp);
    if (rap_addr != G_MAXUINT64) {
        /* segment found, send it */
        gsize gop_size;

        gop_size = encoder_output_gop_size (encoder_output, rap_addr);
        cache_control = g_strdup_printf ("max-age=%lu", encoder_output->dvr_duration);
        header = g_strdup_printf (http_200, PACKAGE_NAME, PACKAGE_VERSION, "video/mpeg", gop_size, cache_control, "");
        g_free (cache_control);
        *buf = g_malloc (strlen (header) + gop_size);
        memcpy (*buf, header, strlen(header));
        if (rap_addr + gop_size + 12 < encoder_output->cache_size) {
            memcpy (*buf + strlen (header), encoder_output->cache_addr + rap_addr + 12, gop_size);

        } else {
            gint n;

            n = encoder_output->cache_size - rap_addr - 12;
            if (n > 0) {
                memcpy (*buf + strlen (header), encoder_output->cache_addr + rap_addr + 12, n);
                memcpy (*buf + strlen (header) + n, encoder_output->cache_addr, gop_size - n);

            } else {
                GST_WARNING ("nnnnn: n < 0 %d", n);
                memcpy (*buf + strlen (header), encoder_output->cache_addr - n, gop_size);
            }
        }
        buf_size = strlen (header) + gop_size;
        g_free (header);

    } else {
        buf_size = 0;
    }
    sem_post (encoder_output->semaphore);

    /* buf_size == 0? segment not found in memory, read frome dvr directory */
    if (buf_size == 0) {
        path = g_strdup_printf ("%s/%04lu%02lu%02lu%02lu/%010lu_%lu_%lu.ts",
                encoder_output->record_path,
                year, month, mday, hour, us, sequence, duration);
        if (!g_file_get_contents (path, &file, &buf_size, &err)) {
            g_error_free (err);
            GST_WARNING ("segment not found: %s", request_data->uri);
            *buf = g_strdup_printf (http_404, PACKAGE_NAME, PACKAGE_VERSION);
            buf_size = strlen (*buf);

        } else {
            max_age = encoder_output->dvr_duration - (g_get_real_time () - timestamp) / 1000000;
            cache_control = g_strdup_printf ("max-age=%lu", max_age);
            header = g_strdup_printf (http_200,
                    PACKAGE_NAME,
                    PACKAGE_VERSION,
                    "video/mpeg",
                    buf_size,
                    cache_control,
                    "");
            g_free (cache_control);
            *buf = g_malloc (buf_size + strlen (header));
            memcpy (*buf, header, strlen (header));
            memcpy (*buf + strlen (header), file, buf_size);
            buf_size += strlen (header);
            g_free (header);
            g_free (file);
        }
        g_free (path);
    }

    return buf_size;
}