<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/> <title>libmtp: hotplug.c</title> <link href="tabs.css" rel="stylesheet" type="text/css"/> <link href="doxygen.css" rel="stylesheet" type="text/css"/> </head> <body> <!-- Generated by Doxygen 1.6.2 --> <div class="navigation" id="top"> <div class="tabs"> <ul> <li><a href="index.html"><span>Main Page</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> <li><a href="dirs.html"><span>Directories</span></a></li> <li><a href="examples.html"><span>Examples</span></a></li> </ul> </div> </div> <div class="contents"> <h1>hotplug.c</h1><div class="fragment"><pre class="fragment"> <span class="preprocessor">#include "common.h"</span> <span class="preprocessor">#include <unistd.h></span> <span class="preprocessor">#include <stdlib.h></span> <span class="preprocessor">#include <stdio.h></span> <span class="preprocessor">#include <string.h></span> <span class="keyword">static</span> <span class="keywordtype">void</span> usage(<span class="keywordtype">void</span>) { fprintf(stderr, <span class="stringliteral">"usage: hotplug [-u -H -i -a\"ACTION\"]\n"</span>); fprintf(stderr, <span class="stringliteral">" -u: use udev syntax\n"</span>); fprintf(stderr, <span class="stringliteral">" -H: use hal syntax\n"</span>); fprintf(stderr, <span class="stringliteral">" -i: use usb.ids simple list syntax\n"</span>); fprintf(stderr, <span class="stringliteral">" -a\"ACTION\": perform udev action ACTION on attachment\n"</span>); exit(1); } <span class="keyword">enum</span> style { style_usbmap, style_udev, style_hal, style_usbids }; <span class="keywordtype">int</span> main (<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> **argv) { <a name="_a0"></a><a class="code" href="structLIBMTP__device__entry__struct.html">LIBMTP_device_entry_t</a> *entries; <span class="keywordtype">int</span> numentries; <span class="keywordtype">int</span> i; <span class="keywordtype">int</span> ret; <span class="keyword">enum</span> style style = style_usbmap; <span class="keywordtype">int</span> opt; <span class="keyword">extern</span> <span class="keywordtype">int</span> optind; <span class="keyword">extern</span> <span class="keywordtype">char</span> *optarg; <span class="keywordtype">char</span> *udev_action = NULL; <span class="keywordtype">char</span> default_udev_action[] = <span class="stringliteral">"SYMLINK+=\"libmtp-%k\", MODE=\"666\""</span>; <span class="keywordtype">char</span> *action; <span class="comment">// To hold the action actually used.</span> uint16_t last_vendor = 0x0000U; <span class="keywordflow">while</span> ( (opt = getopt(argc, argv, <span class="stringliteral">"uUiHa:"</span>)) != -1 ) { <span class="keywordflow">switch</span> (opt) { <span class="keywordflow">case</span> <span class="charliteral">'a'</span>: udev_action = strdup(optarg); <span class="keywordflow">case</span> <span class="charliteral">'u'</span>: style = style_udev; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <span class="charliteral">'H'</span>: style = style_hal; <span class="keywordflow">break</span>; <span class="keywordflow">case</span> <span class="charliteral">'i'</span>: style = style_usbids; <span class="keywordflow">break</span>; <span class="keywordflow">default</span>: usage(); } } <span class="keywordflow">if</span> (udev_action != NULL) { action = udev_action; } <span class="keywordflow">else</span> { action = default_udev_action; } <a name="a1"></a><a class="code" href="group__internals.html#gaaca880ea9ab434e8cf1a1051128318ef">LIBMTP_Init</a>(); ret = <a name="a2"></a><a class="code" href="group__internals.html#ga0d452be0f83d37296cfa3307fb9a8fd7">LIBMTP_Get_Supported_Devices_List</a>(&entries, &numentries); <span class="keywordflow">if</span> (ret == 0) { <span class="keywordflow">switch</span> (style) { <span class="keywordflow">case</span> style_udev: printf(<span class="stringliteral">"# UDEV-style hotplug map for libmtp\n"</span>); printf(<span class="stringliteral">"# Put this file in /etc/udev/rules.d\n\n"</span>); printf(<span class="stringliteral">"ACTION!=\"add\", GOTO=\"libmtp_rules_end\"\n"</span>); printf(<span class="stringliteral">"ENV{MAJOR}!=\"?*\", GOTO=\"libmtp_rules_end\"\n"</span>); printf(<span class="stringliteral">"SUBSYSTEM==\"usb\", GOTO=\"libmtp_usb_rules\"\n"</span> <span class="stringliteral">"# The following thing will be deprecated when older kernels are phased out.\n"</span> <span class="stringliteral">"SUBSYSTEM==\"usb_device\", GOTO=\"libmtp_usb_device_rules\"\n"</span> <span class="stringliteral">"GOTO=\"libmtp_rules_end\"\n\n"</span> <span class="stringliteral">"LABEL=\"libmtp_usb_rules\"\n\n"</span>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_usbmap: printf(<span class="stringliteral">"# This usermap will call the script \"libmtp.sh\" whenever a known MTP device is attached.\n\n"</span>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_hal: printf(<span class="stringliteral">"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <!-- -*- SGML -*- -->\n"</span>); printf(<span class="stringliteral">"<!-- This file was generated by %s - - fdi -->\n"</span>, argv[0]); printf(<span class="stringliteral">"<deviceinfo version=\"0.2\">\n"</span>); printf(<span class="stringliteral">" <device>\n"</span>); printf(<span class="stringliteral">" <match key=\"info.subsystem\" string=\"usb\">\n"</span>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_usbids: printf(<span class="stringliteral">"# usb.ids style device list from libmtp\n"</span>); printf(<span class="stringliteral">"# Compare: http://www.linux-usb.org/usb.ids\n"</span>); <span class="keywordflow">break</span>; } <span class="keywordflow">for</span> (i = 0; i < numentries; i++) { <a class="code" href="structLIBMTP__device__entry__struct.html">LIBMTP_device_entry_t</a> * entry = &entries[i]; <span class="keywordflow">switch</span> (style) { <span class="keywordflow">case</span> style_udev: { printf(<span class="stringliteral">"# %s %s\n"</span>, entry-><a name="a3"></a><a class="code" href="structLIBMTP__device__entry__struct.html#aa32c5d07072e58790a4935eca4159e9c">vendor</a>, entry-><a name="a4"></a><a class="code" href="structLIBMTP__device__entry__struct.html#ad392e158dfb9bb0aef58d180b98357e5">product</a>); <span class="comment">// Old style directly SYSFS named.</span> <span class="comment">// printf("SYSFS{idVendor}==\"%04x\", SYSFS{idProduct}==\"%04x\", %s\n", entry->vendor_id, entry->product_id, action);</span> <span class="comment">// Newer style</span> printf(<span class="stringliteral">"ATTR{idVendor}==\"%04x\", ATTR{idProduct}==\"%04x\", %s\n"</span>, entry-><a name="a5"></a><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a>, entry-><a name="a6"></a><a class="code" href="structLIBMTP__device__entry__struct.html#a450dfc3a7c9d46f998ad1599df776193">product_id</a>, action); <span class="keywordflow">break</span>; } <span class="keywordflow">case</span> style_usbmap: printf(<span class="stringliteral">"# %s %s\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#aa32c5d07072e58790a4935eca4159e9c">vendor</a>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#ad392e158dfb9bb0aef58d180b98357e5">product</a>); printf(<span class="stringliteral">"libmtp.sh 0x0003 0x%04x 0x%04x 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a450dfc3a7c9d46f998ad1599df776193">product_id</a>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_hal: printf(<span class="stringliteral">" <!-- %s %s -->\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#aa32c5d07072e58790a4935eca4159e9c">vendor</a>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#ad392e158dfb9bb0aef58d180b98357e5">product</a>); printf(<span class="stringliteral">" <match key=\"usb.vendor_id\" int=\"0x%04x\">\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a>); printf(<span class="stringliteral">" <match key=\"usb.product_id\" int=\"0x%04x\">\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a450dfc3a7c9d46f998ad1599df776193">product_id</a>); <span class="comment">/* FIXME: If hal >=0.5.10 can be depended upon, the matches below with contains_not can instead use addset */</span> printf(<span class="stringliteral">" <match key=\"info.capabilities\" contains_not=\"portable_audio_player\">\n"</span>); printf(<span class="stringliteral">" <append key=\"info.capabilities\" type=\"strlist\">portable_audio_player</append>\n"</span>); printf(<span class="stringliteral">" </match>\n"</span>); printf(<span class="stringliteral">" <merge key=\"info.vendor\" type=\"string\">%s</merge>\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#aa32c5d07072e58790a4935eca4159e9c">vendor</a>); printf(<span class="stringliteral">" <merge key=\"info.product\" type=\"string\">%s</merge>\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#ad392e158dfb9bb0aef58d180b98357e5">product</a>); printf(<span class="stringliteral">" <merge key=\"info.category\" type=\"string\">portable_audio_player</merge>\n"</span>); printf(<span class="stringliteral">" <merge key=\"portable_audio_player.access_method\" type=\"string\">user</merge>\n"</span>); printf(<span class="stringliteral">" <match key=\"portable_audio_player.access_method.protocols\" contains_not=\"mtp\">\n"</span>); printf(<span class="stringliteral">" <append key=\"portable_audio_player.access_method.protocols\" type=\"strlist\">mtp</append>\n"</span>); printf(<span class="stringliteral">" </match>\n"</span>); printf(<span class="stringliteral">" <append key=\"portable_audio_player.access_method.drivers\" type=\"strlist\">libmtp</append>\n"</span>); <span class="comment">/* FIXME: needs true list of formats ... But all of them can do MP3 and WMA */</span> printf(<span class="stringliteral">" <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/mpeg\">\n"</span>); printf(<span class="stringliteral">" <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/mpeg</append>\n"</span>); printf(<span class="stringliteral">" </match>\n"</span>); printf(<span class="stringliteral">" <match key=\"portable_audio_player.output_formats\" contains_not=\"audio/x-ms-wma\">\n"</span>); printf(<span class="stringliteral">" <append key=\"portable_audio_player.output_formats\" type=\"strlist\">audio/x-ms-wma</append>\n"</span>); printf(<span class="stringliteral">" </match>\n"</span>); <span class="comment">/* Special hack to support the OGG format - irivers, TrekStor and NormSoft (Palm) can always play these files! */</span> <span class="keywordflow">if</span> (entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a> == 0x4102 || <span class="comment">// iriver</span> entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a> == 0x066f || <span class="comment">// TrekStor</span> entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a> == 0x1703) { <span class="comment">// NormSoft, Inc.</span> printf(<span class="stringliteral">" <match key=\"portable_audio_player.output_formats\" contains_not=\"application/ogg\">\n"</span>); printf(<span class="stringliteral">" <append key=\"portable_audio_player.output_formats\" type=\"strlist\">application/ogg</append>\n"</span>); printf(<span class="stringliteral">" </match>\n"</span>); } printf(<span class="stringliteral">" <merge key=\"portable_audio_player.libmtp.protocol\" type=\"string\">mtp</merge>\n"</span>); printf(<span class="stringliteral">" </match>\n"</span>); printf(<span class="stringliteral">" </match>\n"</span>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_usbids: <span class="keywordflow">if</span> (last_vendor != entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a>) { printf(<span class="stringliteral">"%04x\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a>); } printf(<span class="stringliteral">"\t%04x %s %s\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a450dfc3a7c9d46f998ad1599df776193">product_id</a>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#aa32c5d07072e58790a4935eca4159e9c">vendor</a>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#ad392e158dfb9bb0aef58d180b98357e5">product</a>); <span class="keywordflow">break</span>; } last_vendor = entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a>; } } <span class="keywordflow">else</span> { printf(<span class="stringliteral">"Error.\n"</span>); exit(1); } <span class="comment">// For backward comparibility with the #$!+@! ever changing</span> <span class="comment">// udev rule style...</span> <span class="keywordflow">if</span> (style == style_udev) { printf(<span class="stringliteral">"GOTO=\"libmtp_rules_end\"\n\n"</span>); printf(<span class="stringliteral">"LABEL=\"libmtp_usb_device_rules\"\n"</span>); <span class="keywordflow">for</span> (i = 0; i < numentries; i++) { <a class="code" href="structLIBMTP__device__entry__struct.html">LIBMTP_device_entry_t</a> * entry = &entries[i]; printf(<span class="stringliteral">"# %s %s\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#aa32c5d07072e58790a4935eca4159e9c">vendor</a>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#ad392e158dfb9bb0aef58d180b98357e5">product</a>); printf(<span class="stringliteral">"ATTRS{idVendor}==\"%04x\", ATTRS{idProduct}==\"%04x\", %s\n"</span>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a132af448075c74acbbc389d074ce1f97">vendor_id</a>, entry-><a class="code" href="structLIBMTP__device__entry__struct.html#a450dfc3a7c9d46f998ad1599df776193">product_id</a>, action); } printf(<span class="stringliteral">"GOTO=\"libmtp_rules_end\"\n\n"</span>); } <span class="comment">// Then the footer.</span> <span class="keywordflow">switch</span> (style) { <span class="keywordflow">case</span> style_usbmap: <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_udev: printf(<span class="stringliteral">"LABEL=\"libmtp_rules_end\"\n"</span>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_hal: printf(<span class="stringliteral">" </match>\n"</span>); printf(<span class="stringliteral">" </device>\n"</span>); printf(<span class="stringliteral">"</deviceinfo>\n"</span>); <span class="keywordflow">break</span>; <span class="keywordflow">case</span> style_usbids: printf(<span class="stringliteral">"\n"</span>); } exit (0); } </pre></div> </div> <hr size="1"/><address style="text-align: right;"><small>Generated by <a href="http://www.doxygen.org/index.html"> <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.6.2 </small></address> </body> </html>