./ 775 20115 11 0 4552136511 4214 ./basic/ 775 20115 11 0 4552136061 5275 ./basic/subr.c 664 20115 11 23750 4552130364 6530 /* @(#)subr.c 1.2 89/01/08 NFS Rev 2 Testsuite */
/*
* Useful subroutines shared by all tests
*/
#include "tests.h"
char *Myname;
#ifdef ANSI
int unix_chdir(char * path);
#ifdef DOS
char *getwd(char * path);
#endif
#endif
/*
* Build a directory tree "lev" levels deep
* with "files" number of files in each directory
* and "dirs" fan out. Starts at the current directory.
* "fname" and "dname" are the base of the names used for
* files and directories.
*/
void
dirtree(lev, files, dirs, fname, dname, totfiles, totdirs)
int lev;
int files;
int dirs;
char *fname;
char *dname;
int *totfiles;
int *totdirs;
{
int fd;
int f, d;
char name[MAXPATHLEN];
if (lev-- == 0) {
return;
}
for ( f = 0; f < files; f++) {
sprintf(name, "%s%d", fname, f);
if ((fd = creat(name, CHMOD_YES)) < 0) {
error("creat %s failed", name);
exit(1);
}
(*totfiles)++;
if (close(fd) < 0) {
error("close %d failed", fd);
exit(1);
}
}
for ( d = 0; d < dirs; d++) {
sprintf(name, "%s%d", dname, d);
#ifdef DOS
if (mkdir(name) < 0) {
#else
if (mkdir(name, 0777) < 0) {
#endif
error("mkdir %s failed", name);
exit(1);
}
(*totdirs)++;
if (unix_chdir(name) < 0) {
error("chdir %s failed", name);
exit(1);
}
dirtree(lev, files, dirs, fname, dname, totfiles, totdirs);
if (unix_chdir("..") < 0) {
error("chdir .. failed");
exit(1);
}
}
}
/*
* Remove a directory tree starting at the current directory.
* "fname" and "dname" are the base of the names used for
* files and directories to be removed - don't remove anything else!
* "files" and "dirs" are used with fname and dname to generate
* the file names to remove.
*
* This routine will fail if, say after removing known files,
* the directory is not empty.
*
* This is used to test the unlink function and to clean up after tests.
*/
void
rmdirtree(lev, files, dirs, fname, dname, totfiles, totdirs, ignore)
int lev;
int files;
int dirs;
char *fname;
char *dname;
int *totfiles; /* total removed */
int *totdirs; /* total removed */
int ignore;
{
int f, d;
char name[MAXPATHLEN];
if (lev-- == 0) {
return;
}
for ( f = 0; f < files; f++) {
sprintf(name, "%s%d", fname, f);
if (unlink(name) < 0 && !ignore) {
error("unlink %s failed", name);
exit(1);
}
(*totfiles)++;
}
for ( d = 0; d < dirs; d++) {
sprintf(name, "%s%d", dname, d);
if (unix_chdir(name) < 0) {
if (ignore)
continue;
error("chdir %s failed", name);
exit(1);
}
rmdirtree(lev, files, dirs, fname, dname, totfiles, totdirs, ignore);
if (unix_chdir("..") < 0) {
error("chdir .. failed");
exit(1);
}
if (rmdir(name) < 0) {
error("rmdir %s failed", name);
exit(1);
}
(*totdirs)++;
}
}
/* VARARGS */
void
error(str, ar1, ar2, ar3, ar4, ar5, ar6, ar7, ar8, ar9)
char *str;
long ar1, ar2, ar3, ar4, ar5, ar6, ar7, ar8, ar9;
{
char *ret;
char path[MAXPATHLEN];
if ((ret = getwd(path)) == NULL)
fprintf(stderr, "%s: getwd failed\n", Myname);
else
fprintf(stderr, "\t%s: (%s) ", Myname, path);
fprintf(stderr, str, ar1, ar2, ar3, ar4, ar5, ar6, ar7, ar8, ar9);
if (errno)
perror(" ");
else
fprintf(stderr, "\n");
fflush(stderr);
if (ret == NULL)
exit(1);
}
static struct timeval ts, te;
/*
* save current time in struct ts
*/
void
starttime()
{
gettimeofday(&ts, (struct timezone *)0);
}
/*
* sets the struct tv to the difference in time between
* current time and the time in struct ts.
*/
void
endtime(tv)
struct timeval *tv;
{
gettimeofday(&te, (struct timezone *)0);
if (te.tv_usec < ts.tv_usec) {
te.tv_sec--;
te.tv_usec += 1000000;
}
tv->tv_usec = te.tv_usec - ts.tv_usec;
tv->tv_sec = te.tv_sec - ts.tv_sec;
}
void
printtimes(tv, nbytes)
struct timeval *tv; /* contains the elapsed time */
long nbytes; /* size * count */
{
fprintf(stdout, " in %ld.%-2ld seconds",
tv->tv_sec, tv->tv_usec / 10000L);
if (nbytes > 0 && tv->tv_sec != 0)
fprintf(stdout, " (%ld bytes/sec)", nbytes/tv->tv_sec);
}
/*
* Set up and move to a test directory
*/
void
testdir(dir)
char *dir;
{
struct stat statb;
char str[MAXPATHLEN];
char *getenv();
/*
* If dir is non-NULL, use that dir. If NULL, first
* check for env variable NFSTESTDIR. If that is not
* set, use the compiled-in TESTDIR.
*/
if (dir == NULL)
if ((dir = getenv("NFSTESTDIR")) == NULL)
dir = TESTDIR;
if (stat(dir, &statb) == 0) {
sprintf(str, "rm -r %s", dir);
if (system(str) != 0) {
error("can't remove old test directory %s", dir);
exit(1);
}
}
#ifdef DOS
if (mkdir(dir) < 0) {
#else
if (mkdir(dir, 0777) < 0) {
#endif
error("can't create test directory %s", dir);
exit(1);
}
if (unix_chdir(dir) < 0) {
error("can't chdir to test directory %s", dir);
exit(1);
}
}
/*
* Move to a test directory
*/
int
mtestdir(dir)
char *dir;
{
char *getenv();
/*
* If dir is non-NULL, use that dir. If NULL, first
* check for env variable NFSTESTDIR. If that is not
* set, use the compiled-in TESTDIR.
*/
if (dir == NULL)
if ((dir = getenv("NFSTESTDIR")) == NULL)
dir = TESTDIR;
if (unix_chdir(dir) < 0) {
error("can't chdir to test directory %s", dir);
return -1;
}
return 0;
}
/*
* get parameter at parm, convert to int, and make sure that
* it is at least min.
*/
long
getparm(parm, min, label)
char *parm, *label;
long min;
{
long val = atol(parm);
if (val < min) {
error("Illegal %s parameter %ld, must be at least %ld",
label, val, min);
exit(1);
}
return val;
}
#ifdef DOS
#ifdef ANSI
void chdrive(char * path);
#endif
/*
* Change to drive specified in path
*/
void
chdrive(path)
char *path;
{
int desireddrive, drive;
if (path[1] == ':')
{
desireddrive = toupper(path[0]) - ('A' - 1);
_dos_setdrive(desireddrive, &drive);
_dos_getdrive(&drive);
if (drive != desireddrive)
{
error("can't change to drive %c:", path[0]);
exit(1);
}
}
}
/*
* exit point for successful test
*/
void
complete()
{
fprintf(stdout, "\t%s ok.\n", Myname);
#ifdef DOS
chdrive(Myname);
#endif
exit(0);
}
int
unix_chdir(path)
char *path;
{
#ifdef DOS
chdrive(path);
#endif
return chdir(path);
}
char *
getwd(path)
char * path;
{
return getcwd(path, MAXPATHLEN);
}
int
unix_chmod(path, mode)
char *path;
int mode;
{
int dosmode = (mode&0500 ? S_IREAD : 0) | (mode&0200 ? S_IWRITE : 0);
return chmod(path, dosmode);
}
int
lstat(path, buf)
char *path;
struct stat *buf;
{
return stat(path, buf);
}
void
gettimeofday(struct timeval *TV, struct timezone *TimeZone)
{
struct dostime_t dostime;
_dos_gettime(&dostime);
TV->tv_sec = dostime.hour * 3600L
+ dostime.minute * 60L
+ dostime.second;
TV->tv_usec = dostime.hsecond * 10000L;
TimeZone = TimeZone; /* shut up compiler/lint */
}
int
statfs(path, buf)
char *path;
struct statfs *buf;
{
char *p = (char *) buf;
int i;
unsigned drive;
struct diskfree_t diskspace;
for (i = 0; i < sizeof(*buf); i++)
*p++ = (char) -1;
buf->f_type = 0; /* that's what the man page says */
if (path[1] == ':')
drive = toupper(path[0]) - ('A' - 1);
else
_dos_getdrive(&drive);
if (_dos_getdiskfree(drive, &diskspace))
return -1;
buf->f_bsize = diskspace.bytes_per_sector;
buf->f_blocks = (long) diskspace.total_clusters
* diskspace.sectors_per_cluster;
buf->f_bfree = (long) diskspace.avail_clusters
* diskspace.sectors_per_cluster;
buf->f_bavail = buf->f_bfree;
return 0;
}
/***************************************************************
DIRENT EMULATION FOR DOS
***************************************************************/
char pattern[MAXNAMLEN];
struct find_t findtst;
int maxentry;
int currententry;
int diropen = 0;
struct dirent *dirlist;
DIR dirst;
#ifdef ANSI
static void copynametolower(char *dest, char *src);
static void findt_to_dirent(struct find_t *f, struct dirent *d);
#endif
DIR *
opendir(dirname)
char *dirname;
{
int i;
unsigned attributes = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
strcpy(pattern, dirname);
strcat(pattern, "\\*.*");
if (diropen)
return NULL;
diropen = 1;
dirlist = (struct dirent *) malloc(512 * sizeof(struct dirent));
if (dirlist == NULL)
return NULL;
if (_dos_findfirst(pattern, attributes, &findtst))
return NULL;
findt_to_dirent(&findtst, &dirlist[0]);
for (i = 1; ! _dos_findnext(&findtst); i++) {
findt_to_dirent(&findtst, &dirlist[i]);
}
maxentry = i - 1;
currententry = 0;
return &dirst;
}
void
rewinddir(dirp)
DIR *dirp;
{
int i;
unsigned attributes = _A_NORMAL|_A_RDONLY|_A_HIDDEN|_A_SUBDIR;
dirp = dirp; /* shut up compiler */
if (_dos_findfirst(pattern, attributes, &findtst)) {
error("rewind failed");
exit(1);
}
findt_to_dirent(&findtst, &dirlist[0]);
for (i = 1; ! _dos_findnext(&findtst); i++) {
findt_to_dirent(&findtst, &dirlist[i]);
}
maxentry = i - 1;
currententry = 0;
}
long
telldir(dirp)
DIR *dirp;
{
dirp = dirp; /* keep compiler happy */
return (long) currententry;
}
void
seekdir(dirp, loc)
DIR *dirp;
long loc;
{
dirp = dirp; /* keep compiler happy */
if (loc <= (long) maxentry)
currententry = (int) loc;
/* else seekdir silently fails */
}
struct dirent *
readdir(dirp)
DIR *dirp;
{
dirp = dirp; /* shut up compiler */
if (currententry > maxentry)
return (struct dirent *) NULL;
else {
return &dirlist[currententry++];
}
}
void
findt_to_dirent(f, d)
struct find_t *f;
struct dirent *d;
{
copynametolower(d->d_name, f->name);
}
static void
copynametolower(dest, src)
char *dest;
char *src;
{
int i;
for (i = 0; dest[i] = (char) tolower((int) src[i]); i++) {
/* null body */
}
}
void
closedir(dirp)
DIR *dirp;
{
dirp = dirp; /* keep compiler happy */
diropen = 0;
}
#endif /* DOS */
* sets the struct tv ./basic/test5a.c 664 20115 11 6656 4552130373 6750 /* @(#)test5a.c 1.2 89/01/10 NFS Rev 2 Testsuite */
/*
* Test write - DOES NOT VERIFY WRITE CONTENTS
*
* Uses the following important system calls against the server:
*
* chdir()
* mkdir() (for initial directory creation if not -m)
* creat()
* write()
* stat()
* fstat()
*/
#include "tests.h"
#define BUFSZ 8192
#define DSIZE 1048576L
int Tflag = 0; /* print timing */
int Hflag = 0; /* print help message */
int Fflag = 0; /* test function only; set count to 1, negate -t */
int Nflag = 0; /* Suppress directory operations */
void usage(void);
void
usage()
{
fprintf(stdout, "usage: %s [-htfn] [size count fname]\n", Myname);
fprintf(stdout, " Flags: h Help - print this usage info\n");
fprintf(stdout, " t Print execution time statistics\n");
fprintf(stdout, " f Test function only (negate -t)\n");
fprintf(stdout, " n Suppress test directory create operations\n");
}
void main(int argc,char *argv[]);
void
main(argc, argv)
int argc;
char *argv[];
{
int count = DCOUNT; /* times to do each file */
int ct;
long size = DSIZE;
long si;
long i;
int fd;
int bytes;
char *bigfile = "bigfile";
struct timeval time;
struct stat statb;
char *opts;
char buf[BUFSZ];
umask(0);
setbuf(stdout, NULL);
Myname = *argv++;
argc--;
while (argc && **argv == '-') {
for (opts = &argv[0][1]; *opts; opts++) {
switch (*opts) {
case 'h': /* help */
usage();
exit(1);
case 't': /* time */
Tflag++;
break;
case 'f': /* funtionality */
Fflag++;
break;
case 'n': /* No Test Directory create */
Nflag++;
break;
default:
error("unknown option '%c'", *opts);
usage();
exit(1);
}
}
argc--;
argv++;
}
if (argc) {
size = getparm(*argv, 1L, "size");
argv++;
argc--;
}
if (argc) {
count = (int) getparm(*argv, 1L, "count");
argv++;
argc--;
}
if (argc) {
bigfile = *argv;
argv++;
argc--;
}
if (argc) {
usage();
exit(1);
}
if (Fflag) {
Tflag = 0;
count = 1;
}
fprintf(stdout, "%s: write\n", Myname);
if (!Nflag)
testdir(NULL);
else
mtestdir(NULL);
/* Set up contents, however we won't verify. */
for (i=0; i < BUFSZ / sizeof(long); i++) {
((long *)buf)[i] = i;
}
if (Tflag) {
starttime();
}
for (ct = 0; ct < count; ct++) {
if ((fd = creat(bigfile, CHMOD_YES)) < 0) {
error("can't create '%s'", bigfile);
exit(1);
}
if (fstat(fd, &statb) < 0) {
error("can't stat '%s'", bigfile);
exit(1);
}
if (statb.st_size != 0) {
error("'%s' has size %ld, should be 0",
bigfile, statb.st_size);
exit(1);
}
for (si = size; si > 0; si -= BUFSZ) {
bytes = (int) MIN((long) BUFSZ, si);
if (write(fd, buf, bytes) != bytes) {
error("'%s' write failed", bigfile);
exit(1);
}
}
close(fd);
if (stat(bigfile, &statb) < 0) {
error("can't stat '%s'", bigfile);
exit(1);
}
if (statb.st_size != size) {
error("'%s' has size %ld, should be %ld",
bigfile, statb.st_size, size);
exit(1);
}
}
if (Tflag) {
endtime(&time);
}
fprintf(stdout, "\twrote %ld byte file %d times", size, count);
if (Tflag) {
printtimes(&time, size * (long) count);
}
fprintf(stdout, "\n");
complete();
}
mpiler happy */
diropen = 0;
}
#endif /* DOS */
* sets the struct tv ./basic/tests.h 664 20115 11 2773 4552130402 6677 /* @(#)tests.h 1.2 89/01/08 NFS Rev 2 Testsuite */
/* Do all includes here so you don't have to mess with each file */
#ifndef DOS
#include <sys/param.h>
#endif
#ifndef major
#include <sys/types.h>
#endif
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#ifdef DOS
#include <fcntl.h>
#include <dos.h>
#include <time.h>
#include "unixdos.h"
#include <direct.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#endif
#define TESTDIR "o:\\nfstestd"
#define DNAME "dir."
#define FNAME "file."
#define DCOUNT 10
#define DDIRS 2
#define DLEVS 5
#define DFILS 5
#ifdef DOS
#define CHMOD_MASK (S_IREAD | S_IWRITE)
#define CHMOD_YES CHMOD_MASK
#define CHMOD_NO S_IREAD
#else
#define CHMOD_MASK 0777
#define CHMOD_YES 0666
#define CHMOD_NO 0
#endif
#ifdef ANSI
void error(char *str,...);
void starttime(void);
void endtime(struct timeval *tv);
void printtimes(struct timeval *tv, long nbytes);
void testdir(char *dir);
int mtestdir(char *dir);
long getparm(char *parm, long min, char *label);
void complete(void);
int unix_chdir(char *path);
void dirtree(int lev, int files, int dirs, char *fname, char *dname, int *totfiles, int *totdirs);
void rmdirtree(int lev, int files, int dirs, char *fname, char *dname, int *totfiles, int *totdirs, int ignore);
#ifdef DOS
char *getwd(char *path);
#endif
int unix_chmod(char *path, int mode);
#endif
extern int errno;
extern char *Myname; /* name I was invoked with (for error msgs) */
e 't'./basic/unixdos.h 664 20115 11 6727 4552130404 7233 struct timeval
{
long tv_sec; /* seconds since midnight (unlike Unix) */
long tv_usec; /* and microseconds */
};
typedef unsigned char u_char;
#define MAXPATHLEN 256 /* tune later */
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
void gettimeofday(struct timeval *TV, struct timezone *TimeZone);
int unix_chdir(char * path);
char * getwd(char * path);
int unix_chmod(char * path, int mode);
int lstat(char *path, struct stat *buf);
/************************************************************
statfs stuff
************************************************************/
typedef struct {
long val[2];
} fsid_t;
struct statfs {
long f_type; /* type of info, zero for now */
long f_bsize; /* fundamental file system block size */
long f_blocks; /* total blocks in file system */
long f_bfree; /* free blocks */
long f_bavail; /* free blocks available to non-super-user */
long f_files; /* total file nodes in file system */
long f_ffree; /* free file nodes in fs */
fsid_t f_fsid; /* file system id */
long f_spare[7]; /* spare for later */
};
int statfs(char *path, struct statfs *buf);
/************************************************************
From /usr/include/directory.h, simplified:
************************************************************/
#ifndef __dirent_h
#define __dirent_h
/*
* Definitions for library routines operating on directories.
*/
typedef int DIR; /* just a dummy */
DIR *opendir(char *dirname);
struct dirent *readdir(DIR *dirp);
void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#ifndef _POSIX_SOURCE
void seekdir(DIR *dirp, long loc);
long telldir(DIR *dirp);
#endif /* POSIX_SOURCE */
#endif /* !__dirent_h */
/*************************************************************
From /usr/include/sys/dirent.h:
*************************************************************/
/*
* Filesystem-independent directory information.
* Directory entry structures are of variable length.
* Each directory entry is a struct dirent containing its file number, the
* offset of the next entry (a cookie interpretable only the filesystem
* type that generated it), the length of the entry, and the length of the
* name contained in the entry. These are followed by the name. The
* entire entry is padded with null bytes to a 4 byte boundary. All names
* are guaranteed null terminated. The maximum length of a name in a
* directory is MAXNAMLEN, plus a null byte.
*/
#ifndef __sys_dirent_h
#define __sys_dirent_h
struct dirent {
/* just need d_name field for Cthon tests */
char d_name[13]; /* name (up to MAXNAMLEN + 1) */
};
#ifndef _POSIX_SOURCE
/*
* It's unlikely to change, but make sure that sizeof d_name above is
* at least MAXNAMLEN + 1 (more may be added for padding).
*/
#define MAXNAMLEN 255
/*
* The macro DIRSIZ(dp) gives the minimum amount of space required to represent
* a directory entry. For any directory entry dp->d_reclen >= DIRSIZ(dp).
* Specific filesystem types may use this macro to construct the value
* for d_reclen.
*/
#undef DIRSIZ
#define DIRSIZ(dp) \
(((sizeof(struct dirent) - (MAXNAMLEN+1) + ((dp)->d_namlen+1)) +3) & ~3)
#endif /* !_POSIX_SOURCE */
#endif /* !__sys_dirent_h */
if /* DOS */
* sets the struct tv ./basic/subr.obj 777 20115 11 35434 4552136064 7072 � subr.c%� MS Cn� �SLIBCE� �0s3� �CV7�N DGROUP_TEXTCODE_DATADATACONST_BSSBSS$$TYPESDEBTYP $$SYMBOLSDEBSYM)� H� H�� H
� H �� o
��
� ���V�
@E��
__acrtused _statfs _fflush _opendir _atol _readdir __ctype
_rewinddir _exit _fprintf _error _closedir
_starttime _endtime _seekdir _getenv _telldir _printtimes _chdir _testdir _getcwd _mtestdir _mkdir _malloc _rmdir _chmod _perror _getparm �� _pattern�b�� n� _complete _close $� _findtst�hb,g� _creat ��. _maxentry��b
_currententry��b_dirlist��b�� __chkstk � _dirst��bT� __aNldiv E� copynametolower Ì _dirtree _sprintf _system �� findt_to_dirent __dos_findfirst
_gettimeofday __dos_findnext _unlink __aNulmul _unix_chdir __dos_getdrive _getwd
_rmdirtree __dos_getdiskfree _unix_chmod _strcat
__dos_gettime ��
_Myname��b�B _lstat _chdrive _stat _errno _strcpy __dos_setdrive __iob ϐ� _statfsg�_opendir] �_readdir5�'
_rewinddir?
�_error��� _closedir��.
_starttime���_endtime���_seekdir�
�$_telldir�
�"_printtimesl��_testdir��� _mtestdir���_getparm"�� _complete
��Ґ _diropen���� copynametolower��,d� _dirtree ��� findt_to_dirent{�)��g
_gettimeofday���_unix_chdirD��_getwdj��
_rmdirtree���_unix_chmod���_lstat���_chdrive��枈 �Ѡ %s%d creat %s failed close %d failed %s%d mkdir %s failed chdir %s failed .. chdir .. failed %s%d unlink %s failed %s%d chdir %s failed .. chdir .. failed rmdir %s failed %s: getwd failed
%s: (%s)
in %ld.%-2ld seconds (%ld bytes/sec) NFSTESTDIR o:\nfstestd rm -r %s can't remove old test directory %s can't create test directory %s can't chdir to test directory %s NFSTESTDIR o:\nfstestd can't chdir to test directory %s Illegal %s parameter %ld, must be at least %ld can't change to drive %c: %s ok.
\*.* y� rewind failed 4� P� � dirtree�� �V)� U��� WV0� �V%Y�� � lev � files
� dirs
� fname � dname � totfiles
� totdirs��� fd��� f��� d
��nameΜ �V)�z �F�N= t� �edž�� � �����F9���|�| �����v
� P�� �P� ����P�� �P� ������= |� �� �P� P� ��� P� ���^������ ��= |� ����� P� ��� P� ���t�dž�� � �����F9���|� �����v�% P�� �P� ���� �P� ��= |� �� �P�* P� ��� P� ���^��� �P� ��= |� �� �P�: P� ��� P� ���v�v�v�v
�v�v�v�����J P� ��= |� �M P� ��� P� ���9�S�] �nV �dV�`��RV2�N��-V �#V���V2��V ��V��V��V*�ǝ��V ��VĐ��~V�oV �eV�a��JV!�;V*�2�B� � �� và
�^_��]� �� � dirtree�� �V)� � �� � rmdirtree� �V5� �U��� WV�� �V%Y�� � � lev � files
� dirs
� fname � dname � totfiles
� totdirs � ignore��� f��� d
��nameQ� �V5�X��F�N= t� �Kdž�� � �����F9���|�S �����v
�] P�� �P� ���� �P� ��= |�"