From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexey Morozov Date: Fri, 07 Jan 2005 17:07:46 +0000 Subject: Several fixes and enhancements for extented naming rules parameters Message-Id: <41DEC1E2.3060806@idisys.iae.nsk.su> MIME-Version: 1 Content-Type: multipart/mixed; boundary="------------010601070409070605020405" List-Id: To: linux-hotplug@vger.kernel.org This is a multi-part message in MIME format. --------------010601070409070605020405 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hello! Playing with udev naming rules, I notices that existing '%e' macro can't be really used in several cases (important at least for me). This 'extended' macro is quite useful if e.g. we try to build nice "human-friendly" device naming scheme and strictly separate devices names and permissions assignment (to rules.d/* and permissions.d/* respectively) First of all, if one tries to give several names to a device (say, create additional symlinks for a CD-RW device like /dev/cdrom, /dev/cdwriter) udev ends up w/ errors. Also I really doubt if %e w/ existing rules processing code can be used in constructions like /dev/discs/disc%e/disc and other devfs-like naming schemes. So I decided to patch it a bit to achieve such functionality. You can find this patch in the attachment. Also I'd like to have another macro. While %e is substituted w/ nothing for 'mydevice%e' if /dev/mydevice doesn't exist yet, this new macro always substituted w/ a non-negative number. I called it %N, but in fact these names can be changed in future. This is particularly useful for names like /dev/discs/disc%N/{.....} and allows to simplify devfs-like naming scripts. And the last macro I have invented so far ;-) (don't be scared, I'm almost satisfied ;-)), is also about unique file names. I'd like to create entries like /dev/cdrom (i.e. only for a first CD-ROM in the system) w/o extra script work, just because udev anyway has all required info in its database. So this macro (which I called %U) just does a small subset of what %e does. I should note, that all these three macros should be used only once per name token (currently, constructions like discs/disc%N/part%N are prohibited, I doubt this is a real limitation anyway), but the could be freely used in constructions like the following: SYMLINK="cdroms/cdrom%N cdroms/cdwriter%N cdrom/cdrom%U". Also I made a patch for (optional) compilation of udev w/ a system-wide installed sysfs libraries. I'm not sure it's a good idea 'for everyone' but if we anyway have libsysfs and it's fresh enough to seamlessly work w/ udev, I don't see any reasons to have a separate copy right in udev source tree. Probably I make a mistake, but it worked /for me/ so far, and hey, it's optional anyway. Hopefully, I'm not just another another wheel re-inventer, and if so, please tell me that, I'll try to be more cautious next time ;-). In the attachments you'll find described patches (for the udev-0.50), sample rules file and scripts, mentioned in rules files. Patches should be applied in next order: %patch -p1 -b .system_sysfs (optional) %patch1 -p1 -b .efmt_fixes %patch2 -p1 -b .Nfmt %patch3 -p1 -b .Ufmt %patch4 -p1 -b .compile_warnings (probably, also optional) These patches probably could peacefully co-exist w/ recent Mandrake's patches for udev. Thank you for your attention. Sincerely yours, Alexey Morozov. --------------010601070409070605020405 Content-Type: text/plain; name="cd-names.conf" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="cd-names.conf" # -*- mode: shell-script; coding: utf-8 -*- # Configuration options for cd-names.sh # # DRIVETYPE_PRIO (= ) # Allows to change order in which capabilities will be examined (and # thus reported). This can lead to naming schemes with different # primary names. Possible capabilities names are: CD, DVD, CDRW and # DVDRW. CDROMs are always assumed as being capable to handle CD # (obvious :-)) # If value isn't set "DVDRW CDRW DVD" is used by default. DRIVETYPE_PRIO="DVDRW CDRW DVD" # DO_ALL_LINKS (= 0/1) # Report all possible names for a given device, not only one for most # priority capability supported by the device. This can lean to e.g. # DVD-RW drive to get '/dev/cdroms/dvdwriter0' as its name and # '/dev/cdroms/dvd0', '/dev/cdroms/cdwriter0' and '/dev/cdroms/cdrom0' # as symlinks to '/dev/cdroms/dvdwriter0' # Default is to report all names #DO_ALL_LINKS=0 # DO_ROOT_LINKS (= 0/1) # Additionally to all entries in '/dev/cdroms/' folder, make symbolic # links to a given device right from '/dev/'. This allows to have # links like '/dev/cdrom' -> '/dev/cdroms/cdrom0' etc # Default is to do root links #DO_ROOT_LINKS=0 # PRIMARY_SUFFIX (= ) # This suffix will be appended to all device names from '/dev/cdroms/' # folder. See 'man 8 udev' for more info. # Default value is '%N' (NOTE: '%N' requires additional patch to # udev as of version 046!) #PRIMARY_SUFFIX="%e" # SECONDARY_SUFFIX (= ) # This suffix will be appended to all device names from '/dev/' if # such entries are to be created (see DO_ROOT_LINKS) # Default value is '%V" (NOTE: '%U' requires additional patch to # udev as of version 046!) #SECONDARY_SUFFIX="%e" --------------010601070409070605020405 Content-Type: application/x-shellscript; name="cd-names.sh" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="cd-names.sh" IyEvYmluL2Jhc2gKIwojIGNkLW5hbWVzLnNoCiMKIyAoRGVzY3JpcHRpb24gc2hhbWVsZXNz bHkgYm9ycm93ZWQgZnJvbSBjZHN5bWxpbmtzLnNoKQojCiMgTWFwcyBDRFJPTSwgQ0QtUiwg Q0RSVywgRFZELCBEVkRSVywgRFZEUkFNIGFuZCBNb3VudHJhaW5lciB0eXBlcyBvZgojIGRl dmljZXMgdG8gaXRzIHVkZXYgbmFtZSBhbmQgc3lub255bXMuCiMgRmlyc3QgcGFyYW1ldGVy IGlzIHRoZSBrZXJuZWwgZGV2aWNlIG5hbWUgKGUuZy4gaGRjIG9yIHNyMCkKIwojIFVzYWdl OiAKIyBCVVM9ImlkZSIsIEtFUk5FTD0iaGRbYS16XSIsIFBST0dSQU09Ii9ldGMvdWRldi9z Y3JpcHRzL2NkLW5hbWVzLnNoICVrIiwgTkFNRT0iJWN7MX0iLCBTWU1MSU5LPSIlY3syK30i CiMgQlVTPSJzY3NpIiwgS0VSTkVMPSJzclswLTldKiIsIFBST0dSQU09Ii9ldGMvdWRldi9z Y3JpcHRzL2NkLW5hbWVzLnNoICVrIiwgTkFNRT0iJWN7MX0iLCBTWU1MSU5LPSIlY3syK30i CiMgQlVTPSJzY3NpIiwgS0VSTkVMPSJzY2RbMC05XSoiLCBQUk9HUkFNPSIvZXRjL3VkZXYv c2NyaXB0cy9jZC1uYW1lcy5zaCAlayIsIE5BTUU9IiVjezF9IiwgU1lNTElOSz0iJWN7Mit9 IgojICh0aGlzIGxhc3Qgb25lIGlzICJqdXN0IGluIGNhc2UiKQojCiMgQWRkaXRpb25hbCBj b25maWd1cmF0aW9uIGlzIGF2YWlsYWJsZSB0aHJvdWdoIC9ldGMvdWRldi9jZC1uYW1lcy5j b25mCiMgU2VlIGNvbW1lbnRzIGluIHRoYXQgZmlsZSByZWdhcmRpbmcgY29uZmlndXJhdGlv biBwYXJhbWV0ZXJzIGFuZAojIHRoZWlyIG1lYW5pbmdzCiMgCiMgKGMpIDIwMDQsIEFsZXhl eSBNb3Jvem92IDxtb3Jvem92QGFsdGxpbnV4Lm9yZz4KIwojIEJVR1M6IERlZmF1bHQgY29u ZmlndXJhdGlvbiByZWxpZXMgb24gJU4gYW5kICVVIGtleXMgc3VwcG9ydGVkCiMgYnkgdWRl diAoUGF0Y2hlcyBuZWVkZWQgYXMgb2YgdWRldi0wNDYpCiMgCiMgSSdtIG5vdCBzdXJlIGlm IHRoaXMgc2NyaXB0IGlzIHNoLXBvcnRhYmxlLgojIEJ1dCBpdCB3b3JrcyBhdCBsZWFzdCBp biBiYXNoMiA7LSkKCkNERFJJVkVfSU5GTz0vcHJvYy9zeXMvZGV2L2Nkcm9tL2luZm8KWyAt ciAiJENERFJJVkVfSU5GTyIgXSB8fCBleGl0IDEKCnRlc3QgLXIgL2V0Yy91ZGV2L2NkLW5h bWVzLmNvbmYgJiYgLiAvZXRjL3VkZXYvY2QtbmFtZXMuY29uZgo6ICR7RFJJVkVUWVBFX1BS SU86PURWRFJXIENEUlcgRFZEIENEfQo6ICR7RE9fQUxMX0xJTktTOj0xfQo6ICR7UFJFRkVS X1RSQURJVElPTkFMOj0wfQo6ICR7UFJJTUFSWV9TVUZGSVg6PSVOfQo6ICR7U0VDT05EQVJZ X1NVRkZJWDo9JVV9CjogJHtERUJVRzo9MH0KCiMjIHVzZSBhIHdyYXBwZXIgaW5zdGVhZCBv ZiBhIHJhdyBncmVwLiBVc2VmdWwgZm9yIGZ1dHVyZQojIHN3aXRjaCB0byBhIHB1cmUtc2hl bGwgc3Vic3RpdHV0aW9uCmZ1bmN0aW9uIGRvX2dyZXAoKSB7CiAgICBncmVwICIkQCIKICAg IHJldHVybiAkPwp9CgpmdW5jdGlvbiBkcHJpbnRmKCkgewogICAgdGVzdCAieCRERUJVRyIg PSAieDEiICYmIHByaW50ZiAiJEAiID4mMgp9CgpmdW5jdGlvbiBkZWNobygpIHsKICAgIHRl c3QgIngkREVCVUciID0gIngxIiAmJiBlY2hvICIkQCIgPiYyCn0KCmZ1bmN0aW9uIGRpZSgp IHsKICAgIHByaW50ZiAiJEAiID4mMgogICAgZXhpdCAxCn0KCmZ1bmN0aW9uIGdldERyaXZl Q29sdW1uKCkgewogICAgbG9jYWwgZHJpdmVOYW1lIGRyaXZlU3RyaW5nIGVudGlyZVN0cmlu ZyByYwogICAgZHByaW50ZiAiZ2V0RHJpdmVDb2x1bW4oJXMpXG4iICIkMSIKICAgIGRyaXZl TmFtZT0kMQogICAgdGVzdCAtbiAiJGRyaXZlTmFtZSIgfHwgZGllICJlbXB0eSBkcml2ZU5h bWUgcGFzc2VkXG4iCiAgICBkcml2ZVN0cmluZz0iZHJpdmUgbmFtZToiCiAgICBlbnRpcmVT dHJpbmc9YGRvX2dyZXAgLS0gIl4kZHJpdmVTdHJpbmciICRDRERSSVZFX0lORk9gCiAgICBy Yz0kPwogICAgdGVzdCAiJHJjIiA9IDAgfHwgcmV0dXJuIC0xCiAgICBlbnRpcmVTdHJpbmc9 JHtlbnRpcmVTdHJpbmc6JHsjZHJpdmVTdHJpbmd9fQogICAgZHByaW50ZiAiZ2V0RHJpdmVD b2x1bW4oKSBlbnRpcmVTdHJpbmc9XCIlc1wiXG4iICIkZW50aXJlU3RyaW5nIgogICAgdGVz dCAtbiAiJGVudGlyZVN0cmluZyIgfHwgcmV0dXJuIDAKICAgIHNldCAtLSAkZW50aXJlU3Ry aW5nICcnCiAgICBjb2x1bW49MQogICAgcmM9MAogICAgd2hpbGUgWyAkIyAtZ3QgMSBdOyBk bwoJZGVjaG8gImdldERyaXZlQ29sdW1uKCkgY2hlY2tpbmciICIkMSIKCXRlc3QgIngkMSIg PSAieCRkcml2ZU5hbWUiICYmIHJjPSRjb2x1bW4gJiYgYnJlYWsKCWNvbHVtbj0kKCgkY29s dW1uICsgMSkpCglzaGlmdAogICAgZG9uZQogICAgZGVjaG8gImdldERyaXZlQ29sdW1uKCkg cmM9JHJjIgogICAgcmV0dXJuICRyYwp9CgpmdW5jdGlvbiBnZXRDYXBhYmlsaXR5SW50KCkK ewogICAgZHByaW50ZiAiZ2V0Q2FwYWJpbGl0eUludCglZCxcIiVzXCIpXG4iICIkMSIgIiQy IgogICAgbG9jYWwgY2FwU3RyaW5nIGRjIGVudGlyZVN0cmluZyByYwogICAgZGM9JDEKICAg IGNhcFN0cmluZz0kMgogICAgdGVzdCAtbiAiJGRjIiAtYSAtbiAiJGNhcFN0cmluZyIgfHwg ZGllICJib3RoIERyaXZlIENvbHVtbiBhbmQgQ2FwYWJpbGl0eSBTdHJpbmcgc2hvdWxkIGJl IHNwZWNpZmllZFxuIgogICAgZW50aXJlU3RyaW5nPWBkb19ncmVwIC0tICJeJGNhcFN0cmlu ZyIgJENERFJJVkVfSU5GT2AKICAgIHJjPSQ/CiAgICB0ZXN0ICIkcmMiICE9IDAgLW8gLXog IiRlbnRpcmVTdHJpbmciICYmIHJldHVybiAwCiAgICBlbnRpcmVTdHJpbmc9JHtlbnRpcmVT dHJpbmc6JHsjY2FwU3RyaW5nfX0KICAgIGRwcmludGYgImdldENhcGFiaWxpdHlJbnQoKSBl bnRpcmVTdHJpbmc9XCIlc1wiXG4iICIkZW50aXJlU3RyaW5nIgogICAgc2V0IC0tICRlbnRp cmVTdHJpbmcgJycKICAgICMgY2hlY2sgaWYgZW5vdWdoIGNvbHVtbnMgd2VyZSByZXR1cm5l ZC4gUmV0dXJuIDAgaWYgaXQncyBub3QKICAgICMgKGFzIGlmIGRyaXZlIGhhZCBubyBzdWNo IGNhcGFiaWxpdHkpCiAgICB0ZXN0ICQjIC1sdCAkZGMgJiYgcmV0dXJuIDAKICAgIGV2YWwg InJjPVwkJGRjIgogICAgcmV0dXJuICRyYwp9CgpmdW5jdGlvbiBnZXRDYXBhYmlsaXR5KCkK ewogICAgZHByaW50ZiAiZ2V0Q2FwYWJpbGl0eUludCglZCxcIiVzXCIpXG4iICIkMSIgIiQy IgogICAgbG9jYWwgY2FwTmFtZSBkYwogICAgZGM9JDEKICAgIGNhcE5hbWU9JDIKICAgIHRl c3QgLW4gIiRkYyIgLWEgLW4gIiRjYXBOYW1lIiB8fCBkaWUgImJvdGggRHJpdmUgQ29sdW1u IGFuZCBDYXBhYmlsaXR5IE5hbWUgc2hvdWxkIGJlIHNwZWNpZmllZFxuIgogICAgbG9jYWwg Q0RUX0NEV1JfVCBDRFRfQ0RXUldfVCBDRFRfRFZEX1QgQ0RUX0RWRFdSX1QgQ0RUX0RWRFdS QU1fVCBDRFRfTVJXX1QgQ0RUX01SV1dfVCBDRFRfUkFNV19UCiAgICBDRFRfQ0RXUl9UPSJD YW4gd3JpdGUgQ0QtUjoiCiAgICBDRFRfQ0RXUldfVD0iQ2FuIHdyaXRlIENELVJXOiIKICAg IENEVF9EVkRfVD0iQ2FuIHJlYWQgRFZEOiIKICAgIENEVF9EVkRXUl9UPSJDYW4gd3JpdGUg RFZELVI6IgogICAgQ0RUX0RWRFdSQU1fVD0iQ2FuIHdyaXRlIERWRC1SQU06IgogICAgQ0RU X01SV19UPSJDYW4gcmVhZCBNUlc6IgogICAgQ0RUX01SV1dfVD0iQ2FuIHdyaXRlIE1SVzoi CiAgICBDRFRfUkFNV19UPSJDYW4gd3JpdGUgUkFNOiIKICAgICMgZGV2aWNlIGNsYXNzZXMK ICAgIGxvY2FsIENEQ19DRFJXIENEQ19EVkQgQ0RDX0RWRFJXCiAgICBDRENfQ0RSVz0iQ0RX UiBDRFdSVyBNUldXIFJBTVciCiAgICBDRENfRFZEPSJEVkQiCiAgICBDRENfRFdEUlc9IkRW RFdSIERWRFdSQU0iCiAgICBDRENfQ0Q9IkNEIgogICAgbG9jYWwgdGl0bGUgY2xhc3MgcmMg Y2xhc3NlcyAKICAgICMgQSBkaXJ0eSBoYWNrLiBXZWxsLCB5b3Uga25vdywgaXQncyBzaGVs bCBwcm9ncmFtbWluZyBhbnl3YXkuCiAgICBmb3IgY2x0eXBlIGluIGBldmFsICJlY2hvIFxc JENEQ18kY2FwTmFtZSJgOyBkbwoJIyBTcGVjaWFsIGNhc2U6IGlmIGNsdHlwZSBpcyBDRCB0 aGVuIHdlIGF1dG9tYXRpY2FsbHkgcmV0dXJuIDEKCXRlc3QgIngkY2x0eXBlIiA9ICJ4Q0Qi ICYmIHJldHVybiAxCgl0aXRsZT0KCWV2YWwgInRpdGxlPVwkQ0RUXyR7Y2x0eXBlfV9UIgoJ ZGVjaG8gImdldENhcGFiaWxpdHkoKSBjbHR5cGU9JyRjbHR5cGUnLCB0aXRsZT0nJHRpdGxl JyIKCXRlc3QgLW4gIiR0aXRsZSIgfHwgY29udGludWUKCWdldENhcGFiaWxpdHlJbnQgIiRk cml2ZUNvbHVtbiIgIiR0aXRsZSIgfHwgcmV0dXJuIDEKICAgIGRvbmUKICAgIHJldHVybiAw Cn0KCmZ1bmN0aW9uIHJlcG9ydERyaXZlKCkgewogICAgZHByaW50ZiAicmVwb3J0RHJpdmUo XCIlc1wiKVxuIiAiJDEiCiAgICBsb2NhbCBkcml2ZVR5cGUKICAgIGRyaXZlVHlwZT0kMQog ICAgbG9jYWwgQ0ROQU1FX0NEIENETkFNRV9DRFJXIENETkFNRV9EVkQgQ0ROQU1FX0RWRFJX CiAgICAjIENhbm9uaWNhbCBuYW1lcyBmb3IgZWFjaCBjbGFzcyBvZiBDRC9EVkQgZGV2aWNl cwogICAgOiAke0NETkFNRV9DRDo9ImNkcm9tIn0KICAgIDogJHtDRE5BTUVfQ0RSVzo9ImNk d3JpdGVyIn0KICAgIDogJHtDRE5BTUVfRFZEOj0iZHZkIn0KICAgIDogJHtDRE5BTUVfRFZE Ulc6PSJkdmR3cml0ZXIifQogICAgbG9jYWwgZHJpdmVOYW1lCiAgICBkcml2ZU5hbWU9CiAg ICBldmFsICJkcml2ZU5hbWU9XCRDRE5BTUVfJHtkcml2ZVR5cGV9IgogICAgdGVzdCAtbiAi JGRyaXZlTmFtZSIgfHwgZGllICJVbmtub3duIGRyaXZlIHR5cGUgJyRkcml2ZVR5cGUnIHNw ZWNpZmllZFxuIgogICAgZWNobyAtbiAiIGNkcm9tcy8ke2RyaXZlTmFtZX0ke1BSSU1BUllf U1VGRklYfSIKICAgIHRlc3QgIngkRE9fUk9PVF9MSU5LUyIgPSAieDEiICYmIGVjaG8gLW4g IiAke2RyaXZlTmFtZX0ke1NFQ09OREFSWV9TVUZGSVh9IgogICAgcmV0dXJuIDAKfQoKZGVj bGFyZSBkcml2ZUNvbHVtbgoKZnVuY3Rpb24gZHJpdmVDYW4oKQp7CiAgICBnZXRDYXBhYmls aXR5ICRkcml2ZUNvbHVtbiAiJEAiIHx8IHJldHVybiAwCiAgICByZXR1cm4gMQp9CgpkZWNs YXJlIGRyaXZlTmFtZQoKZHJpdmVOYW1lPSQxCmdldERyaXZlQ29sdW1uICRkcml2ZU5hbWUK ZHJpdmVDb2x1bW49JD8KdGVzdCAkZHJpdmVDb2x1bW4gLWd0IDAgfHwgZGllICJDYW4ndCBj YWxjdWxhdGUgZHJpdmUgJyVzJyBjb2x1bW4gKHJjPSVkKVxuIiAiJGRyaXZlTmFtZSIgIiRk cml2ZUNvbHVtbiIKCiMgRmluYWxseSByZXBvcnQgYWxsIGRyaXZlIG5hbWVzCgojIEFkZCBD RC1ST00gdHlwZSBpZiBpdCdzIG5vdCBpbiB0aGUgbGlzdCB5ZXQKRFJJVkVUWVBFX1BSSU89 IiAkRFJJVkVUWVBFX1BSSU8gIgp0ZXN0ICJ4JHtEUklWRVRZUEVfUFJJTy8gQ0QgfSIgPT0g IngkRFJJVkVUWVBFX1BSSU8iICYmIFwKICAgIERSSVZFVFlQRV9QUklPPSIkRFJJVkVUWVBF X1BSSU8gQ0QiCgojIE5vdyBsb29wIHRocm91Z2ggYWxsICJleHRyYSIgZHJpdmUgdHlwZXMK ZGVjbGFyZSBkcml2ZXR5cGUKZm9yIGRyaXZldHlwZSBpbiAkRFJJVkVUWVBFX1BSSU87IGRv CiAgICBpZiBkcml2ZUNhbiAkZHJpdmV0eXBlOyB0aGVuCglyZXBvcnREcml2ZSAkZHJpdmV0 eXBlCgl0ZXN0ICJ4JERPX0FMTF9MSU5LUyIgIT0gIngxIiAmJiBicmVhawogICAgZmkKZG9u ZQoKZWNobwo= --------------010601070409070605020405 Content-Type: application/x-shellscript; name="drive-names.sh" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="drive-names.sh" IyEvYmluL2Jhc2gKIyBBIHNpbXBsaWZpZWQgKGFuZCBzb21ld2hhdCBjb3JyZWN0ZWQpIHZl cnNpb24gb2YgTWRrJ3MgaWRlLWRldmZzLnNoCgpLRVJORUxOQU1FPSQxCkJVU0lEPSQyClBB UlROVU09JDMKRFJJVkVUWVBFPSQ0CgpbIC1zIC9ldGMvdWRldi91ZGV2LmNvbmYgXSAmJiAu IC9ldGMvdWRldi91ZGV2LmNvbmYKCjogJHt1ZGV2X3Jvb3Q6PS9kZXZ9CnVkZXZfcm9vdD0k e3VkZXZfcm9vdCUvfQoKOiAke0RSSVZFVFlQRTo9aWRlfQoKZnVuY3Rpb24gZmFpbGJhY2so KSB7CgkjIGZhaWwgYmFjayBjYXNlLiBNYXliZSBJIHNob3VsZCBzaW1wbHkgZGllIGF0IHRo aXMKCSMgcG9pbnQgYW5kIHRyeSB0byBzdWNjZXNzIHcvIGFub3RoZXIgcnVsZQojIAllY2hv ICRLRVJORUxOQU1FIAojIAlleGl0IDAKCWV4aXQgMQp9CgppZiBbIC16ICIkUEFSVE5VTSIg XTsgdGhlbgoJIyBOZWVkIHRvIHVuZGVyc3RhbmQgZHJpdmVzIG9yaWdpbjogYSBkaXNrLCBh IGNkcm9tIG9yIGFuIGlkZS1mbG9wcHkKCWlmIFsgIngkRFJJVkVUWVBFIiA9ICJ4aWRlIiBd OyB0aGVuCgkJWyAhIC1yIC9wcm9jL2lkZS8ke0tFUk5FTE5BTUV9L21lZGlhIF0gJiYgZmFp bGJhY2sKCQlNRURJQT1gY2F0IC9wcm9jL2lkZS8ke0tFUk5FTE5BTUV9L21lZGlhYAoJCWNh c2UgIngkTUVESUEiIGluCgkJCXhjZHJvbSkKCQkJIFsgLXggL2V0Yy91ZGV2L3NjcmlwdHMv Y2QtbmFtZXMuc2ggXSAmJiBleGVjIC9ldGMvdWRldi9zY3JpcHRzL2NkLW5hbWVzLnNoICRL RVJORUxOQU1FCgkJCSAjIEZhbGxiYWNrIGNhc2UKCQkJIGVjaG8gLW4gImNkcm9tcy9jZHJv bSVOIgoJCQkgI1sgLUwgJHVkZXZfcm9vdC9jZHJvbSBdIHx8IGVjaG8gLW4gIiBjZHJvbSIK CQkJIGVjaG8KCQkJOzsKCQkJeGRpc2spCgkJCSBlY2hvICJkaXNjcy9kaXNjJU4vZGlzYyIK CQkJOzsKCQkJeGZsb3BweSkKCQkJIGVjaG8gImZsb3BwaWVzL2Zsb3BweSVOIgoJCQk7OwoJ CQkqKQoJCQkgZmFpbGJhY2sgMQoJCQk7OwoJCWVzYWMKCWVsaWYgWyAieCREUklWRVRZUEUi ID0gInhzY3NpIiBdOyB0aGVuCgkJY2FzZSAieCRLRVJORUxOQU1FIiBpbgoJCQl4c2RbYS16 XSopCgkJCSBlY2hvICJkaXNjcy9kaXNjJU4vZGlzYyIKICAgICAgICAgICAgICAgICAgICAg ICAgOzsKCQkJKikKCQkJIGZhaWxiYWNrIDEKCQkJOzsKCQllc2FjCgllbHNlCgkgICAgZmFp bGJhY2sgNgoJZmkKZWxzZQoJIyBBIGhhcmRlciBjYXNlLiBXZSBuZWVkIHRvIHVuZGVyc3Rh bmQgd2hhdCAiZGlzYyIgbGFiZWwgd2FzIGFzc2lnbmVkCgkjIHRvIHRoZSB3aG9sZSBkZXZp Y2UuIFRoZSBwcm9ibGVtIGlzIGFsc28gaW4gcGFyYWxsZWwgZGVsaXZlcmluZyBvZgoJIyBk ZXZpY2UgY3JlYXRpb24gZXZlbnRzIGV2ZW4gZm9yIGRyaXZlcyB3LyBwYXJ0aXRpb25zLiBJ J20gbm90IHN1cmUKCSMgdGhhdCBpcyBub3QgYSBidWcgb2YgdWRldiA6LS8KCWRyaXZlTmFt ZT0ke0tFUk5FTE5BTUUlJVswLTldKn0KCgkjIHBvbGxpbmcgc3Vja3MgYmFkbHkKCXRpbWVv dXQ9NQoKCXdoaWxlIHRlc3QgJHRpbWVvdXQgLWd0IDAgLWEgISAtZSAkdWRldl9yb290LyRk cml2ZU5hbWUgOyBkbwoJICAgIHRpbWVvdXQ9JCgoJHRpbWVvdXQtMSkpCgkgICAgc2xlZXAg MQoJZG9uZQoKCSMgU2V2ZXJhbCBjYXNlcyBhcmUgcG9zc2libGUKCSMgMS4gL2Rldi8kZHJp dmVOYW1lIGlzIGEgbGluayB0byBhIGJsb2NrIGRldmljZSB0aGF0IGxvb2tzIGxpa2UKCSMg ZGlzY3MvKi9kaXNjICAoaS5lLiBzaG9ydGVuZWQgZGV2ZnMgc2NoZW1lIGlzIGluIHVzZSku CgkjICAgPT4gd2Ugc2hvdWxkIHJlcG9ydCBwYXJ0aXRpb24gYXMgcGFydCRQQVJUTlVNIGlu IGNvcnJlc3BvbmRlbnQKCSMgZGlzY3MvKi8gc3ViZGlyZWN0b3J5LCB3aGljaCBzaG91bGQg YmUgcmV0cml2ZWQgYnkgcmVhZGxpbmsKCSMgYW5kIHNvbWUgYmFzaCBtYWdpYy4KCQoJIyAy LiAvZGV2LyRkcml2ZU5hbWUgaXMgYSBibG9jayBkZXZpY2UgaXRzZWxmLiBJIGFzc3VtZSB0 aGF0IHRoZQoJIyBzYW1lIHNjcmlwdCB3YXMgdXNlZCB0byBuYW1lIHRoZSB3aG9sZSBkcml2 ZSwgc28gc29tZSBzb3J0IG9mCgkjIC9kZXYvZGlzY3MvKi9kaXNjIHdhcyBhbHJlYWR5IGNy ZWF0ZWQgYW5kIHByb2JhYmx5IGl0J3MgYSBzeW1saW5rCgkjIHRvIC9kZXYvJGRyaXZlTmFt ZS4gRmluZS4gV2UncmUgZ29pbmcgdG8gc2VlIHdoaWNoIGVudHJ5IHBvaW50cwoJIyB0byAv ZGV2LyRkcml2ZU5hbWUgYW5kIHJlcG9ydCBwYXJ0aXRpb24gZm9yIGl0LgoJIwoJIyAzLiAv ZGV2LyRkcml2ZU5hbWUgaXMgYSBsaW5rIGJ1dCBlaXRoZXIgbm90IHRvIGEgYmxvY2sgZGV2 aWNlIG9yCgkjIHRvIGEgYmxvY2sgZGV2aWNlIG91dHNpZGUgL2Rldi9kaXNjcy4gV2UgY2Fu J3QgZG8gYW55dGhpbmcgdy8KCSMgdGhhdCBhbmQgdGggZW50aXJlIHJ1bGUgc2hvdWxkIGJl IG1hcmtlZCBhcyBmYWlsZWQKCSMKCSMgNC4gL2Rldi8kZHJpdmVOYW1lIGlzIGEgYmxvY2sg ZGV2aWNlIGJ1dCBhcHByb3ByaWF0ZQoJIyAvZGV2L2Rpc2NzLyovZGlzYyBjYW4ndCBiZSBm b3VuZC4gQWxzbyB0aGUgcnVsZSBpcyBmYWlsZWQKCSMgNS4gL2Rldi8kZHJpdmVOYW1lIGlz IG5laXRoZXIgYSBsaW5rIG5vciBhIGJsb2NrLiBUaGUgcnVsZSBpcyBmYWlsZWQKCglpZiBb IC1MICR1ZGV2X3Jvb3QvJGRyaXZlTmFtZSBdOyB0aGVuCgkgICAgWyAtYiAkdWRldl9yb290 LyRkcml2ZU5hbWUgXSB8fCBmYWlsYmFjayAyCgkgICAgZGlzYz1gcmVhZGxpbmsgJHVkZXZf cm9vdC8kZHJpdmVOYW1lYCB8fCBmYWlsYmFjayAzCgkgICAgWyAieCR7ZGlzYyNkaXNjcy99 IiA9ICJ4JGRpc2MiIC1vICJ4JHtkaXNjJS9kaXNjfSIgPSAieCRkaXNjIiBdICYmIGZhaWxi YWNrIDMKCSAgICBlY2hvICR7ZGlzYyVkaXNjfXBhcnQkUEFSVE5VTQoJZWxpZiBbIC1iICR1 ZGV2X3Jvb3QvJGRyaXZlTmFtZSAgXTsgdGhlbgoJICAgIGZvciBkaXNjIGluICR1ZGV2X3Jv b3QvZGlzY3MvKi9kaXNjOyBkbwoJCVsgLUwgJGRpc2MgXSB8fCBjb250aW51ZQoJCWRyaXZl PWByZWFscGF0aCAkZGlzY2AgfHwgY29udGludWUKCQlbICJ4JGRyaXZlIiA9ICJ4JHVkZXZf cm9vdC8kZHJpdmVOYW1lIiBdIHx8IGNvbnRpbnVlCgkJZWNobyAke2Rpc2MlZGlzY31wYXJ0 JFBBUlROVU0KCQlleGl0IDAKCSAgICBkb25lCgkgICAgIyBObyBhcHByb3ByaWF0ZSBsaW5r CgkgICAgZmFpbGJhY2sgNAoJZWxzZQoJICAgIGZhaWxiYWNrIDUKICAgICAgICBmaQpmaQpl eGl0IDAKCg== --------------010601070409070605020405 Content-Type: text/x-patch; name="udev-0.46-alt-Nfmt.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="udev-0.46-alt-Nfmt.patch" diff -urN udev-046.orig/namedev.c udev-046/namedev.c --- udev-046.orig/namedev.c 2004-12-28 02:44:57 +0600 +++ udev-046/namedev.c 2004-12-28 02:48:45 +0600 @@ -178,19 +178,13 @@ return -1; } -/** Finds the lowest positive N such that N isn't present in - * $(udevroot) either as a file or a symlink. - * - * @param name Name to check for - * @return 0 if didn't exist and N otherwise. +/** Internal function used by find_free_number and + * find_free_number_zerobase */ -static int find_free_number(struct udevice *udev, const char *name, const char *tail) +static int find_free_number_internal(struct udevice *udev, const char *name, const char* tail, char *filename, int maxsize) { - char filename[NAME_SIZE]; int num = 0; struct udevice db_udev; - - snprintf(filename, NAME_SIZE, "%s%s", name, tail); while (1) { dbg("look for existing node '%s'", filename); memset(&db_udev, 0x00, sizeof(struct udevice)); @@ -204,11 +198,36 @@ info("find_free_number gone crazy (num=%d), aborted", num); return -1; } - snprintf(filename, NAME_SIZE, "%s%d%s", name, num, tail); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, maxsize, "%s%d%s", name, num, tail); } } +/** Finds the lowest positive N such that N isn't present in + * $(udevroot) either as a file or a symlink. + * + * @param name Name to check for + * @return 0 if didn't exist and N otherwise. + */ +static int find_free_number(struct udevice *udev, const char *name, const char *tail) +{ + char filename[NAME_SIZE]; + snprintf(filename, NAME_SIZE, "%s%s", name, tail); + return find_free_number_internal(udev, name, tail, filename, NAME_SIZE); +} + +/** Finds the lowest non-negative N such that N isn't present in + * $(udevroot) either as a file or a symlink. + * + * @param name Name to check for + * @return 0 if didn't exist and N otherwise. + */ +static int find_free_number_zerobase(struct udevice *udev, const char *name, const char *tail) +{ + char filename[NAME_SIZE]; + snprintf(filename, NAME_SIZE, "%s%d%s", name, 0, tail); + return find_free_number_internal(udev, name, tail, filename, NAME_SIZE); +} + static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device); @@ -344,6 +363,18 @@ } strfieldcatmax(string, tail, maxsize); return; + case 'N': + if (!use_ext) { + dbg("prohibited usage of attribute %%e"); + break; + } + /* prohibite "extended" attributes in tail */ + apply_format_token(udev, tail, NAME_SIZE, class_dev, sysfs_device, 0); + next_free_number = find_free_number_zerobase(udev, string, tail); + sprintf(temp2, "%d", next_free_number); + strfieldcatmax(string, temp2, maxsize); + strfieldcatmax(string, tail, maxsize); + return; default: dbg("unknown substitution type '%%%c'", c); break; diff -urN udev-046.orig/udev.8.in udev-046/udev.8.in --- udev-046.orig/udev.8.in 2004-11-19 01:39:15 +0600 +++ udev-046/udev.8.in 2004-12-28 02:49:59 +0600 @@ -285,6 +285,10 @@ can be used to create compatibility symlinks and enumerate devices of the same type originating from different kernel subsystems. .TP +.B %N +Similar to %e but always substituted by a smallest non-negative number +giving an unique device node. +.TP .B %% The '%' character itself. .P --------------010601070409070605020405 Content-Type: text/x-patch; name="udev-0.46-alt-Ufmt.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="udev-0.46-alt-Ufmt.patch" diff -urN udev-046.orig/namedev.c udev-046/namedev.c --- udev-046.orig/namedev.c 2004-12-28 02:50:52 +0600 +++ udev-046/namedev.c 2004-12-28 02:51:21 +0600 @@ -375,6 +375,22 @@ strfieldcatmax(string, temp2, maxsize); strfieldcatmax(string, tail, maxsize); return; + case 'U': + if (!use_ext) { + dbg("prohibited usage of attribute %%e"); + break; + } + /* prohibite "extended" attributes in tail */ + apply_format_token(udev, tail, NAME_SIZE, class_dev, sysfs_device, 0); + { + struct udevice db_udev; + strfieldcatmax(string, tail, maxsize); + if (0 == udev_db_get_device_byname(&db_udev, string)) { + /* device exists */ + string[0] = '\0'; + } + } + return; default: dbg("unknown substitution type '%%%c'", c); break; diff -urN udev-046.orig/udev.8.in udev-046/udev.8.in --- udev-046.orig/udev.8.in 2004-12-28 02:50:52 +0600 +++ udev-046/udev.8.in 2004-12-28 02:52:36 +0600 @@ -289,6 +289,11 @@ similar to %e but always substituted by a smallest non-negative number giving an unique device node. .TP +.B %N +If a device node already exists with the name, the entire name is skipped. +This allows to create, say, /dev/cdrom (usually a link) but not /dev/cdrom1 +and only if /dev/cdrom doesn't exist before +.TP .B %% The '%' character itself. .P --------------010601070409070605020405 Content-Type: text/x-patch; name="udev-0.46-alt-compile_warnings.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="udev-0.46-alt-compile_warnings.patch" diff -urN udev-046.orig/udev_db.c udev-046/udev_db.c --- udev-046.orig/udev_db.c 2004-12-09 22:10:53 +0600 +++ udev-046/udev_db.c 2004-12-09 22:12:28 +0600 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "udev.h" --------------010601070409070605020405 Content-Type: text/x-patch; name="udev-0.50-alt-system_sysfs.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="udev-0.50-alt-system_sysfs.patch" diff -urN udev-050.orig/extras/scsi_id/Makefile udev-050/extras/scsi_id/Makefile --- udev-050.orig/extras/scsi_id/Makefile 2004-12-18 11:53:07 +0600 +++ udev-050/extras/scsi_id/Makefile 2005-01-02 22:15:19 +0600 @@ -31,6 +31,11 @@ override CFLAGS+=-Wall -fno-builtin PROG=scsi_id + +ifeq ($(strip $(SYS_SYSFS)),) +CPPFLAGS = -I../../libsysfs +endif + SYSFS=-lsysfs # @@ -53,7 +58,7 @@ echo $(INSTALL_DATA) -D ./scsi_id.config $(DESTDIR)$(etcdir); \ $(INSTALL_DATA) -D ./scsi_id.config $(DESTDIR)$(etcdir)/scsi_id.config; \ fi - + uninstall: -rm $(DESTDIR)$(sbindir)/$(PROG) -rm $(DESTDIR)$(mandir)/man8/scsi_id.8 @@ -73,7 +78,7 @@ spotless: clean .c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + $(QUIET) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< $(PROG): $(OBJS) $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) diff -urN udev-050.orig/extras/volume_id/Makefile udev-050/extras/volume_id/Makefile --- udev-050.orig/extras/volume_id/Makefile 2004-12-18 11:53:07 +0600 +++ udev-050/extras/volume_id/Makefile 2005-01-02 22:13:39 +0600 @@ -28,14 +28,24 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} +ifeq ($(strip $(SYS_SYSFS)),) +CPPFLAGS = -I../../libsysfs +endif + override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \ -Wpointer-arith -Wcast-align -Wsign-compare override CFLAGS+=-D_FILE_OFFSET_BITS=64 -OBJS = volume_id.o udev_volume_id.o dasdlabel.o $(SYSFS) +OBJS = volume_id.o udev_volume_id.o dasdlabel.o HEADERS = volume_id.h dasdlabel.h +ifeq ($(strip $(SYS_SYSFS)),) +OBJS += $(SYSFS) +else +LDFLAGS += $(SYS_SYSFS) +endif + $(OBJS): $(HEADERS) .c.o: diff -urN udev-050.orig/extras/volume_id/udev_volume_id.c udev-050/extras/volume_id/udev_volume_id.c --- udev-050.orig/extras/volume_id/udev_volume_id.c 2004-12-18 11:53:07 +0600 +++ udev-050/extras/volume_id/udev_volume_id.c 2005-01-02 20:09:11 +0600 @@ -28,7 +28,7 @@ #include #include -#include "../../libsysfs/sysfs/libsysfs.h" +#include #include "../../udev_utils.h" #include "../../logging.h" #include "volume_id.h" diff -urN udev-050.orig/libsysfs/dlist.c udev-050/libsysfs/dlist.c --- udev-050.orig/libsysfs/dlist.c 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/dlist.c 2005-01-02 20:09:11 +0600 @@ -27,7 +27,7 @@ * delete function. Otherwise dlist will just use free. */ -#include "dlist.h" +#include "sysfs/dlist.h" /* * Return pointer to node at marker. diff -urN udev-050.orig/libsysfs/dlist.h udev-050/libsysfs/dlist.h --- udev-050.orig/libsysfs/dlist.h 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/dlist.h 1970-01-01 07:00:00 +0700 @@ -1,205 +0,0 @@ -/* - * dlist.h - * - * Copyright (C) 2003 Eric J Bohm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _DLIST_H_ -#define _DLIST_H_ - -/* Double linked list header. - -* navigate your list with DLIST_PREV and DLIST_NEXT. These are macros -* so function call overhead is minimized. - -* Supports perl style push, pop, shift, unshift list semantics. - -* You allocate the data and give dlist the pointer. If your data is -* complex set the dlist->del_func to a an appropriate delete using -* dlist_new_with_delete. Your delete function must match -(void * )(del(void *) -*Otherwise dlist will just use free. - -* NOTE: The small amount of pain involved in doing that allows us to -* avoid copy in copy out semantics. - -* Dlist uses an internal mark pointer to keep track of where you are -* in the list. - -* insert and delete take a directional parameter. Where direction -* corresponds to the direction in which you want the list to go. -* true direction corresponded to progressing forward in the last -* false to regressing in the list. -* so a dlist_insert(yourlist,item,1) will insert it after the mark -* so a dlist_insert(yourlist,item,0) will insert it before the mark -* any insert will move the mark to the new node regardless of the direction. - -* Just use the dlist_(insert|delete)_(before|after) macros if you do not want -* to think about it. - -*/ -#include -typedef struct dl_node { - struct dl_node *prev; - struct dl_node *next; - void *data; -} DL_node; - -typedef struct dlist { - DL_node *marker; - unsigned long count; - size_t data_size; - void (*del_func)(void *); - DL_node headnode; - DL_node *head; -} Dlist; - -Dlist *dlist_new(size_t datasize); -Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)); -void *_dlist_mark_move(Dlist *list,int direction); -void *dlist_mark(Dlist *); -void dlist_start(Dlist *); -void dlist_end(Dlist *); -void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction); -void *dlist_insert(Dlist *,void *,int) ; - -void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *)); - -void dlist_delete(Dlist *,int); - -void dlist_push(Dlist *,void *); - -void dlist_unshift(Dlist *,void *); -void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *)); - -void *dlist_pop(Dlist *); - -void *dlist_shift(Dlist *); - -void dlist_destroy(Dlist *); - -int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)); - -void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)); - -void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)); - - -void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b); - -void dlist_transform(struct dlist *list, void (*node_operation)(void *)); - - -/* - * _dlist_remove is for internal use only - * _dlist_mark_move is for internal use only - */ -void *_dlist_remove(struct dlist *,struct dl_node *,int ); -void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction); - -#define dlist_prev(A) _dlist_mark_move((A),0) -#define dlist_next(A) _dlist_mark_move((A),1) - -#define dlist_insert_before(A,B) dlist_insert((A),(B),0) -#define dlist_insert_after(A,B) dlist_insert((A),(B),1) - -#define dlist_delete_before(A) dlist_delete((A),0) -#define dlist_delete_after(A) dlist_delete((A),1) - -/** - * provide for loop header which iterates the mark from start to end - * list: the dlist pointer, use dlist_mark(list) to get iterator - */ -#define dlist_for_each(list) \ - for(dlist_start(list),dlist_next(list); \ - (list)->marker!=(list)->head;dlist_next(list)) - -/** - * provide for loop header which iterates the mark from end to start - * list: the dlist pointer, use dlist_mark(list) to get iterator - */ -#define dlist_for_each_rev(list) \ - for(dlist_end(list),dlist_prev(list); \ - (list)->marker!=(list)->head;dlist_prev(list)) - -/** - * provide for loop header which iterates through the list without moving mark - * list: the dlist_pointer - * iterator: dl_node pointer to iterate - */ -#define dlist_for_each_nomark(list,iterator) \ - for((iterator)=(list)->head->next; (iterator)!=(list)->head; \ - (iterator)=(iterator)->next) - -/** - * provide for loop header which iterates through the list without moving mark - * in reverse - * list: the dlist_pointer - * iterator: dl_node pointer to iterate - */ -#define dlist_for_each_nomark_rev(list,iterator) \ - for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \ - (iterator)=(iterator)->prev) -/** - * provide for loop header which iterates through the list providing a - * data iterator - * list: the dlist pointer - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ - -#define dlist_for_each_data(list,data_iterator,datatype) \ - for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \ - (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list)) - -/** - * provide for loop header which iterates through the list providing a - * data iterator in reverse - * list: the dlist pointer - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ -#define dlist_for_each_data_rev(list,data_iterator,datatype) \ - for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \ - (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list)) - -/** - * provide for loop header which iterates through the list providing a - * data iterator without moving the mark - * list: the dlist pointer - * iterator: the dl_node pointer to iterate - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ - -#define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \ - for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \ - (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator)) - -/** - * provide for loop header which iterates through the list providing a - * data iterator in reverse without moving the mark - * list: the dlist pointer - * iterator: the dl_node pointer to iterate - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ -#define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \ - for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \ - (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator)) - -#endif /* _DLIST_H_ */ diff -urN udev-050.orig/libsysfs/sysfs/dlist.h udev-050/libsysfs/sysfs/dlist.h --- udev-050.orig/libsysfs/sysfs/dlist.h 1970-01-01 07:00:00 +0700 +++ udev-050/libsysfs/sysfs/dlist.h 2005-01-02 20:09:11 +0600 @@ -0,0 +1,205 @@ +/* + * dlist.h + * + * Copyright (C) 2003 Eric J Bohm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _DLIST_H_ +#define _DLIST_H_ + +/* Double linked list header. + +* navigate your list with DLIST_PREV and DLIST_NEXT. These are macros +* so function call overhead is minimized. + +* Supports perl style push, pop, shift, unshift list semantics. + +* You allocate the data and give dlist the pointer. If your data is +* complex set the dlist->del_func to a an appropriate delete using +* dlist_new_with_delete. Your delete function must match +(void * )(del(void *) +*Otherwise dlist will just use free. + +* NOTE: The small amount of pain involved in doing that allows us to +* avoid copy in copy out semantics. + +* Dlist uses an internal mark pointer to keep track of where you are +* in the list. + +* insert and delete take a directional parameter. Where direction +* corresponds to the direction in which you want the list to go. +* true direction corresponded to progressing forward in the last +* false to regressing in the list. +* so a dlist_insert(yourlist,item,1) will insert it after the mark +* so a dlist_insert(yourlist,item,0) will insert it before the mark +* any insert will move the mark to the new node regardless of the direction. + +* Just use the dlist_(insert|delete)_(before|after) macros if you do not want +* to think about it. + +*/ +#include +typedef struct dl_node { + struct dl_node *prev; + struct dl_node *next; + void *data; +} DL_node; + +typedef struct dlist { + DL_node *marker; + unsigned long count; + size_t data_size; + void (*del_func)(void *); + DL_node headnode; + DL_node *head; +} Dlist; + +Dlist *dlist_new(size_t datasize); +Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)); +void *_dlist_mark_move(Dlist *list,int direction); +void *dlist_mark(Dlist *); +void dlist_start(Dlist *); +void dlist_end(Dlist *); +void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction); +void *dlist_insert(Dlist *,void *,int) ; + +void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *)); + +void dlist_delete(Dlist *,int); + +void dlist_push(Dlist *,void *); + +void dlist_unshift(Dlist *,void *); +void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *)); + +void *dlist_pop(Dlist *); + +void *dlist_shift(Dlist *); + +void dlist_destroy(Dlist *); + +int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)); + +void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)); + +void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)); + + +void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b); + +void dlist_transform(struct dlist *list, void (*node_operation)(void *)); + + +/* + * _dlist_remove is for internal use only + * _dlist_mark_move is for internal use only + */ +void *_dlist_remove(struct dlist *,struct dl_node *,int ); +void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction); + +#define dlist_prev(A) _dlist_mark_move((A),0) +#define dlist_next(A) _dlist_mark_move((A),1) + +#define dlist_insert_before(A,B) dlist_insert((A),(B),0) +#define dlist_insert_after(A,B) dlist_insert((A),(B),1) + +#define dlist_delete_before(A) dlist_delete((A),0) +#define dlist_delete_after(A) dlist_delete((A),1) + +/** + * provide for loop header which iterates the mark from start to end + * list: the dlist pointer, use dlist_mark(list) to get iterator + */ +#define dlist_for_each(list) \ + for(dlist_start(list),dlist_next(list); \ + (list)->marker!=(list)->head;dlist_next(list)) + +/** + * provide for loop header which iterates the mark from end to start + * list: the dlist pointer, use dlist_mark(list) to get iterator + */ +#define dlist_for_each_rev(list) \ + for(dlist_end(list),dlist_prev(list); \ + (list)->marker!=(list)->head;dlist_prev(list)) + +/** + * provide for loop header which iterates through the list without moving mark + * list: the dlist_pointer + * iterator: dl_node pointer to iterate + */ +#define dlist_for_each_nomark(list,iterator) \ + for((iterator)=(list)->head->next; (iterator)!=(list)->head; \ + (iterator)=(iterator)->next) + +/** + * provide for loop header which iterates through the list without moving mark + * in reverse + * list: the dlist_pointer + * iterator: dl_node pointer to iterate + */ +#define dlist_for_each_nomark_rev(list,iterator) \ + for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \ + (iterator)=(iterator)->prev) +/** + * provide for loop header which iterates through the list providing a + * data iterator + * list: the dlist pointer + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ + +#define dlist_for_each_data(list,data_iterator,datatype) \ + for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \ + (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list)) + +/** + * provide for loop header which iterates through the list providing a + * data iterator in reverse + * list: the dlist pointer + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ +#define dlist_for_each_data_rev(list,data_iterator,datatype) \ + for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \ + (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list)) + +/** + * provide for loop header which iterates through the list providing a + * data iterator without moving the mark + * list: the dlist pointer + * iterator: the dl_node pointer to iterate + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ + +#define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \ + for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \ + (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator)) + +/** + * provide for loop header which iterates through the list providing a + * data iterator in reverse without moving the mark + * list: the dlist pointer + * iterator: the dl_node pointer to iterate + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ +#define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \ + for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \ + (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator)) + +#endif /* _DLIST_H_ */ diff -urN udev-050.orig/libsysfs/sysfs_bus.c udev-050/libsysfs/sysfs_bus.c --- udev-050.orig/libsysfs/sysfs_bus.c 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/sysfs_bus.c 2005-01-02 20:09:11 +0600 @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" static void sysfs_close_dev(void *dev) diff -urN udev-050.orig/libsysfs/sysfs_class.c udev-050/libsysfs/sysfs_class.c --- udev-050.orig/libsysfs/sysfs_class.c 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/sysfs_class.c 2005-01-02 20:09:11 +0600 @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" static void sysfs_close_cls_dev(void *dev) diff -urN udev-050.orig/libsysfs/sysfs_device.c udev-050/libsysfs/sysfs_device.c --- udev-050.orig/libsysfs/sysfs_device.c 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/sysfs_device.c 2005-01-02 20:09:11 +0600 @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" /** diff -urN udev-050.orig/libsysfs/sysfs_dir.c udev-050/libsysfs/sysfs_dir.c --- udev-050.orig/libsysfs/sysfs_dir.c 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/sysfs_dir.c 2005-01-02 20:09:11 +0600 @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" /** diff -urN udev-050.orig/libsysfs/sysfs_driver.c udev-050/libsysfs/sysfs_driver.c --- udev-050.orig/libsysfs/sysfs_driver.c 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/sysfs_driver.c 2005-01-02 20:09:11 +0600 @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" static void sysfs_close_driver_device(void *device) diff -urN udev-050.orig/libsysfs/sysfs_utils.c udev-050/libsysfs/sysfs_utils.c --- udev-050.orig/libsysfs/sysfs_utils.c 2004-12-18 11:53:07 +0600 +++ udev-050/libsysfs/sysfs_utils.c 2005-01-02 20:09:11 +0600 @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" static int sort_char(void *new, void *old) diff -urN udev-050.orig/Makefile udev-050/Makefile --- udev-050.orig/Makefile 2004-12-18 11:53:07 +0600 +++ udev-050/Makefile 2005-01-02 22:12:55 +0600 @@ -92,7 +92,11 @@ RANLIB = $(CROSS)ranlib HOSTCC = gcc -export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH_LIB_OBJS CRT0 +ifeq ($(strip $(SYS_SYSFS)),) +CPPFLAGS = -I`pwd`/libsysfs +endif + +export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH_LIB_OBJS CRT0 CPPFLAGS # code taken from uClibc to determine the current arch ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ @@ -170,9 +174,6 @@ LIB_OBJS += -lselinux endif -CFLAGS += -I$(PWD)/libsysfs/sysfs \ - -I$(PWD)/libsysfs - # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf @@ -182,6 +183,7 @@ $(MAKE) prefix=$(prefix) \ LD="$(LD)" \ SYSFS="$(SYSFS)" \ + SYS_SYSFS=$(SYS_SYSFS) \ KERNEL_DIR="$(KERNEL_DIR)" \ QUIET="$(QUIET)" \ -C $$target $@ ; \ @@ -227,11 +229,13 @@ namedev.o \ namedev_parse.o -OBJS = \ - libsysfs/sysfs.a \ - udev.a - +ifneq ($(strip $(SYS_SYSFS)),) +LIB_OBJS += $(SYS_SYSFS) +else SYSFS = $(PWD)/libsysfs/sysfs.a +endif + +OBJS = udev.a $(SYSFS) ifeq ($(strip $(USE_KLIBC)),true) HEADERS += \ @@ -258,7 +262,7 @@ $(QUIET) $(AR) cq $@ $(UDEV_OBJS) $(QUIET) $(RANLIB) $@ -libsysfs/sysfs.a: $(SYSFS_OBJS) +$(PWD)/libsysfs/sysfs.a: $(SYSFS_OBJS) rm -f $@ $(QUIET) $(AR) cq $@ $(SYSFS_OBJS) $(QUIET) $(RANLIB) $@ @@ -331,7 +335,7 @@ $(QUIET) $(STRIPCMD) $@ .c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + $(QUIET) $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< clean: @@ -342,7 +346,7 @@ $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ - $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + $(MAKE) prefix=$(prefix) LD="$(LD)" SYS_SYSFS=$(SYS_SYSFS) SYSFS="$(SYSFS)" \ -C $$target $@ ; \ done ; \ @@ -437,7 +441,7 @@ endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ - $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + $(MAKE) prefix=$(prefix) LD="$(LD)" SYS_SYSFS=$(SYS_SYSFS) SYSFS="$(SYSFS)" \ -C $$target $@ ; \ done ; \ @@ -461,7 +465,7 @@ - killall $(DAEMON) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ - $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + $(MAKE) prefix=$(prefix) LD="$(LD)" SYS_SYSFS=$(SYS_SYSFS) SYSFS="$(SYSFS)" \ -C $$target $@ ; \ done ; \ diff -urN udev-050.orig/namedev.c udev-050/namedev.c --- udev-050.orig/namedev.c 2004-12-18 11:53:07 +0600 +++ udev-050/namedev.c 2005-01-02 20:09:11 +0600 @@ -32,7 +32,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "list.h" #include "udev.h" #include "udev_utils.h" diff -urN udev-050.orig/udev_add.c udev-050/udev_add.c --- udev-050.orig/udev_add.c 2004-12-18 11:53:07 +0600 +++ udev-050/udev_add.c 2005-01-02 20:09:11 +0600 @@ -36,7 +36,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "udev.h" #include "udev_utils.h" #include "udev_version.h" diff -urN udev-050.orig/udev.c udev-050/udev.c --- udev-050.orig/udev.c 2004-12-18 11:53:07 +0600 +++ udev-050/udev.c 2005-01-02 20:09:11 +0600 @@ -31,7 +31,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "udev.h" #include "udev_utils.h" #include "udev_sysfs.h" diff -urN udev-050.orig/udev_config.c udev-050/udev_config.c --- udev-050.orig/udev_config.c 2004-12-18 11:53:07 +0600 +++ udev-050/udev_config.c 2005-01-02 20:09:11 +0600 @@ -32,7 +32,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "udev.h" #include "udev_utils.h" #include "udev_version.h" diff -urN udev-050.orig/udev_db.c udev-050/udev_db.c --- udev-050.orig/udev_db.c 2004-12-18 11:53:07 +0600 +++ udev-050/udev_db.c 2005-01-02 20:09:11 +0600 @@ -31,7 +31,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "udev.h" #include "udev_utils.h" #include "logging.h" diff -urN udev-050.orig/udev.h udev-050/udev.h --- udev-050.orig/udev.h 2004-12-18 11:53:07 +0600 +++ udev-050/udev.h 2005-01-02 20:09:11 +0600 @@ -24,7 +24,7 @@ #define _UDEV_H_ #include -#include "libsysfs/sysfs/libsysfs.h" +#include #define ALARM_TIMEOUT 120 #define COMMENT_CHARACTER '#' diff -urN udev-050.orig/udevinfo.c udev-050/udevinfo.c --- udev-050.orig/udevinfo.c 2004-12-18 11:53:07 +0600 +++ udev-050/udevinfo.c 2005-01-02 20:09:11 +0600 @@ -27,8 +27,8 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "libsysfs/dlist.h" +#include +#include #include "udev.h" #include "udev_utils.h" #include "udev_version.h" diff -urN udev-050.orig/udev_start.c udev-050/udev_start.c --- udev-050.orig/udev_start.c 2004-12-18 11:53:07 +0600 +++ udev-050/udev_start.c 2005-01-02 20:09:11 +0600 @@ -33,7 +33,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "logging.h" #include "udev_utils.h" #include "list.h" diff -urN udev-050.orig/udev_sysfs.c udev-050/udev_sysfs.c --- udev-050.orig/udev_sysfs.c 2004-12-18 11:53:07 +0600 +++ udev-050/udev_sysfs.c 2005-01-02 20:09:11 +0600 @@ -28,7 +28,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "udev_version.h" #include "udev_sysfs.h" #include "udev_utils.h" diff -urN udev-050.orig/udev_sysfs.h udev-050/udev_sysfs.h --- udev-050.orig/udev_sysfs.h 2004-12-18 11:53:07 +0600 +++ udev-050/udev_sysfs.h 2005-01-02 20:09:11 +0600 @@ -22,7 +22,7 @@ #ifndef _UDEV_SYSFS_H_ #define _UDEV_SYSFS_H_ -#include "libsysfs/sysfs/libsysfs.h" +#include #define WAIT_MAX_SECONDS 5 #define WAIT_LOOP_PER_SECOND 20 diff -urN udev-050.orig/udevtest.c udev-050/udevtest.c --- udev-050.orig/udevtest.c 2004-12-18 11:53:07 +0600 +++ udev-050/udevtest.c 2005-01-02 20:09:11 +0600 @@ -27,7 +27,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" +#include #include "udev.h" #include "udev_sysfs.h" #include "udev_utils.h" --------------010601070409070605020405 Content-Type: text/x-patch; name="udev-0.46-alt-efmt_fixes.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="udev-0.46-alt-efmt_fixes.patch" diff -urN udev-046.orig/namedev.c udev-046/namedev.c --- udev-046.orig/namedev.c 2004-12-28 02:43:18 +0600 +++ udev-046/namedev.c 2004-12-28 02:43:54 +0600 @@ -184,13 +184,13 @@ * @param name Name to check for * @return 0 if didn't exist and N otherwise. */ -static int find_free_number(struct udevice *udev, const char *name) +static int find_free_number(struct udevice *udev, const char *name, const char *tail) { char filename[NAME_SIZE]; int num = 0; struct udevice db_udev; - strfieldcpy(filename, name); + snprintf(filename, NAME_SIZE, "%s%s", name, tail); while (1) { dbg("look for existing node '%s'", filename); memset(&db_udev, 0x00, sizeof(struct udevice)); @@ -204,14 +204,18 @@ info("find_free_number gone crazy (num=%d), aborted", num); return -1; } - snprintf(filename, NAME_SIZE, "%s%d", name, num); + snprintf(filename, NAME_SIZE, "%s%d%s", name, num, tail); filename[NAME_SIZE-1] = '\0'; } } static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_class_device *class_dev, - struct sysfs_device *sysfs_device) + struct sysfs_device *sysfs_device); + +static void apply_format_token(struct udevice *udev, char *string, size_t maxsize, + struct sysfs_class_device *class_dev, + struct sysfs_device *sysfs_device, int use_ext) { char temp[NAME_SIZE]; char temp2[NAME_SIZE]; @@ -291,12 +295,12 @@ strfieldcpy(temp2, spos); else strfieldcpymax(temp2, spos, slen+1); - strfieldcatmax(string, temp2, maxsize); - dbg("substitute part of result string '%s'", temp2); } else { - strfieldcatmax(string, udev->program_result, maxsize); - dbg("substitute result string '%s'", udev->program_result); + strfieldcpy(temp2, udev->program_result); } + apply_format(udev, temp2, NAME_SIZE, class_dev, sysfs_device); + strfieldcatmax(string, temp2, maxsize); + dbg("substitute part of result string '%s'", temp2); break; case 's': if (attr != NULL) { @@ -327,12 +331,19 @@ pos++; break; case 'e': - next_free_number = find_free_number(udev, string); + if (!use_ext) { + dbg("prohibited usage of attribute %%e"); + break; + } + /* prohibite "extended" attributes in tail */ + apply_format_token(udev, tail, NAME_SIZE, class_dev, sysfs_device, 0); + next_free_number = find_free_number(udev, string, tail); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); strfieldcatmax(string, temp2, maxsize); } - break; + strfieldcatmax(string, tail, maxsize); + return; default: dbg("unknown substitution type '%%%c'", c); break; @@ -345,6 +356,67 @@ } } +#define declare_string_size(strname, strsize) char (strname)[strsize] +/* A decimal number can't be more then 30 symbols wide */ +#define maxint_digits 30 +static void apply_format(struct udevice *udev, char *string, size_t maxsize, + struct sysfs_class_device *class_dev, + struct sysfs_device *sysfs_device) +{ + int consumed; + char *tokenptr; + size_t tokenspace; + size_t tokenlen; + char *stringptr = string; + char sscanf_ptrn[5 + maxint_digits]; + declare_string_size(token, maxsize); + snprintf(sscanf_ptrn, 5 + maxint_digits, "%%%ds%%n", maxsize - 1); + tokenptr = token; + tokenptr[0] = '\0'; + tokenspace = maxsize; + while (0 < sscanf(stringptr, sscanf_ptrn, tokenptr, &consumed)) { + /* next token now has been put into 'token' + * let's process it... + */ + apply_format_token(udev, tokenptr, tokenspace, class_dev, sysfs_device, 1); + + /* Now we need to add a trailing whitespace to the + * processed token and advance to the next string's + * token... + */ + stringptr += consumed; + tokenlen = strlen(tokenptr); + /* hopefully I didn't make a mistake in bound + * checks... tokenlen is always less than tokenspace + * at least by one. But we need to check if there's a + * space for additional whitespace and next token + * (i.e. tokenlen must be at least 3 bytes less than + * tokenspace). Additionally we should prevent int + * overflow errors... + */ + if (tokenspace < 3 || tokenspace - 3 <= tokenlen) { + if (*stringptr) + dbg("Space exhausted while some trailing data left in format string"); + break; + } + strncat(tokenptr + tokenlen, " ", tokenspace - tokenlen - 1); + tokenptr += tokenlen + 1; + tokenspace -= tokenlen + 1; + /* and finally adjust sscanf_ptrn to prevent buffer + * overflow in sscanf + */ + snprintf(sscanf_ptrn, 5 + maxint_digits, "%%%ds%%n", tokenspace - 1); + } + /* remove leading and trailing whitespace. They do matter sometimes */ + for(tokenptr = token;isspace(*tokenptr);tokenptr++); + tokenlen = strlen(tokenptr); + if (tokenlen > 0) + tokenptr[tokenlen - 1] = '\0'; + strncpy(string, tokenptr, maxsize); +} +#undef declare_string_size +#undef maxint_digits + static void fix_kernel_name(struct udevice *udev) { char *temp = udev->kernel_name; --------------010601070409070605020405-- ------------------------------------------------------- The SF.Net email is sponsored by: Beat the post-holiday blues Get a FREE limited edition SourceForge.net t-shirt from ThinkGeek. It's fun and FREE -- well, almost....http://www.thinkgeek.com/sfshirt _______________________________________________ Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net Linux-hotplug-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel