/* * skip over bit maps on the tape */ void skipmaps(void) { while (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI) skipfile(); }
/* * skip over all the directories on the tape */ void skipdirs(void) { while (curfile.dip && (curfile.dip->di_mode & IFMT) == IFDIR) { skipfile(); } }
/* * skip over all the directories on the tape */ void skipdirs(void) { while (curfile.ino && (curfile.mode & IFMT) == IFDIR) { skipfile(); } }
int extractfile(char *name) { int flags; uid_t uid; gid_t gid; mode_t mode; int extsize; struct timeval mtimep[2], ctimep[2]; struct entry *ep; char *buf; curfile.name = name; curfile.action = USING; mtimep[0].tv_sec = curfile.atime_sec; mtimep[0].tv_usec = curfile.atime_nsec / 1000; mtimep[1].tv_sec = curfile.mtime_sec; mtimep[1].tv_usec = curfile.mtime_nsec / 1000; ctimep[0].tv_sec = curfile.atime_sec; ctimep[0].tv_usec = curfile.atime_nsec / 1000; ctimep[1].tv_sec = curfile.birthtime_sec; ctimep[1].tv_usec = curfile.birthtime_nsec / 1000; extsize = curfile.extsize; uid = getuid(); if (uid == 0) uid = curfile.uid; gid = curfile.gid; mode = curfile.mode; flags = curfile.file_flags; switch (mode & IFMT) { default: fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode); skipfile(); return (FAIL); case IFSOCK: vprintf(stdout, "skipped socket %s\n", name); skipfile(); return (GOOD); case IFDIR: if (mflag) { ep = lookupname(name); if (ep == NULL || ep->e_flags & EXTRACT) panic("unextracted directory %s\n", name); skipfile(); return (GOOD); } vprintf(stdout, "extract file %s\n", name); return (genliteraldir(name, curfile.ino)); case IFLNK: lnkbuf[0] = '\0'; pathlen = 0; buf = setupextattr(extsize); getfile(xtrlnkfile, xtrattr, xtrlnkskip); if (pathlen == 0) { vprintf(stdout, "%s: zero length symbolic link (ignored)\n", name); return (GOOD); } if (linkit(lnkbuf, name, SYMLINK) == GOOD) { if (extsize > 0) set_extattr_link(name, buf, extsize); (void) lchown(name, uid, gid); (void) lchmod(name, mode); (void) lutimes(name, ctimep); (void) lutimes(name, mtimep); (void) lchflags(name, flags); return (GOOD); } return (FAIL); case IFIFO: vprintf(stdout, "extract fifo %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) (void) unlink(name); if (mkfifo(name, 0600) < 0) { fprintf(stderr, "%s: cannot create fifo: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } if (extsize == 0) { skipfile(); } else { buf = setupextattr(extsize); getfile(xtrnull, xtrattr, xtrnull); set_extattr_file(name, buf, extsize); } (void) chown(name, uid, gid); (void) chmod(name, mode); (void) utimes(name, ctimep); (void) utimes(name, mtimep); (void) chflags(name, flags); return (GOOD); case IFCHR: case IFBLK: vprintf(stdout, "extract special file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) (void) unlink(name); if (mknod(name, (mode & (IFCHR | IFBLK)) | 0600, (int)curfile.rdev) < 0) { fprintf(stderr, "%s: cannot create special file: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } if (extsize == 0) { skipfile(); } else { buf = setupextattr(extsize); getfile(xtrnull, xtrattr, xtrnull); set_extattr_file(name, buf, extsize); } (void) chown(name, uid, gid); (void) chmod(name, mode); (void) utimes(name, ctimep); (void) utimes(name, mtimep); (void) chflags(name, flags); return (GOOD); case IFREG: vprintf(stdout, "extract file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) (void) unlink(name); if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { fprintf(stderr, "%s: cannot create file: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } buf = setupextattr(extsize); getfile(xtrfile, xtrattr, xtrskip); if (extsize > 0) set_extattr_fd(ofile, name, buf, extsize); (void) fchown(ofile, uid, gid); (void) fchmod(ofile, mode); (void) futimes(ofile, ctimep); (void) futimes(ofile, mtimep); (void) fchflags(ofile, flags); (void) close(ofile); return (GOOD); } /* NOTREACHED */ }
/* * This is the routine used to extract files for the 'x' and 'i' commands. * Efficiently extract a subset of the files on a tape. */ void createfiles(void) { ino_t first, next, last; struct entry *ep; long curvol; vprintf(stdout, "Extract requested files\n"); curfile.action = SKIP; getvol((long)1); skipmaps(); skipdirs(); first = lowerbnd(ROOTINO); last = upperbnd(maxino - 1); for (;;) { curvol = volno; first = lowerbnd(first); last = upperbnd(last); /* * Check to see if any files remain to be extracted */ if (first > last) return; if (Dflag) { if (curfile.ino == maxino) return; if((ep = lookupino(curfile.ino)) != NULL && (ep->e_flags & (NEW|EXTRACT))) { goto justgetit; } else { skipfile(); continue; } } /* * Reject any volumes with inodes greater than the last * one needed, so that we can quickly skip backwards to * a volume containing useful inodes. We can't do this * if there are no further volumes available (curfile.ino * >= maxino) or if we are already at the first tape. */ if (curfile.ino > last && curfile.ino < maxino && volno > 1) { curfile.action = SKIP; getvol((long)0); skipmaps(); skipdirs(); continue; } /* * Decide on the next inode needed. * Skip across the inodes until it is found * or a volume change is encountered */ if (curfile.ino < maxino) { next = lowerbnd(curfile.ino); while (next > curfile.ino && volno == curvol) skipfile(); if (volno != curvol) { skipmaps(); skipdirs(); continue; } } else { /* * No further volumes or inodes available. Set * `next' to the first inode, so that a warning * is emitted below for each missing file. */ next = first; } /* * If the current inode is greater than the one we were * looking for then we missed the one we were looking for. * Since we only attempt to extract files listed in the * dump map, the lost files must have been due to a tape * read error, or a file that was removed while the dump * was in progress. Thus we report all requested files * between the one we were looking for, and the one we * found as missing, and delete their request flags. */ while (next < curfile.ino) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); fprintf(stderr, "%s: not found on tape\n", myname(ep)); ep->e_flags &= ~NEW; next = lowerbnd(next); } /* * The current inode is the one that we are looking for, * so extract it per its requested name. */ if (next == curfile.ino && next <= last) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); justgetit: (void) extractfile(myname(ep)); ep->e_flags &= ~NEW; if (volno != curvol) skipmaps(); } } }
/* * This is the routine used to extract files for the 'r' command. * Extract new leaves. */ void createleaves(char *symtabfile) { struct entry *ep; ino_t first; long curvol; if (command == 'R') { vprintf(stdout, "Continue extraction of new leaves\n"); } else { vprintf(stdout, "Extract new leaves.\n"); dumpsymtable(symtabfile, volno); } first = lowerbnd(ROOTINO); curvol = volno; while (curfile.ino < maxino) { first = lowerbnd(first); /* * If the next available file is not the one which we * expect then we have missed one or more files. Since * we do not request files that were not on the tape, * the lost files must have been due to a tape read error, * or a file that was removed while the dump was in progress. */ while (first < curfile.ino) { ep = lookupino(first); if (ep == NULL) panic("%ju: bad first\n", (uintmax_t)first); fprintf(stderr, "%s: not found on tape\n", myname(ep)); ep->e_flags &= ~(NEW|EXTRACT); first = lowerbnd(first); } /* * If we find files on the tape that have no corresponding * directory entries, then we must have found a file that * was created while the dump was in progress. Since we have * no name for it, we discard it knowing that it will be * on the next incremental tape. */ if (first != curfile.ino) { fprintf(stderr, "expected next file %ju, got %ju\n", (uintmax_t)first, (uintmax_t)curfile.ino); skipfile(); goto next; } ep = lookupino(curfile.ino); if (ep == NULL) panic("unknown file on tape\n"); if ((ep->e_flags & (NEW|EXTRACT)) == 0) badentry(ep, "unexpected file on tape"); /* * If the file is to be extracted, then the old file must * be removed since its type may change from one leaf type * to another (e.g. "file" to "character special"). */ if ((ep->e_flags & EXTRACT) != 0) { removeleaf(ep); ep->e_flags &= ~REMOVED; } (void) extractfile(myname(ep)); ep->e_flags &= ~(NEW|EXTRACT); /* * We checkpoint the restore after every tape reel, so * as to simplify the amount of work required by the * 'R' command. */ next: if (curvol != volno) { dumpsymtable(symtabfile, volno); skipmaps(); curvol = volno; } } }
int extractfile(char *name) { u_int flags; uid_t uid; gid_t gid; mode_t mode; struct timeval mtimep[2], ctimep[2]; struct entry *ep; int setbirth; curfile.name = name; curfile.action = USING; mtimep[0].tv_sec = curfile.atime_sec; mtimep[0].tv_usec = curfile.atime_nsec / 1000; mtimep[1].tv_sec = curfile.mtime_sec; mtimep[1].tv_usec = curfile.mtime_nsec / 1000; setbirth = curfile.birthtime_sec != 0; if (setbirth) { ctimep[0].tv_sec = curfile.atime_sec; ctimep[0].tv_usec = curfile.atime_nsec / 1000; ctimep[1].tv_sec = curfile.birthtime_sec; ctimep[1].tv_usec = curfile.birthtime_nsec / 1000; } uid = curfile.uid; gid = curfile.gid; mode = curfile.mode; flags = curfile.file_flags; switch (mode & IFMT) { default: fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode); skipfile(); return (FAIL); case IFSOCK: Vprintf(stdout, "skipped socket %s\n", name); skipfile(); return (GOOD); case IFDIR: if (mflag) { ep = lookupname(name); if (ep == NULL || ep->e_flags & EXTRACT) panic("unextracted directory %s\n", name); skipfile(); return (GOOD); } Vprintf(stdout, "extract file %s\n", name); return (genliteraldir(name, curfile.ino)); case IFLNK: { lnkbuf[0] = '\0'; pathlen = 0; getfile(xtrlnkfile, xtrlnkskip); if (pathlen == 0) { Vprintf(stdout, "%s: zero length symbolic link (ignored)\n", name); return (GOOD); } if (linkit(lnkbuf, name, SYMLINK) == FAIL) return (FAIL); (void)lchown(name, uid, gid); return (GOOD); } case IFCHR: case IFBLK: Vprintf(stdout, "extract special file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (mknod(name, mode, (int)curfile.rdev) < 0) { warn("%s: cannot create special file", name); skipfile(); return (FAIL); } (void)chown(name, uid, gid); (void)chmod(name, mode); (void)chflags(name, flags); skipfile(); if (setbirth) (void)utimes(name, ctimep); (void)utimes(name, mtimep); return (GOOD); case IFIFO: Vprintf(stdout, "extract fifo %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (mkfifo(name, mode) < 0) { warn("%s: cannot create fifo", name); skipfile(); return (FAIL); } (void)chown(name, uid, gid); (void)chmod(name, mode); (void)chflags(name, flags); skipfile(); if (setbirth) (void)utimes(name, ctimep); (void)utimes(name, mtimep); return (GOOD); case IFREG: Vprintf(stdout, "extract file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { warn("%s: cannot create file", name); skipfile(); return (FAIL); } (void)fchown(ofile, curfile.uid, curfile.gid); (void)fchmod(ofile, mode); (void)fchflags(ofile, flags); getfile(xtrfile, xtrskip); (void)close(ofile); if (setbirth) (void)utimes(name, ctimep); (void)utimes(name, mtimep); return (GOOD); } /* NOTREACHED */ }
int extractfile(char *name) { int flags; uid_t uid; gid_t gid; mode_t mode; struct timeval timep[2]; struct entry *ep; curfile.name = name; curfile.action = USING; timep[0].tv_sec = curfile.dip->di_atime; timep[0].tv_usec = curfile.dip->di_atimensec / 1000; timep[1].tv_sec = curfile.dip->di_mtime; timep[1].tv_usec = curfile.dip->di_mtimensec / 1000; uid = curfile.dip->di_uid; gid = curfile.dip->di_gid; mode = curfile.dip->di_mode; flags = curfile.dip->di_flags; switch (mode & IFMT) { default: fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode); skipfile(); return (FAIL); case IFSOCK: vprintf(stdout, "skipped socket %s\n", name); skipfile(); return (GOOD); case IFDIR: if (mflag) { ep = lookupname(name); if (ep == NULL || ep->e_flags & EXTRACT) panic("unextracted directory %s\n", name); skipfile(); return (GOOD); } vprintf(stdout, "extract file %s\n", name); return (genliteraldir(name, curfile.ino)); case IFLNK: lnkbuf[0] = '\0'; pathlen = 0; getfile(xtrlnkfile, xtrlnkskip); if (pathlen == 0) { vprintf(stdout, "%s: zero length symbolic link (ignored)\n", name); return (GOOD); } if (linkit(lnkbuf, name, SYMLINK) == GOOD) { lchown(name, uid, gid); lchmod(name, mode); lutimes(name, timep); return (GOOD); } return (FAIL); case IFIFO: vprintf(stdout, "extract fifo %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag && !Nflag) unlink(name); if (mkfifo(name, mode) < 0) { fprintf(stderr, "%s: cannot create fifo: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } chown(name, uid, gid); chmod(name, mode); utimes(name, timep); chflags(name, flags); skipfile(); return (GOOD); case IFCHR: case IFBLK: vprintf(stdout, "extract special file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) unlink(name); if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) { fprintf(stderr, "%s: cannot create special file: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } chown(name, uid, gid); chmod(name, mode); utimes(name, timep); chflags(name, flags); skipfile(); return (GOOD); case IFREG: vprintf(stdout, "extract file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) unlink(name); if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { fprintf(stderr, "%s: cannot create file: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } fchown(ofile, uid, gid); fchmod(ofile, mode); getfile(xtrfile, xtrskip); close(ofile); utimes(name, timep); chflags(name, flags); return (GOOD); } /* NOTREACHED */ }
/* * This is the routine used to extract files for the 'x' and 'i' commands. * Efficiently extract a subset of the files on a tape. */ void createfiles(void) { ino_t first, next, last; struct entry *ep; long curvol; Vprintf(stdout, "Extract requested files\n"); curfile.action = SKIP; getvol((long)1); skipmaps(); skipdirs(); first = lowerbnd(ROOTINO); last = upperbnd(maxino - 1); for (;;) { first = lowerbnd(first); last = upperbnd(last); /* * Check to see if any files remain to be extracted */ if (first > last) return; /* * Reject any volumes with inodes greater * than the last one needed */ while (curfile.ino > last) { curfile.action = SKIP; getvol((long)0); skipmaps(); skipdirs(); } /* * Decide on the next inode needed. * Skip across the inodes until it is found * or an out of order volume change is encountered */ next = lowerbnd(curfile.ino); do { curvol = volno; while (next > curfile.ino && volno == curvol) skipfile(); skipmaps(); skipdirs(); } while (volno == curvol + 1); /* * If volume change out of order occurred the * current state must be recalculated */ if (volno != curvol) continue; /* * If the current inode is greater than the one we were * looking for then we missed the one we were looking for. * Since we only attempt to extract files listed in the * dump map, the lost files must have been due to a tape * read error, or a file that was removed while the dump * was in progress. Thus we report all requested files * between the one we were looking for, and the one we * found as missing, and delete their request flags. */ while (next < curfile.ino) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); fprintf(stderr, "%s: not found on tape\n", myname(ep)); ep->e_flags &= ~NEW; next = lowerbnd(next); } /* * The current inode is the one that we are looking for, * so extract it per its requested name. */ if (next == curfile.ino && next <= last) { ep = lookupino(next); if (ep == NULL) panic("corrupted symbol table\n"); (void)extractfile(myname(ep)); ep->e_flags &= ~NEW; if (volno != curvol) skipmaps(); } } }
static void scan_directory(const char *basedir, const char *subdir) { char path[MAXPGPATH]; DIR *dir; struct dirent *de; snprintf(path, sizeof(path), "%s/%s", basedir, subdir); dir = opendir(path); if (!dir) { fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"), progname, path, strerror(errno)); exit(1); } while ((de = readdir(dir)) != NULL) { char fn[MAXPGPATH]; struct stat st; if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) continue; /* Skip temporary files */ if (strncmp(de->d_name, PG_TEMP_FILE_PREFIX, strlen(PG_TEMP_FILE_PREFIX)) == 0) continue; /* Skip temporary folders */ if (strncmp(de->d_name, PG_TEMP_FILES_DIR, strlen(PG_TEMP_FILES_DIR)) == 0) return; snprintf(fn, sizeof(fn), "%s/%s", path, de->d_name); if (lstat(fn, &st) < 0) { fprintf(stderr, _("%s: could not stat file \"%s\": %s\n"), progname, fn, strerror(errno)); exit(1); } if (S_ISREG(st.st_mode)) { char fnonly[MAXPGPATH]; char *forkpath, *segmentpath; BlockNumber segmentno = 0; if (skipfile(de->d_name)) continue; /* * Cut off at the segment boundary (".") to get the segment number * in order to mix it into the checksum. Then also cut off at the * fork boundary, to get the relfilenode the file belongs to for * filtering. */ strlcpy(fnonly, de->d_name, sizeof(fnonly)); segmentpath = strchr(fnonly, '.'); if (segmentpath != NULL) { *segmentpath++ = '\0'; segmentno = atoi(segmentpath); if (segmentno == 0) { fprintf(stderr, _("%s: invalid segment number %d in file name \"%s\"\n"), progname, segmentno, fn); exit(1); } } forkpath = strchr(fnonly, '_'); if (forkpath != NULL) *forkpath++ = '\0'; if (only_relfilenode && strcmp(only_relfilenode, fnonly) != 0) /* Relfilenode not to be included */ continue; scan_file(fn, segmentno); } #ifndef WIN32 else if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode)) #else else if (S_ISDIR(st.st_mode) || pgwin32_is_junction(fn)) #endif scan_directory(path, de->d_name); } closedir(dir); }
int main(int argc, char **argv) { int fd = -1; char magicbuf[MAGIC_LEN], *restorename; char *version = PACKAGE_VERSION; restorename = argv[1]; if (argc == 1 || (strcmp(argv[1], "--help") == 0 && argc == 2)) { printf("%s", theUsage); return 1; } else if (strcmp (argv[1], "--version") == 0 && argc == 2) { printf("%s\n", (version[0] == '\0' ? "Standalone MTCP" : version)); return 1; } else if (restorename[0] == '-' && restorename[1] == '\0') { fd = 0; /* read from stdin */ } else { /* argv[1] should be a real filename */ if (-1 == (fd = open(restorename, O_RDONLY))) { perror("open"); return 1; } } memset(magicbuf, 0, sizeof magicbuf); readall(fd, magicbuf, MAGIC_LEN); if (memcmp (magicbuf, "DMTCP_CHECKPOINT", MAGIC_LEN) == 0) { while (memcmp(magicbuf, MAGIC, MAGIC_LEN) != 0) { int i; for (i = 0; i < MAGIC_LEN-1; i++) magicbuf[i] = magicbuf[i+1]; magicbuf[MAGIC_LEN-1] = '\0'; /* MAGIC should be a string w/o '\0' */ if (0 == readall(fd, magicbuf+(MAGIC_LEN-1), 1)) /* if EOF */ break; } } if (memcmp (magicbuf, MAGIC, MAGIC_LEN) != 0) { char command[512]; fprintf (stderr, "readmtcp: Not an mtcp image; trying it as dmtcp image\n"); sprintf (command, "gzip -dc %s | %s -", restorename, argv[0]); exit( system(command) ); } /* Find where the restore image goes */ VA restore_begin; size_t restore_size; void *restore_start; /* will be bound to fnc, mtcp_restore_start */ void (*finishrestore) (void); /* Set the resource limits for stack from saved values */ struct rlimit stack_rlimit; #ifdef FAST_CKPT_RST_VIA_MMAP Area area; fastckpt_read_header(fd, &stack_rlimit, &area, (VA*) &restore_start); restore_begin = area.addr; restore_size = area.size; finishrestore = (void*) fastckpt_get_finishrestore(); printf("mtcp_restart: saved stack resource limit:" \ " soft_lim: %lu, hard_lim: %lu\n", stack_rlimit.rlim_cur, stack_rlimit.rlim_max); printf("*** restored libmtcp.so\n"); printf("%p-%p rwxp %p 00:00 0 [libmtcp.so]\n", restore_begin, restore_begin + restore_size, restore_begin); printf("restore_start routine: %p\n", restore_start); printf("*** finishrestore\n"); printf("finishrestore routine: %p\n", finishrestore); #else readcs (fd, CS_STACKRLIMIT); /* resource limit for stack */ readall(fd, &stack_rlimit, sizeof stack_rlimit); printf("mtcp_restart: saved stack resource limit:" \ " soft_lim: %lu, hard_lim: %lu\n", stack_rlimit.rlim_cur, stack_rlimit.rlim_max); printf("*** restored libmtcp.so\n"); readcs (fd, CS_RESTOREBEGIN); /* beginning of checkpointed libmtcp.so image */ readall(fd, &restore_begin, sizeof restore_begin); readcs (fd, CS_RESTORESIZE); /* size of checkpointed libmtcp.so image */ readall(fd, &restore_size, sizeof restore_size); readcs (fd, CS_RESTORESTART); readall(fd, &restore_start, sizeof restore_start); readcs (fd, CS_RESTOREIMAGE); skipfile (fd, restore_size); printf("%p-%p rwxp %p 00:00 0 [libmtcp.so]\n", restore_begin, restore_begin + restore_size, restore_begin); printf("restore_start routine: %p\n", restore_start); printf("*** finishrestore\n"); readcs (fd, CS_FINISHRESTORE); readall(fd, &finishrestore, sizeof finishrestore); printf("finishrestore routine: %p\n", finishrestore); char linkbuf[FILENAMESIZE]; int fdnum, linklen ; struct stat statbuf; off_t offset; printf("*** file descriptors\n"); readcs (fd, CS_FILEDESCRS); while (1) { /* Read parameters of next file to restore */ readall(fd, &fdnum, sizeof fdnum); if (fdnum < 0) break; readall(fd, &statbuf, sizeof statbuf); readall(fd, &offset, sizeof offset); readall(fd, &linklen, sizeof linklen); if ((size_t)linklen >= sizeof linkbuf) { printf ("filename too long %d\n", linklen); exit(1); } readall(fd, linkbuf, linklen); linkbuf[linklen] = '\0'; } #endif printf("*** memory sections\n"); while(1) { Area area; char cstype; #ifdef FAST_CKPT_RST_VIA_MMAP if (fastckpt_get_next_area_dscr(&area) == 0) break; #else readall(fd, &cstype, sizeof cstype); if (cstype == CS_THEEND) break; if (cstype != CS_AREADESCRIP) { printf ("readmtcp: expected CS_AREADESCRIP but had %d\n", cstype); exit(1); } readall(fd, &area, sizeof area); readcs (fd, CS_AREACONTENTS); #ifdef ANDROID if ((area.prot & MTCP_PROT_SKIP_PAGE) != 0) { printf("%p-%p %s skipped\n", area.addr, area.addr + area.size, area.name); } else #endif if ((area.prot & MTCP_PROT_ZERO_PAGE) == 0) { skipfile (fd, area.size); } #endif printf("%p-%p %c%c%c%c %8x 00:00 0 %s\n", area.addr, area.addr + area.size, ( area.prot & PROT_READ ? 'r' : '-' ), ( area.prot & PROT_WRITE ? 'w' : '-' ), ( area.prot & PROT_EXEC ? 'x' : '-' ), ( area.flags & MAP_SHARED ? 's' : ( area.flags & MAP_ANONYMOUS ? 'p' : '-' ) ), 0, area.name); } printf("*** done\n"); close (fd); mtcp_restore_cpfd = -1; return 0; }