3
* Example program to create hotplug scripts.
5
* Copyright (C) 2005-2007 Linus Walleij <triad@df.lth.se>
6
* Copyright (C) 2006-2008 Marcus Meissner <marcus@jet.franken.de>
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.
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.
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.
29
static void usage(void)
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");
46
int main (int argc, char **argv)
48
LIBMTP_device_entry_t *entries;
52
enum style style = style_usbmap;
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;
61
while ( (opt = getopt(argc, argv, "uUiHa:")) != -1 ) {
64
udev_action = strdup(optarg);
79
if (udev_action != NULL) {
82
action = default_udev_action;
86
ret = LIBMTP_Get_Supported_Devices_List(&entries, &numentries);
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");
101
printf("# This usermap will call the script \"libmtp.sh\" whenever a known MTP device is attached.\n\n");
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");
111
printf("# usb.ids style device list from libmtp\n");
112
printf("# Compare: http://www.linux-usb.org/usb.ids\n");
116
for (i = 0; i < numentries; i++) {
117
LIBMTP_device_entry_t * entry = &entries[i];
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);
126
printf("ATTR{idVendor}==\"%04x\", ATTR{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);
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);
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");
164
printf(" <merge key=\"portable_audio_player.libmtp.protocol\" type=\"string\">mtp</merge>\n");
165
printf(" </match>\n");
166
printf(" </match>\n");
169
if (last_vendor != entry->vendor_id) {
170
printf("%04x\n", entry->vendor_id);
172
printf("\t%04x %s %s\n", entry->product_id, entry->vendor, entry->product);
175
last_vendor = entry->vendor_id;
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];
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);
193
printf("GOTO=\"libmtp_rules_end\"\n\n");
201
printf("LABEL=\"libmtp_rules_end\"\n");
204
printf(" </match>\n");
205
printf(" </device>\n");
206
printf("</deviceinfo>\n");