//SNP process uses this function to receive a sendseg_arg_t structure which contains a segment and its destination node ID from the SRT process. //Parameter tran_conn is the TCP descriptor of the connection between the SRT process and the SNP process. //Return 1 if a sendseg_arg_t is succefully received, otherwise return -1. int getsegToSend(int tran_conn, int* dest_nodeID, seg_t* segPtr) { sendseg_arg_t a; if (-1 == recvf(&a, tran_conn)) { return -1; } *dest_nodeID = a.nodeID; memcpy(segPtr, &a.seg, sizeof(seg_t)); return 1; }
//SRT process uses this function to receive a sendseg_arg_t structure which contains a segment and its src node ID from the SNP process. //Parameter network_conn is the TCP descriptor of the connection between the SRT process and the SNP process. //When a segment is received, use seglost to determine if the segment should be discarded, also check the checksum. //Return 1 if a sendseg_arg_t is succefully received, otherwise return -1. int snp_recvseg(int network_conn, int* src_nodeID, seg_t* segPtr) { sendseg_arg_t a; if (-1 == recvf(&a, network_conn)) { return -1; } *src_nodeID = a.nodeID; memcpy(segPtr, &a.seg, sizeof(seg_t)); return 1; }
/* * Server routine to read requests and process them. * Commands are: * Tname - Transmit file if out of date * Vname - Verify if file out of date or not * Qname - Query if file exists. Return mtime & size if it does. */ void server() { char cmdbuf[BUFSIZ]; register char *cp; signal(SIGHUP, cleanup); signal(SIGINT, cleanup); signal(SIGQUIT, cleanup); signal(SIGTERM, cleanup); signal(SIGPIPE, cleanup); rem = 0; oumask = umask(0); (void) sprintf(buf, "V%d\n", VERSION); (void) write(rem, buf, strlen(buf)); for (;;) { cp = cmdbuf; if (read(rem, cp, 1) <= 0) return; if (*cp++ == '\n') { error("server: expected control record\n"); continue; } do { if (read(rem, cp, 1) != 1) cleanup(0); } while (*cp++ != '\n' && cp < &cmdbuf[BUFSIZ]); *--cp = '\0'; cp = cmdbuf; switch (*cp++) { case 'T': /* init target file/directory name */ catname = 1; /* target should be directory */ goto dotarget; case 't': /* init target file/directory name */ catname = 0; dotarget: if (exptilde(target, cp) == NULL) continue; tp = target; while (*tp) tp++; ack(); continue; case 'R': /* Transfer a regular file. */ recvf(cp, S_IFREG); continue; case 'D': /* Transfer a directory. */ recvf(cp, S_IFDIR); continue; case 'K': /* Transfer symbolic link. */ recvf(cp, S_IFLNK); continue; case 'k': /* Transfer hard link. */ hardlink(cp); continue; case 'E': /* End. (of directory) */ *tp = '\0'; if (catname <= 0) { error("server: too many 'E's\n"); continue; } tp = stp[--catname]; *tp = '\0'; ack(); continue; case 'C': /* Clean. Cleanup a directory */ clean(cp); continue; case 'Q': /* Query. Does the file/directory exist? */ query(cp); continue; case 'S': /* Special. Execute commands */ dospecial(cp); continue; #ifdef notdef /* * These entries are reserved but not currently used. * The intent is to allow remote hosts to have master copies. * Currently, only the host rdist runs on can have masters. */ case 'X': /* start a new list of files to exclude */ except = bp = NULL; case 'x': /* add name to list of files to exclude */ if (*cp == '\0') { ack(); continue; } if (*cp == '~') { if (exptilde(buf, cp) == NULL) continue; cp = buf; } if (bp == NULL) except = bp = expand(makeblock(NAME, cp), E_VARS); else bp->b_next = expand(makeblock(NAME, cp), E_VARS); while (bp->b_next != NULL) bp = bp->b_next; ack(); continue; case 'I': /* Install. Transfer file if out of date. */ opts = 0; while (*cp >= '0' && *cp <= '7') opts = (opts << 3) | (*cp++ - '0'); if (*cp++ != ' ') { error("server: options not delimited\n"); return; } install(cp, opts); continue; case 'L': /* Log. save message in log file */ log(lfp, cp); continue; #endif case '\1': nerrs++; continue; case '\2': return; default: error("server: unknown command '%s'\n", cp); case '\0': continue; } } }