Bug Summary

File:venus/./afsio.c
Location:line 831, column 2
Description:Value stored to 'code' is never read

Annotated Source Code

1/*
2 * Copyright (c) 2007, Hartmut Reuter,
3 * RZG, Max-Planck-Institut f. Plasmaphysik.
4 * All Rights Reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28 * Revised in 2010 by Chaz Chandler to enhance clientless operations.
29 * Now utilizes libafscp by Chaskiel Grundman.
30 * Work funded in part by Sine Nomine Associates (http://www.sinenomine.net/)
31 */
32
33#include <afsconfig.h>
34#include <afs/param.h>
35#include <afs/stds.h>
36
37#include <roken.h>
38
39#include <stdio.h>
40#ifdef AFS_NT40_ENV
41#include <windows.h>
42#define _CRT_RAND_S
43#include <process.h>
44#include <afs/smb_iocons.h>
45#include <afs/afsd.h>
46#include <afs/cm_ioctl.h>
47#include <afs/pioctl_nt.h>
48#include <WINNT/syscfg.h>
49#else
50#include <netdb.h>
51#include <afs/afsint.h>
52#define FSINT_COMMON_XG1 1
53#endif
54#include <sys/stat.h>
55#include <afs/cmd.h>
56#include <afs/auth.h>
57#include <afs/vlserver.h>
58#include <afs/ihandle.h>
59#include <afs/com_err.h>
60#include <afs/afscp.h>
61#ifdef HAVE_DIRENT_H1
62#include <dirent.h>
63#endif
64#ifdef HAVE_DIRECT_H
65#include <direct.h>
66#endif
67#include <hcrypto/md5.h>
68#ifdef AFS_PTHREAD_ENV1
69#include <assert.h>
70pthread_key_t uclient_key;
71#endif
72
73static int lockFile(struct cmd_syndesc *, void *);
74static int readFile(struct cmd_syndesc *, void *);
75static int writeFile(struct cmd_syndesc *, void *);
76static void printDatarate(void);
77static void summarizeDatarate(struct timeval *, const char *);
78static int CmdProlog(struct cmd_syndesc *, char **, char **,
79 char **, char **);
80static int ScanFid(char *, struct AFSFid *);
81static afs_int32 GetVenusFidByFid(char *, char *, int, struct afscp_venusfid **);
82static afs_int32 GetVenusFidByPath(char *, char *, struct afscp_venusfid **);
83static int BreakUpPath(char *, char *, char *);
84
85static char pnp[AFSPATHMAX1024]; /* filename of this program when called */
86static int verbose = 0; /* Set if -verbose option given */
87static int cellGiven = 0; /* Set if -cell option given */
88static int force = 0; /* Set if -force option given */
89static int readlock = 0; /* Set if -readlock option given */
90static int waittime = 0; /* Set if -waittime option given */
91static int useFid = 0; /* Set if fidwrite/fidread/fidappend invoked */
92static int append = 0; /* Set if append/fidappend invoked */
93static struct timeval starttime, opentime, readtime, writetime;
94static afs_uint64 xfered = 0;
95static struct timeval now;
96#ifdef AFS_NT40_ENV
97static int Timezone; /* Roken gettimeofday ignores the timezone */
98#else
99static struct timezone Timezone;
100#endif
101
102#define BUFFLEN65536 65536
103#define WRITEBUFLEN(65536 * 1024) (BUFFLEN65536 * 1024)
104#define MEGABYTE_F1048576.0f 1048576.0f
105
106static MD5_CTX md5;
107static int md5sum = 0; /* Set if -md5 option given */
108
109struct wbuf {
110 struct wbuf *next;
111 afs_uint32 offset; /* offset inside the buffer */
112 afs_uint32 buflen; /* total length == BUFFLEN */
113 afs_uint32 used; /* bytes used inside buffer */
114 char buf[BUFFLEN65536];
115};
116
117/*!
118 * returns difference in seconds between two times
119 *
120 * \param[in] from start time
121 * \param[in] to end time
122 *
123 * \post returns "to" minus "from" in seconds
124 *
125 */
126static_inlinestatic inline float
127time_elapsed(struct timeval *from, struct timeval *to)
128{
129 return (float)(to->tv_sec + (to->tv_usec * 0.000001) - from->tv_sec -
130 (from->tv_usec * 0.000001));
131} /* time_elapsed */
132
133/*!
134 * prints current average data transfer rate at no less than 30-second intervals
135 */
136static void
137printDatarate(void)
138{
139 static float oldseconds = 0.0;
140 static afs_uint64 oldxfered = 0;
141 float seconds;
142
143 gettimeofday(&now, &Timezone);
144 seconds = time_elapsed(&opentime, &now);
145 if ((seconds - oldseconds) > 30) {
146 fprintf(stderr__stderrp, "%llu MB transferred, present data rate = %.3f MB/sec.\n", xfered >> 20, /* total bytes transferred, in MB */
147 (xfered - oldxfered) / (seconds - oldseconds) / MEGABYTE_F1048576.0f);
148 oldxfered = xfered;
149 oldseconds = seconds;
150 }
151} /* printDatarate */
152
153/*!
154 * prints overall average data transfer rate and elapsed time
155 *
156 * \param[in] tvp current time (to compare with file open time)
157 * \param[in] xfer_type string identify transfer type ("read" or "write")
158 */
159static void
160summarizeDatarate(struct timeval *tvp, const char *xfer_type)
161{
162 float seconds = time_elapsed(&opentime, tvp);
163
164 fprintf(stderr__stderrp, "Transfer of %llu bytes took %.3f sec.\n",
165 xfered, seconds);
166 fprintf(stderr__stderrp, "Total data rate = %.03f MB/sec. for %s\n",
167 xfered / seconds / MEGABYTE_F1048576.0f, xfer_type);
168} /* summarizeDatarate */
169
170/*!
171 * prints final MD5 sum of all file data transferred
172 *
173 * \param[in] fname file name or FID
174 */
175static void
176summarizeMD5(char *fname)
177{
178 afs_uint32 md5int[4];
179 char *p;
180
181 MD5_Finalhc_MD5_Final((char *) &md5int[0], &md5);
182 p = fname + strlen(fname);
183 while (p > fname) {
184 if (*(--p) == '/') {
185 ++p;
186 break;
187 }
188 }
189 fprintf(stderr__stderrp, "%08x%08x%08x%08x %s\n", htonl(md5int[0])(__builtin_constant_p(md5int[0]) ? ((((__uint32_t)(md5int[0])
) >> 24) | ((((__uint32_t)(md5int[0])) & (0xff <<
16)) >> 8) | ((((__uint32_t)(md5int[0])) & (0xff <<
8)) << 8) | (((__uint32_t)(md5int[0])) << 24)) :
__bswap32_var(md5int[0]))
,
190 htonl(md5int[1])(__builtin_constant_p(md5int[1]) ? ((((__uint32_t)(md5int[1])
) >> 24) | ((((__uint32_t)(md5int[1])) & (0xff <<
16)) >> 8) | ((((__uint32_t)(md5int[1])) & (0xff <<
8)) << 8) | (((__uint32_t)(md5int[1])) << 24)) :
__bswap32_var(md5int[1]))
, htonl(md5int[2])(__builtin_constant_p(md5int[2]) ? ((((__uint32_t)(md5int[2])
) >> 24) | ((((__uint32_t)(md5int[2])) & (0xff <<
16)) >> 8) | ((((__uint32_t)(md5int[2])) & (0xff <<
8)) << 8) | (((__uint32_t)(md5int[2])) << 24)) :
__bswap32_var(md5int[2]))
, htonl(md5int[3])(__builtin_constant_p(md5int[3]) ? ((((__uint32_t)(md5int[3])
) >> 24) | ((((__uint32_t)(md5int[3])) & (0xff <<
16)) >> 8) | ((((__uint32_t)(md5int[3])) & (0xff <<
8)) << 8) | (((__uint32_t)(md5int[3])) << 24)) :
__bswap32_var(md5int[3]))
, p);
191} /* summarizeMD5 */
192
193/*!
194 * parses all command-line arguments
195 *
196 * \param[in] as arguments list
197 * \param[out] cellp cell name
198 * \param[out] realmp realm name
199 * \param[out] fnp filename (either fid or path)
200 * \param[out] slp "synthesized" (made up) data given
201 *
202 * \post returns 0 on success or -1 on error
203 *
204 */
205static int
206CmdProlog(struct cmd_syndesc *as, char **cellp, char **realmp,
207 char **fnp, char **slp)
208{
209 int i;
210 struct cmd_parmdesc *pdp;
211
212 if (as == NULL((void *)0)) {
213 afs_com_err(pnp, EINVAL22, "(syndesc is null)");
214 return -1;
215 }
216
217 /* determine which command was requested */
218 if (strncmp(as->name, "fid", 3) == 0) /* fidread/fidwrite/fidappend */
219 useFid = 1;
220 if ( (strcmp(as->name, "append") == 0) ||
221 (strcmp(as->name, "fidappend") == 0) )
222 append = 1; /* global */
223
224 /* attempts to ensure loop is bounded: */
225 for (pdp = as->parms, i = 0; pdp && (i < as->nParms); i++, pdp++) {
226 if (pdp->items != NULL((void *)0)) {
227 if (strcmp(pdp->name, "-verbose") == 0)
228 verbose = 1;
229 else if (strcmp(pdp->name, "-md5") == 0)
230 md5sum = 1; /* global */
231 else if (strcmp(pdp->name, "-cell") == 0) {
232 cellGiven = 1; /* global */
233 *cellp = pdp->items->data;
234 } else if ( (strcmp(pdp->name, "-file") == 0) ||
235 (strcmp(pdp->name, "-fid") == 0) ||
236 (strcmp(pdp->name, "-vnode") == 0) )
237 *fnp = pdp->items->data;
238 else if (strcmp(pdp->name, "-force") == 0)
239 force = 1; /* global */
240 else if (strcmp(pdp->name, "-synthesize") == 0)
241 *slp = pdp->items->data;
242 else if (strcmp(pdp->name, "-realm") == 0)
243 *realmp = pdp->items->data;
244 else if (strcmp(pdp->name, "-wait") == 0)
245 waittime = atoi(pdp->items->data);
246 else if (strcmp(pdp->name, "-readlock") == 0)
247 readlock = 1;
248 }
249 }
250 return 0;
251} /* CmdProlog */
252
253int
254main(int argc, char **argv)
255{
256 struct cmd_syndesc *ts;
257 char baseName[AFSNAMEMAX256];
258
259 /* try to get only the base name of this executable for use in logs */
260 if (BreakUpPath(argv[0], NULL((void *)0), baseName) > 0)
261 strlcpy(pnp, baseName, AFSNAMEMAX256);
262 else
263 strlcpy(pnp, argv[0], AFSPATHMAX1024);
264
265#ifdef AFS_PTHREAD_ENV1
266 assert(pthread_key_create(&uclient_key, NULL) == 0)((pthread_key_create(&uclient_key, ((void *)0)) == 0) ? (
void)0 : __assert(__func__, "./afsio.c", 266, "pthread_key_create(&uclient_key, NULL) == 0"
))
;
267#endif
268
269 ts = cmd_CreateSyntax("lock", lockFile, (void *)LockWrite1,
270 "lock a file in AFS");
271 cmd_AddParm(ts, "-file", CMD_SINGLE2, CMD_REQUIRED0, "AFS-filename");
272 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
273 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
274 cmd_Seek(ts, 4);
275 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
276 cmd_AddParm(ts, "-waitseconds", CMD_SINGLE2, CMD_OPTIONAL1, "seconds to wait before giving up");
277 cmd_AddParm(ts, "-readlock", CMD_FLAG1, CMD_OPTIONAL1, "read lock only");
278
279 ts = cmd_CreateSyntax("fidlock", lockFile, (void *)LockWrite1,
280 "lock by FID a file from AFS");
281 cmd_IsAdministratorCommand(ts);
282 cmd_AddParm(ts, "-fid", CMD_SINGLE2, CMD_REQUIRED0,
283 "volume.vnode.uniquifier");
284 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
285 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
286 cmd_Seek(ts, 4);
287 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
288 cmd_AddParm(ts, "-waitseconds", CMD_SINGLE2, CMD_OPTIONAL1, "seconds to wait before giving up");
289 cmd_AddParm(ts, "-readlock", CMD_FLAG1, CMD_OPTIONAL1, "read lock only");
290
291 ts = cmd_CreateSyntax("unlock", lockFile, (void *)LockRelease3,
292 "unlock a file in AFS");
293 cmd_AddParm(ts, "-file", CMD_SINGLE2, CMD_REQUIRED0, "AFS-filename");
294 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
295 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
296 cmd_Seek(ts, 4);
297 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
298 cmd_AddParm(ts, "-waitseconds", CMD_SINGLE2, CMD_OPTIONAL1, "seconds to wait before giving up");
299
300 ts = cmd_CreateSyntax("fidunlock", lockFile, (void *)LockRelease3,
301 "unlock by FID a file from AFS");
302 cmd_IsAdministratorCommand(ts);
303 cmd_AddParm(ts, "-fid", CMD_SINGLE2, CMD_REQUIRED0,
304 "volume.vnode.uniquifier");
305 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
306 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
307 cmd_Seek(ts, 4);
308 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
309 cmd_AddParm(ts, "-waitseconds", CMD_SINGLE2, CMD_OPTIONAL1, "seconds to wait before giving up");
310
311 ts = cmd_CreateSyntax("read", readFile, NULL((void *)0),
312 "read a file from AFS");
313 cmd_AddParm(ts, "-file", CMD_SINGLE2, CMD_REQUIRED0, "AFS-filename");
314 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
315 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
316 cmd_AddParm(ts, "-md5", CMD_FLAG1, CMD_OPTIONAL1, "calculate md5 checksum");
317 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
318
319 ts = cmd_CreateSyntax("fidread", readFile, CMD_REQUIRED0,
320 "read on a non AFS-client a file from AFS");
321 cmd_IsAdministratorCommand(ts);
322 cmd_AddParm(ts, "-fid", CMD_SINGLE2, CMD_REQUIRED0,
323 "volume.vnode.uniquifier");
324 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
325 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
326 cmd_AddParm(ts, "-md5", CMD_FLAG1, CMD_OPTIONAL1, "calculate md5 checksum");
327 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
328
329 ts = cmd_CreateSyntax("write", writeFile, NULL((void *)0),
330 "write a file into AFS");
331 cmd_AddParm(ts, "-file", CMD_SINGLE2, CMD_REQUIRED0, "AFS-filename");
332 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
333 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
334 cmd_AddParm(ts, "-md5", CMD_FLAG1, CMD_OPTIONAL1, "calculate md5 checksum");
335 cmd_AddParm(ts, "-force", CMD_FLAG1, CMD_OPTIONAL1,
336 "overwrite existing file");
337 cmd_AddParm(ts, "-synthesize", CMD_SINGLE2, CMD_OPTIONAL1,
338 "create data pattern of specified length instead reading from stdin");
339 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
340
341 ts = cmd_CreateSyntax("fidwrite", writeFile, CMD_REQUIRED0,
342 "write a file into AFS");
343 cmd_IsAdministratorCommand(ts);
344 cmd_AddParm(ts, "-vnode", CMD_SINGLE2, CMD_REQUIRED0,
345 "volume.vnode.uniquifier");
346 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
347 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
348 cmd_AddParm(ts, "-md5", CMD_FLAG1, CMD_OPTIONAL1, "calculate md5 checksum");
349 cmd_AddParm(ts, "-force", CMD_FLAG1, CMD_OPTIONAL1,
350 "overwrite existing file");
351 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
352
353 ts = cmd_CreateSyntax("append", writeFile, NULL((void *)0),
354 "append to a file in AFS");
355 cmd_AddParm(ts, "-file", CMD_SINGLE2, CMD_REQUIRED0, "AFS-filename");
356 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
357 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
358 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
359
360 ts = cmd_CreateSyntax("fidappend", writeFile, NULL((void *)0),
361 "append to a file in AFS");
362 cmd_IsAdministratorCommand(ts);
363 cmd_AddParm(ts, "-vnode", CMD_SINGLE2, CMD_REQUIRED0,
364 "volume.vnode.uniquifier");
365 cmd_AddParm(ts, "-cell", CMD_SINGLE2, CMD_OPTIONAL1, "cellname");
366 cmd_AddParm(ts, "-verbose", CMD_FLAG1, CMD_OPTIONAL1, (char *)0);
367 cmd_AddParm(ts, "-realm", CMD_SINGLE2, CMD_OPTIONAL1, "REALMNAME");
368
369 if (afscp_Init(NULL((void *)0)) != 0)
370 exit(1);
371
372 cmd_Dispatch(argc, argv);
373
374 afscp_Finalize();
375 exit(0);
376} /* main */
377
378/*!
379 * standardized way of parsing a File ID (FID) from command line input
380 *
381 * \param[in] fidString dot-delimited FID triple
382 * \param[out] fid pointer to the AFSFid to fill in
383 *
384 * \post The FID pointed to by "fid" is filled in which the parsed Volume,
385 * Vnode, and Uniquifier data. The string should be in the format
386 * of three numbers separated by dot (.) delimiters, representing
387 * (in order) the volume id, vnode number, and uniquifier.
388 * Example: "576821346.1.1"
389 */
390static int
391ScanFid(char *fidString, struct AFSFid *fid)
392{
393 int i = 0, code = 0;
394 long unsigned int f1, f2, f3;
395
396 if (fidString) {
397 i = sscanf(fidString, "%lu.%lu.%lu", &f1, &f2, &f3);
398 fid->Volume = (afs_uint32) f1;
399 fid->Vnode = (afs_uint32) f2;
400 fid->Unique = (afs_uint32) f3;
401 }
402 if (i != 3) {
403 fid->Volume = 0;
404 fid->Vnode = 0;
405 fid->Unique = 0;
406 code = EINVAL22;
407 afs_com_err(pnp, code, "(invalid FID triple: %s)", fidString);
408 }
409
410 return code;
411} /* ScanFid */
412
413/*!
414 * look up cell info and verify FID info from user input
415 *
416 * \param[in] fidString string containing FID info
417 * \param[in] cellName cell name string
418 * \param[in] onlyRW bool: 1 = RW vol only, 0 = any vol type
419 * \param[out] avfpp pointer to venusfid info
420 *
421 * \post *avfpp will contain the VenusFid info found for the FID
422 * given by the used in the string fidString and zero is
423 * returned. If not found, an appropriate afs error code
424 * is returned and *avfpp will be NULL.
425 *
426 * \note Any non-NULL avfpp returned should later be freed with
427 * afscp_FreeFid() when no longer needed.
428 */
429static afs_int32
430GetVenusFidByFid(char *fidString, char *cellName, int onlyRW,
431 struct afscp_venusfid **avfpp)
432{
433 afs_int32 code = 0;
434 struct stat sbuf;
435 struct afscp_volume *avolp;
436
437 if (*avfpp == NULL((void *)0)) {
438 *avfpp = malloc(sizeof(struct afscp_venusfid));
439 if ( *avfpp == NULL((void *)0) ) {
440 code = ENOMEM12;
441 return code;
442 }
443 }
444 memset(*avfpp, 0, sizeof(struct afscp_venusfid));
445
446 if (cellName == NULL((void *)0)) {
447 (*avfpp)->cell = afscp_DefaultCell();
448 } else {
449 (*avfpp)->cell = afscp_CellByName(cellName, NULL((void *)0));
450 }
451 if ((*avfpp)->cell == NULL((void *)0)) {
452 if (afscp_errno == 0)
453 code = EINVAL22;
454 else
455 code = afscp_errno;
456 return code;
457 }
458
459 code = ScanFid(fidString, &((*avfpp)->fid));
460 if (code != 0) {
461 code = EINVAL22;
462 return code;
463 }
464
465 avolp = afscp_VolumeById((*avfpp)->cell, (*avfpp)->fid.Volume);
466 if (avolp == NULL((void *)0)) {
467 if (afscp_errno == 0)
468 code = ENOENT2;
469 else
470 code = afscp_errno;
471 afs_com_err(pnp, code, "(finding volume %lu)",
472 afs_printable_uint32_lu((*avfpp)->fid.Volume));
473 return code;
474 }
475
476 if ( onlyRW && (avolp->voltype != RWVOL0) ) {
477 avolp = afscp_VolumeByName((*avfpp)->cell, avolp->name, RWVOL0);
478 if (avolp == NULL((void *)0)) {
479 if (afscp_errno == 0)
480 code = ENOENT2;
481 else
482 code = afscp_errno;
483 afs_com_err(pnp, code, "(finding volume %lu)",
484 afs_printable_uint32_lu((*avfpp)->fid.Volume));
485 return code;
486 }
487 (*avfpp)->fid.Volume = avolp->id; /* is this safe? */
488 }
489
490 code = afscp_Stat((*avfpp), &sbuf);
491 if (code != 0) {
492 afs_com_err(pnp, code, "(stat failed with code %d)", code);
493 return code;
494 }
495 return 0;
496} /* GetVenusFidByFid */
497
498/*!
499 * Split a full path up into dirName and baseName components
500 *
501 * \param[in] fullPath can be absolute, relative, or local
502 * \param[out] dirName pointer to allocated char buffer or NULL
503 * \param[out] baseName pointer to allocated char buffer or NULL
504 *
505 * \post To the fulleset extent possible, the rightmost full path
506 * component will be copied into baseName and all other
507 * components into dirName (minus the trailing path separator).
508 * If either dirName or baseName are NULL, only the non-NULL
509 * pointer will be filled in (but both can't be null or it would
510 * be pointless) -- so the caller can retrieve, say, only baseName
511 * if desired. The return code is the number of strings copied:
512 * 0 if neither dirName nor baseName could be filled in
513 * 1 if either dirName or baseName were filled in
514 * 2 if both dirName and baseName were filled in
515 */
516static int
517BreakUpPath(char *fullPath, char *dirName, char *baseName)
518{
519 char *lastSlash;
520 size_t dirNameLen = 0;
521 int code = 0, useDirName = 1, useBaseName = 1;
522
523 if (fullPath == NULL((void *)0)) {
524 return code;
525 }
526
527 if (dirName == NULL((void *)0))
528 useDirName = 0;
529 if (baseName == NULL((void *)0))
530 useBaseName = 0;
531 if (!useBaseName && !useDirName) {
532 /* would be pointless to continue -- must be error in call */
533 return code;
534 }
535#ifdef AFS_NT40_ENV
536 lastSlash = strrchr(fullPath, '\\');
537#else
538 lastSlash = strrchr(fullPath, '/');
539#endif
540 if (lastSlash != NULL((void *)0)) {
541 /* then lastSlash points to the last path separator in fullPath */
542 if (useDirName) {
543 dirNameLen = strlen(fullPath) - strlen(lastSlash);
544 strlcpy(dirName, fullPath, dirNameLen + 1);
545 code++;
546 }
547 if (useBaseName) {
548 lastSlash++;
549 strlcpy(baseName, lastSlash, strlen(lastSlash) + 1);
550 code++;
551 }
552 } else {
553 /* there are no path separators in fullPath -- it's just a baseName */
554 if (useBaseName) {
555 strlcpy(baseName, fullPath, strlen(fullPath) + 1);
556 code++;
557 }
558 }
559 return code;
560} /* BreakUpPath */
561
562/*!
563 * Get the VenusFid info available for the file at AFS path 'fullPath'.
564 * Works without pioctls/afsd by using libafscp. Analogous to
565 * get_file_cell() in the previous iteration of afsio.
566 *
567 * \param[in] fullPath the file name
568 * \param[in] cellName the cell name to look up
569 * \param[out] avfpp pointer to Venus FID info to be filled in
570 *
571 * \post If the path resolves successfully (using afscp_ResolvePath),
572 * then vfpp will contain the Venus FID info (cell info plus
573 * AFSFid) of the last path segment in fullPath.
574 */
575static afs_int32
576GetVenusFidByPath(char *fullPath, char *cellName,
577 struct afscp_venusfid **avfpp)
578{
579 afs_int32 code = 0;
580
581 if (fullPath == NULL((void *)0)) {
582 return -1;
583 }
584
585 if (cellName != NULL((void *)0)) {
586 code = (afs_int32) afscp_SetDefaultCell(cellName);
587 if (code != 0) {
588 return code;
589 }
590 }
591
592 *avfpp = afscp_ResolvePath(fullPath);
593 if (*avfpp == NULL((void *)0)) {
594 if (afscp_errno == 0)
595 code = ENOENT2;
596 else
597 code = afscp_errno;
598 }
599
600 return code;
601} /* GetVenusFidByPath */
602
603static int
604lockFile(struct cmd_syndesc *as, void *arock)
605{
606 char *fname = NULL((void *)0);
607 char *cell = NULL((void *)0);
608 char *realm = NULL((void *)0);
609 afs_int32 code = 0;
610 struct AFSFetchStatus OutStatus;
611 struct afscp_venusfid *avfp = NULL((void *)0);
612 char *buf = 0;
613 char ipv4_addr[16];
614 int locktype = (int)(intptr_t) arock;
615
616#ifdef AFS_NT40_ENV
617 /* stdout on Windows defaults to _O_TEXT mode */
618 _setmode(1, _O_BINARY);
619#endif
620
621 gettimeofday(&starttime, &Timezone);
622
623 CmdProlog(as, &cell, &realm, &fname, NULL((void *)0));
624 afscp_AnonymousAuth(1);
625
626 if ((locktype == LockWrite1) && readlock)
627 locktype = LockRead0;
628
629 if (realm != NULL((void *)0))
630 code = afscp_SetDefaultRealm(realm);
631
632 if (cell != NULL((void *)0))
633 code = afscp_SetDefaultCell(cell);
634
635 if (useFid)
636 code = GetVenusFidByFid(fname, cell, 0, &avfp);
637 else
638 code = GetVenusFidByPath(fname, cell, &avfp);
639 if (code != 0) {
640 afs_com_err(pnp, code, "(file not found: %s)", fname);
641 return code;
642 }
643
644retry:
645 code = afscp_GetStatus(avfp, &OutStatus);
646 if (code != 0) {
647 afs_inet_ntoa_r(avfp->cell->fsservers[0]->addrs[0], ipv4_addr);
648 afs_com_err(pnp, code, "(failed to get status of file %s from"
649 "server %s, code = %d)", fname, ipv4_addr, code);
650 afscp_FreeFid(avfp);
651 return code;
652 }
653
654 if (locktype != LockRelease3) {
655 while (OutStatus.lockCount != 0) {
656 code = afscp_WaitForCallback(avfp, waittime);
657 if ((code == -1) && (afscp_errno == ETIMEDOUT60))
658 break;
659 if ((code = afscp_GetStatus(avfp, &OutStatus)) != 0)
660 break;
661 }
662 } else {
663 if (OutStatus.lockCount == 0) {
664 code = -1;
665 }
666 }
667
668 if (!code) {
669 code = afscp_Lock(avfp, locktype);
670 if ((code == -1) && (afscp_errno == EWOULDBLOCK35))
671 goto retry;
672 }
673 afscp_FreeFid(avfp);
674
675 if (buf != NULL((void *)0))
676 free(buf);
677
678 if (code != 0)
679 afs_com_err(pnp, code, "(failed to change lock status: %d)", afscp_errno);
680
681 return code;
682} /* lockFile */
683
684static int
685readFile(struct cmd_syndesc *as, void *unused)
686{
687 char *fname = NULL((void *)0);
688 char *cell = NULL((void *)0);
689 char *realm = NULL((void *)0);
690 afs_int32 code = 0;
691 struct AFSFetchStatus OutStatus;
692 struct afscp_venusfid *avfp = NULL((void *)0);
693 afs_int64 Pos;
694 afs_int32 len;
695 afs_int64 length = 0, Len;
696 int bytes;
697 int worstCode = 0;
698 char *buf = 0;
699 char ipv4_addr[16];
700 int bufflen = BUFFLEN65536;
701
702#ifdef AFS_NT40_ENV
703 /* stdout on Windows defaults to _O_TEXT mode */
704 _setmode(1, _O_BINARY);
705#endif
706
707 gettimeofday(&starttime, &Timezone);
708
709 CmdProlog(as, &cell, &realm, &fname, NULL((void *)0));
710 afscp_AnonymousAuth(1);
711
712 if (md5sum)
713 MD5_Inithc_MD5_Init(&md5);
714
715 if (realm != NULL((void *)0))
716 code = afscp_SetDefaultRealm(realm);
717
718 if (cell != NULL((void *)0))
719 code = afscp_SetDefaultCell(cell);
720
721 if (useFid)
722 code = GetVenusFidByFid(fname, cell, 0, &avfp);
723 else
724 code = GetVenusFidByPath(fname, cell, &avfp);
725 if (code != 0) {
726 afs_com_err(pnp, code, "(file not found: %s)", fname);
727 return code;
728 }
729
730 if (avfp->fid.Vnode & 1) {
731 code = ENOENT2;
732 afs_com_err(pnp, code, "(%s is a directory, not a file)", fname);
733 afscp_FreeFid(avfp);
734 return code;
735 }
736
737 code = afscp_GetStatus(avfp, &OutStatus);
738 if (code != 0) {
739 afs_inet_ntoa_r(avfp->cell->fsservers[0]->addrs[0], ipv4_addr);
740 afs_com_err(pnp, code, "(failed to get status of file %s from"
741 "server %s, code = %d)", fname, ipv4_addr, code);
742 afscp_FreeFid(avfp);
743 return code;
744 }
745
746 gettimeofday(&opentime, &Timezone);
747 if (verbose)
748 fprintf(stderr__stderrp, "Startup to find the file took %.3f sec.\n",
749 time_elapsed(&starttime, &opentime));
750 Len = OutStatus.Length_hi;
751 Len <<= 32;
752 Len += OutStatus.Length;
753 ZeroInt64(Pos)(Pos = 0);
754 buf = (char *) malloc(bufflen * sizeof(char));
755 if (buf == NULL((void *)0)) {
756 code = ENOMEM12;
757 afs_com_err(pnp, code, "(cannot allocate buffer)");
758 afscp_FreeFid(avfp);
759 return code;
760 }
761 memset(buf, 0, bufflen * sizeof(char));
762 length = Len;
763 while (!code && NonZeroInt64(length)(length)) {
764 if (length > bufflen)
765 len = bufflen;
766 else
767 len = (afs_int32) length;
768 bytes = afscp_PRead(avfp, buf, len, Pos);
769 if (bytes != len)
770 code = -3; /* what error name should we use here? */
771 if (md5sum)
772 MD5_Updatehc_MD5_Update(&md5, buf, len);
773 if (code == 0) {
774 len = write(1, buf, len); /* to stdout */
775 if (len == 0)
776 code = errno(* __error());
777 }
778 length -= len;
779 xfered += len;
780 if (verbose)
781 printDatarate();
782 Pos += len;
783 worstCode = code;
784 }
785 afscp_FreeFid(avfp);
786
787 gettimeofday(&readtime, &Timezone);
788 if (md5sum)
789 summarizeMD5(fname);
790 if (verbose)
791 summarizeDatarate(&readtime, "read");
792 if (buf != NULL((void *)0))
793 free(buf);
794
795 return worstCode;
796} /* readFile */
797
798static int
799writeFile(struct cmd_syndesc *as, void *unused)
800{
801 char *fname = NULL((void *)0);
802 char *cell = NULL((void *)0);
803 char *sSynthLen = NULL((void *)0);
804 char *realm = NULL((void *)0);
805 afs_int32 code = 0;
806 afs_int32 byteswritten;
807 struct AFSFetchStatus OutStatus;
808 struct AFSStoreStatus InStatus;
809 struct afscp_venusfid *dirvfp = NULL((void *)0), *newvfp = NULL((void *)0);
810 afs_int64 Pos;
811 afs_int64 length, Len, synthlength = 0, offset = 0;
812 afs_int64 bytes;
813 int worstCode = 0;
814 int synthesize = 0;
815 int overWrite = 0;
816 struct wbuf *bufchain = 0;
817 struct wbuf *previous, *tbuf;
818 char dirName[AFSPATHMAX1024];
819 char baseName[AFSNAMEMAX256];
820 char ipv4_addr[16];
821
822#ifdef AFS_NT40_ENV
823 /* stdin on Windows defaults to _O_TEXT mode */
824 _setmode(0, _O_BINARY);
825#endif
826
827 CmdProlog(as, &cell, &realm, &fname, &sSynthLen);
828 afscp_AnonymousAuth(1);
829
830 if (realm != NULL((void *)0))
831 code = afscp_SetDefaultRealm(realm);
Value stored to 'code' is never read
832
833 if (cell != NULL((void *)0))
834 code = afscp_SetDefaultCell(cell);
835
836 if (sSynthLen) {
837 code = util_GetInt64(sSynthLen, &synthlength);
838 if (code != 0) {
839 afs_com_err(pnp, code, "(invalid value for synthesize length %s)",
840 sSynthLen);
841 return code;
842 }
843 synthesize = 1;
844 }
845
846 if (useFid) {
847 code = GetVenusFidByFid(fname, cell, 1, &newvfp);
848 if (code != 0) {
849 afs_com_err(pnp, code, "(GetVenusFidByFid returned code %d)", code);
850 return code;
851 }
852 } else {
853 code = GetVenusFidByPath(fname, cell, &newvfp);
854 if (code == 0) { /* file was found */
855 if (force)
856 overWrite = 1;
857 else if (!append) {
858 /*
859 * file cannot already exist if specified by path and not
860 * appending to it unless user forces overwrite
861 */
862 code = EEXIST17;
863 afscp_FreeFid(newvfp);
864 afs_com_err(pnp, code, "(use -force to overwrite)");
865 return code;
866 }
867 } else { /* file not found */
868 if (append) {
869 code = ENOENT2;
870 afs_com_err(pnp, code, "(cannot append to non-existent file)");
871 return code;
872 }
873 }
874 if (!append && !overWrite) { /* must create a new file in this case */
875 if ( BreakUpPath(fname, dirName, baseName) != 2 ) {
876 code = EINVAL22;
877 afs_com_err(pnp, code, "(must provide full AFS path)");
878 afscp_FreeFid(newvfp);
879 return code;
880 }
881
882 code = GetVenusFidByPath(dirName, cell, &dirvfp);
883 afscp_FreeFid(newvfp); /* release now-unneeded fid */
884 newvfp = NULL((void *)0);
885 if (code != 0) {
886 afs_com_err(pnp, code, "(is dir %s in AFS?)", dirName);
887 return code;
888 }
889 }
890 }
891
892 if ( (newvfp != NULL((void *)0)) && (newvfp->fid.Vnode & 1) ) {
893 code = EISDIR21;
894 afs_com_err(pnp, code, "(%s is a directory, not a file)", fname);
895 afscp_FreeFid(newvfp);
896 afscp_FreeFid(dirvfp);
897 return code;
898 }
899 gettimeofday(&starttime, &Timezone);
900
901 InStatus.UnixModeBits = 0644;
902 InStatus.Mask = AFS_SETMODE8 + AFS_FSYNC1024;
903 if (newvfp == NULL((void *)0)) {
904 code = afscp_CreateFile(dirvfp, baseName, &InStatus, &newvfp);
905 if (code != 0) {
906 afs_com_err(pnp, code,
907 "(could not create file %s in directory %lu.%lu.%lu)",
908 baseName, afs_printable_uint32_lu(dirvfp->fid.Volume),
909 afs_printable_uint32_lu(dirvfp->fid.Vnode),
910 afs_printable_uint32_lu(dirvfp->fid.Unique));
911 return code;
912 }
913 }
914 code = afscp_GetStatus(newvfp, &OutStatus);
915 if (code != 0) {
916 afs_inet_ntoa_r(newvfp->cell->fsservers[0]->addrs[0], ipv4_addr);
917 afs_com_err(pnp, code, "(failed to get status of file %s from"
918 "server %s, code = %d)", fname, ipv4_addr, code);
919 afscp_FreeFid(newvfp);
920 afscp_FreeFid(dirvfp);
921 return code;
922 }
923
924 if ( !append && !force &&
925 (OutStatus.Length != 0 || OutStatus.Length_hi !=0 ) ) {
926 /*
927 * file exists, is of non-zero length, and we're not appending
928 * to it: user must force overwrite
929 * (covers fidwrite edge case)
930 */
931 code = EEXIST17;
932 afscp_FreeFid(newvfp);
933 afscp_FreeFid(dirvfp);
934 afs_com_err(pnp, code, "(use -force to overwrite)");
935 return code;
936 }
937
938 if (append) {
939 Pos = OutStatus.Length_hi;
940 Pos = (Pos << 32) | OutStatus.Length;
941 } else
942 Pos = 0;
943 previous = (struct wbuf *)&bufchain;
944 if (md5sum)
945 MD5_Inithc_MD5_Init(&md5);
946
947 /*
948 * currently, these two while loops (1) read the whole source file in
949 * before (2) writing any of it out, meaning that afsio can't deal with
950 * files larger than the maximum amount of memory designated for
951 * reading a file in (WRITEBUFLEN).
952 * Consider going to a single loop, like in readFile(), though will
953 * have implications on timing statistics (such as the "Startup to
954 * find the file" time, below).
955 */
956 Len = 0;
957 while (Len < WRITEBUFLEN(65536 * 1024)) {
958 tbuf = (struct wbuf *)malloc(sizeof(struct wbuf));
959 if (tbuf == NULL((void *)0)) {
960 if (!bufchain) {
961 code = ENOMEM12;
962 afscp_FreeFid(newvfp);
963 afscp_FreeFid(dirvfp);
964 afs_com_err(pnp, code, "(cannot allocate buffer)");
965 return code;
966 }
967 break;
968 }
969 memset(tbuf, 0, sizeof(struct wbuf));
970 tbuf->buflen = BUFFLEN65536;
971 if (synthesize) {
972 afs_int64 ll, l = tbuf->buflen;
973 if (l > synthlength)
974 l = synthlength;
975 for (ll = 0; ll < l; ll += 4096) {
976 sprintf(&tbuf->buf[ll], "Offset (0x%x, 0x%x)\n",
977 (unsigned int)((offset + ll) >> 32),
978 (unsigned int)((offset + ll) & 0xffffffff));
979 }
980 offset += l;
981 synthlength -= l;
982 tbuf->used = (afs_int32) l;
983 } else
984 tbuf->used = read(0, &tbuf->buf, tbuf->buflen); /* from stdin */
985 if (tbuf->used == 0) {
986 free(tbuf);
987 break;
988 }
989 if (md5sum)
990 MD5_Updatehc_MD5_Update(&md5, &tbuf->buf, tbuf->used);
991 previous->next = tbuf;
992 previous = tbuf;
993 Len += tbuf->used;
994 }
995 gettimeofday(&opentime, &Timezone);
996 if (verbose)
997 fprintf(stderr__stderrp, "Startup to find the file took %.3f sec.\n",
998 time_elapsed(&starttime, &opentime));
999 bytes = Len;
1000 while (!code && bytes) {
1001 Len = bytes;
1002 length = Len;
1003 tbuf = bufchain;
1004 if (Len) {
1005 for (tbuf = bufchain; tbuf; tbuf = tbuf->next) {
1006 if (tbuf->used == 0)
1007 break;
1008 byteswritten = afscp_PWrite(newvfp, tbuf->buf,
1009 tbuf->used, Pos + xfered);
1010 if (byteswritten != tbuf->used) {
1011 fprintf(stderr__stderrp,"Only %d instead of %" AFS_INT64_FMT"lld" " bytes transferred by rx_Write()\n", byteswritten, length);
1012 fprintf(stderr__stderrp, "At %" AFS_UINT64_FMT"llu" " bytes from the end\n", length);
1013 code = -4;
1014 break;
1015 }
1016 xfered += tbuf->used;
1017 if (verbose)
1018 printDatarate();
1019 length -= tbuf->used;
1020 }
1021 }
1022 Pos += Len;
1023 bytes = 0;
1024 if (!code) {
1025 for (tbuf = bufchain; tbuf; tbuf = tbuf->next) {
1026 tbuf->offset = 0;
1027 if (synthesize) {
1028 afs_int64 ll, l = tbuf->buflen;
1029 if (l > synthlength)
1030 l = synthlength;
1031 for (ll = 0; ll < l; ll += 4096) {
1032 sprintf(&tbuf->buf[ll], "Offset (0x%x, 0x%x)\n",
1033 (unsigned int)((offset + ll) >> 32),
1034 (unsigned int)((offset + ll) & 0xffffffff));
1035 }
1036 offset += l;
1037 synthlength -= l;
1038 tbuf->used = (afs_int32) l;
1039 } else
1040 tbuf->used = read(0, &tbuf->buf, tbuf->buflen); /* from stdin */
1041 if (!tbuf->used)
1042 break;
1043 if (md5sum)
1044 MD5_Updatehc_MD5_Update(&md5, &tbuf->buf, tbuf->used);
1045 Len += tbuf->used;
1046 bytes += tbuf->used;
1047 }
1048 }
1049 }
1050 afscp_FreeFid(newvfp);
1051 afscp_FreeFid(dirvfp);
1052
1053 gettimeofday(&writetime, &Timezone);
1054 if (code) {
1055 afs_com_err(pnp, code, "(%s failed with code %d)", as->name,
1056 code);
1057 } else if (verbose) {
1058 summarizeDatarate(&writetime, "write");
1059 }
1060 while (bufchain) {
1061 tbuf = bufchain;
1062 bufchain = tbuf->next;
1063 free(tbuf);
1064 }
1065
1066 if (md5sum)
1067 summarizeMD5(fname);
1068
1069 return worstCode;
1070} /* writeFile */