int main(int argc, char **argv) { int beforec, afterc, i; char *table, **before, **after; struct rlimit rl; getrlimit(RLIMIT_NOFILE, &rl); for (i = rl.rlim_cur; i > 2; i--) close(i); whoami = ((whoami = strrchr(argv[0], '/')) ? whoami+1 : argv[0]); table = argv[1]; beforec = atoi(argv[2]); before = &argv[4]; afterc = atoi(argv[3]); after = &argv[4 + beforec]; setvbuf(stdout, NULL, _IOLBF, BUFSIZ); strcpy(tbl_buf, table); strcat(tbl_buf, " ("); for (i = 0; i < beforec; i++) { if (i > 0) strcat(tbl_buf, ","); strcat(tbl_buf, before[i]); } strcat(tbl_buf, ")->("); for (i = 0; i < afterc; i++) { if (i > 0) strcat(tbl_buf, ","); strcat(tbl_buf, after[i]); } strcat(tbl_buf, ")"); initialize_sms_error_table(); initialize_krb_error_table(); if (!strcmp(table, "users")) do_user(before, beforec, after, afterc); else if (!strcmp(table, "list")) do_list(before, beforec, after, afterc); else if (!strcmp(table, "imembers")) do_member(before, beforec, after, afterc); else if (!strcmp(table, "filesys")) do_filesys(before, beforec, after, afterc); else if (!strcmp(table, "quota")) do_quota(before, beforec, after, afterc); exit(0); }
int restore_line(const char *filename,uint64_t lv,char *line) { char *ptr; uint32_t ts; int status; char* errormsgs[]={ ERROR_STRINGS }; status = ERROR_MISMATCH; ptr = line; EAT(ptr,filename,lv,':'); EAT(ptr,filename,lv,' '); GETU32(ts,ptr); EAT(ptr,filename,lv,'|'); switch (*ptr) { case 'A': if (strncmp(ptr,"ACCESS",6)==0) { status = do_access(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"ATTR",4)==0) { status = do_attr(filename,lv,ts,ptr+4); } else if (strncmp(ptr,"APPEND",6)==0) { status = do_append(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"ACQUIRE",7)==0) { status = do_acquire(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"AQUIRE",6)==0) { status = do_acquire(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'C': if (strncmp(ptr,"CREATE",6)==0) { status = do_create(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"CUSTOMER",8)==0) { // deprecated status = do_session(filename,lv,ts,ptr+8); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'E': if (strncmp(ptr,"EMPTYTRASH",10)==0) { status = do_emptytrash(filename,lv,ts,ptr+10); } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) { status = do_emptyreserved(filename,lv,ts,ptr+13); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'F': if (strncmp(ptr,"FREEINODES",10)==0) { status = do_freeinodes(filename,lv,ts,ptr+10); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'I': if (strncmp(ptr,"INCVERSION",10)==0) { status = do_incversion(filename,lv,ts,ptr+10); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'L': if (strncmp(ptr,"LENGTH",6)==0) { status = do_length(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"LINK",4)==0) { status = do_link(filename,lv,ts,ptr+4); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'M': if (strncmp(ptr,"MOVE",4)==0) { status = do_move(filename,lv,ts,ptr+4); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'P': if (strncmp(ptr,"PURGE",5)==0) { status = do_purge(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'Q': if (strncmp(ptr,"QUOTA",5)==0) { status = do_quota(filename,lv,ts,ptr+5); } break; case 'R': if (strncmp(ptr,"RELEASE",7)==0) { status = do_release(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"REPAIR",6)==0) { status = do_repair(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'S': if (strncmp(ptr,"SETEATTR",8)==0) { status = do_seteattr(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SETGOAL",7)==0) { status = do_setgoal(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SETPATH",7)==0) { status = do_setpath(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SETTRASHTIME",12)==0) { status = do_settrashtime(filename,lv,ts,ptr+12); } else if (strncmp(ptr,"SETXATTR",8)==0) { status = do_setxattr(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SNAPSHOT",8)==0) { status = do_snapshot(filename,lv,ts,ptr+8); } else if (strncmp(ptr,"SYMLINK",7)==0) { status = do_symlink(filename,lv,ts,ptr+7); } else if (strncmp(ptr,"SESSION",7)==0) { status = do_session(filename,lv,ts,ptr+7); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'T': if (strncmp(ptr,"TRUNC",5)==0) { status = do_trunc(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'U': if (strncmp(ptr,"UNLINK",6)==0) { status = do_unlink(filename,lv,ts,ptr+6); } else if (strncmp(ptr,"UNDEL",5)==0) { status = do_undel(filename,lv,ts,ptr+5); } else if (strncmp(ptr,"UNLOCK",6)==0) { status = do_unlock(filename,lv,ts,ptr+6); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; case 'W': if (strncmp(ptr,"WRITE",5)==0) { status = do_write(filename,lv,ts,ptr+5); } else { printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } break; default: printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr); } if (status>STATUS_OK) { printf("%s:%"PRIu64": error: %d (%s)\n",filename,lv,status,errormsgs[status]); } return status; }
/* If tmp_mount_point is non-null, mount the filesystem there. This is for the * tmp mount we do to check the user password * If multiple fstab entries are to be mounted on "n_name", it will try to mount each one * in turn, and stop on 1st success, or no more match. */ int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device, char *tmp_mount_point) { int i = 0; int ret = FS_MGR_DOMNT_FAILED; int mount_errors = 0; int first_mount_errno = 0; char *m; if (!fstab) { return ret; } for (i = 0; i < fstab->num_entries; i++) { if (!fs_match(fstab->recs[i].mount_point, n_name)) { continue; } /* We found our match */ /* If this swap or a raw partition, report an error */ if (!strcmp(fstab->recs[i].fs_type, "swap") || !strcmp(fstab->recs[i].fs_type, "emmc") || !strcmp(fstab->recs[i].fs_type, "mtd")) { ERROR("Cannot mount filesystem of type %s on %s\n", fstab->recs[i].fs_type, n_blk_device); goto out; } /* First check the filesystem if requested */ if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { wait_for_file(n_blk_device, WAIT_TIMEOUT); } int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { check_fs(n_blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point); } if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); } if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) { int rc = fs_mgr_setup_verity(&fstab->recs[i]); if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) { INFO("Verity disabled"); } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) { ERROR("Could not set up verified partition, skipping!\n"); continue; } } /* Now mount it where requested */ if (tmp_mount_point) { m = tmp_mount_point; } else { m = fstab->recs[i].mount_point; } if (__mount(n_blk_device, m, &fstab->recs[i])) { if (!first_mount_errno) first_mount_errno = errno; mount_errors++; continue; } else { ret = 0; goto out; } } if (mount_errors) { ERROR("Cannot mount filesystem on %s at %s. error: %s\n", n_blk_device, m, strerror(first_mount_errno)); if (first_mount_errno == EBUSY) { ret = FS_MGR_DOMNT_BUSY; } else { ret = FS_MGR_DOMNT_FAILED; } } else { /* We didn't find a match, say so and return an error */ ERROR("Cannot find mount point %s in fstab\n", fstab->recs[i].mount_point); } out: return ret; }
/* * Tries to mount any of the consecutive fstab entries that match * the mountpoint of the one given by fstab->recs[start_idx]. * * end_idx: On return, will be the last rec that was looked at. * attempted_idx: On return, will indicate which fstab rec * succeeded. In case of failure, it will be the start_idx. * Returns * -1 on failure with errno set to match the 1st mount failure. * 0 on success. */ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_idx, int *attempted_idx) { int i; int mount_errno = 0; int mounted = 0; if (!end_idx || !attempted_idx || start_idx >= fstab->num_entries) { errno = EINVAL; if (end_idx) *end_idx = start_idx; if (attempted_idx) *attempted_idx = start_idx; return -1; } /* Hunt down an fstab entry for the same mount point that might succeed */ for (i = start_idx; /* We required that fstab entries for the same mountpoint be consecutive */ i < fstab->num_entries && !strcmp(fstab->recs[start_idx].mount_point, fstab->recs[i].mount_point); i++) { /* * Don't try to mount/encrypt the same mount point again. * Deal with alternate entries for the same point which are required to be all following * each other. */ if (mounted) { ERROR("%s(): skipping fstab dup mountpoint=%s rec[%d].fs_type=%s already mounted as %s.\n", __func__, fstab->recs[i].mount_point, i, fstab->recs[i].fs_type, fstab->recs[*attempted_idx].fs_type); continue; } int force_check = do_quota(fstab->recs[i].blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) { check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point); } if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) { do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type, &fstab->recs[i]); } if (!__mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, &fstab->recs[i])) { *attempted_idx = i; mounted = 1; if (i != start_idx) { ERROR("%s(): Mounted %s on %s with fs_type=%s instead of %s\n", __func__, fstab->recs[i].blk_device, fstab->recs[i].mount_point, fstab->recs[i].fs_type, fstab->recs[start_idx].fs_type); } } else { /* back up errno for crypto decisions */ mount_errno = errno; } } /* Adjust i for the case where it was still withing the recs[] */ if (i < fstab->num_entries) --i; *end_idx = i; if (!mounted) { *attempted_idx = start_idx; errno = mount_errno; return -1; } return 0; }