/* Finds and reports all duplicate clusters in each bucket of collected files. */ static void process_clusters(void) { size_t i, j, first, second, index = 1; FileList duplicates; init_file_list(&duplicates); for (i = 0; i < BUCKET_COUNT; i++) { File* files = buckets[i].files; for (first = 0; first < buckets[i].allocated; first++) { if (files[first].status == INVALID || files[first].status == DUPLICATE) { continue; } for (second = first + 1; second < buckets[i].allocated; second++) { if (files[second].status == INVALID || files[second].status == DUPLICATE) { continue; } if (compare_files(&files[first], &files[second]) == 0) { if (duplicates.allocated == 0) { *alloc_file(&duplicates) = files[first]; files[first].status = DUPLICATE; } *alloc_file(&duplicates) = files[second]; files[second].status = DUPLICATE; } else { if (files[first].status == INVALID) break; } } if (duplicates.allocated > 0) { report_cluster(&duplicates, index); empty_file_list(&duplicates); index++; } } for (j = 0; j < buckets[i].allocated; j++) free_file(&files[j]); } free_file_list(&duplicates); }
/* Processes a single file. */ static void process_file(const char* path, struct stat* sb) { if (sb->st_size == 0) { if (ignore_empty_flag) return; } /* NOTE: Check for duplicate arguments? */ if (physical_flag) { /* TODO: Make this less pessimal */ size_t i, bucket = BUCKET_INDEX(sb->st_size); for (i = 0; i < buckets[bucket].allocated; i++) { if (buckets[bucket].files[i].device == sb->st_dev && buckets[bucket].files[i].inode == sb->st_ino) { return; } } } init_file(alloc_file(&buckets[BUCKET_INDEX(sb->st_size)]), path, sb); }
/** * Insert a new file to the global file table. * * @param inode corresponding inode * @param name filename * @param mode DATA_FILE | DIRECTORY * @return assigned file descriptor */ file_nr insert_file(m_inode *inode, char *name, uint8 mode) { name = strdup(name); file_nr old = name2desc(name); //exists a file with the same path already? if (old != NOT_FOUND) { fs_dprintf("[fs_file_table] file already exists. returned old FD.\n"); free(name); return old; } file *fd = alloc_file(); if (fd == (file*) NULL) { fs_dprintf("[fs_file_table] new file could not be allocated!\n"); free(name); return NOT_POSSIBLE; } fd->f_inode = inode; fd->f_name = name; fd->f_mode = mode; return fd->f_desc; }
/** * anon_inode_getfd - creates a new file instance by hooking it up to an * anonymous inode, and a dentry that describe the "class" * of the file * * @name: [in] name of the "class" of the new file * @fops: [in] file operations for the new file * @priv: [in] private data for the new file (will be file's private_data) * @flags: [in] flags * * Creates a new file by hooking it on a single inode. This is useful for files * that do not need to have a full-fledged inode in order to operate correctly. * All the files created with anon_inode_getfile() will share a single inode, * hence saving memory and avoiding code duplication for the file/inode/dentry * setup. Returns the newly created file* or an error pointer. */ struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags) { struct qstr this; struct dentry *dentry; struct file *file; int error; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); /* * Link the inode to a directory entry by creating a unique name * using the inode sequence number. */ error = -ENOMEM; this.name = name; this.len = strlen(name); this.hash = 0; dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this); if (!dentry) goto err_module; /* * We know the anon_inode inode count is always greater than zero, * so we can avoid doing an igrab() and we can use an open-coded * atomic_inc(). */ atomic_inc(&anon_inode_inode->i_count); dentry->d_op = &anon_inodefs_dentry_operations; /* Do not publish this dentry inside the global dentry hash table */ dentry->d_flags &= ~DCACHE_UNHASHED; d_instantiate(dentry, anon_inode_inode); error = -ENFILE; file = alloc_file(anon_inode_mnt, dentry, FMODE_READ | FMODE_WRITE, fops); if (!file) goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; file->f_pos = 0; file->f_flags = O_RDWR | (flags & O_NONBLOCK); file->f_version = 0; file->private_data = priv; return file; err_dput: dput(dentry); err_module: module_put(fops->owner); return ERR_PTR(error); }
/* Add ref to file, or allocate a new file copy if file==NULL */ struct file *get_file(struct file *file) { if (file == NULL) file = alloc_file(); file->ref += 1; return file; }
/** * anon_inode_getfd - creates a new file instance by hooking it up to an * anonymous inode, and a dentry that describe the "class" * of the file * * @name: [in] name of the "class" of the new file * @fops: [in] file operations for the new file * @priv: [in] private data for the new file (will be file's private_data) * @flags: [in] flags * * Creates a new file by hooking it on a single inode. This is useful for files * that do not need to have a full-fledged inode in order to operate correctly. * All the files created with anon_inode_getfile() will share a single inode, * hence saving memory and avoiding code duplication for the file/inode/dentry * setup. Returns the newly created file* or an error pointer. */ struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags) { struct qstr this; struct path path; struct file *file; int error; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); /* * Link the inode to a directory entry by creating a unique name * using the inode sequence number. */ error = -ENOMEM; this.name = name; this.len = strlen(name); this.hash = 0; path.dentry = d_alloc(anon_inode_mnt->mnt_sb->s_root, &this); if (!path.dentry) goto err_module; path.mnt = mntget(anon_inode_mnt); /* * We know the anon_inode inode count is always greater than zero, * so we can avoid doing an igrab() and we can use an open-coded * atomic_inc(). */ atomic_inc(&anon_inode_inode->i_count); path.dentry->d_op = &anon_inodefs_dentry_operations; d_instantiate(path.dentry, anon_inode_inode); error = -ENFILE; file = alloc_file(&path, OPEN_FMODE(flags), fops); if (!file) goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; file->f_pos = 0; file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); file->f_version = 0; file->private_data = priv; return file; err_dput: path_put(&path); err_module: module_put(fops->owner); return ERR_PTR(error); }
int lws_tls_client_create_vhost_context(struct lws_vhost *vh, const struct lws_context_creation_info *info, const char *cipher_list, const char *ca_filepath, const char *cert_filepath, const char *private_key_filepath) { X509 *d2i_X509(X509 **cert, const unsigned char *buffer, long len); SSL_METHOD *method = (SSL_METHOD *)TLS_client_method(); unsigned long error; lws_filepos_t len; uint8_t *buf; if (!method) { error = ERR_get_error(); lwsl_err("problem creating ssl method %lu: %s\n", error, ERR_error_string(error, (char *)vh->context->pt[0].serv_buf)); return 1; } /* create context */ vh->tls.ssl_client_ctx = SSL_CTX_new(method); if (!vh->tls.ssl_client_ctx) { error = ERR_get_error(); lwsl_err("problem creating ssl context %lu: %s\n", error, ERR_error_string(error, (char *)vh->context->pt[0].serv_buf)); return 1; } if (!ca_filepath) return 0; if (alloc_file(vh->context, ca_filepath, &buf, &len)) { lwsl_err("Load CA cert file %s failed\n", ca_filepath); return 1; } vh->tls.x509_client_CA = d2i_X509(NULL, buf, len); free(buf); if (!vh->tls.x509_client_CA) { lwsl_err("client CA: x509 parse failed\n"); return 1; } if (!vh->tls.ssl_ctx) SSL_CTX_add_client_CA(vh->tls.ssl_client_ctx, vh->tls.x509_client_CA); else SSL_CTX_add_client_CA(vh->tls.ssl_ctx, vh->tls.x509_client_CA); lwsl_notice("client loaded CA for verification %s\n", ca_filepath); return 0; }
/* * from tizsrv class */ static OMX_ERRORTYPE oggdmux_prc_allocate_resources (void * ap_obj, OMX_U32 a_pid) { oggdmux_prc_t * p_prc = ap_obj; assert (p_prc); tiz_check_omx (alloc_uri (p_prc)); tiz_check_omx (alloc_file (p_prc)); tiz_check_omx (alloc_data_stores (p_prc)); tiz_check_omx (alloc_oggz (p_prc)); return OMX_ErrorNone; }
int alloc_pem_to_der_file(struct lws_context *context, const char *filename, uint8_t **buf, lws_filepos_t *amount) { uint8_t *pem, *p, *q, *end; lws_filepos_t len; int n; n = alloc_file(context, filename, &pem, &len); if (n) return n; /* trim the first line */ p = pem; end = p + len; if (strncmp((char *)p, "-----", 5)) goto bail; p += 5; while (p < end && *p != '\n' && *p != '-') p++; if (*p != '-') goto bail; while (p < end && *p != '\n') p++; if (p >= end) goto bail; p++; /* trim the last line */ q = end - 2; while (q > pem && *q != '\n') q--; if (*q != '\n') goto bail; *q = '\0'; *amount = lws_b64_decode_string((char *)p, (char *)pem, len); *buf = pem; return 0; bail: lws_free(pem); return 4; }
/** * anon_inode_getfile - creates a new file instance by hooking it up to an * anonymous inode, and a dentry that describe the "class" * of the file * * @name: [in] name of the "class" of the new file * @fops: [in] file operations for the new file * @priv: [in] private data for the new file (will be file's private_data) * @flags: [in] flags * * Creates a new file by hooking it on a single inode. This is useful for files * that do not need to have a full-fledged inode in order to operate correctly. * All the files created with anon_inode_getfile() will share a single inode, * hence saving memory and avoiding code duplication for the file/inode/dentry * setup. Returns the newly created file* or an error pointer. */ struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags) { struct qstr this; struct path path; struct file *file; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); /* * Link the inode to a directory entry by creating a unique name * using the inode sequence number. */ file = ERR_PTR(-ENOMEM); this.name = name; this.len = strlen(name); this.hash = 0; path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this); if (!path.dentry) goto err_module; path.mnt = mntget(anon_inode_mnt); /* * We know the anon_inode inode count is always greater than zero, * so ihold() is safe. */ ihold(anon_inode_inode); d_instantiate(path.dentry, anon_inode_inode); file = alloc_file(&path, OPEN_FMODE(flags), fops); if (IS_ERR(file)) goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); file->private_data = priv; return file; err_dput: path_put(&path); err_module: module_put(fops->owner); return file; }
/** * shmem_file_setup - get an unlinked file living in tmpfs * @name: name for dentry (to be seen in /proc/<pid>/maps * @size: size to be set for the file * @flags: vm_flags */ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) { int error; struct file *file; struct inode *inode; struct dentry *dentry, *root; struct qstr this; if (IS_ERR(shm_mnt)) return (void *)shm_mnt; error = -ENOMEM; this.name = name; this.len = strlen(name); this.hash = 0; /* will go */ root = shm_mnt->mnt_root; dentry = d_alloc(root, &this); if (!dentry) goto put_memory; error = -ENOSPC; inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); if (!inode) goto put_dentry; d_instantiate(dentry, inode); error = -ENFILE; file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ, &ramfs_file_operations); if (!file) goto put_dentry; inode->i_nlink = 0; /* It is unlinked */ /* notify everyone as to the change of file size */ error = do_truncate(dentry, size, 0, file); if (error < 0) goto close_file; return file; close_file: put_filp(file); return ERR_PTR(error); put_dentry: dput(dentry); put_memory: return ERR_PTR(error); }
struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags) { struct qstr this; struct path path; struct file *file; int error; if (IS_ERR(anon_inode_inode)) return ERR_PTR(-ENODEV); if (fops->owner && !try_module_get(fops->owner)) return ERR_PTR(-ENOENT); error = -ENOMEM; this.name = name; this.len = strlen(name); this.hash = 0; path.dentry = d_alloc_pseudo(anon_inode_mnt->mnt_sb, &this); if (!path.dentry) goto err_module; path.mnt = mntget(anon_inode_mnt); ihold(anon_inode_inode); d_instantiate(path.dentry, anon_inode_inode); error = -ENFILE; file = alloc_file(&path, OPEN_FMODE(flags), fops); if (!file) goto err_dput; file->f_mapping = anon_inode_inode->i_mapping; file->f_pos = 0; file->f_flags = flags & (O_ACCMODE | O_NONBLOCK); file->f_version = 0; file->private_data = priv; return file; err_dput: path_put(&path); err_module: module_put(fops->owner); return ERR_PTR(error); }
FILE *op::fopen(const char *path, const char *mode) { uint8_t fd; if ((int8_t)(fd = alloc_file()) == -1) return NULL; file_t *file = __file__[fd]; if (!fs->readFileInfo(path, file)) { uint8_t err = errno; if (fclose(fd) == 0) errno = err; return NULL; } if ((file->fp = fdevopen(NULL, op::fgetchar)) == NULL) { fclose(fd); errno = ENOMEM; return NULL; } return file->fp; }
// TODO: refactor vfs so we can allocate fd and do the basic initialization struct file *alloc_socket_file(struct socket* sock) { struct file *file = alloc_file(); if (file == NULL) return 0; // Linux fakes a dentry and an inode for socks, see socket.c : sock_alloc_file file->f_dentry = NULL; // This might break things? file->f_vfsmnt = 0; file->f_flags = 0; file->f_mode = S_IRUSR | S_IWUSR; // both read and write for socket files file->f_pos = 0; file->f_uid = 0; file->f_gid = 0; file->f_error = 0; file->f_op = &socket_op; file->f_privdata = sock; file->f_mapping = 0; return file; }
int searchdir(const char *name) { struct inode *inode = NULL; struct inode *parent = NULL; struct file *file; char *pathbuf = NULL; char *part, *p, echar; int symlink_count = MAX_SYMLINK_CNT; dprintf("searchdir: %s root: %p cwd: %p\n", name, this_fs->root, this_fs->cwd); if (!(file = alloc_file())) goto err_no_close; file->fs = this_fs; /* if we have ->searchdir method, call it */ if (file->fs->fs_ops->searchdir) { file->fs->fs_ops->searchdir(name, file); if (file->inode) return file_to_handle(file); else goto err; } /* else, try the generic-path-lookup method */ parent = get_inode(this_fs->cwd); p = pathbuf = strdup(name); if (!pathbuf) goto err; do { got_link: if (*p == '/') { put_inode(parent); parent = get_inode(this_fs->root); } do { inode = get_inode(parent); while (*p == '/') p++; if (!*p) break; part = p; while ((echar = *p) && echar != '/') p++; *p++ = '\0'; if (part[0] == '.' && part[1] == '.' && part[2] == '\0') { if (inode->parent) { put_inode(parent); parent = get_inode(inode->parent); put_inode(inode); inode = NULL; if (!echar) { /* Terminal double dots */ inode = parent; parent = inode->parent ? get_inode(inode->parent) : NULL; } } } else if (part[0] != '.' || part[1] != '\0') { inode = this_fs->fs_ops->iget(part, parent); if (!inode) goto err; if (inode->mode == DT_LNK) { char *linkbuf, *q; int name_len = echar ? strlen(p) : 0; int total_len = inode->size + name_len + 2; int link_len; if (!this_fs->fs_ops->readlink || --symlink_count == 0 || /* limit check */ total_len > MAX_SYMLINK_BUF) goto err; linkbuf = malloc(total_len); if (!linkbuf) goto err; link_len = this_fs->fs_ops->readlink(inode, linkbuf); if (link_len <= 0) { free(linkbuf); goto err; } q = linkbuf + link_len; if (echar) { if (link_len > 0 && q[-1] != '/') *q++ = '/'; memcpy(q, p, name_len+1); } else { *q = '\0'; } free(pathbuf); p = pathbuf = linkbuf; put_inode(inode); inode = NULL; goto got_link; } inode->name = strdup(part); dprintf("path component: %s\n", inode->name); inode->parent = parent; parent = NULL; if (!echar) break; if (inode->mode != DT_DIR) goto err; parent = inode; inode = NULL; } } while (echar); } while (0); free(pathbuf); pathbuf = NULL; put_inode(parent); parent = NULL; if (!inode) goto err; file->inode = inode; file->offset = 0; return file_to_handle(file); err: put_inode(inode); put_inode(parent); if (pathbuf) free(pathbuf); _close_file(file); err_no_close: return -1; }
static int onload_alloc_file(tcp_helper_resource_t *thr, oo_sp ep_id, int flags, int fd_type) { struct qstr name = { .name = "" }; #ifdef EFX_HAVE_STRUCT_PATH struct path path; #define my_dentry path.dentry #else struct dentry *dentry; #define my_dentry dentry #endif struct file *file; int fd; struct inode *inode; ci_private_t *priv; struct file_operations *fops; fops = oo_fops_by_type(fd_type); if( fops == NULL ) return -EINVAL; ci_assert_equal(fops->owner, THIS_MODULE); inode = new_inode(onload_mnt->mnt_sb); if( inode == NULL ) return -ENOMEM; #ifdef EFX_FSTYPE_HAS_MOUNT inode->i_ino = get_next_ino(); #endif if( fd_type == CI_PRIV_TYPE_NETIF ) inode->i_mode = S_IRWXUGO; if( fd_type == CI_PRIV_TYPE_TCP_EP || fd_type == CI_PRIV_TYPE_UDP_EP ) inode->i_mode = #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) /* in 2.6.18 this flag makes us "socket" and sendmsg crashes; * see sock_from_file() */ S_IFSOCK | #endif S_IRWXUGO; else inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR; inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); priv = &container_of(inode, struct onload_inode, vfs_inode)->priv; priv->thr = thr; priv->sock_id = ep_id; priv->fd_type = fd_type; fd = get_unused_fd(); if( fd < 0 ) { iput(inode); return fd; } /*ci_log("[%d]%s(%d:%d) return %d priv=%p", current->pid, __func__, thr->id, ep_id, fd, priv);*/ #ifdef EFX_FSTYPE_HAS_MOUNT #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37) path.dentry = d_alloc(onload_mnt->mnt_sb->s_root, &name); if( path.dentry != NULL ) path.dentry->d_op = &onloadfs_dentry_operations; #else path.dentry = d_alloc_pseudo(onload_mnt->mnt_sb, &name); #endif #else /* EFX_FSTYPE_HAS_MOUNT */ #ifdef EFX_HAVE_D_DNAME my_dentry = d_alloc(onload_mnt->mnt_sb->s_root, &name); #else { char str[32]; name.len = onloadfs_name(&container_of(inode, struct onload_inode, vfs_inode)->priv, str, sizeof(str)); name.name = str; name.hash = inode->i_ino; my_dentry = d_alloc(onload_mnt->mnt_sb->s_root, &name); } #endif #endif /* EFX_FSTYPE_HAS_MOUNT */ if( my_dentry == NULL ) { put_unused_fd(fd); iput(inode); return -ENOMEM; } #if !defined(EFX_FSTYPE_HAS_MOUNT) || defined(EFX_OLD_MOUNT_PSEUDO) my_dentry->d_op = &onloadfs_dentry_operations; #if !defined(EFX_HAVE_STRUCT_PATH) && defined(EFX_HAVE_D_DNAME) my_dentry->d_flags &= ~DCACHE_UNHASHED; #endif #endif d_instantiate(my_dentry, inode); #ifndef EFX_HAVE_D_DNAME d_rehash(my_dentry); #endif inode->i_fop = fops; #ifdef EFX_HAVE_STRUCT_PATH path.mnt = mntget(onload_mnt); file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops); #else file = alloc_file(onload_mnt, dentry, FMODE_READ | FMODE_WRITE, fops); #endif if( file == NULL) { #ifdef EFX_HAVE_STRUCT_PATH path_put(&path); #else dput(dentry); iput(inode); #endif put_unused_fd(fd); return -ENFILE; } priv->_filp = file; file->f_flags = O_RDWR | (flags & O_NONBLOCK); file->f_pos = 0; file->private_data = priv; if( flags & O_CLOEXEC ) { struct files_struct *files = current->files; struct fdtable *fdt; spin_lock(&files->file_lock); fdt = files_fdtable(files); rcu_assign_pointer(fdt->fd[fd], file); efx_set_close_on_exec(fd, fdt); spin_unlock(&files->file_lock); } else fd_install(fd, file); try_module_get(THIS_MODULE); ci_assert_equal(file->f_op, fops); return fd; } void onload_priv_free(ci_private_t *priv) { if( priv->_filp->f_vfsmnt != onload_mnt) ci_free(priv); /* inode will free the priv automatically */ } int oo_create_fd(tcp_helper_endpoint_t* ep, int flags, int fd_type) { int fd; tcp_helper_resource_t *trs = ep->thr; citp_waitable_obj *wo = SP_TO_WAITABLE_OBJ(&trs->netif, ep->id); efab_thr_ref(trs); fd = onload_alloc_file(trs, ep->id, flags, fd_type); if( fd < 0 ) { efab_thr_release(trs); OO_DEBUG_ERR(ci_log("%s: onload_alloc_file failed (%d)", __FUNCTION__, fd)); return fd; } ci_atomic32_and(&wo-> waitable.sb_aflags, ~(CI_SB_AFLAG_ORPHAN | CI_SB_AFLAG_TCP_IN_ACCEPTQ)); return fd; }
int main(int argc,char *argv[]) { int er=1,i; signed char *s=NULL; char *tmpp; int mifiles = 5; int nifiles = 0; int verbose = 0; int oldfile = 0; int no_link = 0; char **ifiles; char *ofile; char *efile; char *lfile; char *ifile; char old_e[MAXLINE]; char old_l[MAXLINE]; char old_o[MAXLINE]; tim1=time(NULL); ncmos=0; n65816=0; cmosfl=1; w65816=0; /* default: 6502 only */ altppchar = '#' ; /* i.e., NO alternate char */ if((tmpp = strrchr(argv[0],'/'))) { tmpp++; } else { tmpp = argv[0]; } if( (!strcmp(tmpp,"xa65816")) || (!strcmp(tmpp,"XA65816")) || (!strcmp(tmpp,"xa816")) || (!strcmp(tmpp,"XA816")) ) { w65816 = 1; /* allow 65816 per default */ } /* default output charset for strings in quotes */ set_charset("ASCII"); ifiles = malloc(mifiles*sizeof(char*)); afile = alloc_file(); if (argc <= 1) { usage(w65816, stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(w65816, stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, authors, copyright); exit(0); } ofile="a.o65"; efile=NULL; lfile=NULL; if(pp_init()) { logout("fatal: pp: no memory!"); return 1; } if(b_init()) { logout("fatal: b: no memory!"); return 1; } if(l_init()) { logout("fatal: l: no memory!"); return 1; } i=1; while(i<argc) { if(argv[i][0]=='-') { switch(argv[i][1]) { case 'p': /* intentionally not allowing an argument to follow with a space to avoid - being seen as the alternate preprocessor char! */ if (argv[i][2] == '\0') { fprintf(stderr, "-p requires a character argument\n"); exit(1); } if (argv[i][2] == '#') fprintf(stderr, "using -p# is evidence of stupidity\n"); altppchar = argv[i][2]; if (argv[i][3] != '\0') fprintf(stderr, "warning: extra characters to -p ignored\n"); break; case 'M': masm = 1; /* MASM compatibility mode */ break; case 'O': /* output charset */ { char *name = NULL; if (argv[i][2] == 0) { name = argv[++i]; } else { name = argv[i]+2; } if (set_charset(name) < 0) { fprintf(stderr, "Output charset name '%s' unknown - ignoring! (check case?)\n", name); } } break; case 'A': /* make text segment start so that text relocation is not necessary when _file_ starts at adr */ romable = 2; if(argv[i][2]==0) romaddr = atoi(argv[++i]); else romaddr = atoi(argv[i]+2); break; case 'G': noglob = 1; break; case 'L': /* define global label */ if(argv[i][2]) lg_set(argv[i]+2); break; case 'r': crossref = 1; break; case 'R': relmode = 1; break; case 'D': s = (signed char*)strstr(argv[i]+2,"="); if(s) *s = ' '; pp_define(argv[i]+2); break; case 'c': no_link = 1; fmode |= FM_OBJ; break; case 'v': verbose = 1; break; case 'C': cmosfl = 0; break; case 'W': w65816 = 0; break; case 'w': w65816 = 1; break; case 'B': showblk = 1; break; case 'x': /* old filename behaviour */ oldfile = 1; fprintf(stderr, "Warning: -x is now deprecated and may disappear in future versions!\n"); break; case 'I': if(argv[i][2]==0) { reg_include(argv[++i]); } else { reg_include(argv[i]+2); } break; case 'o': if(argv[i][2]==0) { ofile=argv[++i]; } else { ofile=argv[i]+2; } break; case 'l': if(argv[i][2]==0) { lfile=argv[++i]; } else { lfile=argv[i]+2; } break; case 'e': if(argv[i][2]==0) { efile=argv[++i]; } else { efile=argv[i]+2; } break; case 'b': /* set segment base addresses */ switch(argv[i][2]) { case 't': if(argv[i][3]==0) tbase = atoi(argv[++i]); else tbase = atoi(argv[i]+3); break; case 'd': if(argv[i][3]==0) dbase = atoi(argv[++i]); else dbase = atoi(argv[i]+3); break; case 'b': if(argv[i][3]==0) bbase = atoi(argv[++i]); else bbase = atoi(argv[i]+3); break; case 'z': if(argv[i][3]==0) zbase = atoi(argv[++i]); else zbase = atoi(argv[i]+3); break; default: fprintf(stderr,"unknown segment type '%c' - ignoring!\n", argv[i][2]); break; } break; case 0: fprintf(stderr, "Single dash '-' on command line - ignoring!\n"); break; default: fprintf(stderr, "Unknown option '%c' - ignoring!\n",argv[i][1]); break; } } else { /* no option -> filename */ ifiles[nifiles++] = argv[i]; if(nifiles>=mifiles) { mifiles += 5; ifiles=realloc(ifiles, mifiles*sizeof(char*)); if(!ifiles) { fprintf(stderr, "Oops: couldn't alloc enough mem for filelist table..!\n"); exit(1); } } } i++; } if(!nifiles) { fprintf(stderr, "No input files given!\n"); exit(0); } if(oldfile) { strcpy(old_e, ifiles[0]); strcpy(old_o, ifiles[0]); strcpy(old_l, ifiles[0]); if(setfext(old_e,".err")==0) efile = old_e; if(setfext(old_o,".obj")==0) ofile = old_o; if(setfext(old_l,".lab")==0) lfile = old_l; } fplab= lfile ? xfopen(lfile,"w") : NULL; fperr= efile ? xfopen(efile,"w") : NULL; if(!strcmp(ofile,"-")) { ofile=NULL; fpout = stdout; } else { fpout= xfopen(ofile,"wb"); } if(!fpout) { fprintf(stderr, "Couldn't open output file!\n"); exit(1); } if(verbose) fprintf(stderr, "%s\n",copyright); if(1 /*!m_init()*/) { if(1 /*!b_init()*/) { if(1 /*!l_init()*/) { /*if(!pp_init())*/ { if(!x_init()) { if(fperr) fprintf(fperr,"%s\n",copyright); if(verbose) logout(ctime(&tim1)); /* Pass 1 */ pc[SEG_ABS]= 0; /* abs addressing */ seg_start(fmode, tbase, dbase, bbase, zbase, 0, relmode); if(relmode) { r_mode(RMODE_RELOC); segment = SEG_TEXT; } else { r_mode(RMODE_ABS); } nolink = no_link; for (i=0; i<nifiles; i++) { ifile = ifiles[i]; sprintf(out,"xAss65: Pass 1: %s\n",ifile); if(verbose) logout(out); er=pp_open(ifile); puttmp(0); puttmp(T_FILE); puttmp(0); puttmp(0); puttmps((signed char*)&ifile, sizeof(filep->fname)); if(!er) { er=pass1(); pp_close(); } else { sprintf(out, "Couldn't open source file '%s'!\n", ifile); logout(out); } } if((er=b_depth())) { sprintf(out,"Still %d blocks open at end of file!\n",er); logout(out); } if(tbase & (align-1)) { sprintf(out,"Warning: text segment ($%04x) start address doesn't align to %d!\n", tbase, align); logout(out); } if(dbase & (align-1)) { sprintf(out,"Warning: data segment ($%04x) start address doesn't align to %d!\n", dbase, align); logout(out); } if(bbase & (align-1)) { sprintf(out,"Warning: bss segment ($%04x) start address doesn't align to %d!\n", bbase, align); logout(out); } if(zbase & (align-1)) { sprintf(out,"Warning: zero segment ($%04x) start address doesn't align to %d!\n", zbase, align); logout(out); } if (n65816>0) fmode |= 0x8000; switch(align) { case 1: break; case 2: fmode |= 1; break; case 4: fmode |= 2; break; case 256: fmode |=3; break; } if((!er) && relmode) h_write(fpout, fmode, tlen, dlen, blen, zlen, 0); if(!er) { if(verbose) logout("xAss65: Pass 2:\n"); seg_pass2(); if(!relmode) { r_mode(RMODE_ABS); } else { r_mode(RMODE_RELOC); segment = SEG_TEXT; } er=pass2(); } if(fplab) printllist(fplab); tim2=time(NULL); if(verbose) printstat(); if((!er) && relmode) seg_end(fpout); /* write reloc/label info */ if(fperr) fclose(fperr); if(fplab) fclose(fplab); if(fpout) fclose(fpout); } else { logout("fatal: x: no memory!\n"); } pp_end(); /* } else { logout("fatal: pp: no memory!");*/ } } else { logout("fatal: l: no memory!\n"); } } else { logout("fatal: b: no memory!\n"); } /*m_exit();*/ } else { logout("Not enough memory available!\n"); } if(ner || er) { fprintf(stderr, "Break after %d error%c\n",ner,ner?'s':0); /*unlink();*/ if(ofile) { unlink(ofile); } } free(ifiles); return( (er || ner) ? 1 : 0 ); }
int searchdir(const char *name, int flags) { static char root_name[] = "/"; struct file *file; char *path, *inode_name, *next_inode_name; struct inode *tmp, *inode = NULL; int symlink_count = MAX_SYMLINK_CNT; dprintf("searchdir: %s root: %p cwd: %p\n", name, this_fs->root, this_fs->cwd); if (!(file = alloc_file())) goto err_no_close; file->fs = this_fs; /* if we have ->searchdir method, call it */ if (file->fs->fs_ops->searchdir) { file->fs->fs_ops->searchdir(name, flags, file); if (file->inode) return file_to_handle(file); else goto err; } /* else, try the generic-path-lookup method */ /* Copy the path */ path = strdup(name); if (!path) { dprintf("searchdir: Couldn't copy path\n"); goto err_path; } /* Work with the current directory, by default */ inode = get_inode(this_fs->cwd); if (!inode) { dprintf("searchdir: Couldn't use current directory\n"); goto err_curdir; } for (inode_name = path; inode_name; inode_name = next_inode_name) { /* Root directory? */ if (inode_name[0] == '/') { next_inode_name = inode_name + 1; inode_name = root_name; } else { /* Find the next inode name */ next_inode_name = strchr(inode_name + 1, '/'); if (next_inode_name) { /* Terminate the current inode name and point to next */ *next_inode_name++ = '\0'; } } if (next_inode_name) { /* Advance beyond redundant slashes */ while (*next_inode_name == '/') next_inode_name++; /* Check if we're at the end */ if (*next_inode_name == '\0') next_inode_name = NULL; } dprintf("searchdir: inode_name: %s\n", inode_name); if (next_inode_name) dprintf("searchdir: Remaining: %s\n", next_inode_name); /* Root directory? */ if (inode_name[0] == '/') { /* Release any chain that's already been established */ put_inode(inode); inode = get_inode(this_fs->root); continue; } /* Current directory? */ if (!strncmp(inode_name, ".", sizeof ".")) continue; /* Parent directory? */ if (!strncmp(inode_name, "..", sizeof "..")) { /* If there is no parent, just ignore it */ if (!inode->parent) continue; /* Add a reference to the parent so we can release the child */ tmp = get_inode(inode->parent); /* Releasing the child will drop the parent back down to 1 */ put_inode(inode); inode = tmp; continue; } /* Anything else */ tmp = inode; inode = this_fs->fs_ops->iget(inode_name, inode); if (!inode) { /* Failure. Release the chain */ put_inode(tmp); break; } /* Sanity-check */ if (inode->parent && inode->parent != tmp) { dprintf("searchdir: iget returned a different parent\n"); put_inode(inode); inode = NULL; put_inode(tmp); break; } inode->parent = tmp; inode->name = strdup(inode_name); dprintf("searchdir: path component: %s\n", inode->name); /* Symlink handling */ if (inode->mode == DT_LNK) { char *new_path; int new_len, copied; /* target path + NUL */ new_len = inode->size + 1; if (next_inode_name) { /* target path + slash + remaining + NUL */ new_len += strlen(next_inode_name) + 1; } if (!this_fs->fs_ops->readlink || /* limit checks */ --symlink_count == 0 || new_len > MAX_SYMLINK_BUF) goto err_new_len; new_path = malloc(new_len); if (!new_path) goto err_new_path; copied = this_fs->fs_ops->readlink(inode, new_path); if (copied <= 0) goto err_copied; new_path[copied] = '\0'; dprintf("searchdir: Symlink: %s\n", new_path); if (next_inode_name) { new_path[copied] = '/'; strcpy(new_path + copied + 1, next_inode_name); dprintf("searchdir: New path: %s\n", new_path); } free(path); path = next_inode_name = new_path; /* Add a reference to the parent so we can release the child */ tmp = get_inode(inode->parent); /* Releasing the child will drop the parent back down to 1 */ put_inode(inode); inode = tmp; continue; err_copied: free(new_path); err_new_path: err_new_len: put_inode(inode); inode = NULL; break; } /* If there's more to process, this should be a directory */ if (next_inode_name && inode->mode != DT_DIR) { dprintf("searchdir: Expected a directory\n"); put_inode(inode); inode = NULL; break; } } err_curdir: free(path); err_path: if (!inode) { dprintf("searchdir: Not found\n"); goto err; } file->inode = inode; file->offset = 0; return file_to_handle(file); err: dprintf("serachdir: error seraching file %s\n", name); _close_file(file); err_no_close: return -1; }