static const char * swap_on_off_geli( const char *name, char *mntops, int doingall ) { struct stat sb; char *dname, *args; int error; error = stat( name, &sb ); if ( which_prog == SWAPON ) do { if ( error == 0 ) break; args = swap_on_geli_args( mntops ); if ( args == NULL ) return ( NULL ); dname = swap_basename( name ); if ( dname == NULL ) { free( args ); return ( NULL ); } error = run_cmd( NULL, "%s onetime%s %s", _PATH_GELI, args, dname ); free( dname ); free( args ); if ( error ) { if ( qflag == 0 ) warnx( "%s: Invalid parameters", name ); return ( NULL ); } } while ( 0 ); return ( swap_on_off_sfile( name, doingall ) ); }
static const char * swap_on_off(const char *name, int doingall, char *mntops) { char base[PATH_MAX]; /* Swap on vnode-backed md(4) device. */ if (mntops != NULL && (fnmatch(_PATH_DEV MD_NAME "[0-9]*", name, 0) == 0 || fnmatch(MD_NAME "[0-9]*", name, 0) == 0 || strncmp(_PATH_DEV MD_NAME, name, sizeof(_PATH_DEV) + sizeof(MD_NAME)) == 0 || strncmp(MD_NAME, name, sizeof(MD_NAME)) == 0)) return (swap_on_off_md(name, mntops, doingall)); basename_r(name, base); /* Swap on encrypted device by GEOM_BDE. */ if (fnmatch("*.bde", base, 0) == 0) return (swap_on_off_gbde(name, doingall)); /* Swap on encrypted device by GEOM_ELI. */ if (fnmatch("*.eli", base, 0) == 0) return (swap_on_off_geli(name, mntops, doingall)); /* Swap on special file. */ return (swap_on_off_sfile(name, doingall)); }
static const char * swap_on_off_gbde(const char *name, int doingall) { const char *ret; char pass[64 * 2 + 1]; unsigned char bpass[64]; char *dname; int i, error; dname = swap_basename(name); if (dname == NULL) return (NULL); if (which_prog == SWAPON) { arc4random_buf(bpass, sizeof(bpass)); for (i = 0; i < (int)sizeof(bpass); i++) sprintf(&pass[2 * i], "%02x", bpass[i]); pass[sizeof(pass) - 1] = '\0'; error = run_cmd(NULL, "%s init %s -P %s", _PATH_GBDE, dname, pass); if (error) { /* bde device found. Ignore it. */ free(dname); if (qflag == 0) warnx("%s: Device already in use", name); return (NULL); } error = run_cmd(NULL, "%s attach %s -p %s", _PATH_GBDE, dname, pass); free(dname); if (error) { warnx("gbde (attach) error: %s", name); return (NULL); } } ret = swap_on_off_sfile(name, doingall); if (which_prog == SWAPOFF) { error = run_cmd(NULL, "%s detach %s", _PATH_GBDE, dname); free(dname); if (error) { /* bde device not found. Ignore it. */ if (qflag == 0) warnx("%s: Device not found", name); return (NULL); } } return (ret); }
static const char * swap_on_off( const char *name, int doingall, char *mntops ) { char base[PATH_MAX]; if ( mntops != NULL && (fnmatch(_PATH_DEV MD_NAME "[0-9]*", name, 0) == 0 || fnmatch(MD_NAME "[0-9]*", name, 0) == 0 || strncmp(_PATH_DEV MD_NAME, name, sizeof(_PATH_DEV) + sizeof(MD_NAME)) == 0 || strncmp(MD_NAME, name, sizeof(MD_NAME)) == 0) ) return ( swap_on_off_md( name, mntops, doingall ) ); basename_r( name, base ); if ( fnmatch( "*.bde", base, 0 ) == 0 ) return ( swap_on_off_gbde( name, doingall ) ); if ( fnmatch( "*.eli", base, 0 ) == 0 ) return ( swap_on_off_geli( name, mntops, doingall ) ); return ( swap_on_off_sfile( name, doingall ) ); }
static const char * swap_on_off_md( const char *name, char *mntops, int doingall ) { FILE *sfd; int fd, mdunit, error; const char *ret; static char mdpath[PATH_MAX], linebuf[PATH_MAX]; char *p, *vnodefile; size_t linelen; u_long ul; fd = -1; sfd = NULL; if ( strlen( name ) == ( sizeof(MD_NAME) - 1 ) ) mdunit = -1; else { errno = 0; ul = strtoul( name + 2, &p, 10 ); if ( errno == 0 ) { if ( *p != '\0' || ul > INT_MAX ) errno = EINVAL; } if ( errno ) { warn( "Bad device unit: %s", name ); return ( NULL ); } mdunit = (int) ul; } vnodefile = NULL; if ( ( p = strstr( mntops, "file=" ) ) != NULL ) { vnodefile = strdup( p + sizeof( "file=" ) - 1 ); p = strchr( vnodefile, ',' ); if ( p != NULL ) *p = '\0'; } if ( vnodefile == NULL ) { warnx( "file option not found for %s", name ); return ( NULL ); } if ( which_prog == SWAPON ) { if ( mdunit == -1 ) { error = run_cmd( &fd, "%s -l -n -f %s", _PATH_MDCONFIG, vnodefile ); if ( error == 0 ) { close( fd ); if ( !qflag ) warnx( "%s: Device already in use", vnodefile ); free( vnodefile ); return ( NULL ); } error = run_cmd( &fd, "%s -a -t vnode -n -f %s", _PATH_MDCONFIG, vnodefile ); if ( error ) { warnx( "mdconfig (attach) error: file=%s", vnodefile ); free( vnodefile ); return ( NULL ); } sfd = fdopen( fd, "r" ); if ( sfd == NULL ) { warn( "mdconfig (attach) fdopen error" ); ret = NULL; goto err; } p = fgetln( sfd, &linelen ); if ( p == NULL && ( linelen < 2 || linelen > sizeof( linebuf ) ) ) { warn( "mdconfig (attach) unexpected output" ); ret = NULL; goto err; } strncpy( linebuf, p, linelen ); linebuf[linelen - 1] = '\0'; errno = 0; ul = strtoul( linebuf, &p, 10 ); if ( errno == 0 ) { if ( *p != '\0' || ul > INT_MAX ) errno = EINVAL; } if ( errno ) { warn( "mdconfig (attach) unexpected output: %s", linebuf ); ret = NULL; goto err; } mdunit = (int) ul; } else { error = run_cmd( &fd, "%s -l -n -f %s -u %d", _PATH_MDCONFIG, vnodefile, mdunit ); if ( error == 0 ) { close( fd ); if ( qflag == 0 ) warnx( "md%d on %s: Device already " "in use", mdunit, vnodefile ); free( vnodefile ); return ( NULL ); } error = run_cmd( NULL, "%s -a -t vnode -u %d -f %s", _PATH_MDCONFIG, mdunit, vnodefile ); if ( error ) { warnx( "mdconfig (attach) error: " "md%d on file=%s", mdunit, vnodefile ); free( vnodefile ); return ( NULL ); } } } else { if ( mdunit == -1 ) { error = run_cmd( &fd, "%s -l -n -f %s", _PATH_MDCONFIG, vnodefile ); if ( error ) { close( fd ); if ( !qflag ) warnx( "md on %s: Device not found", vnodefile ); free( vnodefile ); return ( NULL ); } sfd = fdopen( fd, "r" ); if ( sfd == NULL ) { warn( "mdconfig (list) fdopen error" ); ret = NULL; goto err; } p = fgetln( sfd, &linelen ); if ( p == NULL && ( linelen < 2 || linelen > sizeof( linebuf ) - 1 ) ) { warn( "mdconfig (list) unexpected output" ); ret = NULL; goto err; } strncpy( linebuf, p, linelen ); linebuf[linelen - 1] = '\0'; p = strchr( linebuf, ' ' ); if ( p != NULL ) *p = '\0'; errno = 0; ul = strtoul( linebuf, &p, 10 ); if ( errno == 0 ) { if ( *p != '\0' || ul > INT_MAX ) errno = EINVAL; } if ( errno ) { warn( "mdconfig (list) unexpected output: %s", linebuf ); ret = NULL; goto err; } mdunit = (int) ul; } else { error = run_cmd( &fd, "%s -l -n -f %s -u %d", _PATH_MDCONFIG, vnodefile, mdunit ); if ( error ) { close( fd ); if ( !qflag ) warnx( "md%d on %s: Device not found", mdunit, vnodefile ); free( vnodefile ); return ( NULL ); } } } snprintf( mdpath, sizeof( mdpath ), "%s%s%d", _PATH_DEV, MD_NAME, mdunit ); mdpath[sizeof( mdpath ) - 1] = '\0'; ret = swap_on_off_sfile( mdpath, doingall ); if ( which_prog == SWAPOFF ) { if ( ret != NULL ) { error = run_cmd( NULL, "%s -d -u %d", _PATH_MDCONFIG, mdunit ); if ( error ) warn( "mdconfig (detach) detach failed: %s%s%d", _PATH_DEV, MD_NAME, mdunit ); } } err: if ( sfd != NULL ) fclose( sfd ); if ( fd != -1 ) close( fd ); free( vnodefile ); return ( ret ); }