Monorepo for Aesthetic.Computer aesthetic.computer

fix: DJ mount skips ALL boot USB partitions, adds ntfs/ext4 support

mountMusic() was mounting /dev/sda2 (boot USB data partition) as
music instead of finding the secondary USB stick. Now:
- Scans /proc/mounts to find ALL mounted device bases to skip
- Tries up to 8 partitions per device (was 4)
- Adds ext4 and ntfs3 filesystem support
- Logs each mount attempt for debugging

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+39 -28
+39 -28
fedac/native/src/js-bindings.c
··· 2444 2444 static JSValue js_mount_music(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 2445 2445 (void)this_val; (void)argc; (void)argv; 2446 2446 2447 - // Create mount point 2448 2447 mkdir("/media", 0755); 2449 2448 2450 2449 // Check if already mounted 2451 - struct stat st_media; 2452 - if (stat("/media/.", &st_media) == 0) { 2453 - struct stat st_root; 2454 - if (stat("/.", &st_root) == 0 && st_media.st_dev != st_root.st_dev) { 2455 - return JS_TRUE; // already mounted 2456 - } 2450 + struct stat st_media, st_root; 2451 + if (stat("/media/.", &st_media) == 0 && stat("/.", &st_root) == 0 && 2452 + st_media.st_dev != st_root.st_dev) { 2453 + return JS_TRUE; 2457 2454 } 2458 2455 2459 - // Find the boot device to skip it 2460 - char boot_dev[64] = ""; 2456 + // Find ALL mounted devices to skip (boot USB may have multiple partitions) 2457 + char skip_bases[8][64]; 2458 + int skip_count = 0; 2461 2459 FILE *fp = fopen("/proc/mounts", "r"); 2462 2460 if (fp) { 2463 2461 char line[256]; 2464 - while (fgets(line, sizeof(line), fp)) { 2465 - if (strstr(line, " /mnt ")) { 2466 - sscanf(line, "%63s", boot_dev); 2467 - // Strip partition number to get base device (e.g. /dev/sda1 -> /dev/sda) 2468 - break; 2462 + while (fgets(line, sizeof(line), fp) && skip_count < 8) { 2463 + char mdev[64]; 2464 + if (sscanf(line, "%63s", mdev) == 1 && strncmp(mdev, "/dev/sd", 7) == 0) { 2465 + // Strip partition number to get base 2466 + char base[64]; 2467 + snprintf(base, sizeof(base), "%s", mdev); 2468 + int len = strlen(base); 2469 + while (len > 0 && base[len-1] >= '0' && base[len-1] <= '9') base[--len] = '\0'; 2470 + // Add if not already in skip list 2471 + int found = 0; 2472 + for (int i = 0; i < skip_count; i++) 2473 + if (strcmp(skip_bases[i], base) == 0) { found = 1; break; } 2474 + if (!found) { 2475 + strncpy(skip_bases[skip_count++], base, 63); 2476 + ac_log("[dj] skip boot device: %s\n", base); 2477 + } 2469 2478 } 2470 2479 } 2471 2480 fclose(fp); 2472 2481 } 2473 - char boot_base[64] = ""; 2474 - if (boot_dev[0]) { 2475 - snprintf(boot_base, sizeof(boot_base), "%s", boot_dev); 2476 - // Remove trailing digits 2477 - int len = strlen(boot_base); 2478 - while (len > 0 && boot_base[len-1] >= '0' && boot_base[len-1] <= '9') { 2479 - boot_base[--len] = '\0'; 2480 - } 2481 - } 2482 2482 2483 - // Try mounting secondary USB partitions 2483 + // Try mounting partitions on non-boot USB devices 2484 2484 const char *bases[] = { "/dev/sda", "/dev/sdb", "/dev/sdc", "/dev/sdd", NULL }; 2485 2485 for (int b = 0; bases[b]; b++) { 2486 - // Skip boot device base 2487 - if (boot_base[0] && strcmp(bases[b], boot_base) == 0) continue; 2486 + int skip = 0; 2487 + for (int i = 0; i < skip_count; i++) 2488 + if (strcmp(bases[b], skip_bases[i]) == 0) { skip = 1; break; } 2489 + if (skip) continue; 2488 2490 2489 - for (int p = 1; p <= 4; p++) { 2491 + for (int p = 1; p <= 8; p++) { 2490 2492 char dev[64]; 2491 2493 snprintf(dev, sizeof(dev), "%s%d", bases[b], p); 2492 2494 struct stat ds; 2493 2495 if (stat(dev, &ds) != 0) continue; 2494 2496 2495 - // Try VFAT first, then exFAT 2497 + ac_log("[dj] trying %s...\n", dev); 2496 2498 if (mount(dev, "/media", "vfat", MS_RDONLY, "iocharset=utf8") == 0) { 2497 2499 ac_log("[dj] mounted %s at /media (vfat)\n", dev); 2498 2500 return JS_TRUE; ··· 2501 2503 ac_log("[dj] mounted %s at /media (exfat)\n", dev); 2502 2504 return JS_TRUE; 2503 2505 } 2506 + if (mount(dev, "/media", "ext4", MS_RDONLY, NULL) == 0) { 2507 + ac_log("[dj] mounted %s at /media (ext4)\n", dev); 2508 + return JS_TRUE; 2509 + } 2510 + if (mount(dev, "/media", "ntfs3", MS_RDONLY, NULL) == 0) { 2511 + ac_log("[dj] mounted %s at /media (ntfs)\n", dev); 2512 + return JS_TRUE; 2513 + } 2504 2514 } 2505 2515 } 2516 + ac_log("[dj] no music USB found\n"); 2506 2517 return JS_FALSE; 2507 2518 } 2508 2519