summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/lib/getservent.c
diff options
context:
space:
mode:
authorGuillaume Cottenceau <gc@mandriva.com>2001-01-04 20:04:45 +0000
committerGuillaume Cottenceau <gc@mandriva.com>2001-01-04 20:04:45 +0000
commit02fec4701cee79f875c1d02b8b4aee09380dbcb8 (patch)
treef4f291aedbb2e60ee58351481858a8cd3ec80b6b /mdk-stage1/dietlibc/lib/getservent.c
parent9887fe04751edf39e8389f2c3ec3f020b5e1c17d (diff)
downloaddrakx-backup-do-not-use-02fec4701cee79f875c1d02b8b4aee09380dbcb8.tar
drakx-backup-do-not-use-02fec4701cee79f875c1d02b8b4aee09380dbcb8.tar.gz
drakx-backup-do-not-use-02fec4701cee79f875c1d02b8b4aee09380dbcb8.tar.bz2
drakx-backup-do-not-use-02fec4701cee79f875c1d02b8b4aee09380dbcb8.tar.xz
drakx-backup-do-not-use-02fec4701cee79f875c1d02b8b4aee09380dbcb8.zip
integrate dietlibc/stdio per default for cdrom and disk only installs
Diffstat (limited to 'mdk-stage1/dietlibc/lib/getservent.c')
-rw-r--r--mdk-stage1/dietlibc/lib/getservent.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/mdk-stage1/dietlibc/lib/getservent.c b/mdk-stage1/dietlibc/lib/getservent.c
new file mode 100644
index 000000000..ee6a77c21
--- /dev/null
+++ b/mdk-stage1/dietlibc/lib/getservent.c
@@ -0,0 +1,141 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+
+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 && isalnum(*cur)) cur++;
+ if (cur>=last) return 0;
+ if (*cur=='\n') goto parseerror;
+ *cur=0; cur++;
+ /* second, the port */
+ while (cur<last && isblank(*cur)) cur++;
+ while (cur<last && isdigit(*cur)) {
+ se.s_port=se.s_port*10+*cur-'0';
+ cur++;
+ }
+ se.s_port=htons(se.s_port);
+ if (cur>=last) return 0;
+ /* third, "/tcp" or "/udp" */
+ if (*cur!='/') goto parseerror;
+ cur++;
+ se.s_proto=cur;
+ while (cur<last && isalpha(*cur)) cur++;
+ if (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)) cur++;
+ aliases[aliasidx]=cur;
+ while (cur<last && isalpha(*cur)) cur++;
+ if (cur>=last || !isblank(*cur)) break;
+ if (*cur=='\n') { *cur++=0; break; }
+ *cur++=0;
+ }
+ aliases[aliasidx]=0;
+ return &se;
+parseerror:
+ while (cur<last && *cur!='\n') cur++;
+ cur++;
+ goto again;
+error:
+ if (servicesmap!=(char*)-1) munmap(servicesmap,serviceslen);
+ if (servicesfd!=-1) close(servicesfd);
+ servicesmap=(char*)-1;
+ servicesfd=-1;
+ errno=ENOMEM;
+ return 0;
+}
+
+struct servent *getservbyname(const char *name, const char *proto) {
+ struct servent *s;
+ for (s=getservent(); s; s=getservent()) {
+ char **tmp;
+#if 0
+ write(1,"found ",6);
+ write(1,s->s_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;
+}
+