meillo@0: /* meillo@0: ** id_parse.c Receive and parse a reply from an IDENT server meillo@0: ** meillo@0: ** Author: Peter Eriksson meillo@0: ** Fiddling: Pär Emanuelsson meillo@0: */ meillo@0: meillo@0: #ifdef NeXT3 meillo@0: # include meillo@0: #endif meillo@0: meillo@0: #include meillo@0: #include meillo@0: #include meillo@0: #include meillo@0: meillo@0: #ifdef HAVE_ANSIHEADERS meillo@0: # include meillo@0: # include meillo@0: # include meillo@0: #endif meillo@0: meillo@0: #include meillo@0: #include meillo@0: #include meillo@0: meillo@0: #ifdef _AIX meillo@0: # include meillo@0: #endif meillo@0: meillo@0: #ifdef _AIX meillo@0: # include meillo@0: #endif meillo@0: #ifdef VMS meillo@10: # include /* for fd_set */ meillo@0: #endif meillo@0: #define IN_LIBIDENT_SRC meillo@0: #include "ident.h" meillo@0: meillo@0: meillo@0: /* meillo@10: int meillo@10: id_parse __P7(ident_t *, id, meillo@10: struct timeval *, timeout, meillo@10: int *, lport, meillo@10: int *, fport, meillo@10: char **, identifier, meillo@10: char **, opsys, meillo@10: char **, charset) meillo@0: */ meillo@0: meillo@10: int meillo@10: id_parse __P((ident_t * id, meillo@10: __STRUCT_TIMEVAL_P timeout, meillo@10: int *lport, meillo@10: int *fport, meillo@10: char **identifier, meillo@10: char **opsys, meillo@10: char **charset)) meillo@0: { meillo@10: char c, *cp, *tmp_charset; meillo@10: fd_set rs; meillo@10: int pos, res = 0, lp, fp; meillo@10: meillo@10: errno = 0; meillo@10: meillo@10: tmp_charset = 0; meillo@10: meillo@10: if (!id) meillo@10: return -1; meillo@10: if (lport) meillo@10: *lport = 0; meillo@10: if (fport) meillo@10: *fport = 0; meillo@10: if (identifier) meillo@10: *identifier = 0; meillo@10: if (opsys) meillo@10: *opsys = 0; meillo@10: if (charset) meillo@10: *charset = 0; meillo@10: meillo@10: pos = strlen(id->buf); meillo@10: meillo@10: if (timeout) { meillo@10: FD_ZERO(&rs); meillo@10: FD_SET(id->fd, &rs); meillo@0: meillo@0: #ifdef __hpux meillo@10: if ((res = select(FD_SETSIZE, (int *) &rs, (int *) 0, (int *) 0, timeout)) < 0) meillo@0: #else meillo@10: if ((res = select(FD_SETSIZE, &rs, (fd_set *) 0, (fd_set *) 0, timeout)) < 0) meillo@0: #endif meillo@10: return -1; meillo@10: meillo@10: if (res == 0) { meillo@10: errno = ETIMEDOUT; meillo@10: return -1; meillo@10: } meillo@0: } meillo@10: meillo@10: /* Every octal value is allowed except 0, \n and \r */ meillo@10: while (pos < sizeof(id->buf) meillo@10: && (res = read(id->fd, id->buf + pos, 1)) == 1 meillo@10: && id->buf[pos] != '\n' && id->buf[pos] != '\r') meillo@10: pos++; meillo@10: meillo@10: if (res < 0) meillo@10: return -1; meillo@10: meillo@10: if (res == 0) { meillo@10: errno = ENOTCONN; meillo@10: return -1; meillo@0: } meillo@10: meillo@10: if (id->buf[pos] != '\n' && id->buf[pos] != '\r') meillo@10: return 0; /* Not properly terminated string */ meillo@10: meillo@10: id->buf[pos++] = '\0'; meillo@10: meillo@10: /* meillo@10: ** Get first field ( , ) meillo@10: */ meillo@10: cp = id_strtok(id->buf, ":", &c); meillo@0: if (!cp) meillo@10: return -2; meillo@10: meillo@10: if (sscanf(cp, " %d , %d", &lp, &fp) != 2) { meillo@10: if (identifier) { meillo@10: *identifier = id_strdup(cp); meillo@10: if (*identifier == NULL) meillo@10: return -4; meillo@10: } meillo@10: return -2; meillo@0: } meillo@10: meillo@10: if (lport) meillo@10: *lport = lp; meillo@10: if (fport) meillo@10: *fport = fp; meillo@10: meillo@0: /* meillo@10: ** Get second field (USERID or ERROR) meillo@10: */ meillo@10: cp = id_strtok((char *) 0, ":", &c); meillo@0: if (!cp) meillo@10: return -2; meillo@10: meillo@10: if (strcmp(cp, "ERROR") == 0) { meillo@10: cp = id_strtok((char *) 0, "\n\r", &c); meillo@10: if (!cp) meillo@10: return -2; meillo@10: meillo@10: if (identifier) { meillo@10: *identifier = id_strdup(cp); meillo@10: if (*identifier == NULL) meillo@10: return -4; meillo@10: } meillo@10: meillo@10: return 2; meillo@10: } else if (strcmp(cp, "USERID") == 0) { meillo@10: /* meillo@10: ** Get first subfield of third field meillo@10: */ meillo@10: cp = id_strtok((char *) 0, ",:", &c); meillo@10: if (!cp) meillo@10: return -2; meillo@10: meillo@10: if (opsys) { meillo@10: *opsys = id_strdup(cp); meillo@10: if (*opsys == NULL) meillo@10: return -4; meillo@10: } meillo@10: meillo@10: /* meillo@10: ** We have a second subfield () meillo@10: */ meillo@10: if (c == ',') { meillo@10: cp = id_strtok((char *) 0, ":", &c); meillo@10: if (!cp) meillo@10: return -2; meillo@10: meillo@10: tmp_charset = cp; meillo@10: if (charset) { meillo@10: *charset = id_strdup(cp); meillo@10: if (*charset == NULL) meillo@10: return -4; meillo@10: } meillo@10: meillo@10: /* meillo@10: ** We have even more subfields - ignore them meillo@10: */ meillo@10: if (c == ',') meillo@10: id_strtok((char *) 0, ":", &c); meillo@10: } meillo@10: meillo@10: if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0) meillo@10: cp = id_strtok((char *) 0, (char *) 0, &c); meillo@10: else meillo@10: cp = id_strtok((char *) 0, "\n\r", &c); meillo@10: meillo@10: if (identifier) { meillo@10: *identifier = id_strdup(cp); meillo@10: if (*identifier == NULL) meillo@10: return -4; meillo@10: } meillo@10: return 1; meillo@10: } else { meillo@10: if (identifier) { meillo@10: *identifier = id_strdup(cp); meillo@10: if (*identifier == NULL) meillo@10: return -4; meillo@10: } meillo@10: return -3; meillo@0: } meillo@0: }