* CellServDB changes.
*/
+#if defined(AFS_SUN5_ENV) && !defined(__sparcv9)
+/* Solaris through 10 in 32 bit mode will return EMFILE if fopen can't
+ get an fd <= 255. We allow the fileserver to claim more fds than that.
+ This has always been a problem since pr_Initialize would have the same
+ issue, but hpr_Initialize makes it more likely that we would see this.
+ Work around it. This is not generic. It's coded with the needs of
+ afsconf_* in mind only.
+
+ http://www.opensolaris.org/os/community/onnv/flag-days/pages/2006042001/
+*/
+
+#define BUFFER 4096
+
+struct afsconf_iobuffer {
+ int _file;
+ char *buffer;
+ char *ptr;
+ char *endptr;
+};
+
+typedef struct afsconf_iobuffer afsconf_FILE;
+
+static afsconf_FILE *
+afsconf_fopen(const char *fname, const char *fmode)
+{
+ int fd;
+ afsconf_FILE *iop;
+
+ if ((fd = open(fname, O_RDONLY)) == -1) {
+ return NULL;
+ }
+
+ iop = malloc(sizeof(struct afsconf_iobuffer));
+ if (iop == NULL) {
+ (void) close(fd);
+ errno = ENOMEM;
+ return NULL;
+ }
+ iop->_file = fd;
+ iop->buffer = malloc(BUFFER);
+ if (iop->buffer == NULL) {
+ (void) close(fd);
+ free((void *) iop);
+ errno = ENOMEM;
+ return NULL;
+ }
+ iop->ptr = iop->buffer;
+ iop->endptr = iop->buffer;
+ return iop;
+}
+
+static int
+afsconf_fclose(afsconf_FILE *iop)
+{
+ if (iop == NULL) {
+ return 0;
+ }
+ close(iop->_file);
+ free((void *)iop->buffer);
+ free((void *)iop);
+ return 0;
+}
+
+static char *
+afsconf_fgets(char *s, int n, afsconf_FILE *iop)
+{
+ char *p;
+
+ p = s;
+ for (;;) {
+ char c;
+
+ if (iop->ptr == iop->endptr) {
+ ssize_t len;
+
+ if ((len = read(iop->_file, (void *)iop->buffer, BUFFER)) == -1) {
+ return NULL;
+ }
+ if (len == 0) {
+ *p = 0;
+ if (s == p) {
+ return NULL;
+ }
+ return s;
+ }
+ iop->ptr = iop->buffer;
+ iop->endptr = iop->buffer + len;
+ }
+ c = *iop->ptr++;
+ *p++ = c;
+ if ((p - s) == (n - 1)) {
+ *p = 0;
+ return s;
+ }
+ if (c == '\n') {
+ *p = 0;
+ return s;
+ }
+ }
+}
+#define fopen afsconf_fopen
+#define fclose afsconf_fclose
+#define fgets afsconf_fgets
+#else
+#define afsconf_FILE FILE
+#endif /* AFS_SUN5_ENV && ! __sparcv9 */
+
/* return port number in network byte order in the low 16 bits of a long; return -1 if not found */
static afs_int32
afsconf_FindService(register const char *aname)
} else {
int len;
strncpy(tbuffer, adir->name, sizeof(tbuffer));
- len = strlen(tbuffer);
+ len = (int)strlen(tbuffer);
if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') {
strncat(tbuffer, "\\", sizeof(tbuffer));
}
AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL);
free(p);
} else {
- int len = strlen(tbuffer);
+ int len = (int)strlen(tbuffer);
if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') {
strncat(tbuffer, "\\", sizeof(tbuffer));
}
if (!(afsconf_path = getenv("AFSCONF"))) {
/* The "AFSCONF" environment (or contents of "/.AFSCONF") will be typically set to something like "/afs/<cell>/common/etc" where, by convention, the default files for "ThisCell" and "CellServDB" will reside; note that a major drawback is that a given afs client on that cell may NOT contain the same contents... */
char *home_dir;
- FILE *fp;
+ afsconf_FILE *fp;
size_t len;
if (!(home_dir = getenv("HOME"))) {
return tdir;
}
-
static int
GetCellUnix(struct afsconf_dir *adir)
{
int rc;
char tbuffer[256];
- FILE *tf;
-
+ int fd;
+
strcompose(tbuffer, 256, adir->name, "/", AFSDIR_THISCELL_FILE, NULL);
- tf = fopen(tbuffer, "r");
- if (tf) {
- /* FIXME: buffer overflow waiting to happen */
- rc = fscanf(tf, "%s", tbuffer);
- if (rc == 1) {
- adir->cellName = (char *)malloc(strlen(tbuffer) + 1);
- strcpy(adir->cellName, tbuffer);
- }
- fclose(tf);
+ fd = open(tbuffer, O_RDONLY, 0);
+ if (fd < 0) {
+ return -1;
} else {
- return -1;
+ int sz;
+
+ memset(tbuffer, 0, 256);
+ sz = read(fd, tbuffer, 255);
+ close(fd);
+ if (sz > 0) {
+ char *p = strchr(tbuffer, '\n');
+ if (p)
+ *p = '\0';
+
+ adir->cellName = (char *)malloc(sz + 1);
+ strncpy(adir->cellName, tbuffer, sz);
+ }
}
return 0;
}
afsconf_OpenInternal(register struct afsconf_dir *adir, char *cell,
char clones[])
{
- FILE *tf;
+ afsconf_FILE *tf;
register char *tp, *bp;
register struct afsconf_entry *curEntry;
struct afsconf_aliasentry *curAlias;
} else {
int len;
strncpy(tbuffer, adir->name, sizeof(tbuffer));
- len = strlen(tbuffer);
+ len = (int)strlen(tbuffer);
if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') {
strncat(tbuffer, "\\", sizeof(tbuffer));
}
struct afsconf_cell *acellInfo)
{
afs_int32 code;
- int tservice, i;
- size_t len;
+ int tservice, i, len;
unsigned char answer[1024];
unsigned char *p;
+ char *dotcellname;
+ int cellnamelength;
char realCellName[256];
char host[256];
int server_num = 0;
* replaced with a more fine-grained lock just for the resolver
* operations.
*/
- LOCK_GLOBAL_MUTEX;
- len = res_search(acellName, C_IN, T_AFSDB, answer, sizeof(answer));
- UNLOCK_GLOBAL_MUTEX;
+
+ if ( ! strchr(acellName,'.') ) {
+ cellnamelength=strlen(acellName);
+ dotcellname=malloc(cellnamelength+2);
+ memcpy(dotcellname,acellName,cellnamelength);
+ dotcellname[cellnamelength]='.';
+ dotcellname[cellnamelength+1]=0;
+ LOCK_GLOBAL_MUTEX;
+ len = res_search(dotcellname, C_IN, T_AFSDB, answer, sizeof(answer));
+ if ( len < 0 ) {
+ len = res_search(acellName, C_IN, T_AFSDB, answer, sizeof(answer));
+ }
+ UNLOCK_GLOBAL_MUTEX;
+ free(dotcellname);
+ } else {
+ LOCK_GLOBAL_MUTEX;
+ len = res_search(acellName, C_IN, T_AFSDB, answer, sizeof(answer));
+ UNLOCK_GLOBAL_MUTEX;
+ }
if (len < 0)
return AFSCONF_NOTFOUND;
register afs_int32 i;
int tservice;
char *tcell;
- size_t cnLen;
+ int cnLen;
int ambig;
char tbuffer[64];
afsconf_Check(adir);
if (acellName) {
tcell = acellName;
- cnLen = strlen(tcell) + 1;
+ cnLen = (int)(strlen(tcell) + 1);
lcstring(tcell, tcell, cnLen);
afsconf_SawCell = 1; /* will ignore the AFSCELL switch on future */
/* call to afsconf_GetLocalCell: like klog */
return 0;
}
+ /* convert key structure to host order */
+ tstr->nkeys = ntohl(tstr->nkeys);
+
if (code < sizeof(afs_int32) + (tstr->nkeys*sizeof(struct afsconf_key))) {
tstr->nkeys = 0;
UNLOCK_GLOBAL_MUTEX;
return 0;
}
- /* convert key structure to host order */
- tstr->nkeys = ntohl(tstr->nkeys);
for (fd = 0; fd < tstr->nkeys; fd++)
tstr->key[fd].kvno = ntohl(tstr->key[fd].kvno);