/* * open a file with flags and mode and return file descriptor. */ int open(const char * path, u32_t flags, u32_t mode) { char buf[MAX_PATH]; struct file * fp; int fd; int err; if((fd = fd_alloc(0)) < 0) return -1; if(vfs_path_conv(path, buf) !=0 ) { fd_free(fd); return -1; } if((err = sys_open(buf, flags, mode, &fp)) != 0) { fd_free(fd); return err; } set_fp(fd, fp); return fd; }
/* * scamper_fds_poll * * the money function: this function polls the file descriptors held by * scamper. for each fd with an event, it calls the callback registered * with the fd. */ int scamper_fds_poll(struct timeval *timeout) { scamper_fd_t *fdn; struct timeval tv; /* * if there are fds that can be reaped, then do so. * if there are fds left over after, use that to guide the select timeout. */ if(dlist_count(refcnt_0) > 0) { gettimeofday_wrap(&tv); while((fdn = (scamper_fd_t *)dlist_head_get(refcnt_0)) != NULL) { assert(fdn->refcnt == 0); if(timeval_cmp(&fdn->tv, &tv) > 0) break; fd_close(fdn); fd_free(fdn); } if(fdn != NULL) { timeval_diff_tv(&tv, &tv, &fdn->tv); if(timeout == NULL || timeval_cmp(&tv, timeout) < 0) timeout = &tv; } } return pollfunc(timeout); }
/* * scamper_fd_private * * allocate a private fd for scamper to manage. this fd is not shared amongst * scamper. */ scamper_fd_t *scamper_fd_private(int fd, scamper_fd_cb_t read_cb, void *read_param, scamper_fd_cb_t write_cb, void *write_param) { scamper_fd_t *fdn = NULL; if((fdn = fd_alloc(SCAMPER_FD_TYPE_PRIVATE, fd)) == NULL) { goto err; } if((fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL) goto err; if(read_cb != NULL) { scamper_fd_read_set(fdn, read_cb, read_param); scamper_fd_read_unpause(fdn); } if(write_cb != NULL) { scamper_fd_write_set(fdn, write_cb, write_param); scamper_fd_write_unpause(fdn); } return fdn; err: if(fdn != NULL) fd_free(fdn); return NULL; }
static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 1; int *ip; switch (cmd) { case BIO_CTRL_RESET: num = 0; case BIO_C_FILE_SEEK: ret = 0; if (b->init) { ret = (long)lseek(b->num, num, SEEK_SET); } break; case BIO_C_FILE_TELL: case BIO_CTRL_INFO: ret = 0; if (b->init) { ret = (long)lseek(b->num, 0, SEEK_CUR); } break; case BIO_C_SET_FD: fd_free(b); b->num = *((int *)ptr); b->shutdown = (int)num; b->init = 1; break; case BIO_C_GET_FD: if (b->init) { ip = (int *)ptr; if (ip != NULL) { *ip = b->num; } return 1; } else { ret = 0; } break; case BIO_CTRL_GET_CLOSE: ret = b->shutdown; break; case BIO_CTRL_SET_CLOSE: b->shutdown = (int)num; break; case BIO_CTRL_PENDING: case BIO_CTRL_WPENDING: ret = 0; break; case BIO_CTRL_FLUSH: ret = 1; break; default: ret = 0; break; } return ret; }
/* * NAME * sh6 - shell (command interpreter) * * SYNOPSIS * sh6 [- | -c [string] | -t | file [arg1 ...]] * * DESCRIPTION * See the sh6(1) manual page for full details. */ int main(int argc, char **argv) { bool dosigs = false; sh_init(argv[0]); if (argv[0] == NULL || *argv[0] == EOS) err(SH_ERR, FMT1S, ERR_ALINVAL); if (fd_isdir(FD0)) goto done; if (argc > 1) { name = argv[1]; dolv = &argv[1]; dolc = argc - 1; if (*argv[1] == HYPHEN) { dosigs = true; if (argv[1][1] == 'c' && argc > 2) { dolv += 1; dolc -= 1; argv2p = argv[2]; } else if (argv[1][1] == 't') one_line_flag = 2; } else { (void)close(FD0); if (open(argv[1], O_RDONLY) != FD0) err(SH_ERR, FMT2S, argv[1], ERR_OPEN); if (fd_isdir(FD0)) goto done; } } else { dosigs = true; if (isatty(FD0) != 0 && isatty(FD2) != 0) prompt = (geteuid() != 0) ? "% " : "# "; } if (dosigs) { if (sasignal(SIGINT, SIG_IGN) == SIG_DFL) sig_child |= S_SIGINT; if (sasignal(SIGQUIT, SIG_IGN) == SIG_DFL) sig_child |= S_SIGQUIT; if (prompt != NULL) if (sasignal(SIGTERM, SIG_IGN) == SIG_DFL) sig_child |= S_SIGTERM; } fd_free(); sh_magic(); loop: if (prompt != NULL) fd_print(FD2, "%s", prompt); rpx_line(); goto loop; done: return status; }
static scamper_fd_t *fd_alloc_dm(int type, int fd, const char *file, const int line) #endif { scamper_fd_t *fdn = NULL; size_t size; int i; #ifndef DMALLOC if((fdn = malloc_zero(sizeof(scamper_fd_t))) == NULL) #else if((fdn = malloc_zero_dm(sizeof(scamper_fd_t), file, line)) == NULL) #endif { goto err; } fdn->type = type; fdn->fd = fd; fdn->refcnt = 1; /* set up to poll read ability */ if((fdn->read.node = dlist_node_alloc(&fdn->read)) == NULL) { goto err; } fdn->read.fdn = fdn; fdn->read.flags = SCAMPER_FD_POLL_FLAG_INACTIVE; /* set up to poll write ability */ if((fdn->write.node = dlist_node_alloc(&fdn->write)) == NULL) { goto err; } fdn->write.fdn = fdn; fdn->write.flags = SCAMPER_FD_POLL_FLAG_INACTIVE; /* store the fd in an array indexed by the fd number */ if(fd+1 > fd_array_s) { size = sizeof(scamper_fd_t *) * (fd+1); if(realloc_wrap((void **)&fd_array, size) != 0) goto err; for(i=fd_array_s; i<fd+1; i++) fd_array[i] = NULL; fd_array_s = fd+1; } fd_array[fd] = fdn; return fdn; err: if(fdn != NULL) fd_free(fdn); return NULL; }
/* * fd_refcnt_0 * * this function is called whenever a fdn with a refcnt field of zero is * found. */ static void fd_refcnt_0(scamper_fd_t *fdn) { /* * if the fd is in a list that is currently locked, then it can't be * removed just yet */ if(dlist_islocked(fd_list) != 0 || (fdn->read.list != NULL && dlist_islocked(fdn->read.list) != 0) || (fdn->write.list != NULL && dlist_islocked(fdn->write.list) != 0)) { return; } /* * if this is a private fd and the reference count has reached zero, * then the scamper_fd structure can be freed up completely now */ if(fdn->type == SCAMPER_FD_TYPE_PRIVATE) { fd_free(fdn); return; } /* if it is not possible to put the node on a list, just free it */ if((fdn->rc0 = dlist_tail_push(refcnt_0, fdn)) == NULL) { fd_close(fdn); fd_free(fdn); return; } /* * set this fd to be closed in ten seconds unless something else comes * along and wants to use it. */ gettimeofday_wrap(&fdn->tv); fdn->tv.tv_sec += 10; return; }
static scamper_fd_t *fd_tcp(int type, void *addr, uint16_t sport) { scamper_fd_t *fdn, findme; size_t len = 0; int fd = -1; findme.type = type; findme.fd_tcp_addr = addr; findme.fd_tcp_sport = sport; if((fdn = fd_find(&findme)) != NULL) { return fdn; } if(type == SCAMPER_FD_TYPE_TCP4) { fd = scamper_tcp4_open(addr, sport); len = sizeof(struct in_addr); } else if(type == SCAMPER_FD_TYPE_TCP6) { fd = scamper_tcp6_open(addr, sport); len = sizeof(struct in6_addr); } if(fd == -1 || (fdn = fd_alloc(type, fd)) == NULL || (addr != NULL && (fdn->fd_tcp_addr = memdup(addr, len)) == NULL)) { goto err; } fdn->fd_tcp_sport = sport; if((fdn->fd_tree_node = splaytree_insert(fd_tree, fdn)) == NULL || (fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL) { goto err; } return fdn; err: if(fd != -1) { if(type == SCAMPER_FD_TYPE_TCP4) scamper_tcp4_close(fd); else if(type == SCAMPER_FD_TYPE_TCP6) scamper_tcp6_close(fd); } if(fdn != NULL) fd_free(fdn); return NULL; }
static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret = 1; int *ip; switch (cmd) { case BIO_CTRL_RESET: num = 0; /* fall thru */ case BIO_C_FILE_SEEK: ret = (long)UP_lseek(b->num, num, 0); break; case BIO_C_FILE_TELL: case BIO_CTRL_INFO: ret = (long)UP_lseek(b->num, 0, 1); break; case BIO_C_SET_FD: fd_free(b); b->num = *((int *)ptr); b->shutdown = (int)num; b->init = 1; break; case BIO_C_GET_FD: if (b->init) { ip = (int *)ptr; if (ip != NULL) *ip = b->num; ret = b->num; } else ret = -1; break; case BIO_CTRL_GET_CLOSE: ret = b->shutdown; break; case BIO_CTRL_SET_CLOSE: b->shutdown = (int)num; break; case BIO_CTRL_PENDING: case BIO_CTRL_WPENDING: ret = 0; break; case BIO_CTRL_DUP: case BIO_CTRL_FLUSH: ret = 1; break; default: ret = 0; break; } return (ret); }
/* * open a directory */ void * opendir(const char * name) { char buf[MAX_PATH]; struct dir * dir; struct file * fp; int fd; int err; if((dir = malloc(sizeof(struct dir))) == NULL) return NULL; /* find empty slot for file descriptor. */ if((fd = fd_alloc(0)) < 0) { free(dir); return NULL; } if((err = vfs_path_conv(name, buf)) !=0 ) { free(dir); fd_free(fd); return NULL; } if((err = sys_opendir(buf, &fp)) != 0) { free(dir); fd_free(fd); return NULL; } set_fp(fd, fp); dir->fd = fd; return (void *)dir; }
int sys_mkdir(char *path, unsigned int mode) { struct file *file; int fd = fd_alloc(); if (fd < 0) goto out; file = file_mkdir(path, mode); if (!file) goto out_free_fd; fd_save_file(fd, file); return fd; out_free_fd: fd_free(fd); out: return -1; }
int sys_open(char *name, unsigned int mode) { struct file *file; int fd = fd_alloc(); if (fd < 0) goto out; file = file_open(name, mode); if (!file) goto out_free_fd; fd_save_file(fd, file); return fd; out_free_fd: fd_free(fd); out: return -1; }
/* * close a file by file descriptor */ int close(int fd) { struct file_t * fp; int err; if(fd < 0) return -1; if((fp = get_fp(fd)) == NULL) return -1; if((err = sys_close(fp)) != 0) return err; fd_free(fd); return 0; }
int main(int argc, char** argv) { if(argc < 4) { fprintf(stderr,"Usage: ./panorepack oldfile newcontents outputfile\n"); exit(1); } filedata* fd = loadfile(argv[1]); if(fd->filetype != SVF) { fprintf(stderr,"Error: oldfile must be valid SVF file\n"); exit(4); } char* newcontents; uint64_t newlen = readintobuf(argv[2], &newcontents); svffile_generic* ret = fd->parsed; // find the data lump header uint32_t i; for(i=0;i<ret->hdr->lumps.count;i++) { if(strncmp(ret->lumpheaders[i].tag,"DATA",4)==0) { break; } } if(i==ret->hdr->lumps.count) { fprintf(stderr,"Error: No DATA lump found in input file!\n"); exit(8); } uint64_t headerlen = fd->length - ret->lumpheaders[i].length; uint64_t newtotallen = headerlen + newlen + 6; char* newbuff = (char*)calloc(sizeof(char),newtotallen); ret->lumpheaders[i].length = newlen + 6; memcpy(newbuff, fd->contents, headerlen); memcpy(newbuff+headerlen+6, newcontents, newlen); *(uint32_t*)(newbuff + headerlen) = crc32(0,newcontents, newlen); *(uint32_t*)newbuff = newtotallen; FILE* of = fopen(argv[3],"w"); if(of == NULL) { fprintf(stderr,"Error: Unable to open output file %s for writing!\n",argv[3]); exit(16); } fwrite(newbuff, sizeof(char), newtotallen, of); fclose(of); free(newbuff); free(newcontents); fd_free(fd); }
/* * close a directory */ int closedir(void * dir) { struct file * fp; struct dir * pdir; int err; if(!dir) return -1; pdir = (struct dir *)dir; if((fp = get_fp(pdir->fd)) == NULL) return -1; if((err = sys_closedir(fp)) != 0) return err; fd_free(pdir->fd); free(dir); return 0; }
static scamper_fd_t *fd_null(int type) { scamper_fd_t *fdn = NULL, findme; int fd = -1; /* first check if a sharable fd exists for this type */ findme.type = type; if((fdn = fd_find(&findme)) != NULL) { return fdn; } if(type == SCAMPER_FD_TYPE_RTSOCK) fd = scamper_rtsock_open(); else if(type == SCAMPER_FD_TYPE_IFSOCK) fd = socket(AF_INET, SOCK_DGRAM, 0); else if(type == SCAMPER_FD_TYPE_IP4) fd = scamper_ip4_openraw(); if(fd == -1 || (fdn = fd_alloc(type, fd)) == NULL || (fdn->fd_tree_node = splaytree_insert(fd_tree, fdn)) == NULL || (fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL) { goto err; } return fdn; err: if(fd != -1) { if(type == SCAMPER_FD_TYPE_RTSOCK) scamper_rtsock_close(fd); else if(type == SCAMPER_FD_TYPE_IFSOCK) close(fd); else if(type == SCAMPER_FD_TYPE_IP4) scamper_ip4_close(fd); } if(fdn != NULL) fd_free(fdn); return NULL; }
static scamper_fd_t *fd_udp(int type, void *addr, uint16_t sport) { scamper_fd_t *fdn, findme; size_t len = 0; int fd = -1; findme.type = type; findme.fd_udp_addr = addr; findme.fd_udp_sport = sport; if((fdn = fd_find(&findme)) != NULL) return fdn; if(type == SCAMPER_FD_TYPE_UDP4) { fd = scamper_udp4_openraw(addr); len = sizeof(struct in_addr); } else if(type == SCAMPER_FD_TYPE_UDP6) { fd = scamper_udp6_open(addr, sport); len = sizeof(struct in6_addr); } else if(type == SCAMPER_FD_TYPE_UDP4DG) { fd = scamper_udp4_opendgram(addr, sport); len = sizeof(struct in_addr); } if(fd == -1 || (fdn = fd_alloc(type, fd)) == NULL || (addr != NULL && (fdn->fd_udp_addr = memdup(addr, len)) == NULL)) { printerror(errno, strerror, __func__, "could not open socket"); goto err; } fdn->fd_udp_sport = sport; if((fdn->fd_tree_node = splaytree_insert(fd_tree, fdn)) == NULL) { printerror(errno, strerror, __func__, "could not add socket to tree"); goto err; } if((fdn->fd_list_node = dlist_tail_push(fd_list, fdn)) == NULL) { printerror(errno, strerror, __func__, "could not add socket to list"); goto err; } return fdn; err: if(fd != -1) { if(type == SCAMPER_FD_TYPE_UDP4 || type == SCAMPER_FD_TYPE_UDP4DG) scamper_udp4_close(fd); else if(type == SCAMPER_FD_TYPE_UDP6) scamper_udp6_close(fd); } if(fdn != NULL) fd_free(fdn); return NULL; }
/* * scamper_fds_cleanup * * tidy up the state allocated to maintain fd records. */ void scamper_fds_cleanup() { scamper_fd_t *fdn; /* clean up the lists */ cleanup_list(read_fds); read_fds = NULL; cleanup_list(write_fds); write_fds = NULL; cleanup_list(read_queue); read_queue = NULL; cleanup_list(write_queue); write_queue = NULL; /* reap anything on the reap list */ if(refcnt_0 != NULL) { while((fdn = (scamper_fd_t *)dlist_head_get(refcnt_0)) != NULL) { fd_close(fdn); fd_free(fdn); } dlist_free(refcnt_0); refcnt_0 = NULL; } /* clean up the tree */ if(fd_tree != NULL) { splaytree_free(fd_tree, NULL); fd_tree = NULL; } /* clean up the list */ if(fd_list != NULL) { dlist_free(fd_list); fd_list = NULL; } /* clean up the array */ if(fd_array != NULL) { free(fd_array); fd_array = NULL; } #ifdef HAVE_POLL if(poll_fds != NULL) { free(poll_fds); poll_fds = NULL; } #endif #ifdef HAVE_KQUEUE if(kq != -1) { close(kq); kq = -1; } if(kevlist != NULL) { free(kevlist); kevlist = NULL; } #endif #ifdef HAVE_EPOLL if(ep != -1) { close(ep); ep = -1; } if(ep_events != NULL) { free(ep_events); ep_events = NULL; } #endif return; }