13aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev/**
23aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * \file hotplug.c
33aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Example program to create hotplug scripts.
43aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
53aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
63aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Copyright (C) 2006-2008 Marcus Meissner <marcus@jet.franken.de>
73aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
83aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This library is free software; you can redistribute it and/or
93aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * modify it under the terms of the GNU Lesser General Public
103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * License as published by the Free Software Foundation; either
113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * version 2 of the License, or (at your option) any later version.
123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * This library is distributed in the hope that it will be useful,
143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * but WITHOUT ANY WARRANTY; without even the implied warranty of
153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Lesser General Public License for more details.
173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev *
183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * You should have received a copy of the GNU Lesser General Public
193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * License along with this library; if not, write to the
203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev * Boston, MA 02111-1307, USA.
223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev */
233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include "common.h"
243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <unistd.h>
253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <stdlib.h>
263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <stdio.h>
273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev#include <string.h>
283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevstatic void usage(void)
303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{
313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stderr, "usage: hotplug [-u -H -i -a\"ACTION\"]\n");
323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stderr, "       -u:  use udev syntax\n");
333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stderr, "       -H:  use hal syntax\n");
343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stderr, "       -i:  use usb.ids simple list syntax\n");
353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  fprintf(stderr, "       -a\"ACTION\": perform udev action ACTION on attachment\n");
363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  exit(1);
373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev}
383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevenum style {
403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  style_usbmap,
413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  style_udev,
423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  style_hal,
433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  style_usbids
443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev};
453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishevint main (int argc, char **argv)
473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev{
483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  LIBMTP_device_entry_t *entries;
493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  int numentries;
503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  int i;
513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  int ret;
523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  enum style style = style_usbmap;
533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  int opt;
543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  extern int optind;
553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  extern char *optarg;
563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  char *udev_action = NULL;
573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  char default_udev_action[] = "SYMLINK+=\"libmtp-%k\", MODE=\"666\"";
583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  char *action; // To hold the action actually used.
593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  uint16_t last_vendor = 0x0000U;
603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  while ( (opt = getopt(argc, argv, "uUiHa:")) != -1 ) {
623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    switch (opt) {
633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case 'a':
643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      udev_action = strdup(optarg);
653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case 'u':
663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      style = style_udev;
673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      break;
683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case 'H':
693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      style = style_hal;
703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      break;
713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case 'i':
723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      style = style_usbids;
733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      break;
743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    default:
753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      usage();
763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  }
783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  if (udev_action != NULL) {
803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    action = udev_action;
813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  } else {
823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    action = default_udev_action;
833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  }
843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  LIBMTP_Init();
863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  ret = LIBMTP_Get_Supported_Devices_List(&entries, &numentries);
873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  if (ret == 0) {
883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    switch (style) {
893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case style_udev:
903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("# UDEV-style hotplug map for libmtp\n");
913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("# Put this file in /etc/udev/rules.d\n\n");
923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("ACTION!=\"add\", GOTO=\"libmtp_rules_end\"\n");
933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("ENV{MAJOR}!=\"?*\", GOTO=\"libmtp_rules_end\"\n");
943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("SUBSYSTEM==\"usb\", GOTO=\"libmtp_usb_rules\"\n"
953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	     "# The following thing will be deprecated when older kernels are phased out.\n"
963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev             "SUBSYSTEM==\"usb_device\", GOTO=\"libmtp_usb_device_rules\"\n"
973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	     "GOTO=\"libmtp_rules_end\"\n\n"
983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	     "LABEL=\"libmtp_usb_rules\"\n\n");
993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      break;
1003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case style_usbmap:
1013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("# This usermap will call the script \"libmtp.sh\" whenever a known MTP device is attached.\n\n");
1023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      break;
1033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case style_hal:
1043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <!-- -*- SGML -*- -->\n");
1053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("<!-- This file was generated by %s - - fdi -->\n", argv[0]);
1063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("<deviceinfo version=\"0.2\">\n");
1073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("  <device>\n");
1083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("    <match key=\"info.subsystem\" string=\"usb\">\n");
1093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      break;
1103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    case style_usbids:
1113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("# usb.ids style device list from libmtp\n");
1123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("# Compare: http://www.linux-usb.org/usb.ids\n");
1133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      break;
1143aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1153aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1163aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    for (i = 0; i < numentries; i++) {
1173aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_device_entry_t * entry = &entries[i];
1183aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1193aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      switch (style) {
1203aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      case style_udev:
1213aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	{
1223aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("# %s %s\n", entry->vendor, entry->product);
1233aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  // Old style directly SYSFS named.
1243aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  // printf("SYSFS{idVendor}==\"%04x\", SYSFS{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
1253aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  // Newer style
1263aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  printf("ATTR{idVendor}==\"%04x\", ATTR{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
1273aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  break;
1283aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev        }
1293aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      case style_usbmap:
1303aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("# %s %s\n", entry->vendor, entry->product);
1313aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("libmtp.sh    0x0003  0x%04x  0x%04x  0x0000  0x0000  0x00    0x00    0x00    0x00    0x00    0x00    0x00000000\n", entry->vendor_id, entry->product_id);
1323aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          break;
1333aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev        case style_hal:
1343aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("      <!-- %s %s -->\n", entry->vendor, entry->product);
1353aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("      <match key=\"usb.vendor_id\" int=\"0x%04x\">\n", entry->vendor_id);
1363aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("        <match key=\"usb.product_id\" int=\"0x%04x\">\n", entry->product_id);
1373aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          /* FIXME: If hal >=0.5.10 can be depended upon, the matches below with contains_not can instead use addset */
1383aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <match key=\"info.capabilities\" contains_not=\"portable_audio_player\">\n");
1393aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("            <append key=\"info.capabilities\" type=\"strlist\">portable_audio_player</append>\n");
1403aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          </match>\n");
1413aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <merge key=\"info.vendor\" type=\"string\">%s</merge>\n", entry->vendor);
1423aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <merge key=\"info.product\" type=\"string\">%s</merge>\n", entry->product);
1433aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <merge key=\"info.category\" type=\"string\">portable_audio_player</merge>\n");
1443aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <merge key=\"portable_audio_player.access_method\" type=\"string\">user</merge>\n");
1453aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <match key=\"portable_audio_player.access_method.protocols\" contains_not=\"mtp\">\n");
1463aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("            <append key=\"portable_audio_player.access_method.protocols\" type=\"strlist\">mtp</append>\n");
1473aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          </match>\n");
1483aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <append key=\"portable_audio_player.access_method.drivers\" type=\"strlist\">libmtp</append>\n");
1493aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          /* FIXME: needs true list of formats ... But all of them can do MP3 and WMA */
1503aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/mpeg\">\n");
1513aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/mpeg</append>\n");
1523aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          </match>\n");
1533aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/x-ms-wma\">\n");
1543aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/x-ms-wma</append>\n");
1553aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          </match>\n");
1563aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  /* Special hack to support the OGG format - irivers, TrekStor and NormSoft (Palm) can always play these files! */
1573aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  if (entry->vendor_id == 0x4102 || // iriver
1583aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      entry->vendor_id == 0x066f || // TrekStor
1593aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	      entry->vendor_id == 0x1703) { // NormSoft, Inc.
1603aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"application/ogg\">\n");
1613aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">application/ogg</append>\n");
1623aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	    printf("          </match>\n");
1633aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev	  }
1643aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("          <merge key=\"portable_audio_player.libmtp.protocol\" type=\"string\">mtp</merge>\n");
1653aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("        </match>\n");
1663aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("      </match>\n");
1673aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev        break;
1683aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev        case style_usbids:
1693aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          if (last_vendor != entry->vendor_id) {
1703aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev            printf("%04x\n", entry->vendor_id);
1713aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          }
1723aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev          printf("\t%04x  %s %s\n", entry->product_id, entry->vendor, entry->product);
1733aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev        break;
1743aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      }
1753aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      last_vendor = entry->vendor_id;
1763aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1773aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  } else {
1783aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("Error.\n");
1793aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    exit(1);
1803aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  }
1813aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1823aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  // For backward comparibility with the #$!+@! ever changing
1833aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  // udev rule style...
1843aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  if (style == style_udev) {
1853aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("GOTO=\"libmtp_rules_end\"\n\n");
1863aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("LABEL=\"libmtp_usb_device_rules\"\n");
1873aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    for (i = 0; i < numentries; i++) {
1883aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      LIBMTP_device_entry_t * entry = &entries[i];
1893aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1903aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("# %s %s\n", entry->vendor, entry->product);
1913aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev      printf("ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
1923aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    }
1933aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("GOTO=\"libmtp_rules_end\"\n\n");
1943aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  }
1953aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
1963aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  // Then the footer.
1973aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  switch (style) {
1983aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case style_usbmap:
1993aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    break;
2003aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case style_udev:
2013aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("LABEL=\"libmtp_rules_end\"\n");
2023aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    break;
2033aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case style_hal:
2043aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("    </match>\n");
2053aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("  </device>\n");
2063aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("</deviceinfo>\n");
2073aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    break;
2083aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  case style_usbids:
2093aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev    printf("\n");
2103aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  }
2113aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev
2123aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev  exit (0);
2133aa430dc5437a98734b36f996f9b17081a589143Yavor Goulishev}
214