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