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