Blame tools/generic-callout.c

Packit 29108b
/* Copyright (c) 2007, 2010 Christophe Fergeau  <teuf@gnome.org>
Packit 29108b
 * Part of the libgpod project.
Packit 29108b
 * 
Packit 29108b
 * URL: http://www.gtkpod.org/
Packit 29108b
 * URL: http://gtkpod.sourceforge.net/
Packit 29108b
 *
Packit 29108b
 * The code contained in this file is free software; you can redistribute
Packit 29108b
 * it and/or modify it under the terms of the GNU Lesser General Public
Packit 29108b
 * License as published by the Free Software Foundation; either version
Packit 29108b
 * 2.1 of the License, or (at your option) any later version.
Packit 29108b
 *
Packit 29108b
 * This file is distributed in the hope that it will be useful,
Packit 29108b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 29108b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 29108b
 * Lesser General Public License for more details.
Packit 29108b
 *
Packit 29108b
 * You should have received a copy of the GNU Lesser General Public
Packit 29108b
 * License along with this code; if not, write to the Free Software
Packit 29108b
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 29108b
 *
Packit 29108b
 * iTunes and iPod are trademarks of Apple
Packit 29108b
 *
Packit 29108b
 * This product is not supported/written/published by Apple!
Packit 29108b
 *
Packit 29108b
 */
Packit 29108b
#include "config.h"
Packit 29108b
Packit 29108b
#include "backends.h"
Packit 29108b
Packit 29108b
#include <errno.h>
Packit 29108b
Packit 29108b
#include <glib.h>
Packit 29108b
#include <glib/gstdio.h>
Packit 29108b
Packit 29108b
#ifndef __USE_BSD
Packit 29108b
  #define __USE_BSD /* for mkdtemp */
Packit 29108b
#endif
Packit 29108b
#include <stdlib.h>
Packit 29108b
#include <string.h>
Packit 29108b
#ifdef HAVE_UNISTD_H
Packit 29108b
#include <unistd.h>
Packit 29108b
#endif
Packit 29108b
#include <sys/mount.h>
Packit 29108b
#include <itdb.h>
Packit 29108b
#include <itdb_device.h>
Packit 29108b
Packit 29108b
#include "itdb-syslog.h"
Packit 29108b
Packit 29108b
#ifdef HAVE_SGUTILS
Packit 29108b
extern char *read_sysinfo_extended (const char *device);
Packit 29108b
#endif
Packit 29108b
#ifdef HAVE_LIBUSB
Packit 29108b
extern char *read_sysinfo_extended_from_usb (guint bus_number, guint device_address);
Packit 29108b
#endif
Packit 29108b
Packit 29108b
struct _ProductionInfo {
Packit 29108b
	gchar *factory_id;
Packit 29108b
	guint production_year;
Packit 29108b
	guint production_week;
Packit 29108b
	guint production_index;
Packit 29108b
	char *model_id;
Packit 29108b
};
Packit 29108b
typedef struct _ProductionInfo ProductionInfo;
Packit 29108b
Packit 29108b
static void 
Packit 29108b
production_info_free (ProductionInfo *info)
Packit 29108b
{
Packit 29108b
	g_return_if_fail (info != NULL);
Packit 29108b
	g_free (info->factory_id);
Packit 29108b
	g_free (info->model_id);
Packit 29108b
	g_free (info);
Packit 29108b
}
Packit 29108b
Packit 29108b
static ProductionInfo *
Packit 29108b
parse_serial_number (const char *serial_number)
Packit 29108b
{
Packit 29108b
	ProductionInfo *info;
Packit 29108b
	char int_str[4];
Packit 29108b
Packit 29108b
	if (serial_number == NULL) {
Packit 29108b
		return NULL;
Packit 29108b
	}
Packit 29108b
	if (strlen (serial_number) < 11) {
Packit 29108b
		return NULL;
Packit 29108b
	}
Packit 29108b
	info = g_new0 (ProductionInfo, 1);
Packit 29108b
	info->factory_id = g_strndup (serial_number, 2);
Packit 29108b
	serial_number += 2;
Packit 29108b
Packit 29108b
	strncpy (int_str, serial_number, 1);
Packit 29108b
	serial_number += 1;
Packit 29108b
	info->production_year = 2000 + g_ascii_strtoull (int_str, NULL, 10);
Packit 29108b
Packit 29108b
	strncpy (int_str, serial_number, 2);
Packit 29108b
	serial_number += 2;
Packit 29108b
	info->production_week = g_ascii_strtoull (int_str, NULL, 10);
Packit 29108b
Packit 29108b
	strncpy (int_str, serial_number, 3);
Packit 29108b
	serial_number += 3;
Packit 29108b
	info->production_index = g_ascii_strtoull (int_str, NULL, 36);
Packit 29108b
Packit 29108b
	info->model_id = g_strdup (serial_number);
Packit 29108b
Packit 29108b
	return info;
Packit 29108b
}
Packit 29108b
Packit 29108b
static char *
Packit 29108b
get_model_name (const Itdb_IpodInfo *info)
Packit 29108b
{
Packit 29108b
	if (info == NULL) {
Packit 29108b
		return NULL;
Packit 29108b
	}
Packit 29108b
	switch (info->ipod_generation) {
Packit 29108b
	case ITDB_IPOD_GENERATION_UNKNOWN:
Packit 29108b
		return g_strdup ("unknown");
Packit 29108b
	case ITDB_IPOD_GENERATION_FIRST:
Packit 29108b
	case ITDB_IPOD_GENERATION_SECOND:
Packit 29108b
	case ITDB_IPOD_GENERATION_THIRD:
Packit 29108b
	case ITDB_IPOD_GENERATION_FOURTH:
Packit 29108b
		return g_strdup ("grayscale");
Packit 29108b
	case ITDB_IPOD_GENERATION_PHOTO:
Packit 29108b
		return g_strdup ("color");
Packit 29108b
	case ITDB_IPOD_GENERATION_MINI_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_MINI_2:
Packit 29108b
		return g_strdup ("mini");
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_3:
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_4:
Packit 29108b
		return g_strdup ("shuffle");
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_3:
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_4:
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_5:
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_6:
Packit 29108b
		return g_strdup ("nano");
Packit 29108b
	case ITDB_IPOD_GENERATION_VIDEO_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_VIDEO_2:
Packit 29108b
		return g_strdup ("video");
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_3:
Packit 29108b
		return g_strdup ("classic");
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_3:
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_4:
Packit 29108b
		return g_strdup ("touch");
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_3:
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_4:
Packit 29108b
		return g_strdup ("phone");
Packit 29108b
	case ITDB_IPOD_GENERATION_IPAD_1:
Packit 29108b
		return g_strdup ("ipad");
Packit 29108b
	case ITDB_IPOD_GENERATION_MOBILE:
Packit 29108b
		return g_strdup ("rokr");
Packit 29108b
	}
Packit 29108b
Packit 29108b
	g_assert_not_reached ();
Packit 29108b
}
Packit 29108b
Packit 29108b
static double
Packit 29108b
get_generation (const Itdb_IpodInfo *info)
Packit 29108b
{
Packit 29108b
	if (info == NULL) {
Packit 29108b
		return 0.0;
Packit 29108b
	}
Packit 29108b
	switch (info->ipod_generation) {
Packit 29108b
	case ITDB_IPOD_GENERATION_UNKNOWN:
Packit 29108b
		return 0.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_FIRST:
Packit 29108b
		return 1.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_SECOND:
Packit 29108b
		return 2.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_THIRD:
Packit 29108b
		return 3.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_FOURTH:
Packit 29108b
		return 4.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_PHOTO:
Packit 29108b
		return 4.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_MINI_1:
Packit 29108b
		return 1.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_MINI_2:
Packit 29108b
		return 2.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_1:
Packit 29108b
		return 1.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_2:
Packit 29108b
		return 2.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_3:
Packit 29108b
		return 3.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_4:
Packit 29108b
		return 4.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_1:
Packit 29108b
		return 1.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_2:
Packit 29108b
		return 2.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_3:
Packit 29108b
		return 3.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_4:
Packit 29108b
		return 4.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_5:
Packit 29108b
		return 5.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_6:
Packit 29108b
		return 6.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_VIDEO_1:
Packit 29108b
		return 5.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_VIDEO_2:
Packit 29108b
		return 5.5;
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_1:
Packit 29108b
		return 6.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_3:
Packit 29108b
		return 6.5;
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_1:
Packit 29108b
		return 1.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_2:
Packit 29108b
		return 2.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_3:
Packit 29108b
		return 3.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_4:
Packit 29108b
		return 4.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_1:
Packit 29108b
		return 1.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_2:
Packit 29108b
		return 2.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_3:
Packit 29108b
		return 3.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_4:
Packit 29108b
		return 4.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_IPAD_1:
Packit 29108b
		return 1.0;
Packit 29108b
	case ITDB_IPOD_GENERATION_MOBILE:
Packit 29108b
		return 1.0;
Packit 29108b
	}
Packit 29108b
Packit 29108b
	g_assert_not_reached ();
Packit 29108b
}
Packit 29108b
Packit 29108b
static char *
Packit 29108b
get_color_name (const Itdb_IpodInfo *info)
Packit 29108b
{
Packit 29108b
	if (info == NULL) {
Packit 29108b
		return NULL;
Packit 29108b
	}	
Packit 29108b
	switch (info->ipod_model) {
Packit 29108b
	case ITDB_IPOD_MODEL_INVALID:
Packit 29108b
	case ITDB_IPOD_MODEL_UNKNOWN:
Packit 29108b
		return NULL;
Packit 29108b
	case ITDB_IPOD_MODEL_COLOR:
Packit 29108b
	case ITDB_IPOD_MODEL_COLOR_U2:
Packit 29108b
	case ITDB_IPOD_MODEL_REGULAR:
Packit 29108b
	case ITDB_IPOD_MODEL_REGULAR_U2:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_WHITE:
Packit 29108b
	case ITDB_IPOD_MODEL_VIDEO_WHITE:
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE:
Packit 29108b
	case ITDB_IPOD_MODEL_MOBILE_1:
Packit 29108b
	case ITDB_IPOD_MODEL_IPHONE_WHITE:
Packit 29108b
		return g_strdup ("white");
Packit 29108b
	case ITDB_IPOD_MODEL_MINI:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_SILVER:
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_SILVER:
Packit 29108b
	case ITDB_IPOD_MODEL_CLASSIC_SILVER:
Packit 29108b
	case ITDB_IPOD_MODEL_TOUCH_SILVER:
Packit 29108b
	case ITDB_IPOD_MODEL_IPHONE_1:
Packit 29108b
	case ITDB_IPOD_MODEL_IPAD:
Packit 29108b
		return g_strdup ("silver");
Packit 29108b
	case ITDB_IPOD_MODEL_VIDEO_U2:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_BLACK:
Packit 29108b
	case ITDB_IPOD_MODEL_VIDEO_BLACK:
Packit 29108b
	case ITDB_IPOD_MODEL_CLASSIC_BLACK:
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_BLACK:
Packit 29108b
	case ITDB_IPOD_MODEL_IPHONE_BLACK:
Packit 29108b
		return g_strdup ("black");
Packit 29108b
	case ITDB_IPOD_MODEL_MINI_PINK:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_PINK:
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_PINK:
Packit 29108b
		return g_strdup ("pink");
Packit 29108b
	case ITDB_IPOD_MODEL_MINI_GREEN:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_GREEN:
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_GREEN:
Packit 29108b
		return g_strdup ("green");
Packit 29108b
	case ITDB_IPOD_MODEL_MINI_GOLD:
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_GOLD:
Packit 29108b
		return g_strdup ("gold");
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_BLUE:
Packit 29108b
	case ITDB_IPOD_MODEL_MINI_BLUE:
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_BLUE:
Packit 29108b
		return g_strdup ("blue");
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_RED:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_RED:
Packit 29108b
		return g_strdup ("red");
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_ORANGE:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_ORANGE:
Packit 29108b
		return g_strdup ("orange");
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_PURPLE:
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_PURPLE:
Packit 29108b
		return g_strdup ("purple");
Packit 29108b
	case ITDB_IPOD_MODEL_NANO_YELLOW:
Packit 29108b
		return g_strdup ("yellow");
Packit 29108b
	case ITDB_IPOD_MODEL_SHUFFLE_STAINLESS:
Packit 29108b
		return g_strdup ("stainless");
Packit 29108b
	}
Packit 29108b
Packit 29108b
	g_assert_not_reached ();
Packit 29108b
}
Packit 29108b
Packit 29108b
static char *
Packit 29108b
get_icon_name (const Itdb_IpodInfo *info)
Packit 29108b
{
Packit 29108b
	const char prefix[] = "multimedia-player-apple-";
Packit 29108b
	if (info == NULL) {
Packit 29108b
		return g_strconcat (prefix, "ipod", NULL);
Packit 29108b
	}
Packit 29108b
	switch (info->ipod_generation) {
Packit 29108b
	case ITDB_IPOD_GENERATION_UNKNOWN:
Packit 29108b
	case ITDB_IPOD_GENERATION_FIRST:
Packit 29108b
	case ITDB_IPOD_GENERATION_SECOND:
Packit 29108b
	case ITDB_IPOD_GENERATION_THIRD:
Packit 29108b
	case ITDB_IPOD_GENERATION_FOURTH:
Packit 29108b
		return g_strconcat (prefix, "ipod", NULL);
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_PHOTO:
Packit 29108b
		return g_strconcat (prefix, "ipod-color", NULL);
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_MINI_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_MINI_2:
Packit 29108b
		switch (info->ipod_model) {
Packit 29108b
		case ITDB_IPOD_MODEL_MINI_BLUE:
Packit 29108b
			return g_strconcat (prefix, "ipod-mini-blue", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_MINI_PINK:
Packit 29108b
			return g_strconcat (prefix, "ipod-mini-pink", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_MINI_GOLD:
Packit 29108b
			return g_strconcat (prefix, "ipod-mini-gold", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_MINI_GREEN:
Packit 29108b
			return g_strconcat (prefix, "ipod-mini-green", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_MINI:
Packit 29108b
			return g_strconcat (prefix, "ipod-mini-silver", NULL);
Packit 29108b
		default:
Packit 29108b
			g_assert_not_reached ();
Packit 29108b
		}
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_3:
Packit 29108b
		return g_strconcat (prefix, "ipod-shuffle", NULL);
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_SHUFFLE_4:
Packit 29108b
		switch (info->ipod_model) {
Packit 29108b
		case ITDB_IPOD_MODEL_SHUFFLE_SILVER:
Packit 29108b
			return g_strconcat (prefix, "ipod-shuffle-clip-silver", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_SHUFFLE_GREEN:
Packit 29108b
			return g_strconcat (prefix, "ipod-shuffle-clip-green", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_SHUFFLE_GOLD:
Packit 29108b
			return g_strconcat (prefix, "ipod-shuffle-clip-gold", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_SHUFFLE_ORANGE:
Packit 29108b
			return g_strconcat (prefix, "ipod-shuffle-clip-orange", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_SHUFFLE_PURPLE:
Packit 29108b
			return g_strconcat (prefix, "ipod-shuffle-clip-purple", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_SHUFFLE_PINK:
Packit 29108b
			return g_strconcat (prefix, "ipod-shuffle-clip-pink", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_SHUFFLE_BLUE:
Packit 29108b
			return g_strconcat (prefix, "ipod-shuffle-clip-blue", NULL);
Packit 29108b
		default:
Packit 29108b
			g_assert_not_reached ();
Packit 29108b
		}
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_1:
Packit 29108b
		if (info->ipod_model == ITDB_IPOD_MODEL_NANO_BLACK) {
Packit 29108b
			return g_strconcat (prefix, "ipod-nano-black", NULL);
Packit 29108b
		} else {
Packit 29108b
			return g_strconcat (prefix, "ipod-nano-white", NULL);
Packit 29108b
		}
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_2:
Packit 29108b
		return g_strconcat (prefix, "ipod-nano-white", NULL);
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_3:
Packit 29108b
		switch (info->ipod_model) {
Packit 29108b
		case ITDB_IPOD_MODEL_NANO_SILVER:
Packit 29108b
			return g_strconcat (prefix, "ipod-nano-video", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_NANO_BLACK:
Packit 29108b
			return g_strconcat (prefix, "ipod-nano-video-black", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_NANO_BLUE:
Packit 29108b
			return g_strconcat (prefix, "ipod-nano-video-turquoise", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_NANO_GREEN:
Packit 29108b
			return g_strconcat (prefix, "ipod-nano-video-green", NULL);
Packit 29108b
		case ITDB_IPOD_MODEL_NANO_RED:
Packit 29108b
			return g_strconcat (prefix, "ipod-nano-video-red", NULL);
Packit 29108b
		default:
Packit 29108b
			g_assert_not_reached ();
Packit 29108b
		}
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_4:
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_5:
Packit 29108b
	case ITDB_IPOD_GENERATION_NANO_6:
Packit 29108b
		/* FIXME: set the correct icon name once it's added to
Packit 29108b
		 * gnome-icon-theme-extras 
Packit 29108b
		 */
Packit 29108b
		return g_strconcat (prefix, "ipod-nano-white", NULL);
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_VIDEO_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_VIDEO_2:
Packit 29108b
		if (info->ipod_model == ITDB_IPOD_MODEL_VIDEO_BLACK) {
Packit 29108b
			return g_strconcat (prefix, "ipod-video-black", NULL);
Packit 29108b
		} else {
Packit 29108b
			return g_strconcat (prefix, "ipod-video-white", NULL);
Packit 29108b
		}
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_1:
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_CLASSIC_3:
Packit 29108b
		if (info->ipod_model == ITDB_IPOD_MODEL_CLASSIC_BLACK) {
Packit 29108b
			return g_strconcat (prefix, "ipod-classic-black", NULL);
Packit 29108b
		} else {
Packit 29108b
			return g_strconcat (prefix, "ipod-classic-white", NULL);
Packit 29108b
		}
Packit 29108b
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_1:
Packit 29108b
		return g_strconcat (prefix, "ipod-touch", NULL);
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_2:
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_3:
Packit 29108b
	case ITDB_IPOD_GENERATION_TOUCH_4:
Packit 29108b
		return g_strconcat (prefix, "ipod-touch-2g", NULL);
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_1:
Packit 29108b
		return g_strdup ("phone-apple-iphone");
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_2:
Packit 29108b
		return g_strdup ("phone-apple-iphone-3g");
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_3:
Packit 29108b
		return g_strdup ("phone-apple-iphone-3gs");
Packit 29108b
	case ITDB_IPOD_GENERATION_IPHONE_4:
Packit 29108b
		return g_strdup ("phone-apple-iphone-4g");
Packit 29108b
	case ITDB_IPOD_GENERATION_IPAD_1:
Packit 29108b
		return g_strdup ("computer-apple-ipad");
Packit 29108b
	case ITDB_IPOD_GENERATION_MOBILE:
Packit 29108b
		return g_strconcat (prefix, "ipod", NULL);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	g_assert_not_reached ();
Packit 29108b
}
Packit 29108b
Packit 29108b
static void set_artwork_information (const SysInfoIpodProperties *props,
Packit 29108b
				     ItdbBackend *backend)
Packit 29108b
{
Packit 29108b
        const GList *formats;
Packit 29108b
Packit 29108b
        /* Cover art */
Packit 29108b
        formats = itdb_sysinfo_properties_get_cover_art_formats (props);
Packit 29108b
        backend->set_artwork_formats (backend, ALBUM, formats);
Packit 29108b
Packit 29108b
        /* Photos */
Packit 29108b
        formats = itdb_sysinfo_properties_get_photo_formats (props);
Packit 29108b
        backend->set_artwork_formats (backend, PHOTO, formats);
Packit 29108b
Packit 29108b
        /* Chapter images */
Packit 29108b
        formats = itdb_sysinfo_properties_get_chapter_image_formats (props);
Packit 29108b
        backend->set_artwork_formats (backend, CHAPTER, formats);
Packit 29108b
}
Packit 29108b
Packit 29108b
static gboolean ipod_set_properties (ItdbBackend *backend,
Packit 29108b
				     const SysInfoIpodProperties *props)
Packit 29108b
{
Packit 29108b
	const char *serial_number;
Packit 29108b
	const char *firmware_version;
Packit 29108b
	char *icon_name;
Packit 29108b
	const Itdb_IpodInfo *info;
Packit 29108b
	char *model_name;
Packit 29108b
	char *color_name;
Packit 29108b
	double generation;
Packit 29108b
	ProductionInfo *prod_info;
Packit 29108b
Packit 29108b
	backend->set_version (backend, 1);
Packit 29108b
Packit 29108b
	serial_number = itdb_sysinfo_properties_get_serial_number (props);
Packit 29108b
Packit 29108b
	info = itdb_ipod_info_from_serial (serial_number);
Packit 29108b
Packit 29108b
	if ((info == NULL) || (info->ipod_generation == ITDB_IPOD_GENERATION_UNKNOWN)) {
Packit 29108b
		backend->set_is_unknown (backend, TRUE);
Packit 29108b
		g_debug("unknown ipod generation");
Packit 29108b
		return TRUE;
Packit 29108b
	} else {
Packit 29108b
		backend->set_is_unknown (backend, FALSE);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	icon_name = get_icon_name (info);
Packit 29108b
	backend->set_icon_name (backend, icon_name);
Packit 29108b
	g_free (icon_name);
Packit 29108b
Packit 29108b
	if (itdb_sysinfo_properties_get_firewire_id (props) != NULL) {
Packit 29108b
		const char *fwid;
Packit 29108b
		fwid = itdb_sysinfo_properties_get_firewire_id (props);
Packit 29108b
		backend->set_firewire_id (backend, fwid);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	if (serial_number != NULL) {
Packit 29108b
		backend->set_serial_number (backend, serial_number);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	firmware_version = itdb_sysinfo_properties_get_firmware_version (props);
Packit 29108b
	if (firmware_version != NULL) {
Packit 29108b
		backend->set_firmware_version (backend, firmware_version);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	set_artwork_information (props, backend);
Packit 29108b
Packit 29108b
	model_name = get_model_name (info);
Packit 29108b
	if (model_name != NULL) {
Packit 29108b
		backend->set_model_name (backend, model_name);
Packit 29108b
		g_free (model_name);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	generation = get_generation (info);
Packit 29108b
	if (generation != 0.0) {
Packit 29108b
		backend->set_generation (backend, generation);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	color_name = get_color_name (info);
Packit 29108b
	if (color_name != NULL) {
Packit 29108b
		backend->set_color (backend, color_name);
Packit 29108b
		g_free (color_name);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	if (serial_number != NULL) {
Packit 29108b
		prod_info = parse_serial_number (serial_number);
Packit 29108b
		if (prod_info != NULL) {
Packit 29108b
			if (prod_info->factory_id != NULL) {
Packit 29108b
				backend->set_factory_id (backend,
Packit 29108b
							prod_info->factory_id);
Packit 29108b
Packit 29108b
			}
Packit 29108b
			if (prod_info->production_year != 0) {
Packit 29108b
				backend->set_production_year (backend,
Packit 29108b
							      prod_info->production_year);
Packit 29108b
Packit 29108b
			}
Packit 29108b
			if (prod_info->production_week != 0) {
Packit 29108b
				backend->set_production_week (backend,
Packit 29108b
							      prod_info->production_week);
Packit 29108b
Packit 29108b
			}
Packit 29108b
			if (prod_info->production_index != 0) {
Packit 29108b
				backend->set_production_index (backend,
Packit 29108b
							       prod_info->production_index);
Packit 29108b
			}
Packit 29108b
		}
Packit 29108b
		production_info_free (prod_info);
Packit 29108b
	}
Packit 29108b
Packit 29108b
	return TRUE;
Packit 29108b
}
Packit 29108b
Packit 29108b
static gboolean mounted_ipod_set_properties (ItdbBackend *backend,
Packit 29108b
					     const char *ipod_mountpoint)
Packit 29108b
{
Packit 29108b
        Itdb_iTunesDB *itdb;
Packit 29108b
        Itdb_Playlist *mpl;
Packit 29108b
        char *control_path;
Packit 29108b
Packit 29108b
        itdb = itdb_parse (ipod_mountpoint, NULL);
Packit 29108b
        if (itdb == NULL) {
Packit 29108b
               g_debug("failed to parse iTunesDB at %s", ipod_mountpoint);
Packit 29108b
               return FALSE;
Packit 29108b
        }
Packit 29108b
        control_path = itdb_get_control_dir (ipod_mountpoint);
Packit 29108b
        if (control_path != NULL) {
Packit 29108b
	   	if (strlen (control_path) >= strlen (ipod_mountpoint)) {
Packit 29108b
			backend->set_control_path (backend,
Packit 29108b
						  control_path + strlen (ipod_mountpoint));
Packit 29108b
			g_free (control_path);
Packit 29108b
		}
Packit 29108b
        }
Packit 29108b
Packit 29108b
        mpl = itdb_playlist_mpl (itdb);
Packit 29108b
        if (mpl == NULL) {
Packit 29108b
                g_debug("corrupted iTunesDB (no master playlist) at %s",
Packit 29108b
                        ipod_mountpoint);
Packit 29108b
                return FALSE;
Packit 29108b
        }
Packit 29108b
	if (mpl->name != NULL) {
Packit 29108b
	    backend->set_name (backend, mpl->name);
Packit 29108b
	}
Packit 29108b
Packit 29108b
        return FALSE;
Packit 29108b
}
Packit 29108b
Packit 29108b
Packit 29108b
static char *mount_ipod (const char *dev_path, const char *fstype)
Packit 29108b
{
Packit 29108b
        char *filename;
Packit 29108b
        char *tmpname;
Packit 29108b
        int result;
Packit 29108b
Packit 29108b
        filename = g_build_filename (TMPMOUNTDIR, "ipodXXXXXX", NULL);
Packit 29108b
        if (filename == NULL) {
Packit 29108b
                g_debug("failed to build temporary template at "TMPMOUNTDIR);
Packit 29108b
                return NULL;
Packit 29108b
        }
Packit 29108b
        tmpname = mkdtemp (filename);
Packit 29108b
        if (tmpname == NULL) {
Packit 29108b
                g_debug("failed to build temporary filename using template %s",
Packit 29108b
                        filename);
Packit 29108b
                g_free (filename);
Packit 29108b
                return NULL;
Packit 29108b
        }
Packit 29108b
        g_assert (tmpname == filename);
Packit 29108b
        result = mount (dev_path, tmpname, fstype, 0, NULL);
Packit 29108b
        if (result != 0) {
Packit 29108b
                g_debug("failed to mount device %s at %s: %s",
Packit 29108b
                        dev_path, tmpname, strerror(errno));
Packit 29108b
                g_rmdir (filename);
Packit 29108b
                g_free (filename);
Packit 29108b
                return NULL;
Packit 29108b
        }
Packit 29108b
        g_debug("device successfully mounted at %s", tmpname);
Packit 29108b
Packit 29108b
        return tmpname;
Packit 29108b
}
Packit 29108b
Packit 29108b
static gboolean write_sysinfo_extended (const char *mountpoint,
Packit 29108b
                                        const char *data)
Packit 29108b
{
Packit 29108b
        char *filename;
Packit 29108b
        char *devdirpath;
Packit 29108b
        gboolean success;
Packit 29108b
        GError *error = { 0, };
Packit 29108b
Packit 29108b
        devdirpath = itdb_get_device_dir (mountpoint);
Packit 29108b
        /* Make sure the device dir exists (not necessarily true on
Packit 29108b
         * Shuffles */
Packit 29108b
        if (devdirpath == NULL) {
Packit 29108b
            gchar *controldirpath;
Packit 29108b
Packit 29108b
            controldirpath = itdb_get_control_dir (mountpoint);
Packit 29108b
            if (controldirpath == NULL) {
Packit 29108b
                itdb_syslog("failed to build path for control dir at %s",
Packit 29108b
                            mountpoint);
Packit 29108b
                return FALSE;
Packit 29108b
            }
Packit 29108b
            devdirpath = g_build_filename (controldirpath, "Device", NULL);
Packit 29108b
            g_free (controldirpath);
Packit 29108b
            g_mkdir (devdirpath, 0777);
Packit 29108b
            g_debug("creating %s", devdirpath);
Packit 29108b
        }
Packit 29108b
        filename = g_build_filename (devdirpath, "SysInfoExtended", NULL);
Packit 29108b
        g_free (devdirpath);
Packit 29108b
        if (filename == NULL) {
Packit 29108b
                itdb_syslog("failed to build path for SysInfoExtended at %s",
Packit 29108b
                            mountpoint);
Packit 29108b
                return FALSE;
Packit 29108b
        }
Packit 29108b
Packit 29108b
        success = g_file_set_contents (filename, data, -1, &error);
Packit 29108b
        if (!success) {
Packit 29108b
            itdb_syslog("failed to write %s: %s", filename, error->message);
Packit 29108b
            g_clear_error(&error);
Packit 29108b
        } else {
Packit 29108b
            g_debug("successfully written SysInfoExtended at %s", filename);
Packit 29108b
        }
Packit 29108b
        g_free (filename);
Packit 29108b
Packit 29108b
        return success;
Packit 29108b
}
Packit 29108b
Packit 29108b
Packit 29108b
static char *get_info_from_usb (usb_bus_number, usb_device_number)
Packit 29108b
{
Packit 29108b
#ifdef HAVE_LIBUSB
Packit 29108b
        return read_sysinfo_extended_from_usb (usb_bus_number,
Packit 29108b
                                               usb_device_number);
Packit 29108b
#else
Packit 29108b
	g_debug("libgpod was compiled without USB support, "
Packit 29108b
		"not trying to read SysInfoExtended from USB");
Packit 29108b
	return NULL;
Packit 29108b
#endif
Packit 29108b
}
Packit 29108b
Packit 29108b
static char *get_info_from_sg (const char *dev)
Packit 29108b
{
Packit 29108b
#ifdef HAVE_SGUTILS
Packit 29108b
	return read_sysinfo_extended (dev);
Packit 29108b
#else
Packit 29108b
	g_debug("libgpod was compiled without sgutils support, "
Packit 29108b
		"not trying to read SysInfoExtended from SCSI");
Packit 29108b
	return NULL;
Packit 29108b
#endif
Packit 29108b
}
Packit 29108b
Packit 29108b
int itdb_callout_set_ipod_properties (ItdbBackend *backend, const char *dev,
Packit 29108b
                                      gint usb_bus_number,
Packit 29108b
                                      gint usb_device_number,
Packit 29108b
				      const char *fstype)
Packit 29108b
{
Packit 29108b
	char *ipod_mountpoint = NULL;
Packit 29108b
	char *xml = NULL;
Packit 29108b
	SysInfoIpodProperties *props;
Packit 29108b
	GError *error = { 0, };
Packit 29108b
Packit 29108b
	if (usb_bus_number != 0) {
Packit 29108b
		g_debug("trying to read info from USB device %d:%d",
Packit 29108b
			usb_bus_number, usb_device_number);
Packit 29108b
		xml = get_info_from_usb (usb_bus_number, usb_device_number);
Packit 29108b
        }
Packit 29108b
	if (xml == NULL) {
Packit 29108b
		g_debug("tring to read info from SCSI device %s", dev);
Packit 29108b
		xml = get_info_from_sg (dev);
Packit 29108b
	} else {
Packit 29108b
		g_debug("iPod properties successfully read from USB");
Packit 29108b
	}
Packit 29108b
Packit 29108b
        if (xml == NULL) {
Packit 29108b
                itdb_syslog("couldn't read SysInfoExtended from device");
Packit 29108b
                return -1;
Packit 29108b
        } else {
Packit 29108b
		g_debug("iPod properties successfully read from SCSI");
Packit 29108b
	}
Packit 29108b
Packit 29108b
        props = itdb_sysinfo_extended_parse_from_xml (xml, &error);
Packit 29108b
	if (props == NULL) {
Packit 29108b
		itdb_syslog("failed to parse SysInfoExtended: %s",
Packit 29108b
			    error->message);
Packit 29108b
		g_clear_error(&error);
Packit 29108b
		g_debug("%s", xml);
Packit 29108b
		return -1;
Packit 29108b
	}
Packit 29108b
Packit 29108b
        ipod_set_properties (backend, props);
Packit 29108b
        itdb_sysinfo_properties_free (props);
Packit 29108b
Packit 29108b
        ipod_mountpoint = mount_ipod (dev, fstype);
Packit 29108b
        if (ipod_mountpoint == NULL) {
Packit 29108b
                itdb_syslog("failed to mount device");
Packit 29108b
                g_free (xml);
Packit 29108b
                return -1;
Packit 29108b
        }
Packit 29108b
        write_sysinfo_extended (ipod_mountpoint, xml);
Packit 29108b
        g_free (xml);
Packit 29108b
Packit 29108b
        /* mounted_ipod_set_properties will call itdb_parse on the ipod
Packit 29108b
         * which we just mounted, which will create an ItdbDevice
Packit 29108b
         * containing most of what 'dev' had above. For now, I'm leaving
Packit 29108b
         * this kind of duplication since I want the hal information to be
Packit 29108b
         * added even if for some reason we don't manage to mount the ipod
Packit 29108b
         */
Packit 29108b
        mounted_ipod_set_properties (backend, ipod_mountpoint);
Packit 29108b
Packit 29108b
        umount (ipod_mountpoint);
Packit 29108b
        g_rmdir (ipod_mountpoint);
Packit 29108b
        g_free (ipod_mountpoint);
Packit 29108b
Packit 29108b
        return 0;
Packit 29108b
}