gchar *dropbox_client_util_sanitize(const gchar *a) {
  /* this function escapes teh following utf-8 characters:
   * '\\', '\n', '\t'
   */
  return g_strescape(a, chars_not_to_escape);
}
예제 #2
0
gboolean extcap_spawn_sync ( gchar * dirname, gchar * command, gint argc, gchar ** args, gchar ** command_output )
{
    gboolean status = FALSE;
    gboolean result = FALSE;
    gchar ** argv = NULL;
    gint cnt = 0;
    gchar * local_output = NULL;
#ifdef _WIN32

#define BUFFER_SIZE 4096
    gchar buffer[BUFFER_SIZE];

    GString *winargs = g_string_sized_new(200);
    gchar *quoted_arg;
    gunichar2 *wcommandline;

    STARTUPINFO info;
    PROCESS_INFORMATION processInfo;

    SECURITY_ATTRIBUTES sa;
    HANDLE child_stdout_rd = NULL;
    HANDLE child_stdout_wr = NULL;
    HANDLE child_stderr_rd = NULL;
    HANDLE child_stderr_wr = NULL;

    const gchar * oldpath = g_getenv("PATH");
    gchar * newpath = NULL;
#else
    gint exit_status = 0;
#endif

    argv = (gchar **) g_malloc0(sizeof(gchar *) * (argc + 2));

#ifdef _WIN32
    newpath = g_strdup_printf("%s;%s", g_strescape(get_progfile_dir(), NULL), oldpath);
    g_setenv("PATH", newpath, TRUE);

    argv[0] = g_strescape(command, NULL);
#else
    argv[0] = g_strdup(command);
#endif

    for ( cnt = 0; cnt < argc; cnt++ )
        argv[cnt+1] = args[cnt];
    argv[argc+1] = NULL;

#ifdef _WIN32

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&child_stdout_rd, &child_stdout_wr, &sa, 0))
    {
        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stdout handle");
        return FALSE;
    }

    if (!CreatePipe(&child_stderr_rd, &child_stderr_wr, &sa, 0))
    {
        CloseHandle(child_stdout_rd);
        CloseHandle(child_stdout_wr);
        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stderr handle");
        return FALSE;
    }

    /* convert args array into a single string */
    /* XXX - could change sync_pipe_add_arg() instead */
    /* there is a drawback here: the length is internally limited to 1024 bytes */
    for (cnt = 0; argv[cnt] != 0; cnt++) {
        if (cnt != 0) g_string_append_c(winargs, ' ');    /* don't prepend a space before the path!!! */
        quoted_arg = protect_arg(argv[cnt]);
        g_string_append(winargs, quoted_arg);
        g_free(quoted_arg);
    }

    wcommandline = g_utf8_to_utf16(winargs->str, (glong)winargs->len, NULL, NULL, NULL);

    memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
    memset(&info, 0, sizeof(STARTUPINFO));

    info.cb = sizeof(STARTUPINFO);
    info.hStdError = child_stderr_wr;
    info.hStdOutput = child_stdout_wr;
    info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    info.wShowWindow = SW_HIDE;

    if (CreateProcess(NULL, wcommandline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &info, &processInfo))
    {
        WaitForSingleObject(processInfo.hProcess, INFINITE);
        win32_readfrompipe(child_stdout_rd, BUFFER_SIZE, buffer);
        local_output = g_strdup_printf("%s", buffer);

        CloseHandle(child_stdout_rd);
        CloseHandle(child_stdout_wr);
        CloseHandle(child_stderr_rd);
        CloseHandle(child_stderr_wr);

        CloseHandle(processInfo.hProcess);
        CloseHandle(processInfo.hThread);
        status = TRUE;
    }
    else
        status = FALSE;

    g_setenv("PATH", oldpath, TRUE);
#else

    status = g_spawn_sync(dirname, argv, NULL,
            (GSpawnFlags) 0, NULL, NULL, &local_output, NULL, &exit_status, NULL);

    if (status && exit_status != 0)
        status = FALSE;
#endif

    if (status)
    {
        if ( command_output != NULL && local_output != NULL )
            *command_output = g_strdup(local_output);

        result = TRUE;
    }

    g_free(local_output);
    g_free(argv);

    return result;
}
예제 #3
0
파일: postal-http.c 프로젝트: catch/postal
static void
postal_http_log_message (PostalHttp        *http,
                         SoupMessage       *message,
                         const gchar       *path,
                         SoupClientContext *client)
{
   const gchar *ip_addr;
   const gchar *version;
   GTimeVal event_time;
   struct tm tt;
   time_t t;
   gchar *epath;
   gchar *formatted = NULL;
   gchar *referrer;
   gchar *user_agent;
   gchar ftime[32];

   g_assert(POSTAL_IS_HTTP(http));
   g_assert(SOUP_IS_MESSAGE(message));
   g_assert(client);

   g_get_current_time(&event_time);
   t = (time_t)event_time.tv_sec;
   localtime_r(&t, &tt);
   strftime(ftime, sizeof ftime, "%b %d %H:%M:%S", &tt);
   ftime[31] = '\0';

   switch (soup_message_get_http_version(message)) {
   case SOUP_HTTP_1_0:
      version = "HTTP/1.0";
      break;
   case SOUP_HTTP_1_1:
      version = "HTTP/1.1";
      break;
   default:
      g_assert_not_reached();
      version = NULL;
      break;
   }

   ip_addr = soup_client_context_get_host(client);
   referrer = (gchar *)soup_message_headers_get_one(message->request_headers, "Referrer");
   user_agent = (gchar *)soup_message_headers_get_one(message->request_headers, "User-Agent");

   epath = g_strescape(path, NULL);
   referrer = g_strescape(referrer ?: "", NULL);
   user_agent = g_strescape(user_agent ?: "", NULL);

   formatted = g_strdup_printf("%s %s \"%s %s %s\" %u %"G_GSIZE_FORMAT" \"%s\" \"%s\"\n",
                               ip_addr,
                               ftime,
                               message->method,
                               epath,
                               version,
                               message->status_code,
                               message->response_body->length,
                               referrer,
                               user_agent);

   neo_logger_log(http->priv->logger,
                  &event_time,
                  NULL,
                  NULL,
                  0,
                  0,
                  0,
                  NULL,
                  formatted);

   g_free(epath);
   g_free(referrer);
   g_free(user_agent);
   g_free(formatted);
}
예제 #4
0
/*
 * updates autos list 
 */
static void update_autos(void)
{
	gchar command[1000];
	GList *unevaluated = NULL, *iter;
	const char *gdb_commands[2];
	int i;

	/* remove all previous GDB variables for autos */
	for (iter = autos; iter; iter = iter->next)
	{
		variable *var = (variable*)iter->data;
		
		sprintf(command, "-var-delete %s", var->internal->str);
		exec_sync_command(command, TRUE, NULL);
	}

	g_list_foreach(autos, (GFunc)variable_free, NULL);
	g_list_free(autos);
	autos = NULL;
	
	/* add current autos to the list */
	
	gdb_commands[0] = g_strdup_printf("-stack-list-arguments 0 %i %i", active_frame, active_frame);
	gdb_commands[1] = "-stack-list-locals 0";
	for (i = 0; i < sizeof (gdb_commands) / sizeof(*gdb_commands); i++)
	{
		gchar *record = NULL, *pos;

		result_class rc = exec_sync_command(gdb_commands[i], TRUE, &record);
		if (RC_DONE != rc)
			break;

		pos = record;
		while ((pos = strstr(pos, "name=\"")))
		{
			variable *var;
			gchar *create_record = NULL, *escaped;

			pos += strlen("name=\"");
			*(strchr(pos, '\"')) = '\0';

			var = variable_new(pos, i ? VT_LOCAL : VT_ARGUMENT);

			/* create new gdb variable */
			escaped = g_strescape(pos, NULL);
			sprintf(command, "-var-create - * \"%s\"", escaped);
			g_free(escaped);

			/* form new variable */
			if (RC_DONE == exec_sync_command(command, TRUE, &create_record))
			{
				gchar *intname = strstr(create_record, "name=\"") + strlen ("name=\"");
				*strchr(intname, '\"') = '\0';
				var->evaluated = TRUE;
				g_string_assign(var->internal, intname);
				autos = g_list_append(autos, var);

				g_free(create_record);
			}
			else
			{
				var->evaluated = FALSE;
				g_string_assign(var->internal, "");
				unevaluated = g_list_append(unevaluated, var);
			}
			
			pos += strlen(pos) + 1;
		}
		g_free(record);
	}
	g_free((void*)gdb_commands[0]);
	
	/* get values for the autos (without incorrect variables) */
	get_variables(autos);
	
	/* add incorrect variables */
	autos = g_list_concat(autos, unevaluated);
}
예제 #5
0
GPid extcap_spawn_async(interface_options * interface, GPtrArray * args)
{
    GPid pid = INVALID_EXTCAP_PID;

#ifdef _WIN32
    gint cnt = 0;
    gchar ** tmp = NULL;

    GString *winargs = g_string_sized_new(200);
    gchar *quoted_arg;
    gunichar2 *wcommandline;

    STARTUPINFO info;
    PROCESS_INFORMATION processInfo;

    SECURITY_ATTRIBUTES sa;
    HANDLE child_stdout_rd = NULL;
    HANDLE child_stdout_wr = NULL;
    HANDLE child_stderr_rd = NULL;
    HANDLE child_stderr_wr = NULL;

    const gchar * oldpath = g_getenv("PATH");
    gchar * newpath = NULL;

#endif

    extcap_userdata * userdata = NULL;
    userdata = (extcap_userdata *) g_malloc0(sizeof(extcap_userdata));

#ifdef _WIN32
    newpath = g_strdup_printf("%s;%s", g_strescape(get_progfile_dir(), NULL), oldpath);
    g_setenv("PATH", newpath, TRUE);

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&child_stdout_rd, &child_stdout_wr, &sa, 0))
    {
        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stdout handle");
        return FALSE;
    }

    if (!CreatePipe(&child_stderr_rd, &child_stderr_wr, &sa, 0))
    {
        CloseHandle(child_stdout_rd);
        CloseHandle(child_stdout_wr);
        g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_DEBUG, "Could not create stderr handle");
        return FALSE;
    }

    /* convert args array into a single string */
    /* XXX - could change sync_pipe_add_arg() instead */
    /* there is a drawback here: the length is internally limited to 1024 bytes */
    for (tmp = (gchar **)args->pdata, cnt = 0; *tmp && **tmp; ++cnt, ++tmp) {
        if (cnt != 0) g_string_append_c(winargs, ' ');    /* don't prepend a space before the path!!! */
        quoted_arg = protect_arg(*tmp);
        g_string_append(winargs, quoted_arg);
        g_free(quoted_arg);
    }

    wcommandline = g_utf8_to_utf16(winargs->str, (glong)winargs->len, NULL, NULL, NULL);

    memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
    memset(&info, 0, sizeof(STARTUPINFO));

    info.cb = sizeof(STARTUPINFO);
    info.hStdError = child_stderr_wr;
    info.hStdOutput = child_stdout_wr;
    info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    info.wShowWindow = SW_HIDE;

    if (CreateProcess(NULL, wcommandline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &info, &processInfo))
    {
        userdata->extcap_stderr_rd = _open_osfhandle((intptr_t)(child_stderr_rd), _O_BINARY);
        userdata->extcap_stdout_rd = _open_osfhandle((intptr_t)(child_stdout_rd), _O_BINARY);
        userdata->threadId = processInfo.hThread;
        pid = processInfo.hProcess;
    }

    g_setenv("PATH", oldpath, TRUE);
#else
    g_spawn_async(NULL, (gchar **)args->pdata, NULL, (GSpawnFlags) G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
            &pid, NULL);
#endif

    userdata->pid = pid;
    interface->extcap_userdata = userdata;

    return pid;
}
예제 #6
0
파일: charset.c 프로젝트: DarshanMn/easytag
/*
 * Convert a string from UTF-8 to the filename system encoding.
 *  - conversion OK : returns the string in filename system encoding (new allocated)
 *  - conversion KO : display error message + returns nothing!
 */
gchar *filename_from_display (const gchar *string)
{
    GError *error = NULL;
    gchar *ret = NULL;
    const gchar *char_encoding = NULL;
    //const gchar *filename_encoding = NULL;

    g_return_val_if_fail (string != NULL, NULL);

    // Get system encoding from LANG if found (ex : fr_FR.UTF-8 => UTF-8)
    if (get_locale())
        char_encoding = strchr(get_locale(), '.');

    if (char_encoding)
        char_encoding = char_encoding+1; // Skip the '.'
    if (char_encoding)
    {
        error = NULL;

        if (FILENAME_CHARACTER_SET_OTHER)
        {
            ret = g_convert(string, -1, char_encoding, "UTF-8", NULL, NULL, &error);

        }else if (FILENAME_CHARACTER_SET_APPROXIMATE)
        {
            // iconv_open (3):
            // When the string "//TRANSLIT" is appended to tocode, transliteration
            // is activated. This means that when a character cannot be represented
            // in the target character set, it can be approximated through one or
            // several similarly looking characters.
            gchar *enc = g_strconcat(char_encoding, "//TRANSLIT", NULL);
            ret = g_convert(string, -1, enc, "UTF-8", NULL, NULL, &error);
            g_free(enc);

        }else if (FILENAME_CHARACTER_SET_DISCARD)
        {
            // iconv_open (3):
            // When the string "//IGNORE" is appended to tocode, characters that
            // cannot be represented in the target character set will be silently
            // discarded.
            gchar *enc = g_strconcat(char_encoding, "//IGNORE", NULL);
            ret = g_convert(string, -1, enc, "UTF-8", NULL, NULL, &error);
            g_free(enc);
        }
    }

    if (!ret)
    {
        // Get system encoding from locale in LANG if found (ex : fr_FR.UTF-8 => fr_FR => ISO-8859-1)
        char_encoding = get_encoding_from_locale(get_locale());
        if (char_encoding)
        {
            //g_print("> char_encoding: %s\n",char_encoding);
            error = NULL;
            ret = g_convert(string, -1, char_encoding, "UTF-8", NULL, NULL, &error);
        }
    }

    if (!ret)
    {
        // Failing that, try ISO-8859-1
        error = NULL;
        ret = g_convert(string, -1, "ISO-8859-1", "UTF-8", NULL, NULL, &error);
    }

    if (!ret)
    {
        if (g_utf8_validate(string, -1, NULL))
        {
            // String already in UTF-8
            ret = g_strdup(string);
        }
    }

    if (!ret)
    {
        // Conversion KO!
        gchar *escaped_str = g_strescape(string, NULL);
        Log_Print(LOG_ERROR,_("The UTF-8 string '%s' couldn't be converted into filename encoding (%s)."),
                    escaped_str, error && error->message ? error->message : _("Invalid UTF-8"));
        g_clear_error(&error);

        ret = escaped_str;
    }

#ifdef G_OS_WIN32
    //ET_Win32_Path_Replace_Backslashes (ret);
#endif /* G_OS_WIN32 */

    return ret; // We need to catch errors (e.g. temp=NULL) in the real code
}
예제 #7
0
/*
 * updates watches list 
 */
static void update_watches(void)
{
	gchar command[1000];
	GList *updating = NULL;
	GList *iter;

	/* delete all GDB variables */
	for (iter = watches; iter; iter = iter->next)
	{
		variable *var = (variable*)iter->data;
		
		if (var->internal->len)
		{
			sprintf(command, "-var-delete %s", var->internal->str);
			exec_sync_command(command, TRUE, NULL);
		}
		
		/* reset all variables fields */
		variable_reset(var);
	}
	
	/* create GDB variables, adding successfully created
	variables to the list then passed for updatind */
	for (iter = watches; iter; iter = iter->next)
	{
		variable *var = (variable*)iter->data;
		gchar *record = NULL;
		gchar *pos;
		gchar *escaped;

		/* try to create variable */
		escaped = g_strescape(var->name->str, NULL);
		sprintf(command, "-var-create - * \"%s\"", escaped);
		g_free(escaped);

		if (RC_DONE != exec_sync_command(command, TRUE, &record))
		{
			/* do not include to updating list, move to next watch */
			var->evaluated = FALSE;
			g_string_assign(var->internal, "");
			g_free(record);
			
			continue;
		}
		
		/* find and assign internal name */
		pos = strstr(record, "name=\"") + strlen("name=\"");
		*strchr(pos, '\"') = '\0'; 
		g_string_assign(var->internal, pos);
		g_free(record);			
		
		var->evaluated = TRUE;

		/* add to updating list */
		updating = g_list_append(updating, var);
	}
	
	/* update watches */
	get_variables(updating);

	/* free updating list */
	g_list_free(updating);
}
예제 #8
0
/**
 * g_strdup_value_contents:
 * @value: #GValue which contents are to be described.
 *
 * Return a newly allocated string, which describes the contents of a
 * #GValue.  The main purpose of this function is to describe #GValue
 * contents for debugging output, the way in which the contents are
 * described may change between different GLib versions.
 *
 * Returns: Newly allocated string.
 */
gchar*
g_strdup_value_contents (const GValue *value)
{
  const gchar *src;
  gchar *contents;

  g_return_val_if_fail (G_IS_VALUE (value), NULL);
  
  if (G_VALUE_HOLDS_STRING (value))
    {
      src = g_value_get_string (value);
      
      if (!src)
	contents = g_strdup ("NULL");
      else
	{
	  gchar *s = g_strescape (src, NULL);

	  contents = g_strdup_printf ("\"%s\"", s);
	  g_free (s);
	}
    }
  else if (g_value_type_transformable (G_VALUE_TYPE (value), G_TYPE_STRING))
    {
      GValue tmp_value = G_VALUE_INIT;
      gchar *s;

      g_value_init (&tmp_value, G_TYPE_STRING);
      g_value_transform (value, &tmp_value);
      s = g_strescape (g_value_get_string (&tmp_value), NULL);
      g_value_unset (&tmp_value);
      if (G_VALUE_HOLDS_ENUM (value) || G_VALUE_HOLDS_FLAGS (value))
	contents = g_strdup_printf ("((%s) %s)",
				    g_type_name (G_VALUE_TYPE (value)),
				    s);
      else
	contents = g_strdup (s ? s : "NULL");
      g_free (s);
    }
  else if (g_value_fits_pointer (value))
    {
      gpointer p = g_value_peek_pointer (value);

      if (!p)
	contents = g_strdup ("NULL");
      else if (G_VALUE_HOLDS_OBJECT (value))
	contents = g_strdup_printf ("((%s*) %p)", G_OBJECT_TYPE_NAME (p), p);
      else if (G_VALUE_HOLDS_PARAM (value))
	contents = g_strdup_printf ("((%s*) %p)", G_PARAM_SPEC_TYPE_NAME (p), p);
      else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
        {
          GStrv strv = g_value_get_boxed (value);
          GString *tmp = g_string_new ("[");

          while (*strv != NULL)
            {
              gchar *escaped = g_strescape (*strv, NULL);

              g_string_append_printf (tmp, "\"%s\"", escaped);
              g_free (escaped);

              if (*++strv != NULL)
                g_string_append (tmp, ", ");
            }

          g_string_append (tmp, "]");
          contents = g_string_free (tmp, FALSE);
        }
      else if (G_VALUE_HOLDS_BOXED (value))
	contents = g_strdup_printf ("((%s*) %p)", g_type_name (G_VALUE_TYPE (value)), p);
      else if (G_VALUE_HOLDS_POINTER (value))
	contents = g_strdup_printf ("((gpointer) %p)", p);
      else
	contents = g_strdup ("???");
    }
  else
    contents = g_strdup ("???");

  return contents;
}
예제 #9
0
/**
 * mongo_bson_to_string:
 * @bson: (in): A #MongoBson.
 *
 * Build a string representing the BSON document.
 *
 * Returns: (transfer full): A string representing the BSON document.
 */
gchar *
mongo_bson_to_string (MongoBson *bson,
                      gboolean   is_array)
{
   MongoBsonIter iter;
   MongoBsonType type;
   GString *str;
   gchar *esc;


   g_return_val_if_fail(bson, NULL);

   str = g_string_new(is_array ? "[" : "{");

   mongo_bson_iter_init(&iter, bson);
   if (mongo_bson_iter_next(&iter)) {
again:
      if (!is_array) {
         esc = g_strescape(mongo_bson_iter_get_key(&iter), NULL);
         g_string_append_printf(str, "\"%s\": ", esc);
         g_free(esc);

      }
      type = mongo_bson_iter_get_value_type(&iter);
      switch (type) {
      case MONGO_BSON_DOUBLE:
         g_string_append_printf(str, "%f",
                                mongo_bson_iter_get_value_double(&iter));
         break;
      case MONGO_BSON_DATE_TIME:
         {
            GTimeVal tv = { 0 };
            gchar *dstr;

            mongo_bson_iter_get_value_timeval(&iter, &tv);
            dstr = g_time_val_to_iso8601(&tv);
            g_string_append_printf(str, "ISODate(\"%s\")", dstr);
            g_free(dstr);
         }
         break;
      case MONGO_BSON_INT32:
         g_string_append_printf(str, "NumberLong(%d)",
                                mongo_bson_iter_get_value_int(&iter));
         break;
      case MONGO_BSON_INT64:
         g_string_append_printf(str, "NumberLong(%"G_GINT64_FORMAT")",
                                mongo_bson_iter_get_value_int64(&iter));
         break;
      case MONGO_BSON_UTF8:
         esc = g_strescape(mongo_bson_iter_get_value_string(&iter, NULL), NULL);
         g_string_append_printf(str, "\"%s\"", esc);
         g_free(esc);
         break;
      case MONGO_BSON_ARRAY:
         {
            MongoBson *child;
            gchar *childstr;

            if ((child = mongo_bson_iter_get_value_array(&iter))) {
               childstr = mongo_bson_to_string(child, TRUE);
               g_string_append(str, childstr);
               mongo_bson_unref(child);
               g_free(childstr);
            }
         }
         break;
      case MONGO_BSON_DOCUMENT:
         {
            MongoBson *child;
            gchar *childstr;

            if ((child = mongo_bson_iter_get_value_bson(&iter))) {
               childstr = mongo_bson_to_string(child, FALSE);
               g_string_append(str, childstr);
               mongo_bson_unref(child);
               g_free(childstr);
            }
         }
         break;
      case MONGO_BSON_BOOLEAN:
         g_string_append_printf(str,
            mongo_bson_iter_get_value_boolean(&iter) ? "true" : "false");
         break;
      case MONGO_BSON_OBJECT_ID:
         {
            MongoObjectId *id;
            gchar *idstr;

            id = mongo_bson_iter_get_value_object_id(&iter);
            idstr = mongo_object_id_to_string(id);
            g_string_append_printf(str, "ObjectId(\"%s\")", idstr);
            mongo_object_id_free(id);
            g_free(idstr);
         }
         break;
      case MONGO_BSON_NULL:
         g_string_append(str, "null");
         break;
      case MONGO_BSON_REGEX:
         /* TODO: */
         g_assert_not_reached();
         break;
      case MONGO_BSON_UNDEFINED:
         g_string_append(str, "undefined");
         break;
      default:
         g_assert_not_reached();
      }

      if (mongo_bson_iter_next(&iter)) {
         g_string_append(str, ", ");
         goto again;
      }
   }

   g_string_append(str, is_array ? "]" : "}");

   return g_string_free(str, FALSE);
}
예제 #10
0
/*
 * debug_dump_element:
 * @bin: the bin that should be analyzed
 * @out: file to write to
 * @indent: level of graph indentation
 *
 * Helper for _gst_debug_bin_to_dot_file() to recursively dump a pipeline.
 */
static void
debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
    const gint indent)
{
  GstIterator *element_iter, *pad_iter;
  gboolean elements_done, pads_done;
  GstElement *element, *peer_element, *target_element;
  GstPad *pad, *peer_pad, *target_pad;
  GstPadDirection dir;
  GstCaps *caps;
  GstStructure *structure;
  gboolean free_caps, free_media;
  guint src_pads, sink_pads;
  gchar *media = NULL;
  gchar *pad_name, *element_name;
  gchar *peer_pad_name, *peer_element_name;
  gchar *target_pad_name, *target_element_name;
  gchar *color_name;
  gchar *state_name = NULL;
  gchar *param_name = NULL;
  gchar *spc = NULL;

  spc = g_malloc (1 + indent * 2);
  memset (spc, 32, indent * 2);
  spc[indent * 2] = '\0';

  element_iter = gst_bin_iterate_elements (bin);
  elements_done = FALSE;
  while (!elements_done) {
    switch (gst_iterator_next (element_iter, (gpointer) & element)) {
      case GST_ITERATOR_OK:
        element_name = debug_dump_make_object_name (GST_OBJECT (element));

        if (details & GST_DEBUG_GRAPH_SHOW_STATES) {
          state_name = debug_dump_get_element_state (GST_ELEMENT (element));
        }
        if (details & GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS) {
          param_name = debug_dump_get_element_params (GST_ELEMENT (element));
        }
        /* elements */
        fprintf (out, "%ssubgraph cluster_%s {\n", spc, element_name);
        fprintf (out, "%s  fontname=\"Bitstream Vera Sans\";\n", spc);
        fprintf (out, "%s  fontsize=\"8\";\n", spc);
        fprintf (out, "%s  style=filled;\n", spc);
        fprintf (out, "%s  color=black;\n\n", spc);
        fprintf (out, "%s  label=\"<%s>\\n%s%s%s\";\n", spc,
            G_OBJECT_TYPE_NAME (element), GST_OBJECT_NAME (element),
            (state_name ? state_name : ""), (param_name ? param_name : "")
            );
        if (state_name) {
          g_free (state_name);
          state_name = NULL;
        }
        if (param_name) {
          g_free (param_name);
          param_name = NULL;
        }
        g_free (element_name);

        src_pads = sink_pads = 0;
        if ((pad_iter = gst_element_iterate_pads (element))) {
          pads_done = FALSE;
          while (!pads_done) {
            switch (gst_iterator_next (pad_iter, (gpointer) & pad)) {
              case GST_ITERATOR_OK:
                dir = gst_pad_get_direction (pad);
                pad_name = debug_dump_make_object_name (GST_OBJECT (pad));
                element_name =
                    debug_dump_make_object_name (GST_OBJECT (element));
                if (GST_IS_GHOST_PAD (pad)) {
                  color_name =
                      (dir == GST_PAD_SRC) ? "#ffdddd" : ((dir ==
                          GST_PAD_SINK) ? "#ddddff" : "#ffffff");
                } else {
                  color_name =
                      (dir == GST_PAD_SRC) ? "#ffaaaa" : ((dir ==
                          GST_PAD_SINK) ? "#aaaaff" : "#cccccc");
                }
                /* pads */
                fprintf (out,
                    "%s  %s_%s [color=black, fillcolor=\"%s\", label=\"%s\"];\n",
                    spc, element_name, pad_name, color_name,
                    GST_OBJECT_NAME (pad));

                if (dir == GST_PAD_SRC)
                  src_pads++;
                else if (dir == GST_PAD_SINK)
                  sink_pads++;
                g_free (pad_name);
                g_free (element_name);
                gst_object_unref (pad);
                break;
              case GST_ITERATOR_RESYNC:
                gst_iterator_resync (pad_iter);
                break;
              case GST_ITERATOR_ERROR:
              case GST_ITERATOR_DONE:
                pads_done = TRUE;
                break;
            }
          }
          gst_iterator_free (pad_iter);
        }
        if (GST_IS_BIN (element)) {
          fprintf (out, "%s  fillcolor=\"#ffffff\";\n", spc);
          /* recurse */
          debug_dump_element (GST_BIN (element), details, out, indent + 1);
        } else {
          if (src_pads && !sink_pads)
            fprintf (out, "%s  fillcolor=\"#ffaaaa\";\n", spc);
          else if (!src_pads && sink_pads)
            fprintf (out, "%s  fillcolor=\"#aaaaff\";\n", spc);
          else if (src_pads && sink_pads)
            fprintf (out, "%s  fillcolor=\"#aaffaa\";\n", spc);
          else
            fprintf (out, "%s  fillcolor=\"#ffffff\";\n", spc);
        }
        fprintf (out, "%s}\n\n", spc);
        if ((pad_iter = gst_element_iterate_pads (element))) {
          pads_done = FALSE;
          while (!pads_done) {
            switch (gst_iterator_next (pad_iter, (gpointer) & pad)) {
              case GST_ITERATOR_OK:
                if (gst_pad_is_linked (pad)
                    && gst_pad_get_direction (pad) == GST_PAD_SRC) {
                  if ((peer_pad = gst_pad_get_peer (pad))) {
                    free_media = FALSE;
                    if ((details & GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE) ||
                        (details & GST_DEBUG_GRAPH_SHOW_CAPS_DETAILS)
                        ) {
                      if ((caps = gst_pad_get_negotiated_caps (pad))) {
                        free_caps = TRUE;
                      } else {
                        free_caps = FALSE;
                        if (!(caps = (GstCaps *)
                                gst_pad_get_pad_template_caps (pad))) {
                          /* this should not happen */
                          media = "?";
                        }
                      }
                      if (caps) {
                        if (details & GST_DEBUG_GRAPH_SHOW_CAPS_DETAILS) {
                          gchar *tmp =
                              g_strdelimit (gst_caps_to_string (caps), ",",
                              '\n');

                          media = g_strescape (tmp, NULL);
                          free_media = TRUE;
                          g_free (tmp);
                        } else {
                          if (GST_CAPS_IS_SIMPLE (caps)) {
                            structure = gst_caps_get_structure (caps, 0);
                            media =
                                (gchar *) gst_structure_get_name (structure);
                          } else
                            media = "*";
                        }
                        if (free_caps) {
                          gst_caps_unref (caps);
                        }
                      }
                    }

                    pad_name = debug_dump_make_object_name (GST_OBJECT (pad));
                    element_name =
                        debug_dump_make_object_name (GST_OBJECT (element));
                    peer_pad_name =
                        debug_dump_make_object_name (GST_OBJECT (peer_pad));
                    if ((peer_element = gst_pad_get_parent_element (peer_pad))) {
                      peer_element_name =
                          debug_dump_make_object_name (GST_OBJECT
                          (peer_element));
                    } else {
                      peer_element_name = "";
                    }
                    /* pad link */
                    if (media) {
                      fprintf (out, "%s%s_%s -> %s_%s [label=\"%s\"]\n", spc,
                          element_name, pad_name, peer_element_name,
                          peer_pad_name, media);
                      if (free_media) {
                        g_free (media);
                      }
                    } else {
                      fprintf (out, "%s%s_%s -> %s_%s\n", spc,
                          element_name, pad_name, peer_element_name,
                          peer_pad_name);
                    }

                    if (GST_IS_GHOST_PAD (pad)) {
                      if ((target_pad =
                              gst_ghost_pad_get_target (GST_GHOST_PAD (pad)))) {
                        target_pad_name =
                            debug_dump_make_object_name (GST_OBJECT
                            (target_pad));
                        if ((target_element =
                                gst_pad_get_parent_element (target_pad))) {
                          target_element_name =
                              debug_dump_make_object_name (GST_OBJECT
                              (target_element));
                        } else {
                          target_element_name = "";
                        }
                        /* src ghostpad relationship */
                        fprintf (out, "%s%s_%s -> %s_%s [style=dashed]\n", spc,
                            target_element_name, target_pad_name, element_name,
                            pad_name);

                        g_free (target_pad_name);
                        if (target_element) {
                          g_free (target_element_name);
                          gst_object_unref (target_element);
                        }
                        gst_object_unref (target_pad);
                      }
                    }
                    if (GST_IS_GHOST_PAD (peer_pad)) {
                      if ((target_pad =
                              gst_ghost_pad_get_target (GST_GHOST_PAD
                                  (peer_pad)))) {
                        target_pad_name =
                            debug_dump_make_object_name (GST_OBJECT
                            (target_pad));
                        if ((target_element =
                                gst_pad_get_parent_element (target_pad))) {
                          target_element_name =
                              debug_dump_make_object_name (GST_OBJECT
                              (target_element));
                        } else {
                          target_element_name = "";
                        }
                        /* sink ghostpad relationship */
                        fprintf (out, "%s%s_%s -> %s_%s [style=dashed]\n", spc,
                            peer_element_name, peer_pad_name,
                            target_element_name, target_pad_name);

                        g_free (target_pad_name);
                        if (target_element) {
                          g_free (target_element_name);
                          gst_object_unref (target_element);
                        }
                        gst_object_unref (target_pad);
                      }
                    }

                    g_free (pad_name);
                    g_free (element_name);
                    g_free (peer_pad_name);
                    if (peer_element) {
                      g_free (peer_element_name);
                      gst_object_unref (peer_element);
                    }
                    gst_object_unref (peer_pad);
                  }
                }
                gst_object_unref (pad);
                break;
              case GST_ITERATOR_RESYNC:
                gst_iterator_resync (pad_iter);
                break;
              case GST_ITERATOR_ERROR:
              case GST_ITERATOR_DONE:
                pads_done = TRUE;
                break;
            }
          }
          gst_iterator_free (pad_iter);
        }
        gst_object_unref (element);
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (element_iter);
        break;
      case GST_ITERATOR_ERROR:
      case GST_ITERATOR_DONE:
        elements_done = TRUE;
        break;
    }
  }
  gst_iterator_free (element_iter);
  g_free (spc);
}
예제 #11
0
static gchar *
debug_dump_get_object_params (GObject * object,
    GstDebugGraphDetails details, const char *const *ignored_propnames)
{
  gchar *param_name = NULL;
  GParamSpec **properties, *property;
  GValue value = { 0, };
  guint i, number_of_properties;
  gchar *tmp, *value_str;
  const gchar *ellipses;

  /* get paramspecs and show non-default properties */
  properties =
      g_object_class_list_properties (G_OBJECT_GET_CLASS (object),
      &number_of_properties);
  if (properties) {
    for (i = 0; i < number_of_properties; i++) {
      gint j;
      gboolean ignore = FALSE;
      property = properties[i];

      /* skip some properties */
      if (!(property->flags & G_PARAM_READABLE))
        continue;
      if (!strcmp (property->name, "name"))
        continue;

      if (ignored_propnames)
        for (j = 0; ignored_propnames[j]; j++)
          if (!g_strcmp0 (ignored_propnames[j], property->name))
            ignore = TRUE;

      if (ignore)
        continue;

      g_value_init (&value, property->value_type);
      g_object_get_property (G_OBJECT (object), property->name, &value);
      if (!(g_param_value_defaults (property, &value))) {
        tmp = g_strdup_value_contents (&value);
        value_str = g_strescape (tmp, NULL);
        g_free (tmp);

        /* too long, ellipsize */
        if (!(details & GST_DEBUG_GRAPH_SHOW_FULL_PARAMS) &&
            strlen (value_str) > PARAM_MAX_LENGTH)
          ellipses = "…";
        else
          ellipses = "";

        if (param_name)
          tmp = param_name;
        else
          tmp = (char *) "";

        if (details & GST_DEBUG_GRAPH_SHOW_FULL_PARAMS) {
          param_name = g_strdup_printf ("%s\\n%s=%s", tmp, property->name,
              value_str);
        } else {
          param_name = g_strdup_printf ("%s\\n%s=%."
              G_STRINGIFY (PARAM_MAX_LENGTH) "s%s", tmp, property->name,
              value_str, ellipses);
        }

        if (tmp[0] != '\0')
          g_free (tmp);

        g_free (value_str);
      }
      g_value_unset (&value);
    }
    g_free (properties);
  }
  return param_name;
}
예제 #12
0
/*
 * 'len' is the value given to us by the server that is supposed to
 * be the length of 'data'.  But apparently there's a time when this
 * length is incorrect.  Christopher Layne thinks it might be a bug
 * in their server code.
 *
 * The following information is from Christopher:
 *
 * It sometimes happens when Yahoo! sends a packet continuation within
 * chat.  Sometimes when joining a large chatroom the initial
 * SERVICE_CHATJOIN packet will be so large that it will need to be
 * split into multiple packets.  That's fine, except that the length
 * of the second packet is wrong.  The packet has the same length as
 * the first packet, and the length given in the header is the same,
 * however the actual data in the packet is shorter than this length.
 * So half of the packet contains good, valid data, and then the rest
 * of the packet is junk.  Luckily there is a null terminator after
 * the valid data and before the invalid data.
 *
 * What does all this mean?  It means that we parse through the data
 * pulling out key/value pairs until we've parsed 'len' bytes, or until
 * we run into a null terminator, whichever comes first.
 */
void yahoo_packet_read(struct yahoo_packet *pkt, const guchar *data, int len)
{
	int pos = 0;
	char key[64];
	const guchar *delimiter;
	gboolean accept;
	guint x;
	struct yahoo_pair *pair;

	while (pos + 1 < len)
	{
		if (data[pos] == '\0')
			break;

		pair = g_new0(struct yahoo_pair, 1);

		x = 0;
		while (pos + 1 < len) {
			if (data[pos] == 0xc0 && data[pos + 1] == 0x80)
				break;
			if (x >= sizeof(key)-1) {
				x++;
				pos++;
				continue;
			}
			key[x++] = data[pos++];
		}
		if (x >= sizeof(key)-1) {
			x = 0;
		}
		key[x] = 0;
		pos += 2;
		pair->key = strtol(key, NULL, 10);
		accept = x; /* if x is 0 there was no key, so don't accept it */

		if (pos + 1 > len) {
			/* Malformed packet! (Truncated--garbage or something) */
			accept = FALSE;
		}

		if (accept) {
			delimiter = (const guchar *)g_strstr_len((const char *)&data[pos], len - pos, "\xc0\x80");
			if (delimiter == NULL)
			{
				/* Malformed packet! (It doesn't end in 0xc0 0x80) */
				g_free(pair);
				pos = len;
				continue;
			}
			x = delimiter - data;
			pair->value = g_strndup((const gchar *)&data[pos], x - pos);
			pos = x;
			pkt->hash = g_slist_prepend(pkt->hash, pair);

			if (purple_debug_is_verbose() || g_getenv("PURPLE_YAHOO_DEBUG")) {
				char *esc;
				esc = g_strescape(pair->value, NULL);
				purple_debug_misc("yahoo", "Key: %d  \tValue: %s\n", pair->key, esc);
				g_free(esc);
			}
		} else {
			g_free(pair);
		}
		pos += 2;

		if (pos + 1 > len) break;

		/* Skip over garbage we've noticed in the mail notifications */
		if (data[0] == '9' && data[pos] == 0x01)
			pos++;
	}

	/*
	 * Originally this function used g_slist_append().  I changed
	 * it to use g_slist_prepend() for improved performance.
	 * Ideally the Yahoo! PRPL code would be indifferent to the
	 * order of the key/value pairs, but I don't know if this is
	 * the case for all incoming messages.  To be on the safe side
	 * we reverse the list.
	 */
	pkt->hash = g_slist_reverse(pkt->hash);
}
예제 #13
0
static gchar *
get_session_address_dbus_launch (GError **error)
{
  gchar *ret;
  gchar *machine_id;
  gchar *command_line;
  gchar *launch_stdout;
  gchar *launch_stderr;
  gint exit_status;
  gchar *old_dbus_verbose;
  gboolean restore_dbus_verbose;

  ret = NULL;
  machine_id = NULL;
  command_line = NULL;
  launch_stdout = NULL;
  launch_stderr = NULL;
  restore_dbus_verbose = FALSE;
  old_dbus_verbose = NULL;

  machine_id = _g_dbus_get_machine_id (error);
  if (machine_id == NULL)
    {
      g_prefix_error (error, _("Cannot spawn a message bus without a machine-id: "));
      goto out;
    }

  /* We're using private libdbus facilities here. When everything
   * (X11, Mac OS X, Windows) is spec'ed out correctly (not even the
   * X11 property is correctly documented right now) we should
   * consider using the spec instead of dbus-launch.
   *
   *   --autolaunch=MACHINEID
   *          This option implies that dbus-launch should scan  for  a  previ‐
   *          ously-started  session  and  reuse the values found there. If no
   *          session is found, it will start a new session. The  --exit-with-
   *          session option is implied if --autolaunch is given.  This option
   *          is for the exclusive use of libdbus, you do not want to  use  it
   *          manually. It may change in the future.
   */

  /* TODO: maybe provide a variable for where to look for the dbus-launch binary? */
  command_line = g_strdup_printf ("dbus-launch --autolaunch=%s --binary-syntax --close-stderr", machine_id);

  if (G_UNLIKELY (_g_dbus_debug_address ()))
    {
      _g_dbus_debug_print_lock ();
      g_print ("GDBus-debug:Address: Running `%s' to get bus address (possibly autolaunching)\n", command_line);
      old_dbus_verbose = g_strdup (g_getenv ("DBUS_VERBOSE"));
      restore_dbus_verbose = TRUE;
      g_setenv ("DBUS_VERBOSE", "1", TRUE);
      _g_dbus_debug_print_unlock ();
    }

  if (!g_spawn_command_line_sync (command_line,
                                  &launch_stdout,
                                  &launch_stderr,
                                  &exit_status,
                                  error))
    {
      g_prefix_error (error, _("Error spawning command line `%s': "), command_line);
      goto out;
    }

  if (!WIFEXITED (exit_status))
    {
      gchar *escaped_stderr;
      escaped_stderr = g_strescape (launch_stderr, "");
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_FAILED,
                   _("Abnormal program termination spawning command line `%s': %s"),
                   command_line,
                   escaped_stderr);
      g_free (escaped_stderr);
      goto out;
    }

  if (WEXITSTATUS (exit_status) != 0)
    {
      gchar *escaped_stderr;
      escaped_stderr = g_strescape (launch_stderr, "");
      g_set_error (error,
                   G_IO_ERROR,
                   G_IO_ERROR_FAILED,
                   _("Command line `%s' exited with non-zero exit status %d: %s"),
                   command_line,
                   WEXITSTATUS (exit_status),
                   escaped_stderr);
      g_free (escaped_stderr);
      goto out;
    }

  /* From the dbus-launch(1) man page:
   *
   *   --binary-syntax Write to stdout a nul-terminated bus address,
   *   then the bus PID as a binary integer of size sizeof(pid_t),
   *   then the bus X window ID as a binary integer of size
   *   sizeof(long).  Integers are in the machine's byte order, not
   *   network byte order or any other canonical byte order.
   */
  ret = g_strdup (launch_stdout);

 out:
  if (G_UNLIKELY (_g_dbus_debug_address ()))
    {
      gchar *s;
      _g_dbus_debug_print_lock ();
      g_print ("GDBus-debug:Address: dbus-launch output:");
      if (launch_stdout != NULL)
        {
          s = _g_dbus_hexdump (launch_stdout, strlen (launch_stdout) + 1 + sizeof (pid_t) + sizeof (long), 2);
          g_print ("\n%s", s);
          g_free (s);
        }
      else
        {
          g_print (" (none)\n");
        }
      g_print ("GDBus-debug:Address: dbus-launch stderr output:");
      if (launch_stderr != NULL)
        g_print ("\n%s", launch_stderr);
      else
        g_print (" (none)\n");
      _g_dbus_debug_print_unlock ();
    }

  g_free (machine_id);
  g_free (command_line);
  g_free (launch_stdout);
  g_free (launch_stderr);
  if (G_UNLIKELY (restore_dbus_verbose))
    {
      if (old_dbus_verbose != NULL)
        g_setenv ("DBUS_VERBOSE", old_dbus_verbose, TRUE);
      else
        g_unsetenv ("DBUS_VERBOSE");
    }
  g_free (old_dbus_verbose);
  return ret;
}
예제 #14
0
static gchar *
format(Log4gLayout *base, Log4gLoggingEvent *event)
{
	struct Private *priv = GET_PRIVATE(base);
	Log4gLevel *level = log4g_logging_event_get_level(event);
	const GTimeVal *tv = log4g_logging_event_get_time_stamp(event);
	gchar *escaped;
	glong start = log4g_logging_event_get_start_time();
	glong time = (tv->tv_sec * 1000) + (tv->tv_usec * 0.001);
	if (priv->string->len > MAX_CAPACITY) {
		g_string_free(priv->string, TRUE);
		priv->string = g_string_sized_new(BUF_SIZE);
		if (!priv->string) {
			return NULL;
		}
	} else {
		g_string_set_size(priv->string, 0);
	}
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	g_string_append(priv->string, "<tr>");
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	/* time */
	g_string_append(priv->string, "<td>");
	g_string_append_printf(priv->string, "%ld", time - start);
	g_string_append(priv->string, "</td>");
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	/* thread */
	escaped = g_strescape(log4g_logging_event_get_thread_name(event), NULL);
	if (escaped) {
		g_string_append_printf(priv->string, "<td title=\"%s\">",
				escaped);
		g_string_append(priv->string, escaped);
		g_free(escaped);
	} else {
		g_string_append(priv->string, "<td>");
		g_string_append(priv->string, "&nbsp;");
	}
	g_string_append(priv->string, "</td>");
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	/* level */
	g_string_append(priv->string, "<td title=\"Level\">");
	escaped = g_strescape(log4g_level_to_string(level), NULL);
	if (escaped) {
		if (log4g_level_equals(level, log4g_level_DEBUG())) {
			g_string_append(priv->string,
					"<font color=\"#339933\"><strong>");
			g_string_append(priv->string, escaped);
			g_string_append(priv->string, "</strong></font>");
		} else if (log4g_level_is_greater_or_equal(level,
					log4g_level_WARN())) {
			g_string_append(priv->string,
					"<font color=\"#993300\"><strong>");
			g_string_append(priv->string, escaped);
			g_string_append(priv->string, "</strong></font>");
		} else {
			g_string_append(priv->string, escaped);
		}
		g_free(escaped);
	} else {
		g_string_append(priv->string, "&nbsp;");
	}
	g_string_append(priv->string, "</td>");
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	/* category */
	escaped = g_strescape(log4g_logging_event_get_logger_name(event), NULL);
	if (escaped) {
		g_string_append_printf(priv->string, "<td title=\"%s\">",
				escaped);
		g_string_append(priv->string, escaped);
		g_free(escaped);
	} else {
		g_string_append(priv->string, "<td>");
		g_string_append(priv->string, "&nbsp;");
	}
	g_string_append(priv->string, "</td>");
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	if (priv->info) {
		/* file:line */
		g_string_append(priv->string, "<td>");
		escaped = g_strescape(log4g_logging_event_get_file_name(event), NULL);
		if (escaped) {
			g_string_append(priv->string, escaped);
			g_free(escaped);
		}
		g_string_append_c(priv->string, ':');
		escaped =
			g_strescape(log4g_logging_event_get_line_number(event), NULL);
		if (escaped) {
			g_string_append(priv->string, escaped);
			g_free(escaped);
		}
		g_string_append(priv->string, "</td>");
		g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	}
	/* message */
	g_string_append_printf(priv->string, "<td title=\"%s\">",
			Q_("Message"));
	escaped = g_strescape(log4g_logging_event_get_rendered_message(event),
			NULL);
	if (escaped) {
		g_string_append(priv->string, escaped);
		g_free(escaped);
	} else {
		g_string_append(priv->string, "&nbsp;");
	}
	g_string_append(priv->string, "</td>");
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	g_string_append(priv->string, "</tr>");
	g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
	/* NDC */
	if (log4g_logging_event_get_ndc(event)) {
		escaped = g_strescape(log4g_logging_event_get_ndc(event), NULL);
		if (escaped) {
			g_string_append_printf(priv->string,
					"<tr><td bgcolor=\"#eeeeee\" "
					"style=\"font-size : xx-small;\" "
					"colspan=\"%d\" title=\"%s\">",
					(priv->info ? 6 : 5),
					Q_("Nested Diagnostic Context"));
			g_string_append(priv->string, "NDC: ");
			g_string_append(priv->string, escaped);
			g_string_append(priv->string, "</td></tr>");
			g_string_append(priv->string, LOG4G_LAYOUT_LINE_SEP);
			g_free(escaped);
		}
	}
	return priv->string->str;
}