// parse_peer(s, len) // Parse a peer specification from the first 'len' characters of 's'. // A peer specification looks like "PEER [alias] [addr]:[port]". static peer_t *parse_peer(const char *s, size_t len) { peer_t *p = (peer_t *) malloc(sizeof(peer_t)); if (p) { p->next = NULL; if (osp2p_snscanf(s, len, "PEER %s %I:%d", p->alias, &p->addr, &p->port) >= 0 && p->port > 0 && p->port <= 65535) return p; } free(p); return NULL; }
// task_upload(t) // Handles an upload request from another peer. // First reads the request into the task buffer, then serves the peer // the requested file. static void task_upload(task_t *t) { int blockno; int namelen; size_t offset; assert(t->type == TASK_UPLOAD); // First, read the request from the peer. while (1) { int ret = read_to_taskbuf(t->peer_fd, t); if (ret == TBUF_ERROR) { error("* Cannot read from connection"); goto exit; } else if (ret == TBUF_END || (t->tail && t->buf[t->tail-1] == '\n')) break; } //************************************* //Exercise 2: prevent a peer from requesting an invalid file name if(strlen(t->buf) > FILENAMESIZ + 10){ error("Error: file name requested by peer is too long\n"); goto exit; } assert(t->head == 0); if (osp2p_snscanf(t->buf, t->tail, "GET %s OSP2P\n", t->filename) < 0) { error("* Odd request %.*s\n", t->tail, t->buf); goto exit; } namelen = strlen(t->filename); blockno = t->filename[namelen-1] - '0'; t->filename[namelen-1] = 0; t->head = t->tail = 0; int i; for(i = 0; i < FILENAMESIZ && t->filename[i] != 0; i++){ if(t->filename[i] == '/'){ error("Error: file requested by peer is not in current directory\n"); goto exit; } } //************************************************* if(evil_mode == 0){ t->disk_fd = open(t->filename, O_RDONLY); if (t->disk_fd == -1) { error("* Cannot open file %s", t->filename); goto exit; } lseek(t->disk_fd, BLKSIZE, SEEK_CUR); message("* Transferring file %s\n", t->filename); // Now, read file from disk and write it to the requesting peer. while (1) { int ret = write_from_taskbuf(t->peer_fd, t); if (ret == TBUF_ERROR) { error("* Peer write error"); goto exit; } ret = read_to_taskbuf(t->disk_fd, t); if (ret == TBUF_ERROR) { error("* Disk read error"); goto exit; } else if (ret == TBUF_END && t->head == t->tail) /* End of file */ break; } } else{ //*************************** //Exercise 3: send null device data to peer t->disk_fd = open("/dev/null", O_RDONLY); if (t->disk_fd == -1) { error("* Cannot open file\n"); goto exit; } message("* Transferring file\n"); while (1) { int ret = write_from_taskbuf(t->peer_fd, t); if (ret == TBUF_ERROR) { error("* Peer write error"); goto exit; } ret = read_to_taskbuf(t->disk_fd, t); if (ret == TBUF_ERROR) { error("* Disk read error"); goto exit; } } //**************************** } message("* Upload of %s complete\n", t->filename); exit: task_free(t); }