hotplug.c

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           // Old style directly SYSFS named.
00121           // printf("SYSFS{idVendor}==\"%04x\", SYSFS{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
00122           // Newer style
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           /* FIXME: If hal >=0.5.10 can be depended upon, the matches below with contains_not can instead use addset */
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           /* FIXME: needs true list of formats ... But all of them can do MP3 and WMA */
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           /* Special hack to support the OGG format - irivers, TrekStor and NormSoft (Palm) can always play these files! */
00151           if (entry->vendor_id == 0x4102 || // iriver
00152               entry->vendor_id == 0x066f || // TrekStor
00153               entry->vendor_id == 0x1703) { // NormSoft, Inc.
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 }

Generated on Mon Aug 6 22:49:52 2007 for libmtp by  doxygen 1.5.3