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

« back to all changes in this revision

Viewing changes to .pc/1002-udev_rules.patch/util/mtp-hotplug.c

  • Committer: Bazaar Package Importer
  • Author(s): Alessio Treglia
  • Date: 2011-02-10 19:19:27 UTC
  • mto: This revision was merged to the branch mainline in revision 36.
  • Revision ID: james.westby@ubuntu.com-20110210191927-lm24a4jfaq0l2g5j
Tags: 1.0.5-2
* 1002-udev_rules.patch:
  - Adapt upstream udev rules file to Debian standards.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * \file mtp-hotplug.c
 
3
 * Program to create hotplug scripts.
 
4
 *
 
5
 * Copyright (C) 2005-2010 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 <libmtp.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, "       -o:  use old udev syntax\n");
 
34
  fprintf(stderr, "       -H:  use hal syntax\n");
 
35
  fprintf(stderr, "       -i:  use usb.ids simple list syntax\n");
 
36
  fprintf(stderr, "       -a\"ACTION\": perform udev action ACTION on attachment\n");
 
37
  fprintf(stderr, "       -p\"DIR\": directory where mtp-probe will be installed\n");
 
38
  exit(1);
 
39
}
 
40
 
 
41
enum style {
 
42
  style_usbmap,
 
43
  style_udev,
 
44
  style_udev_old,
 
45
  style_hal,
 
46
  style_usbids
 
47
};
 
48
 
 
49
int main (int argc, char **argv)
 
50
{
 
51
  LIBMTP_device_entry_t *entries;
 
52
  int numentries;
 
53
  int i;
 
54
  int ret;
 
55
  enum style style = style_usbmap;
 
56
  int opt;
 
57
  extern int optind;
 
58
  extern char *optarg;
 
59
  char *udev_action = NULL;
 
60
  /*
 
61
   * You could tag on MODE="0666" here to enfore writeable
 
62
   * device nodes, use the command line argument for that.
 
63
   * Current udev default rules will make any device tagged
 
64
   * with ENV{ID_MEDIA_PLAYER}=1 writable for the console
 
65
   * user.
 
66
   */
 
67
  char default_udev_action[] = "SYMLINK+=\"libmtp-%k\", ENV{ID_MTP_DEVICE}=\"1\", ENV{ID_MEDIA_PLAYER}=\"1\"";
 
68
  char *action; // To hold the action actually used.
 
69
  uint16_t last_vendor = 0x0000U;
 
70
  char *mtp_probe_dir = NULL;
 
71
  char default_mtp_probe_dir[] = "/lib/udev";
 
72
 
 
73
  while ( (opt = getopt(argc, argv, "uoiHa:p:")) != -1 ) {
 
74
    switch (opt) {
 
75
    case 'a':
 
76
      udev_action = strdup(optarg);
 
77
      break;
 
78
    case 'u':
 
79
      style = style_udev;
 
80
      break;
 
81
    case 'o':
 
82
      style = style_udev_old;
 
83
      break;
 
84
    case 'H':
 
85
      style = style_hal;
 
86
      break;
 
87
    case 'i':
 
88
      style = style_usbids;
 
89
      break;
 
90
    case 'p':
 
91
      mtp_probe_dir = strdup(optarg);
 
92
      break;
 
93
    default:
 
94
      usage();
 
95
    }
 
96
  }
 
97
 
 
98
  if (udev_action != NULL) {
 
99
    action = udev_action;
 
100
  } else {
 
101
    action = default_udev_action;
 
102
  }
 
103
 
 
104
  if (mtp_probe_dir == NULL) mtp_probe_dir = default_mtp_probe_dir;
 
105
 
 
106
  LIBMTP_Init();
 
107
  ret = LIBMTP_Get_Supported_Devices_List(&entries, &numentries);
 
108
  if (ret == 0) {
 
109
    switch (style) {
 
110
    case style_udev:
 
111
      printf("# UDEV-style hotplug map for libmtp\n");
 
112
      printf("# Put this file in /etc/udev/rules.d\n\n");
 
113
      printf("ACTION!=\"add\", GOTO=\"libmtp_rules_end\"\n");
 
114
      printf("ENV{MAJOR}!=\"?*\", GOTO=\"libmtp_rules_end\"\n");
 
115
      printf("SUBSYSTEM==\"usb\", GOTO=\"libmtp_usb_rules\"\n"
 
116
             "GOTO=\"libmtp_rules_end\"\n\n"
 
117
             "LABEL=\"libmtp_usb_rules\"\n\n");
 
118
      break;
 
119
    case style_udev_old:
 
120
      printf("# UDEV-style hotplug map for libmtp\n");
 
121
      printf("# Put this file in /etc/udev/rules.d\n\n");
 
122
      printf("ACTION!=\"add\", GOTO=\"libmtp_rules_end\"\n");
 
123
      printf("ENV{MAJOR}!=\"?*\", GOTO=\"libmtp_rules_end\"\n");
 
124
      printf("SUBSYSTEM==\"usb_device\", GOTO=\"libmtp_usb_device_rules\"\n"
 
125
             "GOTO=\"libmtp_rules_end\"\n\n"
 
126
             "LABEL=\"libmtp_usb_device_rules\"\n\n");
 
127
      break;
 
128
    case style_usbmap:
 
129
      printf("# This usermap will call the script \"libmtp.sh\" whenever a known MTP device is attached.\n\n");
 
130
      break;
 
131
    case style_hal:
 
132
      printf("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <!-- -*- SGML -*- -->\n");
 
133
      printf("<!-- This file was generated by %s - - fdi -->\n", argv[0]);
 
134
      printf("<deviceinfo version=\"0.2\">\n");
 
135
      printf("  <device>\n");
 
136
      printf("    <match key=\"info.subsystem\" string=\"usb\">\n");
 
137
      break;
 
138
    case style_usbids:
 
139
      printf("# usb.ids style device list from libmtp\n");
 
140
      printf("# Compare: http://www.linux-usb.org/usb.ids\n");
 
141
      break;
 
142
    }
 
143
 
 
144
    for (i = 0; i < numentries; i++) {
 
145
      LIBMTP_device_entry_t * entry = &entries[i];
 
146
 
 
147
      switch (style) {
 
148
      case style_udev:
 
149
      case style_udev_old:
 
150
        printf("# %s %s\n", entry->vendor, entry->product);
 
151
        printf("ATTR{idVendor}==\"%04x\", ATTR{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
 
152
        break;
 
153
      case style_usbmap:
 
154
          printf("# %s %s\n", entry->vendor, entry->product);
 
155
          printf("libmtp.sh    0x0003  0x%04x  0x%04x  0x0000  0x0000  0x00    0x00    0x00    0x00    0x00    0x00    0x00000000\n", entry->vendor_id, entry->product_id);
 
156
          break;
 
157
        case style_hal:
 
158
          printf("      <!-- %s %s -->\n", entry->vendor, entry->product);
 
159
          printf("      <match key=\"usb.vendor_id\" int=\"0x%04x\">\n", entry->vendor_id);
 
160
          printf("        <match key=\"usb.product_id\" int=\"0x%04x\">\n", entry->product_id);
 
161
          /* FIXME: If hal >=0.5.10 can be depended upon, the matches below with contains_not can instead use addset */
 
162
          printf("          <match key=\"info.capabilities\" contains_not=\"portable_audio_player\">\n");
 
163
          printf("            <append key=\"info.capabilities\" type=\"strlist\">portable_audio_player</append>\n");
 
164
          printf("          </match>\n");
 
165
          printf("          <merge key=\"info.vendor\" type=\"string\">%s</merge>\n", entry->vendor);
 
166
          printf("          <merge key=\"info.product\" type=\"string\">%s</merge>\n", entry->product);
 
167
          printf("          <merge key=\"info.category\" type=\"string\">portable_audio_player</merge>\n");
 
168
          printf("          <merge key=\"portable_audio_player.access_method\" type=\"string\">user</merge>\n");
 
169
          printf("          <match key=\"portable_audio_player.access_method.protocols\" contains_not=\"mtp\">\n");
 
170
          printf("            <append key=\"portable_audio_player.access_method.protocols\" type=\"strlist\">mtp</append>\n");
 
171
          printf("          </match>\n");
 
172
          printf("          <append key=\"portable_audio_player.access_method.drivers\" type=\"strlist\">libmtp</append>\n");
 
173
          /* FIXME: needs true list of formats ... But all of them can do MP3 and WMA */
 
174
          printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/mpeg\">\n");
 
175
          printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/mpeg</append>\n");
 
176
          printf("          </match>\n");
 
177
          printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/x-ms-wma\">\n");
 
178
          printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/x-ms-wma</append>\n");
 
179
          printf("          </match>\n");
 
180
          /* Special hack to support the OGG format - irivers, TrekStor and NormSoft (Palm) can always play these files! */
 
181
          if (entry->vendor_id == 0x4102 || // iriver
 
182
              entry->vendor_id == 0x066f || // TrekStor
 
183
              entry->vendor_id == 0x1703) { // NormSoft, Inc.
 
184
            printf("          <match key=\"portable_audio_player.output_formats\" contains_not=\"application/ogg\">\n");
 
185
            printf("            <append key=\"portable_audio_player.output_formats\" type=\"strlist\">application/ogg</append>\n");
 
186
            printf("          </match>\n");
 
187
          }
 
188
          printf("          <merge key=\"portable_audio_player.libmtp.protocol\" type=\"string\">mtp</merge>\n");
 
189
          printf("        </match>\n");
 
190
          printf("      </match>\n");
 
191
        break;
 
192
        case style_usbids:
 
193
          if (last_vendor != entry->vendor_id) {
 
194
            printf("%04x\n", entry->vendor_id);
 
195
          }
 
196
          printf("\t%04x  %s %s\n", entry->product_id, entry->vendor, entry->product);
 
197
        break;
 
198
      }
 
199
      last_vendor = entry->vendor_id;
 
200
    }
 
201
  } else {
 
202
    printf("Error.\n");
 
203
    exit(1);
 
204
  }
 
205
 
 
206
  // Then the footer.
 
207
  switch (style) {
 
208
  case style_usbmap:
 
209
    break;
 
210
  case style_udev:
 
211
  case style_udev_old:
 
212
    /*
 
213
     * This is code that invokes the mtp-probe program on
 
214
     * every USB device that is either PTP or vendor specific
 
215
     */
 
216
    printf("\n# Autoprobe vendor-specific, communication and PTP devices\n");
 
217
    printf("ENV{ID_MTP_DEVICE}!=\"1\", ATTR{bDeviceClass}==\"00|02|06|ff\", PROGRAM=\"%s/mtp-probe /sys$env{DEVPATH} $attr{busnum} $attr{devnum}\", RESULT==\"1\", %s\n", mtp_probe_dir, action);
 
218
    printf("\nLABEL=\"libmtp_rules_end\"\n");
 
219
    break;
 
220
  case style_hal:
 
221
    printf("    </match>\n");
 
222
    printf("  </device>\n");
 
223
    printf("</deviceinfo>\n");
 
224
    break;
 
225
  case style_usbids:
 
226
    printf("\n");
 
227
  }
 
228
 
 
229
  exit (0);
 
230
}