int main(int argc, char *argv[]) { int exit_status; if (getpid() == 1 && getppid() == 0) is_init = true; mainloop_init(); printf("Bluetooth periperhal ver %s\n", VERSION); prepare_filesystem(); if (is_init) { uint8_t addr[6]; if (efivars_read("BluetoothStaticAddress", NULL, addr, 6) < 0) { printf("Generating new persistent static address\n"); addr[0] = rand(); addr[1] = rand(); addr[2] = rand(); addr[3] = 0x34; addr[4] = 0x12; addr[5] = 0xc0; efivars_write("BluetoothStaticAddress", EFIVARS_NON_VOLATILE | EFIVARS_BOOTSERVICE_ACCESS | EFIVARS_RUNTIME_ACCESS, addr, 6); } gap_set_static_address(addr); run_shell(); } log_open(); gap_start(); if (is_init) attach_start(); exit_status = mainloop_run_with_signal(signal_callback, NULL); if (is_init) attach_stop(); gap_stop(); log_close(); return exit_status; }
static bool prepare_block_device(void* ctx, const char* path) { (void) ctx; struct harddisk* hd = harddisk_openat(AT_FDCWD, path, O_RDONLY); if ( !hd ) { int true_errno = errno; struct stat st; if ( lstat(path, &st) == 0 && !S_ISBLK(st.st_mode) ) return true; errno = true_errno; fatal("%s: %m", path); } if ( !harddisk_inspect_blockdevice(hd) ) { if ( errno == ENOTBLK ) return true; if ( errno == EINVAL ) return warning("%s: %m", path), true; fatal("%s: %m", path); } if ( hds_used == hds_length ) { // TODO: Potential overflow. size_t new_length = hds_length ? 2 * hds_length : 16; struct harddisk** new_hds = (struct harddisk**) reallocarray(hds, new_length, sizeof(struct harddisk*)); if ( !new_hds ) fatal("realloc: %m"); hds = new_hds; hds_length = new_length; } hds[hds_used++] = hd; struct blockdevice* bdev = &hd->bdev; enum partition_error parterr = blockdevice_get_partition_table(&bdev->pt, bdev); if ( parterr == PARTITION_ERROR_ABSENT || parterr == PARTITION_ERROR_UNRECOGNIZED ) { prepare_filesystem(path, bdev); return true; } else if ( parterr == PARTITION_ERROR_ERRNO ) { if ( errno == EIO || errno == EINVAL ) warning("%s: %s", path, partition_error_string(parterr)); else fatal("%s: %s", path, partition_error_string(parterr)); return true; } else if ( parterr != PARTITION_ERROR_NONE ) { warning("%s: %s", path, partition_error_string(parterr)); return true; } for ( size_t i = 0; i < bdev->pt->partitions_count; i++ ) { struct partition* p = bdev->pt->partitions[i]; assert(p->path); struct stat st; if ( stat(p->path, &st) == 0 ) { // TODO: Check the existing partition has the right offset and // length, but definitely do not recreate it if it already // exists properly. } else if ( errno == ENOENT ) { int mountfd = open(p->path, O_RDONLY | O_CREAT | O_EXCL); if ( mountfd < 0 ) fatal("%s:˙%m", p->path); int partfd = mkpartition(hd->fd, p->start, p->length); if ( partfd < 0 ) fatal("mkpartition: %s:˙%m", p->path); if ( fsm_fsbind(partfd, mountfd, 0) < 0 ) fatal("fsbind: %s:˙%m", p->path); close(partfd); close(mountfd); } else { fatal("stat: %s: %m", p->path); } prepare_filesystem(p->path, &p->bdev); } return true; }