mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-06-05 17:00:21 +08:00
384 lines
7.8 KiB
C
384 lines
7.8 KiB
C
/* very crude and basic fs utilities for testing the NFS */
|
|
|
|
/* Till Straumann, <strauman@slac.stanford.edu>, 10/2002 */
|
|
|
|
/*
|
|
* Authorship
|
|
* ----------
|
|
* This software (NFS-2 client implementation for RTEMS) was created by
|
|
* Till Straumann <strauman@slac.stanford.edu>, 2002-2007,
|
|
* Stanford Linear Accelerator Center, Stanford University.
|
|
*
|
|
* Acknowledgement of sponsorship
|
|
* ------------------------------
|
|
* The NFS-2 client implementation for RTEMS 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.
|
|
*
|
|
* Stanford disclaimer of copyright
|
|
* --------------------------------
|
|
* Stanford University, owner of the copyright, hereby disclaims its
|
|
* copyright and all other rights in this software. Hence, anyone may
|
|
* freely use it for any purpose without restriction.
|
|
*
|
|
* Maintenance of notices
|
|
* ----------------------
|
|
* In the interest of clarity regarding the origin and status of this
|
|
* SLAC software, this and all the preceding Stanford University notices
|
|
* are to remain affixed to any copy or derivative of this software made
|
|
* or distributed by the recipient and are to be affixed to any copy of
|
|
* software made or distributed by the recipient that contains a copy or
|
|
* derivative of this software.
|
|
*
|
|
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
|
|
*/
|
|
|
|
#if HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#ifdef __vxworks
|
|
#include <vxWorks.h>
|
|
#endif
|
|
#include <stdio.h>
|
|
#include <dirent.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <limits.h> /* PATH_MAX */
|
|
|
|
#include <inttypes.h> /* PRI* */
|
|
|
|
#if SIZEOF_MODE_T == 8
|
|
#define PRIomode_t PRIo64
|
|
#elif SIZEOF_MODE_T == 4
|
|
#define PRIomode_t PRIo32
|
|
#else
|
|
#error "unsupport size of mode_t"
|
|
#endif
|
|
|
|
#if SIZEOF_OFF_T == 8
|
|
#define PRIdoff_t PRIo64
|
|
#elif SIZEOF_OFF_T == 4
|
|
#define PRIdoff_t PRIo32
|
|
#else
|
|
#error "unsupported size of off_t"
|
|
#endif
|
|
|
|
#ifdef HAVE_CEXP
|
|
#include <cexpHelp.h>
|
|
#endif
|
|
|
|
#ifndef __vxworks
|
|
int
|
|
pwd(void)
|
|
{
|
|
char buf[PATH_MAX];
|
|
|
|
if ( !getcwd(buf,PATH_MAX)) {
|
|
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, %10" PRIdoff_t "b, %5i.%-5i 0%04" PRIomode_t " %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[PATH_MAX+1];
|
|
char *chpt;
|
|
DIR *dp = 0;
|
|
int rval = -1;
|
|
struct stat buf;
|
|
|
|
if ( !dir )
|
|
dir = ".";
|
|
|
|
strncpy(path, dir, PATH_MAX);
|
|
path[PATH_MAX] = 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
|