#include <roken.h>
-#include <stdio.h>
#ifdef AFS_NT40_ENV
#include <windows.h>
#define _CRT_RAND_S
-#include <process.h>
#include <afs/smb_iocons.h>
#include <afs/afsd.h>
#include <afs/cm_ioctl.h>
#include <afs/pioctl_nt.h>
#include <WINNT/syscfg.h>
#else
-#include <netdb.h>
#include <afs/afsint.h>
#define FSINT_COMMON_XG 1
#endif
-#include <sys/stat.h>
+
+#include <afs/opr.h>
#include <afs/cmd.h>
#include <afs/auth.h>
#include <afs/vlserver.h>
#include <afs/ihandle.h>
#include <afs/com_err.h>
#include <afs/afscp.h>
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
+
#ifdef HAVE_DIRECT_H
#include <direct.h>
#endif
-#ifdef AFS_DARWIN_ENV
-#include <sys/malloc.h>
-#else
-#include <malloc.h>
-#endif
#include <hcrypto/md5.h>
#ifdef AFS_PTHREAD_ENV
-#include <assert.h>
pthread_key_t uclient_key;
#endif
+static int lockFile(struct cmd_syndesc *, void *);
static int readFile(struct cmd_syndesc *, void *);
static int writeFile(struct cmd_syndesc *, void *);
static void printDatarate(void);
static int ScanFid(char *, struct AFSFid *);
static afs_int32 GetVenusFidByFid(char *, char *, int, struct afscp_venusfid **);
static afs_int32 GetVenusFidByPath(char *, char *, struct afscp_venusfid **);
-static int BreakUpPath(char *, char *, char *);
+static int BreakUpPath(char *, char *, char *, size_t);
static char pnp[AFSPATHMAX]; /* filename of this program when called */
static int verbose = 0; /* Set if -verbose option given */
+static int clear = 0; /* Set if -clear option given,
+ Unset if -crypt given; default is -crypt */
static int cellGiven = 0; /* Set if -cell option given */
static int force = 0; /* Set if -force option given */
+static int readlock = 0; /* Set if -readlock option given */
+static int waittime = 0; /* Set if -waittime option given */
static int useFid = 0; /* Set if fidwrite/fidread/fidappend invoked */
static int append = 0; /* Set if append/fidappend invoked */
static struct timeval starttime, opentime, readtime, writetime;
if (pdp->items != NULL) {
if (strcmp(pdp->name, "-verbose") == 0)
verbose = 1;
+ if (strcmp(pdp->name, "-clear") == 0)
+ clear = 1;
+ if (strcmp(pdp->name, "-crypt") == 0)
+ clear = 0;
else if (strcmp(pdp->name, "-md5") == 0)
md5sum = 1; /* global */
else if (strcmp(pdp->name, "-cell") == 0) {
*slp = pdp->items->data;
else if (strcmp(pdp->name, "-realm") == 0)
*realmp = pdp->items->data;
+ else if (strcmp(pdp->name, "-wait") == 0)
+ waittime = atoi(pdp->items->data);
+ else if (strcmp(pdp->name, "-readlock") == 0)
+ readlock = 1;
}
}
return 0;
int
main(int argc, char **argv)
{
- afs_int32 code = 0;
struct cmd_syndesc *ts;
char baseName[AFSNAMEMAX];
/* try to get only the base name of this executable for use in logs */
- if (BreakUpPath(argv[0], NULL, baseName) > 0)
+ if (BreakUpPath(argv[0], NULL, baseName, AFSNAMEMAX) > 0)
strlcpy(pnp, baseName, AFSNAMEMAX);
else
strlcpy(pnp, argv[0], AFSPATHMAX);
#ifdef AFS_PTHREAD_ENV
- assert(pthread_key_create(&uclient_key, NULL) == 0);
+ opr_Verify(pthread_key_create(&uclient_key, NULL) == 0);
#endif
- ts = cmd_CreateSyntax("read", readFile, CMD_REQUIRED,
+ ts = cmd_CreateSyntax("lock", lockFile, (void *)LockWrite,
+ "lock a file in AFS");
+ cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename");
+ cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
+ cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_Seek(ts, 4);
+ cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
+ cmd_AddParm(ts, "-waitseconds", CMD_SINGLE, CMD_OPTIONAL, "seconds to wait before giving up");
+ cmd_AddParm(ts, "-readlock", CMD_FLAG, CMD_OPTIONAL, "read lock only");
+
+ ts = cmd_CreateSyntax("fidlock", lockFile, (void *)LockWrite,
+ "lock by FID a file from AFS");
+ cmd_IsAdministratorCommand(ts);
+ cmd_AddParm(ts, "-fid", CMD_SINGLE, CMD_REQUIRED,
+ "volume.vnode.uniquifier");
+ cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
+ cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_Seek(ts, 4);
+ cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
+ cmd_AddParm(ts, "-waitseconds", CMD_SINGLE, CMD_OPTIONAL, "seconds to wait before giving up");
+ cmd_AddParm(ts, "-readlock", CMD_FLAG, CMD_OPTIONAL, "read lock only");
+
+ ts = cmd_CreateSyntax("unlock", lockFile, (void *)LockRelease,
+ "unlock a file in AFS");
+ cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename");
+ cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
+ cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_Seek(ts, 4);
+ cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
+ cmd_AddParm(ts, "-waitseconds", CMD_SINGLE, CMD_OPTIONAL, "seconds to wait before giving up");
+
+ ts = cmd_CreateSyntax("fidunlock", lockFile, (void *)LockRelease,
+ "unlock by FID a file from AFS");
+ cmd_IsAdministratorCommand(ts);
+ cmd_AddParm(ts, "-fid", CMD_SINGLE, CMD_REQUIRED,
+ "volume.vnode.uniquifier");
+ cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
+ cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_Seek(ts, 4);
+ cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
+ cmd_AddParm(ts, "-waitseconds", CMD_SINGLE, CMD_OPTIONAL, "seconds to wait before giving up");
+
+ ts = cmd_CreateSyntax("read", readFile, NULL,
"read a file from AFS");
cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename");
cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
"volume.vnode.uniquifier");
cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
- ts = cmd_CreateSyntax("write", writeFile, CMD_REQUIRED,
+ ts = cmd_CreateSyntax("write", writeFile, NULL,
"write a file into AFS");
cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename");
cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
"overwrite existing file");
"volume.vnode.uniquifier");
cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
cmd_AddParm(ts, "-md5", CMD_FLAG, CMD_OPTIONAL, "calculate md5 checksum");
cmd_AddParm(ts, "-force", CMD_FLAG, CMD_OPTIONAL,
"overwrite existing file");
cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
- ts = cmd_CreateSyntax("append", writeFile, CMD_REQUIRED,
+ ts = cmd_CreateSyntax("append", writeFile, NULL,
"append to a file in AFS");
cmd_AddParm(ts, "-file", CMD_SINGLE, CMD_REQUIRED, "AFS-filename");
cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
- ts = cmd_CreateSyntax("fidappend", writeFile, CMD_REQUIRED,
+ ts = cmd_CreateSyntax("fidappend", writeFile, NULL,
"append to a file in AFS");
cmd_IsAdministratorCommand(ts);
cmd_AddParm(ts, "-vnode", CMD_SINGLE, CMD_REQUIRED,
"volume.vnode.uniquifier");
cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cellname");
cmd_AddParm(ts, "-verbose", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-clear", CMD_FLAG, CMD_OPTIONAL, (char *)0);
+ cmd_AddParm(ts, "-crypt", CMD_FLAG, CMD_OPTIONAL, (char *)0);
cmd_AddParm(ts, "-realm", CMD_SINGLE, CMD_OPTIONAL, "REALMNAME");
if (afscp_Init(NULL) != 0)
exit(1);
- code = cmd_Dispatch(argc, argv);
+ cmd_Dispatch(argc, argv);
afscp_Finalize();
exit(0);
struct afscp_volume *avolp;
if (*avfpp == NULL) {
- *avfpp = malloc(sizeof(struct afscp_venusfid));
+ *avfpp = calloc(1, sizeof(struct afscp_venusfid));
if ( *avfpp == NULL ) {
code = ENOMEM;
return code;
}
}
- memset(*avfpp, 0, sizeof(struct afscp_venusfid));
if (cellName == NULL) {
(*avfpp)->cell = afscp_DefaultCell();
* 2 if both dirName and baseName were filled in
*/
static int
-BreakUpPath(char *fullPath, char *dirName, char *baseName)
+BreakUpPath(char *fullPath, char *dirName, char *baseName, size_t baseNameSize)
{
char *lastSlash;
size_t dirNameLen = 0;
/* then lastSlash points to the last path separator in fullPath */
if (useDirName) {
dirNameLen = strlen(fullPath) - strlen(lastSlash);
- strlcpy(dirName, fullPath, dirNameLen + 1);
+ strlcpy(dirName, fullPath, min(dirNameLen + 1, baseNameSize));
code++;
}
if (useBaseName) {
lastSlash++;
- strlcpy(baseName, lastSlash, strlen(lastSlash) + 1);
+ strlcpy(baseName, lastSlash, min(strlen(lastSlash) + 1, baseNameSize));
code++;
}
} else {
/* there are no path separators in fullPath -- it's just a baseName */
if (useBaseName) {
- strlcpy(baseName, fullPath, strlen(fullPath) + 1);
+ strlcpy(baseName, fullPath, min(strlen(fullPath) + 1, baseNameSize));
code++;
}
}
} /* GetVenusFidByPath */
static int
+lockFile(struct cmd_syndesc *as, void *arock)
+{
+ char *fname = NULL;
+ char *cell = NULL;
+ char *realm = NULL;
+ afs_int32 code = 0;
+ struct AFSFetchStatus OutStatus;
+ struct afscp_venusfid *avfp = NULL;
+ char *buf = 0;
+ char ipv4_addr[16];
+ int locktype = (int)(intptr_t) arock;
+
+#ifdef AFS_NT40_ENV
+ /* stdout on Windows defaults to _O_TEXT mode */
+ _setmode(1, _O_BINARY);
+#endif
+
+ gettimeofday(&starttime, &Timezone);
+
+ CmdProlog(as, &cell, &realm, &fname, NULL);
+ afscp_AnonymousAuth(1);
+ if (clear)
+ afscp_Insecure();
+
+ if ((locktype == LockWrite) && readlock)
+ locktype = LockRead;
+
+ if (realm != NULL)
+ code = afscp_SetDefaultRealm(realm);
+
+ if (cell != NULL)
+ code = afscp_SetDefaultCell(cell);
+
+ if (useFid)
+ code = GetVenusFidByFid(fname, cell, 0, &avfp);
+ else
+ code = GetVenusFidByPath(fname, cell, &avfp);
+ if (code != 0) {
+ afs_com_err(pnp, code, "(file not found: %s)", fname);
+ return code;
+ }
+
+retry:
+ code = afscp_GetStatus(avfp, &OutStatus);
+ if (code != 0) {
+ afs_inet_ntoa_r(avfp->cell->fsservers[0]->addrs[0], ipv4_addr);
+ afs_com_err(pnp, code, "(failed to get status of file %s from"
+ "server %s, code = %d)", fname, ipv4_addr, code);
+ afscp_FreeFid(avfp);
+ return code;
+ }
+
+ if (locktype != LockRelease) {
+ while (OutStatus.lockCount != 0) {
+ code = afscp_WaitForCallback(avfp, waittime);
+ if ((code == -1) && (afscp_errno == ETIMEDOUT))
+ break;
+ if ((code = afscp_GetStatus(avfp, &OutStatus)) != 0)
+ break;
+ }
+ } else {
+ if (OutStatus.lockCount == 0) {
+ code = -1;
+ }
+ }
+
+ if (!code) {
+ code = afscp_Lock(avfp, locktype);
+ if ((code == -1) && (afscp_errno == EWOULDBLOCK))
+ goto retry;
+ }
+ afscp_FreeFid(avfp);
+
+ if (buf != NULL)
+ free(buf);
+
+ if (code != 0)
+ afs_com_err(pnp, code, "(failed to change lock status: %d)", afscp_errno);
+
+ return code;
+} /* lockFile */
+
+static int
readFile(struct cmd_syndesc *as, void *unused)
{
char *fname = NULL;
CmdProlog(as, &cell, &realm, &fname, NULL);
afscp_AnonymousAuth(1);
+ if (clear)
+ afscp_Insecure();
if (md5sum)
MD5_Init(&md5);
Len <<= 32;
Len += OutStatus.Length;
ZeroInt64(Pos);
- buf = (char *) malloc(bufflen * sizeof(char));
+ buf = calloc(bufflen, sizeof(char));
if (buf == NULL) {
code = ENOMEM;
afs_com_err(pnp, code, "(cannot allocate buffer)");
afscp_FreeFid(avfp);
return code;
}
- memset(buf, 0, bufflen * sizeof(char));
length = Len;
while (!code && NonZeroInt64(length)) {
if (length > bufflen)
CmdProlog(as, &cell, &realm, &fname, &sSynthLen);
afscp_AnonymousAuth(1);
+ if (clear)
+ afscp_Insecure();
if (realm != NULL)
code = afscp_SetDefaultRealm(realm);
}
}
if (!append && !overWrite) { /* must create a new file in this case */
- if ( BreakUpPath(fname, dirName, baseName) != 2 ) {
+ if ( BreakUpPath(fname, dirName, baseName, AFSNAMEMAX) != 2 ) {
code = EINVAL;
afs_com_err(pnp, code, "(must provide full AFS path)");
afscp_FreeFid(newvfp);
gettimeofday(&starttime, &Timezone);
InStatus.UnixModeBits = 0644;
+ InStatus.Mask = AFS_SETMODE + AFS_FSYNC;
if (newvfp == NULL) {
code = afscp_CreateFile(dirvfp, baseName, &InStatus, &newvfp);
if (code != 0) {
return code;
}
- InStatus.Mask = AFS_SETMODE + AFS_FSYNC;
if (append) {
Pos = OutStatus.Length_hi;
Pos = (Pos << 32) | OutStatus.Length;
*/
Len = 0;
while (Len < WRITEBUFLEN) {
- tbuf = (struct wbuf *)malloc(sizeof(struct wbuf));
+ tbuf = calloc(1, sizeof(struct wbuf));
if (tbuf == NULL) {
if (!bufchain) {
code = ENOMEM;
}
break;
}
- memset(tbuf, 0, sizeof(struct wbuf));
tbuf->buflen = BUFFLEN;
if (synthesize) {
afs_int64 ll, l = tbuf->buflen;