|
|
BSD 4.3tahoe
#ifndef lint
static char *rcsid = "$Header: /var/lib/cvsd/repos/CSRG/43BSDTahoe/new/xns/examples/filing_common/system_interface.c,v 1.1.1.1 2018/04/24 16:12:58 root Exp $";
#endif lint
/*
* Copyright (c) 1986, 1987 Xerox Corporation.
*/
/* $Log: system_interface.c,v $
/* Revision 1.1.1.1 2018/04/24 16:12:58 root
/* BSD 4.3tahoe
/*
* 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 DEBUG
FILE *msgs;
#endif DEBUG
extern 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;
{
int status;
#ifdef DEBUG
fprintf(msgs," deleting '%s'",file_context_block->pathname);
#endif DEBUG
if ( file_context_block->isdirectory ) {
if ( fork() == 0 ) { /* use rm -rf for directories */
execl("/bin/rm", "rm", "-rf", file_context_block->pathname, 0);
ReturnAccessError(FILING_accessRightsInsufficient);
/* NOT REACHED */
}
wait(&status);
if ( status ) {
ReturnAccessError(FILING_accessRightsInsufficient);
/* NOT REACHED */
}
} else { /* use unlink for non-directories */
if ( unlink(file_context_block->pathname) == -1 ) {
switch (errno) {
case EACCES : /* user has no access */
ReturnAccessError(FILING_accessRightsInsufficient);
/* NOT REACHED */
case ENOENT : /* no such file */
case ENOTDIR : /* no such directory */
ReturnAccessError(FILING_fileNotFound);
/* NOT REACHED */
default : /* all other errors */
ReturnAccessError(FILING_accessRightsIndeterminate);
/* NOT REACHED */
}
}
}
}
/*
* routine:
* delete_partial_file
* input:
* pointer to file handle
* returns:
* -1 - success
*/
delete_partial_file(file_context_block)
file_handle *file_context_block;
{
unlink(file_context_block->pathname);
return(-1);
}
/*
* routine:
* access_file
* input:
* pointer to file handle
* returns:
* -1 - success
*/
access_file(file_context_block)
file_handle *file_context_block;
{
#ifdef DEBUG
fprintf(msgs, "access_file\n");
#endif DEBUG
if ( access(file_context_block->pathname,R_OK | F_OK) == -1 ) {
switch (errno) {
case EACCES : /* user has no access */
ReturnAccessError(FILING_fileChanged);
/* NOT REACHED */
case ENOENT : /* no such file */
case ENOTDIR : /* no such directory */
ReturnHandleError(FILING_invalid);
/* NOT REACHED */
default : /* all other errors */
ReturnAccessError(FILING_accessRightsIndeterminate);
/* NOT REACHED */
}
}
return(-1);
}
/*
* routine:
* set_create_time
* input:
* pointer to file context block
* where
* if no createdOn value was specified on Store, createdon = 0
* if createdOn value was specified on Store, createdOn != 0,
* value is in XNS time format
* returns:
* none
*/
set_create_time(file_context_block)
file_handle *file_context_block;
{
time_t time_buffer[2];
time_t time();
if ( file_context_block->createdon ) /* save createdOn if specified */
time_buffer[1]= file_context_block->createdon - XNS_TIME_DIFFERENCE;
else /* else, set to current date/time */
time_buffer[1]= time(0);
time_buffer[0]= time(0); /* set modifiedOn to current date/time */
utime(file_context_block->pathname,time_buffer);
}
/*
* routine:
* make_attribute_sequence
* inputs:
* pointer to file name
* pointer to sequence of attributes to fill in
* returns:
* -1 - success
*/
make_attribute_sequence(pathname, attrseq)
char *pathname;
FILING_AttributeSequence *attrseq;
{
int i;
struct stat file_stat;
FILING_AttributeType t;
LongCardinal createdon, modifiedon;
LongCardinal type, get_type();
LongCardinal datasize;
Boolean isdirectory;
Boolean all_attributes= FALSE;
Cardinal unix_version= 1;
Boolean istemporary= FALSE;
#ifdef FILETOOLCOMPATIBILITY
Cardinal fileid[6];
AUTHENTICATION_Clearinghouse_Name user;
AUTHENTICATION_Clearinghouse_Name CH_StringToName();
char *name, *pwname;
char *rindex();
struct passwd *getpwuid(), *pwd;
#endif FILETOOLCOMPATIBILITY
#ifdef EXTENSIONS
Boolean inroot= FALSE;
FILE *fd;
#endif EXTENSIONS
#ifdef DEBUG
fprintf(msgs, "make_attrseq '%s'\n", pathname);
#endif DEBUG
#ifndef FILINGSUBSET1
if ( (name= rindex(pathname, '/')) == 0 )
name= pathname;
else {
#ifdef EXTENSIONS
if ( name == pathname ) inroot= TRUE;
#endif EXTENSIONS
name++;
}
#endif FILINGSUBSET1
if ( stat(pathname, &file_stat) == -1 ) {
ReturnAccessError(FILING_accessRightsInsufficient);
/* NOT REACHED */
}
createdon= file_stat.st_mtime + XNS_TIME_DIFFERENCE; /* createdOn */
modifiedon= file_stat.st_atime + XNS_TIME_DIFFERENCE; /* modifiedOn */
datasize= file_stat.st_size; /* dataSize */
/* type and isDirectory */
if ( (file_stat.st_mode & S_IFDIR) != 0 ) {
isdirectory= TRUE;
#ifdef EXTENSIONS
if ( inroot ) /* if root & directory, assume file drawer */
type= TYPE_VPDrawer;
else
type= FILING_tDirectory;
#else EXTENSIONS
type= FILING_tDirectory;
#endif EXTENSIONS
} else {
type= get_type(pathname);
#ifdef EXTENSIONS
if ( (type > LAST_FILING_TYPE) && (type != TYPE_Interpress) &&
(type != TYPE_VPCanvas) ) {
if ( (fd= fopen(pathname, "r")) == NULL ) {
ReturnAccessError(FILING_fileChanged);
/* NOT REACHED */
}
isdirectory= GetDirectoryAttribute(fd);
fclose(fd);
} else {
isdirectory= FALSE;
}
#else EXTENSIONS
isdirectory= FALSE;
#endif EXTENSIONS
}
#ifdef EXTENSIONS
if ( attrseq->length == -1 ) {
all_attributes= TRUE;
if ( (type > LAST_FILING_TYPE) && (type != TYPE_Interpress) &&
(type != TYPE_VPCanvas) )
make_required_attributes(attrseq);
else
make_supported_attributes(attrseq);
}
#endif EXTENSIONS
for ( i= 0 ; i < attrseq->length ; i++ ) {
t= attrseq->sequence[i].type;
#ifdef DEBUG
fprintf(msgs,"#%d type= %d \n", i, t);
#endif DEBUG
if ( t == FILING_pathname ) {
StringToAttr(pathname, &attrseq->sequence[i]);
} else if ( t == FILING_type ) {
LongCardinalToAttr(type, &attrseq->sequence[i]);
} else if ( t == FILING_dataSize ) {
LongCardinalToAttr(datasize, &attrseq->sequence[i]);
} else if ( t == FILING_isDirectory ) {
BooleanToAttr(isdirectory, &attrseq->sequence[i]);
} else if ( t == FILING_createdOn ) {
LongCardinalToAttr(createdon, &attrseq->sequence[i]);
} else if ( t == FILING_modifiedOn ) {
LongCardinalToAttr(modifiedon, &attrseq->sequence[i]);
} else if ( t == FILING_version ) {
CardinalToAttr(unix_version, &attrseq->sequence[i]);
} else if ( t == FILING_isTemporary ) {
BooleanToAttr(istemporary, &attrseq->sequence[i]);
#ifdef FILETOOLCOMPATIBILITY
} else if ( t == FILING_name ) {
StringToAttr(name, &attrseq->sequence[i]);
} else if ( t == FILING_fileID ) {
fileid[0]= (file_stat.st_ino >> 16) & 0xffff;
fileid[1]= file_stat.st_ino & 0xffff;
fileid[2]= fileid[3]= fileid[4]= 0;
FileIDToAttr(fileid, &attrseq->sequence[i]);
} else if ( t == FILING_readOn ) {
LongCardinalToAttr(modifiedon, &attrseq->sequence[i]);
} else if ( t == FILING_createdBy ) {
if ( (pwd= getpwuid(file_stat.st_uid)) == 0 )
pwname= "Unkown";
else
pwname= pwd->pw_name;
user= CH_StringToName(pwname,NULL);
UserToAttr(user,&attrseq->sequence[i]);
#endif FILETOOLCOMPATIBILITY
} else {
attrseq->sequence[i].value.length= 0;
attrseq->sequence[i].value.sequence= (Unspecified *)0;
}
}
#ifdef EXTENSIONS
if ( all_attributes ) {
if ( (type > LAST_FILING_TYPE) && (type != TYPE_Interpress) &&
(type != TYPE_VPCanvas) ) {
if ( (fd= fopen(pathname, "r")) == NULL ) {
ReturnAccessError(FILING_fileChanged);
/* NOT REACHED */
}
if ( AddAllExtendedAttributes(fd, attrseq) != -1 ) {
fclose(fd);
ReturnAccessError(FILING_fileChanged);
/* NOT REACHED */
}
fclose(fd);
}
}
#endif EXTENSIONS
}
int
getBDTch(conn,bpp)
CourierConnection *conn;
u_char **bpp;
{
static u_char buffer[SPPMAXDATA];
static int count;
if (*bpp == NULL) {*bpp = buffer; count = 0;}
if (*bpp >= buffer+count) {
count=BDTread(conn,buffer,sizeof(buffer));
*bpp = buffer;
}
if (count <= 0) return(EOF);
else return(*((*bpp)++));
}
storeproc(conn,handle)
CourierConnection *conn;
file_handle *handle;
{
int count, ocount, ch, hashbytes;
char buffer[SPPMAXDATA];
int charset, charset16;
char *bp;
register FILE *fout;
register int fd;
fout= handle->file_desc;
fd= fileno(fout);
#ifdef FILETOOLCOMPATIBILITY
if ( handle->type == FILING_tText ) {
charset = 0; charset16 = 0; bp = NULL;
while ((ch = getBDTch(conn,&bp)) != EOF) {
if (ch == '\377') {
ch = getBDTch(conn,&bp);
if (ch == '\377') charset16 = 1;
else charset = ch;
continue;
}
if (charset16) {
charset = ch;
ch = getBDTch(conn,&bp);
}
switch (charset) {
case 0: /* normal character set -- minimal xlation */
if (ch == '\r') {
int nextch;
putc('\n',fout);
if ( (nextch = getBDTch(conn,&bp)) != '\n'){
if (nextch == '\r')
putc('\n',fout);
else if (nextch == ','+0200)
putc('_',fout);
else if (nextch != EOF)
putc(nextch,fout);
else
continue;
}
break;
}
else if (ch == ','+0200) ch = '_';
/* more mapping here */
putc(ch,fout);
break;
default:
break; /* ignore */
}
}
/* if (count < 0) perror("netin"); */
} else {
#else FILETOOLCOMPATIBILITY
{
#endif FILETOOLCOMPATIBILITY
errno = ocount = 0;
fflush(fout);
while ((count = BDTread(conn, buffer, sizeof(buffer))) > 0) {
if ((ocount = write(fd,buffer,count)) < 0) {
perror("write");
BDTabort(conn);
return(0);
}
}
if (count < 0) {
perror("netin");
return(0);
}
}
return(-1);
}
retrieveproc(conn, handle)
CourierConnection *conn;
file_handle *handle;
{
int count, ocount;
u_char buffer[SPPMAXDATA];
u_char *bp;
errno = ocount = 0;
clearerr(handle->file_desc);
if ( handle->type == -1 )
handle->type= handle->truetype;
#ifdef DEBUG
fprintf(msgs, "transferring data type= %d\n", handle->type);
#endif DEBUG
#ifdef FILETOOLCOMPATIBILITY
if (handle->type == FILING_tText) {
while ((count = fread(buffer, sizeof(char), SPPMAXDATA, handle->file_desc)) > 0) {
ocount = count;
for (bp = buffer; count > 0; count--, bp++) {
if (*bp == '\n') *bp = '\r';
else if (*bp == '_') *bp = ','+0200;
/* more translations here */
}
if ((ocount = BDTwrite(conn, buffer, ocount)) <= 0)
break;
}
} else {
#else FILETOOLCOMPATIBILITY
{
#endif FILETOOLCOMPATIBILITY
while ((count = fread(buffer, sizeof(char), SPPMAXDATA, handle->file_desc)) > 0
&& (ocount = BDTwrite(conn, buffer, count)) > 0) {
}
}
if (ocount < 0) {
BDTabort(conn);
perror("netout");
return(0);
}
else if (ferror(handle->file_desc)) {
BDTabort(conn);
perror("read");
return(0);
}
else
BDTclosewrite(conn);
return(-1);
}
#ifdef FILETOOLCOMPATIBILITY
get_name_from_fileID(handle, fileid)
file_handle *handle;
Unspecified *fileid;
{
char cmd[256];
char pathname[256];
char buffer[256];
int inode;
FILE *fd, *popen();
Boolean first= TRUE;
if ( *(handle->pathname) == '\0' ) {
ReturnAttributeTypeError(FILING_unreasonable, FILING_fileID);
/* NOT REACHED */
}
#ifdef DEBUG
fprintf(msgs, "looking for fileid %x %x\n", fileid[0], fileid[1]);
#endif DEBUG
strcpy(cmd, "/bin/ls -1ai ");
strcat(cmd, handle->pathname);
if ( (fd= popen(cmd, "r")) == NULL ) {
ReturnAccessError(FILING_accessRightsInsufficient);
/* NOT REACHED */
}
while ( fgets(buffer, sizeof(buffer), fd) != NULL ) {
buffer[strlen(buffer)-1]= '\0';
sscanf(buffer, "%d %s", &inode, pathname);
#ifdef DEBUG
fprintf(msgs, "inode= %d '%s'\n",inode, pathname);
#endif DEBUG
if ( (fileid[0] == ((inode>>16)&0xffff)) &&
(fileid[1] == (inode&0xffff)) ) {
if ( strcmp(handle->pathname, "/") != 0 )
strcat(handle->pathname, "/");
strcat(handle->pathname, pathname);
pclose(fd);
return(-1);
}
}
pclose(fd);
ReturnAccessError(FILING_fileNotFound);
/* NOT REACHED */
}
#endif FILETOOLCOMPATIBILITY
check_pathname(pathname)
char *pathname;
{
char *ptr;
for ( ptr= pathname; *ptr != '\0' ; ptr++ ) {
if ( isspace(*ptr) || iscntrl(*ptr) ) {
ReturnAttributeValueError(FILING_illegal, FILING_pathname);
/* NOT REACHED */
}
}
return(-1);
}
#ifdef EXTENSIONS
/*
* make_backup
*
*/
make_backup(handle)
file_handle *handle;
{
char buffer[2048];
char backup_name[MAX_FILE_NAME_LENGTH];
int fin, fout, count;
strcpy(backup_name, handle->pathname);
strcat(backup_name, ".REP");
if ( (fin= open(handle->pathname, O_RDONLY, 0)) < 0 ) {
return(0);
/* NOT REACHED */
}
if ( (fout= open(backup_name, O_WRONLY|O_CREAT, 0600)) < 0 ) {
return(0);
/* NOT REACHED */
}
while ( (count= read(fin, buffer, sizeof(buffer))) > 0 ) {
if ( write(fout, buffer, count) < 0 ) {
close(fin);
close(fout);
unlink(backup_name);
return(0);
/* NOT REACHED */
}
}
close(fin);
close(fout);
return(-1);
}
/*
* recall_backup
*
*/
recall_backup(handle)
file_handle *handle;
{
char backup_name[MAX_FILE_NAME_LENGTH];
strcpy(backup_name, handle->pathname);
strcat(backup_name, ".REP");
/*
* we better not see an error here, since we have already
* munged the original file
*/
if ( rename(backup_name, handle->pathname) == -1 ) {
return(0);
}
return(-1);
}
unlink_backup(handle)
file_handle *handle;
{
char backup_name[MAX_FILE_NAME_LENGTH];
strcpy(backup_name, handle->pathname);
strcat(backup_name, ".REP");
if ( unlink(backup_name) == -1 ) {
return(0);
}
return(-1);
}
#endif EXTENSIONS
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.