int afscp_GetStatus(const struct afscp_venusfid *fid, struct AFSFetchStatus *s) { struct afscp_volume *v; struct afscp_server *server; struct AFSCallBack cb; struct AFSVolSync vs; struct AFSFid tf = fid->fid; struct afscp_statent *stored, key; void *cached; int code, i, j; time_t now; v = afscp_VolumeById(fid->cell, fid->fid.Volume); if (v == NULL) { return -1; } memset(&key, 0, sizeof(key)); memcpy(&key.me, fid, sizeof(*fid)); cached = tfind(&key, &v->statcache, statcompare); if (cached != NULL) { stored = *(struct afscp_statent **)cached; pthread_mutex_lock(&(stored->mtx)); memmove(s, &stored->status, sizeof(*s)); afs_dprintf(("Stat %u.%lu.%lu.%lu returning cached result\n", fid->cell->id, fid->fid.Volume, fid->fid.Vnode, fid->fid.Unique)); if (stored->nwaiters) pthread_cond_broadcast(&(stored->cv)); pthread_mutex_unlock(&(stored->mtx)); return 0; } code = ENOENT; for (i = 0; i < v->nservers; i++) { server = afscp_ServerByIndex(v->servers[i]); if (server && server->naddrs > 0) { for (j = 0; j < server->naddrs; j++) { time(&now); code = RXAFS_FetchStatus(server->conns[j], &tf, s, &cb, &vs); if (code == 0) { afscp_AddCallBack(server, &fid->fid, s, &cb, now); /* calls _StatStuff */ afs_dprintf(("Stat %d.%lu.%lu.%lu" " ok: type %ld size %ld\n", fid->cell->id, afs_printable_uint32_lu(fid->fid.Volume), afs_printable_uint32_lu(fid->fid.Vnode), afs_printable_uint32_lu(fid->fid.Unique), afs_printable_int32_ld(s->FileType), afs_printable_int32_ld(s->Length))); return 0; } } } } afscp_errno = code; return -1; }
/* bc_openTextFile - This function opens a temp file to read in the * config text recd from the bu server. On Unix, an unlink() is done on * the file as soon as it is opened, so when the program exits, the file will * be removed automatically, while being invisible while in use. * On NT, however, the file must be explicitly deleted after use with an unlink() * Input: * Pointer to a udhClientTextP struct. The open stream ptr is stored in * the udbClientTextP.textStream member. * Output: The temp file name is returned in tmpFileName. This should be used * to delete the file when done with it. * Return Values: * !0: error code * 0: Success. */ int bc_openTextFile(udbClientTextP ctPtr, char *tmpFileName) { int code = 0; int fd; if (ctPtr->textStream != NULL) { fclose(ctPtr->textStream); ctPtr->textStream = NULL; } sprintf(tmpFileName, "%s/bu_XXXXXX", gettmpdir()); fd = mkstemp(tmpFileName); if (fd == -1) ERROR(BUDB_INTERNALERROR); ctPtr->textStream = fdopen(fd, "w+"); if (ctPtr->textStream == NULL) ERROR(BUDB_INTERNALERROR); #ifndef AFS_NT40_ENV /* This can't be done on NT */ /* make the file invisible to others */ code = unlink(tmpFileName); if (code) ERROR(errno); #endif afs_dprintf(("file is %s\n", tmpFileName)); normal_exit: return code; error_exit: if (ctPtr->textStream != NULL) { fclose(ctPtr->textStream); ctPtr->textStream = NULL; } goto normal_exit; }
struct afscp_volume * afscp_VolumeByName(struct afscp_cell *cell, const char *vname, afs_int32 intype) { union allvldbentry u; struct afscp_volume *ret, key; struct afscp_server *server; afs_int32 code, vtype, type, srv; void *s; #ifdef AFSCP_DEBUG struct in_addr i; #endif if (intype == RWVOL) vtype = VLSF_RWVOL; else if (intype == ROVOL) vtype = VLSF_ROVOL; else if (intype == BACKVOL) vtype = VLSF_BACKVOL; else { afscp_errno = EINVAL; return NULL; } memset(&key, 0, sizeof(key)); strlcpy(key.name, vname, sizeof(key.name)); key.voltype = vtype; s = tfind(&key, &cell->volsbyname, ncompare); if (s) { ret = *(struct afscp_volume **)s; return ret; } type = 0; code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, (char *)vname, &u.u); if (code == RXGEN_OPCODE) { type = 1; code = ubik_VL_GetEntryByNameN(cell->vlservers, 0, (char *)vname, &u.n); if (code == RXGEN_OPCODE) { type = 2; code = ubik_VL_GetEntryByNameO(cell->vlservers, 0, (char *)vname, &u.o); } } if (code != 0) { afscp_errno = code; return NULL; } ret = calloc(1, sizeof(struct afscp_volume)); if (ret == NULL) { afscp_errno = ENOMEM; return NULL; } strlcpy(ret->name, u.u.name, sizeof(ret->name)); ret->nservers = 0; ret->cell = cell; switch (type) { case 0: ret->id = u.u.volumeId[intype]; for (srv = 0; srv < u.u.nServers; srv++) { if ((u.u.serverFlags[srv] & vtype) == 0) continue; afs_dprintf(("uvldbentry server %d flags: %x\n", srv, u.u.serverFlags[srv])); if ((u.u.serverFlags[srv] & VLSF_UUID) == 0) server = afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low); else server = afscp_ServerById(cell, &u.u.serverNumber[srv]); if (!server) continue; ret->servers[ret->nservers++] = server->index; } break; case 1: ret->id = u.n.volumeId[intype]; for (srv = 0; srv < u.n.nServers; srv++) { if ((u.n.serverFlags[srv] & vtype) == 0) continue; server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]); if (!server) continue; ret->servers[ret->nservers++] = server->index; } break; case 2: ret->id = u.o.volumeId[intype]; for (srv = 0; srv < u.o.nServers; srv++) { if ((u.o.serverFlags[srv] & vtype) == 0) continue; server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]); if (!server) continue; ret->servers[ret->nservers++] = server->index; } break; } if (!ret->nservers || !ret->id) { free(ret); return NULL; } ret->voltype = intype; #ifdef AFSCP_DEBUG server = afscp_ServerByIndex(ret->servers[0]); if (server != NULL) i.s_addr = server->addrs[0]; else i.s_addr = 0; #endif afs_dprintf(("New volume BYNAME %s (%lu) on %s (%d)\n", ret->name, afs_printable_uint32_lu(ret->id), inet_ntoa(i), ret->servers[0])); s = tsearch(&key, &cell->volsbyname, ncompare); if (s) *(struct afscp_volume **)s = ret; key.id = ret->id; s = tsearch(&key, &cell->volsbyid, icompare); if (s) *(struct afscp_volume **)s = ret; return ret; }
struct afscp_volume * afscp_VolumeById(struct afscp_cell *cell, afs_uint32 id) { union allvldbentry u; struct afscp_volume *ret, key; struct afscp_server *server; afs_int32 code, vtype, type, srv; int voltype = -1; char idbuffer[16]; void *s; #ifdef AFSCP_DEBUG struct in_addr i; #endif memset(&key, 0, sizeof(key)); key.id = id; s = tfind(&key, &cell->volsbyid, icompare); if (s) { ret = *(struct afscp_volume **)s; return ret; } snprintf(idbuffer, sizeof(idbuffer), "%lu", afs_printable_uint32_lu(id)); type = 0; code = ubik_VL_GetEntryByNameU(cell->vlservers, 0, idbuffer, &u.u); if (code == RXGEN_OPCODE) { type = 1; code = ubik_VL_GetEntryByIDN(cell->vlservers, 0, id, -1, &u.n); if (code == RXGEN_OPCODE) { type = 2; code = ubik_VL_GetEntryByID(cell->vlservers, 0, id, -1, &u.o); } } if (code != 0) { afscp_errno = code; return NULL; } ret = calloc(1, sizeof(struct afscp_volume)); if (ret == NULL) { afscp_errno = ENOMEM; return NULL; } strlcpy(ret->name, u.u.name, sizeof(ret->name)); ret->nservers = 0; ret->cell = cell; switch (type) { case 0: if (id == u.u.volumeId[RWVOL]) { vtype = VLSF_RWVOL; voltype = RWVOL; } else if (id == u.u.volumeId[ROVOL]) { vtype = VLSF_ROVOL; voltype = ROVOL; } else if (id == u.u.volumeId[BACKVOL]) { vtype = VLSF_BACKVOL; voltype = BACKVOL; } else { vtype = 0; voltype = -1; } for (srv = 0; srv < u.u.nServers; srv++) { if ((u.u.serverFlags[srv] & vtype) == 0) continue; if ((u.u.serverFlags[srv] & VLSF_UUID) == 0) server = afscp_ServerByAddr(cell, u.u.serverNumber[srv].time_low); else server = afscp_ServerById(cell, &u.u.serverNumber[srv]); if (!server) continue; ret->servers[ret->nservers++] = server->index; } break; case 1: if (id == u.n.volumeId[RWVOL]) { vtype = VLSF_RWVOL; voltype = RWVOL; } else if (id == u.n.volumeId[ROVOL]) { vtype = VLSF_ROVOL; voltype = ROVOL; } else if (id == u.n.volumeId[BACKVOL]) { vtype = VLSF_BACKVOL; voltype = BACKVOL; } else { vtype = 0; voltype = -1; } for (srv = 0; srv < u.n.nServers; srv++) { if ((u.n.serverFlags[srv] & vtype) == 0) continue; server = afscp_ServerByAddr(cell, u.n.serverNumber[srv]); if (server == NULL) continue; ret->servers[ret->nservers++] = server->index; } break; case 2: if (id == u.o.volumeId[RWVOL]) { vtype = VLSF_RWVOL; voltype = RWVOL; } else if (id == u.o.volumeId[ROVOL]) { vtype = VLSF_ROVOL; voltype = ROVOL; } else if (id == u.o.volumeId[BACKVOL]) { vtype = VLSF_BACKVOL; voltype = BACKVOL; } else { vtype = 0; voltype = -1; } for (srv = 0; srv < u.o.nServers; srv++) { if ((u.o.serverFlags[srv] & vtype) == 0) continue; server = afscp_ServerByAddr(cell, u.o.serverNumber[srv]); if (server == NULL) continue; ret->servers[ret->nservers++] = server->index; } break; } ret->voltype = voltype; #ifdef AFSCP_DEBUG server = afscp_ServerByIndex(ret->servers[0]); if (server) i.s_addr = server->addrs[0]; else i.s_addr = 0; #endif afs_dprintf(("New volume BYID %s (%lu) on %s (%d)\n", ret->name, afs_printable_uint32_lu(ret->id), inet_ntoa(i), ret->servers[0])); s = tsearch(&key, &cell->volsbyid, icompare); if (s) *(struct afscp_volume **)s = ret; strlcpy(key.name, ret->name, sizeof(key.name)); s = tsearch(&key, &cell->volsbyname, ncompare); if (s) *(struct afscp_volume **)s = ret; return ret; }
/* takes server in host byte order */ struct afscp_server * afscp_ServerByAddr(struct afscp_cell *thecell, afs_uint32 addr) { /* implement uniquifiers? */ int i, j; struct afscp_server **newlist; struct afscp_server **newall; struct afscp_server *ret = NULL; afsUUID uuid; bulkaddrs addrs; struct ListAddrByAttributes attrs; afs_int32 nentries, code, uniq; if (thecell == NULL) return ret; /* cannot continue without thecell */ for (i = 0; i < thecell->nservers; i++) { ret = thecell->fsservers[i]; for (j = 0; j < ret->naddrs; j++) if (ret->addrs[j] == htonl(addr)) { return ret; } } if (thecell->nservers >= thecell->srvsalloced) { if (thecell->srvsalloced) thecell->srvsalloced = thecell->srvsalloced * 2; else thecell->srvsalloced = 4; newlist = realloc(thecell->fsservers, thecell->srvsalloced * sizeof(struct afscp_server)); if (newlist == NULL) { return NULL; } thecell->fsservers = newlist; } ret = malloc(sizeof(struct afscp_server)); if (ret == NULL) { return NULL; } memset(ret, 0, sizeof(struct afscp_server)); thecell->fsservers[thecell->nservers] = ret; ret->cell = thecell->id; memset(&uuid, 0, sizeof(uuid)); memset(&addrs, 0, sizeof(addrs)); memset(&attrs, 0, sizeof(attrs)); attrs.Mask = VLADDR_IPADDR; attrs.ipaddr = addr; code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &uuid, &uniq, &nentries, &addrs); if (code != 0) { memset(&ret->id, 0, sizeof(uuid)); ret->naddrs = 1; ret->addrs[0] = htonl(addr); ret->conns[0] = rx_NewConnection(ret->addrs[0], htons(AFSCONF_FILEPORT), 1, thecell->security, thecell->scindex); } else { char s[512]; afsUUID_to_string(&uuid, s, 511); afs_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr, s)); if (nentries > AFS_MAXHOSTS) { nentries = AFS_MAXHOSTS; /* XXX I don't want to do *that* much dynamic allocation */ abort(); } memmove(&ret->id, &uuid, sizeof(afsUUID)); ret->naddrs = nentries; for (i = 0; i < nentries; i++) { ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]); ret->conns[i] = rx_NewConnection(ret->addrs[i], htons(AFSCONF_FILEPORT), 1, thecell->security, thecell->scindex); } _xdr_free(_xdr_bulkaddrs, &addrs); } thecell->nservers++; if (afscp_nservers >= afscp_srvsalloced) { if (afscp_srvsalloced) afscp_srvsalloced = afscp_srvsalloced * 2; else afscp_srvsalloced = 4; newall = realloc(allservers, afscp_srvsalloced * sizeof(struct afscp_server *)); if (newall == NULL) { return ret; } allservers = newall; } ret->index = afscp_nservers; allservers[afscp_nservers++] = ret; return ret; }
/* takes server in host byte order */ struct afscp_server * afscp_ServerById(struct afscp_cell *thecell, afsUUID * u) { /* impliment uniquifiers? */ int i, code; struct afscp_server **newlist; struct afscp_server **newall; struct afscp_server *ret = NULL; afsUUID tmp; bulkaddrs addrs; struct ListAddrByAttributes attrs; afs_int32 nentries, uniq; char s[512]; afsUUID_to_string(u, s, 511); afs_dprintf(("GetServerByID %s\n", s)); for (i = 0; i < thecell->nservers; i++) { if (afs_uuid_equal(&thecell->fsservers[i]->id, u)) { return thecell->fsservers[i]; } } if (thecell->nservers >= thecell->srvsalloced) { if (thecell->srvsalloced) thecell->srvsalloced = thecell->srvsalloced * 2; else thecell->srvsalloced = 4; newlist = realloc(thecell->fsservers, thecell->srvsalloced * sizeof(struct afscp_server *)); if (newlist == NULL) { return NULL; } thecell->fsservers = newlist; } ret = malloc(sizeof(struct afscp_server)); if (ret == NULL) { return NULL; } memset(ret, 0, sizeof(struct afscp_server)); thecell->fsservers[thecell->nservers] = ret; memmove(&ret->id, u, sizeof(afsUUID)); ret->cell = thecell->id; memset(&tmp, 0, sizeof(tmp)); memset(&addrs, 0, sizeof(addrs)); memset(&attrs, 0, sizeof(attrs)); attrs.Mask = VLADDR_UUID; memmove(&attrs.uuid, u, sizeof(afsUUID)); code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &tmp, &uniq, &nentries, &addrs); if (code != 0) { return NULL; } if (nentries > AFS_MAXHOSTS) { nentries = AFS_MAXHOSTS; /* XXX I don't want to do *that* much dynamic allocation */ abort(); } ret->naddrs = nentries; for (i = 0; i < nentries; i++) { ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]); ret->conns[i] = rx_NewConnection(ret->addrs[i], htons(AFSCONF_FILEPORT), 1, thecell->security, thecell->scindex); } _xdr_free(_xdr_bulkaddrs, &addrs); thecell->nservers++; if (afscp_nservers >= afscp_srvsalloced) { if (afscp_srvsalloced) afscp_srvsalloced = afscp_srvsalloced * 2; else afscp_srvsalloced = 4; newall = realloc(allservers, afscp_srvsalloced * sizeof(struct afscp_server *)); if (newall == NULL) { return ret; } allservers = newall; } ret->index = afscp_nservers; allservers[afscp_nservers++] = ret; return ret; }
int bcdb_SaveTextFile(udbClientTextP ctPtr) { afs_int32 bufferSize; afs_int32 offset, chunkSize, fileSize; charListT charList; afs_int32 code = 0; /* allocate a buffer */ bufferSize = 1024; charList.charListT_val = malloc(bufferSize); if (charList.charListT_val == 0) ERROR(BUDB_INTERNALERROR); charList.charListT_len = bufferSize; if (ctPtr->textStream == NULL) ERROR(BUDB_INTERNALERROR); rewind(ctPtr->textStream); fileSize = (afs_int32) filesize(ctPtr->textStream); afs_dprintf(("filesize is %d\n", fileSize)); rewind(ctPtr->textStream); /* special case empty files */ if (fileSize == 0) { charList.charListT_len = 0; code = ubik_BUDB_SaveText(udbHandle.uh_client, 0, ctPtr->lockHandle, ctPtr->textType, 0, BUDB_TEXT_COMPLETE, &charList); goto error_exit; } offset = 0; while (fileSize != 0) { chunkSize = min(fileSize, bufferSize); code = fread(charList.charListT_val, sizeof(char), chunkSize, ctPtr->textStream); if (code != chunkSize) printf("code = %d\n", code); if (ferror(ctPtr->textStream)) ERROR(BUDB_INTERNALERROR); charList.charListT_len = chunkSize; code = ubik_BUDB_SaveText(udbHandle.uh_client, 0, ctPtr->lockHandle, ctPtr->textType, offset, (chunkSize == fileSize) ? BUDB_TEXT_COMPLETE : 0, &charList); if (code) ERROR(code); fileSize -= chunkSize; offset += chunkSize; } error_exit: /* if ( ctPtr->textStream >= 0 ) * close(ctPtr->textStream); */ if (charList.charListT_val) free(charList.charListT_val); return (code); }