📄 spm.c
字号:
* such as the port number assigned to this socket */length = sizeof(sin);if(getsockname(skt->skt,(struct sockaddr *) &sin,&length)) { freeSocket(skt); skt= NULL; return skt; }skt->port= ntohs(sin.sin_port);/* prepare socket queue for (up to) PM_MAXREQUESTS (nominally 10) connection requests. * Often, even though PM_MAXREQUESTS > 5, only 5 pending connection requests will be * permitted by your o/s settings. */listen(skt->skt,PM_MAXREQUESTS);#ifndef MSDOS#ifndef _AIX/* turn off TCP's buffering algorithm so small packets don't get * needlessly delayed */if(setsockopt(skt->skt,IPPROTO_TCP,TCP_NODELAY,(char *) &status,sizeof(status)) < 0) { }#endif /* #ifndef _AIX ... */#endif /* #ifndef MSDOS ... *//* return server socket */return skt;}/* ---------------------------------------------------------------------- *//* makePortTable: this function allocates, links, sets up a PortTable */#ifdef __PROTOTYPE__static PortTable *makePortTable( SKTEVENT port, char *sharehost)#elsestatic PortTable *makePortTable(port,sharehost)SKTEVENT port;char *sharehost;#endif{PortTable *p;/* allocate a PortTable */p= (PortTable *) malloc(sizeof(PortTable));outofmem((void *) p,"attempt to makePortTable(%s,%d)",sktname,port);/* double link a PortTable */if(ptl) ptl->nxt= p;else phd = p;p->nxt= NULL;p->prv= ptl;ptl = p;/* set up PortTable */p->sktname= (char *) calloc((size_t) strlen(sktname)+1,sizeof(char));outofmem((void *) p->sktname,"attempt to allocate sktname<%s>\n",sktname);strcpy(p->sktname,sktname);p->sharehost= NULL;p->port = port;/* set up optional sharehost */if(sharehost) { p->sharehost= (char *) calloc((size_t) strlen(sharehost)+1,sizeof(char)); outofmem((void *) p->sharehost,"attempt to allocate sharehost<%s>\n",sharehost); strcpy(p->sharehost,sharehost); }return p;}/* ---------------------------------------------------------------------- *//* delPortTable: this function deletes a PortTable */#ifdef __PROTOTYPE__static void delPortTable(PortTable *p)#elsestatic void delPortTable(p)PortTable *p;#endif{/* free memory used by PortTable */if(p->sktname) free(p->sktname);if(p->sharehost) free(p->sharehost);/* de-link the PortTable */if(p->prv) p->prv->nxt= p->nxt;else phd = p->nxt;if(p->nxt) p->nxt->prv= p->prv;else ptl = p->prv;}/* ---------------------------------------------------------------------- *//* pm_server: this function handles the PortMaster Server protocol */#ifdef __PROTOTYPE__void pm_server( Socket *client, /* temporary client->PortMaster socket */ SKTEVENT event) /* PM_SERVER or PM_SHARE */#elsevoid pm_server(client,event)Socket *client;SKTEVENT event;#endif{PortTable *p;SKTEVENT port;static char sharehost[BUFSIZE];Swrite(client,(char *) &ok,sizeof(ok));if(event == PM_SHARE) { if(Stimeoutwait(client,TIMEOUT,0L) < 0) longjmp(timedout,1); Sgets(sharehost,BUFSIZE,client); }else sharehost[0]= '\0';if(Stimeoutwait(client,TIMEOUT,0L) < 0) longjmp(timedout,1);Sgets(sktname,BUFSIZE,client);/* check if sktname already in table */for(p= phd; p; p= p->nxt) if(!strcmp(sktname,p->sktname)) { Swrite(client,(char *) &sorry,sizeof(sorry)); return; }if(Stimeoutwait(client,TIMEOUT,0L) < 0) longjmp(timedout,1);Sreadbytes(client,(char *) &port,sizeof(port));port= ntohs( port);/* make a PortTable entry for the new server */p = makePortTable(port,(event == PM_SHARE)? sharehost : NULL);/* unable to make PortTable entry */if(!p) { Swrite(client,(char *) &sorry,sizeof(sorry)); }else { Swrite(client,(char *) &ok,sizeof(ok)); }}/* ---------------------------------------------------------------------- *//* pm_client: handle PortMaster client protocol (looks up server port) */#ifdef __PROTOTYPE__void pm_client(Socket *client)#elsevoid pm_client(client)Socket *client;#endif{PortTable *p;SKTEVENT port;Swrite(client,(char *) &ok,sizeof(ok));if(Stimeoutwait(client,TIMEOUT,0L) < 0) longjmp(timedout,1);Sgets(sktname,BUFSIZE,client);/* attempt to look up sktname in PortTable linked list */for(p= phd; p; p= p->nxt) { if(!strcmp(p->sktname,sktname)) { /* respond with PM_OK (normally) or PM_OKSHARE for PortMaster-sharing */ if(p->sharehost) { Swrite(client,(char *) &okshare,sizeof(okshare)); Sputs(p->sharehost,client); } else { Swrite(client,(char *) &ok,sizeof(ok)); } /* return port number */ port= htons(p->port); Swrite(client,(char *) &port,sizeof(port)); break; } }/* if unable to find server */if(!p) { Swrite(client,(char *) &sorry,sizeof(sorry)); }}/* ---------------------------------------------------------------------- *//* pm_close: this function handles a server close (removes server from * PortTable) */#ifdef __PROTOTYPE__void pm_close(Socket *client)#elsevoid pm_close(client)Socket *client;#endif{PortTable *p;SKTEVENT port;Swrite(client,(char *) &ok,sizeof(ok));/* get port of skt to be closed */if(Stimeoutwait(client,TIMEOUT,0L) < 0) longjmp(timedout,1);Sreadbytes(client,(char *) &port,sizeof(port));port= ntohs( port);for(p= phd; p; p= p->nxt) { if(p->port == port) { Swrite(client,(char *) &ok,sizeof(ok)); delPortTable(p); break; } }/* report if unable to find requested port */if(!p) { Swrite(client,(char *) &sorry,sizeof(sorry)); }}/* ---------------------------------------------------------------------- *//* pm_quit: this function causes the PortMaster to quit (shutdown) */#ifdef __PROTOTYPE__void pm_quit( Socket *server, Socket *client)#elsevoid pm_quit( server, client)Socket *server;Socket *client;#endif{Swrite(client,(char *) &ok,sizeof(ok));/* get sktname (should be PortMaster) */if(Stimeoutwait(client,TIMEOUT,0L) < 0) longjmp(timedout,1);Sgets(sktname,BUFSIZE,client);/* if sktname was "PortMaster", then quit */if(!strcmp(sktname,"PortMaster")) { if(client) { shutdown(client->skt,2); close(client->skt); client->skt= NULL; freeSocket(client); } if(server) { shutdown(client->skt,2); close(server->skt); server->skt= NULL; freeSocket(server); }#ifdef vms exit(1);#else exit(0);#endif }/* if not "PortMaster", then don't quit */else { Swrite(client,(char *) &sorry,sizeof(sorry)); }}/* ---------------------------------------------------------------------- *//* pm_table: this function returns the PortMaster's PortTable through the * socket to it */#ifdef __PROTOTYPE__void pm_table(Socket *client)#elsevoid pm_table(client)Socket *client;#endif{PortTable *p;SKTEVENT cnt;Swrite(client,(char *) &ok,sizeof(ok));/* count table entries */for(p= phd, cnt= 0; p; p= p->nxt) ++cnt;cnt= htons(cnt);Swrite(client,(char *) &cnt,sizeof(cnt));/* send PortMaster table out the socket */for(p= phd; p; p= p->nxt) { if(p->sharehost) Sprintf(client,"%s@%s : %d",p->sktname,p->sharehost,p->port); else Sprintf(client,"%s : %d",p->sktname,p->port); }}/* ---------------------------------------------------------------------- *//* pm_rmserver: this function removes a server entry from the PortTable */#ifdef __PROTOTYPE__void pm_rmserver(Socket *client)#elsevoid pm_rmserver(client)Socket *client;#endif{char locbuf[BUFSIZE];PortTable *p;Swrite(client,(char *) &ok,sizeof(ok));/* get name of server to be removed from PortTable */if(Stimeoutwait(client,TIMEOUT,0L) < 0) longjmp(timedout,1);Sgets(locbuf,BUFSIZE,client);for(p= phd; p; p= p->nxt) { if(!strcmp(p->sktname,locbuf)) { Swrite(client,(char *) &ok,sizeof(ok)); delPortTable(p); break; } }/* report if unable to find requested port */if(!p) { Swrite(client,(char *) &sorry,sizeof(sorry)); }}/* --------------------------------------------------------------------- */#ifdef SPMFIREWALL/* firewall: how to keep out unwanted types * Environment Variable: SPMFIREWALL=spfirewall.dat file * * <spmfirewall.dat> format: * [#*] [#*] [#*] [#*] [#*] [#*] * * Use a number to restrict entry; an * for accept all * * Returns: 0=accept * 1=reject */#ifdef __PROTOTYPE__int firewall(Socket *skt)#elseint firewall(skt)Socket *skt;#endif{int ret = 1; /* default: flag as reject */static struct sockaddr name;static int namelen= sizeof(name.sa_data);SpmFW *spmfw = NULL;if(!spmfwhd) { return 0; }/* get connecting socket's internet address (peername) */if(getpeername(skt->skt,&name,&namelen) == -1) { }else { /* check that connecting socket's internet address is approved */ int i; int datum; for(spmfw= spmfwhd; spmfw; spmfw= spmfw->nxt) { for(i= 0; i < SPMFWDATA; ++i) { datum= name.sa_data[i]; if(datum < 0) datum+= 256; if(spmfw->data[i] != -1 && spmfw->data[i] != datum) break; } if(i >= SPMFWDATA) { /* name in firewall */ ret= 0; /* accept */ break; } } }return ret;}/* --------------------------------------------------------------------- *//* firewall_init: initialize PortMaster firewall */#ifdef __PROTOTYPE__void firewall_init(char *fwfile)#elsevoid firewall_init(fwfile)char *fwfile;#endif{char buf[BUFSIZE];char *b;int i;int self = 0;FILE *fp = NULL;SpmFW *spmfw= NULL;/* free up old firewall data (if any) */if(spmfwhd) { SpmFW *spmfwnxt=NULL; for(spmfw= spmfwhd; spmfw; spmfw= spmfwnxt) { spmfwnxt= spmfw->nxt; free((char *) spmfw); } spmfwhd= NULL; }if(!fwfile || !fwfile[0]) { /* get fwfile from environment SPMFIREWALL */ fwfile= getenv("SPMFIREWALL"); }if(fwfile) { fp= fopen(fwfile,"r"); if(fp) { /* allocate and forward-link a SpmFW */ spmfw= (SpmFW *) malloc(sizeof(SpmFW)); if(!spmfw) { error(XTDIO_WARNING, "unable to allocate a SpmFW in firewall_init()\n"); return; } spmfw->nxt = spmfwhd; spmfwhd = spmfw; /* insure that the PortMaster host is on the firewall list */ spmfw->data[0]= -1; spmfw->data[1]= -1; spmfw->data[2]= hostaddr[0]; spmfw->data[3]= hostaddr[1]; spmfw->data[4]= hostaddr[2]; spmfw->data[5]= hostaddr[3]; /* read in <spmfirewall.dat> file */ while(fgets(buf,BUFSIZE,fp)) { /* ignore comments, ignore blank lines */ b= strchr(buf,'#'); if(b) *b= '\0'; b= stpblk(buf); if(!b[0]) continue; /* allocate and forward-link a SpmFW */ spmfw= (SpmFW *) malloc(sizeof(SpmFW)); if(!spmfw) { error(XTDIO_WARNING, "unable to allocate a SpmFW in firewall_init()\n"); return; } spmfw->nxt= spmfwhd; spmfwhd = spmfw; for(i= 0; i < SPMFWDATA; ++i) { if(*b == '*') { spmfw->data[i]= -1; b = stpblk(b+1); } else { sscanf(b,"%d",&spmfw->data[i]); b= stpnxt(b,"%d%b"); } } } } }}/* --------------------------------------------------------------------- *//* pm_fwinit: handles PortMaster firewall re-initialize */#ifdef __PROTOTYPE__void pm_fwinit(Socket *client)#elsevoid pm_fwinit(client)Socket *client;#endif{firewall_init("");Swrite(client,(char *) &ok,sizeof(ok));}#endif /* SPMFIREWALL *//* --------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -