📄 system_interface.c
字号:
#ifndef lintstatic char *rcsid = "$Header: system_interface.c,v 1.6 87/05/14 11:35:19 ed Exp $";#endif lint/* * Copyright (c) 1986, 1987 Xerox Corporation. *//* $Log: system_interface.c,v $ * Revision 1.6 87/05/14 11:35:19 ed * Enhanced fileID to be 32 bit inode (previous oversight). * Also get_name_from_fileID now uses -a on ls to look at all files. * * Revision 1.5 87/04/16 15:26:17 ed * Fixed bug if count was Filing4_unlimitedCount. (from jqj) * Resolved lingering Subset pathname bugs. * * Revision 1.4 87/04/01 10:10:42 ed * Added recognition of 'file drawers' (directories in root) * in make_attribute_sequence. * * Revision 1.3 87/03/31 14:17:54 ed * Fixed bug in access_file (per JQ Johnson) passed dir_handle, * expected pathname, check for -1 failure, not success. * * Revision 1.2 87/03/31 09:46:46 ed * New procedures: Create, ChangeAttributes(name only), Copy, Move, * Replace, Serialize, Deserialize. * Added conditional disabling of root logins. * Support for GetAttributes (allAttributeTypes). * Support for filter of type all. * * Revision 1.1 87/01/14 11:26:12 ed * Initial revision * */#include <stdio.h>#include <pwd.h>#include <signal.h>#include <errno.h>#include <ctype.h>#include <sys/file.h>#include <sys/time.h>#include <sys/types.h>#include <sys/stat.h>#include <netns/ns.h>#include <netns/sp.h>#ifdef FILING4#include "filingV4.h"#include "authenticationV2.h"#endif FILING4#ifdef FILING5#include "filingV5.h"#include "authenticationV2.h"#endif FILING5#ifdef FILING6#include "filingV6.h"#include "authenticationV3.h"#endif FILING5#ifdef FILINGSUBSET1#include "filingsubsetV1.h"#include "authenticationV3.h"#endif FILINGSUBSET1#include <xnscourier/filing_server.h>#include <xnscourier/filetypes.h>#define XNS_TIME_DIFFERENCE 2177452800 /* [(1970-1901) years * 365 days/year + 17 leap days */ /* * 24 hours/day * 60 min/hour * 60 sec/min */#define SERVICE_ROOT "/" /* root directory for service */#ifdef DEBUGFILE *msgs;#endif DEBUGextern int errno;Cardinal continuance; /* continuance value, in seconds */extern continuance_expiration(); /* expiration routine *//* * routine: * verifyandposition_user * input: * user_name - derived from secondary credentials * user_password - derived form secondary credentials * returns: * -1 - success * else Filing Error, Problem */verifyandposition_user(user_name,user_password)char *user_name;char *user_password;{ struct passwd *pwd_entry; struct passwd *getpwnam(); char *crypt();#ifdef DEBUG fprintf(msgs, "user= '%s'\n", user_name);#endif DEBUG /* determine if user is valid */ if ( (pwd_entry= getpwnam(user_name)) == (struct passwd *)0 ) { char *lowercase();#ifdef DEBUG fprintf(msgs, "name= '%s'\n",lowercase(user_name));#endif DEBUG if ( (pwd_entry= getpwnam(lowercase(user_name))) == (struct passwd *)0 ) {#if FILING4 | FILING5 ReturnAuthenticationError(AUTHENTICATION_credentialsInvalid);#else FILING4 | FILING5 ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid);#endif FILING4 | FILING5 /* NOT REACHED */ } }#if !(FILING4 | FILING5) if ( strcmp(pwd_entry->pw_passwd, crypt(user_password,pwd_entry->pw_passwd)) ) { ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid); /* NOT REACHED */ }#endif !(FILING4 | FILING5) /* set process group ID */ if ( setgid(pwd_entry->pw_gid) == -1 ) {#if FILING4 | FILING5 ReturnAuthenticationError(AUTHENTICATION_credentialsInvalid);#else FILING4 | FILING5 ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid);#endif FILING4 | FILING5 /* NOT REACHED */ } /* set process user ID */ if ( setuid(pwd_entry->pw_uid) == -1 ) {#if FILING4 | FILING5 ReturnAuthenticationError(AUTHENTICATION_credentialsInvalid);#else FILING4 | FILING5 ReturnAuthenticationError(FILING_secondaryCredentialsValueInvalid);#endif FILING4 | FILING5 /* NOT REACHED */ } /* position in service root */ if ( chdir(SERVICE_ROOT) == -1 ) { ReturnServiceError(FILING_serviceUnavailable); /* NOT REACHED */ } return(-1);}/* * routine: * set_continuance_timer */set_continuance_timer(){ alarm(0); /* cancel any previous alarm */ signal(SIGALRM, continuance_expiration); /* set routine to catch alarm */ alarm(continuance); /* set alarm */}/* * routine: * reset_continuance_timer */reset_continuance_timer(){ alarm(0); /* cancel previous alarm */ alarm(continuance); /* then, reset alarm */}/* * routine: * cancel_continuance_timer */cancel_continuance_timer(){ alarm(0); /* cancel any previous alarm */ signal(SIGALRM,SIG_IGN); /* set routine to ignore alarm */}/* * routine: * open_file * input: * pointer to file handle * returns: * -1 - success * else FILING_ error, problem */open_file(file_context_block)file_handle *file_context_block;{#ifdef DEBUG fprintf(msgs, "open_file\n");#endif DEBUG if ( (file_context_block->file_desc= fopen(file_context_block->pathname, "r")) == NULL ) { switch (errno) { case EACCES : /* user has no access */ ReturnAccessError(FILING_accessRightsInsufficient); /* NOT REACHED */ case ENOENT : /* no such file */ case ENOTDIR : /* no such directory */ ReturnHandleError(FILING_fileNotFound); /* NOT REACHED */ default : /* all other errors */ ReturnAccessError(FILING_accessRightsIndeterminate); /* NOT REACHED */ } } return(-1);}/* * routine: * close_file * input: * pointer to file handle * returns: * -1 - success */close_file(file_context_block)file_handle *file_context_block;{#ifdef DEBUG fprintf(msgs, "closing...\n");#endif DEBUG if ( file_context_block->file_desc != NULL ) { fclose(file_context_block->file_desc); file_context_block->file_desc= 0; } return(-1);}/* * routine: * stat_file * input: * pointer to file handle * returns: * -1 - success * else Filing Error, Problem * * file_context_block entries filled in */stat_file(file_context_block)file_handle *file_context_block;{ struct stat file_stat; LongCardinal get_type();#ifdef DEBUG fprintf(msgs, "stating '%s'\n",file_context_block->pathname);#endif DEBUG if ( stat(file_context_block->pathname,&file_stat) == -1 ) { switch (errno) { case EACCES : /* user has no access */ ReturnAccessError(FILING_accessRightsInsufficient); /* NOT REACHED */ case ENOTDIR : /* directory doesn't exist */ case ENOENT : /* file doesn't exist */ ReturnAccessError(FILING_fileNotFound); default : /* all other errors */ ReturnAccessError(FILING_accessRightsIndeterminate); } } file_context_block->datasize= file_stat.st_size; /* dataSize */ /* file type */ if ( (file_stat.st_mode & S_IFDIR) != 0 ) { /* directory */ file_context_block->isdirectory= TRUE; file_context_block->truetype= FILING_tDirectory; } else { file_context_block->isdirectory= FALSE; /* non-directory */ file_context_block->truetype= get_type(file_context_block->pathname); } return(-1);}/* * routine: * create_file * input: * pointer to file handle * returns: * -1 - success * else FILING_ Error, Problem * * file_context_block->file_desc filled in */create_file(file_context_block)file_handle *file_context_block;{ if ( access(file_context_block->pathname, F_OK) == 0 ) { ReturnInsertionError(FILING_fileNotUnique); /* NOT REACHED */ } if ( (file_context_block->file_desc= fopen(file_context_block->pathname, "w")) ) { switch (errno) { case EACCES : /* user has no access */ ReturnAccessError(FILING_accessRightsInsufficient); /* NOT REACHED */ case EEXIST : /* file exists */ ReturnInsertionError(FILING_fileNotUnique); /* NOT REACHED */ case ENOENT : /* no such file, OK */ break; case ENOTDIR : /* no such directory */ ReturnAccessError(FILING_fileNotFound); /* NOT REACHED */ case EMFILE : /* process file table full */ case ENFILE : /* system file table full */ ReturnSpaceError(FILING_allocationExceeded); /* NOT REACHED */ default : /* all other errors */ ReturnAccessError(FILING_accessRightsIndeterminate); /* NOT REACHED */ } } return(1);}/* * routine: * create_directory * input: * pointer to file handle * returns: * -1 - success * else FILING_ Error, Problem * */create_directory(file_context_block)file_handle *file_context_block;{ int status;#ifdef DEBUG fprintf(msgs, "createdir '%s'\n",file_context_block->pathname);#endif DEBUG status= 0; if ( fork() == 0 ) { /* execute command */ execl("/bin/mkdir", "mkdir", file_context_block->pathname, 0); ReturnAccessError(FILING_accessRightsInsufficient); /* NOT REACHED */ } wait(&status); if ( status ) { /* error reports accessRightsInsufficient */ ReturnAccessError(FILING_accessRightsInsufficient); /* NOT REACHED */ } return(-1);}/* * routine: * rename_file * input: * pointer to old name * pointer to file handle (containing new name) * returns: * -1 - success * else Filing Error, Problem * */rename_file(oldname, file_context_block)char *oldname;file_handle *file_context_block;{ if ( access(file_context_block->pathname, F_OK) == 0 ) { ReturnInsertionError(FILING_fileNotUnique); /* NOT REACHED */ }#ifdef DEBUG fprintf(msgs, "renaming '%s' to '%s'\n",oldname, file_context_block->pathname);#endif DEBUG if ( rename(oldname, file_context_block->pathname) == -1 ) { switch (errno) { case EACCES : /* user has no access */ ReturnAccessError(FILING_accessRightsInsufficient); /* NOT REACHED */ case ENOTDIR : /* directory doesn't exist */ case ENOENT : /* file doesn't exist */ case EXDEV : /* no cross file system move */ ReturnAccessError(FILING_fileChanged); /* NOT REACHED */ case EINVAL : /* old is parent of new */ ReturnInsertionError(FILING_loopInHierarchy); /* NOT REACHED */ default : /* all other errors */ ReturnAccessError(FILING_accessRightsIndeterminate); /* NOT REACHED */ } } return(-1);}/* * routine: * copy_file * input: * pointer to old file handle * pointer to new file handle * returns: * -1 - success * else Filing Error, Problem * */copy_file(old_file_context_block, new_file_context_block)file_handle *old_file_context_block;file_handle *new_file_context_block;{ int pid, s; if ( strncmp(old_file_context_block->pathname, new_file_context_block->pathname, strlen(old_file_context_block->pathname)) == 0 ) { ReturnInsertionError(FILING_loopInHierarchy); /* NOT REACHED */ } if ( access(new_file_context_block->pathname, F_OK) == 0 ) { ReturnInsertionError(FILING_fileNotUnique); /* NOT REACHED */ }#ifdef DEBUG fprintf(msgs, "copying '%s' to '%s'\n",old_file_context_block->pathname, new_file_context_block->pathname);#endif DEBUG if ( copy(old_file_context_block->pathname, new_file_context_block->pathname) != -1 ) { ReturnAccessError(FILING_fileChanged); /* NOT REACHED */ } return(-1);}copy(from, to)char *from;char *to;{ int pid, s; if ( (pid= fork()) == 0 ) { /* child */ execl("/bin/cp", "cp", "-r", from, to, 0); exit(1); } if ( pid == -1 ) { ReturnUndefinedError(0); /* NOT REACHED */ } while ( wait(&s) != pid ) ; /* * would be nice if cp returned useful errors, but ... */ if ( s != 0 ) { ReturnAccessError(FILING_fileChanged); /* NOT REACHED */ } return(-1);}list_directory(conn, directory, attr, file_spec, count)CourierConnection *conn;file_handle *directory;FILING_AttributeTypeSequence attr;char *file_spec;Cardinal count;{ FILING_StreamOfAttributeSequence stream_of_attrseq; FILING_AttributeSequence attribute_sequence; FILE *pipe_desc; FILE *popen(); Boolean first= TRUE; char command[256]; char filename[MAX_FILE_NAME_LENGTH]; stream_of_attrseq.nextSegment_case.segment.length= 1; stream_of_attrseq.nextSegment_case.segment.sequence= &attribute_sequence; strcpy(command, "/bin/ls -1d "); /* form appropriate command */ strcat(command, directory->pathname); if ( strcmp(directory->pathname, "/") != 0 ) { strcat(command, "/"); } strcat(command, file_spec); if ( get_types(attr, &attribute_sequence) != -1 ) { /* NOT REACHED */ }#ifdef DEBUG fprintf(msgs, "listing '%s'\n",command);#endif DEBUG if ( (pipe_desc= popen(command, "r")) == NULL ) { /* issue command */ ReturnAccessError(FILING_accessRightsInsufficient); /* NOT REACHED */ } while ( fgets(filename, MAX_FILE_NAME_LENGTH, pipe_desc) != NULL ) { first= FALSE; filename[strlen(filename)-1]= '\0';#ifdef DEBUG fprintf(msgs,"got '%s' ",filename); fprintf(msgs, "count= %d\n",count);#endif DEBUG if ( (count != FILING_unlimitedCount) && (--count < 0) ) { break; } make_attribute_sequence(filename,&attribute_sequence); put_next_attribute_sequence(conn, &stream_of_attrseq); } if ( first == TRUE ) { pclose(pipe_desc);/* ReturnAccessError(FILING_fileNotFound); ??? */ /* NOT REACHED */ } put_last_attribute_sequence(conn); BDTclosewrite(conn); pclose(pipe_desc); return(-1);}/* * routine: * delete_file * input: * pointer to file handle * returns: * -1 - success * else Filing Error, Problem */delete_file(file_context_block)file_handle *file_context_block;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -