[147] | 1 | /* |
---|
| 2 | * |
---|
[1939] | 3 | * Copyright (C) 1988, 1989 by the Massachusetts Institute of Technology |
---|
| 4 | * Developed by the MIT Student Information Processing Board (SIPB). |
---|
| 5 | * For copying information, see the file mit-copyright.h in this release. |
---|
[150] | 6 | * |
---|
[1939] | 7 | */ |
---|
| 8 | /* |
---|
[17452] | 9 | * $Id: coreutil.c,v 1.32 2002-04-06 15:18:55 zacheiss Exp $ |
---|
[150] | 10 | * |
---|
| 11 | * |
---|
[147] | 12 | * coreutil.c -- These contain lower-layer, utility type routines to |
---|
| 13 | * be used by core. These include things to handle the |
---|
| 14 | * in-memory superblock, and to open & close meetings. |
---|
| 15 | * |
---|
| 16 | */ |
---|
| 17 | |
---|
[150] | 18 | #ifndef lint |
---|
[1478] | 19 | #ifdef __STDC__ |
---|
| 20 | const |
---|
| 21 | #endif |
---|
| 22 | static char rcsid_coreutil_c[] = |
---|
[17452] | 23 | "$Id: coreutil.c,v 1.32 2002-04-06 15:18:55 zacheiss Exp $"; |
---|
[1478] | 24 | #endif /* lint */ |
---|
[150] | 25 | |
---|
[1938] | 26 | #include <discuss/types.h> |
---|
| 27 | #include <discuss/dsc_et.h> |
---|
| 28 | #include "atom.h" |
---|
[147] | 29 | #include "mtg.h" |
---|
[1938] | 30 | #include <discuss/tfile.h> |
---|
| 31 | #include <discuss/acl.h> |
---|
| 32 | #include "internal.h" |
---|
| 33 | #include "ansi.h" |
---|
[12439] | 34 | #if HAVE_ZEPHYR |
---|
[752] | 35 | #include <zephyr/zephyr.h> |
---|
[12439] | 36 | #endif |
---|
| 37 | #include <stdio.h> |
---|
[12267] | 38 | #include <stdlib.h> |
---|
[147] | 39 | #include <errno.h> |
---|
[972] | 40 | #include <sys/types.h> |
---|
[17452] | 41 | #include <unistd.h> |
---|
[752] | 42 | #include <netdb.h> |
---|
[147] | 43 | #include <sys/file.h> |
---|
| 44 | #include <sys/stat.h> |
---|
[6571] | 45 | #include <string.h> |
---|
[12439] | 46 | #if HAVE_FCNTL_H |
---|
[6571] | 47 | #include <fcntl.h> |
---|
| 48 | #endif |
---|
[17452] | 49 | #include <unistd.h> |
---|
[147] | 50 | |
---|
| 51 | /* global variables */ |
---|
[1938] | 52 | char current_mtg [256] = ""; /* meeting that's opened */ |
---|
| 53 | int u_trn_f,u_control_f,u_acl_f; /* UNIX file descriptors */ |
---|
| 54 | bool nuclear = FALSE; /* Using atomic reads/writes */ |
---|
| 55 | afile a_control_f = NULL; /* radioactive file descriptor */ |
---|
| 56 | tfile abort_file = NULL; /* close this on abort */ |
---|
| 57 | bool read_lock = FALSE; /* have lock on u_control_f */ |
---|
[11464] | 58 | bool mtg_swapped = FALSE; /* current meeting is swapped */ |
---|
[1938] | 59 | dsc_acl *mtg_acl = NULL; /* current mtg acl */ |
---|
| 60 | int last_acl_mod; /* last mod to ACL */ |
---|
[147] | 61 | mtg_super super; |
---|
| 62 | char *super_chairman; |
---|
| 63 | char *super_long_name; |
---|
[1938] | 64 | int has_privs = 0; /* Has privileges (linked) */ |
---|
| 65 | int no_nuke = 0; /* Don't be atomic (linked) */ |
---|
[12439] | 66 | #if HAVE_ZEPHYR |
---|
[1938] | 67 | int use_zephyr = 1; /* Actually do use Zephyr. */ |
---|
[2080] | 68 | #else |
---|
| 69 | int use_zephyr = 0; |
---|
[1938] | 70 | #endif |
---|
[147] | 71 | |
---|
| 72 | |
---|
| 73 | /* EXTERNAL */ |
---|
| 74 | extern int errno; |
---|
| 75 | extern char rpc_caller []; |
---|
| 76 | |
---|
| 77 | /* |
---|
| 78 | * |
---|
| 79 | * new_string (s) -- Routine to create a copy of the given string, using |
---|
| 80 | * malloc. |
---|
| 81 | * |
---|
| 82 | */ |
---|
| 83 | char *new_string (s) |
---|
| 84 | char *s; |
---|
| 85 | { |
---|
| 86 | int len; |
---|
| 87 | char *newstr; |
---|
| 88 | |
---|
| 89 | len = strlen (s) + 1; |
---|
[170] | 90 | newstr = malloc ((unsigned)len); |
---|
| 91 | (void) strcpy (newstr, s); |
---|
[147] | 92 | return (newstr); |
---|
| 93 | } |
---|
| 94 | |
---|
| 95 | /* |
---|
| 96 | * |
---|
| 97 | * open_mtg (mtg_name) -- Routine to open a meeting, if necessary. |
---|
| 98 | * |
---|
| 99 | */ |
---|
| 100 | int open_mtg (mtg_name) |
---|
| 101 | char *mtg_name; |
---|
| 102 | { |
---|
| 103 | char str[256]; |
---|
| 104 | int result; |
---|
| 105 | int mtg_name_len; |
---|
| 106 | trn_base tb; |
---|
[170] | 107 | int uid = (int)geteuid(); |
---|
[150] | 108 | struct stat sb; |
---|
[147] | 109 | |
---|
| 110 | mtg_name_len = strlen (mtg_name); |
---|
[1938] | 111 | if (mtg_name[0] != '/' || mtg_name_len == 0 || mtg_name_len > 168 |
---|
| 112 | || mtg_name [mtg_name_len-1] == '/') { |
---|
[147] | 113 | return (BAD_PATH); |
---|
| 114 | } |
---|
| 115 | |
---|
[2033] | 116 | /* Check for moved meeting */ |
---|
[170] | 117 | (void) strcpy (str, mtg_name); |
---|
[2033] | 118 | (void) strcat (str, "/forward"); |
---|
| 119 | if (!stat(str, &sb)) { |
---|
| 120 | return(MTG_MOVED); |
---|
| 121 | } |
---|
| 122 | |
---|
| 123 | (void) strcpy (str, mtg_name); |
---|
[170] | 124 | (void) strcat (str, "/acl"); |
---|
[147] | 125 | |
---|
[150] | 126 | if (!strcmp (mtg_name, current_mtg)) { |
---|
| 127 | /* |
---|
| 128 | * is acl stale? |
---|
| 129 | */ |
---|
[257] | 130 | if (stat(str, &sb) >= 0) |
---|
| 131 | if (sb.st_mtime <= last_acl_mod) |
---|
| 132 | return (0); /* that was easy */ |
---|
[150] | 133 | } |
---|
| 134 | |
---|
[147] | 135 | if (current_mtg [0] != '\0') { /* close previous meeting */ |
---|
| 136 | if (nuclear) |
---|
| 137 | panic ("Nuclear flag error"); /* should never happen */ |
---|
[170] | 138 | (void) close (u_trn_f); |
---|
| 139 | (void) close (u_control_f); |
---|
[147] | 140 | current_mtg [0] = '\0'; |
---|
| 141 | acl_destroy(mtg_acl); |
---|
| 142 | } |
---|
| 143 | |
---|
| 144 | u_trn_f = u_control_f = u_acl_f = 0; |
---|
| 145 | |
---|
| 146 | if ((u_acl_f = open(str, O_RDONLY, 0700)) < 0) { |
---|
| 147 | if (errno == ENOENT) |
---|
| 148 | result = NO_SUCH_MTG; |
---|
| 149 | else if (errno == EACCES) |
---|
| 150 | result = NO_ACCESS; |
---|
| 151 | else |
---|
| 152 | result = BAD_PATH; |
---|
| 153 | goto punt; |
---|
| 154 | } |
---|
| 155 | if (!fis_owner (u_acl_f, uid)) { |
---|
| 156 | result = NO_ACCESS; |
---|
| 157 | goto punt; |
---|
| 158 | } |
---|
| 159 | |
---|
| 160 | mtg_acl = acl_read (u_acl_f); |
---|
[170] | 161 | (void) fstat(u_acl_f, &sb); |
---|
[150] | 162 | last_acl_mod = sb.st_mtime; |
---|
[170] | 163 | (void) close(u_acl_f); |
---|
[147] | 164 | u_acl_f = 0; |
---|
| 165 | |
---|
[170] | 166 | (void) strcpy (str, mtg_name); |
---|
| 167 | (void) strcat (str, "/control"); |
---|
[147] | 168 | |
---|
| 169 | if ((u_control_f = open(str, O_RDWR, 0700)) < 0) { |
---|
| 170 | if (errno == ENOENT) |
---|
| 171 | result = NO_SUCH_MTG; |
---|
| 172 | else if (errno == EACCES) |
---|
| 173 | result = NO_ACCESS; |
---|
| 174 | else |
---|
| 175 | result = BAD_PATH; |
---|
| 176 | goto punt; |
---|
| 177 | } |
---|
| 178 | |
---|
| 179 | if (!fis_owner (u_control_f, uid)) { |
---|
| 180 | result = NO_ACCESS; |
---|
| 181 | goto punt; |
---|
| 182 | } |
---|
| 183 | |
---|
[170] | 184 | (void) strcpy (str, mtg_name); |
---|
| 185 | (void) strcat (str, "/transactions"); |
---|
[147] | 186 | |
---|
| 187 | if ((u_trn_f = open(str, O_RDWR, 0700)) < 0) { |
---|
| 188 | if (errno == ENOENT) |
---|
| 189 | result = NO_SUCH_MTG; |
---|
| 190 | else if (errno == EACCES) |
---|
| 191 | result = NO_ACCESS; |
---|
| 192 | else |
---|
| 193 | result = BAD_PATH; |
---|
| 194 | goto punt; |
---|
| 195 | } |
---|
| 196 | |
---|
| 197 | if (!fis_owner (u_trn_f, uid)) { |
---|
| 198 | result = NO_ACCESS; |
---|
| 199 | goto punt; |
---|
| 200 | } |
---|
| 201 | |
---|
| 202 | read (u_trn_f, (char *) &tb, sizeof (trn_base)); |
---|
[11464] | 203 | if (tb.unique == TRN_BASE_UNIQUE_SWAP) { |
---|
| 204 | swap_trn_base(&tb); |
---|
| 205 | mtg_swapped = TRUE; |
---|
| 206 | } else { |
---|
| 207 | mtg_swapped = FALSE; |
---|
| 208 | } |
---|
| 209 | |
---|
[147] | 210 | if (tb.unique != TRN_BASE_UNIQUE) { |
---|
| 211 | result = INCONSISTENT; |
---|
| 212 | goto punt; |
---|
| 213 | } |
---|
| 214 | |
---|
[170] | 215 | (void) strcpy (current_mtg, mtg_name); |
---|
[147] | 216 | |
---|
| 217 | return (0); |
---|
| 218 | |
---|
| 219 | punt: |
---|
| 220 | if (u_trn_f) |
---|
[170] | 221 | (void) close(u_trn_f); |
---|
[147] | 222 | if (u_control_f) |
---|
[170] | 223 | (void) close(u_control_f); |
---|
[147] | 224 | if (u_acl_f) |
---|
[170] | 225 | (void) close(u_acl_f); |
---|
[147] | 226 | acl_destroy(mtg_acl); |
---|
| 227 | mtg_acl = NULL; |
---|
| 228 | return (result); |
---|
| 229 | } |
---|
| 230 | |
---|
| 231 | |
---|
| 232 | int read_super() |
---|
| 233 | { |
---|
| 234 | if (nuclear) { |
---|
| 235 | aread (a_control_f, (char *) &super, sizeof(super), 0); |
---|
| 236 | } else { |
---|
[17452] | 237 | lseek (u_control_f, (long)0, SEEK_SET); |
---|
[170] | 238 | read (u_control_f, (char *) &super, sizeof (super)); |
---|
[147] | 239 | } |
---|
| 240 | |
---|
[11464] | 241 | if (!mtg_swapped) { |
---|
| 242 | if (super.unique != MTG_SUPER_UNIQUE) |
---|
| 243 | return (INCONSISTENT); |
---|
| 244 | } else { |
---|
| 245 | if (super.unique != MTG_SUPER_UNIQUE_SWAP) |
---|
| 246 | return (INCONSISTENT); |
---|
| 247 | swap_super(&super); |
---|
| 248 | } |
---|
[1072] | 249 | |
---|
[147] | 250 | if (super.version != MTG_SUPER_1) |
---|
| 251 | return (NEW_VERSION); |
---|
| 252 | |
---|
[170] | 253 | super_long_name = malloc ((unsigned)super.long_name_len); |
---|
| 254 | super_chairman = malloc ((unsigned)super.chairman_len); |
---|
[147] | 255 | |
---|
| 256 | if (nuclear) { |
---|
| 257 | aread (a_control_f, super_long_name, super.long_name_len, super.long_name_addr); |
---|
| 258 | aread (a_control_f, super_chairman, super.chairman_len, super.chairman_addr); |
---|
| 259 | } else { |
---|
[17452] | 260 | lseek (u_control_f, (long)super.long_name_addr, SEEK_SET); |
---|
[147] | 261 | read (u_control_f, super_long_name, super.long_name_len); |
---|
[17452] | 262 | lseek (u_control_f, (long)super.chairman_addr, SEEK_SET); |
---|
[147] | 263 | read (u_control_f, super_chairman, super.chairman_len); |
---|
| 264 | } |
---|
| 265 | |
---|
| 266 | return(0); |
---|
| 267 | } |
---|
| 268 | |
---|
| 269 | write_super () |
---|
| 270 | { |
---|
| 271 | int sc_len, sl_len; |
---|
[11464] | 272 | int slong_name_len, slong_name_addr; |
---|
| 273 | int schairman_len, schairman_addr; |
---|
[147] | 274 | |
---|
| 275 | sc_len = strlen (super_chairman)+1; |
---|
| 276 | sl_len = strlen (super_long_name)+1; |
---|
| 277 | |
---|
| 278 | if (sc_len != super.chairman_len || sl_len != super.long_name_len) { /* reallocate things */ |
---|
| 279 | super.long_name_addr = sizeof (super); |
---|
| 280 | super.long_name_len = sl_len; |
---|
| 281 | super.chairman_addr = super.long_name_addr + super.long_name_len; |
---|
| 282 | super.chairman_len = sc_len; |
---|
| 283 | } |
---|
| 284 | |
---|
[11464] | 285 | /* Copy into locals to avoid swapping */ |
---|
| 286 | slong_name_len = super.long_name_len; |
---|
| 287 | slong_name_addr = super.long_name_addr; |
---|
| 288 | schairman_len = super.chairman_len; |
---|
| 289 | schairman_addr = super.chairman_addr; |
---|
| 290 | |
---|
| 291 | if (mtg_swapped) |
---|
| 292 | swap_super(&super); |
---|
| 293 | |
---|
[147] | 294 | if (nuclear) { |
---|
| 295 | awrite (a_control_f, (char *) &super, sizeof (super), 0); |
---|
[11464] | 296 | awrite (a_control_f, super_long_name, slong_name_len, slong_name_addr); |
---|
| 297 | awrite (a_control_f, super_chairman, schairman_len, schairman_addr); |
---|
[147] | 298 | } else { |
---|
[17452] | 299 | lseek (u_control_f, (long)0, SEEK_SET); |
---|
[147] | 300 | write (u_control_f, (char *) &super, sizeof (super)); |
---|
[17452] | 301 | lseek (u_control_f, (long)slong_name_addr, SEEK_SET); |
---|
[11464] | 302 | write (u_control_f, super_long_name, slong_name_len); |
---|
[17452] | 303 | lseek (u_control_f, (long)schairman_addr, SEEK_SET); |
---|
[11464] | 304 | write (u_control_f, super_chairman, schairman_len); |
---|
[147] | 305 | } |
---|
| 306 | |
---|
| 307 | free (super_chairman); |
---|
[2079] | 308 | super_chairman = NULL; |
---|
[147] | 309 | free (super_long_name); |
---|
[2079] | 310 | super_long_name = NULL; |
---|
[147] | 311 | super.unique = 0; /* prevent accidents */ |
---|
| 312 | |
---|
| 313 | return; |
---|
| 314 | } |
---|
| 315 | |
---|
| 316 | /* |
---|
| 317 | * |
---|
| 318 | * forget_super () -- Routine to dump superblock, like when we just read |
---|
| 319 | * it. This frees any alloc'd storage. |
---|
| 320 | * |
---|
| 321 | */ |
---|
| 322 | forget_super() |
---|
| 323 | { |
---|
[2079] | 324 | if (super_long_name != NULL) |
---|
| 325 | free(super_long_name); |
---|
| 326 | super_long_name = NULL; |
---|
[147] | 327 | |
---|
[2079] | 328 | if (super_chairman != NULL) |
---|
| 329 | free(super_chairman); |
---|
| 330 | super_chairman = NULL; |
---|
[147] | 331 | super.unique = 0; |
---|
| 332 | } |
---|
| 333 | |
---|
| 334 | /* |
---|
| 335 | * |
---|
| 336 | * start_read () -- This reserves the meeting for non-destructive reading. |
---|
| 337 | * Simply does an flock. |
---|
| 338 | * |
---|
| 339 | */ |
---|
| 340 | start_read() |
---|
| 341 | { |
---|
[7185] | 342 | struct flock lock; |
---|
| 343 | |
---|
[1503] | 344 | if (!no_nuke) { |
---|
[9551] | 345 | lock.l_type = F_RDLCK; |
---|
[7185] | 346 | lock.l_start = 0; |
---|
| 347 | lock.l_whence = 0; |
---|
| 348 | lock.l_len = 0; |
---|
[9551] | 349 | if (fcntl(u_control_f, F_SETLKW, &lock) < 0) |
---|
[1503] | 350 | panic ("Cannot share lock"); |
---|
| 351 | read_lock = TRUE; |
---|
| 352 | } |
---|
[147] | 353 | } |
---|
| 354 | |
---|
| 355 | /* |
---|
| 356 | * |
---|
| 357 | * finish_read () -- This frees up our reservation on the meeting. This |
---|
| 358 | * does the opposite of start_read. |
---|
| 359 | * |
---|
| 360 | */ |
---|
| 361 | finish_read() |
---|
| 362 | { |
---|
[7185] | 363 | struct flock lock; |
---|
| 364 | |
---|
[1503] | 365 | if (!no_nuke) { |
---|
[7185] | 366 | lock.l_type = F_UNLCK; |
---|
| 367 | lock.l_start = 0; |
---|
| 368 | lock.l_whence = 0; |
---|
| 369 | lock.l_len = 0; |
---|
| 370 | fcntl(u_control_f, F_SETLK, &lock); |
---|
[1503] | 371 | read_lock = 0; |
---|
| 372 | } |
---|
[147] | 373 | } |
---|
| 374 | |
---|
| 375 | /* |
---|
| 376 | * |
---|
| 377 | * chain_addr -- Returns address of given chain block. |
---|
| 378 | * |
---|
| 379 | */ |
---|
| 380 | faddr chain_addr(trn) |
---|
| 381 | trn_nums trn; |
---|
| 382 | { |
---|
| 383 | if (trn < super.lowest || trn > super.highest) |
---|
| 384 | return (0); |
---|
| 385 | |
---|
| 386 | return (super.chain_start + (trn-1) * sizeof (chain_blk)); |
---|
| 387 | } |
---|
| 388 | |
---|
| 389 | int read_chain (trn, cb) |
---|
| 390 | trn_nums trn; |
---|
| 391 | chain_blk *cb; |
---|
| 392 | { |
---|
| 393 | faddr cbaddr; |
---|
| 394 | |
---|
| 395 | cbaddr = chain_addr (trn); |
---|
| 396 | if (cbaddr == 0) |
---|
| 397 | return (NO_SUCH_TRN); |
---|
| 398 | |
---|
| 399 | if (nuclear) |
---|
| 400 | aread (a_control_f, (char *) cb, sizeof (chain_blk), cbaddr); |
---|
| 401 | else { |
---|
[17452] | 402 | lseek (u_control_f, (long)cbaddr, SEEK_SET); |
---|
[147] | 403 | read (u_control_f, (char *) cb, sizeof (chain_blk)); |
---|
| 404 | } |
---|
| 405 | |
---|
[11464] | 406 | if (mtg_swapped) |
---|
| 407 | swap_chain(cb); |
---|
| 408 | |
---|
[1072] | 409 | if (cb -> unique != CHAIN_BLK_UNIQUE || cb -> current != trn) |
---|
| 410 | return (INCONSISTENT); |
---|
| 411 | |
---|
[147] | 412 | if (cb -> version != CHAIN_BLK_1) |
---|
| 413 | return (NEW_VERSION); |
---|
| 414 | |
---|
| 415 | return (0); |
---|
| 416 | } |
---|
| 417 | |
---|
| 418 | int write_chain (cb) |
---|
| 419 | chain_blk *cb; |
---|
| 420 | { |
---|
| 421 | faddr cbaddr; |
---|
| 422 | |
---|
| 423 | cbaddr = chain_addr (cb -> current); |
---|
| 424 | if (cbaddr == 0) |
---|
| 425 | return (NO_SUCH_TRN); |
---|
| 426 | |
---|
[11464] | 427 | if (mtg_swapped) |
---|
| 428 | swap_chain(cb); |
---|
| 429 | |
---|
[247] | 430 | if (nuclear) { |
---|
[11464] | 431 | if (awrite (a_control_f, (char *) cb, sizeof (chain_blk), cbaddr) != sizeof (chain_blk)) { |
---|
| 432 | if (mtg_swapped) |
---|
| 433 | swap_chain(cb); |
---|
[247] | 434 | return (NO_WRITE); |
---|
[11464] | 435 | } |
---|
[247] | 436 | } |
---|
[147] | 437 | else { |
---|
[17452] | 438 | lseek (u_control_f, (long)cbaddr, SEEK_SET); |
---|
[11464] | 439 | if (write (u_control_f, (char *) cb, sizeof (chain_blk)) != sizeof (chain_blk)) { |
---|
| 440 | if (mtg_swapped) |
---|
| 441 | swap_chain(cb); |
---|
[247] | 442 | return (NO_WRITE); |
---|
[11464] | 443 | } |
---|
[147] | 444 | } |
---|
| 445 | |
---|
[11464] | 446 | if (mtg_swapped) |
---|
| 447 | swap_chain(cb); |
---|
[147] | 448 | return (0); |
---|
| 449 | } |
---|
| 450 | |
---|
| 451 | /* |
---|
| 452 | * |
---|
| 453 | * read_trn -- routine to read a transaction from the transaction file. |
---|
| 454 | * |
---|
| 455 | */ |
---|
[2743] | 456 | int read_trn (trn_addr, th, th_subject, th_author, th_signature) |
---|
[147] | 457 | faddr trn_addr; |
---|
| 458 | trn_hdr *th; |
---|
[2743] | 459 | char **th_subject, **th_author, **th_signature; |
---|
[147] | 460 | { |
---|
[2743] | 461 | char *author; |
---|
| 462 | |
---|
[17452] | 463 | lseek (u_trn_f, (long)trn_addr, SEEK_SET); |
---|
[147] | 464 | read (u_trn_f, (char *) th, sizeof (trn_hdr)); |
---|
| 465 | |
---|
[11464] | 466 | if (mtg_swapped) |
---|
| 467 | swap_trn(th); |
---|
| 468 | |
---|
[1072] | 469 | if (th -> unique != TRN_HDR_UNIQUE) |
---|
| 470 | return (INCONSISTENT); |
---|
| 471 | |
---|
[147] | 472 | if (th -> version != TRN_HDR_1) |
---|
| 473 | return(NEW_VERSION); |
---|
| 474 | |
---|
[2743] | 475 | if (th_subject != NULL) { |
---|
[170] | 476 | *th_subject = malloc ((unsigned)(th -> subject_len)); |
---|
[17452] | 477 | lseek (u_trn_f, (long)(th -> subject_addr), SEEK_SET); |
---|
[147] | 478 | read (u_trn_f, *th_subject, th -> subject_len); |
---|
| 479 | } |
---|
| 480 | |
---|
[2743] | 481 | if (th_author != NULL || th_signature != NULL) { |
---|
| 482 | author = malloc ((unsigned)(th -> author_len)); |
---|
[17452] | 483 | lseek (u_trn_f, (long)(th -> author_addr), SEEK_SET); |
---|
[2743] | 484 | read (u_trn_f, author, th -> author_len); |
---|
[147] | 485 | } |
---|
| 486 | |
---|
[2743] | 487 | if (th_author != NULL) |
---|
| 488 | *th_author = author; |
---|
| 489 | |
---|
| 490 | if (th_signature != NULL) { |
---|
| 491 | if (strlen(author)+1 == th -> author_len) { |
---|
| 492 | *th_signature = new_string(author); /* No signature, return author */ |
---|
| 493 | } else { |
---|
| 494 | *th_signature = new_string(&author[strlen(author)+1]); |
---|
| 495 | } |
---|
| 496 | if (th_author == NULL) |
---|
| 497 | free(author); |
---|
| 498 | } |
---|
| 499 | |
---|
[147] | 500 | return(0); |
---|
| 501 | } |
---|
| 502 | |
---|
| 503 | |
---|
| 504 | /* |
---|
| 505 | * |
---|
| 506 | * core_abort () -- Routine for use by core routines to clean things up. |
---|
| 507 | * |
---|
| 508 | */ |
---|
| 509 | core_abort () |
---|
| 510 | { |
---|
| 511 | int dummy; |
---|
| 512 | |
---|
| 513 | if (nuclear) { |
---|
| 514 | aabort(a_control_f); |
---|
| 515 | nuclear = FALSE; |
---|
| 516 | } |
---|
| 517 | |
---|
| 518 | if (abort_file != NULL) { |
---|
| 519 | tclose (abort_file,&dummy); |
---|
| 520 | abort_file = NULL; |
---|
| 521 | } |
---|
| 522 | |
---|
| 523 | if (read_lock) |
---|
| 524 | finish_read(); |
---|
| 525 | |
---|
[2079] | 526 | forget_super(); |
---|
| 527 | |
---|
[147] | 528 | return; |
---|
| 529 | } |
---|
| 530 | |
---|
| 531 | /* |
---|
| 532 | * |
---|
| 533 | * fsize () -- Routine to find out the size of a file. |
---|
| 534 | * |
---|
| 535 | */ |
---|
| 536 | fsize (d) |
---|
| 537 | int d; |
---|
| 538 | { |
---|
| 539 | struct stat buf; |
---|
| 540 | |
---|
| 541 | if (fstat (d, &buf) < 0) |
---|
| 542 | return (0); |
---|
| 543 | |
---|
| 544 | return (buf.st_size); |
---|
| 545 | } |
---|
| 546 | /* |
---|
| 547 | * |
---|
| 548 | * fis_owner () -- Routine to find out if uid is owner of file. |
---|
| 549 | * |
---|
| 550 | */ |
---|
| 551 | fis_owner (d, uid) |
---|
| 552 | int d,uid; |
---|
| 553 | { |
---|
| 554 | struct stat buf; |
---|
| 555 | |
---|
| 556 | if (fstat (d, &buf) < 0) |
---|
| 557 | return (0); |
---|
| 558 | |
---|
| 559 | return (uid == buf.st_uid); |
---|
| 560 | } |
---|
| 561 | |
---|
| 562 | /* |
---|
| 563 | * |
---|
| 564 | * has_trn_access -- Routine to return true if current user can access |
---|
| 565 | * transaction. |
---|
| 566 | * |
---|
| 567 | */ |
---|
| 568 | bool has_trn_access(author,mode) |
---|
| 569 | char *author; |
---|
| 570 | char mode; |
---|
| 571 | { |
---|
| 572 | char *test_modes; |
---|
| 573 | |
---|
[257] | 574 | if (has_privs) |
---|
| 575 | return(TRUE); /* linked in */ |
---|
| 576 | |
---|
[147] | 577 | switch (mode) { |
---|
| 578 | case 'd': |
---|
| 579 | if (!strcmp(author,rpc_caller)) { |
---|
| 580 | test_modes = "o"; |
---|
| 581 | } else { |
---|
| 582 | test_modes = "d"; |
---|
| 583 | } |
---|
| 584 | return (acl_check(mtg_acl,rpc_caller,test_modes)); |
---|
| 585 | |
---|
| 586 | case 'r': |
---|
| 587 | return (acl_check(mtg_acl,rpc_caller,"r") || |
---|
| 588 | ((!strcmp (author, rpc_caller)) && acl_check(mtg_acl,rpc_caller,"o"))); |
---|
| 589 | default: |
---|
| 590 | panic ("Invalid mode"); |
---|
[170] | 591 | /*NOTREACHED*/ |
---|
[147] | 592 | } |
---|
| 593 | } |
---|
| 594 | /* |
---|
| 595 | * |
---|
| 596 | * has_mtg_access -- Routine to return true if current user can access |
---|
| 597 | * mtg, with given mode. |
---|
| 598 | * |
---|
| 599 | */ |
---|
| 600 | bool has_mtg_access(mode) |
---|
| 601 | char mode; |
---|
| 602 | { |
---|
| 603 | char *test_modes; |
---|
[296] | 604 | char mode_str[3]; |
---|
[147] | 605 | |
---|
[257] | 606 | if (has_privs) /* linked in stuff */ |
---|
| 607 | return (TRUE); |
---|
| 608 | |
---|
[147] | 609 | switch (mode) { |
---|
| 610 | case 'w': |
---|
| 611 | case 'a': |
---|
[296] | 612 | case 'r': |
---|
[147] | 613 | case 's': |
---|
[296] | 614 | case 'o': |
---|
| 615 | mode_str[0] = mode; |
---|
| 616 | mode_str[1] = '\0'; |
---|
| 617 | test_modes = mode_str; |
---|
[147] | 618 | break; |
---|
| 619 | |
---|
| 620 | case 'c': |
---|
| 621 | test_modes = "c"; |
---|
| 622 | break; |
---|
| 623 | |
---|
| 624 | default: |
---|
| 625 | panic("Invalid mode"); |
---|
| 626 | } |
---|
| 627 | |
---|
| 628 | return(acl_check(mtg_acl,rpc_caller,test_modes)); |
---|
| 629 | } |
---|
| 630 | /* |
---|
| 631 | * |
---|
| 632 | * panic -- just a printf |
---|
| 633 | * |
---|
| 634 | */ |
---|
| 635 | panic(str) |
---|
| 636 | char *str; |
---|
| 637 | { |
---|
| 638 | printf("panic: %s\n",str); |
---|
| 639 | perror("discuss"); |
---|
| 640 | exit(1); |
---|
| 641 | } |
---|
[1938] | 642 | |
---|
[12439] | 643 | #if HAVE_ZEPHYR |
---|
[752] | 644 | /* |
---|
| 645 | * |
---|
| 646 | * mtg_znotify -- send off a Zephyr notification as appropriate |
---|
| 647 | * |
---|
| 648 | */ |
---|
[1938] | 649 | |
---|
| 650 | static const char * this_host = (const char *) NULL; |
---|
| 651 | |
---|
[2743] | 652 | void mtg_znotify(mtg_name, subject, author, signature) |
---|
| 653 | char *mtg_name, *subject, *author, *signature; |
---|
[752] | 654 | { |
---|
[1478] | 655 | register dsc_acl_entry *ae; |
---|
[752] | 656 | register int n; |
---|
| 657 | ZNotice_t notice; |
---|
[2750] | 658 | char *msglst[5],bfr[30],fullpath[256]; |
---|
[2743] | 659 | int code, list_size; |
---|
[1938] | 660 | |
---|
| 661 | if (!use_zephyr) |
---|
| 662 | return; |
---|
| 663 | |
---|
| 664 | if (!this_host) { |
---|
| 665 | /* perform initializations */ |
---|
| 666 | char *h; |
---|
| 667 | char host[100]; |
---|
| 668 | struct hostent *hent; |
---|
| 669 | if (gethostname(host,100) != 0) |
---|
| 670 | return; |
---|
| 671 | hent = (struct hostent *) gethostbyname(host); |
---|
| 672 | if (hent == 0) |
---|
| 673 | return; |
---|
| 674 | h = (char *) malloc (strlen (hent->h_name) + 1); |
---|
| 675 | if (!h) |
---|
| 676 | return; |
---|
| 677 | strcpy (h, hent->h_name); |
---|
| 678 | this_host = h; |
---|
| 679 | ZInitialize(); |
---|
| 680 | } |
---|
| 681 | |
---|
[752] | 682 | /* Set up the notice structure */ |
---|
[7185] | 683 | memset(¬ice, 0, sizeof(notice)); |
---|
[752] | 684 | |
---|
[1938] | 685 | sprintf(fullpath,"%s:%s", this_host, mtg_name); |
---|
[1510] | 686 | ZOpenPort(NULL); |
---|
[752] | 687 | notice.z_kind = UNSAFE; |
---|
| 688 | notice.z_port = 0; |
---|
| 689 | notice.z_class = "DISCUSS"; |
---|
| 690 | notice.z_class_inst = fullpath; |
---|
| 691 | notice.z_opcode = "NEW_TRN"; |
---|
| 692 | notice.z_sender = 0; |
---|
[2743] | 693 | if (signature == NULL) |
---|
| 694 | notice.z_default_format = "New transaction [$1] entered in $2\nFrom: $3\nSubject: $4"; |
---|
| 695 | else |
---|
| 696 | notice.z_default_format = "New transaction [$1] entered in $2\nFrom: $3 ($5)\nSubject: $4"; |
---|
[752] | 697 | msglst[0] = bfr; |
---|
| 698 | sprintf(msglst[0],"%04d",super.highest); |
---|
| 699 | msglst[1] = super_long_name; |
---|
| 700 | msglst[2] = author; |
---|
| 701 | msglst[3] = subject; |
---|
[2743] | 702 | list_size = 4; |
---|
| 703 | if (signature != NULL) { |
---|
| 704 | msglst[4] = signature; |
---|
| 705 | list_size = 5; |
---|
| 706 | } |
---|
[752] | 707 | |
---|
| 708 | /* Does "*" have read access? If so, just send out a global |
---|
| 709 | * notice. |
---|
| 710 | */ |
---|
| 711 | |
---|
| 712 | /* XXX |
---|
| 713 | * Check at some point for people who don't have access, etc. |
---|
| 714 | */ |
---|
[1938] | 715 | |
---|
[752] | 716 | for (ae = mtg_acl->acl_entries, n=mtg_acl->acl_length; |
---|
| 717 | n; |
---|
| 718 | ae++, n--) { |
---|
| 719 | if ((strcmp("*", ae->principal) == 0) && |
---|
| 720 | acl_is_subset("r", ae->modes)) |
---|
| 721 | break; |
---|
| 722 | } |
---|
| 723 | if (n) { |
---|
[1517] | 724 | notice.z_recipient = ""; |
---|
[752] | 725 | /* We really don't care if it gets through... */ |
---|
[2743] | 726 | code = ZSendList(¬ice,msglst,list_size,ZNOAUTH); |
---|
[752] | 727 | return; |
---|
| 728 | } |
---|
| 729 | for (ae = mtg_acl->acl_entries, n=mtg_acl->acl_length; |
---|
| 730 | n; |
---|
| 731 | ae++, n--) { |
---|
| 732 | if (acl_is_subset("r", ae->modes)) { |
---|
| 733 | notice.z_recipient = ae->principal; |
---|
[2743] | 734 | ZSendList(¬ice,msglst,list_size,ZNOAUTH); |
---|
[752] | 735 | } |
---|
| 736 | } |
---|
| 737 | } |
---|
[12439] | 738 | #endif |
---|
[11464] | 739 | |
---|
| 740 | static unsigned long swap_32(val) |
---|
| 741 | unsigned long val; |
---|
| 742 | { |
---|
| 743 | unsigned char b1 = (val >> 24) & 0xff; |
---|
| 744 | unsigned char b2 = (val >> 16) & 0xff; |
---|
| 745 | unsigned char b3 = (val >> 8) & 0xff; |
---|
| 746 | unsigned char b4 = val & 0xff; |
---|
| 747 | |
---|
| 748 | return ((b4 << 24) | (b3 << 16) | (b2 << 8) | b1); |
---|
| 749 | } |
---|
| 750 | |
---|
| 751 | static unsigned int swap_16(val) |
---|
| 752 | unsigned int val; |
---|
| 753 | { |
---|
| 754 | unsigned char b1 = (val >> 8) & 0xff; |
---|
| 755 | unsigned char b2 = val & 0xff; |
---|
| 756 | |
---|
| 757 | return ((b2 << 8) | b1); |
---|
| 758 | } |
---|
| 759 | |
---|
| 760 | swap_super(superp) |
---|
| 761 | mtg_super *superp; |
---|
| 762 | { |
---|
| 763 | superp->version = swap_32(superp->version); |
---|
| 764 | superp->unique = swap_32(superp->unique); |
---|
| 765 | superp->first = swap_32(superp->first); |
---|
| 766 | superp->last = swap_32(superp->last); |
---|
| 767 | superp->lowest = swap_32(superp->lowest); |
---|
| 768 | superp->highest = swap_32(superp->highest); |
---|
| 769 | superp->highest_chain = swap_32(superp->highest_chain); |
---|
| 770 | superp->date_created = swap_32(superp->date_created); |
---|
| 771 | superp->date_modified = swap_32(superp->date_modified); |
---|
| 772 | superp->long_name_addr = swap_32(superp->long_name_addr); |
---|
| 773 | superp->chairman_addr = swap_32(superp->chairman_addr); |
---|
| 774 | superp->long_name_len = swap_16(superp->long_name_len); |
---|
| 775 | superp->chairman_len = swap_16(superp->chairman_len); |
---|
| 776 | superp->flags = swap_16(superp->flags); |
---|
| 777 | superp->chain_start = swap_32(superp->chain_start); |
---|
| 778 | superp->high_water = swap_32(superp->high_water); |
---|
| 779 | superp->trn_fsize = swap_32(superp->trn_fsize); |
---|
| 780 | superp->highest_trn_addr = swap_32(superp->highest_trn_addr); |
---|
| 781 | } |
---|
| 782 | |
---|
| 783 | swap_chain(cbp) |
---|
| 784 | chain_blk *cbp; |
---|
| 785 | { |
---|
| 786 | cbp->version = swap_32(cbp->version); |
---|
| 787 | cbp->unique = swap_32(cbp->unique); |
---|
| 788 | cbp->current = swap_32(cbp->current); |
---|
| 789 | cbp->prev = swap_32(cbp->prev); |
---|
| 790 | cbp->next = swap_32(cbp->next); |
---|
| 791 | cbp->pref = swap_32(cbp->pref); |
---|
| 792 | cbp->nref = swap_32(cbp->nref); |
---|
| 793 | cbp->trn_chain = swap_32(cbp->trn_chain); |
---|
| 794 | cbp->trn_addr = swap_32(cbp->trn_addr); |
---|
| 795 | cbp->flags = swap_16(cbp->flags); |
---|
| 796 | cbp->filler = swap_16(cbp->filler); |
---|
| 797 | cbp->chain_fref = swap_32(cbp->chain_fref); |
---|
| 798 | cbp->chain_lref = swap_32(cbp->chain_lref); |
---|
| 799 | } |
---|
| 800 | |
---|
| 801 | swap_trn_base(tbp) |
---|
| 802 | trn_base *tbp; |
---|
| 803 | { |
---|
| 804 | tbp->version = swap_32(tbp->version); |
---|
| 805 | tbp->unique = swap_32(tbp->unique); |
---|
| 806 | tbp->date_created = swap_32(tbp->date_created); |
---|
| 807 | tbp->long_name_addr = swap_32(tbp->long_name_addr); |
---|
| 808 | tbp->chairman_addr = swap_32(tbp->chairman_addr); |
---|
| 809 | tbp->long_name_len = swap_16(tbp->long_name_len); |
---|
| 810 | tbp->chairman_len = swap_16(tbp->chairman_len); |
---|
| 811 | tbp->public_flag = swap_16(tbp->public_flag); |
---|
| 812 | } |
---|
| 813 | |
---|
| 814 | swap_trn(thp) |
---|
| 815 | trn_hdr *thp; |
---|
| 816 | { |
---|
| 817 | thp->version = swap_32(thp->version); |
---|
| 818 | thp->unique = swap_32(thp->unique); |
---|
| 819 | thp->current = swap_32(thp->current); |
---|
| 820 | thp->orig_pref = swap_32(thp->orig_pref); |
---|
| 821 | thp->date_entered = swap_32(thp->date_entered); |
---|
| 822 | thp->num_lines = swap_32(thp->num_lines); |
---|
| 823 | thp->num_chars = swap_32(thp->num_chars); |
---|
| 824 | thp->prev_trn = swap_32(thp->prev_trn); |
---|
| 825 | thp->subject_addr = swap_32(thp->subject_addr); |
---|
| 826 | thp->author_addr = swap_32(thp->author_addr); |
---|
| 827 | thp->text_addr = swap_32(thp->text_addr); |
---|
| 828 | thp->subject_len = swap_16(thp->subject_len); |
---|
| 829 | thp->author_len = swap_16(thp->author_len); |
---|
| 830 | } |
---|