/* * The builtin Directory object. * Copyright (c) 1998-1999 New Generation Software (NGS) Oy * * Author: Markku Rossi <mtr@ngs.fi> */ /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * MA 02111-1307, USA */ /* * $Source: /tmp/cvsroot-15-2-2007/clamav-devel/libclamav/js/b_dir.c,v $ * $Id: b_dir.c,v 1.2 2006/10/28 11:27:44 njh Exp $ */ #if HAVE_CONFIG_H #include "clamav-config.h" #endif #ifdef CL_EXPERIMENTAL #include "jsint.h" /* * Types and definitions. */ /* Class context. */ struct dir_ctx_st { /* Methods. */ JSSymbol s_close; JSSymbol s_open; JSSymbol s_read; JSSymbol s_rewind; JSSymbol s_seek; JSSymbol s_tell; }; typedef struct dir_ctx_st DirCtx; /* Instance context. */ struct dir_instance_ctx_st { DIR *dir; char *path; /* The virtual machine handle is needed for the delete_proc. */ JSVirtualMachine *vm; }; typedef struct dir_instance_ctx_st DirInstanceCtx; /* * Static functions. */ /* Method proc. */ static int method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, void *instance_context, JSSymbol method, JSNode *result_return, JSNode *args) { DirCtx *ctx = builtin_info->obj_context; DirInstanceCtx *ictx = instance_context; /* Static methods. */ if (method == vm->syms.s_toString) { if (args->u.vinteger != 0) goto argument_error; if (ictx) js_vm_make_string (vm, result_return, ictx->path, strlen (ictx->path)); else js_vm_make_static_string (vm, result_return, "Directory", 9); } /* ********************************************************************** */ else if (ictx) { /* * Instance methods. */ if (method == ctx->s_close) { if (args->u.vinteger != 0) goto argument_error; if (ictx->dir) if (closedir (ictx->dir) >= 0) { ictx->dir = NULL; JS_VM_FREE_FD (vm); } result_return->type = JS_BOOLEAN; result_return->u.vboolean = ictx->dir == NULL; } /* ***************************************************************** */ else if (method == ctx->s_open) { if (args->u.vinteger != 0) goto argument_error; if (ictx->dir == NULL) { JS_VM_ALLOCATE_FD (vm, "Directory.open()"); ictx->dir = opendir (ictx->path); if (ictx->dir == NULL) /* Directory opening failed. */ JS_VM_FREE_FD (vm); } result_return->type = JS_BOOLEAN; result_return->u.vboolean = ictx->dir != NULL; } /* ***************************************************************** */ else if (method == ctx->s_read) { struct dirent *de; if (args->u.vinteger != 0) goto argument_error; if (ictx->dir == NULL) goto not_open; de = readdir (ictx->dir); if (de) js_vm_make_string (vm, result_return, de->d_name, strlen (de->d_name)); else { result_return->type = JS_BOOLEAN; result_return->u.vboolean = 0; } } /* ***************************************************************** */ else if (method == ctx->s_rewind) { if (args->u.vinteger != 0) goto argument_error; if (ictx->dir == NULL) goto not_open; rewinddir (ictx->dir); result_return->type = JS_UNDEFINED; } /* ***************************************************************** */ else if (method == ctx->s_seek) { if (args->u.vinteger != 1) goto argument_error; if (args[1].type != JS_INTEGER) goto argument_type_error; if (ictx->dir == NULL) goto not_open; seekdir (ictx->dir, args[1].u.vinteger); result_return->type = JS_UNDEFINED; } /* ***************************************************************** */ else if (method == ctx->s_tell) { if (args->u.vinteger != 0) goto argument_error; if (ictx->dir == NULL) goto not_open; result_return->u.vinteger = telldir (ictx->dir); if (result_return->u.vinteger < 0) { result_return->type = JS_BOOLEAN; result_return->u.vboolean = 0; } else result_return->type = JS_INTEGER; } /* ***************************************************************** */ else return JS_PROPERTY_UNKNOWN; } /* ********************************************************************** */ else return JS_PROPERTY_UNKNOWN; return JS_PROPERTY_FOUND; /* * Error handling. */ argument_error: sprintf (vm->error, "Directory.%s(): illegal amount of arguments", js_vm_symname (vm, method)); js_vm_error (vm); argument_type_error: sprintf (vm->error, "Directory.%s(): illegal argument", js_vm_symname (vm, method)); js_vm_error (vm); not_open: sprintf (vm->error, "Directory.%s(): directory is no opened", js_vm_symname (vm, method)); js_vm_error (vm); insecure_feature: sprintf (vm->error, "Directory.%s(): not allowed in secure mode", js_vm_symname (vm, method)); js_vm_error (vm); /* NOTREACHED */ return 0; } /* Property proc. */ static int property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, void *instance_context, JSSymbol property, int set, JSNode *node) { /* We have no properties. */ if (!set) node->type = JS_UNDEFINED; return JS_PROPERTY_UNKNOWN; } /* New proc. */ static void new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args, JSNode *result_return) { DirInstanceCtx *instance; if (args->u.vinteger != 1) { sprintf (vm->error, "new Directory(): illegal amount of arguments"); js_vm_error (vm); } if (args[1].type != JS_STRING) { sprintf (vm->error, "new Directory(): illegal argument"); js_vm_error (vm); } instance = js_calloc (vm, 1, sizeof (*instance)); instance->path = js_string_to_c_string (vm, &args[1]); instance->vm = vm; js_vm_builtin_create (vm, result_return, builtin_info, instance); } /* Delete proc. */ static void delete_proc (JSBuiltinInfo *builtin_info, void *instance_context) { DirInstanceCtx *ictx = instance_context; if (ictx) { if (ictx->dir) { closedir (ictx->dir); JS_VM_FREE_FD (ictx->vm); } js_free (ictx->path); js_free (ictx); } } /* * Global functions. */ void js_builtin_Directory (JSVirtualMachine *vm) { JSNode *n; JSBuiltinInfo *info; DirCtx *ctx; ctx = js_calloc (vm, 1, sizeof (*ctx)); ctx->s_close = js_vm_intern (vm, "close"); ctx->s_open = js_vm_intern (vm, "open"); ctx->s_read = js_vm_intern (vm, "read"); ctx->s_rewind = js_vm_intern (vm, "rewind"); ctx->s_seek = js_vm_intern (vm, "seek"); ctx->s_tell = js_vm_intern (vm, "tell"); /* Object information. */ info = js_vm_builtin_info_create (vm); info->method_proc = method; info->property_proc = property; info->new_proc = new_proc; info->delete_proc = delete_proc; info->obj_context = ctx; info->obj_context_delete = js_free; /* Define it. */ n = &vm->globals[js_vm_intern (vm, "Directory")]; js_vm_builtin_create (vm, n, info, NULL); } #endif /*CL_EXPERIMENTAL*/