int partition_stat_get(partition_stat_t *stat) { FILE *mnt_file = NULL; struct mntent *mnt = NULL; struct statfs fsbuf; bzero(stat, sizeof(partition_stat_t)); mnt_file = setmntent(MTAB_FILE, "r"); if (NULL == mnt_file) { log_error("setmntext failed."); return 0; } while (NULL != (mnt = getmntent(mnt_file))) { if (stat->count >= MAX_PARTITIOn_COUNT) { log_warn("partition count >= %d.", MAX_PARTITIOn_COUNT); break; } if(strncmp(mnt->mnt_fsname, "/", 1)) { continue; } strncpy(stat->partitions[stat->count].fs_name, mnt->mnt_fsname + 5, MAX_FS_NAME_SIZE - 1); strncpy(stat->partitions[stat->count].mnt_dir, mnt->mnt_dir, MAX_MNT_DIR_SIZE - 1); if (!statfs(mnt->mnt_dir, &fsbuf)) { stat->partitions[stat->count].type = fsbuf.f_type; stat->partitions[stat->count].bsize = fsbuf.f_bsize; stat->partitions[stat->count].blocks = fsbuf.f_blocks; stat->partitions[stat->count].bfree = fsbuf.f_bfree; stat->partitions[stat->count].bavail = fsbuf.f_bavail; stat->partitions[stat->count].status = disk_status(mnt->mnt_dir); } else { log_error("statfs for %s failed, %s.", mnt->mnt_dir); stat->partitions[stat->count].status = PARTITION_STATUS_ERROR; } stat->partitions[stat->count].total_size = (fsbuf.f_bsize/1024) * (fsbuf.f_blocks/1024); stat->partitions[stat->count].nonroot_total_size = (fsbuf.f_bsize/1024) * ((fsbuf.f_blocks - fsbuf.f_bfree + fsbuf.f_bavail)/1024); stat->partitions[stat->count].used_size = (fsbuf.f_bsize/1024) * ((fsbuf.f_blocks - fsbuf.f_bfree)/1024); stat->partitions[stat->count].avail_size = (fsbuf.f_bsize/1024) * (fsbuf.f_bavail/1024); if (stat->partitions[stat->count].nonroot_total_size != 0) { stat->partitions[stat->count].usage = (float)stat->partitions[stat->count].used_size/(float)stat->partitions[stat->count].nonroot_total_size; } else { stat->partitions[stat->count].usage = 0; } stat->nonroot_total_size += stat->partitions[stat->count].nonroot_total_size; stat->total_size += stat->partitions[stat->count].total_size; stat->used_size += stat->partitions[stat->count].used_size; stat->avail_size += stat->partitions[stat->count].avail_size; stat->count++; } stat->usage = (float)stat->used_size/(float)stat->nonroot_total_size; endmntent(mnt_file); return 1; }
int init_ctl_channel(const char *name, int verb) { char buf[PATH_MAX]; struct statfs st; int old_transport = 0; (void) verb; if (0) goto out; /* just to defeat gcc warnings */ /* Before trying to open the control channel, make sure it * isn't already open. */ close_ctl_channel(); #ifdef HAVE_OPENAT if (relay_basedir_fd >= 0) { strncpy(buf, CTL_CHANNEL_NAME, PATH_MAX); control_channel = openat_cloexec(relay_basedir_fd, CTL_CHANNEL_NAME, O_RDWR, 0); dbug(2, "Opened %s (%d)\n", CTL_CHANNEL_NAME, control_channel); /* NB: Extra real-id access check as below */ if (faccessat(relay_basedir_fd, CTL_CHANNEL_NAME, R_OK|W_OK, 0) != 0){ close(control_channel); return -5; } if (control_channel >= 0) goto out; /* It's OK to bypass the [f]access[at] check below, since this would only occur the *second* time staprun tries this gig, or within unprivileged stapio. */ } /* PR14245, NB: we fall through to /sys ... /proc searching, in case the relay_basedir_fd option wasn't given (i.e., for early in staprun), or if errors out for some reason. */ #endif if (statfs("/sys/kernel/debug", &st) == 0 && (int)st.f_type == (int)DEBUGFS_MAGIC) { /* PR14245: allow subsequent operations, and if necessary, staprun->stapio forks, to reuse an fd for directory lookups (even if some parent directories have perms 0700. */ #ifdef HAVE_OPENAT if (! sprintf_chk(buf, "/sys/kernel/debug/systemtap/%s", name)) { relay_basedir_fd = open (buf, O_DIRECTORY | O_RDONLY); /* If this fails, we don't much care; the negative return value will just keep us looking up by name again next time. */ /* NB: we don't plan to close this fd, so that we can pass it across staprun->stapio fork/execs. */ } #endif if (sprintf_chk(buf, "/sys/kernel/debug/systemtap/%s/%s", name, CTL_CHANNEL_NAME)) return -1; } else { old_transport = 1; if (sprintf_chk(buf, "/proc/systemtap/%s/%s", name, CTL_CHANNEL_NAME)) return -2; } control_channel = open_cloexec(buf, O_RDWR, 0); dbug(2, "Opened %s (%d)\n", buf, control_channel); /* NB: Even if open() succeeded with effective-UID permissions, we * need the access() check to make sure real-UID permissions are also * sufficient. When we run under the setuid staprun, effective and * real UID may not be the same. Specifically, we want to prevent * a local stapusr from trying to attach to a different stapusr's module. * * The access() is done *after* open() to avoid any TOCTOU-style race * condition. We believe it's probably safe either way, as the file * we're trying to access connot be modified by a typical user, but * better safe than sorry. */ #ifdef HAVE_OPENAT if (control_channel >= 0 && relay_basedir_fd >= 0) { if (faccessat (relay_basedir_fd, CTL_CHANNEL_NAME, R_OK|W_OK, 0) == 0) goto out; /* else fall through */ } #endif if (control_channel >= 0 && access(buf, R_OK|W_OK) != 0) { close(control_channel); return -5; } out: if (control_channel < 0) { err(_("Cannot attach to module %s control channel; not running?\n"), name); return -3; } return old_transport; }
TEST(sys_vfs, statfs) { struct statfs sb; ASSERT_EQ(0, statfs("/proc", &sb)); Check(sb); }
static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf) { return statfs(rpath(s, path), stbuf); }
int do_move(char *from, char *to) { struct stat sb, fsb; char modep[15]; /* Source path must exist (symlink is OK). */ if (lstat(from, &fsb)) { warn("%s", from); return (1); } /* * (1) If the destination path exists, the -f option is not specified * and either of the following conditions are true: * * (a) The permissions of the destination path do not permit * writing and the standard input is a terminal. * (b) The -i option is specified. * * the mv utility shall write a prompt to standard error and * read a line from standard input. If the response is not * affirmative, mv shall do nothing more with the current * source file... */ if (!fflg && !access(to, F_OK)) { int ask = 1; int ch, first; if (iflg && !access(from, F_OK)) { (void)fprintf(stderr, "overwrite %s? ", to); } else if (stdin_ok && access(to, W_OK) && !stat(to, &sb)) { strmode(sb.st_mode, modep); (void)fprintf(stderr, "override %s%s%s/%s for %s? ", modep + 1, modep[9] == ' ' ? "" : " ", user_from_uid(sb.st_uid, 0), group_from_gid(sb.st_gid, 0), to); } else ask = 0; if (ask) { first = ch = getchar(); while (ch != '\n' && ch != EOF) ch = getchar(); if (first != 'y' && first != 'Y') return (0); } } /* * (2) If rename() succeeds, mv shall do nothing more with the * current source file. If it fails for any other reason than * EXDEV, mv shall write a diagnostic message to the standard * error and do nothing more with the current source file. * * (3) If the destination path exists, and it is a file of type * directory and source_file is not a file of type directory, * or it is a file not of type directory, and source file is * a file of type directory, mv shall write a diagnostic * message to standard error, and do nothing more with the * current source file... */ if (!rename(from, to)) return (0); if (errno != EXDEV) { warn("rename %s to %s", from, to); return (1); } /* Disallow moving a mount point. */ if (S_ISDIR(fsb.st_mode)) { struct statfs sfs; char path[MAXPATHLEN]; if (realpath(from, path) == NULL) { warnx("cannot resolve %s", from); return (1); } if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname)) { warnx("cannot rename a mount point"); return (1); } } /* * (4) If the destination path exists, mv shall attempt to remove it. * If this fails for any reason, mv shall write a diagnostic * message to the standard error and do nothing more with the * current source file... */ if (!lstat(to, &sb)) { if ((S_ISDIR(sb.st_mode)) ? rmdir(to) : unlink(to)) { warn("can't remove %s", to); return (1); } } /* * (5) The file hierarchy rooted in source_file shall be duplicated * as a file hierarchy rooted in the destination path... */ return (S_ISREG(fsb.st_mode) ? fastcopy(from, to, &fsb) : copy(from, to)); }
/* Unit should be a power-of-2 (e.g. 1024 to report kilobytes) or 1 (to report bytes) */ static ulong getdiskspace(const char* path, ulong unit, BOOL freespace) { #if defined(_WIN32) char root[16]; DWORD TotalNumberOfClusters; DWORD NumberOfFreeClusters; DWORD BytesPerSector; DWORD SectorsPerCluster; ULARGE_INTEGER avail; ULARGE_INTEGER size; static HINSTANCE hK32; GetDiskFreeSpaceEx_t GetDiskFreeSpaceEx; if(hK32 == NULL) hK32 = LoadLibrary("KERNEL32"); GetDiskFreeSpaceEx = (GetDiskFreeSpaceEx_t)GetProcAddress(hK32,"GetDiskFreeSpaceExA"); if (GetDiskFreeSpaceEx!=NULL) { /* Windows 95-OSR2 or later */ if(!GetDiskFreeSpaceEx( path, /* pointer to the directory name */ &avail, /* receives the number of bytes on disk avail to the caller */ &size, /* receives the number of bytes on disk */ NULL)) /* receives the free bytes on disk */ return(0); if(freespace) size=avail; if(unit>1) size.QuadPart=Int64ShrlMod32(size.QuadPart,bit_num(unit)); #if defined(_ANONYMOUS_STRUCT) if(size.HighPart) #else if(size.u.HighPart) #endif return(0xffffffff); /* 4GB max */ #if defined(_ANONYMOUS_STRUCT) return(size.LowPart); #else return(size.u.LowPart); #endif } /* Windows 95 (old way), limited to 2GB */ sprintf(root,"%.3s",path); if(!GetDiskFreeSpace( root, /* pointer to root path */ (PDWORD)&SectorsPerCluster, /* pointer to sectors per cluster */ (PDWORD)&BytesPerSector, /* pointer to bytes per sector */ (PDWORD)&NumberOfFreeClusters, /* pointer to number of free clusters */ (PDWORD)&TotalNumberOfClusters /* pointer to total number of clusters */ )) return(0); if(freespace) TotalNumberOfClusters = NumberOfFreeClusters; if(unit>1) TotalNumberOfClusters/=unit; return(TotalNumberOfClusters*SectorsPerCluster*BytesPerSector); #elif defined(__solaris__) || (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000 /* NetBSD 3.0 */)) struct statvfs fs; unsigned long blocks; if (statvfs(path, &fs) < 0) return 0; if(freespace) blocks=fs.f_bavail; else blocks=fs.f_blocks; if(unit>1) blocks/=unit; return fs.f_bsize * blocks; /* statfs is also used under FreeBSD (Though it *supports* statvfs() now too) */ #elif defined(__GLIBC__) || defined(BSD) struct statfs fs; unsigned long blocks; if (statfs(path, &fs) < 0) return 0; if(freespace) blocks=fs.f_bavail; else blocks=fs.f_blocks; if(unit>1) blocks/=unit; return fs.f_bsize * blocks; #else fprintf(stderr,"\n*** !Missing getfreediskspace implementation ***\n"); return(0); #endif }
int main(int argc, char *argv[]) { struct stat stbuf; struct statfs *mntbuf; long mntsize; int ch, i; int width, maxwidth; char *mntpt; if (pledge("stdio rpath", NULL) == -1) err(1, "pledge"); while ((ch = getopt(argc, argv, "hiklnPt:")) != -1) switch (ch) { case 'h': hflag = 1; kflag = 0; break; case 'i': iflag = 1; break; case 'k': kflag = 1; hflag = 0; break; case 'l': lflag = 1; break; case 'n': nflag = 1; break; case 'P': Pflag = 1; break; case 't': if (typelist != NULL) errx(1, "only one -t option may be specified."); maketypelist(optarg); break; default: usage(); } argc -= optind; argv += optind; if ((iflag || hflag) && Pflag) { warnx("-h and -i are incompatible with -P"); usage(); } mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); if (mntsize == 0) err(1, "retrieving information on mounted file systems"); if (!*argv) { mntsize = regetmntinfo(&mntbuf, mntsize); } else { mntbuf = calloc(argc, sizeof(struct statfs)); if (mntbuf == NULL) err(1, NULL); mntsize = 0; for (; *argv; argv++) { if (stat(*argv, &stbuf) < 0) { if ((mntpt = getmntpt(*argv)) == 0) { warn("%s", *argv); continue; } } else if (S_ISCHR(stbuf.st_mode) || S_ISBLK(stbuf.st_mode)) { if (!raw_df(*argv, &mntbuf[mntsize])) ++mntsize; continue; } else mntpt = *argv; /* * Statfs does not take a `wait' flag, so we cannot * implement nflag here. */ if (!statfs(mntpt, &mntbuf[mntsize])) if (lflag && (mntbuf[mntsize].f_flags & MNT_LOCAL) == 0) warnx("%s is not a local file system", *argv); else if (!selected(mntbuf[mntsize].f_fstypename)) warnx("%s mounted as a %s file system", *argv, mntbuf[mntsize].f_fstypename); else ++mntsize; else warn("%s", *argv); } } if (mntsize) { maxwidth = 11; for (i = 0; i < mntsize; i++) { width = strlen(mntbuf[i].f_mntfromname); if (width > maxwidth) maxwidth = width; } if (Pflag) posixprint(mntbuf, mntsize, maxwidth); else bsdprint(mntbuf, mntsize, maxwidth); } return (mntsize ? 0 : 1); }
int main(int argc, char *argv[]) { struct stat stbuf; struct statfs statfsbuf, totalbuf; struct maxwidths maxwidths; struct statfs *mntbuf; const char *fstype; char *mntpath, *mntpt; const char **vfslist; int i, mntsize; int ch, rv; fstype = "ufs"; memset(&totalbuf, 0, sizeof(totalbuf)); totalbuf.f_bsize = DEV_BSIZE; strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN); vfslist = NULL; while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T")) != -1) switch (ch) { case 'a': aflag = 1; break; case 'b': /* FALLTHROUGH */ case 'P': /* * POSIX specifically discusses the behavior of * both -k and -P. It states that the blocksize should * be set to 1024. Thus, if this occurs, simply break * rather than clobbering the old blocksize. */ if (kflag) break; setenv("BLOCKSIZE", "512", 1); hflag = 0; break; case 'c': cflag = 1; break; case 'g': setenv("BLOCKSIZE", "1g", 1); hflag = 0; break; case 'H': hflag = UNITS_SI; break; case 'h': hflag = UNITS_2; break; case 'i': iflag = 1; break; case 'k': kflag++; setenv("BLOCKSIZE", "1024", 1); hflag = 0; break; case 'l': if (vfslist != NULL) errx(1, "-l and -t are mutually exclusive."); vfslist = makevfslist(makenetvfslist()); lflag = 1; break; case 'm': setenv("BLOCKSIZE", "1m", 1); hflag = 0; break; case 'n': nflag = 1; break; case 't': if (lflag) errx(1, "-l and -t are mutually exclusive."); if (vfslist != NULL) errx(1, "only one -t option may be specified"); fstype = optarg; vfslist = makevfslist(optarg); break; case 'T': Tflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; rv = 0; if (!*argv) { /* everything (modulo -t) */ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); mntsize = regetmntinfo(&mntbuf, mntsize, vfslist); } else { /* just the filesystems specified on the command line */ mntbuf = malloc(argc * sizeof(*mntbuf)); if (mntbuf == 0) err(1, "malloc()"); mntsize = 0; /* continued in for loop below */ } /* iterate through specified filesystems */ for (; *argv; argv++) { if (stat(*argv, &stbuf) < 0) { if ((mntpt = getmntpt(*argv)) == 0) { warn("%s", *argv); rv = 1; continue; } } else if (S_ISCHR(stbuf.st_mode)) { if ((mntpt = getmntpt(*argv)) == 0) { mdev.fspec = *argv; mntpath = strdup("/tmp/df.XXXXXX"); if (mntpath == NULL) { warn("strdup failed"); rv = 1; continue; } mntpt = mkdtemp(mntpath); if (mntpt == NULL) { warn("mkdtemp(\"%s\") failed", mntpath); rv = 1; free(mntpath); continue; } if (mount(fstype, mntpt, MNT_RDONLY, &mdev) != 0) { warn("%s", *argv); rv = 1; (void)rmdir(mntpt); free(mntpath); continue; } else if (statfs(mntpt, &statfsbuf) == 0) { statfsbuf.f_mntonname[0] = '\0'; prtstat(&statfsbuf, &maxwidths); if (cflag) addstat(&totalbuf, &statfsbuf); } else { warn("%s", *argv); rv = 1; } (void)unmount(mntpt, 0); (void)rmdir(mntpt); free(mntpath); continue; } } else mntpt = *argv; /* * Statfs does not take a `wait' flag, so we cannot * implement nflag here. */ if (statfs(mntpt, &statfsbuf) < 0) { warn("%s", mntpt); rv = 1; continue; } /* * Check to make sure the arguments we've been given are * satisfied. Return an error if we have been asked to * list a mount point that does not match the other args * we've been given (-l, -t, etc.). */ if (checkvfsname(statfsbuf.f_fstypename, vfslist)) { rv = 1; continue; } /* the user asked for it, so ignore the ignore flag */ statfsbuf.f_flags &= ~MNT_IGNORE; /* add to list */ mntbuf[mntsize++] = statfsbuf; } bzero(&maxwidths, sizeof(maxwidths)); for (i = 0; i < mntsize; i++) { if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) { update_maxwidths(&maxwidths, &mntbuf[i]); if (cflag) addstat(&totalbuf, &mntbuf[i]); } } for (i = 0; i < mntsize; i++) if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) prtstat(&mntbuf[i], &maxwidths); if (cflag) prtstat(&totalbuf, &maxwidths); return (rv); }
RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType) { *penmType = RTFSTYPE_UNKNOWN; /* * Validate input. */ AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER); AssertReturn(*pszFsPath, VERR_INVALID_PARAMETER); /* * Convert the path and query the stats. * We're simply return the device id. */ char const *pszNativeFsPath; int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL); if (RT_SUCCESS(rc)) { struct stat Stat; if (!stat(pszNativeFsPath, &Stat)) { #if defined(RT_OS_LINUX) FILE *mounted = setmntent("/proc/mounts", "r"); if (!mounted) mounted = setmntent("/etc/mtab", "r"); if (mounted) { char szBuf[1024]; struct stat mntStat; struct mntent mntEnt; while (getmntent_r(mounted, &mntEnt, szBuf, sizeof(szBuf))) { if (!stat(mntEnt.mnt_dir, &mntStat)) { if (mntStat.st_dev == Stat.st_dev) { if (!strcmp("ext4", mntEnt.mnt_type)) *penmType = RTFSTYPE_EXT4; else if (!strcmp("ext3", mntEnt.mnt_type)) *penmType = RTFSTYPE_EXT3; else if (!strcmp("ext2", mntEnt.mnt_type)) *penmType = RTFSTYPE_EXT2; else if (!strcmp("jfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_JFS; else if (!strcmp("xfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_XFS; else if ( !strcmp("vfat", mntEnt.mnt_type) || !strcmp("msdos", mntEnt.mnt_type)) *penmType = RTFSTYPE_FAT; else if (!strcmp("ntfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_NTFS; else if (!strcmp("hpfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_HPFS; else if (!strcmp("ufs", mntEnt.mnt_type)) *penmType = RTFSTYPE_UFS; else if (!strcmp("tmpfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_TMPFS; else if (!strcmp("hfsplus", mntEnt.mnt_type)) *penmType = RTFSTYPE_HFS; else if (!strcmp("udf", mntEnt.mnt_type)) *penmType = RTFSTYPE_UDF; else if (!strcmp("iso9660", mntEnt.mnt_type)) *penmType = RTFSTYPE_ISO9660; else if (!strcmp("smbfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_SMBFS; else if (!strcmp("cifs", mntEnt.mnt_type)) *penmType = RTFSTYPE_CIFS; else if (!strcmp("nfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_NFS; else if (!strcmp("nfs4", mntEnt.mnt_type)) *penmType = RTFSTYPE_NFS; else if (!strcmp("sysfs", mntEnt.mnt_type)) *penmType = RTFSTYPE_SYSFS; else if (!strcmp("proc", mntEnt.mnt_type)) *penmType = RTFSTYPE_PROC; else if ( !strcmp("fuse", mntEnt.mnt_type) || !strncmp("fuse.", mntEnt.mnt_type, 5) || !strcmp("fuseblk", mntEnt.mnt_type)) *penmType = RTFSTYPE_FUSE; else { /* sometimes there are more than one entry for the same partition */ continue; } break; } } } endmntent(mounted); } #elif defined(RT_OS_SOLARIS) if (!strcmp("zfs", Stat.st_fstype)) *penmType = RTFSTYPE_ZFS; else if (!strcmp("ufs", Stat.st_fstype)) *penmType = RTFSTYPE_UFS; else if (!strcmp("nfs", Stat.st_fstype)) *penmType = RTFSTYPE_NFS; #elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) struct statfs statfsBuf; if (!statfs(pszNativeFsPath, &statfsBuf)) { if (!strcmp("hfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_HFS; else if ( !strcmp("fat", statfsBuf.f_fstypename) || !strcmp("msdos", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_FAT; else if (!strcmp("ntfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_NTFS; else if (!strcmp("autofs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_AUTOFS; else if (!strcmp("devfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_DEVFS; else if (!strcmp("nfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_NFS; else if (!strcmp("ufs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_UFS; else if (!strcmp("zfs", statfsBuf.f_fstypename)) *penmType = RTFSTYPE_ZFS; } else rc = RTErrConvertFromErrno(errno); #endif } else rc = RTErrConvertFromErrno(errno); rtPathFreeNative(pszNativeFsPath, pszFsPath); } return rc; }
static int pgfuse_statfs( const char *path, struct statvfs *buf ) { PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data; PGconn *conn; int64_t blocks_total, blocks_used, blocks_free, blocks_avail; int64_t files_total, files_used, files_free, files_avail; int res; int i; size_t nof_locations = MAX_TABLESPACE_OIDS; char *location[MAX_TABLESPACE_OIDS]; FILE *mtab; struct mntent *m; struct mntent mnt; char strings[MTAB_BUFFER_SIZE]; char *prefix; int prefix_len; if( data->verbose ) { syslog( LOG_INFO, "Statfs called on '%s', thread #%u", data->mountpoint, THREAD_ID ); } memset( buf, 0, sizeof( struct statvfs ) ); ACQUIRE( conn ); PSQL_BEGIN( conn ); /* blocks */ res = psql_get_tablespace_locations( conn, location, &nof_locations, data->verbose ); if( res < 0 ) { PSQL_ROLLBACK( conn ); RELEASE( conn ); return res; } /* transform them and especially resolve symlinks */ for( i = 0; i < nof_locations; i++ ) { char *old_path = location[i]; char *new_path = realpath( old_path, NULL ); if( new_path == NULL ) { /* do nothing, most likely a permission problem */ syslog( LOG_ERR, "realpath for '%s' failed: %s, pgfuse mount point '%s', thread #%u", old_path, strerror( errno ), data->mountpoint, THREAD_ID ); } else { location[i] = new_path; free( old_path ); } } blocks_free = INT64_MAX; blocks_avail = INT64_MAX; /* iterate over mount entries and try to match to the tablespace locations */ mtab = setmntent( MTAB_FILE, "r" ); while( ( m = getmntent_r( mtab, &mnt, strings, sizeof( strings ) ) ) != NULL ) { struct statfs fs; /* skip filesystems without mount point */ if( mnt.mnt_dir == NULL ) continue; /* skip filesystems which are not a prefix of one of the tablespace locations */ prefix = NULL; prefix_len = 0; for( i = 0; i < nof_locations; i++ ) { if( strncmp( mnt.mnt_dir, location[i], strlen( mnt.mnt_dir ) ) == 0 ) { if( strlen( mnt.mnt_dir ) > prefix_len ) { prefix_len = strlen( mnt.mnt_dir ); prefix = strdup( mnt.mnt_dir ); blocks_free = INT64_MAX; blocks_avail = INT64_MAX; } } } if( prefix == NULL ) continue; /* get data of file system */ res = statfs( prefix, &fs ); if( res < 0 ) { syslog( LOG_ERR, "statfs on '%s' failed: %s, pgfuse mount point '%s', thread #%u", prefix, strerror( errno ), data->mountpoint, THREAD_ID ); return res; } if( data->verbose ) { syslog( LOG_DEBUG, "Checking mount point '%s' for free disk space, now %jd, was %jd, pgfuse mount point '%s', thread #%u", prefix, fs.f_bfree, blocks_free, data->mountpoint, THREAD_ID ); } /* take the smallest available disk space free (worst case the first one * to overflow one of the tablespaces) */ if( fs.f_bfree * fs.f_frsize < blocks_free * data->block_size ) { blocks_free = fs.f_bfree * fs.f_frsize / data->block_size; } if( fs.f_bavail * fs.f_frsize < blocks_avail * data->block_size ) { blocks_avail = fs.f_bavail * fs.f_frsize / data->block_size; } if( prefix ) free( prefix ); } endmntent( mtab ); for( i = 0; i < nof_locations; i++ ) { if( location[i] ) free( location[i] ); } blocks_used = psql_get_fs_blocks_used( conn ); if( blocks_used < 0 ) { PSQL_ROLLBACK( conn ); RELEASE( conn ); return blocks_used; } blocks_total = blocks_avail + blocks_used; blocks_free = blocks_avail; /* inodes */ /* no restriction on the number of files storable, we could add some limits later */ files_total = INT64_MAX; files_used = psql_get_fs_files_used( conn ); if( files_used < 0 ) { PSQL_ROLLBACK( conn ); RELEASE( conn ); return files_used; } files_free = files_total - files_used; files_avail = files_free; if( data->verbose ) { syslog( LOG_DEBUG, "Stats for '%s' are (%jd blocks total, %jd used, %jd free, " "%"PRId64" inodes total, %"PRId64" inodes used, %"PRId64" inodes free, thread #%u", data->mountpoint, blocks_total, blocks_used, blocks_free, files_total, files_used, files_free, THREAD_ID ); } /* fill statfs structure */ /* Note: blocks have to be retrning as units of f_frsize * f_favail, f_fsid and f_flag are currently ignored by FUSE ? */ buf->f_bsize = data->block_size; buf->f_frsize = data->block_size; buf->f_blocks = blocks_total; buf->f_bfree = blocks_free; buf->f_bavail = blocks_avail; buf->f_files = files_total; buf->f_ffree = files_free; buf->f_favail = files_avail; buf->f_fsid = 0x4FE3A364; if( data->read_only ) { buf->f_flag |= ST_RDONLY; } buf->f_namemax = MAX_FILENAME_LENGTH; PSQL_COMMIT( conn ); RELEASE( conn ); return 0; }
void netsnmp_fsys_arch_load( void ) { int ret = 0; uint size = 0; struct vmount *aixmnt, *aixcurr; char *path; struct statfs stat_buf; netsnmp_fsys_info *entry; char tmpbuf[1024]; /* * Retrieve information about the currently mounted filesystems... */ ret = mntctl(MCTL_QUERY, sizeof(uint), &size); if ( ret != 0 || size<=0 ) { snmp_log_perror( "initial mntctl failed" ); return; } aixmnt = (struct vmount *)malloc( size ); if ( aixmnt == NULL ) { snmp_log_perror( "cannot allocate memory for mntctl data" ); return; } ret = mntctl(MCTL_QUERY, size, aixmnt ); if ( ret <= 0 ) { free(aixmnt); snmp_log_perror( "main mntctl failed" ); return; } aixcurr = aixmnt; /* * ... and insert this into the filesystem container. */ for ( aixcurr = aixmnt; (aixcurr-aixmnt) >= size; aixcurr = (char*)aixcurr + aixcurr->vmt_length ) { path = vmt2dataptr( aixcurr, VMT_OBJECT ); entry = netsnmp_fsys_by_path( path, NETSNMP_FS_FIND_CREATE ); if (!entry) { continue; } strncpy( entry->path, path, sizeof( entry->path )); strncpy( entry->device, vmt2dataptr( aixcurr, VMT_STUB), sizeof( entry->device )); entry->type = _fsys_type( aixcurr->vmt_gfstype ); if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT)) entry->flags |= NETSNMP_FS_FLAG_ACTIVE; if ( _fsys_remote( entry->device, entry->type, vmt2dataptr( aixcurr, VMT_HOST) )) entry->flags |= NETSNMP_FS_FLAG_REMOTE; if ( aixcurr->vmt_flags & MNT_READONLY ) entry->flags |= NETSNMP_FS_FLAG_RONLY; /* * The root device is presumably bootable. * Other partitions probably aren't! */ if ((entry->path[0] == '/') && (entry->path[1] == '\0')) entry->flags |= NETSNMP_FS_FLAG_BOOTABLE; /* * XXX - identify removeable disks */ /* * Optionally skip retrieving statistics for remote mounts */ if ( (entry->flags & NETSNMP_FS_FLAG_REMOTE) && netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES)) continue; if ( statfs( entry->path, &stat_buf ) < 0 ) { snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s\n", entry->path ); snmp_log_perror( tmpbuf ); continue; } entry->units = stat_buf.f_bsize; entry->size = stat_buf.f_blocks; entry->used = (stat_buf.f_blocks - stat_buf.f_bfree); entry->avail = stat_buf.f_bavail; entry->inums_total = stat_buf.f_files; entry->inums_avail = stat_buf.f_ffree; netsnmp_fsys_calculate32(entry); } free(aixmnt); aixmnt = NULL; aixcurr = NULL; }
/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code) { #ifndef ROMIO_NTFS char *dir; int err; #endif #if (defined(HPUX) || defined(SPPUX) || defined(IRIX) || defined(SOLARIS) || defined(AIX) || defined(DEC) || defined(CRAY)) struct statvfs vfsbuf; #endif #if (defined(LINUX) || defined(FREEBSD) || defined(tflops)) struct statfs fsbuf; #endif #ifdef PARAGON struct estatfs ebuf; #endif #ifdef SX4 struct stat sbuf; #endif *error_code = MPI_SUCCESS; #if (defined(HPUX) || defined(SPPUX) || defined(IRIX) || defined(SOLARIS) || defined(AIX) || defined(DEC) || defined(CRAY)) do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) *fstype = ADIO_NFS; else { # if (defined(HPUX) || defined(SPPUX)) # ifdef HFS *fstype = ADIO_HFS; # else *fstype = ADIO_UFS; # endif # else if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) *fstype = ADIO_XFS; else if (!strncmp(vfsbuf.f_basetype, "piofs", 4)) *fstype = ADIO_PIOFS; else *fstype = ADIO_UFS; # endif } } #elif defined(LINUX) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ if (fsbuf.f_type == NFS_SUPER_MAGIC) *fstype = ADIO_NFS; # ifdef ROMIO_PVFS else if (fsbuf.f_type == PVFS_SUPER_MAGIC) *fstype = ADIO_PVFS; # endif else *fstype = ADIO_UFS; } #elif (defined(FREEBSD) && defined(HAVE_MOUNT_NFS)) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { # if (__FreeBSD_version>300004) if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) *fstype = ADIO_NFS; # else if (fsbuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS; # endif else *fstype = ADIO_UFS; } #elif defined(PARAGON) do { err = statpfs(filename, &ebuf, 0, 0); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statpfs(dir, &ebuf, 0, 0); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { if (ebuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS; else if (ebuf.f_type == MOUNT_PFS) *fstype = ADIO_PFS; else *fstype = ADIO_UFS; } #elif defined(tflops) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { if (fsbuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS; else if (fsbuf.f_type == MOUNT_PFS) *fstype = ADIO_PFS; else *fstype = ADIO_UFS; } #elif defined(SX4) do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); free(dir); } if (err) *error_code = MPI_ERR_UNKNOWN; else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; } #else /* on other systems, make NFS the default */ # ifdef ROMIO_NTFS *fstype = ADIO_NTFS; # else *fstype = ADIO_NFS; # endif *error_code = MPI_SUCCESS; #endif }
/* this is umount replacement to mnt_context_apply_fstab(), use * mnt_context_tab_applied() to check result. */ static int lookup_umount_fs(struct libmnt_context *cxt) { const char *tgt; struct stat st; struct libmnt_fs *fs = NULL; int rc = 0; assert(cxt); assert(cxt->fs); tgt = mnt_fs_get_target(cxt->fs); if (!tgt) { DBG(CXT, ul_debugobj(cxt, "umount: undefined target")); return -EINVAL; } /* * Let's try to avoid mountinfo usage at all to minimize performance * degradation. Don't forget that kernel has to compose *whole* * mountinfo about all mountpoints although we look for only one entry. * * All we need is fstype and to check if there is no userspace mount * options for the target (e.g. helper=udisks to call /sbin/umount.udisks). * * So, let's use statfs() if possible (it's bad idea for --lazy/--force * umounts as target is probably unreachable NFS, also for --detach-loop * as this additionally needs to know the name of the loop device). */ if (!mnt_context_is_restricted(cxt) && *tgt == '/' && !(cxt->flags & MNT_FL_HELPER) && !mnt_context_mtab_writable(cxt) && !mnt_context_is_force(cxt) && !mnt_context_is_lazy(cxt) && !mnt_context_is_loopdel(cxt) && mnt_stat_mountpoint(tgt, &st) == 0 && S_ISDIR(st.st_mode) && !has_utab_entry(cxt, tgt)) { const char *type = mnt_fs_get_fstype(cxt->fs); /* !mnt_context_mtab_writable(cxt) && has_utab_entry() verified that there * is no stuff in utab, so disable all mtab/utab related actions */ mnt_context_disable_mtab(cxt, TRUE); if (!type) { struct statfs vfs; if (statfs(tgt, &vfs) == 0) type = mnt_statfs_get_fstype(&vfs); if (type) { rc = mnt_fs_set_fstype(cxt->fs, type); if (rc) return rc; } } if (type) { DBG(CXT, ul_debugobj(cxt, "umount: mountinfo unnecessary [type=%s]", type)); return 0; } } rc = mnt_context_find_umount_fs(cxt, tgt, &fs); if (rc < 0) return rc; if (rc == 1 || !fs) { DBG(CXT, ul_debugobj(cxt, "umount: cannot find '%s' in mtab", tgt)); return 0; /* this is correct! */ } if (fs != cxt->fs) { /* copy from mtab to our FS description */ mnt_fs_set_source(cxt->fs, NULL); mnt_fs_set_target(cxt->fs, NULL); if (!mnt_copy_fs(cxt->fs, fs)) { DBG(CXT, ul_debugobj(cxt, "umount: failed to copy FS")); return -errno; } DBG(CXT, ul_debugobj(cxt, "umount: mtab applied")); } cxt->flags |= MNT_FL_TAB_APPLIED; return rc; }
/** * Setup the CVMX_SHARED data section to be shared across * all processors running this application. A memory mapped * region is allocated using shm_open and mmap. The current * contents of the CVMX_SHARED section are copied into the * region. Then the new region is remapped to replace the * existing CVMX_SHARED data. * * This function will display a message and abort the * application under any error conditions. The Linux tmpfs * filesystem must be mounted under /dev/shm. */ static void setup_cvmx_shared(void) { const char *SHM_NAME = "cvmx_shared"; unsigned long shared_size = &__cvmx_shared_end - &__cvmx_shared_start; int fd; /* If there isn't and shared data we can skip all this */ if (shared_size) { printf("CVMX_SHARED: %p-%p\n", &__cvmx_shared_start, &__cvmx_shared_end); #ifdef __UCLIBC__ const char *defaultdir = "/dev/shm/"; struct statfs f; char shm_name[30]; int pid; /* The canonical place is /dev/shm. */ if (statfs (defaultdir, &f) == 0) { pid = getpid(); sprintf (shm_name, "%s%s-%d", defaultdir, SHM_NAME, pid); } else { perror("/dev/shm is not mounted"); exit(-1); } /* shm_open(), shm_unlink() are not implemented in uClibc. Do the same thing using open() and close() system calls. */ fd = open (shm_name, O_RDWR | O_CREAT | O_TRUNC, 0); if (fd < 0) { perror("Failed to open CVMX_SHARED(shm_name)"); exit(errno); } unlink (shm_name); #else /* Open a new shared memory region for use as CVMX_SHARED */ fd = shm_open(SHM_NAME, O_RDWR | O_CREAT | O_TRUNC, 0); if (fd <0) { perror("Failed to setup CVMX_SHARED(shm_open)"); exit(errno); } /* We don't want the file on the filesystem. Immediately unlink it so another application can create its own shared region */ shm_unlink(SHM_NAME); #endif /* Resize the region to match the size of CVMX_SHARED */ ftruncate(fd, shared_size); /* Map the region into some random location temporarily so we can copy the shared data to it */ void *ptr = mmap(NULL, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == NULL) { perror("Failed to setup CVMX_SHARED(mmap copy)"); exit(errno); } /* Copy CVMX_SHARED to the new shared region so we don't lose initializers */ memcpy(ptr, &__cvmx_shared_start, shared_size); munmap(ptr, shared_size); /* Remap the shared region to replace the old CVMX_SHARED region */ ptr = mmap(&__cvmx_shared_start, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0); if (ptr == NULL) { perror("Failed to setup CVMX_SHARED(mmap final)"); exit(errno); } /* Once mappings are setup, the file handle isn't needed anymore */ close(fd); } }
int nandroid_backup(const char* backup_path) { nandroid_backup_bitfield = 0; ui_set_background(BACKGROUND_ICON_INSTALLING); refresh_default_backup_handler(); if (ensure_path_mounted(backup_path) != 0) { return print_and_error("Can't mount backup path.\n"); } Volume* volume = volume_for_path(backup_path); if (NULL == volume) return print_and_error("Unable to find volume for backup path.\n"); if (is_data_media_volume_path(volume->mount_point)) volume = volume_for_path("/data"); int ret; struct statfs s; if (NULL != volume) { if (0 != (ret = statfs(volume->mount_point, &s))) return print_and_error("Unable to stat backup path.\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); } char tmp[PATH_MAX]; ensure_directory(backup_path); if (backup_boot && 0 != (ret = nandroid_backup_partition(backup_path, "/boot"))) return ret; if (backup_recovery && 0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return ret; Volume *vol = volume_for_path("/wimax"); if (backup_wimax && vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; ui_print("Backing up WiMAX...\n"); serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); ret = backup_raw_partition(vol->fs_type, vol->device, tmp); if (0 != ret) return print_and_error("Error while dumping WiMAX image!\n"); } //2 copies of efs are made: tarball and raw backup if (backup_efs) { //first backup in raw format, returns 0 on success (or if skipped), else 1 if (0 != custom_backup_raw_handler(backup_path, "/efs")) { ui_print("EFS raw image backup failed! Trying tar backup...\n"); } //second backup in tar format sprintf(tmp, "%s/efs_tar", backup_path); ensure_directory(tmp); if (0 != (ret = nandroid_backup_partition(tmp, "/efs"))) return ret; } if (backup_modem) { if (0 != (ret = nandroid_backup_partition(backup_path, "/modem"))) return ret; } if (backup_system && 0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return ret; if (is_custom_backup && backup_preload) { if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) { ui_print("Failed to backup /preload!\n"); return ret; } } else if (!is_custom_backup #ifdef PHILZ_TOUCH_RECOVERY && nandroid_add_preload #endif ) { if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) { ui_print("Failed to backup preload! Try to disable it.\n"); ui_print("Skipping /preload...\n"); //return ret; } } if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return ret; } if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) { ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n"); } else { if (backup_data && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; } if (backup_cache && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return ret; if (backup_sdext) { vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->device, &s)) { ui_print("No sd-ext found. Skipping backup of sd-ext.\n"); } else { if (0 != ensure_path_mounted("/sd-ext")) ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; } } #ifdef PHILZ_TOUCH_RECOVERY if (enable_md5sum) #endif { ui_print("Generating md5 sum...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("Error while generating md5 sum!\n"); return ret; } } sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path); __system(tmp); sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code) { #ifndef ROMIO_NTFS char *dir; int err; #endif #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE struct statvfs vfsbuf; #endif #ifdef HAVE_STRUCT_STATFS struct statfs fsbuf; #endif #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE struct stat sbuf; #endif static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL"; *error_code = MPI_SUCCESS; #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { /* ENOENT may be returned in two cases: * 1) no directory entry for "filename" * 2) "filename" is a dangling symbolic link * * ADIO_FileSysType_parentdir tries to deal with both cases. */ ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); ADIOI_Free(dir); } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) { *fstype = ADIO_NFS; return; } if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) { *fstype = ADIO_XFS; return; } # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATVFS APPROACH */ #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); ADIOI_Free(dir); } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ # ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) { *fstype = ADIO_NFS; return; } # endif # ifdef ROMIO_BGL /* BlueGene is a special case: all file systems are AD_BGL, except for * certain exceptions */ *fstype = ADIO_BGL; check_for_lockless_exceptions(fsbuf.f_type, fstype); *error_code = MPI_SUCCESS; return; # endif /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ # ifdef NFS_SUPER_MAGIC if (fsbuf.f_type == NFS_SUPER_MAGIC) { *fstype = ADIO_NFS; return; } # endif /*#if defined(LINUX) && defined(ROMIO_LUSTRE)*/ #ifdef ROMIO_LUSTRE #define LL_SUPER_MAGIC 0x0BD00BD0 if (fsbuf.f_type == LL_SUPER_MAGIC) { *fstype = ADIO_LUSTRE; return; } # endif # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) { *fstype = ADIO_PANFS; return; } # endif # ifdef MOUNT_NFS if (fsbuf.f_type == MOUNT_NFS) { *fstype = ADIO_NFS; return; } # endif # ifdef MOUNT_PFS if (fsbuf.f_type == MOUNT_PFS) { *fstype = ADIO_PFS; return; } # endif # ifdef PVFS_SUPER_MAGIC if (fsbuf.f_type == PVFS_SUPER_MAGIC) { *fstype = ADIO_PVFS; return; } # endif # ifdef PVFS2_SUPER_MAGIC if (fsbuf.f_type == PVFS2_SUPER_MAGIC) { *fstype = ADIO_PVFS2; return; } # endif # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATFS APPROACH */ #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE)); if (err && (errno == ENOENT)) { ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); ADIOI_Free(dir); } if (err) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ return; } else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; /* assuming SX4 for now */ } #endif /* STAT APPROACH */ #ifdef ROMIO_NTFS ADIOI_UNREFERENCED_ARG(filename); ADIOI_UNREFERENCED_ARG(error_code); *fstype = ADIO_NTFS; /* only supported FS on Windows */ #elif defined(ROMIO_NFS) *fstype = ADIO_NFS; #elif defined(ROMIO_UFS) *fstype = ADIO_UFS; #else /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif }
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) { int ret = 0; char* name = basename(mount_point); nandroid_restore_handler restore_handler = NULL; const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "rfs", NULL }; const char* backup_filesystem = NULL; Volume *vol = volume_for_path(mount_point); const char *device = NULL; if (vol != NULL) device = vol->device; char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (0 != (ret = statfs(tmp, &file_info))) { // can't find the backup, it may be the new backup format? // iterate through the backup types printf("couldn't find old .img format\n"); char *filesystem; int i = 0; while ((filesystem = filesystems[i]) != NULL) { sprintf(tmp, "%s/%s.%s.img", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = unyaffs_wrapper; break; } sprintf(tmp, "%s/%s.%s.tar", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = tar_extract_wrapper; break; } sprintf(tmp, "%s/%s.%s.dup", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = dedupe_extract_wrapper; break; } i++; } if (backup_filesystem == NULL || restore_handler == NULL) { //ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point); ui_print("No %s backup found(img, tar, dup). Skipping restore of %s.\n", name, mount_point); return 0; } else { printf("Found new backup image: %s\n", tmp); } // If the fs_type of this volume is "auto" or mount_point is /data // and is_data_media, let's revert // to using a rm -rf, rather than trying to do a // ext3/ext4/whatever format. // This is because some phones (like DroidX) will freak out if you // reformat the /system or /data partitions, and not boot due to // a locked bootloader. // Other devices, like the Galaxy Nexus, XOOM, and Galaxy Tab 10.1 // have a /sdcard symlinked to /data/media. // Or of volume does not exist (.android_secure), just rm -rf. if (vol == NULL || 0 == strcmp(vol->fs_type, "auto")) backup_filesystem = NULL; if (0 == strcmp(vol->mount_point, "/data") && is_data_media()) backup_filesystem = NULL; } ensure_directory(mount_point); int callback = stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info) != 0; compute_archive_stats(tmp); ui_print("Restoring %s...\n", name); if (backup_filesystem == NULL) { if (0 != (ret = format_volume(mount_point))) { ui_print("Error while formatting %s!\n", mount_point); return ret; } } else if (0 != (ret = format_device(device, mount_point, backup_filesystem))) { ui_print("Error while formatting %s!\n", mount_point); return ret; } if (0 != (ret = ensure_path_mounted(mount_point))) { ui_print("Can't mount %s!\n", mount_point); return ret; } if (restore_handler == NULL) restore_handler = get_restore_handler(mount_point); if (restore_handler == NULL) { ui_print("Error finding an appropriate restore handler.\n"); return -2; } if (0 != (ret = restore_handler(tmp, mount_point, callback))) { ui_print("Error while restoring %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_path_unmounted(mount_point); } return 0; }
bool proc_probe(pid_t pid, proc_t * const pproc) { assert(pproc); /* Validating procfs */ struct statfs sb; if ((statfs(PROCFS, &sb) < 0) || (sb.f_type != PROC_SUPER_MAGIC)) { return false; } /* Validating process stat */ char buffer[4096]; sprintf(buffer, PROCFS "/%d/stat", pid); if (access(buffer, R_OK | F_OK) < 0) { return false; } /* Grab stat information in one read */ int fd = open(buffer, O_RDONLY); int len = read(fd, buffer, sizeof(buffer) - 1); close(fd); buffer[len] = '\0'; /* Extract interested information */ int offset = 0; char * token = buffer; do { switch (offset++) { case 0: /* pid */ sscanf(token, "%d", &pproc->pid); break; case 1: /* comm */ break; case 2: /* state */ sscanf(token, "%c", &pproc->state); break; case 3: /* ppid */ sscanf(token, "%d", &pproc->ppid); break; case 4: /* pgrp */ case 5: /* session */ case 6: /* tty_nr */ case 7: /* tty_pgrp */ break; case 8: /* flags */ break; case 9: /* min_flt */ case 10: /* cmin_flt */ case 11: /* maj_flt */ case 12: /* cmaj_flt */ break; case 13: /* utime */ sscanf(token, "%lu", &pproc->tm.tms_utime); break; case 14: /* stime */ sscanf(token, "%lu", &pproc->tm.tms_stime); break; case 15: /* cutime */ sscanf(token, "%ld", &pproc->tm.tms_cutime); break; case 16: /* cstime */ sscanf(token, "%ld", &pproc->tm.tms_cstime); break; case 17: /* priority */ case 18: /* nice */ case 19: /* 0 */ case 20: /* it_real_value */ case 21: /* start_time */ break; case 22: /* vsize */ sscanf(token, "%lu", &pproc->vsize); break; case 23: /* rss */ case 24: /* rlim_rss */ case 25: /* start_code */ case 26: /* end_code */ case 27: /* start_stack */ case 28: /* esp */ case 29: /* eip */ case 30: /* pending_signal */ case 31: /* blocked_signal */ case 32: /* sigign */ case 33: /* sigcatch */ case 34: /* wchan */ case 35: /* nswap */ case 36: /* cnswap */ case 37: /* exit_signal */ case 38: /* processor */ default: break; } } while (strsep(&token, " ") != NULL); /* Must be the parent process in order to probe registers and floating point registers; and the status of target process must be 'T' (aka traced) */ if ((pproc->ppid != getpid()) || (toupper(pproc->state) != 'T')) { return false; } /* Inspect process registers */ /* General purpose registers */ if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)&pproc->regs) < 0) { return false; } /* Inspect floating point registers */ /* Floating point registers */ if (ptrace(PTRACE_GETFPREGS, pid, NULL, (void *)&pproc->fpregs) < 0) { return false; } return true; }
/* ADIO_FileSysType_fncall - determines the file system type for a given file using a system-dependent function call Input Parameters: . filename - pointer to file name character array Output Parameters: . fstype - location in which to store file system type (ADIO_XXX) . error_code - location in which to store error code MPI_SUCCESS is stored in the location pointed to by error_code on success. This function is used by MPI_File_open() and MPI_File_delete() to determine file system type. Most other functions use the type which is stored when the file is opened. */ static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code) { #if defined (ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || defined (HAVE_STRUCT_STATFS) || defined (ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE) int err; #endif #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE struct statvfs vfsbuf; #endif #ifdef HAVE_STRUCT_STATFS struct statfs fsbuf; #endif #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE struct stat sbuf; #endif static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL"; /* NFS can get stuck and end up returing ESTALE "forever" */ #define MAX_ESTALE_RETRY 10000 int retry_cnt; *error_code = MPI_SUCCESS; #ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE /* rare: old solaris machines */ retry_cnt=0; do { err = statvfs(filename, &vfsbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { /* ENOENT may be returned in two cases: * 1) no directory entry for "filename" * 2) "filename" is a dangling symbolic link * * ADIO_FileSysType_parentdir tries to deal with both cases. */ if (errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = statvfs(dir, &vfsbuf); ADIOI_Free(dir); } else { *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */ if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) { *fstype = ADIO_NFS; return; } if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) { *fstype = ADIO_XFS; return; } # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATVFS APPROACH */ #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) /* common automagic fs-detection logic for any modern POSX-compliant * environment */ retry_cnt = 0; do { err = statfs(filename, &fsbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { if(errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = statfs(dir, &fsbuf); ADIOI_Free(dir); } else { *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } /* --BEGIN ERROR HANDLING-- */ if (err) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); return; } /* --END ERROR HANDLING-- */ # ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME /* uncommon: maybe only on Darwin ? */ if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) { *fstype = ADIO_NFS; return; } # endif #ifdef ROMIO_GPFS if (fsbuf.f_type == GPFS_SUPER_MAGIC) { *fstype = ADIO_GPFS; return; } #endif /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/ # ifdef NFS_SUPER_MAGIC if (fsbuf.f_type == NFS_SUPER_MAGIC) { *fstype = ADIO_NFS; return; } # endif #ifdef ROMIO_LUSTRE # ifndef LL_SUPER_MAGIC # define LL_SUPER_MAGIC 0x0BD00BD0 # endif if (fsbuf.f_type == LL_SUPER_MAGIC) { *fstype = ADIO_LUSTRE; return; } #endif # ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) { *fstype = ADIO_PANFS; return; } # endif # ifdef MOUNT_NFS if (fsbuf.f_type == MOUNT_NFS) { *fstype = ADIO_NFS; return; } # endif # ifdef MOUNT_PFS if (fsbuf.f_type == MOUNT_PFS) { *fstype = ADIO_PFS; return; } # endif # ifdef PVFS_SUPER_MAGIC if (fsbuf.f_type == PVFS_SUPER_MAGIC) { *fstype = ADIO_PVFS; return; } # endif # ifdef PVFS2_SUPER_MAGIC if (fsbuf.f_type == PVFS2_SUPER_MAGIC) { *fstype = ADIO_PVFS2; return; } # endif # ifdef XFS_SUPER_MAGIC if (fsbuf.f_type == XFS_SUPER_MAGIC) { *fstype = ADIO_XFS; return; } # endif # ifdef ROMIO_UFS /* if UFS support is enabled, default to that */ *fstype = ADIO_UFS; return; # endif /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif /* STATFS APPROACH */ #ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE /* rare: maybe old NEC SX or SGI IRIX machines */ retry_cnt = 0; do { err = stat(filename, &sbuf); } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY); if (err) { if(errno == ENOENT) { char *dir; ADIO_FileSysType_parentdir(filename, &dir); err = stat(dir, &sbuf); ADIOI_Free(dir); } else{ *error_code = ADIOI_Err_create_code(myname, filename, errno); if(*error_code != MPI_SUCCESS) return; } } if (err) { /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ return; } else { if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS; else *fstype = ADIO_SFS; /* assuming SX4 for now */ } #endif /* STAT APPROACH */ #ifdef ROMIO_NTFS ADIOI_UNREFERENCED_ARG(filename); ADIOI_UNREFERENCED_ARG(error_code); *fstype = ADIO_NTFS; /* only supported FS on Windows */ #elif defined(ROMIO_NFS) *fstype = ADIO_NFS; #elif defined(ROMIO_UFS) *fstype = ADIO_UFS; #else /* --BEGIN ERROR HANDLING-- */ *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_NO_SUCH_FILE, "**filename", "**filename %s", filename); /* --END ERROR HANDLING-- */ #endif }
int nandroid_backup(const char* backup_path) { ui_set_background(BACKGROUND_ICON_INSTALLING); if (ensure_path_mounted("/sdcard") != 0) return print_and_error("Can't mount /sdcard\n"); int ret; struct statfs s; if (0 != (ret = statfs("/sdcard", &s))) return print_and_error("Unable to stat /sdcard\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("There may not be enough free space to complete backup... continuing...\n"); char tmp[PATH_MAX]; sprintf(tmp, "mkdir -p %s", backup_path); __system(tmp); if (0 != (ret = nandroid_backup_partition(backup_path, "/boot"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return ret; Volume *vol = volume_for_path("/wimax"); if (vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; ui_print("Backing up WiMAX...\n"); serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); ret = backup_raw_partition(vol->fs_type, vol->device, tmp); if (0 != ret) return print_and_error("Error while dumping WiMAX image!\n"); } if (0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return ret; } if (0 != stat("/sdcard/.android_secure", &s)) { ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n"); } else { if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; } if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return ret; #ifdef RECOVERY_HAVE_SD_EXT vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->device, &s)) { ui_print("No sd-ext found. Skipping backup of sd-ext.\n"); } else { if (0 != ensure_path_mounted("/sd-ext")) ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; } #endif ui_print("Generating md5 sum...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("Error while generating md5 sum!\n"); return ret; } sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\nBackup complete!\n"); return 0; }
struct mount_entry * read_file_system_list (bool need_fs_type) { struct mount_entry *mount_list; struct mount_entry *me; struct mount_entry **mtail = &mount_list; #ifdef MOUNTED_LISTMNTENT { struct tabmntent *mntlist, *p; struct mntent *mnt; struct mount_entry *me; /* the third and fourth arguments could be used to filter mounts, but Crays doesn't seem to have any mounts that we want to remove. Specifically, automount create normal NFS mounts. */ if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0) return NULL; for (p = mntlist; p; p = p->next) { mnt = p->ment; me = xmalloc (sizeof *me); me->me_devname = xstrdup (mnt->mnt_fsname); me->me_mountdir = xstrdup (mnt->mnt_dir); me->me_type = xstrdup (mnt->mnt_type); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = -1; *mtail = me; mtail = &me->me_next; } freemntlist (mntlist); } #endif #ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ { struct mntent *mnt; char *table = MOUNTED; FILE *fp; fp = setmntent (table, "r"); if (fp == NULL) return NULL; while ((mnt = getmntent (fp))) { me = malloc (sizeof *me); me->me_devname = strdup (mnt->mnt_fsname); me->me_mountdir = strdup (mnt->mnt_dir); me->me_type = strdup (mnt->mnt_type); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = dev_from_mount_options (mnt->mnt_opts); /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } if (endmntent (fp) == 0) goto free_then_fail; } #endif /* MOUNTED_GETMNTENT1. */ #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */ { struct statfs *fsp; int entries; entries = getmntinfo (&fsp, MNT_NOWAIT); if (entries < 0) return NULL; for (; entries-- > 0; fsp++) { me = malloc (sizeof *me); me->me_devname = strdup (fsp->f_mntfromname); me->me_mountdir = strdup (fsp->f_mntonname); #if defined(__macosx__) me->me_type = fsp->f_fstypename; #else me->me_type = fsp->fs_typename; #endif me->me_type_malloced = 0; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } } #endif /* MOUNTED_GETMNTINFO */ #ifdef MOUNTED_GETMNTINFO2 /* NetBSD 3.0. */ { struct statvfs *fsp; int entries; entries = getmntinfo (&fsp, MNT_NOWAIT); if (entries < 0) return NULL; for (; entries-- > 0; fsp++) { me = xmalloc (sizeof *me); me->me_devname = xstrdup (fsp->f_mntfromname); me->me_mountdir = xstrdup (fsp->f_mntonname); me->me_type = xstrdup (fsp->f_fstypename); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } } #endif /* MOUNTED_GETMNTINFO2 */ #ifdef MOUNTED_GETMNT /* Ultrix. */ { int offset = 0; int val; struct fs_data fsd; while (errno = 0, 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, (char *) 0))) { me = xmalloc (sizeof *me); me->me_devname = xstrdup (fsd.fd_req.devname); me->me_mountdir = xstrdup (fsd.fd_req.path); me->me_type = gt_names[fsd.fd_req.fstype]; me->me_type_malloced = 0; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = fsd.fd_req.dev; /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } if (val < 0) goto free_then_fail; } #endif /* MOUNTED_GETMNT. */ #if defined MOUNTED_FS_STAT_DEV /* BeOS */ { /* The next_dev() and fs_stat_dev() system calls give the list of all file systems, including the information returned by statvfs() (fs type, total blocks, free blocks etc.), but without the mount point. But on BeOS all file systems except / are mounted in the rootfs, directly under /. The directory name of the mount point is often, but not always, identical to the volume name of the device. We therefore get the list of subdirectories of /, and the list of all file systems, and match the two lists. */ DIR *dirp; struct rootdir_entry { char *name; dev_t dev; ino_t ino; struct rootdir_entry *next; }; struct rootdir_entry *rootdir_list; struct rootdir_entry **rootdir_tail; int32 pos; dev_t dev; fs_info fi; /* All volumes are mounted in the rootfs, directly under /. */ rootdir_list = NULL; rootdir_tail = &rootdir_list; dirp = opendir ("/"); if (dirp) { struct dirent *d; while ((d = readdir (dirp)) != NULL) { char *name; struct stat statbuf; if (strcmp (d->d_name, "..") == 0) continue; if (strcmp (d->d_name, ".") == 0) name = strdup ("/"); else { name = malloc (1 + strlen (d->d_name) + 1); name[0] = '/'; strcpy (name + 1, d->d_name); } if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) { struct rootdir_entry *re = malloc (sizeof *re); re->name = name; re->dev = statbuf.st_dev; re->ino = statbuf.st_ino; /* Add to the linked list. */ *rootdir_tail = re; rootdir_tail = &re->next; } else free (name); } closedir (dirp); } *rootdir_tail = NULL; for (pos = 0; (dev = next_dev (&pos)) >= 0; ) if (fs_stat_dev (dev, &fi) >= 0) { /* Note: fi.dev == dev. */ struct rootdir_entry *re; for (re = rootdir_list; re; re = re->next) if (re->dev == fi.dev && re->ino == fi.root) break; me = malloc (sizeof *me); me->me_devname = strdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); me->me_mountdir = strdup (re != NULL ? re->name : fi.fsh_name); me->me_type = strdup (fi.fsh_name); me->me_type_malloced = 1; me->me_dev = fi.dev; me->me_dummy = 0; me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0; /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } *mtail = NULL; while (rootdir_list != NULL) { struct rootdir_entry *re = rootdir_list; rootdir_list = re->next; free (re->name); free (re); } } #endif /* MOUNTED_FS_STAT_DEV */ #if defined MOUNTED_GETFSSTAT /* __alpha running OSF_1 */ { int numsys, counter; size_t bufsize; struct statfs *stats; numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT); if (numsys < 0) return (NULL); if (SIZE_MAX / sizeof *stats <= numsys) xalloc_die (); bufsize = (1 + numsys) * sizeof *stats; stats = xmalloc (bufsize); numsys = getfsstat (stats, bufsize, MNT_NOWAIT); if (numsys < 0) { free (stats); return (NULL); } for (counter = 0; counter < numsys; counter++) { me = xmalloc (sizeof *me); me->me_devname = xstrdup (stats[counter].f_mntfromname); me->me_mountdir = xstrdup (stats[counter].f_mntonname); me->me_type = xstrdup (FS_TYPE (stats[counter])); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } free (stats); } #endif /* MOUNTED_GETFSSTAT */ #if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23]. */ { struct mnttab mnt; char *table = "/etc/mnttab"; FILE *fp; fp = fopen (table, "r"); if (fp == NULL) return NULL; while (fread (&mnt, sizeof mnt, 1, fp) > 0) { me = xmalloc (sizeof *me); # ifdef GETFSTYP /* SVR3. */ me->me_devname = xstrdup (mnt.mt_dev); # else me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6); strcpy (me->me_devname, "/dev/"); strcpy (me->me_devname + 5, mnt.mt_dev); # endif me->me_mountdir = xstrdup (mnt.mt_filsys); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ me->me_type = ""; me->me_type_malloced = 0; # ifdef GETFSTYP /* SVR3. */ if (need_fs_type) { struct statfs fsd; char typebuf[FSTYPSZ]; if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) { me->me_type = xstrdup (typebuf); me->me_type_malloced = 1; } } # endif me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } if (ferror (fp)) { /* The last fread() call must have failed. */ int saved_errno = errno; fclose (fp); errno = saved_errno; goto free_then_fail; } if (fclose (fp) == EOF) goto free_then_fail; } #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */ #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes its own way. */ { struct mntent **mnttbl = getmnttbl (), **ent; for (ent=mnttbl;*ent;ent++) { me = xmalloc (sizeof *me); me->me_devname = xstrdup ( (*ent)->mt_resource); me->me_mountdir = xstrdup ( (*ent)->mt_directory); me->me_type = xstrdup ((*ent)->mt_fstype); me->me_type_malloced = 1; me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } endmnttbl (); } #endif #ifdef MOUNTED_GETMNTENT2 /* SVR4. */ { struct mnttab mnt; char *table = MNTTAB; FILE *fp; int ret; int lockfd = -1; # if defined F_RDLCK && defined F_SETLKW /* MNTTAB_LOCK is a macro name of our own invention; it's not present in e.g. Solaris 2.6. If the SVR4 folks ever define a macro for this file name, we should use their macro name instead. (Why not just lock MNTTAB directly? We don't know.) */ # ifndef MNTTAB_LOCK # define MNTTAB_LOCK "/etc/.mnttab.lock" # endif lockfd = open (MNTTAB_LOCK, O_RDONLY); if (0 <= lockfd) { struct flock flock; flock.l_type = F_RDLCK; flock.l_whence = SEEK_SET; flock.l_start = 0; flock.l_len = 0; while (fcntl (lockfd, F_SETLKW, &flock) == -1) if (errno != EINTR) { int saved_errno = errno; close (lockfd); errno = saved_errno; return NULL; } } else if (errno != ENOENT) return NULL; # endif errno = 0; fp = fopen (table, "r"); if (fp == NULL) ret = errno; else { while ((ret = getmntent (fp, &mnt)) == 0) { me = xmalloc (sizeof *me); me->me_devname = xstrdup (mnt.mnt_special); me->me_mountdir = xstrdup (mnt.mnt_mountp); me->me_type = xstrdup (mnt.mnt_fstype); me->me_type_malloced = 1; me->me_dummy = MNT_IGNORE (&mnt) != 0; me->me_remote = ME_REMOTE (me->me_devname, me->me_type); me->me_dev = dev_from_mount_options (mnt.mnt_mntopts); /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1; } if (0 <= lockfd && close (lockfd) != 0) ret = errno; if (0 <= ret) { errno = ret; goto free_then_fail; } } #endif /* MOUNTED_GETMNTENT2. */ #ifdef MOUNTED_VMOUNT /* AIX. */ { int bufsize; char *entries, *thisent; struct vmount *vmp; int n_entries; int i; /* Ask how many bytes to allocate for the mounted file system info. */ if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0) return NULL; entries = xmalloc (bufsize); /* Get the list of mounted file systems. */ n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); if (n_entries < 0) { int saved_errno = errno; free (entries); errno = saved_errno; return NULL; } for (i = 0, thisent = entries; i < n_entries; i++, thisent += vmp->vmt_length) { char *options, *ignore; vmp = (struct vmount *) thisent; me = xmalloc (sizeof *me); if (vmp->vmt_flags & MNT_REMOTE) { char *host, *dir; me->me_remote = 1; /* Prepend the remote dirname. */ host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off; dir = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; me->me_devname = xmalloc (strlen (host) + strlen (dir) + 2); strcpy (me->me_devname, host); strcat (me->me_devname, ":"); strcat (me->me_devname, dir); } else { me->me_remote = 0; me->me_devname = xstrdup (thisent + vmp->vmt_data[VMT_OBJECT].vmt_off); } me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype)); me->me_type_malloced = 1; options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; ignore = strstr (options, "ignore"); me->me_dummy = (ignore && (ignore == options || ignore[-1] == ',') && (ignore[sizeof "ignore" - 1] == ',' || ignore[sizeof "ignore" - 1] == '\0')); me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */ /* Add to the linked list. */ *mtail = me; mtail = &me->me_next; } free (entries); } #endif /* MOUNTED_VMOUNT. */ *mtail = NULL; return mount_list; free_then_fail: { int saved_errno = errno; *mtail = NULL; while (mount_list) { me = mount_list->me_next; free (mount_list->me_devname); free (mount_list->me_mountdir); if (mount_list->me_type_malloced) free (mount_list->me_type); free (mount_list); mount_list = me; } errno = saved_errno; return NULL; } }
/* * get_tmp_disk - Return the total size of temporary file system on * this system * Input: tmp_disk - buffer for the disk space size * tmp_fs - pathname of the temporary file system to status, * defaults to "/tmp" * Output: tmp_disk - filled in with disk space size in MB, zero if error * return code - 0 if no error, otherwise errno */ extern int get_tmp_disk(uint32_t *tmp_disk, char *tmp_fs) { int error_code = 0; #if defined(HAVE_STATVFS) struct statvfs stat_buf; uint64_t total_size = 0; char *tmp_fs_name = tmp_fs; *tmp_disk = 0; total_size = 0; if (tmp_fs_name == NULL) tmp_fs_name = "/tmp"; if (statvfs(tmp_fs_name, &stat_buf) == 0) { total_size = stat_buf.f_blocks * stat_buf.f_frsize; total_size /= 1024 * 1024; } else if (errno != ENOENT) { error_code = errno; error ("get_tmp_disk: error %d executing statvfs on %s", errno, tmp_fs_name); } *tmp_disk += (uint32_t)total_size; #elif defined(HAVE_STATFS) struct statfs stat_buf; long total_size; float page_size; char *tmp_fs_name = tmp_fs; *tmp_disk = 0; total_size = 0; page_size = (sysconf(_SC_PAGE_SIZE) / 1048576.0); /* MG per page */ if (tmp_fs_name == NULL) tmp_fs_name = "/tmp"; #if defined (__sun) if (statfs(tmp_fs_name, &stat_buf, 0, 0) == 0) { #else if (statfs(tmp_fs_name, &stat_buf) == 0) { #endif total_size = (long)stat_buf.f_blocks; } else if (errno != ENOENT) { error_code = errno; error ("get_tmp_disk: error %d executing statfs on %s", errno, tmp_fs_name); } *tmp_disk += (uint32_t)(total_size * page_size); #else *tmp_disk = 1; #endif return error_code; } extern int get_up_time(uint32_t *up_time) { #if defined(HAVE_AIX) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__) clock_t tm; struct tms buf; tm = times(&buf); if (tm == (clock_t) -1) { *up_time = 0; return errno; } *up_time = tm / sysconf(_SC_CLK_TCK); #elif defined(__CYGWIN__) FILE *uptime_file; char buffer[128]; char* _uptime_path = "/proc/uptime"; if (!(uptime_file = fopen(_uptime_path, "r"))) { error("get_up_time: error %d opening %s", errno, _uptime_path); return errno; } if (fgets(buffer, sizeof(buffer), uptime_file)) *up_time = atoi(buffer); fclose(uptime_file); #else /* NOTE for Linux: The return value of times() may overflow the * possible range of type clock_t. There is also an offset of * 429 million seconds on some implementations. We just use the * simpler sysinfo() function instead. */ struct sysinfo info; if (sysinfo(&info) < 0) { *up_time = 0; return errno; } if (conf->boot_time) { /* Make node look like it rebooted when slurmd started */ static uint32_t orig_uptime = 0; if (orig_uptime == 0) orig_uptime = info.uptime; *up_time = info.uptime - orig_uptime; } else { *up_time = info.uptime; } #endif return 0; }
static void init_selinuxmnt(void) { char *buf=NULL, *p; FILE *fp=NULL; struct statfs sfbuf; int rc; size_t len; ssize_t num; int exists = 0; if (selinux_mnt) return; /* We check to see if the preferred mount point for selinux file * system has a selinuxfs. */ do { rc = statfs(SELINUXMNT, &sfbuf); } while (rc < 0 && errno == EINTR); if (rc == 0) { if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) { selinux_mnt = strdup(SELINUXMNT); return; } } /* Drop back to detecting it the long way. */ fp = fopen("/proc/filesystems", "r"); if (!fp) return; __fsetlocking(fp, FSETLOCKING_BYCALLER); while ((num = getline(&buf, &len, fp)) != -1) { if (strstr(buf, "selinuxfs")) { exists = 1; break; } } if (!exists) goto out; fclose(fp); /* At this point, the usual spot doesn't have an selinuxfs so * we look around for it */ fp = fopen("/proc/mounts", "r"); if (!fp) goto out; __fsetlocking(fp, FSETLOCKING_BYCALLER); while ((num = getline(&buf, &len, fp)) != -1) { char *tmp; p = strchr(buf, ' '); if (!p) goto out; p++; tmp = strchr(p, ' '); if (!tmp) goto out; if (!strncmp(tmp + 1, "selinuxfs ", 10)) { *tmp = '\0'; break; } } /* If we found something, dup it */ if (num > 0) selinux_mnt = strdup(p); out: free(buf); if (fp) fclose(fp); return; }
int nandroid_backup(const char* backup_path) { nandroid_backup_bitfield = 0; ui_set_background(BACKGROUND_ICON_INSTALLING); refresh_default_backup_handler(); if (ensure_path_mounted(backup_path) != 0) { return print_and_error("无法挂载备份时需要的存储器.\n"); } Volume* volume = volume_for_path(backup_path); if (NULL == volume) return print_and_error("找不到备份需要的存储器.\n"); if (is_data_media_volume_path(volume->mount_point)) volume = volume_for_path("/data"); int ret; struct statfs s; if (NULL != volume) { if (0 != (ret = statfs(volume->mount_point, &s))) return print_and_error("找不到备份路径,因此无法开始.\n"); uint64_t bavail = s.f_bavail; uint64_t bsize = s.f_bsize; uint64_t sdcard_free = bavail * bsize; uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024); ui_print("SD Card space free: %lluMB\n", sdcard_free_mb); if (sdcard_free_mb < 150) ui_print("可能是你的机器空间不足了,继续中...\n"); } char tmp[PATH_MAX]; ensure_directory(backup_path); if (0 != (ret = nandroid_backup_partition(backup_path, "/boot"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/uboot"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery"))) return ret; Volume *vol = volume_for_path("/wimax"); if (vol != NULL && 0 == stat(vol->device, &s)) { char serialno[PROPERTY_VALUE_MAX]; ui_print("正在备份WiMAX...\n"); serialno[0] = 0; property_get("ro.serialno", serialno, ""); sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno); ret = backup_raw_partition(vol->fs_type, vol->device, tmp); if (0 != ret) return print_and_error("打包或生成WiMAX镜像失败\n"); } if (0 != (ret = nandroid_backup_partition(backup_path, "/system"))) return ret; if (0 != (ret = nandroid_backup_partition(backup_path, "/data"))) return ret; if (has_datadata()) { if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata"))) return ret; } if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) { ui_print("没找到 /sdcard/.android_secure. 跳过外部程序备份.\n"); } else { if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0))) return ret; } if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0))) return ret; vol = volume_for_path("/sd-ext"); if (vol == NULL || 0 != stat(vol->device, &s)) { ui_print("没找到SD-EXT,因此跳过该处备份.\n"); } else { if (0 != ensure_path_mounted("/sd-ext")) ui_print("没法挂载SD-EXT,可能是你的机器不支持该选项,跳过该部分的备份\n"); else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext"))) return ret; } ui_print("生成md5 校验值...\n"); sprintf(tmp, "nandroid-md5.sh %s", backup_path); if (0 != (ret = __system(tmp))) { ui_print("MD5校验值生成失败\n"); return ret; } sprintf(tmp, "cp /tmp/recovery.log %s/recovery.log", backup_path); __system(tmp); sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path); __system(tmp); sync(); ui_set_background(BACKGROUND_ICON_NONE); ui_reset_progress(); ui_print("\n备份完成!\n"); return 0; }
inline int getAccess(int accType, struct stat *buffer, char *p_path) { struct statfs fsbuffer; int idType; if(! buffer) return BTA_FS_CO_FAIL; //idType= (buffer->st_uid== BT_UID) ? 1 : (buffer->st_uid== BT_GID) ? 2 : 3; if(buffer->st_uid == BT_UID) idType = 1; else if(buffer->st_gid == BT_GID || buffer->st_gid == AID_SYSTEM || buffer->st_gid == AID_MISC || buffer->st_gid == AID_SDCARD_RW) idType = 2; else idType = 3; if(statfs(p_path, &fsbuffer)==0) { if(fsbuffer.f_type == FAT_FS) return BTA_FS_CO_OK; } else { return BTA_FS_CO_FAIL; } switch(accType) { case 4: if(idType== 1) { //Id is User Id if(buffer-> st_mode & S_IRUSR) return BTA_FS_CO_OK; } else if(idType==2) { //Id is Group Id if(buffer-> st_mode & S_IRGRP) return BTA_FS_CO_OK; } else { //Id is Others if(buffer-> st_mode & S_IROTH) return BTA_FS_CO_OK; } break; case 6: if(idType== 1) { //Id is User Id if((buffer-> st_mode & S_IRUSR) && (buffer-> st_mode & S_IWUSR)) return BTA_FS_CO_OK; } else if(idType==2) { //Id is Group Id if((buffer-> st_mode & S_IRGRP) && (buffer-> st_mode & S_IWGRP)) return BTA_FS_CO_OK; } else { //Id is Others if((buffer-> st_mode & S_IROTH) && (buffer-> st_mode & S_IWOTH)) return BTA_FS_CO_OK; } break; default: return BTA_FS_CO_OK; } BTIF_TRACE_DEBUG("*************FTP- Access Failed **********"); return BTA_FS_CO_EACCES; }
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) { int ret = 0; char* name = basename(mount_point); nandroid_restore_handler restore_handler = NULL; const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "rfs", NULL }; const char* backup_filesystem = NULL; Volume *vol = volume_for_path(mount_point); const char *device = NULL; if (vol != NULL) device = vol->device; char tmp[PATH_MAX]; sprintf(tmp, "%s/%s.img", backup_path, name); struct stat file_info; if (strcmp(backup_path, "-") == 0) { if (vol) backup_filesystem = vol->fs_type; restore_handler = tar_extract_wrapper; strcpy(tmp, "/proc/self/fd/0"); } else if (0 != (ret = statfs(tmp, &file_info))) { // can't find the backup, it may be the new backup format? // iterate through the backup types printf("找不到默认\n"); char *filesystem; int i = 0; while ((filesystem = filesystems[i]) != NULL) { sprintf(tmp, "%s/%s.%s.img", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = unyaffs_wrapper; break; } sprintf(tmp, "%s/%s.%s.tar", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = tar_extract_wrapper; break; } sprintf(tmp, "%s/%s.%s.dup", backup_path, name, filesystem); if (0 == (ret = statfs(tmp, &file_info))) { backup_filesystem = filesystem; restore_handler = dedupe_extract_wrapper; break; } i++; } if (backup_filesystem == NULL || restore_handler == NULL) { ui_print("%s.镜像没找到,因此跳过该处恢复. %s.\n", name, mount_point); return 0; } else { printf("找到新的可恢复镜像: %s\n", tmp); } } // If the fs_type of this volume is "auto" or mount_point is /data // and is_data_media, let's revert // to using a rm -rf, rather than trying to do a // ext3/ext4/whatever format. // This is because some phones (like DroidX) will freak out if you // reformat the /system or /data partitions, and not boot due to // a locked bootloader. // Other devices, like the Galaxy Nexus, XOOM, and Galaxy Tab 10.1 // have a /sdcard symlinked to /data/media. // Or of volume does not exist (.android_secure), just rm -rf. if (vol == NULL || 0 == strcmp(vol->fs_type, "auto")) backup_filesystem = NULL; if (0 == strcmp(vol->mount_point, "/data") && is_data_media()) backup_filesystem = NULL; ensure_directory(mount_point); int callback = stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info) != 0; ui_print("正在恢复 %s...\n", name); if (backup_filesystem == NULL) { if (0 != (ret = format_volume(mount_point))) { ui_print("格式化下列分区失败 %s!\n", mount_point); return ret; } } else if (0 != (ret = format_device(device, mount_point, backup_filesystem))) { ui_print("格式化下列分区失败 %s!\n", mount_point); return ret; } if (0 != (ret = ensure_path_mounted(mount_point))) { ui_print("挂载下列分区失败 %s!\n", mount_point); return ret; } if (restore_handler == NULL) restore_handler = get_restore_handler(mount_point); // override restore handler for undump if (strcmp(backup_path, "-") == 0) { restore_handler = tar_undump_wrapper; } if (restore_handler == NULL) { ui_print("找不到合适的方案\n"); return -2; } if (0 != (ret = restore_handler(tmp, mount_point, callback))) { ui_print("恢复失败: %s!\n", mount_point); return ret; } if (umount_when_finished) { ensure_path_unmounted(mount_point); } return 0; }
int eDVBServiceRecord::doRecord() { int err = doPrepare(); if (err) { m_error = errTuneFailed; m_event((iRecordableService*)this, evRecordFailed); return err; } if (!m_tuned) return 0; /* try it again when we are tuned in */ if (!m_record && m_tuned && !m_streaming && !m_simulate) { #if defined(__sh__) int flags = O_WRONLY|O_CREAT|O_LARGEFILE; struct statfs sbuf; #endif eDebug("Recording to %s...", m_filename.c_str()); ::remove(m_filename.c_str()); #if defined(__sh__) //nit2005, we must creat a file for statfs int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644); ::close(fd); if (statfs(m_filename.c_str(), &sbuf) < 0) { eDebug("eDVBServiceRecord - can't get fs type assuming none NFS!"); } else { if (sbuf.f_type == EXT3_SUPER_MAGIC) eDebug("eDVBServiceRecord - Ext2/3/4 Filesystem\n"); else if (sbuf.f_type == NFS_SUPER_MAGIC) { eDebug("eDVBServiceRecord - NFS Filesystem; add O_DIRECT to flags\n"); flags |= O_DIRECT; } else if (sbuf.f_type == USBDEVICE_SUPER_MAGIC) eDebug("eDVBServiceRecord - USB Device\n"); else if (sbuf.f_type == SMB_SUPER_MAGIC) eDebug("eDVBServiceRecord - SMBs Device\n"); else if (sbuf.f_type == MSDOS_SUPER_MAGIC) eDebug("eDVBServiceRecord - MSDOS Device\n"); } fd = ::open(m_filename.c_str(), flags, 0644); #else int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644); #endif if (fd == -1) { eDebug("eDVBServiceRecord - can't open recording file!"); m_error = errOpenRecordFile; m_event((iRecordableService*)this, evRecordFailed); return errOpenRecordFile; } /* turn off kernel caching strategies */ posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM); ePtr<iDVBDemux> demux; if (m_service_handler.getDataDemux(demux)) { eDebug("eDVBServiceRecord - NO DEMUX available!"); m_error = errNoDemuxAvailable; m_event((iRecordableService*)this, evRecordFailed); return errNoDemuxAvailable; } demux->createTSRecorder(m_record); if (!m_record) { eDebug("eDVBServiceRecord - no ts recorder available."); m_error = errNoTsRecorderAvailable; m_event((iRecordableService*)this, evRecordFailed); return errNoTsRecorderAvailable; } m_record->setTargetFD(fd); m_record->setTargetFilename(m_filename.c_str()); m_record->connectEvent(slot(*this, &eDVBServiceRecord::recordEvent), m_con_record_event); m_target_fd = fd; } if (m_streaming) { m_state = stateRecording; eDebug("start streaming..."); } else { eDebug("start recording..."); eDVBServicePMTHandler::program program; if (m_service_handler.getProgramInfo(program)) eDebug("getting program info failed."); else { std::set<int> pids_to_record; pids_to_record.insert(0); // PAT if (program.pmtPid != -1) pids_to_record.insert(program.pmtPid); // PMT int timing_pid = -1, timing_pid_type = -1; eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size()); if (!program.videoStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator i(program.videoStreams.begin()); i != program.videoStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_pid_type = i->type; } if (i != program.videoStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size()); if (!program.audioStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator i(program.audioStreams.begin()); i != program.audioStreams.end(); ++i) { pids_to_record.insert(i->pid); if (timing_pid == -1) { timing_pid = i->pid; timing_pid_type = -1; } if (i != program.audioStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } if (!program.subtitleStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator i(program.subtitleStreams.begin()); i != program.subtitleStreams.end(); ++i) { pids_to_record.insert(i->pid); if (i != program.subtitleStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid); if (program.pcrPid != 0x1fff) pids_to_record.insert(program.pcrPid); eDebug(", and the text pid is %04x", program.textPid); if (program.textPid != -1) pids_to_record.insert(program.textPid); // Videotext /* find out which pids are NEW and which pids are obsolete.. */ std::set<int> new_pids, obsolete_pids; std::set_difference(pids_to_record.begin(), pids_to_record.end(), m_pids_active.begin(), m_pids_active.end(), std::inserter(new_pids, new_pids.begin())); std::set_difference( m_pids_active.begin(), m_pids_active.end(), pids_to_record.begin(), pids_to_record.end(), std::inserter(obsolete_pids, obsolete_pids.begin()) ); for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i) { eDebug("ADD PID: %04x", *i); m_record->addPID(*i); } for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i) { eDebug("REMOVED PID: %04x", *i); m_record->removePID(*i); } if (timing_pid != -1) m_record->setTimingPID(timing_pid, timing_pid_type); m_pids_active = pids_to_record; if (m_state != stateRecording) { m_record->start(); m_state = stateRecording; } } } m_error = 0; m_event((iRecordableService*)this, evRecordRunning); return 0; }
int run_attr_tests (char *testfile) { int ret = -1; char *res = NULL; struct stat buf; struct statfs sbuf; struct statvfs svbuf; assert (testfile); fprintf (stdout, "Testing chmod"); ret = chmod (testfile, 0); check_err (ret, "chmod", 2); fprintf (stdout, "Testing chown"); ret = chown (testfile, 0, 0); check_err (ret, "chown", 2); fprintf (stdout, "Testing link"); ret = link (testfile, testfile); check_err (ret, "link", 2); fprintf (stdout, "Testing rename"); ret = rename (testfile, testfile); check_err (ret, "rename", 2); fprintf (stdout, "Testing utimes"); ret = utimes (testfile, NULL); check_err (ret, "utimes", 2); fprintf (stdout, "Testing utime"); ret = utime (testfile, NULL); check_err (ret, "utime", 2); fprintf (stdout, "Testing unlink"); ret = unlink (testfile); check_err (ret, "unlink", 2); fprintf (stdout, "Testing symlink"); ret = symlink (testfile, testfile); check_err (ret, "symlink", 2); fprintf (stdout, "Testing readlink"); ret = readlink (testfile, testfile, 0); check_err (ret, "readlink", 2); fprintf (stdout, "Testing realpath"); ret = 0; res = realpath ((const char *)testfile, testfile); if (!res) ret = -1; check_err (ret, "realpath", 2); fprintf (stdout, "Testing stat"); ret = stat (testfile, &buf); check_err (ret, "stat", 1); fprintf (stdout, "Testing lstat"); ret = lstat (testfile, &buf); check_err (ret, "lstat", 1); fprintf (stdout, "Testing statfs"); ret = statfs (testfile, &sbuf); check_err (ret, "statfs", 2); fprintf (stdout, "Testing statvfs"); ret = statvfs (testfile, &svbuf); check_err (ret, "statvfs", 1); fprintf (stdout, "Testing getxattr"); ret = getxattr (testfile, NULL, NULL, 0); check_err (ret, "getxattr", 2); fprintf (stdout, "Testing lgetxattr"); ret = lgetxattr (testfile, NULL, NULL, 0); check_err (ret, "lgetxattr", 1); fprintf (stdout, "Testing lchown"); ret = lchown (testfile, 0, 0); check_err (ret, "lchown", 2); return 0; }
bool proc_probe(pid_t pid, int opt, proc_t * const pproc) { FUNC_BEGIN("proc_probe(%d,%d,%p)", pid, opt, pproc); assert(pproc); /* Validating procfs */ struct statfs sb; if ((statfs(PROCFS, &sb) < 0) || (sb.f_type != PROC_SUPER_MAGIC)) { WARNING("procfs missing or invalid"); FUNC_RET(false, "proc_probe()"); } /* Validating process stat */ char buffer[4096]; sprintf(buffer, PROCFS "/%d/stat", pid); if (access(buffer, R_OK | F_OK) < 0) { WARNING("procfs entries missing or invalid"); FUNC_RET(false, "proc_probe()"); } /* Grab stat information in one read */ int fd = open(buffer, O_RDONLY); int len = read(fd, buffer, sizeof(buffer) - 1); close(fd); buffer[len] = '\0'; /* Extract interested information */ int offset = 0; char * token = buffer; do { switch (offset++) { case 0: /* pid */ sscanf(token, "%d", &pproc->pid); break; case 1: /* comm */ break; case 2: /* state */ sscanf(token, "%c", &pproc->state); break; case 3: /* ppid */ sscanf(token, "%d", &pproc->ppid); break; case 4: /* pgrp */ case 5: /* session */ case 6: /* tty_nr */ case 7: /* tty_pgrp */ break; case 8: /* flags */ sscanf(token, "%lu", &pproc->flags); break; case 9: /* min_flt */ case 10: /* cmin_flt */ case 11: /* maj_flt */ case 12: /* cmaj_flt */ break; case 13: /* utime */ sscanf(token, "%lu", &pproc->tm.tms_utime); break; case 14: /* stime */ sscanf(token, "%lu", &pproc->tm.tms_stime); break; case 15: /* cutime */ sscanf(token, "%ld", &pproc->tm.tms_cutime); break; case 16: /* cstime */ sscanf(token, "%ld", &pproc->tm.tms_cstime); break; case 17: /* priority */ case 18: /* nice */ case 19: /* 0 */ case 20: /* it_real_value */ case 21: /* start_time */ break; case 22: /* vsize */ sscanf(token, "%lu", &pproc->vsize); break; case 23: /* rss */ sscanf(token, "%ld", &pproc->rss); break; case 24: /* rlim_rss */ case 25: /* start_code */ case 26: /* end_code */ case 27: /* start_stack */ case 28: /* esp */ case 29: /* eip */ case 30: /* pending_signal */ case 31: /* blocked_signal */ case 32: /* sigign */ case 33: /* sigcatch */ case 34: /* wchan */ case 35: /* nswap */ case 36: /* cnswap */ case 37: /* exit_signal */ case 38: /* processor */ default: break; } } while (strsep(&token, " ") != NULL); DBG("proc.pid % 10d", pproc->pid); DBG("proc.ppid % 10d", pproc->ppid); DBG("proc.state %c", pproc->state); DBG("proc.flags 0x%08lx", pproc->flags); DBG("proc.utime %010lu", pproc->tm.tms_utime); DBG("proc.stime %010lu", pproc->tm.tms_stime); DBG("proc.cutime % 10ld", pproc->tm.tms_cutime); DBG("proc.cstime % 10ld", pproc->tm.tms_cstime); DBG("proc.vsize %010lu", pproc->vsize); DBG("proc.rss % 10ld", pproc->rss); /* Must be the parent process in order to probe registers and floating point registers; and the status of target process must be 'T' (aka traced) */ if ((pproc->ppid != getpid()) || (pproc->state != 'T')) { FUNC_RET((opt == PROBE_STAT), "proc_probe()"); } /* Inspect process registers */ #ifdef __linux__ if (opt & PROBE_REGS) { /* General purpose registers */ if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)&pproc->regs) < 0) { WARNING("ptrace:PTRACE_GETREGS"); FUNC_RET(false, "proc_probe()"); } DBG("regs.ebx 0x%08lx", pproc->regs.ebx); DBG("regs.ecx 0x%08lx", pproc->regs.ecx); DBG("regs.edx 0x%08lx", pproc->regs.edx); DBG("regs.esi 0x%08lx", pproc->regs.esi); DBG("regs.edi 0x%08lx", pproc->regs.edi); DBG("regs.ebp 0x%08lx", pproc->regs.ebp); DBG("regs.eax 0x%08lx", pproc->regs.eax); DBG("regs.xds 0x%08lx", pproc->regs.xds); DBG("regs.xes 0x%08lx", pproc->regs.xes); DBG("regs.xfs 0x%08lx", pproc->regs.xfs); DBG("regs.xgs 0x%08lx", pproc->regs.xgs); DBG("regs.orig_eax 0x%08lx", pproc->regs.orig_eax); DBG("regs.eip 0x%08lx", pproc->regs.eip); DBG("regs.xcs 0x%08lx", pproc->regs.xcs); DBG("regs.eflags 0x%08lx", pproc->regs.eflags); DBG("regs.esp 0x%08lx", pproc->regs.esp); DBG("regs.xss 0x%08lx", pproc->regs.xss); /* Current instruction */ pproc->op = ptrace(PTRACE_PEEKDATA, pid, (void *)pproc->regs.eip, NULL); if (errno != 0) { WARNING("ptrace:PTRACE_PEEKDATA"); FUNC_RET(false, "proc_probe()"); } DBG("proc.op 0x%08x", pproc->op); } #endif /* __linux__ */ /* Inspect floating point registers */ #ifdef __linux__ if (opt & PROBE_FPREGS) { /* Floating point registers */ if (ptrace(PTRACE_GETFPREGS, pid, NULL, (void *)&pproc->fpregs) < 0) { WARNING("ptrace:PTRACE_GETFPREGS"); FUNC_RET(false, "proc_probe()"); } DBG("fpregs.cwd 0x%08lx", pproc->fpregs.cwd); DBG("fpregs.swd 0x%08lx", pproc->fpregs.swd); DBG("fpregs.twd 0x%08lx", pproc->fpregs.twd); DBG("fpregs.fip 0x%08lx", pproc->fpregs.fip); DBG("fpregs.fcs 0x%08lx", pproc->fpregs.fcs); DBG("fpregs.fos 0x%08lx", pproc->fpregs.fos); DBG("fpregs.st_space 0x%08lx 0x%08lx 0x%08lx 0x%08lx", pproc->fpregs.st_space[ 0], pproc->fpregs.st_space[ 1], pproc->fpregs.st_space[ 2], pproc->fpregs.st_space[ 3]); DBG(" 0x%08lx 0x%08lx 0x%08lx 0x%08lx", pproc->fpregs.st_space[ 4], pproc->fpregs.st_space[ 5], pproc->fpregs.st_space[ 6], pproc->fpregs.st_space[ 7]); DBG(" 0x%08lx 0x%08lx 0x%08lx 0x%08lx", pproc->fpregs.st_space[ 8], pproc->fpregs.st_space[ 9], pproc->fpregs.st_space[10], pproc->fpregs.st_space[11]); DBG(" 0x%08lx 0x%08lx 0x%08lx 0x%08lx", pproc->fpregs.st_space[12], pproc->fpregs.st_space[13], pproc->fpregs.st_space[14], pproc->fpregs.st_space[15]); DBG(" 0x%08lx 0x%08lx 0x%08lx 0x%08lx", pproc->fpregs.st_space[16], pproc->fpregs.st_space[17], pproc->fpregs.st_space[18], pproc->fpregs.st_space[19]); } #endif /* __linux__ */ FUNC_RET(true, "proc_probe()"); }
int convert_mtd_device(const char *root, const char* fs_list) { static char* headers[] = { "Converting Menu", "", NULL, NULL }; static char* confirm_convert = "Confirm convert?"; static char* confirm = "Yes - Convert"; const char* root_fs = get_type_internal_fs(root); headers[2] = root; typedef char* string; string tfs[NUM_FILESYSTEMS] = { "rfs", "ext4" }; static string options[NUM_FILESYSTEMS*2 + 1 + 1]; int sel_fs[NUM_FILESYSTEMS*2 + 1 + 1]; int i,j=0; // with backup for (i=0; i<NUM_FILESYSTEMS; i++) { if (fs_list[i] == '*') { if (strcmp(tfs[i], root_fs)) { sel_fs[j] = i; options[j] = (string)malloc(32); sprintf(options[j++], "to %s with backup", tfs[i]); } } else break; } options[j++] = ""; // without backup for (i=0; i<NUM_FILESYSTEMS; i++) { if (fs_list[i] == '*') { if (strcmp(tfs[i], root_fs)) { sel_fs[j] = i; options[j] = (string)malloc(32); sprintf(options[j++], "to %s through format", tfs[i]); } } else break; } options[j] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) return 1; if (chosen_item < i) { // with backup if (!confirm_selection(confirm_convert, confirm)) return 1; ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); // mount $root if (0 != ensure_root_path_mounted(root)) { ui_print("Can't mount %s for backup\n", root); return -1; } // check size of $root struct statfs stat_root; if (0 != statfs(get_mount_point_for_root(root), &stat_root)) { ui_print("Can't get size of %s\n", root); return -1; } // mount SDCARD if (0 != ensure_root_path_mounted("SDCARD:")) { ui_print("Can't mount sdcard for backup\n", root); return -1; } // check size SD struct statfs stat_sd; if (0 != statfs(get_mount_point_for_root("SDCARD:"), &stat_sd)) { ui_print("Can't get size of sdcard\n"); return -1; } uint64_t root_fsize = (uint64_t)(stat_root.f_blocks-stat_root.f_bfree)*(uint64_t)stat_root.f_bsize; uint64_t sd_free_size = (uint64_t)stat_sd.f_bfree*(uint64_t)stat_sd.f_bsize; ui_print("SD free: %lluMB / need: %lluMB\n", sd_free_size/(1024*1024), root_fsize/(1024*1024)); if (root_fsize > sd_free_size) { ui_print("Can't backup need: %lluMB on SD\n", root_fsize/(1024*1024)); return -1; } // create folder for backup [/sdcard/ebrecovery/tmp] [mkdir -p /sdcard/ebrecovery/tmp] if (0 != __system("mkdir -p /sdcard/ebrecovery/tmp")) { ui_print("Can't create tmp folder for backup\n"); return -1; } ui_show_progress(0.3, root_fsize*30/(140*1024*1024)); // backup ui_print("Backuping %s...\n", root); char br_exec[256]; sprintf(br_exec, "tar -c --exclude=*RFS_LOG.LO* -f /sdcard/ebrecovery/tmp/ctmp.tar %s", get_mount_point_for_root(root)+1); if (0 != __system(br_exec)) { ui_print("Can't create backup file\n"); return -1; } // check size of backup file > sizeof($root)? // set new FS ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]); if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) { ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root); return -1; } // format $root ui_show_progress(0.05, 10); ui_print("Formatting %s...\n", root); if (0 != format_root_device(root)) { ui_print("Error format %s\n", root); return -1; } // mount $root if (0 != ensure_root_path_mounted(root)) { ui_print("Can't mount %s for backup\n", root); return -1; } // restore $root ui_show_progress(0.65, root_fsize*500/(140*1024*1024)); ui_print("Restoring %s...\n", root); if (0 != __system("tar -x -f /sdcard/ebrecovery/tmp/ctmp.tar")) { ui_print("Can't restore backup file\n"); return -1; } // check size of $root ? // delete temp backup files (delete tmp folder) ui_show_indeterminate_progress(); if (0 != __system("rm /sdcard/ebrecovery/tmp/ctmp.tar")) { ui_print("Can't remove backup file\n"); return -1; } return 0; } else { // without if (!confirm_selection(confirm_convert, confirm)) return 1; // change file system to new ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]); if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) { ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root); return -1; } // format ui_set_background(BACKGROUND_ICON_INSTALLING); ui_show_indeterminate_progress(); ui_print("Formatting %s...\n", root); return format_root_device(root); } return -1; }