struct servent * getservent_r(struct servent *sp, struct servent_data *sd) { if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0 && _servent_open(sd) == -1) return NULL; if (sd->flags & _SV_CDB) { const void *data; size_t len; if (sd->flags & _SV_FIRST) { sd->cdb_index = 0; sd->flags &= ~_SV_FIRST; } if (cdbr_get(sd->cdb, sd->cdb_index, &data, &len)) return NULL; ++sd->cdb_index; return _servent_parsedb(sd, sp, data, len); } if (sd->flags & _SV_PLAINFILE) { for (;;) { if (_servent_getline(sd) == -1) return NULL; if (_servent_parseline(sd, sp) == NULL) continue; return sp; } } return NULL; }
static struct servent * _servent_getbyport(struct servent_data *sd, struct servent *sp, int port, const char *proto) { if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0) return NULL; if (sd->flags & _SV_CDB) { uint8_t buf[255 + 4]; size_t protolen; const uint8_t *data; const void *data_ptr; size_t datalen; port = be16toh(port); if (proto != NULL && *proto == '\0') return NULL; if (proto != NULL) protolen = strlen(proto); else protolen = 0; if (port < 0 || port > 65536) return NULL; buf[0] = 0; buf[1] = protolen; be16enc(buf + 2, port); memcpy(buf + 4, proto, protolen); if (cdbr_find(sd->cdb, buf, 4 + protolen, &data_ptr, &datalen)) return NULL; if (datalen < protolen + 4) return NULL; data = data_ptr; if (be16dec(data) != port) return NULL; if (protolen) { if (data[2] != protolen) return NULL; if (memcmp(data + 3, proto, protolen + 1)) return NULL; } return _servent_parsedb(sd, sp, data, datalen); } else { while (_servent_getline(sd) != -1) { if (_servent_parseline(sd, sp) == NULL) continue; if (sp->s_port != port) continue; if (proto == NULL || strcmp(sp->s_proto, proto) == 0) return sp; } return NULL; } }
static struct servent * _servent_getbyname(struct servent_data *sd, struct servent *sp, const char *name, const char *proto) { if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0) return NULL; #if 0 if (sd->flags & _SV_CDB) { uint8_t buf[255 * 2 + 2]; size_t namelen, protolen; const uint8_t *data, *data_end; const void *data_ptr; size_t datalen; namelen = strlen(name); if (namelen == 0 || namelen > 255) return NULL; if (proto != NULL) { protolen = strlen(proto); if (protolen == 0 || protolen > 255) return NULL; } else protolen = 0; if (namelen + protolen > 255) return NULL; buf[0] = (uint8_t)namelen; buf[1] = (uint8_t)protolen; memcpy(buf + 2, name, namelen); memcpy(buf + 2 + namelen, proto, protolen); if (cdbr_find(sd->cdb, buf, 2 + namelen + protolen, &data_ptr, &datalen)) return NULL; if (datalen < namelen + protolen + 6) return NULL; data = data_ptr; data_end = data + datalen; if (protolen) { if (data[2] != protolen) return NULL; if (memcmp(data + 3, proto, protolen + 1)) return NULL; } data += 3 + data[2] + 1; if (data > data_end) return NULL; while (data != data_end) { if (*data == '\0') return NULL; if (data + data[0] + 2 > data_end) return NULL; if (data[0] == namelen && memcmp(data + 1, name, namelen + 1) == 0) return _servent_parsedb(sd, sp, data_ptr, datalen); data += data[0] + 2; } return NULL; } else #endif { while (_servent_getline(sd) != -1) { char **cp; if (_servent_parseline(sd, sp) == NULL) continue; if (strcmp(name, sp->s_name) == 0) goto gotname; for (cp = sp->s_aliases; *cp; cp++) if (strcmp(name, *cp) == 0) goto gotname; continue; gotname: if (proto == NULL || strcmp(sp->s_proto, proto) == 0) return sp; } return NULL; } }