?? gnuserv.c
字號:
u_long host_addr; struct entry *next;};struct entry *permitted_hosts[TABLE_SIZE];/* permitted -- return whether a given host is allowed to connect to the server.*/int permitted(host_addr) u_long host_addr;{ int key; struct entry *entry; /* First find the hash key */ key = HASH(host_addr) % TABLE_SIZE; /* Now check the chain for that hash key */ for(entry=permitted_hosts[key]; entry != NULL; entry=entry->next) if (host_addr == entry->host_addr) return(TRUE); return(FALSE);} /* permitted *//* add_host -- add the given host to the list of permitted hosts, provided it isn't already there.*/ void add_host(host_addr) u_long host_addr;{ int key; struct entry *new_entry; if (!permitted(host_addr)) { if ((new_entry = (struct entry *) malloc(sizeof(struct entry))) == NULL) { fprintf(stderr,"%s: unable to malloc space for permitted host entry\n", progname); exit(1); }; /* if */ new_entry->host_addr = host_addr; key = HASH(host_addr) % TABLE_SIZE; new_entry->next = permitted_hosts[key]; permitted_hosts[key] = new_entry; }; /* if */} /* add_host *//* setup_table -- initialise the table of hosts allowed to contact the server, by reading from the file specified by the GNU_SECURE environment variable Put in the local machine, and, if a security file is specifed, add each host that is named in the file. Return the number of hosts added.*/int setup_table(){ FILE *host_file; char *file_name; char hostname[HOSTNAMSZ]; u_long host_addr; int i, hosts=0; /* Make sure every entry is null */ for (i=0; i<TABLE_SIZE; i++) permitted_hosts[i] = NULL;#if 0 /* Don't even want to allow access from the local host by default */ gethostname(hostname,HOSTNAMSZ); if ((host_addr = internet_addr(hostname)) == -1) { fprintf(stderr,"%s: unable to find %s in /etc/hosts or from YP", progname,hostname); exit(1); }; /* if */ add_host(host_addr); /* add local host */#endif if (((file_name = getenv("GNU_SECURE")) != NULL && /* security file */ (host_file = fopen(file_name,"r")) != NULL)) { /* opened ok */ while ((fscanf(host_file,"%s",hostname) != EOF)) /* find a host */ if ((host_addr = internet_addr(hostname)) != -1) {/* get its addr */ add_host(host_addr); /* add the addr */ hosts++; } fclose(host_file); }; /* if */ return hosts;} /* setup_table *//* internet_init -- initialize server, returning an internet socket that can be listened on.*/int internet_init(){ int ls; /* socket descriptor */ struct servent *sp; /* pointer to service information */ struct sockaddr_in server; /* for local socket address */ char *ptr; /* ptr to return from getenv */ if (setup_table() == 0) return -1; /* clear out address structure */ bzero((char *)&server,sizeof(struct sockaddr_in)); /* Set up address structure for the listen socket. */ server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; /* Find the information for the gnu server * in order to get the needed port number. */ if ((ptr=getenv("GNU_PORT")) != NULL) server.sin_port = htons(atoi(ptr)); else if ((sp = getservbyname ("gnuserv", "tcp")) == NULL) server.sin_port = htons(DEFAULT_PORT+getuid()); else server.sin_port = sp->s_port; /* Create the listen socket. */ if ((ls = socket (AF_INET,SOCK_STREAM, 0)) == -1) { perror(progname); fprintf(stderr,"%s: unable to create socket\n",progname); exit(1); }; /* if */ /* Bind the listen address to the socket. */ if (bind(ls,(struct sockaddr *) &server,sizeof(struct sockaddr_in)) == -1) { perror(progname); fprintf(stderr,"%s: unable to bind socket\n",progname); exit(1); }; /* if */ /* Initiate the listen on the socket so remote users * can connect. */ if (listen(ls,20) == -1) { perror(progname); fprintf(stderr,"%s: unable to listen\n",progname); exit(1); }; /* if */ return(ls);} /* internet_init *//* handle_internet_request -- accept a request from a client and send the information to stdout (the gnu process).*/void handle_internet_request(ls)int ls; /* listen socket */{ int s; int addrlen = sizeof(struct sockaddr_in); struct sockaddr_in peer; /* for peer socket address */ bzero((char *)&peer,sizeof(struct sockaddr_in)); if ((s = accept(ls,(struct sockaddr *)&peer,&addrlen)) == -1) { perror(progname); fprintf(stderr,"%s: unable to accept\n",progname); exit(1); }; /* if */ /* Check that access is allowed - if not return crud to the client */ if (!permitted(peer.sin_addr.s_addr)) { send_string(s,"gnudoit: Connection refused\ngnudoit: unable to connect to remote"); close(s); return; }; /* if */ echo_request(s); } /* handle_internet_request */#endif /* INTERNET_DOMAIN_SOCKETS */#ifdef UNIX_DOMAIN_SOCKETS/* unix_init -- initialize server, returning an unix-domain socket that can be listened on.*/int unix_init(){ int ls; /* socket descriptor */ struct sockaddr_un server; /* unix socket address */ if ((ls = socket(AF_UNIX,SOCK_STREAM, 0)) < 0) { perror(progname); fprintf(stderr,"%s: unable to create socket\n",progname); exit(1); }; /* if */ /* Set up address structure for the listen socket. */#ifdef HIDE_UNIX_SOCKET sprintf(server.sun_path,"/tmp/gsrvdir%d",geteuid()); if (mkdir(server.sun_path, 0700) < 0) { /* assume it already exists, and try to set perms */ if (chmod(server.sun_path, 0700) < 0) { perror(progname); fprintf(stderr,"%s: can't set permissions on %s\n", progname, server.sun_path); exit(1); } } strcat(server.sun_path,"/gsrv"); unlink(server.sun_path); /* remove old file if it exists */#else /* HIDE_UNIX_SOCKET */ sprintf(server.sun_path,"/tmp/gsrv%d",geteuid()); unlink(server.sun_path); /* remove old file if it exists */#endif /* HIDE_UNIX_SOCKET */ server.sun_family = AF_UNIX; if (bind(ls,(struct sockaddr *)&server,strlen(server.sun_path)+2) < 0) { perror(progname); fprintf(stderr,"%s: unable to bind socket\n",progname); exit(1); }; /* if */ chmod(server.sun_path,0700); /* only this user can send commands */ if (listen(ls,20) < 0) { perror(progname); fprintf(stderr,"%s: unable to listen\n",progname); exit(1); }; /* if */ signal(SIGPIPE,SIG_IGN); /* in case user kills client */ return(ls);} /* unix_init *//* handle_unix_request -- accept a request from a client and send the information to stdout (the gnu process).*/void handle_unix_request(ls)int ls; /* listen socket */{ int s; int len = sizeof(struct sockaddr_un); struct sockaddr_un server; /* for unix socket address */ server.sun_family = AF_UNIX; if ((s = accept(ls,(struct sockaddr *)&server,&len)) < 0) { perror(progname); fprintf(stderr,"%s: unable to accept\n",progname); }; /* if */ echo_request(s); } /* handle_unix_request */#endif /* UNIX_DOMAIN_SOCKETS */main(argc,argv) int argc; char *argv[];{ int ils = -1; /* internet domain listen socket */ int uls = -1; /* unix domain listen socket */ int chan; /* temporary channel number */#ifdef SYSV_IPC struct msgbuf *msgp; /* message buffer */#endif /* SYSV_IPC */ progname = argv[0]; for(chan=3; chan < _NFILE; close(chan++)) /* close unwanted channels */ ;#ifdef USE_LITOUT { /* this is to allow ^D to pass to emacs */ int d = LLITOUT; (void) ioctl(fileno(stdout), TIOCLBIS, &d); }#endif#ifdef SYSV_IPC ipc_init(&msgp); /* get a msqid to listen on, and a message buffer */#endif /* SYSV_IPC */#ifdef INTERNET_DOMAIN_SOCKETS ils = internet_init(); /* get a internet domain socket to listen on */#endif /* INTERNET_DOMAIN_SOCKETS */#ifdef UNIX_DOMAIN_SOCKETS uls = unix_init(); /* get a unix domain socket to listen on */#endif /* UNIX_DOMAIN_SOCKETS */ while (1) {#ifdef SYSV_IPC handle_ipc_request(msgp);#else /* NOT SYSV_IPC */ fd_set rmask; FD_ZERO(&rmask); FD_SET(fileno(stdin), &rmask); if (uls >= 0) FD_SET(uls, &rmask); if (ils >= 0) FD_SET(ils, &rmask); if (select(max2(fileno(stdin),max2(uls,ils)) + 1, &rmask, (fd_set *)NULL, (fd_set *)NULL, (struct timeval *)NULL) < 0) { perror(progname); fprintf(stderr,"%s: unable to select\n",progname); exit(1); }; /* if */#ifdef UNIX_DOMAIN_SOCKETS if (uls > 0 && FD_ISSET(uls, &rmask)) handle_unix_request(uls);#endif#ifdef INTERNET_DOMAIN_SOCKETS if (ils > 0 && FD_ISSET(ils, &rmask)) handle_internet_request(ils);#endif /* INTERNET_DOMAIN_SOCKETS */ if (FD_ISSET(fileno(stdin), &rmask)) /* from stdin (gnu process) */ handle_response();#endif /* NOT SYSV_IPC */ }; /* while */} /* main */#endif /* SYSV_IPC || UNIX_DOMAIN_SOCKETS || INTERNET_DOMAIN_SOCKETS */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -