10 #include <sys/ioctl.h>
13 #include <sys/statfs.h>
17 #define BLKGETSIZE _IO(0x12,96)
20 #define BLKGETSIZE64 _IOR(0x12,114,size_t)
23 static uint64_t get_psize(char *dev
)
26 unsigned long sectors
;
29 if ((fd
= open(dev
, O_RDONLY
)) >= 0) {
30 if (ioctl(fd
, BLKGETSIZE64
, &bytes
) < 0) {
32 /* Can't get bytes, try 512 byte sectors */
33 if (ioctl(fd
, BLKGETSIZE
, §ors
) >= 0)
34 bytes
= (uint64_t)sectors
<< 9;
42 #define PROC_SCSI_ROOT "/proc/scsi"
43 #define USB_STORAGE "usb-storage"
45 int is_partition_mounted(char *dev_name
, int host_num
, char *dsc_name
, char *pt_name
, uint flags
)
54 type
= find_label_or_uuid(dev_name
, the_label
, NULL
);
55 if (*the_label
== 0) {
56 strncpy(the_label
, pt_name
, sizeof(the_label
));
59 if (flags
& EFH_PRINT
) {
60 if (flags
& EFH_1ST_DISC
) {
61 // [disc_name, [partitions array]],...
62 web_printf("]],['%s',[", dsc_name
);
64 // [partition_name, is_mounted, mount_point, type, opts, size, free],...
65 js
= js_string(the_label
);
66 web_printf("%s['%s',", (flags
& EFH_1ST_DISC
) ? "" : ",", js
? : "");
70 if ((mnt
= findmntents(dev_name
, 0, 0, 0))) {
72 if (flags
& EFH_PRINT
) {
73 if (statfs(mnt
->mnt_dir
, &sf
) == 0) {
74 size
= (uint64_t)sf
.f_bsize
* sf
.f_blocks
;
75 fsize
= (uint64_t)sf
.f_bsize
* sf
.f_bfree
;
78 size
= get_psize(dev_name
);
81 web_printf("1,'%s','%s','%s',%llu,%llu]",
82 mnt
->mnt_dir
, mnt
->mnt_type
, mnt
->mnt_opts
, size
, fsize
);
85 else if ((mnt
= findmntents(dev_name
, 1, 0, 0))) {
87 if (flags
& EFH_PRINT
) {
88 web_printf("2,'','swap','',%llu,0]",
89 (uint64_t)atoi(mnt
->mnt_type
) * 1024);
93 if (flags
& EFH_PRINT
) {
94 web_printf("0,'','%s','',%llu,0]", type
? : "", get_psize(dev_name
));
101 int is_host_mounted(int host_no
, int print_parts
)
103 if (print_parts
) web_puts("[-1,[");
105 int mounted
= exec_for_host(
108 print_parts
? EFH_PRINT
: 0,
109 is_partition_mounted
);
111 if (print_parts
) web_puts("]]");
117 * The disc # doesn't correspond to the host#, since there may be more than
118 * one partition on a disk.
119 * Nor does either correspond to the scsi host number.
120 * And if the user plugs or unplugs a usb storage device after bringing up the
121 * NAS:USB support page, the numbers won't match anymore, since "part#"s
122 * may be added or deleted to the /dev/discs* or /dev/scsi**.
124 * But since we only need to support the devices list and mount/unmount
125 * functionality on the host level, the host# shoudl work ok. Just make sure
126 * to always pass and use the _host#_, and not the disc#.
128 void asp_usbdevices(int argc
, char **argv
)
138 char *tmp
, *js_vend
, *js_prod
;
139 char g_usb_vendor
[30], g_usb_product
[30];
141 web_puts("\nusbdev = [");
143 if (!nvram_match("usb_enable", "1")) {
148 /* find all attached USB storage devices */
149 #if 1 // NZ = Get the info from the SCSI subsystem.
150 fp
= fopen(PROC_SCSI_ROOT
"/scsi", "r");
152 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
153 p
= strstr(line
, "Host: scsi");
155 host_no
= atoi(p
+ 10);
156 if (host_no
== last_hn
)
159 if (fgets(line
, sizeof(line
), fp
) != NULL
) {
160 memset(g_usb_vendor
, 0, sizeof(g_usb_vendor
));
161 memset(g_usb_product
, 0, sizeof(g_usb_product
));
162 p
= strstr(line
, " Vendor: ");
163 p1
= strstr(line
+ 10 + 8, " Model: ");
165 strncpy(g_usb_vendor
, p
+ 10, 8);
166 strncpy(g_usb_product
, p1
+ 8, 16);
167 js_vend
= js_string(g_usb_vendor
);
168 js_prod
= js_string(g_usb_product
);
169 web_printf("%s['Storage','%d','%s','%s','', [", i
? "," : "",
170 host_no
, js_vend
? : "", js_prod
? : "");
173 mounted
= is_host_mounted(host_no
, 1);
174 web_printf("], %d]", mounted
);
182 #else // Get the info from the usb/storage subsystem.
184 struct dirent
*scsi_dirent
;
185 char *g_usb_serial
[30];
188 scsi_dir
= opendir(PROC_SCSI_ROOT
);
189 while (scsi_dir
&& (scsi_dirent
= readdir(scsi_dir
)))
191 if (!strncmp(USB_STORAGE
, scsi_dirent
->d_name
, strlen(USB_STORAGE
)))
193 sprintf(line
, "%s/%s", PROC_SCSI_ROOT
, scsi_dirent
->d_name
);
194 usb_dir
= opendir(line
);
195 while (usb_dir
&& (dp
= readdir(usb_dir
)))
197 if (!strcmp(dp
->d_name
, "..") || !strcmp(dp
->d_name
, "."))
199 sprintf(line
, "%s/%s/%s", PROC_SCSI_ROOT
, scsi_dirent
->d_name
, dp
->d_name
);
201 fp
= fopen(line
, "r");
205 g_usb_product
[0] = 0;
209 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
210 if (strstr(line
, "Attached: Yes")) {
213 else if (strstr(line
, "Vendor")) {
214 tmp
= strtok(line
, " ");
215 tmp
= strtok(NULL
, "\n");
216 strncpy(g_usb_vendor
, tmp
, sizeof(g_usb_vendor
) - 1);
219 else if (strstr(line
, "Product")) {
220 tmp
= strtok(line
, " ");
221 tmp
= strtok(NULL
, "\n");
222 strncpy(g_usb_product
, tmp
, sizeof(g_usb_product
) - 1);
225 else if (strstr(line
, "Serial Number")) {
226 tmp
= strtok(line
, " ");
227 tmp
= strtok(NULL
, " ");
228 tmp
= strtok(NULL
, "\n");
229 strncpy(g_usb_serial
, tmp
, sizeof(g_usb_serial
) - 1);
235 attached
= (strlen(g_usb_product
) > 0) || (strlen(g_usb_vendor
) > 0);
238 /* Host no. assigned by scsi driver for this UFD */
239 host_no
= atoi(dp
->d_name
);
240 js_vend
= js_string(g_usb_vendor
);
241 js_prod
= js_string(g_usb_product
);
242 web_printf("%s['Storage','%d','%s','%s','%s', [", i
? "," : "",
243 host_no
, js_vend
? : "", js_prod
? : "", g_usb_serial
);
246 mounted
= is_host_mounted(host_no
, 1);
247 web_printf("], %d]", mounted
);
261 /* now look for printers */
262 usb_dir
= opendir("/proc/usblp");
263 while (usb_dir
&& (dp
= readdir(usb_dir
)))
265 if (!strcmp(dp
->d_name
, "..") || !strcmp(dp
->d_name
, "."))
268 sprintf(line
, "/proc/usblp/%s", dp
->d_name
);
269 if ((fp
= fopen(line
, "r"))) {
271 g_usb_product
[0] = 0;
274 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
275 if (strstr(line
, "Manufacturer")) {
276 tmp
= strtok(line
, "=");
277 tmp
= strtok(NULL
, "\n");
278 strncpy(g_usb_vendor
, tmp
, sizeof(g_usb_vendor
) - 1);
281 else if (strstr(line
, "Model")) {
282 tmp
= strtok(line
, "=");
283 tmp
= strtok(NULL
, "\n");
284 strncpy(g_usb_product
, tmp
, sizeof(g_usb_product
) - 1);
288 if ((strlen(g_usb_product
) > 0) || (strlen(g_usb_vendor
) > 0)) {
289 js_vend
= js_string(g_usb_vendor
);
290 js_prod
= js_string(g_usb_product
);
291 web_printf("%s['Printer','%s','%s','%s','']", i
? "," : "",
292 dp
->d_name
, js_vend
? : "", js_prod
? : "");
307 void wo_usbcommand(char *url
)
312 web_puts("\nusb = [\n");
313 if ((p
= webcgi_get("remove")) != NULL
) {
316 else if ((p
= webcgi_get("mount")) != NULL
) {
320 add_remove_usbhost(p
, add
);
321 web_printf("%d", is_host_mounted(atoi(p
), 0));