flocksim.c | flocksim.c | |||
---|---|---|---|---|
/* ======================================================================== | ||||
* Copyright 1988-2006 University of Washington | ||||
* | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | ||||
* You may obtain a copy of the License at | ||||
* | ||||
* http://www.apache.org/licenses/LICENSE-2.0 | ||||
* | ||||
* | ||||
* ======================================================================== | ||||
*/ | ||||
/* | /* | |||
* Program: flock emulation via fcntl() locking | * Program: flock emulation via fcntl() locking | |||
* | * | |||
* Author: Mark Crispin | * Author: Mark Crispin | |||
* Networks and Distributed Computing | * Networks and Distributed Computing | |||
* Computing & Communications | * Computing & Communications | |||
* University of Washington | * University of Washington | |||
* Administration Building, AG-44 | * Administration Building, AG-44 | |||
* Seattle, WA 98195 | * Seattle, WA 98195 | |||
* Internet: MRC@CAC.Washington.EDU | * Internet: MRC@CAC.Washington.EDU | |||
* | * | |||
* Date: 10 April 2001 | * Date: 10 April 2001 | |||
* Last Edited: 21 October 2003 | * Last Edited: 30 August 2006 | |||
* | ||||
* The IMAP toolkit provided in this Distribution is | ||||
* Copyright 1988-2003 University of Washington. | ||||
* The full text of our legal notices is contained in the file called | ||||
* CPYRIGHT, included with this Distribution. | ||||
*/ | */ | |||
#undef flock /* name is used as a struct for fcntl */ | #undef flock /* name is used as a struct for fcntl */ | |||
#undef fork /* make damn sure that we don't use vfork!! */ | #undef fork /* make damn sure that we don't use vfork!! */ | |||
#include "nfstest.c" /* get NFS tester */ | #include "nfstest.c" /* get NFS tester */ | |||
#ifndef NSIG /* don't know if this can happen */ | #ifndef NSIG /* don't know if this can happen */ | |||
#define NSIG 32 /* a common maximum */ | #define NSIG 32 /* a common maximum */ | |||
#endif | #endif | |||
/* Emulator for flock() call | /* Emulator for flock() call | |||
skipping to change at line 497 | skipping to change at line 505 | |||
*/ | */ | |||
long safe_status (DRIVER *dtb,MAILSTREAM *stream,char *mbx,long flags) | long safe_status (DRIVER *dtb,MAILSTREAM *stream,char *mbx,long flags) | |||
{ | { | |||
long ret = master (stream,NIL,NIL); | long ret = master (stream,NIL,NIL); | |||
if (lockslavep) exit ((*dtb->status) (stream,mbx,flags)); | if (lockslavep) exit ((*dtb->status) (stream,mbx,flags)); | |||
return ret; | return ret; | |||
} | } | |||
/* Scan file for contents | /* Scan file for contents | |||
* Accepts: file name | * Accepts: driver to call under slave | |||
* file name | ||||
* desired contents | * desired contents | |||
* length of contents | ||||
* length of file | ||||
* Returns: NIL if contents not found, T if found | * Returns: NIL if contents not found, T if found | |||
*/ | */ | |||
long safe_scan_contents (char *name,char *contents,unsigned long csiz, | long safe_scan_contents (DRIVER *dtb,char *name,char *contents, | |||
unsigned long fsiz) | unsigned long csiz,unsigned long fsiz) | |||
{ | { | |||
long ret = master (NIL,NIL,NIL); | long ret = master (NIL,NIL,NIL); | |||
if (lockslavep) exit (dummy_scan_contents (name,contents,csiz,fsiz)); | if (lockslavep) exit (scan_contents (dtb,name,contents,csiz,fsiz)); | |||
return ret; | return ret; | |||
} | } | |||
/* Safely copy message to mailbox | /* Safely copy message to mailbox | |||
* Accepts: driver to call under slave | * Accepts: driver to call under slave | |||
* MAIL stream | * MAIL stream | |||
* sequence | * sequence | |||
* destination mailbox | * destination mailbox | |||
* copy options | * copy options | |||
* Returns: T if success, NIL if failed | * Returns: T if success, NIL if failed | |||
*/ | */ | |||
skipping to change at line 660 | skipping to change at line 671 | |||
} | } | |||
/* Disk error found | /* Disk error found | |||
* Accepts: stream | * Accepts: stream | |||
* system error code | * system error code | |||
* flag indicating that mailbox may be clobbered | * flag indicating that mailbox may be clobbered | |||
* Returns: abort flag | * Returns: abort flag | |||
*/ | */ | |||
long slave_diskerror (MAILSTREAM *stream,long errcode,long serious) | long slave_diskerror (MAILSTREAM *stream,long errcode,long serious) | |||
{ | { | |||
char tmp[MAILTMPLEN]; | ||||
int c; | int c; | |||
long ret = NIL; | ||||
fprintf (slaveout,"D%lx %lu %lu\n",(unsigned long) stream,errcode,serious ); | fprintf (slaveout,"D%lx %lu %lu\n",(unsigned long) stream,errcode,serious ); | |||
fflush (slaveout); | fflush (slaveout); | |||
if ((c = getc (slavein)) == '+') return LONGT; | switch (c = getc (slavein)) { | |||
if (c != '-') slave_fatal ("Unknown master response for diskerror"); | case EOF: /* pipe broken */ | |||
return NIL; | slave_fatal ("Pipe broken reading diskerror response"); | |||
case '+': /* user wants to abort */ | ||||
ret = LONGT; | ||||
case '-': /* no abort */ | ||||
break; | ||||
default: | ||||
sprintf (tmp,"Unknown master response for diskerror: %c",c); | ||||
slave_fatal (tmp); | ||||
} | ||||
return ret; | ||||
} | } | |||
/* Log a fatal error event | /* Log a fatal error event | |||
* Accepts: string to log | * Accepts: string to log | |||
* Does not return | ||||
*/ | */ | |||
void slave_fatal (char *string) | void slave_fatal (char *string) | |||
{ | { | |||
syslog (LOG_ALERT,"IMAP toolkit slave process crash: %.100s",string); | syslog (LOG_ALERT,"IMAP toolkit slave process crash: %.100s",string); | |||
fprintf (slaveout,"F%s\n",string); | fprintf (slaveout,"F%s\n",string); | |||
fflush (slaveout); | fflush (slaveout); | |||
abort (); /* die */ | abort (); /* die */ | |||
} | } | |||
/* Append read buffer | /* Append read buffer | |||
skipping to change at line 704 | skipping to change at line 727 | |||
#if 0 | #if 0 | |||
/* This doesn't work on Solaris with GCC. I think that it's a C library | /* This doesn't work on Solaris with GCC. I think that it's a C library | |||
* bug, since the problem only shows up if the application does fread() | * bug, since the problem only shows up if the application does fread() | |||
* on some other file | * on some other file | |||
*/ | */ | |||
for (t = s; n && ((i = fread (t,1,n,slavein)); t += i,n -= i); | for (t = s; n && ((i = fread (t,1,n,slavein)); t += i,n -= i); | |||
#else | #else | |||
for (t = s; n && ((c = getc (slavein)) != EOF); *t++ = c,--n); | for (t = s; n && ((c = getc (slavein)) != EOF); *t++ = c,--n); | |||
#endif | #endif | |||
if (n) { | if (n) { | |||
sprintf (tmp,"Error reading %s with %lu bytes remaining",error,n); | sprintf (tmp,"Pipe broken reading %s with %lu bytes remaining",error,n) ; | |||
slave_fatal (tmp); | slave_fatal (tmp); | |||
} | } | |||
return s; | return s; | |||
} | } | |||
/* Append message callback | /* Append message callback | |||
* Accepts: MAIL stream | * Accepts: MAIL stream | |||
* append data package | * append data package | |||
* pointer to return initial flags | * pointer to return initial flags | |||
* pointer to return message internal date | * pointer to return message internal date | |||
* pointer to return stringstruct of message or NIL to stop | * pointer to return stringstruct of message or NIL to stop | |||
skipping to change at line 736 | skipping to change at line 759 | |||
if (ad->flags) fs_give ((void **) &ad->flags); | if (ad->flags) fs_give ((void **) &ad->flags); | |||
if (ad->date) fs_give ((void **) &ad->date); | if (ad->date) fs_give ((void **) &ad->date); | |||
if (ad->msg) fs_give ((void **) &ad->msg); | if (ad->msg) fs_give ((void **) &ad->msg); | |||
*flags = *date = NIL; /* assume no flags or date */ | *flags = *date = NIL; /* assume no flags or date */ | |||
fputs ("A\n",slaveout); /* tell master we're doing append callback * / | fputs ("A\n",slaveout); /* tell master we're doing append callback * / | |||
fflush (slaveout); | fflush (slaveout); | |||
switch (c = getc (slavein)) { /* what did master say? */ | switch (c = getc (slavein)) { /* what did master say? */ | |||
case '+': /* have message, get size of flags */ | case '+': /* have message, get size of flags */ | |||
for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); | for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); | |||
if (c != ' ') { | if (c != ' ') { | |||
if (c == EOF) sprintf (tmp,"Pipe broken after flag size %lu",n); | ||||
sprintf (tmp,"Missing delimiter after flag size %lu: %c",n,c); | sprintf (tmp,"Missing delimiter after flag size %lu: %c",n,c); | |||
slave_fatal (tmp); | slave_fatal (tmp); | |||
} | } | |||
if (n) *flags = ad->flags = slave_append_read (n,"flags"); | if (n) *flags = ad->flags = slave_append_read (n,"flags"); | |||
/* get size of date */ | /* get size of date */ | |||
for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); | for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); | |||
if (c != ' ') { | if (c != ' ') { | |||
sprintf (tmp,"Missing delimiter after date size %lu: %c",n,c); | if (c == EOF) sprintf (tmp,"Pipe broken after date size %lu",n); | |||
else sprintf (tmp,"Missing delimiter after date size %lu: %c",n,c); | ||||
slave_fatal (tmp); | slave_fatal (tmp); | |||
} | } | |||
if (n) *date = ad->date = slave_append_read (n,"date"); | if (n) *date = ad->date = slave_append_read (n,"date"); | |||
/* get size of message */ | /* get size of message */ | |||
for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); | for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); | |||
if (c != ' ') { | if (c != ' ') { | |||
if (c == EOF) sprintf (tmp,"Pipe broken after message size %lu",n); | ||||
sprintf (tmp,"Missing delimiter after message size %lu: %c",n,c); | sprintf (tmp,"Missing delimiter after message size %lu: %c",n,c); | |||
slave_fatal (tmp); | slave_fatal (tmp); | |||
} | } | |||
if (n) { /* make buffer for message */ | if (n) { /* make buffer for message */ | |||
ad->msg = slave_append_read (n,"message"); | ad->msg = slave_append_read (n,"message"); | |||
/* initialize stringstruct */ | /* initialize stringstruct */ | |||
INIT (&ad->message,mail_string,(void *) ad->msg,n); | INIT (&ad->message,mail_string,(void *) ad->msg,n); | |||
ad->first = NIL; /* no longer first message */ | ad->first = NIL; /* no longer first message */ | |||
*message = &ad->message; /* return message */ | *message = &ad->message; /* return message */ | |||
} | } | |||
else *message = NIL; /* empty message */ | else *message = NIL; /* empty message */ | |||
return LONGT; | return LONGT; | |||
case '-': /* error */ | case '-': /* error */ | |||
*message = NIL; /* set stop */ | *message = NIL; /* set stop */ | |||
break; | break; | |||
case EOF: /* end of file */ | ||||
slave_fatal ("Pipe broken reading append response"); | ||||
default: /* unknown event */ | default: /* unknown event */ | |||
sprintf (tmp,"Unknown master response for append: %c",c); | sprintf (tmp,"Unknown master response for append: %c",c); | |||
slave_fatal (tmp); | slave_fatal (tmp); | |||
} | } | |||
return NIL; /* return failure */ | return NIL; /* return failure */ | |||
} | } | |||
/* Proxy copy across mailbox formats | /* Proxy copy across mailbox formats | |||
* Accepts: mail stream | * Accepts: mail stream | |||
* sequence to copy on this stream | * sequence to copy on this stream | |||
* destination mailbox | * destination mailbox | |||
End of changes. 15 change blocks. | ||||
15 lines changed or deleted | 43 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |