/* // ColdMUD was created and is copyright 1993, 1994 by Greg Hudson // // ColdX is a derivitive work, and is copyright 1995 by the ColdX Project. // Full copyright information can be found in the file doc/CREDITS // // File: ioop.c // Version: 0.1-5 // Last Edited: 5 Aug 1995 // // --- // // Function operators for connection and file i/o */ /* posix sucks */ /* #define _POSIX_SOURCE */ #include "config.h" #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <string.h> #include "defs.h" #include "x.tab.h" #include "operator.h" #include "execute.h" #include "data.h" #include "memory.h" #include "io.h" #include "cmstring.h" #include "ident.h" #include "util.h" /* // Initialize a file path, make sure you can open it, etc // // return values: // // 0 if it failed and threw an error // 1 if everything is O.K. // // Added: 30 Jul 95 - BJG */ int init_file_path(Data * name, struct stat * statbuf, char * fname, int max) { int len; len = string_length(name->u.str); if (strstr(string_chars(name->u.str), "../") || len == 0) { cthrow(perm_id, "Filename %D is not legal.", name); return 0; } /* create a variable it will pull the base name from */ strncpy(fname, "root/", max); strncat(fname, string_chars(name->u.str), max); /* Stat the file */ if (stat(fname, statbuf) < 0) { cthrow(file_id, "Cannot find file %D.", name); return 0; } if (S_ISDIR(statbuf->st_mode)) { cthrow(directory_id, "File %D is a directory.", name); return 0; } return 1; } /* // Echo a buffer to the connection */ void op_echo(void) { Data *args; /* Accept a string to echo. */ if (!func_init_1(&args, BUFFER)) return; /* Write the string to any connection associated with this object. */ tell(cur_frame->object->dbref, args[0].u.buffer); pop(1); push_int(1); } /* // Get basic statistics on a file // // Added: 30 Jul 95 - BJG */ void op_stat_file(void) { struct stat sbuf; register int x; List * s; Data * args, * d; char fname[BIGBUF]; if (!func_init_1(&args, STRING)) return; if (!init_file_path(&args[0], &sbuf, fname, BIGBUF)) { return; } s = list_new(5); d = list_empty_spaces(s, 5); for (x=0; x < 5; x++) d[x].type = INTEGER; d[0].u.val = (int) sbuf.st_mode; d[1].u.val = (int) sbuf.st_size; d[2].u.val = (int) sbuf.st_atime; d[3].u.val = (int) sbuf.st_mtime; d[4].u.val = (int) sbuf.st_ctime; push_list(s); list_discard(s); } /* // Read a file into the db // // Added: 30 Jul 95 - BJG */ void op_read_file(void) { size_t size, i, r; Data *args; FILE *fp; char fname[BIGBUF]; Buffer *buf; struct stat statbuf; int len; /* Accept the name of a file to read */ if (!func_init_1(&args, STRING)) return; if (!init_file_path(&args[0], &statbuf, fname, BIGBUF)) { return; } size = statbuf.st_size; /* Open the file for reading. */ fp = open_scratch_file(fname, "r"); pop(1); if (!fp) { cthrow(file_id, "Cannot open file %D for reading.", &args[0]); return; } /* Allocate a buffer to hold the file contents. */ buf = buffer_new(size); /* Read in the file. */ i = 0; while (i < size) { r = fread(buf->s + i, sizeof(unsigned char), size, fp); if (r <= 0) { buffer_discard(buf); close_scratch_file(fp); cthrow(file_id, "Trouble reading file %D.", &args[0]); return; } i += r; } /* return the buffer (wahoo, big memory chunks) */ push_buffer(buf); /* Discard the buffer and close the file. */ buffer_discard(buf); close_scratch_file(fp); } /* // echo a file to the connection */ void op_echo_file(void) { size_t size, i, r; Data *args; FILE *fp; char fname[BIGBUF]; Buffer *buf; struct stat statbuf; int len; /* Accept the name of a file to echo. */ if (!func_init_1(&args, STRING)) return; /* Initialize the file */ if (!init_file_path(&args[0], &statbuf, fname, BIGBUF)) { return; } pop(1); size = statbuf.st_size; /* Open the file for reading. */ fp = open_scratch_file(fname, "r"); if (!fp) { cthrow(file_id, "Cannot open file %D for reading.", &args[0]); return; } /* Allocate a buffer to hold the file contents. */ buf = buffer_new(size); /* Read in the file. */ i = 0; while (i < size) { r = fread(buf->s + i, sizeof(unsigned char), size, fp); if (r <= 0) { buffer_discard(buf); close_scratch_file(fp); cthrow(file_id, "Trouble reading file %D.", &args[0]); return; } i += r; } /* Write the file. */ tell(cur_frame->object->dbref, buf); /* Discard the buffer and close the file. */ buffer_discard(buf); close_scratch_file(fp); push_int(1); } void op_close_connection(void) { /* Accept no arguments. */ if (!func_init_0()) return; /* Kick off anyone assigned to the current object. */ push_int(boot(cur_frame->object->dbref)); }