int file_size(char *file) { struct stat st; file = check_valid_path(file, current_object, "file_size", 0); if (!file) return -1; if (file[0] == '/') file++; if (!legal_path(file)) return -1; #ifdef PURIFY (void)memset(&st, '\0', sizeof(st)); #endif if (stat(file, &st) == -1) return -1; if (S_IFDIR & st.st_mode) return -2; return (int)st.st_size; }
void f_async_getdir(){ function_to_call_t *cb = get_cb(); process_efun_callback(1, cb, F_ASYNC_READ); cb->f.fp->hdr.ref++; add_getdir(check_valid_path((sp-1)->u.string, current_object, "get_dir", 0), cb); pop_2_elems(); }
/* * Append string to file. Return 0 for failure, otherwise 1. */ int write_file (const char * file, const char * str, int flags) { FILE *f; #ifdef WIN32 char fmode[3]; #endif file = check_valid_path(file, current_object, "write_file", 1); if (!file) return 0; #ifdef WIN32 fmode[0] = (flags & 1) ? 'w' : 'a'; fmode[1] = 't'; fmode[2] = '\0'; f = fopen(file, fmode); #else f = fopen(file, (flags & 1) ? "w" : "a"); #endif if (f == 0) { error("Wrong permissions for opening file /%s for %s.\n\"%s\"\n", file, (flags & 1) ? "overwrite" : "append", port_strerror(errno)); } fwrite(str, strlen(str), 1, f); fclose(f); return 1; }
void f_async_write(){ function_to_call_t *cb = get_cb(); process_efun_callback(3, cb, F_ASYNC_WRITE); cb->f.fp->hdr.ref++; add_write(check_valid_path((sp-3)->u.string, current_object, "write_file", 1), (sp-2)->u.string, strlen((sp-2)->u.string), (sp-1)->u.number, cb); pop_n_elems(4); }
char *read_bytes (const char * file, int start, int len, int * rlen) { struct stat st; FILE *fptr; char *str; int size; if (len < 0) return 0; file = check_valid_path(file, current_object, "read_bytes", 0); if (!file) return 0; fptr = fopen(file, "rb"); if (fptr == NULL) return 0; if (fstat(fileno(fptr), &st) == -1) fatal("Could not stat an open file.\n"); size = st.st_size; if (start < 0) start = size + start; if (len == 0) len = size; if (len > MAX_BYTE_TRANSFER) { fclose(fptr); error("Transfer exceeded maximum allowed number of bytes.\n"); return 0; } if (start >= size) { fclose(fptr); return 0; } if ((start + len) > size) len = (size - start); if ((size = fseek(fptr, start, 0)) < 0) { fclose(fptr); return 0; } str = new_string(len, "read_bytes: str"); size = fread(str, 1, len, fptr); fclose(fptr); if (size <= 0) { FREE_MSTR(str); return 0; } /* * The string has to end to '\0'!!! */ str[size] = '\0'; *rlen = size; return str; }
int remove_file (const char * path) { path = check_valid_path(path, current_object, "remove_file", 1); if (path == 0) return 0; if (unlink(path) == -1) return 0; return 1; }
int write_bytes(char *file, int start, char *str) { struct stat st; int size, f; file = check_valid_path(file, current_object, "write_bytes", 1); if (!file) return 0; if (strlen(str) > MAX_BYTE_TRANSFER) return 0; f = open(file, O_WRONLY); if (f < 0) return 0; #ifdef PURIFY (void)memset(&st, '\0', sizeof(st)); #endif if (fstat(f, &st) == -1) fatal("Could not stat an open file.\n"); size = (int)st.st_size; if(start < 0) start = size + start; if (start >= size) { (void)close(f); return 0; } if ((start + strlen(str)) > size) { (void)close(f); return 0; } if ((size = (int)lseek(f, (off_t)start, 0)) < 0) { (void)close(f); return 0; } size = write(f, str, strlen(str)); (void)close(f); if (size <= 0) { return 0; } return 1; }
void dumpstat (const char * tfn) { FILE *f; object_t *ob; const char *fn; #ifdef F_SET_HIDE int display_hidden; #endif fn = check_valid_path(tfn, current_object, "dumpallobj", 1); if (!fn) { error("Invalid path '/%s' for writing.\n", tfn); return; } f = fopen(fn, "w"); if (!f) { error("Unable to open '/%s' for writing.\n", fn); return; } #ifdef F_SET_HIDE display_hidden = -1; #endif for (ob = obj_list; ob; ob = ob->next_all) { long tmp; #ifdef F_SET_HIDE if (ob->flags & O_HIDDEN) { if (display_hidden == -1) display_hidden = valid_hide(current_object); if (!display_hidden) continue; } #endif /* FIXME */ if (ob->prog && (ob->prog->ref == 1 || !(ob->flags & O_CLONE))) tmp = ob->prog->total_size; else tmp = 0; fprintf(f, "%-20s %ld ref %2d %s %s (%d)\n", ob->obname, tmp + data_size(ob) + sizeof(object_t), ob->ref, ob->flags & O_HEART_BEAT ? "HB" : " ", #ifndef NO_ENVIRONMENT ob->super ? ob->super->obname : "--", #else "--", #endif /* ob->cpu */ 0); } fclose(f); }
/*-------------------------------------------------------------------------*/ Bool dumpstat_dest(string_t *fname) /* this function dumps statistics about all destructed objects into the file * $MUDLIB/<fname>. It is called by dump_driver_info(). * Return TRUE on success, FALSE if <fname> can't be written. */ { FILE *f; object_t *ob; fname = check_valid_path(fname, current_object, STR_OBJDUMP, MY_TRUE); if (!fname) return MY_FALSE; f = fopen(get_txt(fname), "w"); if (!f) { free_mstring(fname); return MY_FALSE; } FCOUNT_WRITE(get_txt(fname)); for (ob = newly_destructed_objs; ob; ob = ob->next_all) { #ifdef DEBUG if (!(ob->flags & O_DESTRUCTED)) /* TODO: Can't happen */ continue; #endif fprintf(f, "%-20s ref %2"PRIdPINT" NEW\n" , get_txt(ob->name) , ob->ref ); } for (ob = destructed_objs; ob; ob = ob->next_all) { #ifdef DEBUG if (!(ob->flags & O_DESTRUCTED)) /* TODO: Can't happen */ continue; #endif fprintf(f, "%-20s ref %2"PRIdPINT"\n" , get_txt(ob->name) , ob->ref ); } fclose(f); free_mstring(fname); return MY_TRUE; } /* dumpstat_dest() */
int write_bytes (const char * file, int start, const char * str, int theLength) { struct stat st; int size; FILE *fptr; file = check_valid_path(file, current_object, "write_bytes", 1); if (!file) return 0; if (theLength > MAX_BYTE_TRANSFER) return 0; /* Under system V, it isn't possible change existing data in a file * opened for append, so it can't be opened for append. * opening for r+ won't create the file if it doesn't exist. * opening for w or w+ will truncate it if it does exist. So we * have to check if it exists first. */ if (stat(file, &st) == -1) { fptr = fopen(file, "wb"); } else { fptr = fopen(file, "r+b"); } if (fptr == NULL) { return 0; } #ifndef LATTICE if (fstat(fileno(fptr), &st) == -1) fatal("Could not stat an open file.\n"); #endif size = st.st_size; if (start < 0) start = size + start; if (start < 0 || start > size) { fclose(fptr); return 0; } if ((size = fseek(fptr, start, 0)) < 0) { fclose(fptr); return 0; } size = fwrite(str, 1, theLength, fptr); fclose(fptr); if (size <= 0) { return 0; } return 1; }
void dumpstat P1(char *, tfn) { FILE *f; object_t *ob; char *fn; int display_hidden; fn = check_valid_path(tfn, current_object, "dumpallobj", 1); if (!fn) { error("Invalid path '%s' for writing.\n", tfn); return; } f = fopen(fn, "w"); if (!f) { error("Unable to open '/%s' for writing.\n", fn); return; } display_hidden = -1; for (ob = obj_list; ob; ob = ob->next_all) { int tmp; if (ob->flags & O_HIDDEN) { if (display_hidden == -1) display_hidden = valid_hide(current_object); if (!display_hidden) continue; } if (ob->prog && (ob->prog->ref == 1 || !(ob->flags & O_CLONE))) tmp = ob->prog->total_size; else tmp = 0; fprintf(f, "%-20s %i ref %2d %s %s (%d) %s\n", ob->name, tmp + data_size(ob) + sizeof(object_t), ob->ref, ob->flags & O_HEART_BEAT ? "HB" : " ", #ifndef NO_ENVIRONMENT ob->super ? ob->super->name : "--", #else "--", #endif /* ob->cpu */ 0, (ob->swap_num >= 0) ? ((ob->flags & O_SWAPPED) ? "SWAPPED(out)" : "SWAPPED(in)") : ""); } fclose(f); }
int file_time(char *file) { struct stat st; file = check_valid_path(file, current_object, "file_time", 0); if (!file) return 0; #ifdef PURIFY (void)memset(&st, '\0', sizeof(st)); #endif if (stat(file, &st) == -1) return 0; return (int)st.st_mtime; }
int file_size (const char * file) { struct stat st; long ret; #ifdef WIN32 char *t; int needs_free = 0, len; const char *p; #endif file = check_valid_path(file, current_object, "file_size", 0); if (!file) return -1; #ifdef WIN32 len = strlen(file); p = file + len - 1; if (*p == '/') { needs_free = 1; p = file; t = new_string(len - 1, "file_size"); memcpy(t, p, len - 1); t[len-1] = 0; file = t; } #endif if (stat(file, &st) == -1) ret = -1; else if (S_IFDIR & st.st_mode) ret = -2; else ret = st.st_size; #ifdef WIN32 if (needs_free) FREE_MSTR(file); #endif return ret; }
/* * Append string to file. Return 0 for failure, otherwise 1. */ int write_file(char *file, char *str) { FILE *f; file = check_valid_path(file, current_object, "write_file", 1); if (!file) return 0; f = fopen(file, "a"); if (f == 0) error("Wrong permissions for opening file %s for append.\n", file); if (s_flag) num_filewrite++; if (fwrite(str, strlen(str), 1, f) != 1) { (void)fclose(f); return 0; } if (fclose(f) == EOF) return 0; return 1; }
/*-------------------------------------------------------------------------*/ svalue_t * f_sl_open (svalue_t *sp) /* EFUN sl_open * * int sl_open(string filename) * * Opens the file <filename> for use as a SQLite database. * If the file doesn't exists it will be created. * Only one open file per object is allowed. On success this * function returns 1, otherwise usually an error is thrown. */ { string_t *file; sqlite3 *db; sqlite_dbs_t *tmp; int err; file = check_valid_path(sp->u.str, current_object, STR_SQLITE_OPEN , MY_TRUE); if (!file) errorf("Illegal use of sl_open('%s')\n", get_txt(sp->u.str)); tmp = find_db (current_object); if (tmp) { free_mstring(file); errorf("The current object already has a database open.\n"); } err = sqlite3_open (get_txt(file), &db); free_mstring(file); if (err) { const char* msg = sqlite3_errmsg(db); sqlite3_close(db); errorf("sl_open: %s\n", msg ); /* NOTREACHED */ } /* create a new chain link and hang on the old chain */ tmp = new_db(); if(!tmp) { sqlite3_close(db); errorf("(sl_open) Out of memory: (%lu bytes)\n", (unsigned long) sizeof(*tmp)); } tmp->db = db; tmp->obj = current_object; current_object->open_sqlite_db = MY_TRUE; /* Synchronous is damn slow. Forget it. */ sqlite3_exec(db, "PRAGMA synchronous = OFF", NULL, NULL, NULL); sqlite3_set_authorizer(db, my_sqlite3_authorizer, NULL); free_string_svalue (sp); put_number (sp, 1); return sp; } /* f_sl_open() */
int do_rename (const char * fr, const char * t, int flag) { const char *from; const char *to; char newfrom[MAX_FNAME_SIZE + MAX_PATH_LEN + 2]; int flen; extern svalue_t apply_ret_value; /* * important that the same write access checks are done for link() as are * done for rename(). Otherwise all kinds of security problems would * arise (e.g. creating links to files in protected directories and then * modifying the protected file by modifying the linked file). The idea * is prevent linking to a file unless the person doing the linking has * permission to move the file. */ from = check_valid_path(fr, current_object, "rename", 1); if (!from) return 1; assign_svalue(&from_sv, &apply_ret_value); to = check_valid_path(t, current_object, "rename", 1); if (!to) return 1; assign_svalue(&to_sv, &apply_ret_value); if (!strlen(to) && !strcmp(t, "/")) { to = "./"; } /* Strip trailing slashes */ flen = strlen(from); if (flen > 1 && from[flen - 1] == '/') { const char *p = from + flen - 2; int n; while (*p == '/' && (p > from)) p--; n = p - from + 1; memcpy(newfrom, from, n); newfrom[n] = 0; from = newfrom; } if (file_size(to) == -2) { /* Target is a directory; build full target filename. */ const char *cp; char newto[MAX_FNAME_SIZE + MAX_PATH_LEN + 2]; cp = strrchr(from, '/'); if (cp) cp++; else cp = from; sprintf(newto, "%s/%s", to, cp); return do_move(from, newto, flag); } else return do_move(from, to, flag); }
array_t *get_dir (const char * path, int flags) { array_t *v; int i, count = 0; #ifndef WIN32 DIR *dirp; #endif int namelen, do_match = 0; #ifndef WIN32 #ifdef USE_STRUCT_DIRENT struct dirent *de; #else struct direct *de; #endif #endif struct stat st; char *endtemp; char temppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 2]; char regexppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 2]; char *p; #ifdef WIN32 struct _finddata_t FindBuffer; long FileHandle, FileCount; #endif if (!path) return 0; path = check_valid_path(path, current_object, "stat", 0); if (path == 0) return 0; if (strlen(path) < 2) { temppath[0] = path[0] ? path[0] : '.'; temppath[1] = '\000'; p = temppath; } else { strncpy(temppath, path, MAX_FNAME_SIZE + MAX_PATH_LEN + 1); temppath[MAX_FNAME_SIZE + MAX_PATH_LEN + 1] = '\0'; /* * If path ends with '/' or "/." remove it */ if ((p = strrchr(temppath, '/')) == 0) p = temppath; if (p[0] == '/' && ((p[1] == '.' && p[2] == '\0') || p[1] == '\0')) *p = '\0'; } if (stat(temppath, &st) < 0) { if (*p == '\0') return 0; if (p != temppath) { strcpy(regexppath, p + 1); *p = '\0'; } else { strcpy(regexppath, p); strcpy(temppath, "."); } do_match = 1; } else if (*p != '\0' && strcmp(temppath, ".")) { if (*p == '/' && *(p + 1) != '\0') p++; v = allocate_empty_array(1); encode_stat(&v->item[0], flags, p, &st); return v; } #ifdef WIN32 FileHandle = -1; FileCount = 1; /* strcat(temppath, "\\*"); */ strcat(temppath, "/*"); if ((FileHandle = _findfirst(temppath, &FindBuffer)) == -1) return 0; #else if ((dirp = opendir(temppath)) == 0) return 0; #endif /* * Count files */ #ifdef WIN32 do { if (!do_match && (!strcmp(FindBuffer.name, ".") || !strcmp(FindBuffer.name, ".."))) { continue; } if (do_match && !match_string(regexppath, FindBuffer.name)) { continue; } count++; if (count >= max_array_size) { break; } } while (!_findnext(FileHandle, &FindBuffer)); _findclose(FileHandle); #else for (de = readdir(dirp); de; de = readdir(dirp)) { #ifdef USE_STRUCT_DIRENT namelen = strlen(de->d_name); #else namelen = de->d_namlen; #endif if (!do_match && (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)) continue; if (do_match && !match_string(regexppath, de->d_name)) continue; count++; if (count >= max_array_size) break; } #endif /* * Make array and put files on it. */ v = allocate_empty_array(count); if (count == 0) { /* This is the easy case :-) */ #ifndef WIN32 closedir(dirp); #endif return v; } #ifdef WIN32 FileHandle = -1; if ((FileHandle = _findfirst(temppath, &FindBuffer)) == -1) return 0; endtemp = temppath + strlen(temppath) - 2; *endtemp = 0; /* strcat(endtemp++, "\\"); */ strcat(endtemp++, "/"); i = 0; do { if (!do_match && (!strcmp(FindBuffer.name, ".") || !strcmp(FindBuffer.name, ".."))) continue; if (do_match && !match_string(regexppath, FindBuffer.name)) continue; if (flags == -1) { strcpy(endtemp, FindBuffer.name); stat(temppath, &st); } encode_stat(&v->item[i], flags, FindBuffer.name, &st); i++; } while (!_findnext(FileHandle, &FindBuffer)); _findclose(FileHandle); #else /* WIN32 */ rewinddir(dirp); endtemp = temppath + strlen(temppath); strcat(endtemp++, "/"); for (i = 0, de = readdir(dirp); i < count; de = readdir(dirp)) { #ifdef USE_STRUCT_DIRENT namelen = strlen(de->d_name); #else namelen = de->d_namlen; #endif if (!do_match && (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)) continue; if (do_match && !match_string(regexppath, de->d_name)) continue; de->d_name[namelen] = '\0'; if (flags == -1) { /* * We'll have to .... sigh.... stat() the file to get some add'tl * info. */ strcpy(endtemp, de->d_name); stat(temppath, &st);/* We assume it works. */ } encode_stat(&v->item[i], flags, de->d_name, &st); i++; } closedir(dirp); #endif /* OS2 */ /* Sort the names. */ qsort((void *) v->item, count, sizeof v->item[0], (flags == -1) ? parrcmp : pstrcmp); return v; }
/* * Append string to file. Return 0 for failure, otherwise 1. */ int write_file(char *file, char *str) { FILE *f; file = check_valid_path(file, current_object, "write_file", 1); if (!file) return 0; f = fopen(file, "a"); if (f == 0) error("Wrong permissions for opening file %s for append.\n", file); if (s_flag) num_filewrite++; if (fwrite(str, strlen(str), 1, f) != 1) { (void)fclose(f); return 0; } if (fclose(f) == EOF) return 0; return 1; } int read_file_len; /* Side effect from read_file, so we know how many lines we managed to read */ char * read_file(char *file, int start, int len) { struct stat st; FILE *f; char *str, *p, *p2, *end, c; size_t size; read_file_len = len; if (len < 0) return 0; file = check_valid_path(file, current_object, "read_file", 0); if (!file) return 0; f = fopen(file, "r"); if (f == 0) return 0; #ifdef PURIFY (void)memset(&st, '\0', sizeof(st)); #endif if (fstat(fileno(f), &st) == -1) fatal("Could not stat an open file.\n"); size = (int)st.st_size; if (s_flag) num_fileread++; if (size > READ_FILE_MAX_SIZE) { if ( start || len ) size = READ_FILE_MAX_SIZE; else { (void)fclose(f); return 0; } } if (!start) start = 1; if (!len) read_file_len = len = READ_FILE_MAX_SIZE; str = allocate_mstring(size); str[size] = '\0'; do { if (size > (int)st.st_size) size = (int)st.st_size; if (fread(str, size, 1, f) != 1) { (void)fclose(f); free_mstring(str); return 0; } st.st_size -= size; end = str + size; for (p = str; ( p2 = memchr(p, '\n', (size_t)(end - p)) ) && --start; ) p = p2 + 1; } while ( start > 1 ); for (p2 = str; p != end; ) { c = *p++; if (!isprint(c) && !isspace(c)) c = ' '; *p2++ = c; if ( c == '\n' ) if (!--len) break; } if (len && st.st_size) { size -= (p2 - str) ; if (size > (int)st.st_size) size = (int)st.st_size; if (fread(p2, size, 1, f) != 1) { (void)fclose(f); free_mstring(str); return 0; } st.st_size -= size; end = p2 + size; for (; p2 != end; ) { c = *p2; if (!isprint(c) && !isspace(c)) *p2 = ' '; p2++; if (c == '\n') if (!--len) break; } if ( st.st_size && len ) { /* tried to read more than READ_MAX_FILE_SIZE */ (void)fclose(f); free_mstring(str); return 0; } } read_file_len -= len; *p2 = '\0'; (void)fclose(f); return str; }
void f_compress_file (void) { int readb; int len; int num_arg = st_num_arg; const char* input_file; const char* output_file; const char* real_input_file; const char* real_output_file; char* tmpout; gzFile out_file; FILE* in_file; char buf[4096]; char outname[1024]; // Not a string? Error! if ((sp - num_arg + 1)->type != T_STRING) { pop_n_elems(num_arg); push_number(0); return ; } input_file = (sp - num_arg + 1)->u.string; if (num_arg == 2) { if (((sp - num_arg + 2)->type != T_STRING)) { pop_n_elems(num_arg); push_number(0); return ; } output_file = (sp - num_arg + 2)->u.string; } else { len = strlen(input_file); if (!strcmp(input_file + len - strlen(GZ_EXTENSION), GZ_EXTENSION)) { // Already compressed... pop_n_elems(num_arg); push_number(0); return ; } tmpout = new_string(strlen(input_file) + strlen(GZ_EXTENSION), "compress_file"); strcpy(tmpout, input_file); strcat(tmpout, GZ_EXTENSION); output_file = tmpout; } real_output_file = check_valid_path(output_file, current_object, "compress_file", 1); if (!real_output_file) { pop_n_elems(num_arg); push_number(0); return ; } // Copy it into our little buffer. strcpy(outname, real_output_file); // Free the old file. if (num_arg != 2) { FREE_MSTR(output_file); } output_file = outname; real_input_file = check_valid_path(input_file, current_object, "compress_file", 0); if (!real_input_file) { pop_n_elems(num_arg); push_number(0); return ; } in_file = fopen(real_input_file, "rb"); if (!in_file) { pop_n_elems(num_arg); push_number(0); return ; } out_file = gzopen(output_file, "wb"); if (!out_file) { fclose(in_file); pop_n_elems(num_arg); push_number(0); return ; } do { readb = fread(buf, 1, 4096, in_file); gzwrite(out_file, buf, readb); } while (readb == 4096); fclose(in_file); gzclose(out_file); unlink(real_input_file); pop_n_elems(num_arg); push_number(1); }
char * read_bytes(char *file, int start, size_t len) { struct stat st; char *str; int size; int f; if(len > MAX_BYTE_TRANSFER) return 0; file = check_valid_path(file, current_object, "read_bytes", 0); if (!file) return 0; f = open(file, O_RDONLY); if (f < 0) return 0; #ifdef PURIFY (void)memset(&st, '\0', sizeof(st)); #endif if (fstat(f, &st) == -1) fatal("Could not stat an open file.\n"); size = (int)st.st_size; if(start < 0) start = size + start; if (start >= size) { (void)close(f); return 0; } if ((start+len) > size) len = (size - start); if ((size = (int)lseek(f, (off_t)start, 0)) < 0) { (void)close(f); return 0; } str = allocate_mstring(len); size = read(f, str, len); (void)close(f); if (size <= 0) { free_mstring(str); return 0; } /* We want to allow all characters to pass untouched! for (il = 0; il < size; il++) if (!isprint(str[il]) && !isspace(str[il])) str[il] = ' '; */ /* * The string has to end to '\0'!!! */ str[size] = '\0'; return str; }
int copy_file (const char * from, const char * to) { char buf[128]; int from_fd, to_fd; int num_read, num_written; char *write_ptr; extern svalue_t apply_ret_value; from = check_valid_path(from, current_object, "move_file", 0); assign_svalue(&from_sv, &apply_ret_value); to = check_valid_path(to, current_object, "move_file", 1); assign_svalue(&to_sv, &apply_ret_value); if (from == 0) return -1; if (to == 0) return -2; if (lstat(from, &from_stats) != 0) { error("/%s: lstat failed\n", from); return 1; } if (lstat(to, &to_stats) == 0) { #ifdef WIN32 if (!strcmp(from, to)) #else if (from_stats.st_dev == to_stats.st_dev && from_stats.st_ino == to_stats.st_ino) #endif { error("`/%s' and `/%s' are the same file", from, to); return 1; } } else if (errno != ENOENT) { error("/%s: unknown error\n", to); return 1; } from_fd = open(from, OPEN_READ); if (from_fd < 0) return -1; if (file_size(to) == -2) { /* Target is a directory; build full target filename. */ const char *cp; char newto[MAX_FNAME_SIZE + MAX_PATH_LEN + 2]; cp = strrchr(from, '/'); if (cp) cp++; else cp = from; sprintf(newto, "%s/%s", to, cp); close(from_fd); return copy_file(from, newto); } to_fd = open(to, OPEN_WRITE | O_CREAT | O_TRUNC, 0666); if (to_fd < 0) { close(from_fd); return -2; } while ((num_read = read(from_fd, buf, 128)) != 0) { if (num_read < 0) { debug_perror("copy_file: read", from); close(from_fd); close(to_fd); return -3; } write_ptr = buf; while (write_ptr != (buf + num_read)) { num_written = write(to_fd, write_ptr, num_read); if (num_written < 0) { debug_perror("copy_file: write", to); close(from_fd); close(to_fd); return -3; } write_ptr += num_written; } } close(from_fd); close(to_fd); return 1; }
/*-------------------------------------------------------------------------*/ Bool dumpstat (string_t *fname) /* This function dumps statistics about all listed objects into the file * $MUDLIB/<fname>. It is called from dump_driver_info. * Return TRUE on success, FALSE if <fname> can't be written. */ { FILE *f; object_t *ob; static char *swapstrings[] = {"", "PROG SWAPPED", "VAR SWAPPED", "SWAPPED", }; fname = check_valid_path(fname, current_object, STR_OBJDUMP, MY_TRUE); if (!fname) return MY_FALSE; f = fopen(get_txt(fname), "w"); if (!f) { free_mstring(fname); return MY_FALSE; } FCOUNT_WRITE(get_txt(fname)); for (ob = obj_list; ob; ob = ob->next_all) { mp_int compsize, totalsize, overhead; char timest[21]; struct tm *tm; #ifdef DEBUG if (ob->flags & O_DESTRUCTED) /* TODO: Can't happen */ continue; #endif compsize = data_size(ob, &totalsize); if (!O_PROG_SWAPPED(ob) && (ob->prog->ref == 1 || !(ob->flags & (O_CLONE|O_REPLACED)))) { overhead = ob->prog->total_size; } else { overhead = 0; } overhead += sizeof (object_t); fprintf(f, "%-20s %5"PRIdMPINT" (%5"PRIdMPINT") ref %2"PRIdPINT" %s " , get_txt(ob->name) , compsize + overhead, totalsize + overhead , ob->ref , ob->flags & O_HEART_BEAT ? "HB" : " " ); if (ob->super) fprintf(f, "%s ", get_txt(ob->super->name)); else fprintf(f, "-- "); if (ob->gigaticks) fprintf(f, " (%"PRIuMPINT"%09"PRIuMPINT")", (mp_uint)ob->gigaticks, (mp_uint)ob->ticks); else fprintf(f, " (%"PRIuMPINT")", (mp_uint)ob->ticks); fprintf(f, " %s", swapstrings[(O_PROG_SWAPPED(ob)?1:0) | (O_VAR_SWAPPED(ob)?2:0)] ); tm = localtime((time_t *)&ob->load_time); strftime(timest, sizeof(timest), "%Y.%m.%d-%H:%M:%S", tm); fprintf(f, " %s\n", timest); } fclose(f); free_mstring(fname); return MY_TRUE; } /* dumpstat() */
int restore_object(struct object *ob, char *file) { char *name, var[100], *buff, *space; size_t len; FILE *f; struct object *save = current_object; struct stat st; int p; if (current_object != ob) fatal("Bad argument to restore_object()\n"); if (ob->flags & O_DESTRUCTED) return 0; file = check_valid_path(file, ob, "restore_object", 0); if (file == 0) error("Illegal use of restore_object()\n"); len = strlen(file); name = alloca(len + 3); (void)strcpy(name, file); if (name[len-2] == '.' && name[len-1] == 'c') name[len-1] = 'o'; else (void)strcat(name, ".o"); f = fopen(name, "r"); if (s_flag) num_fileread++; if (!f || fstat(fileno(f), &st) == -1) { if (f) (void)fclose(f); return 0; } if (st.st_size == 0) { (void)fclose(f); return 0; } buff = xalloc((size_t)st.st_size + 1); current_object = ob; for (;;) { struct svalue *v; if (fgets(buff, (int)st.st_size + 1, f) == 0) break; /* Remember that we have a newline at end of buff ! */ space = strchr(buff, ' '); if (space == 0 || space - buff >= sizeof (var)) { (void)fclose(f); free(buff); error("Illegal format when restoring %s.\n", file); } (void)strncpy(var, buff, (size_t)(space - buff)); var[space - buff] = '\0'; p = find_status(ob->prog, var, TYPE_MOD_STATIC); if (p == -1) continue; v = &ob->variables[p]; space++; if (!restore_one(v, &space)) { (void)fclose(f); free(buff); error("Illegal format when restoring %s from %s.\n", var, file); } } current_object = save; if (d_flag & DEBUG_RESTORE) debug_message("Object %s restored from %s.\n", ob->name, file); free(buff); (void)fclose(f); return 1; }
char *read_file (const char * file, int start, int len) { struct stat st; FILE *f; int lastchunk, chunk, ssize, fsize; char *str, *p, *p2; if (len < 0) return 0; file = check_valid_path(file, current_object, "read_file", 0); if (!file) return 0; /* * file doesn't exist, or is really a directory */ if (stat(file, &st) == -1 || (st.st_mode & S_IFDIR)) return 0; f = fopen(file, FOPEN_READ); if (f == 0) return 0; #ifndef LATTICE if (fstat(fileno(f), &st) == -1) fatal("Could not stat an open file.\n"); #endif /* lastchunk = the size of the last chunk we read * chunk = size of the next chunk we will read (always < fsize) * fsize = amount left in file */ lastchunk = chunk = ssize = fsize = st.st_size; if (fsize > READ_FILE_MAX_SIZE) lastchunk = chunk = ssize = READ_FILE_MAX_SIZE; /* Can't shortcut out if size > max even if start and len aren't specified, since we still need to check for \0, and \r's may pull the size into range */ if (start < 1) start = 1; if (len == 0) len = READ_FILE_MAX_SIZE; str = new_string(ssize, "read_file: str"); if (fsize == 0) { /* zero length file */ str[0] = 0; fclose(f); return str; } do { /* read another chunk */ if (fsize == 0 || fread(str, chunk, 1, f) != 1) goto free_str; p = str; lastchunk = chunk; fsize -= chunk; if (chunk > fsize) chunk = fsize; while (start > 1) { /* skip newlines */ p2 = memchr(p, '\n', str + lastchunk - p); if (p2) { p = p2 + 1; start--; } else break; /* get another chunk */ } } while (start > 1); /* until we've skipped enough */ p2 = str; while (1) { char c; if (p == str + lastchunk) { /* need another chunk */ if (chunk > ssize - (p2 - str)) chunk = ssize - (p2 - str); /* space remaining */ if (fsize == 0) break; /* nothing left */ if (chunk == 0 || fread(p2, chunk, 1, f) != 1) goto free_str; p = p2; lastchunk = chunk + (p2 - str); /* fudge since we didn't start at str */ fsize -= chunk; if (chunk > fsize) chunk = fsize; } c = *p++; if (c == '\0') { FREE_MSTR(str); fclose(f); error("Attempted to read '\\0' into string!\n"); } if (c != '\r' || *p != '\n') { *p2++ = c; if (c == '\n' && --len == 0) break; /* done */ } } *p2 = 0; str = extend_string(str, p2 - str); /* fix string length */ fclose(f); return str; /* Error path: unwind allocated resources */ free_str: FREE_MSTR(str); fclose(f); return 0; }
/* Current flags: * 1 - do disassembly * 2 - dump line number table */ void dump_prog (program_t * prog, const char * fn, int flags) { const char *fname; FILE *f; int i, j; int num_funcs_total; fname = check_valid_path(fn, current_object, "dumpallobj", 1); if (!fname) { error("Invalid path '%s' for writing.\n", fn); return; } f = fopen(fname, "w"); if (!f) { error("Unable to open '/%s' for writing.\n", fname); return; } fprintf(f, "NAME: /%s\n", prog->filename); fprintf(f, "INHERITS:\n"); fprintf(f, "\tname fio vio\n"); fprintf(f, "\t---------------- --- ---\n"); for (i = 0; i < prog->num_inherited; i++) fprintf(f, "\t%-20s %5d %5d\n", prog->inherit[i].prog->filename, prog->inherit[i].function_index_offset, prog->inherit[i].variable_index_offset ); fprintf(f, "PROGRAM:"); for (i = 0; i < prog->program_size; i++) { if (i % 16 == 0) fprintf(f, "\n\t%04x: ", (unsigned int) i); fprintf(f, "%02d ", (unsigned char) prog->program[i]); } fputc('\n', f); fprintf(f, "FUNCTIONS:\n"); fprintf(f, " name offset flags fio # locals # args\n"); fprintf(f, " --------------------- ------ ------- --- -------- ------\n"); num_funcs_total = prog->last_inherited + prog->num_functions_defined; for (i = 0; i < num_funcs_total; i++) { char sflags[8]; int flags; int runtime_index; function_t *func_entry = find_func_entry(prog, i); register int low, high, mid; flags = prog->function_flags[i]; if (flags & FUNC_ALIAS) { runtime_index = flags & ~FUNC_ALIAS; sflags[4] = 'a'; } else { runtime_index = i; sflags[4] = '-'; } flags = prog->function_flags[runtime_index]; sflags[0] = (flags & FUNC_INHERITED) ? 'i' : '-'; sflags[1] = (flags & FUNC_UNDEFINED) ? 'u' : '-'; sflags[2] = (flags & FUNC_STRICT_TYPES) ? 's' : '-'; sflags[3] = (flags & FUNC_PROTOTYPE) ? 'p' : '-'; sflags[5] = (flags & FUNC_TRUE_VARARGS) ? 'V' : '-'; sflags[6] = (flags & FUNC_VARARGS) ? 'v' : '-'; sflags[7] = '\0'; if (flags & FUNC_INHERITED) { low = 0; high = prog->num_inherited - 1; while (high > low) { mid = (low + high + 1)/2; if (prog->inherit[mid].function_index_offset > runtime_index) high = mid -1; else low = mid; } fprintf(f, "%4d: %-20s %5d %7s %5d\n", i, func_entry->funcname, low, sflags, runtime_index - prog->inherit[low].function_index_offset); } else { fprintf(f, "%4d: %-20s %5d %7s %7d %5d\n", i, func_entry->funcname, runtime_index - prog->last_inherited ,sflags, func_entry->num_arg, func_entry->num_local); } } fprintf(f, "VARIABLES:\n"); for (i = 0; i < prog->num_variables_defined; i++) fprintf(f, "%4d: %-12s\n", i, prog->variable_table[i]); fprintf(f, "STRINGS:\n"); for (i = 0; i < prog->num_strings; i++) { fprintf(f, "%4d: ", i); for (j = 0; j < 32; j++) { char c; if (!(c = prog->strings[i][j])) break; else if (c == '\n') fprintf(f, "\\n"); else fputc(c, f); } fputc('\n', f); } if (flags & 1) { fprintf(f, "\n;;; *** Disassembly ***\n"); disassemble(f, prog->program, 0, prog->program_size, prog); } if (flags & 2) { fprintf(f, "\n;;; *** Line Number Info ***\n"); dump_line_numbers(f, prog); } fclose(f); }
/* * Save an object to a file. * The routine checks with the function "valid_write()" in /obj/master.c * to assertain that the write is legal. */ void save_object(struct object *ob, char *file) { char *name, *tmp_name; size_t len; int i, j; FILE *f; int failed = 0; struct savebuf sbuf; /* struct svalue *v; */ if (ob->flags & O_DESTRUCTED) return; file = check_valid_path(file, ob, "save_object", 1); if (file == 0) error("Illegal use of save_object()\n"); len = strlen(file); name = alloca(len + 2 + 1); (void)strcpy(name, file); (void)strcat(name, ".o"); /* * Write the save-files to different directories, just in case * they are on different file systems. */ tmp_name = alloca(len + 2 + 4 + 1); (void)sprintf(tmp_name, "%s.tmp", name); f = fopen(tmp_name, "w"); if (s_flag) num_filewrite++; if (f == 0) { error("Could not open %s for a save.\n", tmp_name); } failed = 0; sbuf.size = 0; sbuf.max_size = 80; sbuf.buf = xalloc(80); sbuf.f = f; for (j = 0; j < (int)ob->prog->num_inherited; j++) { struct program *prog = ob->prog->inherit[j].prog; if (ob->prog->inherit[j].type & TYPE_MOD_SECOND || prog->num_variables == 0) continue; for (i = 0; i < (int)prog->num_variables; i++) { struct svalue *v = &ob->variables[i + ob->prog->inherit[j].variable_index_offset]; if (ob->prog->inherit[j].prog->variable_names[i].type & TYPE_MOD_STATIC) continue; if (v->type == T_NUMBER || v->type == T_STRING || v->type == T_POINTER || v->type == T_MAPPING || v->type == T_OBJECT || v->type == T_FLOAT) { /* XXX function */ add_strbuf(&sbuf, ob->prog->inherit[j].prog->variable_names[i].name); add_strbuf(&sbuf, " "); save_one(&sbuf, v); add_strbuf(&sbuf, "\n"); } } } fwrite(sbuf.buf, sbuf.size, 1, f); free(sbuf.buf); if (fclose(f) == EOF) failed = 1; if (failed) { (void)unlink(tmp_name); error("Failed to save to file. Disk could be full.\n"); } if (rename(tmp_name, name) == -1) { (void)unlink(tmp_name); perror(name); (void)printf("Failed to link %s to %s\n", tmp_name, name); error("Failed to save object !\n"); } }
void save_map(struct object *ob, struct mapping *map, char *file) { char *name, *tmp_name; struct apair *i; size_t len; int j; FILE *f; struct savebuf sbuf; int failed = 0; /* struct svalue *v; */ file = check_valid_path(file, ob, "save_map", 1); if (file == 0) error("Illegal use of save_map()\n"); for (j = 0; j < map->size; j++) { for (i = map->pairs[j]; i; i = i->next) { if (i->arg.type != T_STRING) error("Non-string index in mapping\n"); if (strpbrk(i->arg.u.string, " \n\r\t\f\v\b") != NULL) error("Mapping index cannot have whitespace\n"); } } len = strlen(file); name = alloca(len + 2 + 1); (void)strcpy(name, file); (void)strcat(name, ".o"); /* * Write the save-files to different directories, just in case * they are on different file systems. */ tmp_name = alloca(len + 2 + 4 + 1); (void)sprintf(tmp_name, "%s.tmp", name); f = fopen(tmp_name, "w"); if (s_flag) num_filewrite++; if (f == 0) { error("Could not open %s for a save.\n", tmp_name); } failed = 0; sbuf.size = 0; sbuf.max_size = 80; sbuf.buf = xalloc(80); sbuf.f = f; for (j = 0; j < map->size; j++) { for (i = map->pairs[j]; i; i = i->next) { struct svalue *v = &i->val; if (i->arg.type != T_STRING) continue; if (v->type == T_NUMBER || v->type == T_STRING || v->type == T_POINTER || v->type == T_MAPPING || v->type == T_OBJECT || v->type == T_FLOAT) { /* XXX function */ add_strbuf(&sbuf, i->arg.u.string); add_strbuf(&sbuf, " "); save_one(&sbuf, v); add_strbuf(&sbuf, "\n"); } } } fwrite(sbuf.buf, sbuf.size, 1, f); free(sbuf.buf); if (fclose(f) == EOF) failed = 1; if (failed) { (void)unlink(tmp_name); error("Failed to save to file. Disk could be full.\n"); } if (rename(tmp_name, name) == -1) { (void)unlink(tmp_name); perror(name); (void)printf("Failed to link %s to %s\n", tmp_name, name); error("Failed to save mapping !\n"); } }
char *read_file(const char * file, int start, int len) { struct stat st; #ifndef PACKAGE_COMPRESS FILE *f; #else gzFile f; #endif int chunk; char *str, *p, *p2; if (len < 0) return 0; file = check_valid_path(file, current_object, "read_file", 0); if (!file) return 0; /* * file doesn't exist, or is really a directory */ if (stat(file, &st) == -1 || (st.st_mode & S_IFDIR)) return 0; #ifndef PACKAGE_COMPRESS f = fopen(file, FOPEN_READ); #else f = gzopen(file, "rb"); #endif if (f == 0) return 0; if (start < 1) start = 1; if (len == 0) len = 2*READ_FILE_MAX_SIZE; str = new_string(2*READ_FILE_MAX_SIZE, "read_file: str"); if (st.st_size== 0) { /* zero length file */ str[0] = 0; #ifndef PACKAGE_COMPRESS fclose(f); #else gzclose(f); #endif str = extend_string(str, 0); /* fix string length */ return str; } do { #ifndef PACKAGE_COMPRESS chunk = fread(str, 1, 2*READ_FILE_MAX_SIZE, f); #else chunk = gzread(f, str, 2*READ_FILE_MAX_SIZE); #endif if (chunk < 1) goto free_str; p = str; while (start > 1) { /* skip newlines */ p2 = (char *)memchr(p, '\n', 2*READ_FILE_MAX_SIZE+str-p); if (p2) { p = p2 + 1; start--; } else break; } } while (start > 1); p2 = str; while (1) { char c; c = *p++; if (p-str > chunk) { if (chunk == 2*READ_FILE_MAX_SIZE) { goto free_str; //file too big } else break; //reached the end } if (p2-str > READ_FILE_MAX_SIZE) goto free_str; //file too big if (c == '\0') { FREE_MSTR(str); #ifndef PACKAGE_COMPRESS fclose(f); #else gzclose(f); #endif error("Attempted to read '\\0' into string!\n"); } if (c != '\r' || *p != '\n') { *p2++ = c; if (c == '\n' && --len == 0) break; /* done */ } } *p2 = 0; str = extend_string(str, p2 - str); /* fix string length */ #ifndef PACKAGE_COMPRESS fclose(f); #else gzclose(f); #endif return str; /* Error path: unwind allocated resources */ free_str: FREE_MSTR(str); #ifndef PACKAGE_COMPRESS fclose(f); #else gzclose(f); #endif return 0; }
void restore_map(struct object *ob, struct mapping *map, char *file) { char *name, *buff, *space; size_t len; FILE *f; struct object *save = current_object; struct stat st; if (current_object != ob) fatal("Bad argument to restore_map()\n"); if (ob->flags & O_DESTRUCTED) return; file = check_valid_path(file, ob, "restore_map", 0); if (file == 0) error("Illegal use of restore_map()\n"); len = strlen(file); name = alloca(len + 2 + 1); (void)strcpy(name, file); if (name[len-2] == '.' && name[len-1] == 'c') name[len-1] = 'o'; else (void)strcat(name, ".o"); f = fopen(name, "r"); if (s_flag) num_fileread++; if (!f || fstat(fileno(f), &st) == -1) { if (f) (void)fclose(f); return; } if (st.st_size == 0) { (void)fclose(f); return; } buff = xalloc((size_t)st.st_size + 1); for (;;) { struct svalue v; v.type = T_STRING; v.string_type = STRING_MSTRING; if (fgets(buff, (int)st.st_size + 1, f) == 0) break; /* Remember that we have a newline at end of buff ! */ space = strchr(buff, ' '); if (space == 0) { (void)fclose(f); free(buff); error("Illegal format when restoring %s.\n", file); } *space++ = '\0'; v.u.string = make_mstring(buff); if (!restore_one(get_map_lvalue(map,&v,1), &space)) { (void)fclose(f); free(buff); free_svalue(&v); error("Illegal format when restoring %s.\n", file); } free_svalue(&v); } current_object = save; free(buff); (void)fclose(f); }
int args_get(int argc, char **argv, args *arg) { int i; int ret = 0; args_init(arg); for(i = 1; i < argc; i++) { if(!strcmp(*(argv + i), "-c") || !strcmp(*(argv + i), "--collect")) { arg->collect = 1; ret++; } else if(!strcmp(*(argv + i), "-g") || !strcmp(*(argv + i), "--graph")) { arg->graph = 1; arg->res = *(argv + i + 1); ret++; } else if(!strcmp(*(argv + i), "-t") || !strcmp(*(argv + i), "--test")) { arg->test = 1; ret++; } else if(!strcmp(*(argv + i), "-d") || !strcmp(*(argv + i), "--daemon")) { arg->daemon = 1; ret++; } else if(!strcmp(*(argv + i), "-r") || !strcmp(*(argv + i), "--rrdopt")) { arg->rrdopt = *(argv + i + 1); ret++; } else if(!strcmp(*(argv + i), "-v") || !strcmp(*(argv + i), "--version")) { arg->version = 1; ret++; } else if(!strcmp(*(argv + i), "-gp") || !strcmp(*(argv + i), "--gpath")) { if(!check_valid_path(*(argv + i + 1))) { arg->gpath = *(argv + i + 1); ret++; } } else if(!strcmp(*(argv + i), "-rp") || !strcmp(*(argv + i), "--rpath")) { if(!check_valid_path(*(argv + i + 1))) { arg->rpath = *(argv + i + 1); ret++; } } else if(!strcmp(*(argv + i), "-f") || !strcmp(*(argv + i), "--conffile")) { if(!check_configuration_file(*(argv + i + 1))) { arg->conffile = *(argv + i + 1); ret++; } } else if(!strcmp(*(argv + i), "-l") || !strcmp(*(argv + i), "--log")) { arg->logfile = *(argv + i + 1); log_set_file(*(argv + i + 1)); ret++; } else if(!strcmp(*(argv + i), "-h") || !strcmp(*(argv + i), "--help")) { arg->help = 1; ret++; } } return ret; }