|
|
1.1 ! root 1: /* ftamd-select.c - FTAM responder -- selection regime */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/ftam2/RCS/ftamd-select.c,v 7.1 90/07/01 21:03:20 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/ftam2/RCS/ftamd-select.c,v 7.1 90/07/01 21:03:20 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: ftamd-select.c,v $ ! 12: * Revision 7.1 90/07/01 21:03:20 mrose ! 13: * pepsy ! 14: * ! 15: * Revision 7.0 89/11/23 21:54:29 mrose ! 16: * Release 6.0 ! 17: * ! 18: */ ! 19: ! 20: /* ! 21: * NOTICE ! 22: * ! 23: * Acquisition, use, and distribution of this module and related ! 24: * materials are subject to the restrictions of a license agreement. ! 25: * Consult the Preface in the User's Manual for the full terms of ! 26: * this agreement. ! 27: * ! 28: */ ! 29: ! 30: ! 31: #include <grp.h> ! 32: #include <stdio.h> ! 33: #include <pwd.h> ! 34: #include "ftamsystem.h" ! 35: ! 36: ! 37: #define NUID 400 ! 38: #define NGID 400 ! 39: ! 40: ! 41: #define FA_CHATTR \ ! 42: (FA_FILENAME | FA_ACCOUNT) ! 43: ! 44: ! 45: #define FA_PERM_WRITE (FA_PERM_INSERT | FA_PERM_REPLACE | FA_PERM_EXTEND \ ! 46: | FA_PERM_ERASE) ! 47: #define FA_PERM_OWNER FA_PERM_CHNGATTR ! 48: #define FA_PERM_PARENT FA_PERM_DELETE ! 49: ! 50: ! 51: #ifdef SYS5 ! 52: struct group *getgrnam (); ! 53: struct passwd *getpwnam (), *getpwent (), *getpwuid (); ! 54: #endif ! 55: ! 56: /* DATA */ ! 57: ! 58: static char mvfile[MAXPATHLEN]; ! 59: static PE rdparam = NULLPE; ! 60: ! 61: char *getfile (); ! 62: #ifdef BRIDGE ! 63: #define E_OK R_OK ! 64: #else ! 65: char *getuser (), *getgroup (); ! 66: #endif ! 67: ! 68: ! 69: long lseek (); ! 70: ! 71: #ifdef SYS5 ! 72: #define EACCESS access ! 73: ! 74: #define rename(f1,f2) \ ! 75: (unlink (f2), link (f1, f2) != NOTOK ? unlink (f1) : NOTOK) ! 76: #endif ! 77: ! 78: #ifdef BRIDGE ! 79: #define ftp_access(file,mode) ftp_exist (file) ! 80: #endif ! 81: ! 82: /* SELECTION REGIME */ ! 83: ! 84: int ftam_selection (ftg, ftm) ! 85: register struct FTAMgroup *ftg, ! 86: *ftm; ! 87: { ! 88: int action, ! 89: state; ! 90: ! 91: bzero ((char *) ftm, sizeof *ftm); ! 92: ftm -> ftg_flags = ftg -> ftg_flags; ! 93: ! 94: statok = 0; ! 95: ! 96: state = FSTATE_SUCCESS; ! 97: if (ftg -> ftg_flags & FTG_SELECT) { ! 98: register struct FTAMselect *ftse = &ftg -> ftg_select; ! 99: register struct FTAMattributes *fa = &ftse -> ftse_attrs; ! 100: struct FTAMdiagnostic *dp = ftm -> ftg_select.ftse_diags; ! 101: ! 102: errno = 0; ! 103: if (!(fa -> fa_present & FA_FILENAME) ! 104: || fa -> fa_nfile != 1 ! 105: || (myfile = getfile (fa -> fa_files[0])) == NULL ! 106: #ifdef BRIDGE ! 107: || ftp_access (myfile, E_OK) == NOTOK) { ! 108: #else ! 109: || stat (myfile, &myst) == NOTOK) { ! 110: #endif ! 111: dp -> ftd_type = DIAG_PERM; ! 112: dp -> ftd_identifier = FS_SEL_FILENAME; ! 113: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 114: dp -> ftd_delay = DIAG_NODELAY; ! 115: if (errno) { ! 116: (void) strcpy (dp -> ftd_data, sys_errname (errno)); ! 117: dp -> ftd_cc = strlen (dp -> ftd_data); ! 118: } ! 119: else ! 120: dp -> ftd_cc = 0; ! 121: dp++; ! 122: ! 123: state = FSTATE_FAILURE; ! 124: goto done_select; ! 125: } ! 126: statok = 1; ! 127: #ifndef BRIDGE ! 128: switch (myst.st_mode & S_IFMT) { ! 129: case S_IFREG: ! 130: case S_IFDIR: ! 131: break; ! 132: ! 133: default: ! 134: if (myst.st_dev == null_dev && myst.st_ino == null_ino) { ! 135: myst.st_mode &= ~S_IFMT, myst.st_mode |= S_IFREG; ! 136: break; ! 137: } ! 138: dp -> ftd_type = DIAG_PERM; ! 139: dp -> ftd_identifier = FS_SEL_AVAIL; ! 140: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 141: dp -> ftd_delay = DIAG_NODELAY; ! 142: dp -> ftd_cc = 0; ! 143: dp++; ! 144: ! 145: state = FSTATE_FAILURE; ! 146: goto done_select; ! 147: } ! 148: #else ! 149: /* can't check a file you don't have */ ! 150: #endif ! 151: ! 152: if (ftg -> ftg_flags & FTG_RDATTR) ! 153: ftse -> ftse_access |= FA_PERM_READATTR; ! 154: if (ftg -> ftg_flags & FTG_CHATTR) ! 155: ftse -> ftse_access |= FA_PERM_CHNGATTR; ! 156: if (ftg -> ftg_flags & FTG_DELETE) ! 157: ftse -> ftse_access |= FA_PERM_DELETE; ! 158: if (chkaccess (NOTOK, ftse -> ftse_access, &ftse -> ftse_conctl, &dp) ! 159: == NOTOK) { ! 160: state = FSTATE_FAILURE; ! 161: goto done_select; ! 162: } ! 163: #ifndef BRIDGE ! 164: if (ftse -> ftse_account) { ! 165: if ((mygid = findgid (ftse -> ftse_account)) == NOTOK) { ! 166: dp -> ftd_type = DIAG_PERM; ! 167: dp -> ftd_identifier = FS_SEL_ACCOUNT; ! 168: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; ! 169: dp -> ftd_delay = DIAG_NODELAY; ! 170: dp -> ftd_cc = 0; ! 171: dp++; ! 172: ! 173: state = FSTATE_FAILURE; ! 174: goto done_select; ! 175: } ! 176: } ! 177: else ! 178: #else ! 179: /* no account checking */ ! 180: #endif ! 181: mygid = NOTOK; ! 182: ! 183: done_select: ; ! 184: myaccess = ftse -> ftse_access; ! 185: ftm -> ftg_select.ftse_state = state; ! 186: ftm -> ftg_select.ftse_ndiag = dp - ftm -> ftg_select.ftse_diags; ! 187: } ! 188: ! 189: if (ftg -> ftg_flags & FTG_CREATE) { ! 190: register struct FTAMcreate *ftce = &ftg -> ftg_create; ! 191: register struct FTAMattributes *fa = &ftce -> ftce_attrs; ! 192: struct FTAMdiagnostic *dp = ftm -> ftg_create.ftce_diags; ! 193: register struct vfsmap *vf; ! 194: ! 195: if (!(fa -> fa_present & FA_FILENAME) ! 196: || fa -> fa_nfile != 1 ! 197: || (myfile = getfile (fa -> fa_files[0])) == NULL) { ! 198: dp -> ftd_type = DIAG_PERM; ! 199: dp -> ftd_identifier = FS_SEL_FILENAME; ! 200: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 201: dp -> ftd_delay = DIAG_NODELAY; ! 202: dp -> ftd_cc = 0; ! 203: dp++; ! 204: ! 205: state = FSTATE_FAILURE; ! 206: goto done_create; ! 207: } ! 208: #ifdef BRIDGE ! 209: if (ftp_access (myfile, E_OK) != NOTOK) ! 210: #else ! 211: if (stat (myfile, &myst) != NOTOK) ! 212: #endif ! 213: statok = 1; ! 214: if (statok) { ! 215: #ifndef BRIDGE /* Assume file type allow corrective action */ ! 216: switch (myst.st_mode & S_IFMT) { ! 217: case S_IFREG: ! 218: break; ! 219: ! 220: case S_IFDIR: ! 221: switch (ftce -> ftce_override) { ! 222: case FOVER_WRITE: ! 223: dp -> ftd_type = DIAG_PERM; ! 224: dp -> ftd_identifier = FS_SEL_CRELOSE; ! 225: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 226: dp -> ftd_delay = DIAG_NODELAY; ! 227: dp -> ftd_cc = 0; ! 228: dp++; ! 229: ! 230: state = FSTATE_FAILURE; ! 231: goto done_create; ! 232: ! 233: default: ! 234: break; ! 235: } ! 236: break; ! 237: ! 238: default: ! 239: if (myst.st_dev == null_dev && myst.st_ino == null_ino) { ! 240: myst.st_mode &= ~S_IFMT, myst.st_mode |= S_IFREG; ! 241: break; ! 242: } ! 243: dp -> ftd_type = DIAG_PERM; ! 244: dp -> ftd_identifier = FS_SEL_AVAIL; ! 245: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 246: dp -> ftd_delay = DIAG_NODELAY; ! 247: dp -> ftd_cc = 0; ! 248: dp++; ! 249: ! 250: state = FSTATE_FAILURE; ! 251: goto done_create; ! 252: } ! 253: #endif ! 254: switch (ftce -> ftce_override) { ! 255: case FOVER_FAIL: ! 256: dp -> ftd_type = DIAG_PERM; ! 257: dp -> ftd_identifier = FS_SEL_EXISTS; ! 258: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 259: dp -> ftd_delay = DIAG_NODELAY; ! 260: dp -> ftd_cc = 0; ! 261: dp++; ! 262: ! 263: state = FSTATE_FAILURE; ! 264: goto done_create; ! 265: ! 266: case FOVER_SELECT: ! 267: if (ftg -> ftg_flags & FTG_RDATTR) ! 268: ftce -> ftce_access |= FA_PERM_READATTR; ! 269: if (ftg -> ftg_flags & FTG_CHATTR) ! 270: ftce -> ftce_access |= FA_PERM_CHNGATTR; ! 271: if (ftg -> ftg_flags & FTG_DELETE) ! 272: ftce -> ftce_access |= FA_PERM_DELETE; ! 273: if (chkaccess (NOTOK, ftce -> ftce_access, ! 274: &ftce -> ftce_conctl, &dp) == NOTOK) { ! 275: state = FSTATE_FAILURE; ! 276: goto done_create; ! 277: } ! 278: break; ! 279: ! 280: default: ! 281: break; ! 282: } ! 283: } ! 284: ! 285: for (vf = vfs; vf -> vf_entry; vf++) ! 286: if (vf -> vf_oid ! 287: && oid_cmp (vf -> vf_oid, fa -> fa_contents) == 0) ! 288: break; ! 289: if (!vf -> vf_entry) { ! 290: (void) sprintf (dp -> ftd_data, ! 291: "invalid contents-type %s", ! 292: sprintoid (fa -> fa_contents)); ! 293: dp -> ftd_cc = strlen (dp -> ftd_data); ! 294: dp -> ftd_type = DIAG_PERM; ! 295: dp -> ftd_identifier = FS_SEL_ATRVALUE; ! 296: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; ! 297: dp -> ftd_delay = DIAG_NODELAY; ! 298: dp++; ! 299: ! 300: state = FSTATE_FAILURE; ! 301: goto done_create; ! 302: } ! 303: ! 304: if (chkattrs (fa, fa -> fa_present & ~(FA_FILENAME | FA_CONTENTS), ! 305: 1, &dp) == NOTOK) { ! 306: state = FSTATE_FAILURE; ! 307: goto done_create; ! 308: } ! 309: ! 310: #ifndef BRIDGE /* no account checking */ ! 311: if (ftce -> ftce_account) { ! 312: if ((mygid = findgid (ftce -> ftce_account)) == NOTOK) { ! 313: dp -> ftd_type = DIAG_PERM; ! 314: dp -> ftd_identifier = FS_SEL_ACCOUNT; ! 315: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; ! 316: dp -> ftd_delay = DIAG_NODELAY; ! 317: dp -> ftd_cc = 0; ! 318: dp++; ! 319: ! 320: state = FSTATE_FAILURE; ! 321: goto done_create; ! 322: } ! 323: } ! 324: else ! 325: #endif ! 326: mygid = NOTOK; ! 327: ! 328: done_create: ; ! 329: ftm -> ftg_create.ftce_state = state; ! 330: ftm -> ftg_create.ftce_ndiag = dp - ftm -> ftg_create.ftce_diags; ! 331: } ! 332: ! 333: if (ftg -> ftg_flags & FTG_RDATTR) ! 334: ftm -> ftg_readattr.ftra_action = FACTION_SUCCESS; ! 335: ! 336: if (ftg -> ftg_flags & FTG_CHATTR) { ! 337: register struct FTAMchngattr *ftca = &ftg -> ftg_chngattr; ! 338: register struct FTAMattributes *fa = &ftca -> ftca_attrs; ! 339: struct FTAMdiagnostic *dp = ftm -> ftg_chngattr.ftca_diags; ! 340: ! 341: if (chkattrs (fa, fa -> fa_present, 0, &dp) == NOTOK) ! 342: action = FACTION_PERM; ! 343: else ! 344: action = FACTION_SUCCESS; ! 345: ! 346: ftm -> ftg_chngattr.ftca_action = action; ! 347: ftm -> ftg_chngattr.ftca_ndiag = dp - ftm -> ftg_chngattr.ftca_diags; ! 348: } ! 349: ! 350: if (ftg -> ftg_flags & FTG_OPEN) { ! 351: register struct FTAMopen *ftop = &ftm -> ftg_open; ! 352: ! 353: ftop -> ftop_state = FSTATE_FAILURE; ! 354: ftop -> ftop_action = FACTION_SUCCESS; ! 355: if (ftop -> ftop_contents = ftg -> ftg_open.ftop_contents) ! 356: ftop -> ftop_parameter = ftg -> ftg_open.ftop_parameter; ! 357: ! 358: FCINIT (&ftop -> ftop_conctl); ! 359: } ! 360: ! 361: if (ftg -> ftg_flags & FTG_CLOSE) ! 362: ftm -> ftg_close.ftcl_action = FACTION_SUCCESS; ! 363: ! 364: if (ftg -> ftg_flags & FTG_DESELECT) ! 365: ftm -> ftg_deselect.ftde_action = FACTION_SUCCESS; ! 366: ! 367: if (ftg -> ftg_flags & FTG_DELETE) ! 368: ftm -> ftg_delete.ftxe_action = FACTION_SUCCESS; ! 369: ! 370: if (ftg -> ftg_flags & FTG_SELECT) { ! 371: register struct FTAMselect *ftse = &ftm -> ftg_select; ! 372: register struct FTAMattributes *fa = &ftse -> ftse_attrs; ! 373: ! 374: if (state != FSTATE_SUCCESS) { ! 375: ftse -> ftse_action = FACTION_PERM; ! 376: *fa = ftg -> ftg_select.ftse_attrs; /* struct copy */ ! 377: ftm -> ftg_flags &= ~(FTG_RDATTR | FTG_CHATTR | FTG_OPEN); ! 378: return; ! 379: } ! 380: ftse -> ftse_action = FACTION_SUCCESS; ! 381: fa -> fa_present = FA_FILENAME; ! 382: fa -> fa_nfile = 0; ! 383: fa -> fa_files[fa -> fa_nfile++] = myfile; ! 384: } ! 385: ! 386: if (ftg -> ftg_flags & FTG_CREATE) { ! 387: register struct FTAMattributes *fa = &ftg -> ftg_create.ftce_attrs; ! 388: register struct FTAMcreate *ftce = &ftm -> ftg_create; ! 389: struct FTAMdiagnostic *dp = ftce -> ftce_diags + ftce -> ftce_ndiag; ! 390: ! 391: if (state != FSTATE_SUCCESS) { ! 392: ftce -> ftce_action = FACTION_PERM; ! 393: ftce -> ftce_attrs = *fa; /* struct copy */ ! 394: ftm -> ftg_flags &= ~(FTG_RDATTR | FTG_CHATTR | FTG_OPEN); ! 395: return; ! 396: } ! 397: switch (ftg -> ftg_create.ftce_override) { ! 398: case FOVER_SELECT: ! 399: default: ! 400: if (statok) ! 401: break; ! 402: goto do_create; ! 403: ! 404: case FOVER_DELETE: ! 405: #ifdef BRIDGE ! 406: if (statok && ftp_delete (myfile) == NOTOK) { ! 407: #else ! 408: if (statok ! 409: && ((myst.st_mode & S_IFMT) == S_IFREG ! 410: ? unlink (myfile) ! 411: : rmdir (myfile)) == NOTOK) { ! 412: bad_override: ; ! 413: #endif ! 414: dp -> ftd_type = DIAG_PERM; ! 415: dp -> ftd_identifier = FS_SEL_CRELOSE; ! 416: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 417: dp -> ftd_delay = DIAG_NODELAY; ! 418: #ifdef BRIDGE ! 419: (void) strcpy (dp -> ftd_data, ftp_error); ! 420: #else ! 421: (void) strcpy (dp -> ftd_data, sys_errname (errno)); ! 422: #endif ! 423: dp -> ftd_cc = strlen (dp -> ftd_data); ! 424: dp++; ! 425: ! 426: bad_create: ; ! 427: ftce -> ftce_action = FACTION_PERM; ! 428: ftce -> ftce_attrs = *fa; /* struct copy */ ! 429: ftce -> ftce_ndiag = dp - ftce -> ftce_diags; ! 430: ! 431: ftce -> ftce_state = FSTATE_FAILURE; ! 432: ftm -> ftg_flags &= ~(FTG_RDATTR | FTG_CHATTR | FTG_OPEN); ! 433: return; ! 434: } ! 435: /* else fall */ ! 436: ! 437: case FOVER_FAIL: ! 438: statok = 0; ! 439: do_create: ; ! 440: if (!(fa -> fa_present & FA_CONTENTS) ! 441: || oid_cmp (vfs[VFS_FDF].vf_oid, fa -> fa_contents)) { ! 442: #ifdef BRIDGE ! 443: if (ftp_create (myfile) == NOTOK) { ! 444: #else ! 445: if ((myfd = open (myfile, O_RDWR | O_CREAT | O_TRUNC, ! 446: 0666)) == NOTOK) { ! 447: #endif ! 448: bad_open: ; ! 449: dp -> ftd_type = DIAG_PERM; ! 450: dp -> ftd_identifier = FS_SEL_CREATE; ! 451: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 452: dp -> ftd_delay = DIAG_NODELAY; ! 453: (void) strcpy (dp -> ftd_data, sys_errname (errno)); ! 454: dp -> ftd_cc = strlen (dp -> ftd_data); ! 455: dp++; ! 456: ! 457: goto bad_create; ! 458: } ! 459: } ! 460: else ! 461: #ifdef BRIDGE ! 462: if (ftp_mkdir (myfile) == NOTOK) ! 463: #else ! 464: if (mkdir (myfile, 0755) == NOTOK) ! 465: #endif ! 466: goto bad_open; ! 467: if (chngattrs (fa -> fa_present ! 468: & ~(FA_FILENAME | FA_CONTENTS), fa, &dp) == NOTOK) ! 469: goto bad_create; ! 470: break; ! 471: ! 472: case FOVER_WRITE: ! 473: if (!statok) ! 474: goto do_create; ! 475: #ifndef BRIDGE ! 476: #ifdef SUNOS4 ! 477: if (myst.st_size > 0 && truncate (myfile, (off_t) 0) == NOTOK) ! 478: goto bad_override; ! 479: #else ! 480: if (myst.st_size > 0 && truncate (myfile, 0) == NOTOK) ! 481: goto bad_override; ! 482: #endif ! 483: #endif ! 484: break; ! 485: } ! 486: ! 487: ftce -> ftce_action = FACTION_SUCCESS; ! 488: (void) readattrs (FA_FILENAME | FA_ACTIONS | FA_CONTENTS, ! 489: &ftce -> ftce_attrs, fa -> fa_contents, ! 490: fa -> fa_parameter, myfile, &myst, &dp); ! 491: if (fa -> fa_present & FA_ACTIONS) ! 492: ftce -> ftce_attrs.fa_permitted &= fa -> fa_permitted; ! 493: ftce -> ftce_ndiag = dp - ftce -> ftce_diags; ! 494: } ! 495: ! 496: if (ftg -> ftg_flags & FTG_RDATTR ! 497: && (ftm -> ftg_readattr.ftra_action == FACTION_SUCCESS)) { ! 498: register struct FTAMreadattr *ftra = &ftm -> ftg_readattr; ! 499: struct FTAMdiagnostic *dp = ftra -> ftra_diags + ftra -> ftra_ndiag; ! 500: ! 501: if (!statok) { ! 502: #ifdef BRIDGE ! 503: if (0) { /* assume OK */ ! 504: #else ! 505: if ((myfd != NOTOK ? fstat (myfd, &myst) ! 506: : stat (myfile, &myst)) == NOTOK) { ! 507: dp -> ftd_type = DIAG_PERM; ! 508: dp -> ftd_identifier = FS_MGT_READ; ! 509: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 510: dp -> ftd_delay = DIAG_NODELAY; ! 511: dp -> ftd_cc = 0; ! 512: dp++; ! 513: #endif ! 514: ! 515: bad_readattr: ; ! 516: ftra -> ftra_action = FACTION_PERM; ! 517: ftra -> ftra_ndiag = dp - ftra -> ftra_diags; ! 518: return; ! 519: } ! 520: else ! 521: statok++; ! 522: } ! 523: if (readattrs (ftg -> ftg_readattr.ftra_attrnames, ! 524: &ftra -> ftra_attrs, ftg -> ftg_flags & FTG_OPEN ! 525: ? ftg -> ftg_open.ftop_contents : NULLOID, NULLPE, ! 526: myfile, &myst, &dp) == NOTOK) ! 527: goto bad_readattr; ! 528: ftra -> ftra_ndiag = dp - ftra -> ftra_diags; ! 529: } ! 530: ! 531: if (ftg -> ftg_flags & FTG_CHATTR ! 532: && (ftm -> ftg_chngattr.ftca_action == FACTION_SUCCESS)) { ! 533: register struct FTAMchngattr *ftca = &ftm -> ftg_chngattr; ! 534: register struct FTAMattributes *fa = &ftg -> ftg_chngattr.ftca_attrs; ! 535: struct FTAMdiagnostic *dp = ftca -> ftca_diags + ftca -> ftca_ndiag; ! 536: ! 537: if (chngattrs (fa -> fa_present, fa, &dp) == NOTOK) { ! 538: ftca -> ftca_action = FACTION_PERM; ! 539: ftca -> ftca_ndiag = dp - ftca -> ftca_diags; ! 540: return; ! 541: } ! 542: ! 543: ftca -> ftca_ndiag = dp - ftca -> ftca_diags; ! 544: } ! 545: ! 546: if (ftg -> ftg_flags & FTG_OPEN) { ! 547: #ifndef BRIDGE ! 548: int mode; ! 549: #endif ! 550: register struct FTAMopen *ftop = &ftm -> ftg_open; ! 551: struct FTAMdiagnostic *dp = ftop -> ftop_diags + ftop -> ftop_ndiag; ! 552: ! 553: ftop -> ftop_state = FSTATE_SUCCESS; ! 554: if (statok == 0) { ! 555: if (stat (myfile, &myst) == NOTOK) { ! 556: #ifndef BRIDGE ! 557: unavailable: ; ! 558: #endif ! 559: dp -> ftd_type = DIAG_PERM; ! 560: dp -> ftd_identifier = FS_SEL_AVAIL; ! 561: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 562: dp -> ftd_delay = DIAG_NODELAY; ! 563: if (errno) { ! 564: (void) strcpy (dp -> ftd_data, sys_errname (errno)); ! 565: dp -> ftd_cc = strlen (dp -> ftd_data); ! 566: } ! 567: else ! 568: dp -> ftd_cc = 0; ! 569: dp++; ! 570: ! 571: ftop -> ftop_state = FSTATE_FAILURE; ! 572: goto done_open; ! 573: } ! 574: else ! 575: statok = 1; ! 576: } ! 577: ! 578: if (ftop -> ftop_contents == NULL) { ! 579: register struct FTAMattributes *fa; ! 580: ! 581: if (ftg -> ftg_flags & FTG_CREATE) { ! 582: fa = &ftg -> ftg_create.ftce_attrs; ! 583: ! 584: ftop -> ftop_contents = fa -> fa_contents; ! 585: ftop -> ftop_parameter = fa -> fa_parameter; ! 586: advise (LLOG_DEBUG, NULLCP, ! 587: "using contents-type from CREATE <%s, 0x%x>", ! 588: oid2ode (ftop -> ftop_contents), ! 589: ftop -> ftop_parameter); ! 590: goto find_myvfs; ! 591: } ! 592: ! 593: if ((ftg -> ftg_flags & FTG_RDATTR) ! 594: && ftm -> ftg_readattr.ftra_action == FACTION_SUCCESS ! 595: && ((fa = &ftm -> ftg_readattr.ftra_attrs) -> fa_present ! 596: & FA_CONTENTS)) { ! 597: ftop -> ftop_contents = fa -> fa_contents; ! 598: ftop -> ftop_parameter = fa -> fa_parameter; ! 599: advise (LLOG_DEBUG, NULLCP, ! 600: "using contents-type from READ-ATTRIBUTE <%s, 0x%x>", ! 601: oid2ode (ftop -> ftop_contents), ! 602: ftop -> ftop_parameter); ! 603: ! 604: find_myvfs: ; ! 605: if ((myvf = st2vfs (myfd, myfile, &myst, ftop -> ftop_contents, ! 606: ftamfd)) == NULL) ! 607: goto no_ascertain; ! 608: if (oid_cmp (ftop -> ftop_contents, myvf -> vf_oid) == 0) ! 609: goto find_param; ! 610: advise (LLOG_DEBUG, NULLCP, ! 611: "wrong intuition; back to step one"); ! 612: ftop -> ftop_contents = NULLOID; ! 613: ftop -> ftop_parameter = NULLPE; ! 614: } ! 615: ! 616: if ((myvf = st2vfs (myfd, myfile, &myst, NULLOID, ftamfd)) ! 617: == NULL) { ! 618: no_ascertain: ; ! 619: (void) strcpy (dp -> ftd_data, ! 620: "unable to ascertain contents-type"); ! 621: dp -> ftd_cc = strlen (dp -> ftd_data); ! 622: dp -> ftd_type = DIAG_PERM; ! 623: dp -> ftd_identifier = FS_ACC_LCL; ! 624: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 625: dp -> ftd_delay = DIAG_NODELAY; ! 626: dp++; ! 627: ! 628: ftop -> ftop_state = FSTATE_FAILURE; ! 629: goto done_open; ! 630: } ! 631: ftop -> ftop_contents = myvf -> vf_oid; ! 632: advise (LLOG_DEBUG, NULLCP, ! 633: "using contents-type from st2vfs: %s", ! 634: oid2ode (ftop -> ftop_contents)); ! 635: ! 636: find_param: ; ! 637: if (myvf -> vf_mandatory > 0 && ftop -> ftop_parameter == NULL) { ! 638: char buffer[BUFSIZ]; ! 639: ! 640: if (rdparam) ! 641: pe_free (rdparam), rdparam = NULLPE; ! 642: if (enc_f (myvf -> vf_number, &_ZDOCS_mod, &rdparam, 1, 0, ! 643: NULLCP, myvf -> vf_parameter) == NOTOK) { ! 644: advise (LLOG_EXCEPTIONS, NULLCP, ! 645: "unable to build parameter: %s", PY_pepy); ! 646: if (rdparam) ! 647: pe_free (rdparam), rdparam = NULLPE; ! 648: goto no_ascertain; ! 649: } ! 650: ftop -> ftop_parameter = rdparam; ! 651: ! 652: vpushstr (buffer); ! 653: vunknown (ftop -> ftop_parameter); ! 654: vpopstr (); ! 655: advise (LLOG_DEBUG, NULLCP, ! 656: "generating parameter from vfs: %s", buffer); ! 657: } ! 658: else ! 659: if (!myvf -> vf_mandatory && ftop -> ftop_parameter) ! 660: ftop -> ftop_parameter = NULLPE; ! 661: } ! 662: else ! 663: if ((myvf = st2vfs (myfd, myfile, &myst, ftop -> ftop_contents, ! 664: ftamfd)) == NULL) { ! 665: dp -> ftd_cc = 0; ! 666: bad_param: ; ! 667: dp -> ftd_type = DIAG_PERM; ! 668: dp -> ftd_identifier = FS_ACC_TYPINCON; ! 669: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; ! 670: dp -> ftd_delay = DIAG_NODELAY; ! 671: dp++; ! 672: ! 673: ftop -> ftop_state = FSTATE_FAILURE; ! 674: goto done_open; ! 675: } ! 676: ! 677: if (oid_cmp (ftop -> ftop_contents, myvf -> vf_oid)) { ! 678: advise (LLOG_NOTICE, NULLCP, "simplifying document type"); ! 679: ! 680: ftop -> ftop_contents = myvf -> vf_oid; ! 681: ftop -> ftop_parameter = NULLPE; ! 682: if (myvf -> vf_mandatory) { ! 683: char buffer[BUFSIZ]; ! 684: ! 685: if (rdparam) ! 686: pe_free (rdparam), rdparam = NULLPE; ! 687: if (enc_f (myvf -> vf_number, &_ZDOCS_mod, &rdparam, 1, 0, ! 688: NULLCP, myvf -> vf_parameter) == NOTOK) { ! 689: advise (LLOG_EXCEPTIONS, NULLCP, ! 690: "unable to build parameter: %s", PY_pepy); ! 691: if (rdparam) ! 692: pe_free (rdparam), rdparam = NULLPE; ! 693: goto no_ascertain; ! 694: } ! 695: ftop -> ftop_parameter = rdparam; ! 696: ! 697: vpushstr (buffer); ! 698: vunknown (ftop -> ftop_parameter); ! 699: vpopstr (); ! 700: advise (LLOG_DEBUG, NULLCP, ! 701: "generating parameter from myvf: %s", buffer); ! 702: } ! 703: } ! 704: ! 705: if (ftop -> ftop_parameter) { ! 706: if (myvf -> vf_number < 0) { ! 707: (void) sprintf (dp -> ftd_data, ! 708: "unexpected document type parameter"); ! 709: dp -> ftd_cc = strlen (dp -> ftd_data); ! 710: goto bad_param; ! 711: } ! 712: myparam = NULL; ! 713: if (dec_f (myvf -> vf_number, &_ZDOCS_mod, ftop -> ftop_parameter, ! 714: 1, NULLIP, NULLVP, &myparam) == NOTOK) { ! 715: (void) sprintf (dp -> ftd_data, ! 716: "unable to parse document type parameter: %s", ! 717: PY_pepy); ! 718: dp -> ftd_cc = strlen (dp -> ftd_data); ! 719: goto bad_param; ! 720: } ! 721: if (myvf -> vf_check ! 722: && (*myvf -> vf_check) (myparam, dp -> ftd_data) ! 723: == NOTOK) ! 724: goto bad_param; ! 725: } ! 726: else ! 727: if (myvf -> vf_mandatory > 0) { ! 728: (void) strcpy (dp -> ftd_data, ! 729: "mandatory document type parameter missing"); ! 730: dp -> ftd_cc = strlen (dp -> ftd_data); ! 731: goto bad_param; ! 732: } ! 733: ! 734: mymode = ftg -> ftg_open.ftop_mode; ! 735: #ifndef BRIDGE ! 736: if (mymode & FA_PERM_WRITE) ! 737: mode = (mymode & FA_PERM_READ) ? O_RDWR : O_WRONLY; ! 738: else ! 739: mode = O_RDONLY; ! 740: #endif ! 741: ! 742: errno = 0; ! 743: #ifndef BRIDGE ! 744: switch (myst.st_mode & S_IFMT) { ! 745: case S_IFREG: ! 746: if (myfd == NOTOK && (myfd = open (myfile, mode)) == NOTOK) ! 747: goto unavailable; ! 748: break; ! 749: ! 750: case S_IFDIR: ! 751: if (mode == O_RDONLY) ! 752: break; ! 753: /* else fall */ ! 754: ! 755: default: ! 756: goto unavailable; ! 757: } ! 758: #endif ! 759: ! 760: myconctl = ftg -> ftg_open.ftop_conctl; /* struct copy */ ! 761: ftm -> ftg_open.ftop_conctl = myconctl; /* .. */ ! 762: mylockstyle = ftg -> ftg_open.ftop_locking; ! 763: ! 764: if (chkaccess (myfd, mymode, &myconctl, &dp) == NOTOK) { ! 765: ftop -> ftop_state = FSTATE_FAILURE; ! 766: goto done_open; ! 767: } ! 768: ! 769: done_open: ; ! 770: ftop -> ftop_ndiag = dp - ftop -> ftop_diags; ! 771: ! 772: if (ftop -> ftop_state != FSTATE_SUCCESS) { ! 773: ftop -> ftop_action = FACTION_PERM; ! 774: return; ! 775: } ! 776: } ! 777: ! 778: if (ftg -> ftg_flags & FTG_CLOSE ! 779: && (ftm -> ftg_close.ftcl_action == FACTION_SUCCESS)) { ! 780: if (myfd != NOTOK) { ! 781: #ifdef BRIDGE ! 782: (void) close (myfd); ! 783: (void) ftp_reply (); ! 784: #else ! 785: unlock (); ! 786: (void) close (myfd); ! 787: #endif ! 788: myfd = NOTOK; ! 789: } ! 790: if (myvf && myparam) { ! 791: fre_obj (myparam, _ZDOCS_mod.md_dtab[myvf -> vf_number], ! 792: &_ZDOCS_mod); ! 793: myparam = NULL; ! 794: } ! 795: } ! 796: ! 797: if (ftg -> ftg_flags & FTG_DESELECT) { ! 798: register struct FTAMdeselect *ftde = &ftm -> ftg_deselect; ! 799: ! 800: if (ftde -> ftde_action == FACTION_SUCCESS) { ! 801: /* anything to charge if (mygid != NOTOK)? ha! */ ! 802: } ! 803: } ! 804: ! 805: if (ftg -> ftg_flags & FTG_DELETE) { ! 806: register struct FTAMdelete *ftxe = &ftm -> ftg_delete; ! 807: struct FTAMdiagnostic *dp = ftxe -> ftxe_diags + ftxe -> ftxe_ndiag; ! 808: ! 809: if (ftxe -> ftxe_action == FACTION_SUCCESS) { ! 810: #ifdef BRIDGE ! 811: if (ftp_delete (myfile) == NOTOK) { ! 812: #else ! 813: if (!statok && stat (myfile, &myst) == NOTOK) ! 814: myst.st_mode = S_IFREG; ! 815: if (((myst.st_mode & S_IFMT) == S_IFREG ? unlink (myfile) ! 816: : rmdir (myfile)) ! 817: == NOTOK) { ! 818: #endif ! 819: dp -> ftd_type = DIAG_PERM; ! 820: dp -> ftd_identifier = FS_SEL_DELETE; ! 821: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 822: dp -> ftd_delay = DIAG_NODELAY; ! 823: #ifdef BRIDGE ! 824: (void) strcpy (dp -> ftd_data, ftp_error); ! 825: #else ! 826: (void) strcpy (dp -> ftd_data, sys_errname (errno)); ! 827: #endif ! 828: dp -> ftd_cc = strlen (dp -> ftd_data); ! 829: dp++; ! 830: ! 831: ftxe -> ftxe_action = FACTION_PERM; ! 832: ftxe -> ftxe_ndiag = dp - ftxe -> ftxe_diags; ! 833: return; ! 834: } ! 835: advise (LLOG_NOTICE, NULLCP, "delete %s", myfile); ! 836: } ! 837: } ! 838: } ! 839: ! 840: /* */ ! 841: ! 842: #ifdef BRIDGE ! 843: /* ARGSUSED */ ! 844: #endif ! 845: ! 846: static int chkaccess (fd, request, fc, diags) ! 847: int fd, ! 848: request; ! 849: #ifndef BRIDGE ! 850: register ! 851: #endif ! 852: struct FTAMconcurrency *fc; ! 853: register struct FTAMdiagnostic **diags; ! 854: { ! 855: int result; ! 856: #ifndef BRIDGE ! 857: register char *cp; ! 858: #endif ! 859: register struct FTAMdiagnostic *dp = *diags; ! 860: ! 861: result = OK; ! 862: ! 863: #ifndef BRIDGE ! 864: if (((request & FA_PERM_READ) && EACCESS (myfile, R_OK) == NOTOK) ! 865: || ((request & FA_PERM_WRITE) && EACCESS (myfile, W_OK) == NOTOK) ! 866: || ((request & FA_PERM_OWNER) ! 867: && (myuid != myst.st_uid && myuid != 0))) { ! 868: no_access: ; ! 869: dp -> ftd_type = DIAG_PERM; ! 870: dp -> ftd_identifier = FS_SEL_ACCAVAIL; ! 871: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 872: dp -> ftd_delay = DIAG_NODELAY; ! 873: dp -> ftd_cc = 0; ! 874: dp++; ! 875: ! 876: result = NOTOK; ! 877: goto out; ! 878: } ! 879: if (request & FA_PERM_PARENT) { ! 880: if (cp = rindex (myfile, '/')) { ! 881: *cp = NULL; ! 882: result = EACCESS (*myfile ? myfile : "/", W_OK); ! 883: *cp = '/'; ! 884: } ! 885: else ! 886: result = EACCESS (".", W_OK); ! 887: ! 888: if (result == NOTOK) ! 889: goto no_access; ! 890: } ! 891: #else ! 892: /* already selected file and know it exists, FTP cannot tell us more */ ! 893: #endif ! 894: ! 895: #ifndef BRIDGE ! 896: out: ; ! 897: ! 898: if (attrs & FATTR_STORAGE) { ! 899: if (fd == NOTOK) { ! 900: mylock = 0; ! 901: ! 902: if (((request & FA_PERM_READATTR) ! 903: && (fc -> fc_readattrlock & FLOCK_RESTRICT)) ! 904: || ((request & FA_PERM_CHNGATTR) ! 905: && (fc -> fc_chngattrlock & FLOCK_RESTRICT)) ! 906: || ((request & FA_PERM_DELETE) ! 907: && (fc -> fc_deletelock & FLOCK_RESTRICT))) { ! 908: dp -> ftd_type = DIAG_PERM; ! 909: dp -> ftd_identifier = FS_SEL_CONSUPRT; ! 910: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 911: dp -> ftd_delay = DIAG_NODELAY; ! 912: dp -> ftd_cc = 0; ! 913: dp++; ! 914: ! 915: result = NOTOK; ! 916: } ! 917: } ! 918: else { ! 919: #ifdef SYS5 ! 920: struct flock fs; ! 921: #endif ! 922: ! 923: if ((request & FA_PERM_WRITE) ! 924: && ((fc -> fc_insertlock & FLOCK_RESTRICT) ! 925: || (fc -> fc_replacelock & FLOCK_RESTRICT) ! 926: || (fc -> fc_eraselock & FLOCK_RESTRICT) ! 927: || (fc -> fc_extendlock & FLOCK_RESTRICT))) { ! 928: mylock = 1; ! 929: #ifndef SYS5 ! 930: if (flock (fd, LOCK_EX) == NOTOK) ! 931: goto bad_concur; ! 932: #else ! 933: fs.l_type = F_WRLCK; ! 934: fs.l_whence = L_SET; ! 935: fs.l_start = fs.l_len = 0; ! 936: if (fcntl (fd, F_SETLKW, &fs) == NOTOK) ! 937: goto bad_concur; ! 938: #endif ! 939: } ! 940: else ! 941: if ((request & FA_PERM_READ) ! 942: && (fc -> fc_readlock & FLOCK_RESTRICT)) { ! 943: mylock = 1; ! 944: #ifndef SYS5 ! 945: if (flock (fd, LOCK_SH) == NOTOK) { ! 946: #else ! 947: fs.l_type = F_RDLCK; ! 948: fs.l_whence = L_SET; ! 949: fs.l_start = fs.l_len = 0; ! 950: if (fcntl (fd, F_SETLKW, &fs) == NOTOK) { ! 951: #endif ! 952: bad_concur: ; ! 953: dp -> ftd_type = DIAG_PERM; ! 954: dp -> ftd_identifier = FS_ACC_CONAVAIL; ! 955: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 956: dp -> ftd_delay = DIAG_NODELAY; ! 957: (void) strcpy (dp -> ftd_data, sys_errname (errno)); ! 958: dp -> ftd_cc = strlen (dp -> ftd_data); ! 959: dp++; ! 960: ! 961: mylock = 0; ! 962: result = NOTOK; ! 963: } ! 964: } ! 965: } ! 966: } ! 967: #endif ! 968: ! 969: *diags = dp; ! 970: return result; ! 971: } ! 972: ! 973: /* */ ! 974: ! 975: static int chkattrs (fa, present, select, diags) ! 976: register struct FTAMattributes *fa; ! 977: long present; ! 978: int select; ! 979: register struct FTAMdiagnostic **diags; ! 980: { ! 981: int id, ! 982: result; ! 983: char *file; ! 984: register struct FTAMdiagnostic *dp = *diags; ! 985: ! 986: result = OK; ! 987: ! 988: present &= ~FA_FUTURESIZE; /* be liberal in what you accept... */ ! 989: if (present & ~(FA_CHATTR | FA_RDATTR)) { ! 990: dp -> ftd_type = DIAG_PERM; ! 991: dp -> ftd_identifier = select ? FS_SEL_INITIAL ! 992: : (present & FA_RDATTR) ? FS_MGT_CHANGE : FS_MGT_EXIST; ! 993: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 994: dp -> ftd_delay = DIAG_NODELAY; ! 995: dp -> ftd_cc = 0; ! 996: dp++; ! 997: ! 998: result = NOTOK; ! 999: } ! 1000: ! 1001: id = select ? FS_SEL_ATRVALUE : FS_MGT_VALUE; ! 1002: ! 1003: if (present & FA_FILENAME) { ! 1004: if (fa -> fa_nfile != 1 ! 1005: || (file = getfile (fa -> fa_files[0])) == NULL) { ! 1006: dp -> ftd_type = DIAG_PERM; ! 1007: dp -> ftd_identifier = id; ! 1008: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; ! 1009: dp -> ftd_delay = DIAG_NODELAY; ! 1010: (void) strcpy (dp -> ftd_data, "00bad filename"); ! 1011: dp -> ftd_cc = strlen (dp -> ftd_data); ! 1012: dp++; ! 1013: ! 1014: result = NOTOK; ! 1015: } ! 1016: else ! 1017: (void) strcpy (mvfile, file); ! 1018: } ! 1019: ! 1020: #ifndef BRIDGE ! 1021: if ((present & FA_ACCOUNT) && findgid (fa -> fa_account) == NOTOK) { ! 1022: dp -> ftd_type = DIAG_PERM; ! 1023: dp -> ftd_identifier = id; ! 1024: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; ! 1025: dp -> ftd_delay = DIAG_NODELAY; ! 1026: (void) strcpy (dp -> ftd_data, "02bad storage account"); ! 1027: dp -> ftd_cc = strlen (dp -> ftd_data); ! 1028: dp++; ! 1029: ! 1030: result = NOTOK; ! 1031: } ! 1032: ! 1033: if ((present & FA_FILESIZE) && fa -> fa_filesize < 0) { ! 1034: dp -> ftd_type = DIAG_PERM; ! 1035: dp -> ftd_identifier = id; ! 1036: dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU; ! 1037: dp -> ftd_delay = DIAG_NODELAY; ! 1038: (void) strcpy (dp -> ftd_data, "13bad filesize"); ! 1039: dp -> ftd_cc = strlen (dp -> ftd_data); ! 1040: dp++; ! 1041: ! 1042: result = NOTOK; ! 1043: } ! 1044: #endif ! 1045: ! 1046: *diags = dp; ! 1047: return result; ! 1048: } ! 1049: ! 1050: /* */ ! 1051: ! 1052: int readattrs (attrnames, fa, proposed, parameter, file, st, diags) ! 1053: int attrnames; ! 1054: register struct FTAMattributes *fa; ! 1055: OID proposed; ! 1056: PE parameter; ! 1057: char *file; ! 1058: struct stat *st; ! 1059: register struct FTAMdiagnostic **diags; ! 1060: { ! 1061: #ifndef BRIDGE ! 1062: int result; ! 1063: char *cp; ! 1064: register struct tm *tm; ! 1065: #endif ! 1066: register struct FTAMdiagnostic *dp = *diags; ! 1067: ! 1068: fa -> fa_present = attrnames; ! 1069: fa -> fa_novalue = attrnames & (FA_SECURITY | FA_PRIVATE); ! 1070: ! 1071: if (attrnames & FA_FILENAME) { ! 1072: fa -> fa_nfile = 0; ! 1073: fa -> fa_files[fa -> fa_nfile++] = file; ! 1074: } ! 1075: ! 1076: if (attrnames & FA_ACTIONS) { ! 1077: fa -> fa_permitted = 0; ! 1078: #ifndef BRIDGE ! 1079: if (EACCESS (file, R_OK) != NOTOK) ! 1080: #endif ! 1081: fa -> fa_permitted |= FA_PERM_READ; ! 1082: ! 1083: #ifndef BRIDGE ! 1084: if (EACCESS (file, W_OK) != NOTOK) ! 1085: #endif ! 1086: fa -> fa_permitted |= FA_PERM_WRITE; ! 1087: ! 1088: if (fa -> fa_permitted & (FA_PERM_READ | FA_PERM_WRITE)) ! 1089: fa -> fa_permitted |= FA_PERM_TRAVERSAL; ! 1090: ! 1091: fa -> fa_permitted |= FA_PERM_READATTR; ! 1092: ! 1093: #ifndef BRIDGE ! 1094: if (myuid == st -> st_uid || myuid == 0) ! 1095: #endif ! 1096: fa -> fa_permitted |= FA_PERM_OWNER; ! 1097: ! 1098: #ifndef BRIDGE ! 1099: if (cp = rindex (file, '/')) { ! 1100: *cp = NULL; ! 1101: result = EACCESS (*file ? file : "/", W_OK); ! 1102: *cp = '/'; ! 1103: } ! 1104: else ! 1105: result = EACCESS (".", W_OK); ! 1106: if (result != NOTOK) ! 1107: #endif ! 1108: fa -> fa_permitted |= FA_PERM_PARENT; ! 1109: } ! 1110: ! 1111: if (attrnames & FA_CONTENTS) { ! 1112: register struct vfsmap *vf; ! 1113: ! 1114: if (vf = st2vfs (myfd, file, st, proposed, ftamfd)) { ! 1115: fa -> fa_contents = vf -> vf_oid; ! 1116: if (proposed ! 1117: && oid_cmp (proposed, vf -> vf_oid) == 0 ! 1118: && parameter ! 1119: && vf -> vf_number >= 0 ! 1120: && vf -> vf_check) { ! 1121: caddr_t p = NULL; ! 1122: ! 1123: if (dec_f (vf -> vf_number, &_ZDOCS_mod, parameter, 1, NULLIP, ! 1124: NULLVP, &p) == NOTOK) { ! 1125: advise (LLOG_NOTICE, NULLCP, ! 1126: "unable to parse document type parameter: %s", ! 1127: PY_pepy); ! 1128: goto bad_param; ! 1129: } ! 1130: if ((*vf -> vf_check) (p, dp -> ftd_data) == NOTOK) { ! 1131: advise (LLOG_NOTICE, NULLCP, ! 1132: "unacceptable document type parameter: %s", ! 1133: dp -> ftd_data); ! 1134: goto bad_param; ! 1135: } ! 1136: fre_obj (p, _ZDOCS_mod.md_dtab[vf -> vf_number], &_ZDOCS_mod); ! 1137: fa -> fa_parameter = parameter; ! 1138: } ! 1139: bad_param: ; ! 1140: ! 1141: if (vf -> vf_parameter) { ! 1142: if (rdparam) ! 1143: pe_free (rdparam), rdparam = NULLPE; ! 1144: ! 1145: if (enc_f (vf -> vf_number, &_ZDOCS_mod, &rdparam, 1, 0, ! 1146: NULLCP, vf -> vf_parameter) == NOTOK) { ! 1147: advise (LLOG_EXCEPTIONS, NULLCP, ! 1148: "unable to build parameter: %s", PY_pepy); ! 1149: if (rdparam) ! 1150: pe_free (rdparam), rdparam = NULLPE; ! 1151: } ! 1152: fa -> fa_parameter = rdparam; ! 1153: } ! 1154: else ! 1155: fa -> fa_parameter = NULLPE; ! 1156: } ! 1157: else ! 1158: fa -> fa_present &= ~FA_CONTENTS; ! 1159: } ! 1160: ! 1161: #ifdef BRIDGE ! 1162: /* these values cannot be obtained from FTP */ ! 1163: if (attrnames & FA_ACCOUNT) ! 1164: #else ! 1165: if ((attrnames & FA_ACCOUNT) ! 1166: && (fa -> fa_account = getgroup (st -> st_gid)) == NULL) ! 1167: #endif ! 1168: fa -> fa_present &= ~FA_ACCOUNT; ! 1169: ! 1170: if (attrnames & FA_DATE_CREATE) ! 1171: #ifndef BRIDGE ! 1172: if (tm = gmtime ((long *) &st -> st_mtime)) ! 1173: tm2ut (tm, &fa -> fa_date_create); ! 1174: else ! 1175: #endif ! 1176: fa -> fa_novalue |= FA_DATE_CREATE; ! 1177: ! 1178: if (attrnames & FA_DATE_MODIFY) ! 1179: #ifndef BRIDGE ! 1180: if (tm = gmtime ((long *) &st -> st_mtime)) ! 1181: tm2ut (tm, &fa -> fa_date_modify); ! 1182: else ! 1183: #endif ! 1184: fa -> fa_novalue |= FA_DATE_MODIFY; ! 1185: ! 1186: if (attrnames & FA_DATE_READ) ! 1187: #ifndef BRIDGE ! 1188: if (tm = gmtime ((long *) &st -> st_atime)) ! 1189: tm2ut (tm, &fa -> fa_date_read); ! 1190: else ! 1191: #endif ! 1192: fa -> fa_novalue |= FA_DATE_READ; ! 1193: ! 1194: if (attrnames & FA_DATE_ATTR) ! 1195: #ifndef BRIDGE ! 1196: if (tm = gmtime ((long *) &st -> st_ctime)) ! 1197: tm2ut (tm, &fa -> fa_date_attribute); ! 1198: else ! 1199: #endif ! 1200: fa -> fa_novalue |= FA_DATE_ATTR; ! 1201: ! 1202: #ifdef BRIDGE ! 1203: if (attrnames & FA_ID_CREATE) ! 1204: #else ! 1205: if ((attrnames & FA_ID_CREATE) ! 1206: && (fa -> fa_id_create = getuser (st -> st_uid)) == NULL) ! 1207: #endif ! 1208: fa -> fa_novalue |= FA_ID_CREATE; ! 1209: ! 1210: #ifdef BRIDGE ! 1211: if (attrnames & FA_ID_MODIFY) ! 1212: #else ! 1213: if ((attrnames & FA_ID_MODIFY) ! 1214: && ((st -> st_mode & 0022) ! 1215: || (fa -> fa_id_modify = getuser (st -> st_uid)) == NULL)) ! 1216: #endif ! 1217: fa -> fa_novalue |= FA_ID_MODIFY; ! 1218: ! 1219: #ifdef BRIDGE ! 1220: if (attrnames & FA_ID_READ) ! 1221: #else ! 1222: if ((attrnames & FA_ID_READ) ! 1223: && ((st -> st_mode & 0044) ! 1224: || (fa -> fa_id_read = getuser (st -> st_uid)) == NULL)) ! 1225: #endif ! 1226: fa -> fa_novalue |= FA_ID_READ; ! 1227: ! 1228: #ifdef BRIDGE ! 1229: if (attrnames & FA_ID_ATTR) ! 1230: #else ! 1231: if ((attrnames & FA_ID_ATTR) ! 1232: && ( (st -> st_mode & 0022) ! 1233: || (fa -> fa_id_attribute = getuser (st -> st_uid)) ! 1234: == NULL)) ! 1235: #endif ! 1236: fa -> fa_novalue |= FA_ID_ATTR; ! 1237: ! 1238: if (attrnames & FA_AVAILABILITY) ! 1239: fa -> fa_availability = FA_AVAIL_IMMED; ! 1240: ! 1241: if (attrnames & FA_FILESIZE) ! 1242: #ifdef BRIDGE ! 1243: fa -> fa_novalue |= FA_FILESIZE; ! 1244: #else ! 1245: fa -> fa_filesize = (int) st -> st_size; ! 1246: #endif ! 1247: ! 1248: if (attrnames & FA_FUTURESIZE) ! 1249: fa -> fa_novalue |= FA_FUTURESIZE; ! 1250: ! 1251: *diags = dp; ! 1252: return OK; ! 1253: } ! 1254: ! 1255: /* */ ! 1256: ! 1257: static int chngattrs (present, fa, diags) ! 1258: long present; ! 1259: register struct FTAMattributes *fa; ! 1260: register struct FTAMdiagnostic **diags; ! 1261: { ! 1262: #ifndef BRIDGE ! 1263: int gid, ! 1264: result; ! 1265: #endif ! 1266: register struct FTAMdiagnostic *dp = *diags; ! 1267: ! 1268: ! 1269: #ifdef BRIDGE ! 1270: statok = 1; ! 1271: #else ! 1272: if ((myfd != NOTOK ? fstat (myfd, &myst) : stat (myfile, &myst)) ! 1273: == NOTOK) { ! 1274: bad_system: ; ! 1275: (void) strcpy (dp -> ftd_data, sys_errname (errno)); ! 1276: dp -> ftd_cc = strlen (dp -> ftd_data); ! 1277: goto no_change; ! 1278: } ! 1279: statok = 1; ! 1280: if (myuid != myst.st_uid && myuid != 0) { ! 1281: errno = EPERM; ! 1282: goto bad_system; ! 1283: } ! 1284: #endif ! 1285: ! 1286: #ifndef BRIDGE ! 1287: if ((present & FA_ACCOUNT) ! 1288: && (gid = findgid (fa -> fa_account)) != NOTOK) { ! 1289: #ifndef SYS5 ! 1290: (void) seteuid (0); ! 1291: result = myfd != NOTOK ? fchown (myfd, -1, gid) ! 1292: : chown (myfile, -1, gid); ! 1293: (void) seteuid (myuid); ! 1294: #else ! 1295: result = chgrp (myfile, gid); ! 1296: #endif ! 1297: ! 1298: if (result == NOTOK) { ! 1299: (void) sprintf (dp -> ftd_data, "%s: %s", fa -> fa_account, ! 1300: sys_errname (errno)); ! 1301: dp -> ftd_cc = strlen (dp -> ftd_data); ! 1302: ! 1303: no_change: ; ! 1304: dp -> ftd_type = DIAG_PERM; ! 1305: dp -> ftd_identifier = FS_MGT_CHANGE; ! 1306: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 1307: dp -> ftd_delay = DIAG_NODELAY; ! 1308: dp++; ! 1309: ! 1310: *diags = dp; ! 1311: return NOTOK; ! 1312: } ! 1313: ! 1314: myst.st_gid = gid; ! 1315: } ! 1316: #endif ! 1317: ! 1318: if (present & FA_FILENAME) { ! 1319: #ifdef BRIDGE ! 1320: if (ftp_rename (myfile, mvfile) == NOTOK) { ! 1321: (void) sprintf (dp -> ftd_data, "%s: %s", fa -> fa_files[0], ! 1322: ftp_error); ! 1323: #else ! 1324: if (rename (myfile, mvfile) == NOTOK) { /* on EXDEV could do gonzo ! 1325: copy, but why bother? */ ! 1326: (void) sprintf (dp -> ftd_data, "%s: %s", fa -> fa_files[0], ! 1327: sys_errname (errno)); ! 1328: #endif ! 1329: dp -> ftd_cc = strlen (dp -> ftd_data); ! 1330: #ifndef BRIDGE ! 1331: goto no_change; ! 1332: #else ! 1333: dp -> ftd_type = DIAG_PERM; ! 1334: dp -> ftd_identifier = FS_MGT_CHANGE; ! 1335: dp -> ftd_observer = dp -> ftd_source = EREF_RFSU; ! 1336: dp -> ftd_delay = DIAG_NODELAY; ! 1337: dp++; ! 1338: ! 1339: *diags = dp; ! 1340: return NOTOK; ! 1341: #endif ! 1342: } ! 1343: advise (LLOG_NOTICE, NULLCP, "rename %s to %s", myfile, mvfile); ! 1344: ! 1345: myfile = mvfile; ! 1346: } ! 1347: ! 1348: *diags = dp; ! 1349: return OK; ! 1350: } ! 1351: ! 1352: /* */ ! 1353: ! 1354: static char *getfile (file) ! 1355: char *file; ! 1356: { ! 1357: register char *bp; ! 1358: #ifndef BRIDGE ! 1359: register char *cp, ! 1360: *pp; ! 1361: register struct passwd *pw; ! 1362: #endif ! 1363: static int i = 0; ! 1364: static char buffer1[MAXPATHLEN], ! 1365: buffer2[MAXPATHLEN]; ! 1366: ! 1367: bp = (i++ % 2) ? buffer1 : buffer2; ! 1368: ! 1369: #ifndef BRIDGE ! 1370: switch (*file) { ! 1371: case '/': ! 1372: if (strlen (file) >= MAXPATHLEN) ! 1373: goto trunc; ! 1374: ! 1375: (void) strcpy (bp, file); ! 1376: break; ! 1377: ! 1378: case '~': ! 1379: if (cp = index (pp = file + 1, '/')) ! 1380: *cp = NULL; ! 1381: ! 1382: if (*pp == NULL) ! 1383: pp = myhome; ! 1384: else { ! 1385: if ((pw = getpwnam (pp)) == NULL) ! 1386: return NULL; ! 1387: else ! 1388: pp = pw -> pw_dir; ! 1389: } ! 1390: ! 1391: if (strlen (pp) + 1 + (cp ? strlen (cp) : 0) >= MAXPATHLEN) ! 1392: goto trunc; ! 1393: ! 1394: (void) sprintf (bp, "%s/%s", pp, cp ? cp + 1 : ""); ! 1395: if (cp) ! 1396: *cp = '/'; ! 1397: break; ! 1398: ! 1399: default: ! 1400: if (strlen (file) + myhomelen + 1 >= MAXPATHLEN) ! 1401: goto trunc; ! 1402: ! 1403: (void) sprintf (bp, "%s/%s", myhome, file); ! 1404: break; ! 1405: } ! 1406: ! 1407: compath (bp); ! 1408: ! 1409: #ifndef apollo /* always return RELATIVE pathnames */ ! 1410: if (strncmp (bp, myhome, myhomelen - 1) == 0) ! 1411: switch (bp[myhomelen - 1]) { ! 1412: case NULL: ! 1413: (void) strcpy (bp, "."); ! 1414: break; ! 1415: ! 1416: case '/': ! 1417: bp += myhomelen; ! 1418: break; ! 1419: ! 1420: default: ! 1421: break; ! 1422: } ! 1423: #endif ! 1424: ! 1425: return bp; ! 1426: ! 1427: trunc: ; ! 1428: errno = 0; ! 1429: return NULLCP; ! 1430: #else ! 1431: (void) strcpy (bp, file); ! 1432: return bp; ! 1433: #endif ! 1434: } ! 1435: ! 1436: /* */ ! 1437: ! 1438: #ifndef BRIDGE ! 1439: /* originally used algorithms similar to those in /bin/ls; Don Preuss of ! 1440: Apollo suggested these algorithms as they work better with distributed ! 1441: /etc/passwd and /etc/group files */ ! 1442: ! 1443: static char *getuser (uid) ! 1444: int uid; ! 1445: { ! 1446: static struct passwd *pw = NULL; ! 1447: ! 1448: if (pw == NULL || pw -> pw_uid != uid) ! 1449: pw = getpwuid (uid); ! 1450: return (pw ? pw -> pw_name : NULL); ! 1451: } ! 1452: ! 1453: /* */ ! 1454: ! 1455: static char *getgroup (gid) ! 1456: int gid; ! 1457: { ! 1458: register struct group *gr; ! 1459: static int my_gid = -1; ! 1460: static char my_name[NMAX + 1]; ! 1461: ! 1462: if (my_gid != gid) { ! 1463: if ((gr = getgrgid (gid)) == NULL) ! 1464: return NULL; ! 1465: ! 1466: my_gid = gr -> gr_gid; ! 1467: (void) strcpy (my_name, gr -> gr_name); ! 1468: } ! 1469: ! 1470: return my_name; ! 1471: } ! 1472: ! 1473: /* */ ! 1474: ! 1475: int findgid (group) ! 1476: char *group; ! 1477: { ! 1478: int i; ! 1479: #ifdef BSD42 ! 1480: int gidset[NGROUPS]; ! 1481: #endif ! 1482: register struct group *gr; ! 1483: static int my_gid = -1; ! 1484: static char my_name[NMAX + 1] = ""; ! 1485: ! 1486: if (*group == NULL) ! 1487: return NOTOK; ! 1488: ! 1489: if (strcmp (my_name, group) != 0) { ! 1490: if ((gr = getgrnam (group)) == NULL) ! 1491: return NOTOK; ! 1492: ! 1493: #ifdef BSD42 ! 1494: for (i = getgroups (NGROUPS, gidset) - 1; i >= 0; i--) ! 1495: if (gr -> gr_gid == gidset[i]) ! 1496: break; ! 1497: if (i < 0) ! 1498: return NOTOK; ! 1499: #endif ! 1500: ! 1501: (void) strcpy (my_name, gr -> gr_name); ! 1502: my_gid = gr -> gr_gid; ! 1503: } ! 1504: ! 1505: return my_gid; ! 1506: } ! 1507: #endif ! 1508: ! 1509: /* */ ! 1510: ! 1511: #ifndef SYS5 ! 1512: #ifndef BRIDGE ! 1513: static int EACCESS (file, mode) ! 1514: char *file; ! 1515: int mode; ! 1516: { ! 1517: int result; ! 1518: ! 1519: (void) seteuid (0); ! 1520: (void) setruid (myuid); ! 1521: ! 1522: result = access (file, mode); ! 1523: ! 1524: (void) setruid (0); ! 1525: (void) seteuid (myuid); ! 1526: ! 1527: return result; ! 1528: } ! 1529: #endif ! 1530: #else ! 1531: ! 1532: /* */ ! 1533: ! 1534: static int chgrp (file, gid) ! 1535: char *file; ! 1536: int gid; ! 1537: { ! 1538: int i, ! 1539: pid, ! 1540: status; ! 1541: char group[10]; ! 1542: struct stat st; ! 1543: ! 1544: (void) sprintf (group, "%d", gid); ! 1545: ! 1546: switch (pid = fork ()) { ! 1547: case NOTOK: ! 1548: return NOTOK; ! 1549: ! 1550: case OK: ! 1551: execl ("/bin/chgrp", "chgrp", group, file, NULLCP); ! 1552: execl ("/usr/bin/chgrp", "chgrp", group, file, NULLCP); ! 1553: execl ("/etc/chgrp", "chgrp", group, file, NULLCP); ! 1554: _exit (NOTOK); ! 1555: ! 1556: default: ! 1557: while ((i = wait (&status)) != NOTOK && pid != i) ! 1558: continue; ! 1559: if (i != NOTOK && status) { ! 1560: if (stat (file, &st) == NOTOK || st.st_gid != gid) { ! 1561: i = NOTOK; ! 1562: errno = EACCES; ! 1563: } ! 1564: else ! 1565: status = OK; ! 1566: } ! 1567: return (i == NOTOK ? NOTOK : status); ! 1568: } ! 1569: } ! 1570: ! 1571: /* */ ! 1572: ! 1573: static int mkdir (dir, mode) ! 1574: char *dir; ! 1575: int mode; ! 1576: { ! 1577: int i, ! 1578: pid, ! 1579: status; ! 1580: struct stat st; ! 1581: ! 1582: switch (pid = fork ()) { ! 1583: case NOTOK: ! 1584: return NOTOK; ! 1585: ! 1586: case OK: ! 1587: (void) umask (~mode); ! 1588: execl ("/bin/mkdir", "mkdir", dir, NULLCP); ! 1589: execl ("/usr/bin/mkdir", "mkdir", dir, NULLCP); ! 1590: execl ("/etc/mkdir", "mkdir", dir, NULLCP); ! 1591: _exit (NOTOK); ! 1592: ! 1593: default: ! 1594: while ((i = wait (&status)) != NOTOK && pid != i) ! 1595: continue; ! 1596: if (i != NOTOK && status) { ! 1597: if (stat (dir, &st) == NOTOK ! 1598: || (st.st_mode & S_IFMT) != S_IFDIR) { ! 1599: i = NOTOK; ! 1600: errno = EACCES; ! 1601: } ! 1602: else ! 1603: status = OK; ! 1604: } ! 1605: return (i == NOTOK ? NOTOK : status); ! 1606: } ! 1607: } ! 1608: ! 1609: /* */ ! 1610: ! 1611: static int rmdir (dir) ! 1612: char *dir; ! 1613: { ! 1614: int i, ! 1615: pid, ! 1616: status; ! 1617: ! 1618: switch (pid = fork ()) { ! 1619: case NOTOK: ! 1620: return NOTOK; ! 1621: ! 1622: case OK: ! 1623: execl ("/bin/rmdir", "rmdir", dir, NULLCP); ! 1624: execl ("/usr/bin/rmdir", "rmdir", dir, NULLCP); ! 1625: execl ("/etc/rmdir", "rmdir", dir, NULLCP); ! 1626: _exit (NOTOK); ! 1627: ! 1628: default: ! 1629: while ((i = wait (&status)) != NOTOK && pid != i) ! 1630: continue; ! 1631: if (i != NOTOK && status) { ! 1632: if (access (dir, 0x00) != NOTOK) { ! 1633: i = NOTOK; ! 1634: errno = EACCES; ! 1635: } ! 1636: else ! 1637: status = OK; ! 1638: } ! 1639: return (i == NOTOK ? NOTOK : status); ! 1640: } ! 1641: } ! 1642: ! 1643: /* */ ! 1644: ! 1645: static int truncate (file, length) ! 1646: char *file; ! 1647: int length; ! 1648: { ! 1649: int fd; ! 1650: ! 1651: if (length != 0) { /* XXX: too much work to get right */ ! 1652: errno = EINVAL; ! 1653: return NOTOK; ! 1654: } ! 1655: ! 1656: if ((fd = open (file, O_WRONLY | O_TRUNC)) == NOTOK) ! 1657: return NOTOK; ! 1658: ! 1659: (void) close (fd); ! 1660: return OK; ! 1661: } ! 1662: ! 1663: ! 1664: /* ARGSUSED */ ! 1665: ! 1666: int ftruncate (fd, length) /* works only 'cause we're lucky */ ! 1667: int fd, ! 1668: length; ! 1669: { ! 1670: return truncate (myfile, length); ! 1671: } ! 1672: #endif ! 1673: ! 1674: /* DEBUG */ ! 1675: ! 1676: #if defined(FTAMDEBUG) && defined(BSD42) ! 1677: #include <syscall.h> ! 1678: ! 1679: ! 1680: static int unlink (file) ! 1681: char *file; ! 1682: { ! 1683: if (debug) { ! 1684: int i, ! 1685: b; ! 1686: ! 1687: again: ; ! 1688: fprintf (stderr, "unlink(\"%s\")? y, w, l: ", file); ! 1689: ! 1690: i = b = getchar (); ! 1691: while (b != '\n' && b != EOF) ! 1692: b = getchar (); ! 1693: ! 1694: switch (i) { ! 1695: case 'y': ! 1696: break; ! 1697: ! 1698: case 'w': ! 1699: return OK; ! 1700: ! 1701: case 'l': ! 1702: return NOTOK; ! 1703: ! 1704: default: ! 1705: goto again; ! 1706: } ! 1707: } ! 1708: ! 1709: return syscall (SYS_unlink, file); ! 1710: } ! 1711: ! 1712: ! 1713: static int rmdir (dir) ! 1714: char *dir; ! 1715: { ! 1716: if (debug) { ! 1717: int i, ! 1718: b; ! 1719: ! 1720: again: ; ! 1721: fprintf (stderr, "rmdir(\"%s\")? y, w, l: ", dir); ! 1722: ! 1723: i = b = getchar (); ! 1724: while (b != '\n' && b != EOF) ! 1725: b = getchar (); ! 1726: ! 1727: switch (i) { ! 1728: case 'y': ! 1729: break; ! 1730: ! 1731: case 'w': ! 1732: return OK; ! 1733: ! 1734: case 'l': ! 1735: return NOTOK; ! 1736: ! 1737: default: ! 1738: goto again; ! 1739: } ! 1740: } ! 1741: ! 1742: return syscall (SYS_rmdir, dir); ! 1743: } ! 1744: ! 1745: ! 1746: /* VARARGS2 */ ! 1747: ! 1748: static int open (file, flags, mode) ! 1749: char *file; ! 1750: int flags, ! 1751: mode; ! 1752: { ! 1753: if (debug) { ! 1754: int i, ! 1755: b; ! 1756: ! 1757: again: ; ! 1758: fprintf (stderr, "open(\"%s\",0x%x,0%o)? y, l: ", file, flags, ! 1759: (flags & O_CREAT) ? mode : 0); ! 1760: ! 1761: i = b = getchar (); ! 1762: while (b != '\n' && b != EOF) ! 1763: b = getchar (); ! 1764: ! 1765: switch (i) { ! 1766: case 'y': ! 1767: break; ! 1768: ! 1769: case 'l': ! 1770: return NOTOK; ! 1771: ! 1772: default: ! 1773: goto again; ! 1774: } ! 1775: } ! 1776: ! 1777: return syscall (SYS_open, file, flags, mode); ! 1778: } ! 1779: ! 1780: ! 1781: static int mkdir (dir, mode) ! 1782: char *dir; ! 1783: int mode; ! 1784: { ! 1785: if (debug) { ! 1786: int i, ! 1787: b; ! 1788: ! 1789: again: ; ! 1790: fprintf (stderr, "mkdir(\"%s\",0%o)? y, w, l: ", dir, mode); ! 1791: ! 1792: i = b = getchar (); ! 1793: while (b != '\n' && b != EOF) ! 1794: b = getchar (); ! 1795: ! 1796: switch (i) { ! 1797: case 'y': ! 1798: break; ! 1799: ! 1800: case 'w': ! 1801: return OK; ! 1802: ! 1803: case 'l': ! 1804: return NOTOK; ! 1805: ! 1806: default: ! 1807: goto again; ! 1808: } ! 1809: } ! 1810: ! 1811: return syscall (SYS_mkdir, dir, mode); ! 1812: } ! 1813: ! 1814: ! 1815: static int chown (file, uid, gid) ! 1816: char *file; ! 1817: int uid, ! 1818: gid; ! 1819: { ! 1820: if (debug) { ! 1821: int i, ! 1822: b; ! 1823: ! 1824: again: ; ! 1825: fprintf (stderr, "chown(\"%s\",%d,%d)? y, w, l: ", file, uid, gid); ! 1826: ! 1827: i = b = getchar (); ! 1828: while (b != '\n' && b != EOF) ! 1829: b = getchar (); ! 1830: ! 1831: switch (i) { ! 1832: case 'y': ! 1833: break; ! 1834: ! 1835: case 'w': ! 1836: return OK; ! 1837: ! 1838: case 'l': ! 1839: return NOTOK; ! 1840: ! 1841: default: ! 1842: goto again; ! 1843: } ! 1844: } ! 1845: ! 1846: return syscall (SYS_chown, file, uid, gid); ! 1847: } ! 1848: ! 1849: ! 1850: static int fchown (fd, uid, gid) ! 1851: int fd; ! 1852: int uid, ! 1853: gid; ! 1854: { ! 1855: if (debug) { ! 1856: int i, ! 1857: b; ! 1858: ! 1859: again: ; ! 1860: fprintf (stderr, "fchown(%d,%d,%d)? y, w, l: ", fd, uid, gid); ! 1861: ! 1862: i = b = getchar (); ! 1863: while (b != '\n' && b != EOF) ! 1864: b = getchar (); ! 1865: ! 1866: switch (i) { ! 1867: case 'y': ! 1868: break; ! 1869: ! 1870: case 'w': ! 1871: return OK; ! 1872: ! 1873: case 'l': ! 1874: return NOTOK; ! 1875: ! 1876: default: ! 1877: goto again; ! 1878: } ! 1879: } ! 1880: ! 1881: return syscall (SYS_fchown, fd, uid, gid); ! 1882: } ! 1883: ! 1884: ! 1885: static int truncate (file, length) ! 1886: char *file; ! 1887: int length; ! 1888: { ! 1889: if (debug) { ! 1890: int i, ! 1891: b; ! 1892: ! 1893: again: ; ! 1894: fprintf (stderr, "truncate(\"%s\",%d)? y, w, l: ", file, length); ! 1895: ! 1896: i = b = getchar (); ! 1897: while (b != '\n' && b != EOF) ! 1898: b = getchar (); ! 1899: ! 1900: switch (i) { ! 1901: case 'y': ! 1902: break; ! 1903: ! 1904: case 'w': ! 1905: return OK; ! 1906: ! 1907: case 'l': ! 1908: return NOTOK; ! 1909: ! 1910: default: ! 1911: goto again; ! 1912: } ! 1913: } ! 1914: ! 1915: return syscall (SYS_truncate, file, length); ! 1916: } ! 1917: ! 1918: ! 1919: static int rename (old, new) ! 1920: char *old; ! 1921: char *new; ! 1922: { ! 1923: if (debug) { ! 1924: int i, ! 1925: b; ! 1926: ! 1927: again: ; ! 1928: fprintf (stderr, "rename(\"%s\",\"%s\")? y, w, l: ", old, new); ! 1929: ! 1930: i = b = getchar (); ! 1931: while (b != '\n' && b != EOF) ! 1932: b = getchar (); ! 1933: ! 1934: switch (i) { ! 1935: case 'y': ! 1936: break; ! 1937: ! 1938: case 'w': ! 1939: return OK; ! 1940: ! 1941: case 'l': ! 1942: return NOTOK; ! 1943: ! 1944: default: ! 1945: goto again; ! 1946: } ! 1947: } ! 1948: ! 1949: return syscall (SYS_rename, old, new); ! 1950: } ! 1951: ! 1952: ! 1953: static int flock (fd, operation) ! 1954: int fd, ! 1955: operation; ! 1956: { ! 1957: if (debug) { ! 1958: int i, ! 1959: b; ! 1960: ! 1961: again: ; ! 1962: fprintf (stderr, "flock(%d,0x%x)? y, w, l: ", fd, operation); ! 1963: ! 1964: i = b = getchar (); ! 1965: while (b != '\n' && b != EOF) ! 1966: b = getchar (); ! 1967: ! 1968: switch (i) { ! 1969: case 'y': ! 1970: break; ! 1971: ! 1972: case 'w': ! 1973: return OK; ! 1974: ! 1975: case 'l': ! 1976: return NOTOK; ! 1977: ! 1978: default: ! 1979: goto again; ! 1980: } ! 1981: } ! 1982: ! 1983: return syscall (SYS_flock, fd, operation); ! 1984: } ! 1985: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.