[2223] | 1 | /* |
---|
[12350] | 2 | * $Id: stack.c,v 1.13 1999-01-22 23:09:06 ghudson Exp $ |
---|
[2223] | 3 | * |
---|
| 4 | * This program is part of a package including delete, undelete, |
---|
| 5 | * lsdel, expunge and purge. The software suite is meant as a |
---|
| 6 | * replacement for rm which allows for file recovery. |
---|
| 7 | * |
---|
| 8 | * Copyright (c) 1989 by the Massachusetts Institute of Technology. |
---|
[4505] | 9 | * For copying and distribution information, see the file "mit-copying.h." |
---|
[2223] | 10 | */ |
---|
| 11 | |
---|
[23663] | 12 | #include <string.h> |
---|
[2220] | 13 | #include <sys/types.h> |
---|
| 14 | #include <stdio.h> |
---|
| 15 | #include <errno.h> |
---|
| 16 | #include "stack.h" |
---|
| 17 | #include "delete_errs.h" |
---|
| 18 | #include "errors.h" |
---|
[4505] | 19 | #include "mit-copying.h" |
---|
[2364] | 20 | #include "util.h" |
---|
[2220] | 21 | |
---|
| 22 | #define STACK_INC 25 |
---|
| 23 | |
---|
| 24 | |
---|
| 25 | |
---|
[24908] | 26 | int dostack(caddr_t data, int op, int bytes) |
---|
[2220] | 27 | { |
---|
| 28 | static caddr_t stack = (caddr_t) NULL; |
---|
| 29 | static int size = 0, count = 0; |
---|
[3062] | 30 | |
---|
[2220] | 31 | switch (op) { |
---|
| 32 | case EMPTY_STACK: |
---|
| 33 | if (size) { |
---|
| 34 | free(stack); |
---|
| 35 | stack = (caddr_t) NULL; |
---|
| 36 | size = count = 0; |
---|
| 37 | } |
---|
[3062] | 38 | #ifdef STACK_DEBUG |
---|
| 39 | fprintf(stderr, "dostack: return 1 (EMPTY_STACK).\n"); |
---|
| 40 | #endif |
---|
[2220] | 41 | return 0; |
---|
| 42 | case STACK_PUSH: |
---|
[3062] | 43 | if (bytes == 0) { |
---|
| 44 | #ifdef STACK_DEBUG |
---|
| 45 | fprintf(stderr, "Pushing 0 bytes at %d offset.\n", count); |
---|
| 46 | fprintf(stderr, "dostack: return 2 (STACK_PUSH).\n"); |
---|
| 47 | #endif |
---|
[2452] | 48 | return 0; |
---|
[3062] | 49 | } |
---|
[2220] | 50 | if (size - count < bytes) { |
---|
[2452] | 51 | do |
---|
| 52 | size += STACK_INC; |
---|
| 53 | while (size - count < bytes); |
---|
[2220] | 54 | stack = (caddr_t) (stack ? realloc((char *) stack, |
---|
| 55 | (unsigned) size) : |
---|
[2364] | 56 | Malloc((unsigned) size)); |
---|
[5048] | 57 | if ((! stack) && size) |
---|
| 58 | { |
---|
[2364] | 59 | size = count = 0; |
---|
[2220] | 60 | set_error(errno); |
---|
[2364] | 61 | error("Malloc"); |
---|
[3062] | 62 | #ifdef STACK_DEBUG |
---|
| 63 | fprintf(stderr, "dostack: return 3 (STACK_PUSH).\n"); |
---|
| 64 | #endif |
---|
[2220] | 65 | return error_code; |
---|
| 66 | } |
---|
| 67 | } |
---|
[3062] | 68 | #ifdef STACK_DEBUG |
---|
| 69 | fprintf(stderr, "Pushing %d bytes at %d offset.\n", bytes, count); |
---|
| 70 | #endif |
---|
[3051] | 71 | memcpy(stack + count, data, bytes); |
---|
[2220] | 72 | count += bytes; |
---|
[3062] | 73 | #ifdef STACK_DEBUG |
---|
| 74 | fprintf(stderr, "dostack: return 4 (STACK_PUSH).\n"); |
---|
| 75 | #endif |
---|
[2220] | 76 | return 0; |
---|
| 77 | case STACK_POP: |
---|
[3062] | 78 | if (bytes == 0) { |
---|
| 79 | #ifdef STACK_DEBUG |
---|
| 80 | fprintf(stderr, "Popping 0 bytes at %d offset.\n", count); |
---|
| 81 | fprintf(stderr, "dostack: return 5 (STACK_POP).\n"); |
---|
| 82 | #endif |
---|
[2452] | 83 | return 0; |
---|
[3062] | 84 | } |
---|
[2220] | 85 | if (count == 0) { |
---|
| 86 | set_status(STACK_EMPTY); |
---|
[3062] | 87 | #ifdef STACK_DEBUG |
---|
| 88 | fprintf(stderr, "dostack: return 6 (STACK_POP).\n"); |
---|
| 89 | #endif |
---|
[2220] | 90 | return error_code; |
---|
| 91 | } |
---|
| 92 | else { |
---|
[2453] | 93 | int newblocks, newsize; |
---|
| 94 | |
---|
[2220] | 95 | count -= bytes; |
---|
[3062] | 96 | #ifdef STACK_DEBUG |
---|
| 97 | fprintf(stderr, "Popping %d bytes at %d offset.\n", bytes, |
---|
| 98 | count); |
---|
| 99 | #endif |
---|
| 100 | memcpy(data, stack + count, bytes); |
---|
[2453] | 101 | newblocks = count / STACK_INC + ((count % STACK_INC) ? 1 : 0); |
---|
| 102 | newsize = newblocks * STACK_INC; |
---|
| 103 | if (newsize < size) { |
---|
| 104 | size = newsize; |
---|
[2220] | 105 | stack = (caddr_t) realloc((char *) stack, (unsigned) size); |
---|
[5048] | 106 | if ((! stack) && size) |
---|
| 107 | { |
---|
[2220] | 108 | set_error(errno); |
---|
| 109 | error("realloc"); |
---|
[3062] | 110 | #ifdef STACK_DEBUG |
---|
| 111 | fprintf(stderr, "dostack: return 7 (STACK_POP).\n"); |
---|
| 112 | #endif |
---|
[2220] | 113 | return error_code; |
---|
| 114 | } |
---|
| 115 | } |
---|
[3062] | 116 | #ifdef STACK_DEBUG |
---|
| 117 | fprintf(stderr, "dostack: return 8 (STACK_POP).\n"); |
---|
| 118 | #endif |
---|
[2220] | 119 | return 0; |
---|
| 120 | } |
---|
| 121 | default: |
---|
| 122 | set_error(STACK_BAD_OP); |
---|
[3062] | 123 | #ifdef STACK_DEBUG |
---|
| 124 | fprintf(stderr, "dostack: return 9.\n"); |
---|
| 125 | #endif |
---|
[2220] | 126 | return error_code; |
---|
| 127 | } |
---|
| 128 | } |
---|