~ubuntu-branches/ubuntu/precise/libmtp/precise-updates

« back to all changes in this revision

Viewing changes to examples/hotplug.c

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2011-02-10 10:43:52 UTC
  • mfrom: (1.1.14 upstream) (35 experimental)
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: james.westby@ubuntu.com-20110210104352-bzqvu9r65gnp1pxl
Tags: 1.0.5-1
* Upload to unstable.
* New upstream release:
  - soname libmtp.so.8.3.5
  - several fixes from Denis Dupeyron to ease work for maintainers:
    + ./configure --enable-doxygen: make Doxygen doc generation optional.
    + ./configure --with-udev=DIR: select a dir for udev.
    + ./configure --with-udev-rules=NAME: select name of udev rules file.
  - several mtp-probe fixes for udev use, now we only probe:
    + Devices that are of known classes to conatin MTP extensions:
      COMM, PTP, CUSTOM and per-interface.
    + Unless the device is CUSTOM, it needs to contain atleast one
      CUSTOM interface.
    + Clear halt on EP 0 after probe if it fails with error.
    + Stop accepting *all* PTP devices as MTP, this is confusing.
  - Minor fixes and new devices.
* Don't build,install static libraries.
* Pass --enable-doxygen to the configure script.
* Refresh patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/** 
2
 
 * \file hotplug.c
3
 
 * Example program to create hotplug scripts.
4
 
 *
5
 
 * Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
6
 
 * Copyright (C) 2006-2008 Marcus Meissner <marcus@jet.franken.de>
7
 
 *
8
 
 * This library is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU Lesser General Public
10
 
 * License as published by the Free Software Foundation; either
11
 
 * version 2 of the License, or (at your option) any later version.
12
 
 *
13
 
 * This library is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 
 * Lesser General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public
19
 
 * License along with this library; if not, write to the
20
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21
 
 * Boston, MA 02111-1307, USA.
22
 
 */
23
 
#include "common.h"
24
 
#include <unistd.h>
25
 
#include <stdlib.h>
26
 
#include <stdio.h>
27
 
#include <string.h>
28
 
 
29
 
static void usage(void)
30
 
{
31
 
  fprintf(stderr, "usage: hotplug [-u -H -i -a\"ACTION\"]\n");
32
 
  fprintf(stderr, "       -u:  use udev syntax\n");
33
 
  fprintf(stderr, "       -H:  use hal syntax\n");
34
 
  fprintf(stderr, "       -i:  use usb.ids simple list syntax\n");
35
 
  fprintf(stderr, "       -a\"ACTION\": perform udev action ACTION on attachment\n");
36
 
  exit(1);
37
 
}
38
 
 
39
 
enum style {
40
 
  style_usbmap,
41
 
  style_udev,
42
 
  style_hal,
43
 
  style_usbids
44
 
};
45
 
 
46
 
int main (int argc, char **argv)
47
 
{
48
 
  LIBMTP_device_entry_t *entries;
49
 
  int numentries;
50
 
  int i;
51
 
  int ret;
52
 
  enum style style = style_usbmap;
53
 
  int opt;
54
 
  extern int optind;
55
 
  extern char *optarg;
56
 
  char *udev_action = NULL;
57
 
  char default_udev_action[] = "SYMLINK+=\"libmtp-%k\", MODE=\"666\"";
58
 
  char *action; // To hold the action actually used.
59
 
  uint16_t last_vendor = 0x0000U;  
60
 
 
61
 
  while ( (opt = getopt(argc, argv, "uUiHa:")) != -1 ) {
62
 
    switch (opt) {
63
 
    case 'a':
64
 
      udev_action = strdup(optarg);
65
 
    case 'u':
66
 
      style = style_udev;
67
 
      break;
68
 
    case 'H':
69
 
      style = style_hal;
70
 
      break;
71
 
    case 'i':
72
 
      style = style_usbids;
73
 
      break;
74
 
    default:
75
 
      usage();
76
 
    }
77
 
  }
78
 
 
79
 
  if (udev_action != NULL) {
80
 
    action = udev_action;
81
 
  } else {
82
 
    action = default_udev_action;
83
 
  }
84
 
 
85
 
  LIBMTP_Init();
86
 
  ret = LIBMTP_Get_Supported_Devices_List(&entries, &numentries);
87
 
  if (ret == 0) {
88
 
    switch (style) {
89
 
    case style_udev:
90
 
      printf("# UDEV-style hotplug map for libmtp\n");
91
 
      printf("# Put this file in /etc/udev/rules.d\n\n");
92
 
      printf("ACTION!=\"add\", GOTO=\"libmtp_rules_end\"\n");
93
 
      printf("ENV{MAJOR}!=\"?*\", GOTO=\"libmtp_rules_end\"\n");
94
 
      printf("SUBSYSTEM==\"usb\", GOTO=\"libmtp_usb_rules\"\n"
95
 
             "# The following thing will be deprecated when older kernels are phased out.\n"
96
 
             "SUBSYSTEM==\"usb_device\", GOTO=\"libmtp_usb_device_rules\"\n"
97
 
             "GOTO=\"libmtp_rules_end\"\n\n"
98
 
             "LABEL=\"libmtp_usb_rules\"\n\n");
99
 
      break;
100
 
    case style_usbmap:
101
 
      printf("# This usermap will call the script \"libmtp.sh\" whenever a known MTP device is attached.\n\n");
102
 
      break;
103
 
    case style_hal:
104
 
      printf("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <!-- -*- SGML -*- -->\n");
105
 
      printf("<!-- This file was generated by %s - - fdi -->\n", argv[0]);
106
 
      printf("<deviceinfo version=\"0.2\">\n");
107
 
      printf("  <device>\n");
108
 
      printf("    <match key=\"info.subsystem\" string=\"usb\">\n");
109
 
      break;
110
 
    case style_usbids:
111
 
      printf("# usb.ids style device list from libmtp\n");
112
 
      printf("# Compare: http://www.linux-usb.org/usb.ids\n");
113
 
      break;
114
 
    }
115
 
 
116
 
    for (i = 0; i < numentries; i++) {
117
 
      LIBMTP_device_entry_t * entry = &entries[i];
118
 
 
119
 
      switch (style) {
120
 
      case style_udev: 
121
 
        {
122
 
          printf("# %s %s\n", entry->vendor, entry->product);
123
 
          // Old style directly SYSFS named.
124
 
          // printf("SYSFS{idVendor}==\"%04x\", SYSFS{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
125
 
          // Newer style
126
 
          printf("ATTR{idVendor}==\"%04x\", ATTR{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
127
 
          break;
128
 
        }
129
 
      case style_usbmap:
130
 
          printf("# %s %s\n", entry->vendor, entry->product);
131
 
          printf("libmtp.sh    0x0003  0x%04x  0x%04x  0x0000  0x0000  0x00    0x00    0x00    0x00    0x00    0x00    0x00000000\n", entry->vendor_id, entry->product_id);
132
 
          break;
133
 
        case style_hal:
134
 
          printf("      <!-- %s %s -->\n", entry->vendor, entry->product);
135
 
          printf("      <match key=\"usb.vendor_id\" int=\"0x%04x\">\n", entry->vendor_id);
136
 
          printf("        <match key=\"usb.product_id\" int=\"0x%04x\">\n", entry->product_id);
137
 
          /* FIXME: If hal >=0.5.10 can be depended upon, the matches below with contains_not can instead use addset */
138
 
          printf("          <match key=\"info.capabilities\" contains_not=\"portable_audio_player\">\n");
139
 
          printf("            <append key=\"info.capabilities\" type=\"strlist\">portable_audio_player</append>\n");
140
 
          printf("          </match>\n");
141
 
          printf("          <merge key=\"info.vendor\" type=\"string\">%s</merge>\n", entry->vendor);
142
 
          printf("          <merge key=\"info.product\" type=\"string\">%s</merge>\n", entry->product);
143
 
          printf("          <merge key=\"info.category\" type=\"string\">portable_audio_player</merge>\n");
144
 
          printf("          <merge key=\"portable_audio_player.access_method\" type=\"string\">user</merge>\n");
145
 
          printf("          <match key=\"portable_audio_player.access_method.protocols\" contains_not=\"mtp\">\n");
146
 
          printf("            <append key=\"portable_audio_player.access_method.protocols\" type=\"strlist\">mtp</append>\n");
147
 
          printf("          </match>\n");
148
 
          printf("          <append key=\"portable_audio_player.access_method.drivers\" type=\"strlist\">libmtp</append>\n");
149
 
          /* FIXME: needs true list of formats ... But all of them can do MP3 and WMA */
150
 
          printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/mpeg\">\n");
151
 
          printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/mpeg</append>\n");
152
 
          printf("          </match>\n");
153
 
          printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/x-ms-wma\">\n");
154
 
          printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/x-ms-wma</append>\n");
155
 
          printf("          </match>\n");
156
 
          /* Special hack to support the OGG format - irivers, TrekStor and NormSoft (Palm) can always play these files! */
157
 
          if (entry->vendor_id == 0x4102 || // iriver
158
 
              entry->vendor_id == 0x066f || // TrekStor
159
 
              entry->vendor_id == 0x1703) { // NormSoft, Inc.
160
 
            printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"application/ogg\">\n");
161
 
            printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">application/ogg</append>\n");
162
 
            printf("          </match>\n");
163
 
          }
164
 
          printf("          <merge key=\"portable_audio_player.libmtp.protocol\" type=\"string\">mtp</merge>\n");
165
 
          printf("        </match>\n");
166
 
          printf("      </match>\n");
167
 
        break;
168
 
        case style_usbids:
169
 
          if (last_vendor != entry->vendor_id) {
170
 
            printf("%04x\n", entry->vendor_id);
171
 
          }
172
 
          printf("\t%04x  %s %s\n", entry->product_id, entry->vendor, entry->product);
173
 
        break;
174
 
      }
175
 
      last_vendor = entry->vendor_id;
176
 
    }
177
 
  } else {
178
 
    printf("Error.\n");
179
 
    exit(1);
180
 
  }
181
 
 
182
 
  // For backward comparibility with the #$!+@! ever changing
183
 
  // udev rule style...
184
 
  if (style == style_udev) {
185
 
    printf("GOTO=\"libmtp_rules_end\"\n\n");
186
 
    printf("LABEL=\"libmtp_usb_device_rules\"\n");
187
 
    for (i = 0; i < numentries; i++) {
188
 
      LIBMTP_device_entry_t * entry = &entries[i];
189
 
 
190
 
      printf("# %s %s\n", entry->vendor, entry->product);
191
 
      printf("ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action); 
192
 
    }
193
 
    printf("GOTO=\"libmtp_rules_end\"\n\n");
194
 
  }
195
 
 
196
 
  // Then the footer.
197
 
  switch (style) {
198
 
  case style_usbmap:
199
 
    break;
200
 
  case style_udev:
201
 
    printf("LABEL=\"libmtp_rules_end\"\n");
202
 
    break;
203
 
  case style_hal:
204
 
    printf("    </match>\n");
205
 
    printf("  </device>\n");
206
 
    printf("</deviceinfo>\n");
207
 
    break;
208
 
  case style_usbids:
209
 
    printf("\n");
210
 
  }
211
 
 
212
 
  exit (0);
213
 
}