void bpagealign(struct Block *blk) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); addzblock(blk, 4096 - (blk->used & 0xfff)); }
char *getstr(struct Block *blk, int off) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); assert((off >= 0) && (off < blk->used)); return (blk->mem)+off; }
// send a text message int cmdchat(char *args) { uint8_t cmdmode; int status; char *inbuf; pid_t procid; // remember to set the "silent" bit to tell the other end that we don't want output cmdmode = CODECHAT; if (args != NULL) { if (silent) { cmdmode = cmdmode | 0x80; } makeblock(cmdmode, (uint8_t *) args, strlen(args)); } else { inbuf = malloc(INPUTBUFFERSIZE); if (inbuf == NULL) { perror("can't allocate memory"); exit(0); } procid = fork(); if (procid == 0) { cmdreceive(NULL); } for (;;) { printf("CHAT] "); if (fgets(inbuf, INPUTBUFFERSIZE, stdin) > 0) { if (!strncmp(inbuf, "quit", 4)) { kill(procid, 9); wait(&status); return (0); } makeblock(cmdmode, (uint8_t *) inbuf, strlen(inbuf)); } else { return (0); } } } return (0); }
int getint(struct Block *blk, int off) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); assert((off >= 0) && (off < blk->used)); assert(off%sizeof(int) == 0); return *( (int *)((blk->mem)+off) ); }
void blkensure(struct Block *blk, int sz) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); if(blk->used + sz >= blk->size) { blk->mem = chgmem(blk->mem, blk->used + sz + GROW); blk->size = blk->used + sz + GROW; } }
int addzblock(struct Block *blk, int sz) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); blkensure(blk, sz); memset(blk->mem + blk->used, 0, sz); blk->used += sz; return blk->used - sz; }
int addint(struct Block *blk, int i) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); blkensure(blk, 4); *(int *)(blk->mem + blk->used) = i; blk->used += 4; return blk->used - 4; }
void placeint(struct Block *zb, int zint, int off) { assert(zb); if(zb->mem == NULL) makeblock(zb); assert(zb->mem); if(off%sizeof(int) != 0) error("Address not int-aligned", off); if((off > zb->used-4) || (off < 0)) fatal("Internal error: Offset outside area"); *(int *)(zb->mem + off) = zint; }
int getdata(struct Block *blk, unsigned char *f, int off, int len) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); assert(off >= 0 && len >= 0); blkensure(blk, len); memcpy(blk->mem + blk->used, f + off, len); blk->used += len; return blk->used - len; }
int addstr(struct Block *blk, char *str) { int len = strlen(str)+1; assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); blkensure(blk, len); strcpy(blk->mem + blk->used, str); blk->used += len; return blk->used - len; }
void alignarea(struct Block *a) { char zeros[4] = {'\0', '\0', '\0', '\0'}; int needed; assert(a); if(a->mem == NULL) makeblock(a); assert(a->mem); needed = 4 - (a->used % 4); if(needed == 4) return; addtoarea(a, zeros, needed); }
int loaddata(struct Block *blk, FILE *f, int off, int len) { assert(blk); if(blk->mem == NULL) makeblock(blk); assert(blk->mem); assert(off >= 0); blkensure(blk, len); if(fseek(f, off, SEEK_SET)) fatal("Can't load data (corrupt QObj?)"); fread(blk->mem + blk->used, 1, len, f); blk->used += len; return blk->used - len; }
int cmdtoken(char *args) { if (args == NULL) { memset(nonce, 0x0, crypto_box_NONCEBYTES); makeblock(CODETOKEN, (uint8_t *) "AAAAAAAA", 8); receivedata(CMDTOKEN); } else if (!strncmp(args, "static", 6)) { printf("nonce is now static\n"); staticnonce = 1; } else if (!strncmp(args, "dynamic", 7)) { printf("nonce is now dynamic\n"); staticnonce = 0; } return (0); }
int addtoarea(struct Block *zarea, void *data, int sz) { int ns; assert(zarea); if(zarea->mem == NULL) makeblock(zarea); assert(zarea->mem); if(zarea->used + sz >= zarea->size) { ns = zarea->used + sz + GROW; zarea->mem = chgmem(zarea->mem, ns); zarea->size = ns; } memcpy(zarea->mem + zarea->used, data, sz); zarea->used += sz; return zarea->used - sz; }
// supply the remote host with a command for execution int cmdexec(char *args) { uint8_t cmdmode; // if we don't get any commands to execute, return if (args == NULL) { return (1); } // remember to set the "silent" bit to tell the other end that we don't want output cmdmode = CODEEXEC; if (silent) { cmdmode = cmdmode | 0x80; } makeblock(cmdmode, (uint8_t *) args, strlen(args)); //if we aren't in silent mode listen for output if (!silent) { receivedata(CMDEXEC); } updatenonce(); return (0); }
/* * 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; } } }