FreeCalypso > hg > freecalypso-sw
view rvinterf/etmsync/fsread.c @ 288:e33d71e9033f
fc-fsio: cpout directory recursion implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 28 Feb 2014 08:46:14 +0000 |
parents | 211b35db427c |
children | 3dd74b16df82 |
line wrap: on
line source
/* * Commands for reading the content of a GSM device's file system */ #include <sys/types.h> #include <sys/param.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <unistd.h> #include "etm.h" #include "ffs.h" #include "tmffs2.h" #include "limits.h" #include "localtypes.h" #include "localstruct.h" #include "exitcodes.h" void ll_print_line(pathname, stat) char *pathname; struct stat_info *stat; { char readonly; if (stat->flags & OF_READONLY) readonly = 'r'; else readonly = ' '; switch (stat->type) { case OT_FILE: printf("f%c %7u %s\n", readonly, stat->size, pathname); return; case OT_DIR: printf("d%c %s\n", readonly, pathname); return; case OT_LINK: printf("l%c %s\n", readonly, pathname); return; default: printf("?%c %s\n", readonly, pathname); } } void mk_ffs_child_path_from_readdir(dirpath, rdname, buf) char *dirpath, *rdname, *buf; { char *tailp; tailp = index(dirpath, '\0') - 1; if (*tailp == '/') sprintf(buf, "%s%s", dirpath, rdname); else sprintf(buf, "%s/%s", dirpath, rdname); } cmd_ll(argc, argv) char **argv; { struct stat_info stat; u_char rdstate[4]; char rdbuf[TMFFS_STRING_SIZE], childpath[TMFFS_STRING_SIZE*2]; int nument, i, rc; rc = do_xlstat(argv[1], &stat); if (rc) return(rc); if (stat.type != OT_DIR) { ll_print_line(argv[1], &stat); return(0); } rc = do_opendir(argv[1], rdstate, &nument); if (rc) return(rc); if (!nument) { printf("<empty dir>\n"); return(0); } for (i = 0; i < nument; i++) { rc = do_readdir(rdstate, rdbuf); if (rc) return(rc); mk_ffs_child_path_from_readdir(argv[1], rdbuf, childpath); rc = do_xlstat(childpath, &stat); if (rc) { printf("xlstat failed on %s\n", childpath); return(rc); } ll_print_line(childpath, &stat); } return(0); } void hexdump_line(offset, buf, len) u_char *buf; { int i, c; printf("%02X: ", offset); for (i = 0; i < 16; i++) { if (i < len) printf("%02X ", buf[i]); else fputs(" ", stdout); if (i == 7 || i == 15) putchar(' '); } for (i = 0; i < len; i++) { c = buf[i]; if (c < ' ' || c > '~') c = '.'; putchar(c); } putchar('\n'); } cmd_hd(argc, argv) char **argv; { u_char databuf[MAX_READ_DATA]; int rc, sz, off, l; rc = do_file_read(argv[1], databuf, MAX_READ_DATA, &sz); if (rc) return(rc); printf("%d bytes read\n", sz); for (off = 0; off < sz; off += 16) { l = sz - off; if (l > 16) l = 16; hexdump_line(off, databuf + off, l); } return(0); } cpout_object(ffspath, hostpath) char *ffspath, *hostpath; { struct stat_info stat; int rc; rc = do_xlstat(ffspath, &stat); if (rc) return(rc); switch (stat.type) { case OT_FILE: return cpout_file(ffspath, &stat, hostpath); case OT_DIR: return cpout_dir(ffspath, hostpath); case OT_LINK: printf("skipping FFS symlink %s\n", ffspath); return(0); default: printf("error: stat returned bad objtype for %s\n", ffspath); return(ERROR_TARGET); } } cpout_file(ffspath, stat, hostpath) char *ffspath, *hostpath; struct stat_info *stat; { int tfd; FILE *of; u_char buf[MAX_READ_DATA]; int rc, sz; printf("copying %s\n", ffspath); rc = fd_open(ffspath, FFS_O_RDONLY, &tfd); if (rc) return(rc); of = fopen(hostpath, "w"); if (!of) { perror(hostpath); fd_close(tfd); return(ERROR_UNIX); } for (;;) { rc = fd_read(tfd, buf, MAX_READ_DATA, &sz); if (rc) { fd_close(tfd); fclose(of); return(rc); } if (!sz) break; fwrite(buf, 1, sz, of); } fclose(of); return fd_close(tfd); } host_mkdir(pathname) char *pathname; { int rc; struct stat st; rc = stat(pathname, &st); if (rc < 0) { rc = mkdir(pathname, 0777); if (rc < 0) { perror(pathname); return(ERROR_UNIX); } return(0); } else { if (S_ISDIR(st.st_mode)) return(0); else { fprintf(stderr, "error: %s already exists and is not a directory\n", pathname); return(ERROR_UNIX); } } } cpout_dir(ffspath_dir, hostpath_dir) char *ffspath_dir, *hostpath_dir; { u_char rdstate[4]; char rdbuf[TMFFS_STRING_SIZE], ffspath_child[TMFFS_STRING_SIZE*2]; char hostpath_child[MAXPATHLEN]; int nument, i, rc; printf("dir %s\n", ffspath_dir); rc = host_mkdir(hostpath_dir); if (rc) return(rc); rc = do_opendir(ffspath_dir, rdstate, &nument); if (rc) return(rc); for (i = 0; i < nument; i++) { rc = do_readdir(rdstate, rdbuf); if (rc) return(rc); mk_ffs_child_path_from_readdir(ffspath_dir, rdbuf, ffspath_child); if (rdbuf[0] == '.') { printf("skipping %s\n", ffspath_child); return(0); } if (strlen(hostpath_dir) + strlen(rdbuf) + 2 > sizeof hostpath_child) { fprintf(stderr, "error: host side pathname buffer overflow\n"); return(ERROR_UNIX); } sprintf(hostpath_child, "%s/%s", hostpath_dir, rdbuf); rc = cpout_object(ffspath_child, hostpath_child); if (rc) return(rc); } return(0); } cmd_cpout(argc, argv) char **argv; { return cpout_object(argv[1], argv[2]); }