+ for(i=0; array[i]; ++i)
+ free(array[i]);
+ free(array);
+}
+
+/**
+Checks if a partition identified by a sysfs path is on a removable device.
+*/
+int is_removable(char *devpath)
+{
+ char fnbuf[256];
+ int len;
+ char *ptr;
+ int fd;
+
+ len = snprintf(fnbuf, sizeof(fnbuf), "/sys%s", devpath);
+ /* Default to not removable if the path was too long. */
+ if(len+10>=(int)sizeof(fnbuf))
+ return 0;
+
+ /* We got a partition as a parameter, but the removable property is on the
+ disk. Replace the last component with "removable". */
+ for(ptr=fnbuf+len; (ptr>fnbuf && *ptr!='/'); --ptr) ;
+ strcpy(ptr, "/removable");
+
+ fd = open(fnbuf, O_RDONLY);
+ if(fd!=-1)
+ {
+ char c;
+ read(fd, &c, 1);
+ close(fd);
+ if(c=='1')
+ {
+ if(verbosity>=2)
+ printf(" Removable\n");
+ return 1;
+ }
+ if(verbosity>=2)
+ printf(" Not removable\n");
+ }
+
+ return 0;
+}
+
+/**
+Checks if a partition's disk or any of its parent devices are connected to any
+of a set of buses. The device is identified by a sysfs path. The bus array
+must be terminated with a NULL entry.
+*/
+int check_buses(char *devpath, char **buses)
+{
+ char fnbuf[256];
+ char *ptr;
+ int len;
+
+ len = snprintf(fnbuf, sizeof(fnbuf), "/sys%s", devpath);
+ /* Default to no match if the path was too long. */
+ if(len+10>=(int)sizeof(fnbuf))
+ return 0;
+
+ for(ptr=fnbuf+len; ptr>fnbuf+12; --ptr)
+ if(*ptr=='/')
+ {
+ char linkbuf[256];
+ /* Replace the last component with "subsystem". */
+ strcpy(ptr, "/subsystem");
+ len = readlink(fnbuf, linkbuf, sizeof(linkbuf)-1);
+
+ if(len!=-1)
+ {
+ linkbuf[len] = 0;
+ /* Extract the last component of the subsystem symlink. */
+ for(; (len>0 && linkbuf[len-1]!='/'); --len) ;
+
+ if(verbosity>=2)
+ {
+ *ptr = 0;
+ printf(" Subsystem of %s is %s\n", fnbuf, linkbuf+len);
+ }
+
+ if(is_in_array(buses, linkbuf+len))
+ return 1;
+ }
+ }
+
+ return 0;