/* ** BootDone -- free up memory allocated for a connection. ** ** Parameters: ** rconn - incoming boot complete packet. ** ** Returns: ** 1 on success, 0 on failure. ** ** Side Effects: ** none. */ int BootDone(RMPCONN *rconn) { RMPCONN *oldconn; struct rmp_packet *rpl; /* * If we cant find the connection, ignore the request. */ if ((oldconn = FindConn(rconn)) == NULL) { syslog(LOG_ERR, "BootDone: no existing connection (%s)", EnetStr(rconn)); return(0); } rpl = &oldconn->rmp; /* cache ptr to RMP packet */ /* * Make sure Session ID's match. */ if (ntohs(rconn->rmp.r_rrq.rmp_session) != ((rpl->r_type == RMP_BOOT_REPL)? ntohs(rpl->r_brpl.rmp_session): ntohs(rpl->r_rrpl.rmp_session))) { syslog(LOG_ERR, "BootDone: bad session id (%s)", EnetStr(rconn)); return(0); } RemoveConn(oldconn); /* remove connection */ syslog(LOG_INFO, "%s: boot complete", EnetStr(rconn)); return(1); }
void C4Network2Client::CloseConns(const char *szMsg) { C4PacketConnRe Pkt(false, false, szMsg); C4Network2IOConnection *pConn; while (pConn = pMsgConn) { // send packet, close if (pConn->isOpen()) { pConn->Send(MkC4NetIOPacket(PID_ConnRe, Pkt)); pConn->Close(); } // remove RemoveConn(pConn); } }
/* ** DoTimeout -- Free any connections that have timed out. ** ** Parameters: ** None. ** ** Returns: ** Nothing. ** ** Side Effects: ** - Timed out connections in `RmpConns' will be freed. */ void DoTimeout(void) { RMPCONN *rtmp; time_t now; /* * For each active connection, if RMP_TIMEOUT seconds have passed * since the last packet was sent, delete the connection. */ now = time(NULL); for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next) if ((rtmp->tstamp.tv_sec + RMP_TIMEOUT) < now) { syslog(LOG_WARNING, "%s: connection timed out (%u)", EnetStr(rtmp), rtmp->rmp.r_type); RemoveConn(rtmp); } }
/* ** SendBootRepl -- open boot file and respond to boot request. ** ** Parameters: ** req - RMP BOOT packet containing the request. ** rconn - the reply packet to be formatted. ** filelist - list of files available to the requester. ** ** Returns: ** 1 on success, 0 on failure. ** ** Side Effects: ** none. */ int SendBootRepl(struct rmp_packet *req, RMPCONN *rconn, char *filelist[]) { int retval; char *filename, filepath[RMPBOOTDATA+1]; RMPCONN *oldconn; struct rmp_packet *rpl; char *src, *dst1, *dst2; u_int8_t i; /* * If another connection already exists, delete it since we * are obviously starting again. */ if ((oldconn = FindConn(rconn)) != NULL) { syslog(LOG_WARNING, "%s: dropping existing connection", EnetStr(oldconn)); RemoveConn(oldconn); } rpl = &rconn->rmp; /* cache ptr to RMP packet */ /* * Set up assorted fields in reply packet. */ rpl->r_brpl.rmp_type = RMP_BOOT_REPL; COPYWORD(req->r_brq.rmp_seqno, rpl->r_brpl.rmp_seqno); rpl->r_brpl.rmp_session = htons(GenSessID()); rpl->r_brpl.rmp_version = htons(RMP_VERSION); rpl->r_brpl.rmp_flnmsize = req->r_brq.rmp_flnmsize; /* * Copy file name to `filepath' string, and into reply packet. */ src = &req->r_brq.rmp_flnm; dst1 = filepath; dst2 = &rpl->r_brpl.rmp_flnm; for (i = 0; i < req->r_brq.rmp_flnmsize; i++) *dst1++ = *dst2++ = *src++; *dst1 = '\0'; /* * If we are booting HP-UX machines, their secondary loader will * ask for files like "/hp-ux". As a security measure, we do not * allow boot files to lay outside the boot directory (unless they * are purposely link'd out. So, make `filename' become the path- * stripped file name and spoof the client into thinking that it * really got what it wanted. */ filename = (filename = strrchr(filepath,'/'))? ++filename: filepath; /* * Check that this is a valid boot file name. */ for (i = 0; i < C_MAXFILE && filelist[i] != NULL; i++) if (STREQN(filename, filelist[i])) goto match; /* * Invalid boot file name, set error and send reply packet. */ rpl->r_brpl.rmp_retcode = RMP_E_NOFILE; retval = 0; goto sendpkt; match: /* * This is a valid boot file. Open the file and save the file * descriptor associated with this connection and set success * indication. If the file couldnt be opened, set error: * "no such file or dir" - RMP_E_NOFILE * "file table overflow" - RMP_E_BUSY * "too many open files" - RMP_E_BUSY * anything else - RMP_E_OPENFILE */ if ((rconn->bootfd = open(filename, O_RDONLY, 0600)) < 0) { rpl->r_brpl.rmp_retcode = (errno == ENOENT)? RMP_E_NOFILE: (errno == EMFILE || errno == ENFILE)? RMP_E_BUSY: RMP_E_OPENFILE; retval = 0; } else { rpl->r_brpl.rmp_retcode = RMP_E_OKAY; retval = 1; } sendpkt: syslog(LOG_INFO, "%s: request to boot %s (%s)", EnetStr(rconn), filename, retval? "granted": "denied"); rconn->rmplen = RMPBOOTSIZE(rpl->r_brpl.rmp_flnmsize); return (retval & SendPacket(rconn)); }