|
|
1.1 ! root 1: #ifndef lint ! 2: static char *rcsid = "$Header: system_interface.c,v 1.6 87/05/14 11:35:19 ed Exp $"; ! 3: #endif lint ! 4: ! 5: /* ! 6: * Copyright (c) 1986, 1987 Xerox Corporation. ! 7: */ ! 8: ! 9: /* $Log: system_interface.c,v $ ! 10: * Revision 1.6 87/05/14 11:35:19 ed ! 11: * Enhanced fileID to be 32 bit inode (previous oversight). ! 12: * Also get_name_from_fileID now uses -a on ls to look at all files. ! 13: * ! 14: * Revision 1.5 87/04/16 15:26:17 ed ! 15: * Fixed bug if count was Filing4_unlimitedCount. (from jqj) ! 16: * Resolved lingering Subset pathname bugs. ! 17: * ! 18: * Revision 1.4 87/04/01 10:10:42 ed ! 19: * Added recognition of 'file drawers' (directories in root) ! 20: * in make_attribute_sequence. ! 21: * ! 22: * Revision 1.3 87/03/31 14:17:54 ed ! 23: * Fixed bug in access_file (per JQ Johnson) passed dir_handle, ! 24: * expected pathname, check for -1 failure, not success. ! 25: * ! 26: * Revision 1.2 87/03/31 09:46:46 ed ! 27: * New procedures: Create, ChangeAttributes(name only), Copy, Move, ! 28: * Replace, Serialize, Deserialize. ! 29: * Added conditional disabling of root logins. ! 30: * Support for GetAttributes (allAttributeTypes). ! 31: * Support for filter of type all. ! 32: * ! 33: * Revision 1.1 87/01/14 11:26:12 ed ! 34: * Initial revision ! 35: * ! 36: */ ! 37: ! 38: #include <stdio.h> ! 39: #include <pwd.h> ! 40: #include <signal.h> ! 41: #include <errno.h> ! 42: #include <ctype.h> ! 43: #include <sys/file.h> ! 44: #include <sys/time.h> ! 45: #include <sys/types.h> ! 46: #include <sys/stat.h> ! 47: #include <netns/ns.h> ! 48: #include <netns/sp.h> ! 49: #ifdef FILING4 ! 50: #include "filingV4.h" ! 51: #include "authenticationV2.h" ! 52: #endif FILING4 ! 53: #ifdef FILING5 ! 54: #include "filingV5.h" ! 55: #include "authenticationV2.h" ! 56: #endif FILING5 ! 57: #ifdef FILING6 ! 58: #include "filingV6.h" ! 59: #include "authenticationV3.h" ! 60: #endif FILING5 ! 61: #ifdef FILINGSUBSET1 ! 62: #include "filingsubsetV1.h" ! 63: #include "authenticationV3.h" ! 64: #endif FILINGSUBSET1 ! 65: #include <xnscourier/filing_server.h> ! 66: #include <xnscourier/filetypes.h> ! 67: ! 68: #define XNS_TIME_DIFFERENCE 2177452800 /* [(1970-1901) years * 365 days/year + 17 leap days */ ! 69: /* * 24 hours/day * 60 min/hour * 60 sec/min */ ! 70: ! 71: #define SERVICE_ROOT "/" /* root directory for service */ ! 72: #ifdef DEBUG ! 73: FILE *msgs; ! 74: #endif DEBUG ! 75: ! 76: extern int errno; ! 77: ! 78: Cardinal continuance; /* continuance value, in seconds */ ! 79: extern continuance_expiration(); /* expiration routine */ ! 80: ! 81: /* ! 82: * routine: ! 83: * verifyandposition_user ! 84: * input: ! 85: * user_name - derived from secondary credentials ! 86: * user_password - derived form secondary credentials ! 87: * returns: ! 88: * -1 - success ! 89: * else Filing Error, Problem ! 90: */ ! 91: ! 92: verifyandposition_user(user_name,user_password) ! 93: char *user_name; ! 94: char *user_password; ! 95: { ! 96: struct passwd *pwd_entry; ! 97: struct passwd *getpwnam(); ! 98: char *crypt(); ! 99: ! 100: #ifdef DEBUG ! 101: fprintf(msgs, "user= '%s'\n", user_name); ! 102: #endif DEBUG ! 103: ! 104: ! 105: /* determine if user is valid */ ! 106: if ( (pwd_entry= getpwnam(user_name)) == (struct passwd *)0 ) { ! 107: char *lowercase(); ! 108: #ifdef DEBUG ! 109: fprintf(msgs, "name= '%s'\n",lowercase(user_name)); ! 110: #endif DEBUG ! 111: if ( (pwd_entry= getpwnam(lowercase(user_name))) == (struct passwd *)0 ) { ! 112: #if FILING4 | FILING5 ! 113: ReturnAuthenticationError(AUTHENTICATION_credentialsInvalid); ! 114: #else FILING4 | FILING5 ! 115: ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid); ! 116: #endif FILING4 | FILING5 ! 117: /* NOT REACHED */ ! 118: } ! 119: } ! 120: ! 121: #if !(FILING4 | FILING5) ! 122: if ( strcmp(pwd_entry->pw_passwd, crypt(user_password,pwd_entry->pw_passwd)) ) { ! 123: ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid); ! 124: /* NOT REACHED */ ! 125: } ! 126: #endif !(FILING4 | FILING5) ! 127: /* set process group ID */ ! 128: if ( setgid(pwd_entry->pw_gid) == -1 ) { ! 129: #if FILING4 | FILING5 ! 130: ReturnAuthenticationError(AUTHENTICATION_credentialsInvalid); ! 131: #else FILING4 | FILING5 ! 132: ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid); ! 133: #endif FILING4 | FILING5 ! 134: /* NOT REACHED */ ! 135: } ! 136: /* set process user ID */ ! 137: if ( setuid(pwd_entry->pw_uid) == -1 ) { ! 138: #if FILING4 | FILING5 ! 139: ReturnAuthenticationError(AUTHENTICATION_credentialsInvalid); ! 140: #else FILING4 | FILING5 ! 141: ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid); ! 142: #endif FILING4 | FILING5 ! 143: /* NOT REACHED */ ! 144: } ! 145: /* position in service root */ ! 146: if ( chdir(SERVICE_ROOT) == -1 ) { ! 147: ReturnServiceError(FILING_serviceUnavailable); ! 148: /* NOT REACHED */ ! 149: } ! 150: ! 151: return(-1); ! 152: } ! 153: ! 154: ! 155: /* ! 156: * routine: ! 157: * set_continuance_timer ! 158: */ ! 159: ! 160: set_continuance_timer() ! 161: { ! 162: alarm(0); /* cancel any previous alarm */ ! 163: signal(SIGALRM, continuance_expiration); /* set routine to catch alarm */ ! 164: alarm(continuance); /* set alarm */ ! 165: } ! 166: ! 167: /* ! 168: * routine: ! 169: * reset_continuance_timer ! 170: */ ! 171: ! 172: reset_continuance_timer() ! 173: { ! 174: alarm(0); /* cancel previous alarm */ ! 175: alarm(continuance); /* then, reset alarm */ ! 176: } ! 177: ! 178: /* ! 179: * routine: ! 180: * cancel_continuance_timer ! 181: */ ! 182: ! 183: cancel_continuance_timer() ! 184: { ! 185: alarm(0); /* cancel any previous alarm */ ! 186: signal(SIGALRM,SIG_IGN); /* set routine to ignore alarm */ ! 187: } ! 188: ! 189: /* ! 190: * routine: ! 191: * open_file ! 192: * input: ! 193: * pointer to file handle ! 194: * returns: ! 195: * -1 - success ! 196: * else FILING_ error, problem ! 197: */ ! 198: ! 199: open_file(file_context_block) ! 200: file_handle *file_context_block; ! 201: { ! 202: #ifdef DEBUG ! 203: fprintf(msgs, "open_file\n"); ! 204: #endif DEBUG ! 205: ! 206: if ( (file_context_block->file_desc= ! 207: fopen(file_context_block->pathname, "r")) == NULL ) { ! 208: switch (errno) { ! 209: case EACCES : /* user has no access */ ! 210: ReturnAccessError(FILING_accessRightsInsufficient); ! 211: /* NOT REACHED */ ! 212: case ENOENT : /* no such file */ ! 213: case ENOTDIR : /* no such directory */ ! 214: ReturnHandleError(FILING_fileNotFound); ! 215: /* NOT REACHED */ ! 216: ! 217: default : /* all other errors */ ! 218: ReturnAccessError(FILING_accessRightsIndeterminate); ! 219: /* NOT REACHED */ ! 220: } ! 221: ! 222: } ! 223: ! 224: return(-1); ! 225: } ! 226: ! 227: /* ! 228: * routine: ! 229: * close_file ! 230: * input: ! 231: * pointer to file handle ! 232: * returns: ! 233: * -1 - success ! 234: */ ! 235: ! 236: close_file(file_context_block) ! 237: file_handle *file_context_block; ! 238: { ! 239: #ifdef DEBUG ! 240: fprintf(msgs, "closing...\n"); ! 241: #endif DEBUG ! 242: if ( file_context_block->file_desc != NULL ) { ! 243: fclose(file_context_block->file_desc); ! 244: file_context_block->file_desc= 0; ! 245: } ! 246: ! 247: return(-1); ! 248: } ! 249: ! 250: /* ! 251: * routine: ! 252: * stat_file ! 253: * input: ! 254: * pointer to file handle ! 255: * returns: ! 256: * -1 - success ! 257: * else Filing Error, Problem ! 258: * ! 259: * file_context_block entries filled in ! 260: */ ! 261: ! 262: stat_file(file_context_block) ! 263: file_handle *file_context_block; ! 264: { ! 265: struct stat file_stat; ! 266: LongCardinal get_type(); ! 267: ! 268: #ifdef DEBUG ! 269: fprintf(msgs, "stating '%s'\n",file_context_block->pathname); ! 270: #endif DEBUG ! 271: ! 272: if ( stat(file_context_block->pathname,&file_stat) == -1 ) { ! 273: switch (errno) { ! 274: case EACCES : /* user has no access */ ! 275: ReturnAccessError(FILING_accessRightsInsufficient); ! 276: /* NOT REACHED */ ! 277: case ENOTDIR : /* directory doesn't exist */ ! 278: case ENOENT : /* file doesn't exist */ ! 279: ReturnAccessError(FILING_fileNotFound); ! 280: ! 281: default : /* all other errors */ ! 282: ReturnAccessError(FILING_accessRightsIndeterminate); ! 283: } ! 284: } ! 285: ! 286: file_context_block->datasize= file_stat.st_size; /* dataSize */ ! 287: ! 288: /* file type */ ! 289: if ( (file_stat.st_mode & S_IFDIR) != 0 ) { /* directory */ ! 290: file_context_block->isdirectory= TRUE; ! 291: file_context_block->truetype= FILING_tDirectory; ! 292: } else { ! 293: file_context_block->isdirectory= FALSE; /* non-directory */ ! 294: file_context_block->truetype= get_type(file_context_block->pathname); ! 295: } ! 296: ! 297: return(-1); ! 298: } ! 299: ! 300: /* ! 301: * routine: ! 302: * create_file ! 303: * input: ! 304: * pointer to file handle ! 305: * returns: ! 306: * -1 - success ! 307: * else FILING_ Error, Problem ! 308: * ! 309: * file_context_block->file_desc filled in ! 310: */ ! 311: ! 312: create_file(file_context_block) ! 313: file_handle *file_context_block; ! 314: ! 315: { ! 316: ! 317: if ( access(file_context_block->pathname, F_OK) == 0 ) { ! 318: ReturnInsertionError(FILING_fileNotUnique); ! 319: /* NOT REACHED */ ! 320: } ! 321: ! 322: if ( (file_context_block->file_desc= ! 323: fopen(file_context_block->pathname, "w")) ) { ! 324: switch (errno) { ! 325: case EACCES : /* user has no access */ ! 326: ReturnAccessError(FILING_accessRightsInsufficient); ! 327: /* NOT REACHED */ ! 328: ! 329: case EEXIST : /* file exists */ ! 330: ReturnInsertionError(FILING_fileNotUnique); ! 331: /* NOT REACHED */ ! 332: ! 333: case ENOENT : /* no such file, OK */ ! 334: break; ! 335: ! 336: case ENOTDIR : /* no such directory */ ! 337: ReturnAccessError(FILING_fileNotFound); ! 338: /* NOT REACHED */ ! 339: ! 340: case EMFILE : /* process file table full */ ! 341: case ENFILE : /* system file table full */ ! 342: ReturnSpaceError(FILING_allocationExceeded); ! 343: /* NOT REACHED */ ! 344: ! 345: default : /* all other errors */ ! 346: ReturnAccessError(FILING_accessRightsIndeterminate); ! 347: /* NOT REACHED */ ! 348: } ! 349: } ! 350: ! 351: return(1); ! 352: } ! 353: /* ! 354: * routine: ! 355: * create_directory ! 356: * input: ! 357: * pointer to file handle ! 358: * returns: ! 359: * -1 - success ! 360: * else FILING_ Error, Problem ! 361: * ! 362: */ ! 363: ! 364: create_directory(file_context_block) ! 365: file_handle *file_context_block; ! 366: ! 367: { ! 368: int status; ! 369: ! 370: #ifdef DEBUG ! 371: fprintf(msgs, "createdir '%s'\n",file_context_block->pathname); ! 372: #endif DEBUG ! 373: status= 0; ! 374: if ( fork() == 0 ) { /* execute command */ ! 375: execl("/bin/mkdir", "mkdir", file_context_block->pathname, 0); ! 376: ReturnAccessError(FILING_accessRightsInsufficient); ! 377: /* NOT REACHED */ ! 378: } ! 379: ! 380: wait(&status); ! 381: if ( status ) { /* error reports accessRightsInsufficient */ ! 382: ReturnAccessError(FILING_accessRightsInsufficient); ! 383: /* NOT REACHED */ ! 384: } ! 385: ! 386: return(-1); ! 387: } ! 388: ! 389: /* ! 390: * routine: ! 391: * rename_file ! 392: * input: ! 393: * pointer to old name ! 394: * pointer to file handle (containing new name) ! 395: * returns: ! 396: * -1 - success ! 397: * else Filing Error, Problem ! 398: * ! 399: */ ! 400: ! 401: rename_file(oldname, file_context_block) ! 402: char *oldname; ! 403: file_handle *file_context_block; ! 404: { ! 405: ! 406: if ( access(file_context_block->pathname, F_OK) == 0 ) { ! 407: ReturnInsertionError(FILING_fileNotUnique); ! 408: /* NOT REACHED */ ! 409: } ! 410: ! 411: #ifdef DEBUG ! 412: fprintf(msgs, "renaming '%s' to '%s'\n",oldname, file_context_block->pathname); ! 413: #endif DEBUG ! 414: ! 415: if ( rename(oldname, file_context_block->pathname) == -1 ) { ! 416: switch (errno) { ! 417: case EACCES : /* user has no access */ ! 418: ReturnAccessError(FILING_accessRightsInsufficient); ! 419: /* NOT REACHED */ ! 420: case ENOTDIR : /* directory doesn't exist */ ! 421: case ENOENT : /* file doesn't exist */ ! 422: case EXDEV : /* no cross file system move */ ! 423: ReturnAccessError(FILING_fileChanged); ! 424: /* NOT REACHED */ ! 425: ! 426: case EINVAL : /* old is parent of new */ ! 427: ReturnInsertionError(FILING_loopInHierarchy); ! 428: /* NOT REACHED */ ! 429: ! 430: default : /* all other errors */ ! 431: ReturnAccessError(FILING_accessRightsIndeterminate); ! 432: /* NOT REACHED */ ! 433: } ! 434: } ! 435: ! 436: return(-1); ! 437: } ! 438: ! 439: /* ! 440: * routine: ! 441: * copy_file ! 442: * input: ! 443: * pointer to old file handle ! 444: * pointer to new file handle ! 445: * returns: ! 446: * -1 - success ! 447: * else Filing Error, Problem ! 448: * ! 449: */ ! 450: ! 451: copy_file(old_file_context_block, new_file_context_block) ! 452: file_handle *old_file_context_block; ! 453: file_handle *new_file_context_block; ! 454: { ! 455: int pid, s; ! 456: ! 457: if ( strncmp(old_file_context_block->pathname, new_file_context_block->pathname, strlen(old_file_context_block->pathname)) == 0 ) { ! 458: ReturnInsertionError(FILING_loopInHierarchy); ! 459: /* NOT REACHED */ ! 460: } ! 461: ! 462: if ( access(new_file_context_block->pathname, F_OK) == 0 ) { ! 463: ReturnInsertionError(FILING_fileNotUnique); ! 464: /* NOT REACHED */ ! 465: } ! 466: ! 467: #ifdef DEBUG ! 468: fprintf(msgs, "copying '%s' to '%s'\n",old_file_context_block->pathname, new_file_context_block->pathname); ! 469: #endif DEBUG ! 470: ! 471: if ( copy(old_file_context_block->pathname, new_file_context_block->pathname) != -1 ) { ! 472: ReturnAccessError(FILING_fileChanged); ! 473: /* NOT REACHED */ ! 474: } ! 475: ! 476: return(-1); ! 477: } ! 478: ! 479: copy(from, to) ! 480: char *from; ! 481: char *to; ! 482: { ! 483: int pid, s; ! 484: ! 485: if ( (pid= fork()) == 0 ) { ! 486: /* child */ ! 487: ! 488: execl("/bin/cp", "cp", "-r", from, to, 0); ! 489: exit(1); ! 490: } ! 491: ! 492: if ( pid == -1 ) { ! 493: ReturnUndefinedError(0); ! 494: /* NOT REACHED */ ! 495: } ! 496: ! 497: while ( wait(&s) != pid ) ; ! 498: ! 499: /* ! 500: * would be nice if cp returned useful errors, but ... ! 501: */ ! 502: ! 503: if ( s != 0 ) { ! 504: ReturnAccessError(FILING_fileChanged); ! 505: /* NOT REACHED */ ! 506: } ! 507: ! 508: return(-1); ! 509: } ! 510: ! 511: list_directory(conn, directory, attr, file_spec, count) ! 512: CourierConnection *conn; ! 513: file_handle *directory; ! 514: FILING_AttributeTypeSequence attr; ! 515: char *file_spec; ! 516: Cardinal count; ! 517: { ! 518: FILING_StreamOfAttributeSequence stream_of_attrseq; ! 519: FILING_AttributeSequence attribute_sequence; ! 520: FILE *pipe_desc; ! 521: FILE *popen(); ! 522: Boolean first= TRUE; ! 523: char command[256]; ! 524: char filename[MAX_FILE_NAME_LENGTH]; ! 525: ! 526: stream_of_attrseq.nextSegment_case.segment.length= 1; ! 527: stream_of_attrseq.nextSegment_case.segment.sequence= &attribute_sequence; ! 528: ! 529: strcpy(command, "/bin/ls -1d "); /* form appropriate command */ ! 530: ! 531: strcat(command, directory->pathname); ! 532: if ( strcmp(directory->pathname, "/") != 0 ) { ! 533: strcat(command, "/"); ! 534: } ! 535: ! 536: strcat(command, file_spec); ! 537: ! 538: if ( get_types(attr, &attribute_sequence) != -1 ) { ! 539: /* NOT REACHED */ ! 540: } ! 541: ! 542: #ifdef DEBUG ! 543: fprintf(msgs, "listing '%s'\n",command); ! 544: #endif DEBUG ! 545: ! 546: if ( (pipe_desc= popen(command, "r")) == NULL ) { /* issue command */ ! 547: ReturnAccessError(FILING_accessRightsInsufficient); ! 548: /* NOT REACHED */ ! 549: } ! 550: ! 551: while ( fgets(filename, MAX_FILE_NAME_LENGTH, pipe_desc) != NULL ) { ! 552: first= FALSE; ! 553: filename[strlen(filename)-1]= '\0'; ! 554: ! 555: #ifdef DEBUG ! 556: fprintf(msgs,"got '%s' ",filename); ! 557: fprintf(msgs, "count= %d\n",count); ! 558: #endif DEBUG ! 559: ! 560: if ( (count != FILING_unlimitedCount) && (--count < 0) ) { ! 561: break; ! 562: } ! 563: ! 564: make_attribute_sequence(filename,&attribute_sequence); ! 565: ! 566: put_next_attribute_sequence(conn, &stream_of_attrseq); ! 567: } ! 568: ! 569: if ( first == TRUE ) { ! 570: pclose(pipe_desc); ! 571: /* ReturnAccessError(FILING_fileNotFound); ??? */ ! 572: /* NOT REACHED */ ! 573: } ! 574: ! 575: put_last_attribute_sequence(conn); ! 576: ! 577: BDTclosewrite(conn); ! 578: pclose(pipe_desc); ! 579: ! 580: return(-1); ! 581: } ! 582: ! 583: /* ! 584: * routine: ! 585: * delete_file ! 586: * input: ! 587: * pointer to file handle ! 588: * returns: ! 589: * -1 - success ! 590: * else Filing Error, Problem ! 591: */ ! 592: ! 593: delete_file(file_context_block) ! 594: file_handle *file_context_block; ! 595: { ! 596: int status; ! 597: ! 598: #ifdef DEBUG ! 599: fprintf(msgs," deleting '%s'",file_context_block->pathname); ! 600: #endif DEBUG ! 601: if ( file_context_block->isdirectory ) { ! 602: if ( fork() == 0 ) { /* use rm -rf for directories */ ! 603: execl("/bin/rm", "rm", "-rf", file_context_block->pathname, 0); ! 604: ReturnAccessError(FILING_accessRightsInsufficient); ! 605: /* NOT REACHED */ ! 606: } ! 607: wait(&status); ! 608: if ( status ) { ! 609: ReturnAccessError(FILING_accessRightsInsufficient); ! 610: /* NOT REACHED */ ! 611: } ! 612: } else { /* use unlink for non-directories */ ! 613: if ( unlink(file_context_block->pathname) == -1 ) { ! 614: switch (errno) { ! 615: case EACCES : /* user has no access */ ! 616: ReturnAccessError(FILING_accessRightsInsufficient); ! 617: /* NOT REACHED */ ! 618: ! 619: case ENOENT : /* no such file */ ! 620: case ENOTDIR : /* no such directory */ ! 621: ReturnAccessError(FILING_fileNotFound); ! 622: /* NOT REACHED */ ! 623: ! 624: default : /* all other errors */ ! 625: ReturnAccessError(FILING_accessRightsIndeterminate); ! 626: /* NOT REACHED */ ! 627: } ! 628: } ! 629: } ! 630: } ! 631: ! 632: /* ! 633: * routine: ! 634: * delete_partial_file ! 635: * input: ! 636: * pointer to file handle ! 637: * returns: ! 638: * -1 - success ! 639: */ ! 640: ! 641: delete_partial_file(file_context_block) ! 642: file_handle *file_context_block; ! 643: { ! 644: unlink(file_context_block->pathname); ! 645: return(-1); ! 646: } ! 647: ! 648: /* ! 649: * routine: ! 650: * access_file ! 651: * input: ! 652: * pointer to file handle ! 653: * returns: ! 654: * -1 - success ! 655: */ ! 656: ! 657: access_file(file_context_block) ! 658: file_handle *file_context_block; ! 659: { ! 660: #ifdef DEBUG ! 661: fprintf(msgs, "access_file\n"); ! 662: #endif DEBUG ! 663: ! 664: if ( access(file_context_block->pathname,R_OK | F_OK) == -1 ) { ! 665: switch (errno) { ! 666: case EACCES : /* user has no access */ ! 667: ReturnAccessError(FILING_fileChanged); ! 668: /* NOT REACHED */ ! 669: case ENOENT : /* no such file */ ! 670: case ENOTDIR : /* no such directory */ ! 671: ReturnHandleError(FILING_invalid); ! 672: /* NOT REACHED */ ! 673: ! 674: default : /* all other errors */ ! 675: ReturnAccessError(FILING_accessRightsIndeterminate); ! 676: /* NOT REACHED */ ! 677: } ! 678: ! 679: } ! 680: ! 681: return(-1); ! 682: } ! 683: ! 684: /* ! 685: * routine: ! 686: * set_create_time ! 687: * input: ! 688: * pointer to file context block ! 689: * where ! 690: * if no createdOn value was specified on Store, createdon = 0 ! 691: * if createdOn value was specified on Store, createdOn != 0, ! 692: * value is in XNS time format ! 693: * returns: ! 694: * none ! 695: */ ! 696: ! 697: set_create_time(file_context_block) ! 698: file_handle *file_context_block; ! 699: ! 700: { ! 701: time_t time_buffer[2]; ! 702: time_t time(); ! 703: ! 704: ! 705: if ( file_context_block->createdon ) /* save createdOn if specified */ ! 706: time_buffer[1]= file_context_block->createdon - XNS_TIME_DIFFERENCE; ! 707: else /* else, set to current date/time */ ! 708: time_buffer[1]= time(0); ! 709: ! 710: time_buffer[0]= time(0); /* set modifiedOn to current date/time */ ! 711: ! 712: utime(file_context_block->pathname,time_buffer); ! 713: } ! 714: ! 715: /* ! 716: * routine: ! 717: * make_attribute_sequence ! 718: * inputs: ! 719: * pointer to file name ! 720: * pointer to sequence of attributes to fill in ! 721: * returns: ! 722: * -1 - success ! 723: */ ! 724: ! 725: make_attribute_sequence(pathname, attrseq) ! 726: char *pathname; ! 727: FILING_AttributeSequence *attrseq; ! 728: { ! 729: int i; ! 730: struct stat file_stat; ! 731: FILING_AttributeType t; ! 732: ! 733: LongCardinal createdon, modifiedon; ! 734: LongCardinal type, get_type(); ! 735: LongCardinal datasize; ! 736: Boolean isdirectory; ! 737: Boolean all_attributes= FALSE; ! 738: Cardinal unix_version= 1; ! 739: Boolean istemporary= FALSE; ! 740: #ifdef FILETOOLCOMPATIBILITY ! 741: Cardinal fileid[6]; ! 742: AUTHENTICATION_Clearinghouse_Name user; ! 743: AUTHENTICATION_Clearinghouse_Name CH_StringToName(); ! 744: char *name, *pwname; ! 745: char *rindex(); ! 746: struct passwd *getpwuid(), *pwd; ! 747: #endif FILETOOLCOMPATIBILITY ! 748: #ifdef EXTENSIONS ! 749: Boolean inroot= FALSE; ! 750: FILE *fd; ! 751: #endif EXTENSIONS ! 752: ! 753: #ifdef DEBUG ! 754: fprintf(msgs, "make_attrseq '%s'\n", pathname); ! 755: #endif DEBUG ! 756: ! 757: #ifndef FILINGSUBSET1 ! 758: if ( (name= rindex(pathname, '/')) == 0 ) ! 759: name= pathname; ! 760: else { ! 761: #ifdef EXTENSIONS ! 762: if ( name == pathname ) inroot= TRUE; ! 763: #endif EXTENSIONS ! 764: name++; ! 765: } ! 766: #endif FILINGSUBSET1 ! 767: ! 768: if ( stat(pathname, &file_stat) == -1 ) { ! 769: ReturnAccessError(FILING_accessRightsInsufficient); ! 770: /* NOT REACHED */ ! 771: } ! 772: ! 773: createdon= file_stat.st_mtime + XNS_TIME_DIFFERENCE; /* createdOn */ ! 774: modifiedon= file_stat.st_atime + XNS_TIME_DIFFERENCE; /* modifiedOn */ ! 775: ! 776: datasize= file_stat.st_size; /* dataSize */ ! 777: ! 778: /* type and isDirectory */ ! 779: if ( (file_stat.st_mode & S_IFDIR) != 0 ) { ! 780: isdirectory= TRUE; ! 781: #ifdef EXTENSIONS ! 782: if ( inroot ) /* if root & directory, assume file drawer */ ! 783: type= TYPE_VPDrawer; ! 784: else ! 785: type= FILING_tDirectory; ! 786: #else EXTENSIONS ! 787: type= FILING_tDirectory; ! 788: #endif EXTENSIONS ! 789: } else { ! 790: type= get_type(pathname); ! 791: #ifdef EXTENSIONS ! 792: if ( (type > LAST_FILING_TYPE) && (type != TYPE_Interpress) && ! 793: (type != TYPE_VPCanvas) ) { ! 794: if ( (fd= fopen(pathname, "r")) == NULL ) { ! 795: ReturnAccessError(FILING_fileChanged); ! 796: /* NOT REACHED */ ! 797: } ! 798: isdirectory= GetDirectoryAttribute(fd); ! 799: fclose(fd); ! 800: } else { ! 801: isdirectory= FALSE; ! 802: } ! 803: #else EXTENSIONS ! 804: isdirectory= FALSE; ! 805: #endif EXTENSIONS ! 806: } ! 807: ! 808: #ifdef EXTENSIONS ! 809: if ( attrseq->length == -1 ) { ! 810: all_attributes= TRUE; ! 811: if ( (type > LAST_FILING_TYPE) && (type != TYPE_Interpress) && ! 812: (type != TYPE_VPCanvas) ) ! 813: make_required_attributes(attrseq); ! 814: else ! 815: make_supported_attributes(attrseq); ! 816: } ! 817: #endif EXTENSIONS ! 818: ! 819: for ( i= 0 ; i < attrseq->length ; i++ ) { ! 820: t= attrseq->sequence[i].type; ! 821: #ifdef DEBUG ! 822: fprintf(msgs,"#%d type= %d \n", i, t); ! 823: #endif DEBUG ! 824: ! 825: if ( t == FILING_pathname ) { ! 826: StringToAttr(pathname, &attrseq->sequence[i]); ! 827: } else if ( t == FILING_type ) { ! 828: LongCardinalToAttr(type, &attrseq->sequence[i]); ! 829: } else if ( t == FILING_dataSize ) { ! 830: LongCardinalToAttr(datasize, &attrseq->sequence[i]); ! 831: } else if ( t == FILING_isDirectory ) { ! 832: BooleanToAttr(isdirectory, &attrseq->sequence[i]); ! 833: } else if ( t == FILING_createdOn ) { ! 834: LongCardinalToAttr(createdon, &attrseq->sequence[i]); ! 835: } else if ( t == FILING_modifiedOn ) { ! 836: LongCardinalToAttr(modifiedon, &attrseq->sequence[i]); ! 837: } else if ( t == FILING_version ) { ! 838: CardinalToAttr(unix_version, &attrseq->sequence[i]); ! 839: } else if ( t == FILING_isTemporary ) { ! 840: BooleanToAttr(istemporary, &attrseq->sequence[i]); ! 841: #ifdef FILETOOLCOMPATIBILITY ! 842: } else if ( t == FILING_name ) { ! 843: StringToAttr(name, &attrseq->sequence[i]); ! 844: } else if ( t == FILING_fileID ) { ! 845: fileid[0]= (file_stat.st_ino >> 16) & 0xffff; ! 846: fileid[1]= file_stat.st_ino & 0xffff; ! 847: fileid[2]= fileid[3]= fileid[4]= 0; ! 848: FileIDToAttr(fileid, &attrseq->sequence[i]); ! 849: } else if ( t == FILING_readOn ) { ! 850: LongCardinalToAttr(modifiedon, &attrseq->sequence[i]); ! 851: } else if ( t == FILING_createdBy ) { ! 852: if ( (pwd= getpwuid(file_stat.st_uid)) == 0 ) ! 853: pwname= "Unkown"; ! 854: else ! 855: pwname= pwd->pw_name; ! 856: user= CH_StringToName(pwname,NULL); ! 857: UserToAttr(user,&attrseq->sequence[i]); ! 858: #endif FILETOOLCOMPATIBILITY ! 859: } else { ! 860: attrseq->sequence[i].value.length= 0; ! 861: attrseq->sequence[i].value.sequence= (Unspecified *)0; ! 862: } ! 863: } ! 864: ! 865: #ifdef EXTENSIONS ! 866: if ( all_attributes ) { ! 867: if ( (type > LAST_FILING_TYPE) && (type != TYPE_Interpress) && ! 868: (type != TYPE_VPCanvas) ) { ! 869: if ( (fd= fopen(pathname, "r")) == NULL ) { ! 870: ReturnAccessError(FILING_fileChanged); ! 871: /* NOT REACHED */ ! 872: } ! 873: if ( AddAllExtendedAttributes(fd, attrseq) != -1 ) { ! 874: fclose(fd); ! 875: ReturnAccessError(FILING_fileChanged); ! 876: /* NOT REACHED */ ! 877: } ! 878: fclose(fd); ! 879: } ! 880: } ! 881: #endif EXTENSIONS ! 882: } ! 883: ! 884: int ! 885: getBDTch(conn,bpp) ! 886: CourierConnection *conn; ! 887: u_char **bpp; ! 888: { ! 889: static u_char buffer[SPPMAXDATA]; ! 890: static int count; ! 891: ! 892: if (*bpp == NULL) {*bpp = buffer; count = 0;} ! 893: if (*bpp >= buffer+count) { ! 894: count=BDTread(conn,buffer,sizeof(buffer)); ! 895: *bpp = buffer; ! 896: } ! 897: if (count <= 0) return(EOF); ! 898: else return(*((*bpp)++)); ! 899: ! 900: } ! 901: ! 902: storeproc(conn,handle) ! 903: CourierConnection *conn; ! 904: file_handle *handle; ! 905: { ! 906: int count, ocount, ch, hashbytes; ! 907: char buffer[SPPMAXDATA]; ! 908: int charset, charset16; ! 909: char *bp; ! 910: register FILE *fout; ! 911: register int fd; ! 912: ! 913: fout= handle->file_desc; ! 914: fd= fileno(fout); ! 915: ! 916: #ifdef FILETOOLCOMPATIBILITY ! 917: if ( handle->type == FILING_tText ) { ! 918: charset = 0; charset16 = 0; bp = NULL; ! 919: while ((ch = getBDTch(conn,&bp)) != EOF) { ! 920: if (ch == '\377') { ! 921: ch = getBDTch(conn,&bp); ! 922: if (ch == '\377') charset16 = 1; ! 923: else charset = ch; ! 924: continue; ! 925: } ! 926: if (charset16) { ! 927: charset = ch; ! 928: ch = getBDTch(conn,&bp); ! 929: } ! 930: switch (charset) { ! 931: case 0: /* normal character set -- minimal xlation */ ! 932: if (ch == '\r') { ! 933: int nextch; ! 934: ! 935: putc('\n',fout); ! 936: if ( (nextch = getBDTch(conn,&bp)) != '\n'){ ! 937: if (nextch == '\r') ! 938: putc('\n',fout); ! 939: else if (nextch == ','+0200) ! 940: putc('_',fout); ! 941: else if (nextch != EOF) ! 942: putc(nextch,fout); ! 943: else ! 944: continue; ! 945: } ! 946: ! 947: break; ! 948: } ! 949: else if (ch == ','+0200) ch = '_'; ! 950: /* more mapping here */ ! 951: putc(ch,fout); ! 952: break; ! 953: default: ! 954: break; /* ignore */ ! 955: } ! 956: } ! 957: /* if (count < 0) perror("netin"); */ ! 958: } else { ! 959: #else FILETOOLCOMPATIBILITY ! 960: { ! 961: #endif FILETOOLCOMPATIBILITY ! 962: errno = ocount = 0; ! 963: fflush(fout); ! 964: while ((count = BDTread(conn, buffer, sizeof(buffer))) > 0) { ! 965: if ((ocount = write(fd,buffer,count)) < 0) { ! 966: perror("write"); ! 967: BDTabort(conn); ! 968: return(0); ! 969: } ! 970: } ! 971: if (count < 0) { ! 972: perror("netin"); ! 973: return(0); ! 974: } ! 975: } ! 976: ! 977: return(-1); ! 978: } ! 979: ! 980: retrieveproc(conn, handle) ! 981: CourierConnection *conn; ! 982: file_handle *handle; ! 983: { ! 984: int count, ocount; ! 985: u_char buffer[SPPMAXDATA]; ! 986: u_char *bp; ! 987: ! 988: errno = ocount = 0; ! 989: clearerr(handle->file_desc); ! 990: ! 991: if ( handle->type == -1 ) ! 992: handle->type= handle->truetype; ! 993: ! 994: #ifdef DEBUG ! 995: fprintf(msgs, "transferring data type= %d\n", handle->type); ! 996: #endif DEBUG ! 997: ! 998: #ifdef FILETOOLCOMPATIBILITY ! 999: if (handle->type == FILING_tText) { ! 1000: while ((count = fread(buffer, sizeof(char), SPPMAXDATA, handle->file_desc)) > 0) { ! 1001: ocount = count; ! 1002: for (bp = buffer; count > 0; count--, bp++) { ! 1003: if (*bp == '\n') *bp = '\r'; ! 1004: else if (*bp == '_') *bp = ','+0200; ! 1005: /* more translations here */ ! 1006: } ! 1007: if ((ocount = BDTwrite(conn, buffer, ocount)) <= 0) ! 1008: break; ! 1009: } ! 1010: } else { ! 1011: #else FILETOOLCOMPATIBILITY ! 1012: { ! 1013: #endif FILETOOLCOMPATIBILITY ! 1014: while ((count = fread(buffer, sizeof(char), SPPMAXDATA, handle->file_desc)) > 0 ! 1015: && (ocount = BDTwrite(conn, buffer, count)) > 0) { ! 1016: } ! 1017: } ! 1018: ! 1019: if (ocount < 0) { ! 1020: BDTabort(conn); ! 1021: perror("netout"); ! 1022: return(0); ! 1023: } ! 1024: else if (ferror(handle->file_desc)) { ! 1025: BDTabort(conn); ! 1026: perror("read"); ! 1027: return(0); ! 1028: } ! 1029: else ! 1030: BDTclosewrite(conn); ! 1031: ! 1032: return(-1); ! 1033: } ! 1034: ! 1035: #ifdef FILETOOLCOMPATIBILITY ! 1036: get_name_from_fileID(handle, fileid) ! 1037: file_handle *handle; ! 1038: Unspecified *fileid; ! 1039: { ! 1040: char cmd[256]; ! 1041: char pathname[256]; ! 1042: char buffer[256]; ! 1043: int inode; ! 1044: FILE *fd, *popen(); ! 1045: Boolean first= TRUE; ! 1046: ! 1047: if ( *(handle->pathname) == '\0' ) { ! 1048: ReturnAttributeTypeError(FILING_unreasonable, FILING_fileID); ! 1049: /* NOT REACHED */ ! 1050: } ! 1051: ! 1052: #ifdef DEBUG ! 1053: fprintf(msgs, "looking for fileid %x %x\n", fileid[0], fileid[1]); ! 1054: #endif DEBUG ! 1055: ! 1056: strcpy(cmd, "/bin/ls -1ai "); ! 1057: strcat(cmd, handle->pathname); ! 1058: ! 1059: if ( (fd= popen(cmd, "r")) == NULL ) { ! 1060: ReturnAccessError(FILING_accessRightsInsufficient); ! 1061: /* NOT REACHED */ ! 1062: } ! 1063: ! 1064: while ( fgets(buffer, sizeof(buffer), fd) != NULL ) { ! 1065: buffer[strlen(buffer)-1]= '\0'; ! 1066: ! 1067: sscanf(buffer, "%d %s", &inode, pathname); ! 1068: #ifdef DEBUG ! 1069: fprintf(msgs, "inode= %d '%s'\n",inode, pathname); ! 1070: #endif DEBUG ! 1071: ! 1072: if ( (fileid[0] == ((inode>>16)&0xffff)) && ! 1073: (fileid[1] == (inode&0xffff)) ) { ! 1074: if ( strcmp(handle->pathname, "/") != 0 ) ! 1075: strcat(handle->pathname, "/"); ! 1076: strcat(handle->pathname, pathname); ! 1077: pclose(fd); ! 1078: return(-1); ! 1079: } ! 1080: } ! 1081: ! 1082: pclose(fd); ! 1083: ReturnAccessError(FILING_fileNotFound); ! 1084: /* NOT REACHED */ ! 1085: } ! 1086: #endif FILETOOLCOMPATIBILITY ! 1087: ! 1088: check_pathname(pathname) ! 1089: char *pathname; ! 1090: { ! 1091: char *ptr; ! 1092: ! 1093: for ( ptr= pathname; *ptr != '\0' ; ptr++ ) { ! 1094: if ( isspace(*ptr) || iscntrl(*ptr) ) { ! 1095: ReturnAttributeValueError(FILING_illegal, FILING_pathname); ! 1096: /* NOT REACHED */ ! 1097: } ! 1098: } ! 1099: ! 1100: return(-1); ! 1101: } ! 1102: ! 1103: #ifdef EXTENSIONS ! 1104: /* ! 1105: * make_backup ! 1106: * ! 1107: */ ! 1108: ! 1109: make_backup(handle) ! 1110: file_handle *handle; ! 1111: ! 1112: { ! 1113: char buffer[2048]; ! 1114: char backup_name[MAX_FILE_NAME_LENGTH]; ! 1115: int fin, fout, count; ! 1116: ! 1117: strcpy(backup_name, handle->pathname); ! 1118: strcat(backup_name, ".REP"); ! 1119: ! 1120: if ( (fin= open(handle->pathname, O_RDONLY, 0)) < 0 ) { ! 1121: return(0); ! 1122: /* NOT REACHED */ ! 1123: } ! 1124: ! 1125: if ( (fout= open(backup_name, O_WRONLY|O_CREAT, 0600)) < 0 ) { ! 1126: return(0); ! 1127: /* NOT REACHED */ ! 1128: } ! 1129: ! 1130: while ( (count= read(fin, buffer, sizeof(buffer))) > 0 ) { ! 1131: if ( write(fout, buffer, count) < 0 ) { ! 1132: close(fin); ! 1133: close(fout); ! 1134: unlink(backup_name); ! 1135: return(0); ! 1136: /* NOT REACHED */ ! 1137: } ! 1138: } ! 1139: ! 1140: close(fin); ! 1141: close(fout); ! 1142: return(-1); ! 1143: } ! 1144: ! 1145: /* ! 1146: * recall_backup ! 1147: * ! 1148: */ ! 1149: ! 1150: recall_backup(handle) ! 1151: file_handle *handle; ! 1152: ! 1153: { ! 1154: char backup_name[MAX_FILE_NAME_LENGTH]; ! 1155: ! 1156: strcpy(backup_name, handle->pathname); ! 1157: strcat(backup_name, ".REP"); ! 1158: ! 1159: /* ! 1160: * we better not see an error here, since we have already ! 1161: * munged the original file ! 1162: */ ! 1163: ! 1164: if ( rename(backup_name, handle->pathname) == -1 ) { ! 1165: return(0); ! 1166: } ! 1167: ! 1168: return(-1); ! 1169: } ! 1170: ! 1171: unlink_backup(handle) ! 1172: file_handle *handle; ! 1173: ! 1174: { ! 1175: char backup_name[MAX_FILE_NAME_LENGTH]; ! 1176: ! 1177: strcpy(backup_name, handle->pathname); ! 1178: strcat(backup_name, ".REP"); ! 1179: ! 1180: if ( unlink(backup_name) == -1 ) { ! 1181: return(0); ! 1182: } ! 1183: ! 1184: return(-1); ! 1185: } ! 1186: #endif EXTENSIONS
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.