Annotation of 43BSDTahoe/new/xns/examples/filing_common/system_interface.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.