mount.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/stat.h>
  6. #include <sys/types.h>
  7. #include <fcntl.h>
  8. #include <sys/ioctl.h>
  9. #include <linux/hdreg.h>
  10. #include <scsi/sg.h>
  11. #include <dirent.h>
  12. #include <sys/wait.h>
  13. #include <sys/inotify.h>
  14. #include <sys/stat.h>
  15. #include <sys/types.h>
  16. #include <glob.h>
  17. #include <libgen.h>
  18. #include <poll.h>
  19. #include <dirent.h>
  20. #include "include/log.h"
  21. #include "include/list.h"
  22. #include "include/sys.h"
  23. #include "include/signal.h"
  24. #include "include/timer.h"
  25. #include "include/autofs.h"
  26. #include "include/ucix.h"
  27. #include "include/fs.h"
  28. #include "include/mount.h"
  29. int mount_new(char *path, char *dev);
  30. struct list_head mounts;
  31. struct mount {
  32. struct list_head list;
  33. char name[64];
  34. char dev[64];
  35. char serial[64];
  36. char vendor[64];
  37. char model[64];
  38. char rev[64];
  39. int mounted;
  40. int ignore;
  41. char size[64];
  42. char sector_size[64];
  43. int fs;
  44. };
  45. char *fs_names[] = {
  46. "",
  47. "",
  48. "MBR",
  49. "EXT2",
  50. "EXT3",
  51. "FAT",
  52. "HFSPLUS",
  53. "",
  54. "NTFS",
  55. "",
  56. "EXT4"
  57. };
  58. #define MAX_MOUNTED 32
  59. #define MAX_MOUNT_NAME 32
  60. char mounted[MAX_MOUNTED][3][MAX_MOUNT_NAME];
  61. int mounted_count = 0;
  62. extern char uci_path[32];
  63. static void mount_dump_uci_state(void)
  64. {
  65. struct uci_context *ctx;
  66. struct list_head *p;
  67. char mountd[] = {"mountd"};
  68. char type[] = {"mountd_disc"};
  69. int mounted = 0;
  70. unsigned long long int size = 0;
  71. unlink("/var/state/mountd");
  72. ctx = ucix_init("mountd");
  73. uci_set_savedir(ctx, "/var/state/");
  74. ucix_add_option_int(ctx, mountd, mountd, "count", list_count(&mounts));
  75. list_for_each(p, &mounts)
  76. {
  77. struct mount *q = container_of(p, struct mount, list);
  78. char t[64];
  79. if(q->fs == EXTENDED)
  80. continue;
  81. ucix_add_section(ctx, mountd, q->serial, type);
  82. strcpy(t, q->dev);
  83. t[3] = '\0';
  84. ucix_add_option(ctx, mountd, q->serial, "disc", t);
  85. ucix_add_option(ctx, mountd, q->serial, "sector_size", q->sector_size);
  86. snprintf(t, 64, "part%dmounted", atoi(&q->dev[3]));
  87. ucix_add_option(ctx, mountd, q->serial, t, (q->mounted)?("1"):("0"));
  88. ucix_add_option(ctx, mountd, q->serial, "vendor", q->vendor);
  89. ucix_add_option(ctx, mountd, q->serial, "model", q->model);
  90. ucix_add_option(ctx, mountd, q->serial, "rev", q->rev);
  91. snprintf(t, 64, "size%d", atoi(&q->dev[3]));
  92. ucix_add_option(ctx, mountd, q->serial, t, q->size);
  93. if(q->fs > MBR && q->fs <= EXT4)
  94. {
  95. snprintf(t, 64, "fs%d", atoi(&q->dev[3]));
  96. ucix_add_option(ctx, mountd, q->serial, t, fs_names[q->fs]);
  97. }
  98. if(q->mounted)
  99. mounted++;
  100. if((!q->ignore) && q->size && q->sector_size)
  101. size = size + (((unsigned long long int)atoi(q->size)) * ((unsigned long long int)atoi(q->sector_size)));
  102. }
  103. ucix_add_option_int(ctx, mountd, mountd, "mounted", mounted);
  104. ucix_add_option_int(ctx, mountd, mountd, "total", size);
  105. system_printf("echo -n %llu > /tmp/run/mountd_size", size);
  106. ucix_save_state(ctx, "mountd");
  107. ucix_cleanup(ctx);
  108. }
  109. static struct mount* mount_find(char *name, char *dev)
  110. {
  111. struct list_head *p;
  112. list_for_each(p, &mounts)
  113. {
  114. struct mount *q = container_of(p, struct mount, list);
  115. if(name)
  116. if(!strcmp(q->name, name))
  117. return q;
  118. if(dev)
  119. if(!strcmp(q->dev, dev))
  120. return q;
  121. }
  122. return 0;
  123. }
  124. static void mount_add_list(char *name, char *dev, char *serial,
  125. char *vendor, char *model, char *rev, int ignore, char *size, char *sector_size, int fs)
  126. {
  127. struct mount *mount;
  128. char tmp[64], tmp2[64];
  129. if(fs <= MBR || fs > EXT4)
  130. return;
  131. mount = malloc(sizeof(struct mount));
  132. INIT_LIST_HEAD(&mount->list);
  133. strncpy(mount->vendor, vendor, 64);
  134. strncpy(mount->model, model, 64);
  135. strncpy(mount->rev, rev, 64);
  136. strncpy(mount->name, name, 64);
  137. strncpy(mount->dev, dev, 64);
  138. strncpy(mount->serial, serial, 64);
  139. strncpy(mount->size, size, 64);
  140. strncpy(mount->sector_size, sector_size, 64);
  141. mount->ignore = ignore;
  142. mount->mounted = 0;
  143. mount->fs = fs;
  144. list_add(&mount->list, &mounts);
  145. if((!mount->ignore) && (mount->fs > MBR) && (mount->fs <= EXT4))
  146. {
  147. log_printf("new mount : %s -> %s (%s)\n", name, dev, fs_names[mount->fs]);
  148. snprintf(tmp, 64, "%s%s", uci_path, name);
  149. snprintf(tmp2, 64, "/tmp/run/mountd/%s", dev);
  150. symlink(tmp2, tmp);
  151. mount_new("/tmp/run/mountd/", dev);
  152. }
  153. }
  154. static int mount_check_disc(char *disc)
  155. {
  156. FILE *fp = fopen("/proc/mounts", "r");
  157. char tmp[256];
  158. int avail = -1;
  159. if(!fp)
  160. {
  161. log_printf("error reading /proc/mounts");
  162. fclose(fp);
  163. return avail;
  164. }
  165. while((fgets(tmp, 256, fp) > 0) && (avail == -1))
  166. {
  167. char *t;
  168. char tmp2[32];
  169. t = strstr(tmp, " ");
  170. if(t)
  171. {
  172. int l;
  173. *t = '\0';
  174. l = snprintf(tmp2, 31, "/dev/%s", disc);
  175. if(!strncmp(tmp, tmp2, l))
  176. avail = 0;
  177. }
  178. }
  179. fclose(fp);
  180. return avail;
  181. }
  182. static int mount_wait_for_disc(char *disc)
  183. {
  184. int i = 10;
  185. while(i--)
  186. {
  187. int ret = mount_check_disc(disc);
  188. if(!ret)
  189. return ret;
  190. poll(0, 0, 100);
  191. }
  192. return -1;
  193. }
  194. int mount_new(char *path, char *dev)
  195. {
  196. struct mount *mount;
  197. char tmp[256];
  198. int ret = 1;
  199. pid_t pid;
  200. mount = mount_find(0, dev);
  201. if(!mount)
  202. {
  203. log_printf("request for invalid path %s%s\n", path, dev);
  204. return -1;
  205. }
  206. if(mount->ignore || mount->mounted || mount->fs == EXTENDED)
  207. return -1;
  208. snprintf(tmp, 256, "%s%s", path, mount->dev);
  209. log_printf("mounting %s\n", tmp);
  210. mkdir(tmp, 777);
  211. pid = autofs_safe_fork();
  212. if(!pid)
  213. {
  214. if(mount->fs == FAT)
  215. {
  216. log_printf("mount -t vfat -o rw,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  217. ret = system_printf("mount -t vfat -o rw,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  218. }
  219. if(mount->fs == EXT4)
  220. {
  221. log_printf("mount -t ext4 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  222. ret = system_printf("mount -t ext4 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  223. }
  224. if(mount->fs == EXT3)
  225. {
  226. log_printf("mount -t ext3 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  227. ret = system_printf("mount -t ext3 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  228. }
  229. if(mount->fs == EXT2)
  230. {
  231. log_printf("mount -t ext2 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  232. ret = system_printf("mount -t ext2 -o rw,defaults /dev/%s %s", mount->dev, tmp);
  233. }
  234. if(mount->fs == HFSPLUS)
  235. {
  236. log_printf("mount -t hfsplus -o rw,defaults,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  237. ret = system_printf("mount -t hfsplus -o rw,defaults,uid=1000,gid=1000 /dev/%s %s", mount->dev, tmp);
  238. }
  239. if(mount->fs == NTFS)
  240. {
  241. log_printf("ntfs-3g /dev/%s %s -o force", mount->dev, tmp);
  242. ret = system_printf("ntfs-3g /dev/%s %s -o force", mount->dev, tmp);
  243. }
  244. exit(WEXITSTATUS(ret));
  245. }
  246. pid = waitpid(pid, &ret, 0);
  247. ret = WEXITSTATUS(ret);
  248. log_printf("----------> mount ret = %d\n", ret);
  249. if(ret && (ret != 0xff))
  250. return -1;
  251. if(mount_wait_for_disc(mount->dev) == 0)
  252. {
  253. mount->mounted = 1;
  254. mount_dump_uci_state();
  255. } else return -1;
  256. return 0;
  257. }
  258. int mount_remove(char *path, char *dev)
  259. {
  260. struct mount *mount;
  261. char tmp[256];
  262. int ret;
  263. snprintf(tmp, 256, "%s%s", path, dev);
  264. log_printf("%s has expired... unmounting\n", tmp);
  265. ret = system_printf("/bin/umount %s", tmp);
  266. if(ret != 0)
  267. return 0;
  268. rmdir(tmp);
  269. mount = mount_find(0, dev);
  270. if(mount)
  271. mount->mounted = 0;
  272. log_printf("finished unmounting\n");
  273. mount_dump_uci_state();
  274. return 0;
  275. }
  276. static int dir_sort(const struct dirent **a, const struct dirent **b)
  277. {
  278. return 0;
  279. }
  280. static int dir_filter(const struct dirent *a)
  281. {
  282. if(strstr(a->d_name, ":"))
  283. return 1;
  284. return 0;
  285. }
  286. static char* mount_get_serial(char *dev)
  287. {
  288. static char tmp[64];
  289. static char tmp2[64];
  290. int disc;
  291. static struct hd_driveid hd;
  292. int i;
  293. static char *serial;
  294. snprintf(tmp, 64, "/dev/%s", dev);
  295. disc = open(tmp, O_RDONLY);
  296. if(!disc)
  297. {
  298. log_printf("Trying to open unknown disc\n");
  299. return 0;
  300. }
  301. i = ioctl(disc, HDIO_GET_IDENTITY, &hd);
  302. close(disc);
  303. if(!i)
  304. serial = (char*)hd.serial_no;
  305. /* if we failed, it probably a usb storage device */
  306. /* there must be a better way for this */
  307. if(i)
  308. {
  309. struct dirent **namelist;
  310. int n = scandir("/sys/bus/scsi/devices/", &namelist, dir_filter, dir_sort);
  311. if(n > 0)
  312. {
  313. while(n--)
  314. {
  315. char *t = strstr(namelist[n]->d_name, ":");
  316. if(t)
  317. {
  318. int id;
  319. struct stat buf;
  320. char tmp3[64];
  321. int ret;
  322. *t = 0;
  323. id = atoi(namelist[n]->d_name);
  324. *t = ':';
  325. sprintf(tmp3, "/sys/bus/scsi/devices/%s/block:%s/", namelist[n]->d_name, dev);
  326. ret = stat(tmp3, &buf);
  327. if(ret)
  328. {
  329. sprintf(tmp3, "/sys/bus/scsi/devices/%s/block/%s/", namelist[n]->d_name, dev);
  330. ret = stat(tmp3, &buf);
  331. }
  332. if(!ret)
  333. {
  334. FILE *fp;
  335. snprintf(tmp2, 64, "/proc/scsi/usb-storage/%d", id);
  336. fp = fopen(tmp2, "r");
  337. if(fp)
  338. {
  339. while(fgets(tmp2, 64, fp) > 0)
  340. {
  341. serial = strstr(tmp2, "Serial Number:");
  342. if(serial)
  343. {
  344. serial += strlen("Serial Number: ");
  345. serial[strlen(serial) - 1] = '\0';
  346. i = 0;
  347. break;
  348. }
  349. }
  350. fclose(fp);
  351. }
  352. }
  353. }
  354. free(namelist[n]);
  355. }
  356. free(namelist);
  357. }
  358. }
  359. if(i)
  360. {
  361. log_printf("could not find a serial number for the device %s\n", dev);
  362. } else {
  363. /* serial string id is cheap, but makes the discs anonymous */
  364. unsigned char uniq[6];
  365. unsigned int *u = (unsigned int*) uniq;
  366. int l = strlen(serial);
  367. int i;
  368. static char disc_id[13];
  369. memset(disc_id, 0, 13);
  370. memset(uniq, 0, 6);
  371. for(i = 0; i < l; i++)
  372. {
  373. uniq[i%6] += serial[i];
  374. }
  375. sprintf(disc_id, "%08X%02X%02X", *u, uniq[4], uniq[5]);
  376. //log_printf("Serial number - %s %s\n", serial, disc_id);
  377. return disc_id;
  378. }
  379. return 0;
  380. }
  381. static void mount_dev_add(char *dev)
  382. {
  383. struct mount *mount = mount_find(0, dev);
  384. if(!mount)
  385. {
  386. char node[64];
  387. char name[64];
  388. int ignore = 0;
  389. char *s;
  390. char tmp[64];
  391. char tmp2[64];
  392. char *p;
  393. struct uci_context *ctx;
  394. char vendor[64];
  395. char model[64];
  396. char rev[64];
  397. char size[64];
  398. char sector_size[64];
  399. FILE *fp;
  400. strcpy(name, dev);
  401. name[3] = '\0';
  402. s = mount_get_serial(name);
  403. if(!s)
  404. return;
  405. snprintf(tmp, 64, "part%s", &dev[3]);
  406. snprintf(node, 64, "Disc-%s", &dev[2]);
  407. if(node[5] >= 'a' && node[5] <= 'z')
  408. {
  409. node[5] -= 'a';
  410. node[5] += 'A';
  411. }
  412. ctx = ucix_init("mountd");
  413. p = ucix_get_option(ctx, "mountd", s, tmp);
  414. ucix_cleanup(ctx);
  415. if(p)
  416. {
  417. if(strlen(p) == 1)
  418. {
  419. if(*p == '0')
  420. ignore = 1;
  421. } else {
  422. snprintf(node, 64, "%s", p);
  423. }
  424. }
  425. strcpy(name, dev);
  426. name[3] = '\0';
  427. snprintf(tmp, 64, "/sys/class/block/%s/device/model", name);
  428. fp = fopen(tmp, "r");
  429. if(!fp)
  430. {
  431. snprintf(tmp, 64, "/sys/block/%s/device/model", name);
  432. fp = fopen(tmp, "r");
  433. }
  434. if(!fp)
  435. snprintf(model, 64, "unknown");
  436. else {
  437. fgets(model, 64, fp);
  438. model[strlen(model) - 1] = '\0';;
  439. fclose(fp);
  440. }
  441. snprintf(tmp, 64, "/sys/class/block/%s/device/vendor", name);
  442. fp = fopen(tmp, "r");
  443. if(!fp)
  444. {
  445. snprintf(tmp, 64, "/sys/block/%s/device/vendor", name);
  446. fp = fopen(tmp, "r");
  447. }
  448. if(!fp)
  449. snprintf(vendor, 64, "unknown");
  450. else {
  451. fgets(vendor, 64, fp);
  452. vendor[strlen(vendor) - 1] = '\0';
  453. fclose(fp);
  454. }
  455. snprintf(tmp, 64, "/sys/class/block/%s/device/rev", name);
  456. fp = fopen(tmp, "r");
  457. if(!fp)
  458. {
  459. snprintf(tmp, 64, "/sys/block/%s/device/rev", name);
  460. fp = fopen(tmp, "r");
  461. }
  462. if(!fp)
  463. snprintf(rev, 64, "unknown");
  464. else {
  465. fgets(rev, 64, fp);
  466. rev[strlen(rev) - 1] = '\0';
  467. fclose(fp);
  468. }
  469. snprintf(tmp, 64, "/sys/class/block/%s/size", dev);
  470. fp = fopen(tmp, "r");
  471. if(!fp)
  472. {
  473. snprintf(tmp, 64, "/sys/block/%s/%s/size", name, dev);
  474. fp = fopen(tmp, "r");
  475. }
  476. if(!fp)
  477. snprintf(size, 64, "unknown");
  478. else {
  479. fgets(size, 64, fp);
  480. size[strlen(size) - 1] = '\0';
  481. fclose(fp);
  482. }
  483. strcpy(tmp2, dev);
  484. tmp2[3] = '\0';
  485. snprintf(tmp, 64, "/sys/block/%s/queue/hw_sector_size", tmp2);
  486. fp = fopen(tmp, "r");
  487. if(!fp)
  488. snprintf(sector_size, 64, "unknown");
  489. else {
  490. fgets(sector_size, 64, fp);
  491. sector_size[strlen(sector_size) - 1] = '\0';
  492. fclose(fp);
  493. }
  494. snprintf(tmp, 64, "/dev/%s", dev);
  495. mount_add_list(node, dev, s, vendor, model, rev, ignore, size, sector_size, detect_fs(tmp));
  496. mount_dump_uci_state();
  497. }
  498. }
  499. static void mount_dev_del(char *dev)
  500. {
  501. struct mount *mount = mount_find(0, dev);
  502. char tmp[256];
  503. if(mount)
  504. {
  505. if(mount->mounted)
  506. {
  507. snprintf(tmp, 256, "%s%s", "/tmp/run/mountd/", mount->name);
  508. log_printf("%s has dissappeared ... unmounting\n", tmp);
  509. snprintf(tmp, 256, "%s%s", "/tmp/run/mountd/", mount->dev);
  510. system_printf("/bin/umount %s", tmp);
  511. rmdir(tmp);
  512. snprintf(tmp, 64, "%s%s", uci_path, mount->name);
  513. unlink(tmp);
  514. mount_dump_uci_state();
  515. }
  516. }
  517. }
  518. void mount_dump_list(void)
  519. {
  520. struct list_head *p;
  521. list_for_each(p, &mounts)
  522. {
  523. struct mount *q = container_of(p, struct mount, list);
  524. log_printf("* %s %s %d\n", q->name, q->dev, q->mounted);
  525. }
  526. }
  527. char* is_mounted(char *block, char *path)
  528. {
  529. int i;
  530. for(i = 0; i < mounted_count; i++)
  531. {
  532. if(block)
  533. if(!strncmp(&mounted[i][0][0], block, strlen(&mounted[i][0][0])))
  534. return &mounted[i][0][0];
  535. if(path)
  536. if(!strncmp(&mounted[i][1][1], &path[1], strlen(&mounted[i][1][0])))
  537. return &mounted[i][0][0];
  538. }
  539. return 0;
  540. }
  541. static void mount_check_mount_list(void)
  542. {
  543. FILE *fp = fopen("/proc/mounts", "r");
  544. char tmp[256];
  545. if(!fp)
  546. {
  547. log_printf("error reading /proc/mounts");
  548. fclose(fp);
  549. return;
  550. }
  551. mounted_count = 0;
  552. while(fgets(tmp, 256, fp) > 0)
  553. {
  554. char *t, *t2;
  555. t = strstr(tmp, " ");
  556. if(t)
  557. {
  558. *t = '\0';
  559. t++;
  560. } else t = tmp;
  561. strncpy(&mounted[mounted_count][0][0], tmp, MAX_MOUNT_NAME);
  562. t2 = strstr(t, " ");
  563. if(t2)
  564. {
  565. *t2 = '\0';
  566. t2++;
  567. } else t2 = t;
  568. strncpy(&mounted[mounted_count][1][0], t, MAX_MOUNT_NAME);
  569. t = strstr(t2, " ");
  570. if(t)
  571. {
  572. *t = '\0';
  573. t++;
  574. } else t = tmp;
  575. strncpy(&mounted[mounted_count][2][0], t2, MAX_MOUNT_NAME);
  576. /* printf("%s %s %s\n",
  577. mounted[mounted_count][0],
  578. mounted[mounted_count][1],
  579. mounted[mounted_count][2]);*/
  580. if(mounted_count < MAX_MOUNTED - 1)
  581. mounted_count++;
  582. else
  583. log_printf("found more than %d mounts \n", MAX_MOUNTED);
  584. }
  585. fclose(fp);
  586. }
  587. /* FIXME: we need more intelligence here */
  588. static int dir_filter2(const struct dirent *a)
  589. {
  590. if(/*strcmp(a->d_name, "sda") &&*/(!strncmp(a->d_name, "sd", 2)))
  591. return 1;
  592. return 0;
  593. }
  594. #define MAX_BLOCK 64
  595. char block[MAX_BLOCK][MAX_BLOCK];
  596. int blk_cnt = 0;
  597. static int check_block(char *b)
  598. {
  599. int i;
  600. for(i = 0; i < blk_cnt; i++)
  601. {
  602. if(!strcmp(block[i], b))
  603. return 1;
  604. }
  605. return 0;
  606. }
  607. static void mount_enum_drives(void)
  608. {
  609. struct dirent **namelist, **namelist2;
  610. int i, n = scandir("/sys/block/", &namelist, dir_filter2, dir_sort);
  611. struct list_head *p;
  612. blk_cnt = 0;
  613. if(n > 0)
  614. {
  615. while(n--)
  616. {
  617. if(blk_cnt < MAX_BLOCK)
  618. {
  619. int m;
  620. char tmp[64];
  621. snprintf(tmp, 64, "/sys/block/%s/", namelist[n]->d_name);
  622. m = scandir(tmp, &namelist2, dir_filter2, dir_sort);
  623. while(m--)
  624. {
  625. strncpy(&block[blk_cnt][0], namelist2[m]->d_name, MAX_BLOCK);
  626. blk_cnt++;
  627. free(namelist2[m]);
  628. }
  629. free(namelist2);
  630. }
  631. free(namelist[n]);
  632. }
  633. free(namelist);
  634. }
  635. p = mounts.next;
  636. while(p != &mounts)
  637. {
  638. struct mount *q = container_of(p, struct mount, list);
  639. char tmp[64];
  640. struct uci_context *ctx;
  641. int del = 0;
  642. char *t;
  643. snprintf(tmp, 64, "part%s", &q->dev[3]);
  644. ctx = ucix_init("mountd");
  645. t = ucix_get_option(ctx, "mountd", q->serial, tmp);
  646. ucix_cleanup(ctx);
  647. if(t && !q->mounted)
  648. {
  649. if(!strcmp(t, "0"))
  650. {
  651. if(!q->ignore)
  652. del = 1;
  653. } else if(!strcmp(t, "1"))
  654. {
  655. if(strncmp(q->name, "Disc-", 5))
  656. del = 1;
  657. } else if(strcmp(q->name, t))
  658. {
  659. del = 1;
  660. }
  661. }
  662. if(!check_block(q->dev)||del)
  663. {
  664. mount_dev_del(q->dev);
  665. p->prev->next = p->next;
  666. p->next->prev = p->prev;
  667. p = p->next;
  668. log_printf("removing %s\n", q->dev);
  669. snprintf(tmp, 64, "%s%s", uci_path, q->name);
  670. unlink(tmp);
  671. system_printf("/etc/mountd/event remove %s %s", q->dev, q->name);
  672. free(q);
  673. mount_dump_uci_state();
  674. system_printf("/etc/fonstated/ReloadSamba");
  675. } else p = p->next;
  676. }
  677. for(i = 0; i < blk_cnt; i++)
  678. mount_dev_add(block[i]);
  679. }
  680. static void mount_check_enum(void)
  681. {
  682. waitpid(-1, 0, WNOHANG);
  683. mount_enum_drives();
  684. }
  685. void mount_init(void)
  686. {
  687. INIT_LIST_HEAD(&mounts);
  688. timer_add(mount_check_mount_list, 2);
  689. timer_add(mount_check_enum, 1);
  690. mount_check_mount_list();
  691. }