예제 #1
0
파일: plugin.c 프로젝트: sujithpshankar/nm
static void
read_connections (NMSystemConfigInterface *config)
{
	SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config);
	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self);
	GDir *dir;
	GError *error = NULL;
	const char *item;
	GHashTable *alive_connections;
	GHashTableIter iter;
	NMKeyfileConnection *connection;
	GPtrArray *dead_connections = NULL;
	guint i;
	GPtrArray *filenames;
	GHashTable *paths;

	dir = g_dir_open (KEYFILE_DIR, 0, &error);
	if (!dir) {
		nm_log_warn (LOGD_SETTINGS, "keyfile: cannot read directory '%s': (%d) %s",
		             KEYFILE_DIR,
		             error ? error->code : -1,
		             error && error->message ? error->message : "(unknown)");
		g_clear_error (&error);
		return;
	}

	alive_connections = g_hash_table_new (NULL, NULL);

	filenames = g_ptr_array_new_with_free_func (g_free);
	while ((item = g_dir_read_name (dir))) {
		if (nm_keyfile_plugin_utils_should_ignore_file (item))
			continue;
		g_ptr_array_add (filenames, g_build_filename (KEYFILE_DIR, item, NULL));
	}
	g_dir_close (dir);

	/* While reloading, we don't replace connections that we already loaded while
	 * iterating over the files.
	 *
	 * To have sensible, reproducible behavior, sort the paths by last modification
	 * time prefering older files.
	 */
	paths = _paths_from_connections (priv->connections);
	g_ptr_array_sort_with_data (filenames, (GCompareDataFunc) _sort_paths, paths);
	g_hash_table_destroy (paths);

	for (i = 0; i < filenames->len; i++) {
		connection = update_connection (self, NULL, filenames->pdata[i], NULL, FALSE, alive_connections, NULL);
		if (connection)
			g_hash_table_add (alive_connections, connection);
	}
	g_ptr_array_free (filenames, TRUE);

	g_hash_table_iter_init (&iter, priv->connections);
	while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) {
		if (   !g_hash_table_contains (alive_connections, connection)
		    && nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection))) {
			if (!dead_connections)
				dead_connections = g_ptr_array_new ();
			g_ptr_array_add (dead_connections, connection);
		}
	}
	g_hash_table_destroy (alive_connections);

	if (dead_connections) {
		for (i = 0; i < dead_connections->len; i++)
			remove_connection (self, dead_connections->pdata[i]);
		g_ptr_array_free (dead_connections, TRUE);
	}
}
예제 #2
0
파일: main.c 프로젝트: bitptr/bytestream
/*
 * Insert all desktop files in a directory into the GtkListStore.
 */
void
apps_list_insert_files(GtkListStore *apps, GHashTable *entry_files, char *dir,
    DIR *dirp, size_t len)
{
	char		*fn = NULL, *name_v = NULL, *exec_v = NULL;
	char		*icon_v = NULL;
	int		 ret;
	size_t		 len_name, len_fn;
	uint8_t		 field_code_flags;
	struct dirent	*dp;
	GKeyFile	*key_file = NULL;
	GError		*error = NULL;
	gboolean	 nodisplay_v, hidden_v, use_term_v;

	while ((dp = readdir(dirp)) != NULL) {
		len_name = strlen(dp->d_name);
		if (len_name <= 8)
			goto cont;
		if (strncmp(dp->d_name + len_name - 8, ".desktop", 8) != 0)
			goto cont;

		len_fn = len_name + len + 1;
		if ((fn = calloc(len_fn, sizeof(char))) == NULL)
			err(1, NULL);
		ret = snprintf(fn, len_fn, "%s/%s", dir, dp->d_name);
		if (ret < 0 || (size_t)ret >= len_fn)
			err(1, NULL);

		key_file = g_key_file_new();
		if (!g_key_file_load_from_file(key_file, fn, G_KEY_FILE_NONE, &error))
			errx(1, "%s", error->message);

		nodisplay_v = g_key_file_get_boolean(key_file,
		    G_KEY_FILE_DESKTOP_GROUP,
		    G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY, NULL);
		if (nodisplay_v != FALSE)
			goto cont;

		name_v = g_key_file_get_locale_string(key_file,
		    G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME,
		    NULL, &error);
		if (name_v == NULL) {
			warnx("g_key_file_get_locale_string: %s",
			    error->message);
			g_clear_error(&error);
			goto cont;
		}

		if (!g_hash_table_add(entry_files, strdup(name_v)))
			goto cont;

		hidden_v = g_key_file_get_boolean(key_file,
		    G_KEY_FILE_DESKTOP_GROUP,
		    G_KEY_FILE_DESKTOP_KEY_HIDDEN, NULL);
		if (hidden_v != FALSE)
			goto cont;

		exec_v = g_key_file_get_locale_string(key_file,
		    G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC,
		    NULL, &error);
		if (exec_v == NULL) {
			warnx("g_key_file_get_locale_string: %s",
			    error->message);
			g_clear_error(&error);
			goto cont;
		}

		field_code_flags = field_codes(exec_v);

		icon_v = g_key_file_get_locale_string(key_file,
		    G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON,
		    NULL, &error);
		g_clear_error(&error);

		use_term_v = g_key_file_get_boolean(key_file,
		    G_KEY_FILE_DESKTOP_GROUP,
		    G_KEY_FILE_DESKTOP_KEY_TERMINAL, NULL);
		g_clear_error(&error);

		gtk_list_store_insert_with_values(apps, NULL, -1,
		    NAME_COLUMN, name_v,
		    EXEC_COLUMN, exec_v,
		    FCODE_COLUMN, field_code_flags,
		    ICON_COLUMN, icon_v,
		    TERM_COLUMN, use_term_v,
		    -1);

cont:
		free(exec_v); exec_v = NULL;
		free(name_v); name_v = NULL;
		free(icon_v); icon_v = NULL;
		free(fn); fn = NULL;
		if (key_file) {
			g_key_file_free(key_file);
			key_file = NULL;
		}
	}
}
예제 #3
0
static void
add_group_to_hashtable (struct group *gr,
                       gpointer user_data)
{
  g_hash_table_add (user_data, g_strdup (gr->gr_name));
}
예제 #4
0
static void
process_lldp_neighbors (NMLldpListener *self)
{
	NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE (self);
	sd_lldp_packet **packets = NULL;
	GHashTable *hash;
	int num, i;

	num = sd_lldp_get_packets (priv->lldp_handle, &packets);
	if (num < 0) {
		nm_log_dbg (LOGD_DEVICE, "LLDP: error %d retrieving neighbor packets for %s",
		            num, priv->iface);
		return;
	}

	hash = g_hash_table_new_full (lldp_neighbor_id_hash, lldp_neighbor_id_equal,
	                              lldp_neighbor_free, NULL);

	for (i = 0; packets && i < num; i++) {
		uint8_t chassis_id_type, port_id_type, *chassis_id, *port_id, data8;
		uint16_t chassis_id_len, port_id_len, len, data16;
		LLDPNeighbor *neigh;
		GValue *value;
		char *str;
		int r;

		if (i >= MAX_NEIGHBORS)
			goto next_packet;

		r = sd_lldp_packet_read_chassis_id (packets[i], &chassis_id_type,
		                                    &chassis_id, &chassis_id_len);
		if (r < 0)
			goto next_packet;

		r = sd_lldp_packet_read_port_id (packets[i], &port_id_type,
		                                 &port_id, &port_id_len);
		if (r < 0)
			goto next_packet;

		neigh = g_malloc0 (sizeof (LLDPNeighbor));
		neigh->tlvs = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, gvalue_destroy);
		neigh->chassis_id_type = chassis_id_type;
		neigh->port_id_type = port_id_type;
		sd_lldp_packet_get_destination_type (packets[i], &neigh->dest);

		if (chassis_id_len < 1) {
			lldp_neighbor_free (neigh);
			goto next_packet;
		}

		switch (chassis_id_type) {
		case LLDP_CHASSIS_SUBTYPE_INTERFACE_ALIAS:
		case LLDP_CHASSIS_SUBTYPE_INTERFACE_NAME:
		case LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED:
		case LLDP_CHASSIS_SUBTYPE_CHASSIS_COMPONENT:
			neigh->chassis_id = strndup ((char *) chassis_id, chassis_id_len);
			break;
		case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS:
			neigh->chassis_id = nm_utils_hwaddr_ntoa (chassis_id, chassis_id_len);
			break;
		default:
			nm_log_dbg (LOGD_DEVICE, "LLDP: unsupported chassis ID type %d", chassis_id_type);
			lldp_neighbor_free (neigh);
			goto next_packet;
		}

		if (port_id_len < 1) {
			lldp_neighbor_free (neigh);
			goto next_packet;
		}

		switch (port_id_type) {
		case LLDP_PORT_SUBTYPE_INTERFACE_ALIAS:
		case LLDP_PORT_SUBTYPE_INTERFACE_NAME:
		case LLDP_PORT_SUBTYPE_LOCALLY_ASSIGNED:
		case LLDP_PORT_SUBTYPE_PORT_COMPONENT:
			neigh->port_id = strndup ((char *) port_id, port_id_len);
			break;
		case LLDP_PORT_SUBTYPE_MAC_ADDRESS:
			neigh->port_id = nm_utils_hwaddr_ntoa (port_id, port_id_len);
			break;
		default:
			nm_log_dbg (LOGD_DEVICE, "LLDP: unsupported port ID type %d", port_id_type);
			lldp_neighbor_free (neigh);
			goto next_packet;
		}

		if (sd_lldp_packet_read_port_description (packets[i], &str, &len) == 0) {
			value = gvalue_new_nstr (str, len);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_PORT_DESCRIPTION, value);
		}

		if (sd_lldp_packet_read_system_name (packets[i], &str, &len) == 0) {
			value = gvalue_new_nstr (str, len);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_SYSTEM_NAME, value);
		}

		if (sd_lldp_packet_read_system_description (packets[i], &str, &len) == 0) {
			value = gvalue_new_nstr (str, len);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, value);
		}

		if (sd_lldp_packet_read_system_capability (packets[i], &data16) == 0) {
			value = gvalue_new_uint (data16);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_SYSTEM_CAPABILITIES, value);
		}

		if (sd_lldp_packet_read_port_vlan_id (packets[i], &data16) == 0) {
			value = gvalue_new_uint (data16);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_IEEE_802_1_PVID, value);
		}

		if (sd_lldp_packet_read_port_protocol_vlan_id (packets[i], &data8, &data16) == 0) {
			value = gvalue_new_uint (data16);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_IEEE_802_1_PPVID, value);

			value = gvalue_new_uint (data8);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS, value);
		}

		if (sd_lldp_packet_read_vlan_name (packets[i], &data16, &str, &len) == 0) {
			value = gvalue_new_uint (data16);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_IEEE_802_1_VID, value);

			value = gvalue_new_nstr (str, len);
			g_hash_table_insert (neigh->tlvs, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, value);
		}

		nm_log_dbg (LOGD_DEVICE, "LLDP: new neigh: CHASSIS='%s' PORT='%s'",
		            neigh->chassis_id, neigh->port_id);

		g_hash_table_add (hash, neigh);
next_packet:
		sd_lldp_packet_unref (packets[i]);
	}

	g_free (packets);

	if (lldp_hash_table_equal (priv->lldp_neighbors, hash)) {
		g_hash_table_destroy (hash);
	} else {
		g_hash_table_destroy (priv->lldp_neighbors);
		priv->lldp_neighbors = hash;
		nm_clear_g_variant (&priv->variant);
		g_object_notify (G_OBJECT (self), NM_LLDP_LISTENER_NEIGHBORS);
	}

	/* Since the processing of the neighbor list is potentially
	 * expensive when there are many neighbors, coalesce multiple
	 * events arriving in short time.
	 */
	priv->timer = g_timeout_add_seconds (MIN_UPDATE_INTERVAL, lldp_timeout, self);
	priv->num_pending_events = 0;
}
static void
get_locale_infos (GtkWidget *chooser)
{
  CcInputChooserPrivate *priv = GET_PRIVATE (chooser);
  GHashTable *layouts_with_locale;
  LocaleInfo *info;
  gchar **locale_ids;
  gchar **locale;
  GList *list, *l;

  priv->locales = g_hash_table_new_full (g_str_hash, g_str_equal,
                                         NULL, locale_info_free);
  priv->locales_by_language = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                     g_free, (GDestroyNotify) g_hash_table_destroy);

  layouts_with_locale = g_hash_table_new (g_str_hash, g_str_equal);

  locale_ids = gnome_get_all_locales ();
  for (locale = locale_ids; *locale; ++locale)
    {
      gchar *lang_code, *country_code;
      gchar *simple_locale;
      gchar *tmp;
      const gchar *type = NULL;
      const gchar *id = NULL;

      if (!gnome_parse_locale (*locale, &lang_code, &country_code, NULL, NULL))
        continue;

      if (country_code != NULL)
	simple_locale = g_strdup_printf ("%s_%s.UTF-8", lang_code, country_code);
      else
	simple_locale = g_strdup_printf ("%s.UTF-8", lang_code);

      if (g_hash_table_contains (priv->locales, simple_locale))
        {
          g_free (simple_locale);
          g_free (country_code);
          g_free (lang_code);
          continue;
        }

      info = g_new0 (LocaleInfo, 1);
      info->id = simple_locale; /* Take ownership */
      info->name = gnome_get_language_from_locale (simple_locale, NULL);
      info->unaccented_name = cc_util_normalize_casefold_and_unaccent (info->name);
      tmp = gnome_get_language_from_locale (simple_locale, "C");
      info->untranslated_name = cc_util_normalize_casefold_and_unaccent (tmp);
      g_free (tmp);

      g_hash_table_replace (priv->locales, simple_locale, info);
      add_locale_to_table (priv->locales_by_language, lang_code, info);

      if (gnome_get_input_source_from_locale (simple_locale, &type, &id) &&
          g_str_equal (type, INPUT_SOURCE_TYPE_XKB))
        {
          add_default_row (chooser, info, type, id);
          g_hash_table_add (layouts_with_locale, (gpointer) id);
        }

      /* We don't own these ids */
      info->layout_rows_by_id = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                       NULL, g_object_unref);
      info->engine_rows_by_id = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                       NULL, g_object_unref);

      list = gnome_xkb_info_get_layouts_for_language (priv->xkb_info, lang_code);
      add_rows_to_table (chooser, info, list, INPUT_SOURCE_TYPE_XKB, id);
      add_ids_to_set (layouts_with_locale, list);
      g_list_free (list);

      if (country_code != NULL)
        {
          list = gnome_xkb_info_get_layouts_for_country (priv->xkb_info, country_code);
          add_rows_to_table (chooser, info, list, INPUT_SOURCE_TYPE_XKB, id);
          add_ids_to_set (layouts_with_locale, list);
          g_list_free (list);
        }

      g_free (lang_code);
      g_free (country_code);
    }
  g_strfreev (locale_ids);

  /* Add a "Other" locale to hold the remaining input sources */
  info = g_new0 (LocaleInfo, 1);
  info->id = g_strdup ("");
  info->name = g_strdup (C_("Keyboard Layout", "Other"));
  info->unaccented_name = g_strdup ("");
  info->untranslated_name = g_strdup ("");
  g_hash_table_replace (priv->locales, info->id, info);

  info->layout_rows_by_id = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   NULL, g_object_unref);
  info->engine_rows_by_id = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                   NULL, g_object_unref);

  list = gnome_xkb_info_get_all_layouts (priv->xkb_info);
  for (l = list; l; l = l->next)
    if (!g_hash_table_contains (layouts_with_locale, l->data))
      add_row_other (chooser, INPUT_SOURCE_TYPE_XKB, l->data);

  g_list_free (list);

  g_hash_table_destroy (layouts_with_locale);
}
예제 #6
0
파일: drun.c 프로젝트: pfsmorigo/rofi
/**
 * This function absorbs/freeś path, so this is no longer available afterwards.
 */
static gboolean read_desktop_file ( DRunModePrivateData *pd, const char *root, const char *path )
{
    // Create ID on stack.
    // We know strlen (path ) > strlen(root)+1
    const ssize_t id_len = strlen ( path ) - strlen ( root );
    char          id[id_len];
    g_strlcpy ( id, &( path[strlen ( root ) + 1] ), id_len );
    for ( int index = 0; index < id_len; index++ ) {
        if ( id[index] == '/' ) {
            id[index] = '-';
        }
    }

    // Check if item is on disabled list.
    if ( g_hash_table_contains ( pd->disabled_entries, id ) ) {
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Skipping: %s, was previously seen.", id );
        return TRUE;
    }
    GKeyFile *kf    = g_key_file_new ();
    GError   *error = NULL;
    g_key_file_load_from_file ( kf, path, 0, &error );
    // If error, skip to next entry
    if ( error != NULL ) {
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Failed to parse desktop file: %s because: %s", path, error->message );
        g_error_free ( error );
        g_key_file_free ( kf );
        return FALSE;
    }
    // Skip non Application entries.
    gchar *key = g_key_file_get_string ( kf, "Desktop Entry", "Type", NULL );
    if ( key == NULL ) {
        // No type? ignore.
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Skipping desktop file: %s because: No type indicated", path );
        g_key_file_free ( kf );
        return FALSE;
    }
    if ( g_strcmp0 ( key, "Application" ) ) {
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Skipping desktop file: %s because: Not of type application (%s)", path, key );
        g_free ( key );
        g_key_file_free ( kf );
        return FALSE;
    }
    g_free ( key );

    // Name key is required.
    if ( !g_key_file_has_key ( kf, "Desktop Entry", "Name", NULL ) ) {
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Invalid DesktopFile: '%s', no 'Name' key present.\n", path );
        g_key_file_free ( kf );
        return FALSE;
    }

    // Skip hidden entries.
    if ( g_key_file_get_boolean ( kf, "Desktop Entry", "Hidden", NULL ) ) {
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Adding desktop file: %s to disabled list because: Hdden", path );
        g_key_file_free ( kf );
        g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) );
        return FALSE;
    }
    // Skip entries that have NoDisplay set.
    if ( g_key_file_get_boolean ( kf, "Desktop Entry", "NoDisplay", NULL ) ) {
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Adding desktop file: %s to disabled list because: NoDisplay", path );
        g_key_file_free ( kf );
        g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) );
        return FALSE;
    }
    // We need Exec, don't support DBusActivatable
    if ( !g_key_file_has_key ( kf, "Desktop Entry", "Exec", NULL ) ) {
        g_log ( LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Unsupported DesktopFile: '%s', no 'Exec' key present.\n", path );
        g_key_file_free ( kf );
        return FALSE;
    }
    size_t nl = ( ( pd->cmd_list_length ) + 1 );
    if ( nl >= pd->cmd_list_length_actual ) {
        pd->cmd_list_length_actual += 256;
        pd->entry_list              = g_realloc ( pd->entry_list, pd->cmd_list_length_actual * sizeof ( *( pd->entry_list ) ) );
    }
    pd->entry_list[pd->cmd_list_length].root = g_strdup ( root );
    pd->entry_list[pd->cmd_list_length].path = g_strdup ( path );
    gchar *n = g_key_file_get_locale_string ( kf, "Desktop Entry", "Name", NULL, NULL );
    pd->entry_list[pd->cmd_list_length].name = n;
    gchar *gn = g_key_file_get_locale_string ( kf, "Desktop Entry", "GenericName", NULL, NULL );
    pd->entry_list[pd->cmd_list_length].generic_name = gn;
#ifdef GET_CAT_PARSE_TIME
    pd->entry_list[pd->cmd_list_length].categories = g_key_file_get_locale_string_list ( kf, "Desktop Entry", "Categories", NULL, NULL, NULL );
#endif
    pd->entry_list[pd->cmd_list_length].exec = g_key_file_get_string ( kf, "Desktop Entry", "Exec", NULL );

    // Keep keyfile around.
    pd->entry_list[pd->cmd_list_length].key_file = kf;
    // We don't want to parse items with this id anymore.
    g_hash_table_add ( pd->disabled_entries, g_strdup ( id ) );
    ( pd->cmd_list_length )++;
    return TRUE;
}
예제 #7
0
/**
 * Erzeugt alle möglichen Spielbretter mit zwei bis zu 10 Spielfiguren
 * für eine variable Spielbrettgröße.
 * Hierbei wird figurenweise vorgegangen. Die Figuren werden auf die 
 * Felder gesetzt. Dabei kommt es zur Mehrfacherzeugung von gleichen
 * Brettern, wenn es mehr als 10 Felder auf dem Spielbrett gibt. 
 */
void spielbretter_berechne(spielbretter_t *bretter)
{
    
    /*Zähler für die Anzahl der generierten Spielbretter*/
    long zaehler_bretter_gesamt = 0;
    /* Zaehlt wie viel spielbretter für eine bestimmte Figurenanzahl erstellt werden */
    long zaehler_bretter_figuren;
    long zaehlerLoesbareBretter = 0;
    long zaehlerLoesbareBretterGesamt = 0;
    

    /* time measurement variables */
    struct timeval start_time;       /* time when program started        */
    struct timeval comp_time;        /* time when calculation completed    */
    struct timeval start_time_figur;      /* start zeit figuren durchlauf */
    struct timeval comp_time_figur;      /* endzeit vom figurenduchlauf */
    
    //if(bretter->prozessNummer == 0)
    {
        gettimeofday(&start_time, NULL);
        gettimeofday(&start_time_figur, NULL); 
    }
	

	/* Spielbrettvariablen, für die verschiedenen Ebenen der for-Schleifen, 
	 * da jede Schleife eigene lokale Variablen braucht, um Überschreiben zu verhindern
	 * Alternative: Zurückrechnen, am Ende der jeweiligen Schleife - aufwendiger */
	sp_okt_t spielbrett_Leer,
			  spielbrett_Dame,
			  spielbrett_Koenig,
			  spielbrett_Springer1, spielbrett_Springer2,
			  spielbrett_Laeufer1, spielbrett_Laeufer2,
			  spielbrett_Turm1, spielbrett_Turm2,
			  spielbrett_Bauer1, spielbrett_Bauer2;
			  
	/*Anzahl der maximal noch setzbaren Figuren
	 * verschiedene Ebenen der for-Schleifen brauchen eigene lokale Variablen, um Überschreiben zu verhindern */
	int anzFiguren_Start,
		anzFiguren_Dame,
		anzFiguren_Koenig,
		anzFiguren_Springer1, anzFiguren_Springer2,
		anzFiguren_Laeufer1, anzFiguren_Laeufer2,
		anzFiguren_Turm1, anzFiguren_Turm2,
		anzFiguren_Bauer1, anzFiguren_Bauer2;
		




	/* Anzahl der Felder, über die iteriert werden muss */
	int anzFelder = SpielbrettBreite * SpielbrettHoehe;
    
    
	spielbrett_Leer = 0;
	anzFiguren_Start = 0;
	spielbrett_Bauer2 = 0;
	
    
    /* initialisiere Hashtabellen zuordnung in Bretter */ 
    bretter->vorgaengerSpielbretter = 0;
    bretter->aktuelleSpielbretter = 1;
    
    /* erzeuge Hashtabellen */
	erzeugeHashtables(bretter);
    
    /* Spielbretter mit einer figur erzeugen */
	spielbretterErzeugung1Figur(bretter);
        
    
	for(int maxFiguren=2; maxFiguren <= 10; maxFiguren++)
    {
        zaehler_bretter_figuren = 0;
        zaehlerLoesbareBretter = 0;
    
        /* Iteration für die Dame über alle Felder und ein zusätzlicher Durchlauf für den Fall: keine Dame
         * für alle anderen Figuren analog!*/
         
        if(bretter->prozessNummer == 0)
        {
            printf("====== Beginne %2d Figuren =======",maxFiguren );
        }
         
        for(int posDame=0; posDame<=anzFelder; posDame++)
        {	
            /* MPI Zuweisung der Schleifen zu den Prozessen. */
            if(bretter->prozessNummer == (int) ((bretter->anzahlProzesse/(anzFelder+1.0)) * posDame))
            {
                //printf(" Prozess %d berechnet posDame %d\n",bretter->prozessNummer, posDame );
                anzFiguren_Dame = anzFiguren_Start;
                spielbrett_Dame = spielbrett_Leer;
                
                if(posDame<anzFelder)
                {
                    /* posDame * 3, da die Figurenrepräsentation Oktal erfolgt und 3 Binärstellen eine Oktalstelle sind*/
                    spielbrett_Dame +=  (DarstellungDame << posDame*3);
                    anzFiguren_Dame ++; 
                }
                
                /* Iteration für den König */
                omp_set_nested(1);
               #pragma omp parallel for \
                    private(anzFiguren_Koenig, anzFiguren_Springer1, anzFiguren_Springer2, anzFiguren_Laeufer1, anzFiguren_Laeufer2, anzFiguren_Turm1, anzFiguren_Turm2, anzFiguren_Bauer1, anzFiguren_Bauer2, spielbrett_Koenig, spielbrett_Springer1, spielbrett_Springer2, spielbrett_Laeufer1, spielbrett_Laeufer2, spielbrett_Turm1, spielbrett_Turm2, spielbrett_Bauer1, spielbrett_Bauer2) \
                    schedule(dynamic)\
                    reduction (+: zaehlerLoesbareBretter, zaehler_bretter_figuren)
                    
                for(int posKoenig=0; posKoenig<=anzFelder; posKoenig++)
                {	
                    anzFiguren_Koenig = anzFiguren_Dame;
                    spielbrett_Koenig = spielbrett_Dame;
                    
                    if(!(anzFiguren_Koenig < maxFiguren))
                    {
                        posKoenig = anzFelder;
                    }
                    
                    
                    if(feldFrei(&posKoenig, &spielbrett_Dame))
                    {
                        if(posKoenig<anzFelder)
                        {
                            spielbrett_Koenig += (DarstellungKoenig << posKoenig*3);
                            anzFiguren_Koenig ++; 
                        }
                        
                        
                        /* Iteration für den Springer */
                       #pragma omp parallel for \
                            num_threads ( bretter->nestedMax ) \
                            private(anzFiguren_Springer1, anzFiguren_Springer2, anzFiguren_Laeufer1, anzFiguren_Laeufer2, anzFiguren_Turm1, anzFiguren_Turm2, anzFiguren_Bauer1, anzFiguren_Bauer2, spielbrett_Springer1, spielbrett_Springer2, spielbrett_Laeufer1, spielbrett_Laeufer2, spielbrett_Turm1, spielbrett_Turm2, spielbrett_Bauer1, spielbrett_Bauer2) \
                            schedule(dynamic)\
                            reduction (+: zaehlerLoesbareBretter, zaehler_bretter_figuren)
                        for(int posSpringer1=0; posSpringer1<=anzFelder; posSpringer1++)
                        {
                            anzFiguren_Springer1 = anzFiguren_Koenig;
                            spielbrett_Springer1 = spielbrett_Koenig;
                            
                            if(!(anzFiguren_Springer1 < maxFiguren))
                            {
                                posSpringer1 = anzFelder;
                            }
                            
                            
                            if(feldFrei(&posSpringer1, &spielbrett_Koenig))
                            {
                                if(posSpringer1<anzFelder)
                                {
                                    spielbrett_Springer1 += (DarstellungSpringer << posSpringer1*3); 
                                    anzFiguren_Springer1 ++;
                                }
                                
                                /* Iteration für den Springer2 
                                 * geänderte Startposition, um Duplikate zu vermeiden
                                 * analog für andere doppelte Figuren */
                                for(int posSpringer2=posSpringer1; posSpringer2<=anzFelder; posSpringer2++)
                                {
                                    anzFiguren_Springer2 = anzFiguren_Springer1;
                                    spielbrett_Springer2 = spielbrett_Springer1;
                                    
                                    if(!(anzFiguren_Springer2 < maxFiguren))
                                    {
                                        posSpringer2 = anzFelder;
                                    }
                                    
                                    if(feldFrei(&posSpringer2, &spielbrett_Springer1))
                                    {
                                        if(posSpringer2<anzFelder)
                                        {
                                            spielbrett_Springer2 += (DarstellungSpringer << posSpringer2*3);
                                            anzFiguren_Springer2 ++;
                                        }
                                        
                                        /* Iteration für den Läufer1 */
                                        for(int posLaeufer1=0; posLaeufer1<=anzFelder; posLaeufer1++)
                                        {
                                            anzFiguren_Laeufer1 = anzFiguren_Springer2;
                                            spielbrett_Laeufer1 = spielbrett_Springer2;
                                            
                                            if(!(anzFiguren_Laeufer1 < maxFiguren))
                                            {
                                                posLaeufer1 = anzFelder;
                                            }
                                            
                                            
                                            if(feldFrei(&posLaeufer1, &spielbrett_Springer2))
                                            {
                                                if(posLaeufer1<anzFelder)
                                                {
                                                    spielbrett_Laeufer1 += (DarstellungLaeufer << posLaeufer1*3);
                                                    anzFiguren_Laeufer1++;
                                                }

                                                /* Iteration für den Läufer2 */
                                                for(int posLaeufer2=posLaeufer1; posLaeufer2<=anzFelder; posLaeufer2++)
                                                {
                                                    anzFiguren_Laeufer2 = anzFiguren_Laeufer1;
                                                    spielbrett_Laeufer2 = spielbrett_Laeufer1;
                                                    
                                                    if(!(anzFiguren_Laeufer2 < maxFiguren))
                                                    {
                                                        posLaeufer2 = anzFelder;
                                                    }
                                                    
                                                    if(feldFrei(&posLaeufer2, &spielbrett_Laeufer1))
                                                    {
                                                        if(posLaeufer2<anzFelder)
                                                        {    
                                                            spielbrett_Laeufer2 += (DarstellungLaeufer << posLaeufer2*3);
                                                            anzFiguren_Laeufer2++;
                                                        }

                                                        /* Iteration für den Turm1 */
                                                        for(int posTurm1=0; posTurm1<=anzFelder; posTurm1++)
                                                        {
                                                            anzFiguren_Turm1 = anzFiguren_Laeufer2;
                                                            spielbrett_Turm1 = spielbrett_Laeufer2;
                                                            
                                                            if(!(anzFiguren_Turm1 < maxFiguren))
                                                            {
                                                                posTurm1 = anzFelder;
                                                            }
                                                            
                                                            if(feldFrei(&posTurm1, &spielbrett_Laeufer2))
                                                            {
                                                                if(posTurm1<anzFelder)
                                                                {
                                                                    spielbrett_Turm1 += (DarstellungTurm << posTurm1*3);
                                                                    anzFiguren_Turm1++;
                                                                }
                                                                
                                                                /* Iteration für den Turm2 */
                                                                for(int posTurm2=posTurm1; posTurm2<=anzFelder; posTurm2++)
                                                                {
                                                                    anzFiguren_Turm2 = anzFiguren_Turm1;
                                                                    spielbrett_Turm2 = spielbrett_Turm1;
                                                                    
                                                                    if(!(anzFiguren_Turm2 < maxFiguren))
                                                                    {
                                                                        posTurm2 = anzFelder;
                                                                    }
                                                    
                                                                    if(feldFrei(&posTurm2, &spielbrett_Turm1))
                                                                    {
                                                                        if(posTurm2<anzFelder){
                                                                            spielbrett_Turm2 += (DarstellungTurm << posTurm2*3);
                                                                            anzFiguren_Turm2++;
                                                                        }
                                                                        
                                                                        /* Iteration für den Bauer1 */
                                                                        for(int posBauer1=0; posBauer1<=anzFelder; posBauer1++)
                                                                        {
                                                                            anzFiguren_Bauer1 = anzFiguren_Turm2;
                                                                            spielbrett_Bauer1 = spielbrett_Turm2;
                                                                            
                                                                            if(!(anzFiguren_Bauer1 < maxFiguren))
                                                                            {
                                                                                posBauer1 = anzFelder;
                                                                            }
                                                    
                                                                            if(feldFrei(&posBauer1, &spielbrett_Turm2))
                                                                            {
                                                                                if(posBauer1<anzFelder)
                                                                                {
                                                                                    spielbrett_Bauer1 += (DarstellungBauer << posBauer1*3);
                                                                                    anzFiguren_Bauer1++;
                                                                                }
                                                                                
                                                                                /* Iteration für den Bauer2 */
                                                                                for(int posBauer2=posBauer1; posBauer2<=anzFelder; posBauer2++)
                                                                                {
                                                                                    anzFiguren_Bauer2 = anzFiguren_Bauer1;
                                                                                    spielbrett_Bauer2 = spielbrett_Bauer1;
                                                                                    
                                                                                    if(!(anzFiguren_Bauer2 < maxFiguren))
                                                                                    {
                                                                                        posBauer2 = anzFelder;
                                                                                    }
                                                    
                                                                                    if(feldFrei(&posBauer2, &spielbrett_Bauer1))
                                                                                    {
                                                                                        if(posBauer2<anzFelder)
                                                                                        {
                                                                                            spielbrett_Bauer2 += (DarstellungBauer << posBauer2*3);
                                                                                            anzFiguren_Bauer2++;
                                                                                        }
                                                                                        
                                                                                        
                                                                                        if(anzFiguren_Bauer2 == maxFiguren)
                                                                                        {
                                                                                            /* Berechne Spielbrett und erhöhe Zähler, wenn lösbar */
                                                                                            zaehlerLoesbareBretter += spielbrettBerechne(spielbrett_Bauer2, bretter);
                                                                                        
                                                                                            
                                                                                            /* Zähler für die Statistik*/
                                                                                            
                                                                                            zaehler_bretter_figuren++;
                                                            
                                                                                        }
                                                                                    }
                                                                                } /* Schleife Bauer2 */
                                                                            }
                                                                        } /* Schleife Bauer1 */
                                                                    }
                                                                } /* Schleife Turm2 */
                                                            }
                                                        } /* Schleife Turm1 */
                                                    }
                                                } /* Schleife Läufer2 */
                                            }
                                        }/* Schleife Läufer1 */
                                    }
                                } /* Schleife Springer2 */
                            }
                        } /* Schleife Springer1 */
                    }
                } /* Schleife König */
            }
        } /* Schleife Dame */
        

     
        /* Statistikwert speichern */
     
        bretter->anzahlBretter[maxFiguren] = zaehler_bretter_figuren;
        zaehler_bretter_gesamt += zaehler_bretter_figuren;
        bretter->loesbareBretter[maxFiguren] = zaehlerLoesbareBretter;
        zaehlerLoesbareBretterGesamt += zaehlerLoesbareBretter;
    
    
        gettimeofday(&comp_time_figur, NULL);
        bretter->berechnungsZeit[maxFiguren] = (comp_time_figur.tv_sec - start_time_figur.tv_sec) + (comp_time_figur.tv_usec - start_time_figur.tv_usec) * 1e-6;
        gettimeofday(&start_time_figur, NULL);
        
        if(bretter->prozessNummer == 0)
        {
            printf(" Fertig nach %8.3f ======\n",bretter->berechnungsZeit[maxFiguren] );
        }
        
        /* Warten bis alle Prozess fertig sind */
        MPI_Barrier(MPI_COMM_WORLD); 
        
        /* nicht mehr benötigte Hashtabellen freigeben */
        g_hash_table_remove_all( bretter->spielbretterHashtables[bretter->vorgaengerSpielbretter]);
        /* Hashtabelle für aktuelle Bretter zu Vorgänger Brettern machen und umgekehrt */ 
        int temp = bretter->aktuelleSpielbretter;
        bretter->aktuelleSpielbretter = bretter->vorgaengerSpielbretter;
        bretter->vorgaengerSpielbretter = temp;
        
        
        /* Buffer und ihre Größe zum Empfangen der Spielbretter */
        sp_okt_t *spielbretterBuf[bretter->anzahlProzesse];
        unsigned int spielbretterBufSize[bretter->anzahlProzesse];
        
        spielbretterBuf[bretter->prozessNummer] = malloc(g_hash_table_size(bretter->spielbretterHashtables[bretter->vorgaengerSpielbretter])* sizeof(sp_okt_t));
        
        GHashTableIter iter;
        gpointer key, value;
        
        
        int i = 0;
        g_hash_table_iter_init (&iter, bretter->spielbretterHashtables[bretter->vorgaengerSpielbretter]);
        while (g_hash_table_iter_next (&iter, &key, &value))
        {
            spielbretterBuf[bretter->prozessNummer][i] = (sp_okt_t) value;
            i++;
        }
        
        
        for(int prozess= 0; prozess < bretter->anzahlProzesse; prozess++)
        {
            
            if(bretter->prozessNummer == prozess)
            {
                /* Größe des Buffer aus der Hashytabellen Größe ableiten */
                spielbretterBufSize[prozess] = g_hash_table_size(bretter->spielbretterHashtables[bretter->vorgaengerSpielbretter]);
            }
            
            /* Größe der Hashtabelle an alle senden */
            MPI_Bcast (&spielbretterBufSize[prozess],1 , MPI_UNSIGNED, prozess, MPI_COMM_WORLD);
            /* Buffer für Datenempfang allozieren */
            if(bretter->prozessNummer != prozess)
            {
                spielbretterBuf[prozess] = malloc(spielbretterBufSize[prozess]* sizeof(sp_okt_t));
            }

            /* Inhalt der Hashtabelle aus dem Buffer an alle senden */
            MPI_Bcast (spielbretterBuf[prozess], spielbretterBufSize[prozess], MPI_UNSIGNED_LONG, prozess, MPI_COMM_WORLD);
        }
        
        
        /* Schreiben der Buffer in die Hashtabelle */
        for(int prozess= 0; prozess < bretter->anzahlProzesse; prozess++)
        {
            if(bretter->prozessNummer != prozess)
            {
                for(unsigned int s = 0; s < spielbretterBufSize[prozess]; s++)
                {
                    g_hash_table_add(bretter->spielbretterHashtables[bretter->vorgaengerSpielbretter],(gpointer) spielbretterBuf[prozess][s]);
                }            
            }
            /* Speicher freigeben */
            free(spielbretterBuf[prozess]);
        }
        
    }
    
    /* Statistik */
    /* Bretterzähler von Prozessen einsammeln */
    MPI_Reduce (&zaehlerLoesbareBretterGesamt, &bretter->loesbareBretterGesamt, 1, MPI_UNSIGNED_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
    MPI_Reduce (&zaehler_bretter_gesamt, &bretter->anzahlBretterGesamt, 1, MPI_UNSIGNED_LONG, MPI_SUM, 0, MPI_COMM_WORLD);
    
    if(bretter->prozessNummer == 0)
    {
        MPI_Reduce (MPI_IN_PLACE, bretter->loesbareBretter, 11, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
        MPI_Reduce (MPI_IN_PLACE, bretter->anzahlBretter, 11, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
        /* Mehrfachzählen der 1 Figurenbretter rückgängig machen */
        bretter->loesbareBretter[1] /= bretter->anzahlProzesse;
        bretter->anzahlBretter[1] /= bretter->anzahlProzesse;
    }
    else
    {
        MPI_Reduce (bretter->loesbareBretter, 0, 11, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
        MPI_Reduce (bretter->anzahlBretter, 0, 11, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
    }
    
    MPI_Reduce (bretter->berechnungsZeit, bretter->berechnungsZeitMax, 11, MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
    MPI_Reduce (bretter->berechnungsZeit, bretter->berechnungsZeitMin, 11, MPI_DOUBLE, MPI_MIN, 0, MPI_COMM_WORLD);
    MPI_Reduce (bretter->berechnungsZeit, bretter->berechnungsZeitAvg, 11, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
    
    /* Summe der Zeiten zu Durchschnitt machen */
    if(bretter->prozessNummer == 0)
    { 
        for(int x = 0; x<=10; x++)
        {
            bretter->berechnungsZeitAvg[x] = bretter->berechnungsZeitAvg[x]/bretter->anzahlProzesse;
        }
    }
    
    /* Speichern der Zeit für den nächsten Durchlauf */
    if(bretter->prozessNummer == 0)
    {   
        gettimeofday(&comp_time, NULL);
        bretter->berechnungsZeitGesamt = (comp_time.tv_sec - start_time.tv_sec) + (comp_time.tv_usec - start_time.tv_usec) * 1e-6;
    }
}
예제 #8
0
static void
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
{
  MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
  drmModeRes *resources;
  drmModeEncoder **encoders;
  GHashTable *modes;
  GHashTableIter iter;
  drmModeModeInfo *mode;
  unsigned int i, j, k;
  unsigned int n_actual_outputs;
  int width, height;
  MetaOutput *old_outputs;
  unsigned int n_old_outputs;

  resources = drmModeGetResources(manager_kms->fd);
  modes = g_hash_table_new (drm_mode_hash, drm_mode_equal);

  manager->max_screen_width = resources->max_width;
  manager->max_screen_height = resources->max_height;

  manager->power_save_mode = META_POWER_SAVE_ON;

  old_outputs = manager->outputs;
  n_old_outputs = manager->n_outputs;

  /* Note: we must not free the public structures (output, crtc, monitor
     mode and monitor info) here, they must be kept alive until the API
     users are done with them after we emit monitors-changed, and thus
     are freed by the platform-independent layer. */
  free_resources (manager_kms);

  manager_kms->n_connectors = resources->count_connectors;
  manager_kms->connectors = g_new (drmModeConnector *, manager_kms->n_connectors);
  for (i = 0; i < manager_kms->n_connectors; i++)
    {
      drmModeConnector *connector;

      connector = drmModeGetConnector (manager_kms->fd, resources->connectors[i]);
      manager_kms->connectors[i] = connector;

      if (connector && connector->connection == DRM_MODE_CONNECTED)
        {
          /* Collect all modes for this connector */
          for (j = 0; j < (unsigned)connector->count_modes; j++)
            g_hash_table_add (modes, &connector->modes[j]);
        }
    }

  encoders = g_new (drmModeEncoder *, resources->count_encoders);
  for (i = 0; i < (unsigned)resources->count_encoders; i++)
    encoders[i] = drmModeGetEncoder (manager_kms->fd, resources->encoders[i]);

  manager->n_modes = g_hash_table_size (modes);
  manager->modes = g_new0 (MetaMonitorMode, manager->n_modes);
  g_hash_table_iter_init (&iter, modes);
  i = 0;
  while (g_hash_table_iter_next (&iter, NULL, (gpointer)&mode))
    {
      MetaMonitorMode *meta_mode;

      meta_mode = &manager->modes[i];

      meta_mode->mode_id = i;
      meta_mode->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN);
      meta_mode->width = mode->hdisplay;
      meta_mode->height = mode->vdisplay;

      /* Calculate refresh rate in milliHz first for extra precision. */
      meta_mode->refresh_rate = (mode->clock * 1000000LL) / mode->htotal;
      meta_mode->refresh_rate += (mode->vtotal / 2);
      meta_mode->refresh_rate /= mode->vtotal;
      if (mode->flags & DRM_MODE_FLAG_INTERLACE)
	meta_mode->refresh_rate *= 2;
      if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
        meta_mode->refresh_rate /= 2;
      if (mode->vscan > 1)
        meta_mode->refresh_rate /= mode->vscan;
      meta_mode->refresh_rate /= 1000.0;

      meta_mode->driver_private = g_slice_dup (drmModeModeInfo, mode);
      meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;

      i++;
    }
  g_hash_table_destroy (modes);

  manager->n_crtcs = resources->count_crtcs;
  manager->crtcs = g_new0 (MetaCRTC, manager->n_crtcs);
  width = 0; height = 0;
  for (i = 0; i < (unsigned)resources->count_crtcs; i++)
    {
      drmModeCrtc *crtc;
      MetaCRTC *meta_crtc;

      crtc = drmModeGetCrtc (manager_kms->fd, resources->crtcs[i]);

      meta_crtc = &manager->crtcs[i];

      meta_crtc->crtc_id = crtc->crtc_id;
      meta_crtc->rect.x = crtc->x;
      meta_crtc->rect.y = crtc->y;
      meta_crtc->rect.width = crtc->width;
      meta_crtc->rect.height = crtc->height;
      meta_crtc->is_dirty = FALSE;
      meta_crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
      /* FIXME: implement! */
      meta_crtc->all_transforms = 1 << META_MONITOR_TRANSFORM_NORMAL;

      if (crtc->mode_valid)
        {
          for (j = 0; j < manager->n_modes; j++)
            {
              if (drm_mode_equal (&crtc->mode, manager->modes[j].driver_private))
                {
                  meta_crtc->current_mode = &manager->modes[j];
                  break;
                }
            }

          width = MAX (width, meta_crtc->rect.x + meta_crtc->rect.width);
          height = MAX (height, meta_crtc->rect.y + meta_crtc->rect.height);
        }

      meta_crtc->driver_private = g_new0 (MetaCRTCKms, 1);
      meta_crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
      find_crtc_properties (manager_kms, meta_crtc);
      init_crtc_rotations (manager, meta_crtc, i);

      drmModeFreeCrtc (crtc);
    }

  manager->screen_width = width;
  manager->screen_height = height;

  manager->outputs = g_new0 (MetaOutput, manager_kms->n_connectors);
  n_actual_outputs = 0;

  for (i = 0; i < manager_kms->n_connectors; i++)
    {
      MetaOutput *meta_output, *old_output;
      MetaOutputKms *output_kms;
      drmModeConnector *connector;
      GArray *crtcs;
      unsigned int crtc_mask;
      GBytes *edid;

      connector = manager_kms->connectors[i];
      meta_output = &manager->outputs[n_actual_outputs];

      if (connector && connector->connection == DRM_MODE_CONNECTED)
	{
          meta_output->driver_private = output_kms = g_slice_new0 (MetaOutputKms);
          meta_output->driver_notify = (GDestroyNotify)meta_output_destroy_notify;

	  meta_output->winsys_id = connector->connector_id;
	  meta_output->name = make_output_name (connector);
	  meta_output->width_mm = connector->mmWidth;
	  meta_output->height_mm = connector->mmHeight;

          switch (connector->subpixel)
            {
            case DRM_MODE_SUBPIXEL_NONE:
              meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_NONE;
              break;
            case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
              meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB;
              break;
            case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
              meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR;
              break;
            case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
              meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_RGB;
              break;
            case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
              meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_BGR;
              break;
            case DRM_MODE_SUBPIXEL_UNKNOWN:
            default:
              meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
              break;
            }

	  meta_output->preferred_mode = NULL;
	  meta_output->n_modes = connector->count_modes;
	  meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
	  for (j = 0; j < meta_output->n_modes; j++) {
            meta_output->modes[j] = find_meta_mode (manager, &connector->modes[j]);
            if (connector->modes[j].type & DRM_MODE_TYPE_PREFERRED)
              meta_output->preferred_mode = meta_output->modes[j];
          }

          if (!meta_output->preferred_mode)
            meta_output->preferred_mode = meta_output->modes[0];

          output_kms->connector = connector;
          output_kms->n_encoders = connector->count_encoders;
          output_kms->encoders = g_new0 (drmModeEncoderPtr, output_kms->n_encoders);

          crtc_mask = ~(unsigned int)0;
	  for (j = 0; j < output_kms->n_encoders; j++)
	    {
              output_kms->encoders[j] = drmModeGetEncoder (manager_kms->fd, connector->encoders[j]);
              if (!output_kms->encoders[j])
                continue;

              /* We only list CRTCs as supported if they are supported by all encoders
                 for this connectors.

                 This is what xf86-video-modesetting does (see drmmode_output_init())
              */
              crtc_mask &= output_kms->encoders[j]->possible_crtcs;

              if (output_kms->encoders[j]->encoder_id == connector->encoder_id)
                output_kms->current_encoder = output_kms->encoders[j];
            }

          crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCRTC*));

          for (j = 0; j < manager->n_crtcs; j++)
            {
              if (crtc_mask & (1 << j))
                {
                  MetaCRTC *crtc = &manager->crtcs[j];
                  g_array_append_val (crtcs, crtc);
		}
	    }

	  meta_output->n_possible_crtcs = crtcs->len;
	  meta_output->possible_crtcs = (void*)g_array_free (crtcs, FALSE);

          if (output_kms->current_encoder && output_kms->current_encoder->crtc_id != 0)
            {
              for (j = 0; j < manager->n_crtcs; j++)
                {
                  if (manager->crtcs[j].crtc_id == output_kms->current_encoder->crtc_id)
                    {
                      meta_output->crtc = &manager->crtcs[j];
                      break;
                    }
                }
            }
          else
            meta_output->crtc = NULL;

          old_output = find_output_by_id (old_outputs, n_old_outputs,
                                          meta_output->winsys_id);
          if (old_output)
            {
              meta_output->is_primary = old_output->is_primary;
              meta_output->is_presentation = old_output->is_presentation;
            }
          else
            {
              meta_output->is_primary = FALSE;
              meta_output->is_presentation = FALSE;
            }

          find_connector_properties (manager_kms, output_kms);
          meta_output->suggested_x = output_kms->suggested_x;
          meta_output->suggested_y = output_kms->suggested_y;
          meta_output->hotplug_mode_update = output_kms->hotplug_mode_update;
          
          edid = read_output_edid (manager_kms, meta_output);
          meta_output_parse_edid (meta_output, edid);
          g_bytes_unref (edid);

          /* MetaConnectorType matches DRM's connector types */
          meta_output->connector_type = (MetaConnectorType) connector->connector_type;

          meta_output->scale = get_output_scale (manager, meta_output);

          output_get_tile_info (manager_kms, meta_output);

          /* FIXME: backlight is a very driver specific thing unfortunately,
             every DDX does its own thing, and the dumb KMS API does not include it.

             For example, xf86-video-intel has a list of paths to probe in /sys/class/backlight
             (one for each major HW maker, and then some).
             We can't do the same because we're not root.
             It might be best to leave backlight out of the story and rely on the setuid
             helper in gnome-settings-daemon.
          */
	  meta_output->backlight_min = 0;
          meta_output->backlight_max = 0;
          meta_output->backlight = -1;

	  n_actual_outputs++;
	}
    }
예제 #9
0
/**
 * gst_rtsp_session_pool_filter:
 * @pool: a #GstRTSPSessionPool
 * @func: (scope call) (allow-none): a callback
 * @user_data: (closure): user data passed to @func
 *
 * Call @func for each session in @pool. The result value of @func determines
 * what happens to the session. @func will be called with the session pool
 * locked so no further actions on @pool can be performed from @func.
 *
 * If @func returns #GST_RTSP_FILTER_REMOVE, the session will be set to the
 * expired state with gst_rtsp_session_set_expired() and removed from
 * @pool.
 *
 * If @func returns #GST_RTSP_FILTER_KEEP, the session will remain in @pool.
 *
 * If @func returns #GST_RTSP_FILTER_REF, the session will remain in @pool but
 * will also be added with an additional ref to the result GList of this
 * function..
 *
 * When @func is %NULL, #GST_RTSP_FILTER_REF will be assumed for all sessions.
 *
 * Returns: (element-type GstRTSPSession) (transfer full): a GList with all
 * sessions for which @func returned #GST_RTSP_FILTER_REF. After usage, each
 * element in the GList should be unreffed before the list is freed.
 */
GList *
gst_rtsp_session_pool_filter (GstRTSPSessionPool * pool,
    GstRTSPSessionPoolFilterFunc func, gpointer user_data)
{
  GstRTSPSessionPoolPrivate *priv;
  GHashTableIter iter;
  gpointer key, value;
  GList *result;
  GHashTable *visited;
  guint cookie;

  g_return_val_if_fail (GST_IS_RTSP_SESSION_POOL (pool), NULL);

  priv = pool->priv;

  result = NULL;
  if (func)
    visited = g_hash_table_new_full (NULL, NULL, g_object_unref, NULL);

  g_mutex_lock (&priv->lock);
restart:
  g_hash_table_iter_init (&iter, priv->sessions);
  cookie = priv->sessions_cookie;
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    GstRTSPSession *session = value;
    GstRTSPFilterResult res;
    gboolean changed;

    if (func) {
      /* only visit each session once */
      if (g_hash_table_contains (visited, session))
        continue;

      g_hash_table_add (visited, g_object_ref (session));
      g_mutex_unlock (&priv->lock);

      res = func (pool, session, user_data);

      g_mutex_lock (&priv->lock);
    } else
      res = GST_RTSP_FILTER_REF;

    changed = (cookie != priv->sessions_cookie);

    switch (res) {
      case GST_RTSP_FILTER_REMOVE:
      {
        gboolean removed = TRUE;

        if (changed)
          /* something changed, check if we still have the session */
          removed = g_hash_table_remove (priv->sessions, key);
        else
          g_hash_table_iter_remove (&iter);

        if (removed) {
          /* if we managed to remove the session, update the cookie and
           * signal */
          cookie = ++priv->sessions_cookie;
          g_mutex_unlock (&priv->lock);

          g_signal_emit (pool,
              gst_rtsp_session_pool_signals[SIGNAL_SESSION_REMOVED], 0,
              session);

          g_mutex_lock (&priv->lock);
          /* cookie could have changed again, make sure we restart */
          changed |= (cookie != priv->sessions_cookie);
        }
        break;
      }
      case GST_RTSP_FILTER_REF:
        /* keep ref */
        result = g_list_prepend (result, g_object_ref (session));
        break;
      case GST_RTSP_FILTER_KEEP:
      default:
        break;
    }
    if (changed)
      goto restart;
  }
  g_mutex_unlock (&priv->lock);

  if (func)
    g_hash_table_unref (visited);

  return result;
}
예제 #10
0
/**
 * Berechnet ein einzelnes Spielbrett.
 * Funktioniert nur, wenn die Spielbretter mit weniger Figuren bereits berechnet 
 * sind!
 * Signatur nach GHRFunc() aus der gnome library 
 * 
 * @param spielbrett sp_okt_t  zuberechnendes spielbrett
 * @param bretter spielbretter * 
 * 
 */
static int spielbrettBerechne(sp_okt_t spielbrett, spielbretter_t *bretter)
{
    
    /* Zwischenspeicherung ob das Spielbrett bereits gelöst ist */
	long loesbar = 0;
    
    
    /* Param Stuct für den Aufruf der Spielfigurenberechnung */
    figuren_param_t param;
    /* Kopieren des Spielbretter Arrays */
    memcpy(param.spielbretterHashtables, bretter->spielbretterHashtables, sizeof(GHashTable*)*11);
    /* Kopiere Variable */
    param.aktuelleSpielbretter = bretter->aktuelleSpielbretter;
    param.vorgaengerSpielbretter = bretter->vorgaengerSpielbretter;
    /* Pointer auf spielbrett in prama speichern */
    param.spielbrett = &spielbrett;
    
    
    /* Zähler Variablen für die for-Scheifen */
    int x, y;
    
    
    /* Speicher allozieren für die Arraydarstellung des Spielbrettes */
    param.spielbrett_array = spielbretterArrayCreate(SpielbrettBreite, SpielbrettHoehe);
    

  
	/* Berechnung der Arraydarstellung aus Oktaldarstellung
	 * einfacher für die Überprüfung der Spielbrettgrenzen*/
    for(x=0; x < SpielbrettBreite; x++)
    {
        for(y=0; y < SpielbrettHoehe; y++)
        {   
			param.spielbrett_array[x][y] = (spielbrett >> ((x+(y*SpielbrettBreite)) * 3)) % 8;
        }
    }
    
	/* Berechnet, ob die Figuren an der jeweiligen Position schlagen können und daraus
	 * ein lösbares neues Spielbrett entsteht */
     
     
     for(x=0; (x < SpielbrettBreite) && (loesbar == 0); x++){
		for(y=0; (y < SpielbrettHoehe) && (loesbar == 0); y++){   
			switch(param.spielbrett_array[x][y]){
				case DarstellungBauer:
					loesbar= berechneBauer(&param, x, y);
					break;
				case DarstellungTurm:
					loesbar = berechneTurm(&param, x, y);
					break;
				case DarstellungLaeufer:
					loesbar = berechneLaeufer(&param, x, y);
					break;
				case DarstellungSpringer:
					loesbar = berechneSpringer(&param, x, y);
					break;
				case DarstellungKoenig:
					loesbar = berechneKoenig(&param, x, y);
					break;
				case DarstellungDame:
					loesbar = berechneDame(&param, x, y);
					break;
			}
		}
	}
    
    /* In der Hashtabelle speichern, wenn ein Spielbrett nicht lösbar ist */
    if(loesbar==0)
    {
        // Kritischer Bereich für omp
        #pragma omp critical (spielbrett_berechne_g_hash_add)
        {
            g_hash_table_add(bretter->spielbretterHashtables[bretter->aktuelleSpielbretter], (gpointer) spielbrett );
        }
    }
	/*Spielbrett Array wird wieder freigegeben*/
	spielbretterArrayDestruct(param.spielbrett_array, SpielbrettBreite);
    
    return loesbar;
}
예제 #11
0
/**
 * as_merge_components:
 *
 * Merge selected data from two components.
 */
static void
as_merge_components (AsComponent *dest_cpt, AsComponent *src_cpt)
{
	guint i;
	AsMergeKind merge_kind;

	merge_kind = as_component_get_merge_kind (src_cpt);
	g_return_if_fail (merge_kind != AS_MERGE_KIND_NONE);

	/* FIXME: We need to merge more attributes */

	/* merge stuff in append mode */
	if (merge_kind == AS_MERGE_KIND_APPEND) {
		GPtrArray *suggestions;
		GPtrArray *cats;

		/* merge categories */
		cats = as_component_get_categories (src_cpt);
		if (cats->len > 0) {
			g_autoptr(GHashTable) cat_table = NULL;
			GPtrArray *dest_categories;

			cat_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
			for (i = 0; i < cats->len; i++) {
				const gchar *cat = (const gchar*) g_ptr_array_index (cats, i);
				g_hash_table_add (cat_table, g_strdup (cat));
			}

			dest_categories = as_component_get_categories (dest_cpt);
			if (dest_categories->len > 0) {
				for (i = 0; i < dest_categories->len; i++) {
					const gchar *cat = (const gchar*) g_ptr_array_index (dest_categories, i);
					g_hash_table_add (cat_table, g_strdup (cat));
				}
			}

			g_ptr_array_set_size (dest_categories, 0);
			as_hash_table_string_keys_to_array (cat_table, dest_categories);
		}

		/* merge suggestions */
		suggestions = as_component_get_suggested (src_cpt);
		if (suggestions != NULL) {
			for (i = 0; i < suggestions->len; i++) {
				as_component_add_suggested (dest_cpt,
						    AS_SUGGESTED (g_ptr_array_index (suggestions, i)));
			}
		}
	}

	/* merge stuff in replace mode */
	if (merge_kind == AS_MERGE_KIND_REPLACE) {
		gchar **pkgnames;

		/* merge names */
		if (as_component_get_name (src_cpt) != NULL)
			as_component_set_name (dest_cpt, as_component_get_name (src_cpt), as_component_get_active_locale (src_cpt));

		/* merge package names */
		pkgnames = as_component_get_pkgnames (src_cpt);
		if ((pkgnames != NULL) && (pkgnames[0] != '\0'))
			as_component_set_pkgnames (dest_cpt, as_component_get_pkgnames (src_cpt));

		/* merge bundles */
		if (as_component_has_bundle (src_cpt))
			as_component_set_bundles_array (dest_cpt, as_component_get_bundles (src_cpt));
	}

	g_debug ("Merged data for '%s'", as_component_get_data_id (dest_cpt));
}
예제 #12
0
static void
load_system_settings (GKeyfileSettingsBackend *kfsb)
{
  GError *error = NULL;
  const char *dir = "/etc/glib-2.0/settings";
  char *path;
  char *contents;

  kfsb->system_keyfile = g_key_file_new ();
  kfsb->system_locks = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);

  if (kfsb->defaults_dir)
    dir = kfsb->defaults_dir;

  path = g_build_filename (dir, "defaults", NULL);

  /* The defaults are in the same keyfile format that we use for the settings.
   * It can be produced from a dconf database using: dconf dump
   */
  if (!g_key_file_load_from_file (kfsb->system_keyfile, path, G_KEY_FILE_NONE, &error))
    {
      if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
        g_warning ("Failed to read %s: %s", path, error->message);
      g_clear_error (&error);
    }
  else
    g_debug ("Loading default settings from %s", path);

  g_free (path);

  path = g_build_filename (dir, "locks", NULL);

  /* The locks file is a text file containing a list paths to lock, one per line.
   * It can be produced from a dconf database using: dconf list-locks
   */
  if (!g_file_get_contents (path, &contents, NULL, &error))
    {
      if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
        g_warning ("Failed to read %s: %s", path, error->message);
      g_clear_error (&error);
    }
  else
    {
      char **lines;
      gsize i;

      g_debug ("Loading locks from %s", path);

      lines = g_strsplit (contents, "\n", 0);
      for (i = 0; lines[i]; i++)
        {
          char *line = lines[i];
          if (line[0] == '#' || line[0] == '\0')
            {
              g_free (line);
              continue;
            }

          g_debug ("Locking key %s", line);
          g_hash_table_add (kfsb->system_locks, g_steal_pointer (&line));
        }

      g_free (lines);
    }
  g_free (contents);

  g_free (path);
}
예제 #13
0
/**
 * as_validator_validate_tree:
 * @validator: An instance of #AsValidator.
 * @root_dir: The root directory of the filesystem tree that should be validated.
 *
 * Validate a full directory tree for issues in AppStream metadata.
 **/
gboolean
as_validator_validate_tree (AsValidator *validator, const gchar *root_dir)
{
	g_autofree gchar *metainfo_dir = NULL;
	g_autofree gchar *legacy_metainfo_dir = NULL;
	g_autofree gchar *apps_dir = NULL;
	g_autoptr(GPtrArray) mfiles = NULL;
	g_autoptr(GPtrArray) mfiles_legacy = NULL;
	g_autoptr(GPtrArray) dfiles = NULL;
	GHashTable *dfilenames = NULL;
	GHashTable *validated_cpts = NULL;
	guint i;
	gboolean ret = TRUE;
	g_autoptr(AsXMLData) xdt = NULL;
	struct MInfoCheckData ht_helper;

	/* cleanup */
	as_validator_clear_issues (validator);

	metainfo_dir = g_build_filename (root_dir, "usr", "share", "metainfo", NULL);
	legacy_metainfo_dir = g_build_filename (root_dir, "usr", "share", "appdata", NULL);
	apps_dir = g_build_filename (root_dir, "usr", "share", "applications", NULL);

	/* check if we actually have a directory which could hold metadata */
	if ((!g_file_test (metainfo_dir, G_FILE_TEST_IS_DIR)) &&
	    (!g_file_test (legacy_metainfo_dir, G_FILE_TEST_IS_DIR))) {
		as_validator_add_issue (validator, NULL,
					AS_ISSUE_IMPORTANCE_INFO,
					AS_ISSUE_KIND_FILE_MISSING,
					"No AppStream metadata was found.");
		goto out;
	}

	/* check if we actually have a directory which could hold application information */
	if (!g_file_test (apps_dir, G_FILE_TEST_IS_DIR)) {
		as_validator_add_issue (validator, NULL,
					AS_ISSUE_IMPORTANCE_PEDANTIC, /* pedantic because not everything which has metadata is an application */
					AS_ISSUE_KIND_FILE_MISSING,
					"No XDG applications directory found.");
	}

	/* holds a filename -> component mapping */
	validated_cpts = g_hash_table_new_full (g_str_hash,
						g_str_equal,
						g_free,
						g_object_unref);

	/* set up XML parser */
	xdt = as_xmldata_new ();
	as_xmldata_initialize (xdt, AS_CURRENT_FORMAT_VERSION,
			       "C",
				NULL,
				NULL,
				NULL,
				0);
	as_xmldata_set_format_style (xdt, AS_FORMAT_STYLE_METAINFO);

	/* validate all metainfo files */
	mfiles = as_utils_find_files_matching (metainfo_dir, "*.xml", FALSE, NULL);
	mfiles_legacy = as_utils_find_files_matching (legacy_metainfo_dir, "*.xml", FALSE, NULL);

	/* in case we only have legacy files */
	if (mfiles == NULL)
		mfiles = g_ptr_array_new_with_free_func (g_free);

	if (mfiles_legacy != NULL) {
		for (i = 0; i < mfiles_legacy->len; i++) {
			const gchar *fname;
			g_autofree gchar *fname_basename = NULL;

			/* process metainfo files in legacy paths */
			fname = (const gchar*) g_ptr_array_index (mfiles_legacy, i);
			fname_basename = g_path_get_basename (fname);
			as_validator_set_current_fname (validator, fname_basename);

			as_validator_add_issue (validator, NULL,
						AS_ISSUE_IMPORTANCE_INFO,
						AS_ISSUE_KIND_LEGACY,
						"The metainfo file is stored in a legacy path. Please place it in '/usr/share/metainfo'.");

			g_ptr_array_add (mfiles, g_strdup (fname));
		}
	}

	for (i = 0; i < mfiles->len; i++) {
		const gchar *fname;
		g_autoptr(GFile) file = NULL;
		g_autoptr(GInputStream) file_stream = NULL;
		g_autoptr(GError) tmp_error = NULL;
		g_autoptr(GString) asdata = NULL;
		gssize len;
		const gsize buffer_size = 1024 * 24;
		g_autofree gchar *buffer = NULL;
		xmlNode *root;
		xmlDoc *doc;
		g_autofree gchar *fname_basename = NULL;

		fname = (const gchar*) g_ptr_array_index (mfiles, i);
		file = g_file_new_for_path (fname);
		if (!g_file_query_exists (file, NULL)) {
			g_warning ("File '%s' suddenly vanished.", fname);
			g_object_unref (file);
			continue;
		}

		fname_basename = g_path_get_basename (fname);
		as_validator_set_current_fname (validator, fname_basename);

		/* load a plaintext file */
		file_stream = G_INPUT_STREAM (g_file_read (file, NULL, &tmp_error));
		if (tmp_error != NULL) {
			as_validator_add_issue (validator, NULL,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_READ_ERROR,
						"Unable to read file: %s", tmp_error->message);
			continue;
		}

		asdata = g_string_new ("");
		buffer = g_malloc (buffer_size);
		while ((len = g_input_stream_read (file_stream, buffer, buffer_size, NULL, &tmp_error)) > 0) {
			g_string_append_len (asdata, buffer, len);
		}
		/* check if there was an error */
		if (tmp_error != NULL) {
			as_validator_add_issue (validator, NULL,
						AS_ISSUE_IMPORTANCE_ERROR,
						AS_ISSUE_KIND_READ_ERROR,
						"Unable to read file: %s", tmp_error->message);
			continue;
		}

		/* now read the XML */
		doc = as_validator_open_xml_document (validator, xdt, asdata->str);
		if (doc == NULL) {
			as_validator_clear_current_fname (validator);
			continue;
		}
		root = xmlDocGetRootElement (doc);

		if (g_strcmp0 ((gchar*) root->name, "component") == 0) {
			AsComponent *cpt;
			cpt = as_validator_validate_component_node (validator,
								    xdt,
								    root);
			if (cpt != NULL)
				g_hash_table_insert (validated_cpts,
							g_strdup (fname_basename),
							cpt);
		} else if (g_strcmp0 ((gchar*) root->name, "components") == 0) {
			as_validator_add_issue (validator, root,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_TAG_NOT_ALLOWED,
					"The metainfo file specifies multiple components. This is not allowed.");
			ret = FALSE;
		} else if (g_str_has_prefix ((gchar*) root->name, "application")) {
			as_validator_add_issue (validator, root,
					AS_ISSUE_IMPORTANCE_ERROR,
					AS_ISSUE_KIND_LEGACY,
					"The metainfo file uses an ancient version of the AppStream specification, which can not be validated. Please migrate it to version 0.6 (or higher).");
			ret = FALSE;
		}

		as_validator_clear_current_fname (validator);
		xmlFreeDoc (doc);
	}

	/* check if we have matching .desktop files */
	dfilenames = g_hash_table_new_full (g_str_hash,
						g_str_equal,
						g_free,
						NULL);
	dfiles = as_utils_find_files_matching (apps_dir, "*.desktop", FALSE, NULL);
	if (dfiles != NULL) {
		for (i = 0; i < dfiles->len; i++) {
			const gchar *fname;
			fname = (const gchar*) g_ptr_array_index (dfiles, i);
			g_hash_table_add (dfilenames,
						g_path_get_basename (fname));
		}
	}

	/* validate the component-id <-> filename relations and availability of other metadata */
	ht_helper.validator = validator;
	ht_helper.desktop_fnames = dfilenames;
	ht_helper.apps_dir = apps_dir;
	g_hash_table_foreach (validated_cpts,
				(GHFunc) as_validator_analyze_component_metainfo_relation_cb,
				&ht_helper);

out:
	if (dfilenames != NULL)
		g_hash_table_unref (dfilenames);
	if (validated_cpts != NULL)
		g_hash_table_unref (validated_cpts);

	return ret;
}
예제 #14
0
DonnaTask *
donna_fs_engine_basic_io_task (DonnaProviderFs    *pfs,
                               DonnaApp           *app,
                               DonnaIoType         type,
                               GPtrArray          *sources,
                               DonnaNode          *dest,
                               const gchar        *new_name,
                               fs_parse_cmdline    parser,
                               fs_file_created     file_created,
                               fs_file_deleted     file_deleted,
                               GError            **error)
{
    DonnaTaskProcess *taskp;
    struct data *data;
    gchar *cmdline;
    gchar *s = NULL;
    guint i;

    data = g_slice_new0 (struct data);
    data->pfs = g_object_ref (pfs);
    data->app = app;
    data->file_created = file_created;
    data->file_deleted = file_deleted;

    if (type == DONNA_IO_DELETE)
    {
        data->removed_prefix = (gchar *) "removed ";
        data->removed_prefix_len = 8; /* x = strlen ("removed ") */
    }

    data->openq = data->closeq = "'";
    switch (type)
    {
        case DONNA_IO_COPY:
            if (new_name && sources->len == 1)
            {
                gchar *ss = g_shell_quote (new_name);
                cmdline = s = g_strconcat ("cp -irvaT %s %d/", ss, NULL);
                g_free (ss);
            }
            else
                cmdline = (gchar *) "cp -irvat %d %s";
            snprintf (data->prefix, LEN_PREFIX + 1, "cp: ");
            break;

        case DONNA_IO_MOVE:
            if (new_name && sources->len == 1)
            {
                gchar *ss = g_shell_quote (new_name);
                cmdline = s = g_strconcat ("mv -ivT %s %d/", ss, NULL);
                g_free (ss);
            }
            else
                cmdline = (gchar *) "mv -ivt %d %s";
            snprintf (data->prefix, LEN_PREFIX + 1, "mv: ");
            break;

        case DONNA_IO_DELETE:
            cmdline = (gchar *) "rm -Irv %s";
            snprintf (data->prefix, LEN_PREFIX + 1, "rm: ");
            data->is_rm = TRUE;
            break;

        default:
            free_data (data);
            g_set_error (error, DONNA_PROVIDER_ERROR,
                    DONNA_PROVIDER_ERROR_NOT_SUPPORTED,
                    "FS Engine 'basic': Operation not supported (%d)", type);
            return NULL;
    }

    cmdline = parser (cmdline, sources, dest, error);
    if (G_UNLIKELY (!cmdline))
    {
        free_data (data);
        g_prefix_error (error, "FS Engine 'basic': Failed to parse command line: ");
        g_free (s);
        return NULL;
    }
    g_free (s);


    taskp = (DonnaTaskProcess *) donna_task_process_new_full (
            (task_init_fn) set_cmdline, cmdline, g_free,
            TRUE /* wait */,
            NULL, NULL, NULL, /* default pauser */
            (task_stdin_fn) handle_stdin, data, NULL,
            (task_closer_fn) closer, data, NULL);
    if (G_UNLIKELY (!taskp))
    {
        free_data (data);
        g_set_error (error, DONNA_PROVIDER_ERROR,
                DONNA_PROVIDER_ERROR_OTHER,
                "FS Engine 'basic': Failed to create new task-process");
        g_free (cmdline);
        return NULL;
    }

    donna_task_process_set_ui_msg (taskp);

    if (G_UNLIKELY (!donna_task_process_set_workdir_to_curdir (taskp, app)))
    {
        g_set_error (error, DONNA_PROVIDER_ERROR,
                DONNA_PROVIDER_ERROR_OTHER,
                "FS Engine 'basic': Failed to set workdir for task-process");
        g_object_unref (taskp);
        return NULL;
    }

    if (type == DONNA_IO_COPY || type == DONNA_IO_MOVE)
    {
        /* construct the list of location to watch for return nodes */
        data->loc_sources = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
        for (i = 0; i < sources->len; ++i)
            g_hash_table_add (data->loc_sources,
                    donna_node_get_location (sources->pdata[i]));
        /* return value */
        data->ret_nodes = g_ptr_array_new_full (sources->len, g_object_unref);
    }

    g_signal_connect (taskp, "pipe-data-received", (GCallback) pipe_data_received, data);
    g_signal_connect (taskp, "pipe-new-line", (GCallback) pipe_new_line, data);
    g_signal_connect_swapped (taskp, "process-ended", (GCallback) free_data, data);

    return (DonnaTask *) taskp;
}
예제 #15
0
static void
grl_tmdb_source_resolve (GrlSource *source,
                                  GrlSourceResolveSpec *rs)
{
  ResolveClosure *closure;
  GrlTmdbRequest *request;
  const char *title = NULL;
  const char *str_movie_id;
  GrlTmdbSource *self = GRL_TMDB_SOURCE (source);
  guint64 movie_id = 0;
  GList *it;

  if (!GRL_IS_MEDIA_VIDEO (rs->media)) {
    /* We only entertain videos */
    rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL);
    return;
  }

  /* Prefer resolving by movie-id: This is more reliable and saves the search query. */
  str_movie_id = grl_data_get_string (GRL_DATA (rs->media),
                                      GRL_TMDB_METADATA_KEY_TMDB_ID);

  if (str_movie_id)
    movie_id = strtoull (str_movie_id, NULL, 10);

  /* Try title if no movie-id could be found. */
  if (movie_id == 0)
    title = grl_media_get_title (rs->media);

  if (movie_id == 0 && title == NULL) {
    /* Can't search for anything without a title or the movie-id ... */
    rs->callback (source, rs->operation_id, rs->media, rs->user_data, NULL);
    return;
  }

  GRL_DEBUG ("grl_tmdb_source_resolve");

  closure = g_slice_new0 (ResolveClosure);
  closure->self = g_object_ref (source);
  closure->rs = rs;
  closure->pending_requests = g_queue_new ();
  closure->keys = g_hash_table_new (g_direct_hash, g_direct_equal);
  closure->slow = FALSE;
  closure->id = movie_id;

  it = rs->keys;

  /* Copy keys to list for faster lookup */
  while (it) {
    g_hash_table_add (closure->keys, it->data);

    /* Enable slow resolution if slow keys are requested */
    closure->slow |= g_hash_table_contains (self->priv->slow_keys,
                                            it->data);
    it = it->next;
  }

  /* Disable slow resolution if slow keys where requested, but the operation
   * options explicitly ask for fast resolving only. */
  if (grl_operation_options_get_flags (rs->options) & GRL_RESOLVE_FAST_ONLY)
    closure->slow = FALSE;

  /* We did not receive the config yet, queue request. Config callback will
   * take care of flushing the queue when ready.
   */
  if (self->priv->configuration == NULL && self->priv->config_pending) {
    g_queue_push_tail (self->priv->pending_resolves, closure);
    return;
  }

  if (self->priv->configuration == NULL) {
    GRL_DEBUG ("Fetching TMDb configuration...");
    /* We need to fetch TMDb's configuration for the image paths */
    request = grl_tmdb_request_new_configuration (closure->self->priv->api_key);
    g_assert (g_queue_is_empty (closure->pending_requests));
    queue_request (closure, request, on_configuration_ready);
    self->priv->config_pending = TRUE;
  }

  if (title) {
    GRL_DEBUG ("Running initial search for title \"%s\"...", title);
    request = grl_tmdb_request_new_search (closure->self->priv->api_key, title);
    queue_request (closure, request, on_search_ready);
    run_pending_requests (closure, 1);
  } else {
    GRL_DEBUG ("Running %s lookup for movie #%" G_GUINT64_FORMAT "...",
               closure->slow ? "slow" : "fast", movie_id);

    if (closure->slow) {
      resolve_slow_details (closure);
    } else {
      queue_detail_request (closure, GRL_TMDB_REQUEST_DETAIL_MOVIE);
    }

    run_pending_requests (closure, G_MAXINT);
  }
}
예제 #16
0
static void
read_connections (SettingsPluginIfcfg *plugin)
{
	SettingsPluginIfcfgPrivate *priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE (plugin);
	GDir *dir;
	GError *err = NULL;
	const char *item;
	GHashTable *alive_connections;
	GHashTableIter iter;
	NMIfcfgConnection *connection;
	GPtrArray *dead_connections = NULL;
	guint i;
	GPtrArray *filenames;
	GHashTable *paths;

	dir = g_dir_open (IFCFG_DIR, 0, &err);
	if (!dir) {
		_LOGW ("Could not read directory '%s': %s", IFCFG_DIR, err->message);
		g_error_free (err);
		return;
	}

	alive_connections = g_hash_table_new (NULL, NULL);

	filenames = g_ptr_array_new_with_free_func (g_free);
	while ((item = g_dir_read_name (dir))) {
		char *full_path, *real_path;

		full_path = g_build_filename (IFCFG_DIR, item, NULL);
		real_path = utils_detect_ifcfg_path (full_path, TRUE);

		if (real_path)
			g_ptr_array_add (filenames, real_path);
		g_free (full_path);
	}
	g_dir_close (dir);

	/* While reloading, we don't replace connections that we already loaded while
	 * iterating over the files.
	 *
	 * To have sensible, reproducible behavior, sort the paths by last modification
	 * time prefering older files.
	 */
	paths = _paths_from_connections (priv->connections);
	g_ptr_array_sort_with_data (filenames, (GCompareDataFunc) _sort_paths, paths);
	g_hash_table_destroy (paths);

	for (i = 0; i < filenames->len; i++) {
		connection = update_connection (plugin, NULL, filenames->pdata[i], NULL, FALSE, alive_connections, NULL);
		if (connection)
			g_hash_table_add (alive_connections, connection);
	}
	g_ptr_array_free (filenames, TRUE);

	g_hash_table_iter_init (&iter, priv->connections);
	while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &connection)) {
		if (   !g_hash_table_contains (alive_connections, connection)
		    && nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection))) {
			if (!dead_connections)
				dead_connections = g_ptr_array_new ();
			g_ptr_array_add (dead_connections, connection);
		}
	}
	g_hash_table_destroy (alive_connections);

	if (dead_connections) {
		for (i = 0; i < dead_connections->len; i++)
			remove_connection (plugin, dead_connections->pdata[i]);
		g_ptr_array_free (dead_connections, TRUE);
	}
}
예제 #17
0
static void
grl_tmdb_source_init (GrlTmdbSource *self)
{
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                                            GRL_TMDB_SOURCE_TYPE,
                                            GrlTmdbSourcePrivate);
  self->priv->supported_keys = g_hash_table_new (g_direct_hash, g_direct_equal);
  self->priv->slow_keys = g_hash_table_new (g_direct_hash, g_direct_equal);

  /* Fast keys */
  g_hash_table_add (self->priv->supported_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_TITLE));
  g_hash_table_add (self->priv->supported_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_THUMBNAIL));
  g_hash_table_add (self->priv->supported_keys,
                    GRLKEYID_TO_POINTER (GRL_TMDB_METADATA_KEY_BACKDROP));
  g_hash_table_add (self->priv->supported_keys,
                    GRLKEYID_TO_POINTER (GRL_TMDB_METADATA_KEY_POSTER));
  g_hash_table_add (self->priv->supported_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_ORIGINAL_TITLE));
  g_hash_table_add (self->priv->supported_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_RATING));
  g_hash_table_add (self->priv->supported_keys,
                    GRLKEYID_TO_POINTER (GRL_TMDB_METADATA_KEY_TMDB_ID));

  /* Slow keys */
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_SITE));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_GENRE));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_STUDIO));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_DESCRIPTION));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_CERTIFICATE));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_REGION));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_TMDB_METADATA_KEY_IMDB_ID));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_KEYWORD));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_PERFORMER));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_PRODUCER));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_DIRECTOR));
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_AUTHOR));

  /* The publication date is both available as fast key in the movie details,
   * but also as more detailed information as regional release date. To avoid
   * confusion in clients that do a fast resolve first and merge slow data
   * later we hide the fast version.
   */
  g_hash_table_add (self->priv->slow_keys,
                    GRLKEYID_TO_POINTER (GRL_METADATA_KEY_PUBLICATION_DATE));

  self->priv->wc = grl_net_wc_new ();
  grl_net_wc_set_throttling (self->priv->wc, 1);

  self->priv->config_pending = FALSE;
  self->priv->pending_resolves = g_queue_new ();
}
예제 #18
0
파일: set.c 프로젝트: seL4/pruner
void set_insert(set_t *s, const char *item) {
    g_hash_table_add(s, (gpointer)item);
}
예제 #19
0
void dt_collection_get_makermodel(const gchar *filter, GList **sanitized, GList **exif)
{
  sqlite3_stmt *stmt;
  gchar *needle = NULL;

  GHashTable *names = NULL;
  if (sanitized)
    names = g_hash_table_new(g_str_hash, g_str_equal);

  if (filter && filter[0] != '\0')
    needle = g_utf8_strdown(filter, -1);

  DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),
                              "select maker, model from images group by maker, model",
                              -1, &stmt, NULL);
  while(sqlite3_step(stmt) == SQLITE_ROW)
  {
    char *exif_maker = (char *)sqlite3_column_text(stmt, 0);
    char *exif_model = (char *)sqlite3_column_text(stmt, 1);

    char maker[64];
    char model[64];
    char alias[64];
    maker[0] = model[0] = alias[0] = '\0';
    dt_rawspeed_lookup_makermodel(exif_maker, exif_model,
                                  maker, sizeof(maker),
                                  model, sizeof(model),
                                  alias, sizeof(alias));

    // Create the makermodel by concatenation
    char makermodel[128];
    g_strlcpy(makermodel, maker, sizeof(makermodel));
    int maker_len = strlen(maker);
    makermodel[maker_len] = ' ';
    g_strlcpy(makermodel+maker_len+1, model, sizeof(makermodel)-maker_len-1);

    gchar *haystack = g_utf8_strdown(makermodel, -1);
    if (!needle || g_strrstr(haystack, needle) != NULL)
    {
      if (exif)
      {
        // Append a two element list with maker and model
        GList *inner_list = NULL;
        inner_list = g_list_append(inner_list, g_strdup(exif_maker));
        inner_list = g_list_append(inner_list, g_strdup(exif_model));
        *exif = g_list_append(*exif, inner_list);
      }

      if (sanitized)
      {
        gchar *key = g_strdup(makermodel);
        g_hash_table_add(names, key);
      }
    }
    g_free(haystack);
  }
  sqlite3_finalize(stmt);
  g_free(needle);

  if(sanitized)
  {
    *sanitized = g_list_sort(g_hash_table_get_keys(names), (GCompareFunc) strcmp);
    g_hash_table_destroy(names);
  }
}
static void
reload_users (Daemon *daemon)
{
        GHashTable *users;
        GHashTable *old_users;
        GHashTable *local;
        GHashTableIter iter;
        gpointer name;
        User *user;

        /* Track the users that we saw during our (re)load */
        users = create_users_hash_table ();

        /*
         * NOTE: As we load data from all the sources, notifies are
         * frozen in load_entries() and then thawed as we process
         * them below.
         */

        /* Load the local users into our hash table */
        load_entries (daemon, users, entry_generator_fgetpwent);
        local = g_hash_table_new (g_str_hash, g_str_equal);
        g_hash_table_iter_init (&iter, users);
        while (g_hash_table_iter_next (&iter, &name, NULL))
                g_hash_table_add (local, name);

        /* Now add/update users from other sources, possibly non-local */
        load_entries (daemon, users, wtmp_helper_entry_generator);
        load_entries (daemon, users, entry_generator_cachedir);

        /* Mark which users are local, which are not */
        g_hash_table_iter_init (&iter, users);
        while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user))
                user_update_local_account_property (user, g_hash_table_lookup (local, name) != NULL);

        g_hash_table_destroy (local);

        /* Swap out the users */
        old_users = daemon->priv->users;
        daemon->priv->users = users;

        /* Remove all the old users */
        g_hash_table_iter_init (&iter, old_users);
        while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) {
                if (!g_hash_table_lookup (users, name)) {
                        user_unregister (user);
                        accounts_accounts_emit_user_deleted (ACCOUNTS_ACCOUNTS (daemon),
                                                             user_get_object_path (user));
                }
        }

        /* Register all the new users */
        g_hash_table_iter_init (&iter, users);
        while (g_hash_table_iter_next (&iter, &name, (gpointer *)&user)) {
                if (!g_hash_table_lookup (old_users, name)) {
                        user_register (user);
                        accounts_accounts_emit_user_added (ACCOUNTS_ACCOUNTS (daemon),
                                                           user_get_object_path (user));
                }
                g_object_thaw_notify (G_OBJECT (user));
        }

        g_hash_table_destroy (old_users);
}
static gchar *
system_timezone_find (void)
{
	GHashTable *ical_zones;
	icalarray *builtin_timezones;
	gint ii;
	gchar *tz, *config_tz = NULL;

	/* return only timezones known to libical */
	ical_zones = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
	g_hash_table_add (ical_zones, g_strdup ("UTC"));

	builtin_timezones = icaltimezone_get_builtin_timezones ();
	for (ii = 0; ii < builtin_timezones->num_elements; ii++) {
		icaltimezone *zone;
		const gchar *location;

		zone = icalarray_element_at (builtin_timezones, ii);
		if (!zone)
			continue;

		location = icaltimezone_get_location (zone);
		if (location)
			g_hash_table_add (
				ical_zones, g_strdup (location));
	}

	/* softlink is the best option, it points to the correct file */
	tz = system_timezone_read_etc_localtime_softlink (ical_zones);
	if (system_timezone_is_valid (tz, ical_zones)) {
		g_hash_table_destroy (ical_zones);
		return tz;
	}

	g_free (tz);

	config_tz = NULL;

	/* read correct timezone name from config file; checking
	 * on /etc/localtime content can pick wrong timezone name,
	 * even the file is same
	 */
	for (ii = 0; get_system_timezone_methods_config[ii] != NULL; ii++) {
		config_tz = get_system_timezone_methods_config[ii] (ical_zones);

		if (system_timezone_is_valid (config_tz, ical_zones)) {
			break;
		}

		g_free (config_tz);
		config_tz = NULL;
	}

	if (config_tz) {
		struct stat stat_localtime;
		gchar *localtime_content = NULL;
		gsize localtime_content_len = -1;

		if (g_stat (ETC_LOCALTIME, &stat_localtime) == 0 &&
		    S_ISREG (stat_localtime.st_mode) &&
		    g_file_get_contents (ETC_LOCALTIME,
					 &localtime_content,
					 &localtime_content_len,
					 NULL)) {
			struct stat stat_config_tz;
			gchar *filename;

			filename = g_build_filename (
				SYSTEM_ZONEINFODIR, config_tz, NULL);

			if (filename &&
			    g_stat (filename, &stat_config_tz) == 0 &&
			    files_are_identical_content (&stat_localtime,
				&stat_config_tz,
				localtime_content,
				localtime_content_len,
				filename)) {
				g_free (filename);
				g_free (localtime_content);
				g_hash_table_destroy (ical_zones);

				/* Corresponding file name to config_tz matches
				 * /etc/localtime, thus that's the correct one.
				 * Return it as system timezone; bonus is that
				 * it might match configured system timezone
				 * name too. */
				return config_tz;
			}
			g_free (filename);
		}

		g_free (localtime_content);
	}

	for (ii = 0; get_system_timezone_methods_slow[ii] != NULL; ii++) {
		tz = get_system_timezone_methods_slow[ii] (ical_zones);

		if (system_timezone_is_valid (tz, ical_zones)) {
			g_hash_table_destroy (ical_zones);
			g_free (config_tz);
			return tz;
		}

		g_free (tz);
	}

	g_hash_table_destroy (ical_zones);

	return config_tz;
}
예제 #22
0
static gboolean
checkout_one_file_at (OstreeRepo                        *repo,
                      OstreeRepoCheckoutOptions         *options,
                      GFile                             *source,
                      GFileInfo                         *source_info,
                      int                                destination_dfd,
                      const char                        *destination_name,
                      GCancellable                      *cancellable,
                      GError                           **error)
{
  gboolean ret = FALSE;
  const char *checksum;
  gboolean is_symlink;
  gboolean can_cache;
  gboolean need_copy = TRUE;
  char loose_path_buf[_OSTREE_LOOSE_PATH_MAX];
  g_autoptr(GInputStream) input = NULL;
  g_autoptr(GVariant) xattrs = NULL;
  gboolean is_whiteout;

  is_symlink = g_file_info_get_file_type (source_info) == G_FILE_TYPE_SYMBOLIC_LINK;

  checksum = ostree_repo_file_get_checksum ((OstreeRepoFile*)source);

  is_whiteout = !is_symlink && options->process_whiteouts &&
    g_str_has_prefix (destination_name, WHITEOUT_PREFIX);

  /* First, see if it's a Docker whiteout,
   * https://github.com/docker/docker/blob/1a714e76a2cb9008cd19609059e9988ff1660b78/pkg/archive/whiteouts.go
   */
  if (is_whiteout)
    {
      const char *name = destination_name + (sizeof (WHITEOUT_PREFIX) - 1);

      if (!name[0])
        {
          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                       "Invalid empty whiteout '%s'", name);
          goto out;
        }

      g_assert (name[0] != '/'); /* Sanity */

      if (!glnx_shutil_rm_rf_at (destination_dfd, name, cancellable, error))
        goto out;

      need_copy = FALSE;
    }
  else if (!is_symlink)
    {
      gboolean did_hardlink = FALSE;
      /* Try to do a hardlink first, if it's a regular file.  This also
       * traverses all parent repos.
       */
      OstreeRepo *current_repo = repo;

      while (current_repo)
        {
          gboolean is_bare = ((current_repo->mode == OSTREE_REPO_MODE_BARE
                               && options->mode == OSTREE_REPO_CHECKOUT_MODE_NONE) ||
                              (current_repo->mode == OSTREE_REPO_MODE_BARE_USER
                               && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER));
          gboolean current_can_cache = (options->enable_uncompressed_cache
                                        && current_repo->enable_uncompressed_cache);
          gboolean is_archive_z2_with_cache = (current_repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
                                               && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER
                                               && current_can_cache);

          /* But only under these conditions */
          if (is_bare || is_archive_z2_with_cache)
            {
              /* Override repo mode; for archive-z2 we're looking in
                 the cache, which is in "bare" form */
              _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE);
              if (!checkout_file_hardlink (current_repo,
                                           options,
                                           loose_path_buf,
                                           destination_dfd, destination_name,
                                           TRUE, &did_hardlink,
                                           cancellable, error))
                goto out;

              if (did_hardlink && options->devino_to_csum_cache)
                {
                  struct stat stbuf;
                  OstreeDevIno *key;
                  
                  if (TEMP_FAILURE_RETRY (fstatat (destination_dfd, destination_name, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0)
                    {
                      glnx_set_error_from_errno (error);
                      goto out;
                    }
                  
                  key = g_new (OstreeDevIno, 1);
                  key->dev = stbuf.st_dev;
                  key->ino = stbuf.st_ino;
                  memcpy (key->checksum, checksum, OSTREE_SHA256_STRING_LEN+1);
                  
                  g_hash_table_add ((GHashTable*)options->devino_to_csum_cache, key);
                }

              if (did_hardlink)
                break;
            }
          current_repo = current_repo->parent_repo;
        }

      need_copy = !did_hardlink;
    }

  can_cache = (options->enable_uncompressed_cache
               && repo->enable_uncompressed_cache);

  /* Ok, if we're archive-z2 and we didn't find an object, uncompress
   * it now, stick it in the cache, and then hardlink to that.
   */
  if (can_cache
      && !is_whiteout
      && !is_symlink
      && need_copy
      && repo->mode == OSTREE_REPO_MODE_ARCHIVE_Z2
      && options->mode == OSTREE_REPO_CHECKOUT_MODE_USER)
    {
      gboolean did_hardlink;
      
      if (!ostree_repo_load_file (repo, checksum, &input, NULL, NULL,
                                  cancellable, error))
        goto out;

      /* Overwrite any parent repo from earlier */
      _ostree_loose_path (loose_path_buf, checksum, OSTREE_OBJECT_TYPE_FILE, OSTREE_REPO_MODE_BARE);

      if (!checkout_object_for_uncompressed_cache (repo, loose_path_buf,
                                                   source_info, input,
                                                   cancellable, error))
        {
          g_prefix_error (error, "Unpacking loose object %s: ", checksum);
          goto out;
        }
      
      g_clear_object (&input);

      /* Store the 2-byte objdir prefix (e.g. e3) in a set.  The basic
       * idea here is that if we had to unpack an object, it's very
       * likely we're replacing some other object, so we may need a GC.
       *
       * This model ensures that we do work roughly proportional to
       * the size of the changes.  For example, we don't scan any
       * directories if we didn't modify anything, meaning you can
       * checkout the same tree multiple times very quickly.
       *
       * This is also scale independent; we don't hardcode e.g. looking
       * at 1000 objects.
       *
       * The downside is that if we're unlucky, we may not free
       * an object for quite some time.
       */
      g_mutex_lock (&repo->cache_lock);
      {
        gpointer key = GUINT_TO_POINTER ((g_ascii_xdigit_value (checksum[0]) << 4) + 
                                         g_ascii_xdigit_value (checksum[1]));
        if (repo->updated_uncompressed_dirs == NULL)
          repo->updated_uncompressed_dirs = g_hash_table_new (NULL, NULL);
        g_hash_table_insert (repo->updated_uncompressed_dirs, key, key);
      }
      g_mutex_unlock (&repo->cache_lock);

      if (!checkout_file_hardlink (repo, options, loose_path_buf,
                                   destination_dfd, destination_name,
                                   FALSE, &did_hardlink,
                                   cancellable, error))
        {
          g_prefix_error (error, "Using new cached uncompressed hardlink of %s to %s: ", checksum, destination_name);
          goto out;
        }

      need_copy = !did_hardlink;
    }

  /* Fall back to copy if we couldn't hardlink */
  if (need_copy)
    {
      if (!ostree_repo_load_file (repo, checksum, &input, NULL, &xattrs,
                                  cancellable, error))
        goto out;

      if (options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES)
        {
          if (!checkout_file_unioning_from_input_at (repo, options, source_info, xattrs, input,
                                                     destination_dfd,
                                                     destination_name,
                                                     cancellable, error)) 
            {
              g_prefix_error (error, "Union checkout of %s to %s: ", checksum, destination_name);
              goto out;
            }
        }
      else
        {
          if (!checkout_file_from_input_at (repo, options, source_info, xattrs, input,
                                            destination_dfd,
                                            destination_name,
                                            cancellable, error))
            {
              g_prefix_error (error, "Checkout of %s to %s: ", checksum, destination_name);
              goto out;
            }
        }

      if (input)
        {
          if (!g_input_stream_close (input, cancellable, error))
            goto out;
        }
    }

  ret = TRUE;
 out:
  return ret;
}
예제 #23
0
static void
add_name_to_hashtable (struct passwd *pw,
                       gpointer user_data)
{
  g_hash_table_add (user_data, g_strdup (pw->pw_name));
}