#include #include #include #include #include #include #include static int servicesfd=-1; static char* servicesmap; static unsigned int serviceslen; static char* aliases[10]; static char *cur; static inline int isalpha(char c) { return (c>='a' && c<='z') || (c>='A' && c<='Z'); } static inline int isdigit(char c) { return (c>='0' && c<='9'); } static inline int isalnum(char c) { return isalpha(c) || isdigit(c); } static inline int isblank(char c) { return (c==' ' || c=='\t'); } /* nameserver 42/tcp name # IEN 116 */ struct servent *getservent(void) { static struct servent se; char *last; int aliasidx; if (servicesfd<0) { servicesfd=open("/etc/services",O_RDONLY); if (servicesfd<0) return 0; serviceslen=lseek(servicesfd,0,SEEK_END); servicesmap=mmap(0,serviceslen,PROT_READ|PROT_WRITE,MAP_PRIVATE,servicesfd,0); if ((long)servicesmap==(-1)) goto error; cur=servicesmap; } last=servicesmap+serviceslen; again: se.s_name=0; se.s_aliases=aliases; aliases[0]=0; se.s_port=0; se.s_proto=0; if (cur>=last) return 0; if (*cur=='#' || *cur=='\n') goto parseerror; /* first, the primary name */ if (!isalpha(*cur)) goto parseerror; se.s_name=cur; se.s_aliases=aliases; while (cur=last) return 0; if (*cur=='\n') goto parseerror; *cur=0; cur++; /* second, the port */ while (cur=last) return 0; /* third, "/tcp" or "/udp" */ if (*cur!='/') goto parseerror; cur++; se.s_proto=cur; while (cur=last) return 0; if (*cur=='\n') { *cur++=0; return &se; } *cur=0; cur++; /* now the aliases */ for (aliasidx=0;aliasidx<10;aliasidx++) { while (cur=last || !isblank(*cur)) break; if (*cur=='\n') { *cur++=0; break; } *cur++=0; } aliases[aliasidx]=0; return &se; parseerror: while (curs_name,strlen(s->s_name)); write(1,"/",1); write(1,s->s_proto,strlen(s->s_proto)); write(1,"\n",1); #endif if (!strcmp(name,s->s_name) && !strcmp(proto,s->s_proto)) return s; tmp=s->s_aliases; while (*tmp) if (!strcmp(name,*tmp++)) return s; } return 0; } struct servent *getservbyport(int port, const char *proto) { struct servent *s; for (s=getservent(); s; s=getservent()) { if (port==s->s_port && !strcmp(proto,s->s_proto)) return s; } return 0; } void setservent(int stayopen) { cur=servicesmap; } void endservent(void) { if (servicesmap!=(char*)-1) munmap(servicesmap,serviceslen); if (servicesfd!=-1) close(servicesfd); servicesmap=(char*)-1; servicesfd=-1; }