00001
00023 #include "common.h"
00024 #include <unistd.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028
00029 static void usage(void)
00030 {
00031 fprintf(stderr, "usage: hotplug [-u -H -i -a\"ACTION\"]\n");
00032 fprintf(stderr, " -u: use udev syntax\n");
00033 fprintf(stderr, " -H: use hal syntax\n");
00034 fprintf(stderr, " -i: use usb.ids simple list syntax\n");
00035 fprintf(stderr, " -a\"ACTION\": perform udev action ACTION on attachment\n");
00036 exit(1);
00037 }
00038
00039 enum style {
00040 style_usbmap,
00041 style_udev,
00042 style_hal,
00043 style_usbids
00044 };
00045
00046 int main (int argc, char **argv)
00047 {
00048 LIBMTP_device_entry_t *entries;
00049 int numentries;
00050 int i;
00051 int ret;
00052 enum style style = style_usbmap;
00053 int opt;
00054 extern int optind;
00055 extern char *optarg;
00056 char *udev_action = NULL;
00057 char default_udev_action[] = "SYMLINK+=\"libmtp-%k\", MODE=\"666\"";
00058 uint16_t last_vendor = 0x0000U;
00059
00060 while ( (opt = getopt(argc, argv, "uiHa:")) != -1 ) {
00061 switch (opt) {
00062 case 'a':
00063 udev_action = strdup(optarg);
00064 case 'u':
00065 style = style_udev;
00066 break;
00067 case 'H':
00068 style = style_hal;
00069 break;
00070 case 'i':
00071 style = style_usbids;
00072 break;
00073 default:
00074 usage();
00075 }
00076 }
00077
00078 LIBMTP_Init();
00079 ret = LIBMTP_Get_Supported_Devices_List(&entries, &numentries);
00080 if (ret == 0) {
00081 switch (style) {
00082 case style_udev:
00083 printf("# UDEV-style hotplug map for libmtp\n");
00084 printf("# Put this file in /etc/udev/rules.d\n\n");
00085 printf("ACTION!=\"add\", GOTO=\"libmtp_rules_end\"\n"
00086 "SUBSYSTEM==\"usb\", GOTO=\"libmtp_rules\"\n"
00087 "# The following line will be deprecated when older kernels are phased out.\n"
00088 "SUBSYSTEM==\"usb_device\", GOTO=\"libmtp_rules\"\n\n"
00089 "GOTO=\"libmtp_rules_end\"\n\n"
00090 "LABEL=\"libmtp_rules\"\n\n");
00091 break;
00092 case style_usbmap:
00093 printf("# This usermap will call the script \"libmtp.sh\" whenever a known MTP device is attached.\n\n");
00094 break;
00095 case style_hal:
00096 printf("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <!-- -*- SGML -*- -->\n");
00097 printf("<!-- This file was generated by %s - - fdi -->\n", argv[0]);
00098 printf("<deviceinfo version=\"0.2\">\n");
00099 printf(" <device>\n");
00100 printf(" <match key=\"info.bus\" string=\"usb\">\n");
00101 break;
00102 case style_usbids:
00103 printf("# usb.ids style device list from libmtp\n");
00104 printf("# Compare: http://www.linux-usb.org/usb.ids\n");
00105 break;
00106 }
00107
00108 for (i = 0; i < numentries; i++) {
00109 LIBMTP_device_entry_t * entry = &entries[i];
00110
00111 switch (style) {
00112 case style_udev: {
00113 char *action;
00114 printf("# %s\n", entry->name);
00115 if (udev_action != NULL) {
00116 action = udev_action;
00117 } else {
00118 action = default_udev_action;
00119 }
00120
00121
00122
00123 printf("ATTR{idVendor}==\"%04x\", ATTR{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
00124 break;
00125 }
00126 case style_usbmap:
00127 printf("# %s\n", entry->name);
00128 printf("libmtp.sh 0x0003 0x%04x 0x%04x 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000\n", entry->vendor_id, entry->product_id);
00129 break;
00130 case style_hal:
00131 printf(" <match key=\"usb.vendor_id\" int=\"0x%04x\">\n", entry->vendor_id);
00132 printf(" <match key=\"usb.product_id\" int=\"0x%04x\">\n", entry->product_id);
00133
00134 printf(" <match key=\"info.capabilities\" contains_not=\"portable_audio_player\">\n");
00135 printf(" <append key=\"info.capabilities\" type=\"strlist\">portable_audio_player</append>\n");
00136 printf(" </match>\n");
00137 printf(" <merge key=\"info.category\" type=\"string\">portable_audio_player</merge>\n");
00138 printf(" <merge key=\"portable_audio_player.access_method\" type=\"string\">user</merge>\n");
00139 printf(" <match key=\"portable_audio_player.access_method.protocols\" contains_not=\"mtp\">\n");
00140 printf(" <append key=\"portable_audio_player.access_method.protocols\" type=\"strlist\">mtp</append>\n");
00141 printf(" </match>\n");
00142 printf(" <append key=\"portable_audio_player.access_method.drivers\" type=\"strlist\">libmtp</append>\n");
00143
00144 printf(" <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/mpeg\">\n");
00145 printf(" <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/mpeg</append>\n");
00146 printf(" </match>\n");
00147 printf(" <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/x-ms-wma\">\n");
00148 printf(" <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/x-ms-wma</append>\n");
00149 printf(" </match>\n");
00150
00151 if (entry->vendor_id == 0x4102 ||
00152 entry->vendor_id == 0x066f ||
00153 entry->vendor_id == 0x1703) {
00154 printf(" <match key=\"portable_audio_player.output_formats\" contains_not=\"application/ogg\">\n");
00155 printf(" <append key=\"portable_audio_player.output_formats\" type=\"strlist\">application/ogg</append>\n");
00156 printf(" </match>\n");
00157 }
00158 printf(" <merge key=\"portable_audio_player.libmtp.protocol\" type=\"string\">mtp</merge>\n");
00159 printf(" <merge key=\"portable_audio_player.libmtp.name\" type=\"string\">%s</merge>\n", entry->name);
00160 printf(" </match>\n");
00161 printf(" </match>\n");
00162 break;
00163 case style_usbids:
00164 if (last_vendor != entry->vendor_id) {
00165 printf("%04x\n", entry->vendor_id);
00166 }
00167 printf("\t%04x %s\n", entry->product_id, entry->name);
00168 break;
00169 }
00170 last_vendor = entry->vendor_id;
00171 }
00172 } else {
00173 printf("Error.\n");
00174 exit(1);
00175 }
00176
00177 switch (style) {
00178 case style_usbmap:
00179 break;
00180 case style_udev:
00181 printf("\nLABEL=\"libmtp_rules_end\"\n");
00182 break;
00183 case style_hal:
00184 printf(" </match>\n");
00185 printf(" </device>\n");
00186 printf("</deviceinfo>\n");
00187 break;
00188 case style_usbids:
00189 printf("\n");
00190 }
00191
00192 exit (0);
00193 }