/* $Id$ */ /* very crude and basic fs utilities for testing the NFS */ /* Till Straumann, , 10/2002 */ /* * Copyright 2002, Stanford University and * Till Straumann * * Stanford Notice * *************** * * Acknowledgement of sponsorship * * * * * * * * * * * * * * * * * * This software was produced by the Stanford Linear Accelerator Center, * Stanford University, under Contract DE-AC03-76SFO0515 with the Department * of Energy. * * Government disclaimer of liability * - - - - - - - - - - - - - - - - - * Neither the United States nor the United States Department of Energy, * nor any of their employees, makes any warranty, express or implied, * or assumes any legal liability or responsibility for the accuracy, * completeness, or usefulness of any data, apparatus, product, or process * disclosed, or represents that its use would not infringe privately * owned rights. * * Stanford disclaimer of liability * - - - - - - - - - - - - - - - - - * Stanford University makes no representations or warranties, express or * implied, nor assumes any liability for the use of this software. * * This product is subject to the EPICS open license * - - - - - - - - - - - - - - - - - - - - - - - - - * Consult the LICENSE file or http://www.aps.anl.gov/epics/license/open.php * for more information. * * Maintenance of notice * - - - - - - - - - - - * In the interest of clarity regarding the origin and status of this * software, Stanford University requests that any recipient of it maintain * this notice affixed to any distribution by the recipient that contains a * copy or derivative of this software. */ #ifdef __vxworks #include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_CEXP #include #endif #ifndef __vxworks int pwd(void) { char buf[MAXPATHLEN]; if ( !getcwd(buf,MAXPATHLEN)) { perror("getcwd"); return -1; } else { printf("%s\n",buf); } return 0; } static int ls_r(char *path, char *chpt, char *name, struct stat *buf) { char *t; sprintf(chpt, "/%s", name); if (lstat(path,buf)) { fprintf(stderr,"stat(%s): %s\n", path, strerror(errno)); return -1; } switch ( buf->st_mode & S_IFMT ) { case S_IFSOCK: case S_IFIFO: t = "|"; break; default: case S_IFREG: case S_IFBLK: case S_IFCHR: t = ""; break; case S_IFDIR: t = "/"; break; case S_IFLNK: t = "@"; break; } printf("%10li, %10lib, %5i.%-5i 0%04o %s%s\n", buf->st_ino, buf->st_size, buf->st_uid, buf->st_gid, buf->st_mode & ~S_IFMT, name, t); *chpt = 0; return 0; } int ls(char *dir, char *opts) { struct dirent *de; char path[MAXPATHLEN+1]; char *chpt; DIR *dp = 0; int rval = -1; struct stat buf; if ( !dir ) dir = "."; strncpy(path, dir, MAXPATHLEN); path[MAXPATHLEN] = 0; chpt = path+strlen(path); if ( !(dp=opendir(dir)) ) { perror("opendir"); goto cleanup; } while ( (de = readdir(dp)) ) { ls_r(path, chpt, de->d_name, &buf); } rval = 0; cleanup: if (dp) closedir(dp); return rval; } #endif #if 0 fprintf(stderr, "usage: cp(""from"",[""to""[,""-f""]]\n"); fprintf(stderr, " ""to""==NULL -> stdout\n"); fprintf(stderr, " ""-f"" -> overwrite existing file\n"); #endif int cp(char *from, char *to, char *opts) { struct stat st; int rval = -1; int fd = -1; FILE *fst = 0; FILE *tst = 0; int flags = O_CREAT | O_WRONLY | O_TRUNC | O_EXCL; if (from) { if ((fd=open(from,O_RDONLY,0)) < 0) { fprintf(stderr, "Opening %s for reading: %s\n", from, strerror(errno)); goto cleanup; } if (fstat(fd, &st)) { fprintf(stderr, "rstat(%s): %s\n", from, strerror(errno)); goto cleanup; } if (!S_ISREG(st.st_mode)) { fprintf(stderr,"Refuse to copy a non-regular file\n"); errno = EINVAL; goto cleanup; } /* Now create a stream -- I experienced occasional weirdness * when circumventing the streams attached to fildno(stdin) * by reading/writing to the underlying fd's directly -> * for now we always go through buffered I/O... */ if ( !(fst=fdopen(fd,"r")) ) { fprintf(stderr, "Opening input stream [fdopen()] failed: %s\n", strerror(errno)); goto cleanup; } /* at this point, we have a stream and don't need 'fd' anymore */ fd = -1; } else { fst = stdin; st.st_mode = 0644; } if (opts && strchr(opts,'f')) flags &= ~ O_EXCL; if (to) { if ( (fd=open(to,flags,st.st_mode)) < 0 ) { fprintf(stderr, "Opening %s for writing: %s\n", to, strerror(errno)); goto cleanup; } if ( !(tst=fdopen(fd, "w")) ) { fprintf(stderr, "Opening output stream [fdopen()] failed: %s\n", strerror(errno)); goto cleanup; } /* at this point we have a stream and don't need 'fd' anymore */ fd = -1; } else { tst = stdout; } /* clear old errors */ clearerr(fst); clearerr(tst); /* use macro versions on register vars; stdio is already buffered, * there's nothing to be gained by reading/writing blocks into * a secondary buffer... */ { register int ch; register FILE *f = fst; register FILE *t = tst; while ( EOF != (ch = getc(f)) && EOF != putc(ch, t) ) /* nothing else */; } if ( ferror(fst) ) { fprintf(stderr,"Read error: %s\n",strerror(errno)); goto cleanup; } if ( ferror(tst) ) { fprintf(stderr,"Write error: %s\n",strerror(errno)); goto cleanup; } rval = 0; cleanup: if ( fd >= 0 ) close(fd); if ( fst ) { if ( from ) fclose(fst); else clearerr(fst); } if ( tst ) { if ( to ) fclose(tst); else { /* flush stdout */ fflush(tst); clearerr(tst); } } return rval; } int ln(char *to, char *name, char *opts) { if (!to) { fprintf(stderr,"ln: need 'to' argument\n"); return -1; } if (!name) { if ( !(name = strrchr(to,'/')) ) { fprintf(stderr, "ln: 'unable to link %s to %s\n", to,to); return -1; } name++; } if (opts || strchr(opts,'s')) { if (symlink(name,to)) { fprintf(stderr,"symlink: %s\n",strerror(errno)); return -1; } } else { if (link(name,to)) { fprintf(stderr,"hardlink: %s\n",strerror(errno)); return -1; } } return 0; } int rm(char *path) { return unlink(path); } int cd(char *path) { return chdir(path); } #ifdef HAVE_CEXP static CexpHelpTabRec _cexpHelpTabDirutils[] __attribute__((unused)) = { HELP( "copy a file: cp(""from"",[""to""[,""-f""]])\n\ from = NULL <-- stdin\n\ to = NULL --> stdout\n\ option -f: overwrite existing file\n", int, cp, (char *from, char *to, char *options) ), HELP( "list a directory: ls([""dir""])\n", int, ls, (char *dir) ), HELP( "remove a file\n", int, rm, (char *path) ), HELP( "change the working directory\n", int, cd, (char *path) ), HELP( "create a link: ln(""to"",""name"",""[-s]""\n\ -s creates a symlink\n", int, ln, (char *to, char *name, char *options) ), HELP("",,0,) }; #endif