int ensure_path_mounted(const char* path) { const Volume* volume = get_volume_for_path(path); if(volume == NULL) { ui_print("RECOVERY::ensure_path_mounted: Unable to locate a volume suitable for path %s\n", path); return -1; } return mount_volume(volume, NULL); // Mount the volume if necessary }
static int submenu_restoreonevolume(const Volume* volume) { char** headers = NULL; // UI menu headers const Volume* sdvolume; // SDCARD volume int sdmounted; // Flag if SDCARD was mounted char filter[256]; // Directory browse filter string char imgfile[256]; // Selected image file to restore int nav; // Menu navigation code int result; // Result from function call // Allocate a standard header headers = alloc_standard_header(SUBHEADER_RESTOREVOLUMES); if(headers == NULL) { LOGE("submenu_restoreonevolume: Cannot allocate menu headers"); return NAVIGATE_ERROR; } // Grab a reference to the SDCARD volume sdvolume = get_volume("SDCARD"); if(sdvolume == NULL) { LOGE("submenu_restoreonevolume: Cannot locate SDCARD volume entry in fstab"); return NAVIGATE_ERROR; } // The SDCARD volume has to be mounted before we can browse it (obviously) result = mount_volume(sdvolume, &sdmounted); if(result != 0) { LOGE("submenu_restoreonevolume: Cannot mount SDCARD volume"); return NAVIGATE_ERROR; } // Generate the directory browse filter string. Backup files can have a number of different // extensions, but if they were created by this recovery they will have the volume name in // ALL CAPS as the base file name snprintf(filter, 256, "%s*.*", volume->name); // Invoke the directory browser against the root of the SDCARD ... nav = navigate_menu_browse(headers, sdvolume->mount_point, filter, imgfile, 256); if(nav == NAVIGATE_SELECT) nav = submenu_restoreonevolume_confirm(volume, imgfile); // Unmount the SDCARD volume if it was mounted by this function if(sdmounted) unmount_volume(sdvolume, NULL); free_menu_list(headers); // Release the string array return nav; // Return navigation code }
int zuluCryptMountVolume( const char * path,const char * m_point,unsigned long mount_opts,const char * fs_opts,uid_t uid ) { int h ; string_t opts = StringVoid ; string_t fs = StringVoid ; string_t loop = StringVoid ; int fd = -1 ; m_struct mst ; mst.device = path ; mst.m_point = m_point ; mst.uid = uid ; mst.m_flags = mount_opts ; /* * zuluCryptGetFileSystemFromDevice() is defined in this source file */ fs = zuluCryptGetFileSystemFromDevice( path ) ; if( fs == StringVoid ){ /* * failed to read file system,probably because the volume does have any or * a plain volume was opened with a wrong key */ return zuluExit( 4,fd,opts,fs,loop ) ; } if( StringStartsWith( fs,"crypto" ) ){ /* * we cant mount an encrypted volume, exiting */ return zuluExit( 4,fd,opts,fs,loop ) ; } /* * zuluCryptMountHasNotAllowedFileSystemOptions() is defined in ./mount_fs_options.c */ if( zuluCryptMountHasNotAllowedFileSystemOptions( uid,fs_opts,fs ) ){ return zuluExit( -1,fd,opts,fs,loop ) ; } mst.fs_flags = fs_opts ; mst.fs = StringContent( fs ) ; opts = set_mount_options( &mst ) ; if( StringPrefixNotEqual( path,"/dev/" ) ){ /* * zuluCryptAttachLoopDeviceToFile() is defined in ./create_loop_device.c */ if( zuluCryptAttachLoopDeviceToFile( mst.device,O_RDWR,&fd,&loop ) ){ mst.device = StringContent( loop ) ; }else{ return zuluExit( -1,fd,opts,fs,loop ) ; } } if( zuluCryptFileSystemIsFUSEbased( path ) ){ /* * These file systems dont see to work with mount() command for some reason. * Them being FUSE based could be a reason. */ switch( mount_FUSEfs( &mst ) ){ case 0 : return zuluExit( 0,fd,opts,fs,loop ) ; case 16 : return zuluExit( 12,fd,opts,fs,loop ) ; default : return zuluExit( 1,fd,opts,fs,loop ) ; } }else{ h = mount_volume( &mst ) ; } return zuluExit( h,fd,opts,fs,loop ) ; }
static int process_mount(struct fuse_client * c) { struct afp_server_mount_request * req; struct afp_server * s=NULL; struct afp_volume * volume; struct afp_connection_request conn_req; int ret; struct stat lstat; if ((c->incoming_size-1) < sizeof(struct afp_server_mount_request)) goto error; req=(void *) c->incoming_string+1; /* Todo should check the existance and perms of the mount point */ if ((ret=access(req->mountpoint,X_OK))!=0) { log_for_client((void *)c,AFPFSD,LOG_DEBUG, "Incorrect permissions on mountpoint %s: %s\n", req->mountpoint, strerror(errno)); goto error; } if (stat(FUSE_DEVICE,&lstat)) { printf("Could not find %s\n",FUSE_DEVICE); goto error; } if (access(FUSE_DEVICE,R_OK | W_OK )!=0) { log_for_client((void *)c, AFPFSD,LOG_NOTICE, "Incorrect permissions on %s, mode of device" " is %o, uid/gid is %d/%d. But your effective " "uid/gid is %d/%d\n", FUSE_DEVICE,lstat.st_mode, lstat.st_uid, lstat.st_gid, geteuid(),getegid()); goto error; } log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Mounting %s from %s on %s\n", (char *) req->url.servername, (char *) req->url.volumename,req->mountpoint); if ((afp_default_connection_request(&conn_req,&req->url))==-1) { log_for_client((void *)c,AFPFSD,LOG_ERR, "Unknown UAM"); return -1; } conn_req.uam_mask=req->uam_mask; if ((s=afp_server_full_connect(c,&conn_req))==NULL) { signal_main_thread(); goto error; } if ((volume=mount_volume(c,s,req->url.volumename, req->url.volpassword))==NULL) { goto error; } volume->extra_flags|=req->volume_options; volume->mapping=req->map; afp_detect_mapping(volume); snprintf(volume->mountpoint,255,req->mountpoint); /* Create the new thread and block until we get an answer back */ { pthread_mutex_t mutex; struct timespec ts; struct timeval tv; int ret; struct start_fuse_thread_arg arg; memset(&arg,0,sizeof(arg)); arg.client = c; arg.volume = volume; arg.wait = 1; arg.changeuid=req->changeuid; gettimeofday(&tv,NULL); ts.tv_sec=tv.tv_sec; ts.tv_sec+=5; ts.tv_nsec=tv.tv_usec*1000; pthread_mutex_init(&mutex,NULL); pthread_cond_init(&volume->startup_condition_cond,NULL); /* Kickoff a thread to see how quickly it exits. If * it exits quickly, we have an error and it failed. */ pthread_create(&volume->thread,NULL,start_fuse_thread,&arg); if (arg.wait) ret = pthread_cond_timedwait( &volume->startup_condition_cond,&mutex,&ts); report_fuse_errors(c); switch (arg.fuse_result) { case 0: if (volume->mounted==AFP_VOLUME_UNMOUNTED) { /* Try and discover why */ switch(arg.fuse_errno) { case ENOENT: log_for_client((void *)c,AFPFSD,LOG_ERR, "Permission denied, maybe a problem with the fuse device or mountpoint?\n"); break; default: log_for_client((void *)c,AFPFSD,LOG_ERR, "Mounting of volume %s of server %s failed.\n", volume->volume_name_printable, volume->server->server_name_printable); } goto error; } else { log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Mounting of volume %s of server %s succeeded.\n", volume->volume_name_printable, volume->server->server_name_printable); return 0; } break; case ETIMEDOUT: log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Still trying.\n"); return 0; break; default: volume->mounted=AFP_VOLUME_UNMOUNTED; log_for_client((void *)c,AFPFSD,LOG_NOTICE, "Unknown error %d, %d.\n", arg.fuse_result,arg.fuse_errno); goto error; } } return AFP_SERVER_RESULT_OKAY; error: if ((s) && (!something_is_mounted(s))) { afp_server_remove(s); } signal_main_thread(); return AFP_SERVER_RESULT_ERROR; }